26 #include "art/Framework/Core/EDAnalyzer.h" 
   27 #include "art/Framework/Core/ModuleMacros.h" 
   28 #include "art/Framework/Principal/Event.h" 
   29 #include "canvas/Utilities/Exception.h" 
   30 #include "messagefacility/MessageLogger/MessageLogger.h" 
   31 #include "fhiclcpp/types/Sequence.h" 
   73   template <
typename Thresholds, 
typename Requirements>
 
   75     (TTree& 
tree, 
Thresholds const& thresholds, Requirements 
const& minReqs);
 
   78   void assignResponse(std::size_t iThr, std::size_t iReq, 
bool resp);
 
   87 namespace icarus::trigger { 
class MajorityTriggerEfficiencyPlots; }
 
  279   : 
public art::EDAnalyzer
 
  292       Name(
"MinimumPrimitives"),
 
  293       Comment(
"minimum required number of trigger primitives for a trigger")
 
  320   virtual void analyze(art::Event 
const& event) 
override;
 
  323   virtual void endJob() 
override;
 
  388     std::size_t 
const thresholdIndex,
 
  433     std::size_t iThr, std::string 
const& threshold,
 
  436     std::vector<WorkingTriggerGate_t> 
const& combinedCounts,
 
  437     std::vector<ChannelID_t> 
const& channelList
 
  457     std::string 
const& threshold
 
  469 template <
typename Thresholds, 
typename Requirements>
 
  471   (TTree& tree, 
Thresholds const& thresholds, Requirements 
const& minReqs)
 
  474   , RespTxxRxx{ std::make_unique<bool[]>(
indices.size()) }
 
  481       std::string 
const branchName
 
  485         (branchName.c_str(), &(RespTxxRxx[
indices(iThr, iReq)]));
 
  496   (std::size_t iThr, std::size_t iReq, 
bool resp)
 
  498   RespTxxRxx[
indices(iThr, iReq)] = resp;
 
  507   : art::EDAnalyzer           (config)
 
  510   , fMinimumPrimitives(config().MinimumPrimitives())
 
  512   std::sort(fMinimumPrimitives.begin(), fMinimumPrimitives.end());
 
  517   if (helper().eventTree()) {
 
  519     fResponseTree = std::make_unique<ResponseTree>
 
  520       (*(helper().eventTree()), helper().ADCthresholds(), fMinimumPrimitives);
 
  524   if (fMinimumPrimitives.empty()) {
 
  525     throw art::Exception(art::errors::Configuration)
 
  526       << 
"At least one 'MinimumPrimitives' requirement... required.";
 
  529   std::size_t iPattern [[maybe_unused]] = 0U; 
 
  530   for (
auto const& req: fMinimumPrimitives) {
 
  531     std::size_t 
const index [[maybe_unused]]
 
  533     assert(index == iPattern++);
 
  537     mf::LogInfo log(helper().logCategory());
 
  539       << 
"Requirement of minimum trigger primitives (" 
  540       << fMinimumPrimitives.size() << 
"):";
 
  541     for (
auto const& req: fMinimumPrimitives) log << 
" " << req;
 
  555   std::vector<SettingsInfo_t> settings;
 
  558     settings.emplace_back(
 
  561       minCountStr + 
" channels required"  
  574   (art::Event 
const& event)
 
  580   helper().process(event);
 
  589   helper().printSummary();
 
  604   helper().TriggerEfficiencyPlotsBase::initializePlotSet(plots, settings);
 
  611   auto [ minimumPrimBinning, minimumPrimBinningLabels ]
 
  613   assert(minimumPrimBinning.size() == minimumPrimBinningLabels.size() + 1U);
 
  616     mf::LogTrace log(helper().logCategory());
 
  617     log << 
"MajorityTriggerEfficiencyPlots (plots '" 
  618       << plots.
name() << 
"') variable binning including the " 
  619       << fMinimumPrimitives.size() << 
" points {";
 
  620     for (
auto value: fMinimumPrimitives) log << 
" " << 
value;
 
  621     log << 
" } => " << minimumPrimBinningLabels.size() << 
" bins: ";
 
  622     for (
auto const& [ value, label ]
 
  623       : util::zip<1U>(minimumPrimBinning, minimumPrimBinningLabels))
 
  625       log << 
" " << value << 
" (\"" << label << 
"\") =>";
 
  627     log << 
" " << minimumPrimBinning.back();
 
  634   auto const [ 
detTimings, beamGate, preSpillWindow ] = makeGatePack();
 
  637     { 
detTimings.toOpticalTicks(helper().triggerTimeResolution()) };
 
  639   auto const& beamGateOpt = beamGate.asOptTickRange();
 
  641   auto* TrigTime = plots.
make<TH2F>(
 
  644       ";minimum requested number of trigger primitives" 
  645       ";optical time tick [ /" + 
util::to_string(triggerResolutionTicks) + 
" ]",
 
  646     minimumPrimBinning.size() - 1U, minimumPrimBinning.data(),
 
  648     beamGateOpt.duration() / triggerResolutionTicks,
 
  649     beamGateOpt.first.value(), beamGateOpt.second.value()
 
  654   auto* Eff = plots.
make<TEfficiency>(
 
  656     "Efficiency of triggering" 
  657       ";minimum requested number of trigger primitives" 
  658       ";trigger efficiency",
 
  659     minimumPrimBinning.size() - 1U, minimumPrimBinning.data()
 
  668     const_cast<TH1*>(Eff->GetTotalHistogram())->GetXaxis(),
 
  669     minimumPrimBinningLabels
 
  677     "Number of trigger primitives (\"channels firing at once\")" 
  678     ";maximum trigger primitives at the same time on a single cryostat" 
  688   std::size_t 
const thresholdIndex,
 
  695   auto const threshold = helper().ADCthresholdTag(thresholdIndex);
 
  697   auto const& beamGate = helper().makeMyBeamGate(clockData);
 
  706     thresholdIndex, threshold, selectedPlots, eventInfo,
 
  708     beamGate.applyToAll(combineTriggerPrimitives(gates, threshold)),
 
  709     helper().extractActiveChannels(gates)
 
  718   std::string 
const& threshold,
 
  722   std::vector<WorkingTriggerGate_t> 
const& combinedCounts,
 
  723   std::vector<ChannelID_t> 
const& channelList
 
  742   using namespace std::string_literals;
 
  744   using ClockTick_t = WorkingTriggerGate_t::TriggerGate_t::ClockTick_t;
 
  745   using OpeningCount_t = WorkingTriggerGate_t::TriggerGate_t::OpeningCount_t;
 
  747   using PrimitiveCount_t = std::pair<ClockTick_t, OpeningCount_t>;
 
  749   PrimitiveCount_t maxPrimitives { ClockTick_t{ 0 } , 0U };
 
  750   for (
auto const& [ iCryo, combinedCount ]
 
  753     auto const maxPrimitiveTime { combinedCount.findMaxOpen() };
 
  754     PrimitiveCount_t 
const maxPrimitivesInCryo
 
  755       { maxPrimitiveTime, combinedCount.openingCount(maxPrimitiveTime) };
 
  756     if (maxPrimitivesInCryo.second > maxPrimitives.second)
 
  757       maxPrimitives = maxPrimitivesInCryo;
 
  759     mf::LogTrace log { helper().logCategory() };
 
  760     log << 
"Max primitive count in " << threshold << 
" for C:" << iCryo << 
": " 
  761       << maxPrimitivesInCryo.second;
 
  762     if (maxPrimitivesInCryo.second > 0) {
 
  763       log << 
" at tick " << maxPrimitivesInCryo.first << 
" (" 
  771   PMTInfo_t const PMTinfo { threshold, channelList };
 
  789       for (
auto const& [ iCryo, cryoGate ]: 
util::enumerate(combinedCounts)) {
 
  792           { 
gateIn(cryoGate), minCount };
 
  793         extractOpeningInfo.setLocation(iCryo);
 
  794         while (extractOpeningInfo) {
 
  795           auto info = extractOpeningInfo();
 
  800       fired = triggerInfo.
fired();
 
  804       mf::LogTrace log(helper().logCategory());
 
  806         << 
" => fired (>" << minCount << 
") at " << triggerInfo.
atTick()
 
  807         << 
" (level " << triggerInfo.
level() << 
") from" 
  810       else log << 
" unknown location";
 
  811       log << 
", " << triggerInfo.
nTriggers() << 
" triggers total:";
 
  813         log << 
" [" << iTrigger << 
"] at " << 
info.tick;
 
  814         if (
info.hasLocation()) log << 
" of C:" << 
info.locationID;
 
  815         else log << 
" [unknown location]";
 
  816         log << 
" (level=" << 
info.level << 
")";
 
  821       mf::LogTrace(helper().logCategory())
 
  822         << 
" => not fired (>" << minCount << 
")";
 
  828     if (fResponseTree) fResponseTree->assignResponse(iThr, iReq, fired);
 
  830     registerTriggerResult(iThr, iReq, fired);
 
  832     std::string 
const minCountStr { 
"Req" + 
std::to_string(minCount) };
 
  845       get.
Eff(
"Eff"s).Fill(fired, minCount);
 
  849         get.Hist2D(
"TriggerTick"s).Fill(minCount, triggerInfo.
atTick().value());
 
  859       helper().fillAllEfficiencyPlots
 
  860         (eventInfo, PMTinfo, triggerInfo, plotSet.demandSandbox(minCountStr));
 
  880     fillEventPlots(eventInfo, plotSet);
 
  886     fillPMTplots(PMTinfo, plotSet);
 
  894     get.
Hist(
"NPrimitives"s).Fill(maxPrimitives.second);
 
  904   std::string 
const& threshold
 
  905 ) 
const -> std::vector<WorkingTriggerGate_t> {
 
  910   std::vector<WorkingTriggerGate_t> cryoCombinedGate;
 
  911   cryoCombinedGate.reserve(cryoGates.size());
 
  916     mf::LogTrace(helper().logCategory())
 
  917       << 
"Simulating trigger response with ADC threshold " << threshold
 
  918       << 
" for " << cryoID << 
" (" << gates.size() << 
" primitives)";
 
  926   return cryoCombinedGate;
 
BEGIN_PROLOG BeamGateDuration pmtthr physics producers trigtilewindowORS Thresholds
 
bool fired() const 
Returns whether the trigger fired. 
 
Obj * make(std::string const &name, std::string const &title, Args &&...args)
Creates a new ROOT object with the specified name and title. 
 
Definition of util::zip(). 
 
Helper class to produce plots about trigger simulation and trigger efficiency. 
 
std::vector< OpeningInfo_t > const & all() const 
 
std::vector< unsigned int > fMinimumPrimitives
Minimum number of trigger primitives for a trigger to happen. 
 
virtual void initializePlotSet(PlotSandbox &plots, std::vector< SettingsInfo_t > const &settings) const override
Initializes full set of plots for (ADC threshold + category). 
 
std::pair< std::vector< double >, std::vector< std::string > > makeVariableBinningAndLabels(Coll const ¢ralPoints)
Returns a variable size binning for the points. 
 
void sortOpenings()
Sorts all openings by time. 
 
Definition of util::enumerate(). 
 
A wrapper to trigger gate objects tracking the input of operations. 
 
virtual void endJob() override
Prints end-of-job summaries. 
 
virtual void beginJob() override
Initializes the plots. 
 
LocationID_t location() const 
Returns the ID of the location of the trigger (undefined if !fired()). 
 
Class managing the serialization of trigger responses in a simple ROOT tree. 
 
ResponseTree(TTree &tree, Thresholds const &thresholds, Requirements const &minReqs)
Constructor: accommodates that many thresholds and requirements. 
 
void assignResponse(std::size_t iThr, std::size_t iReq, bool resp)
Assigns the response for the specified trigger. 
 
auto gatesIn(TrackingGateColl &trackingGates)
 
std::size_t size(FixedBins< T, C > const &) noexcept
 
void applyAxisLabels(TAxis *pAxis, std::vector< std::string > const &labels, int first=1)
Sets all the labels starting with the bin first (1 by default). 
 
TEfficiency & Eff(std::string const &name) const 
 
fhicl::Sequence< unsigned int > MinimumPrimitives
 
std::unique_ptr< ResponseTree > fResponseTree
Handler of ROOT tree output. 
 
TensorIndices class to flatten multi-dimension indices into linear. 
 
bool hasLocation() const 
Returns if the location of the trigger is set (undefined if !fired()). 
 
std::string const & name() const 
Returns the sandbox name. 
 
std::unique_ptr< bool[]> RespTxxRxx
 
TH1 & Hist(std::string const &name) const 
 
Helper data structure to store transient trigger result. 
 
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration. 
 
timescale_traits< OpticalTimeCategory >::tick_interval_t optical_time_ticks
 
icarus::trigger::TrackedOpticalTriggerGate< sbn::OpDetWaveformMeta > InputTriggerGate_t
Type of trigger gate extracted from the input event. 
 
std::vector< WorkingTriggerGate_t > combineTriggerPrimitives(TriggerGatesPerCryostat_t const &cryoGates, std::string const &threshold) const 
Computes the trigger response from primitives with the given threshold. 
 
MajorityTriggerEfficiencyPlots(Parameters const &config)
 
Information about the event. 
 
Converts a tensor element specification into a linear index. 
 
electronics_time toElectronicsTime(FromTime time) const 
Converts a time point into electronics time scale. 
 
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string. 
 
void plotResponses(std::size_t iThr, std::string const &threshold, PlotSandboxRefs_t const &plotSets, EventInfo_t const &eventInfo, detinfo::DetectorClocksData const &clockData, std::vector< WorkingTriggerGate_t > const &combinedCounts, std::vector< ChannelID_t > const &channelList)
Completes the event trigger simulation and fills the plots. 
 
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type. 
 
A bunch of diverse utilities and futilities related to ROOT. 
 
virtual void simulateAndPlot(std::size_t const thresholdIndex, TriggerGatesPerCryostat_t const &gates, EventInfo_t const &eventInfo, detinfo::DetectorClocksData const &clockData, PlotSandboxRefs_t const &selectedPlots) override
Simulates all trigger minimum requirements plots the results. 
 
MajorityTriggerEfficiencyPlots & helper()
 
std::vector< PlotDef > plots
 
Utilities for the conversion of trigger gate data formats. 
 
BEGIN_PROLOG vertical distance to the surface Name
 
Helper data structure to store PMT activity information in the event. 
 
Simple class holding a tree. 
 
auto sumGates(GateColl const &gates)
Sums all the gates in a collection. 
 
Base class for _art_modules plotting trigger efficiencies. 
 
util::MatrixIndices indices
 
virtual void analyze(art::Event const &event) override
Fills the plots. Also extracts the information to fill them with. 
 
MajorityTriggerEfficiencyPlots const & helper() const 
Access to the helper. 
 
A wrapper to trigger gate objects tracking the contributions. 
 
art::EDAnalyzer::Table< Config > Parameters
 
optical_tick atTick() const 
Returns the time of the trigger (undefined if !fired()). 
 
Contains all timing reference information for the detector. 
 
std::string to_string(WindowPattern const &pattern)
 
then echo File list $list not found else cat $list while read file do echo $file sed s
 
A class exposing an upgraded interface of detinfo::DetectorClocksData. 
 
Data types for detinfo::DetectorTimings. 
 
Functions pulling in STL customization if available. 
 
Selected information about the event. 
 
std::vector< std::reference_wrapper< PlotSandbox const  >> PlotSandboxRefs_t
List of references to plot sandboxes. 
 
Opening_t level() const 
Returns the opening level of the trigger (undefined if !fired()). 
 
virtual void initializePlots(PlotCategories_t categories, std::vector< SettingsInfo_t > const &settings)
Initializes all the plot sets, one per PMT threshold. 
 
std::vector< TriggerGates_t > TriggerGatesPerCryostat_t
Type of lists of gates, one list per cryostat (outer index: cryostat no). 
 
MajorityTriggerEfficiencyPlots & operator=(MajorityTriggerEfficiencyPlots const &)=delete
 
detinfo::timescales::optical_tick optical_tick
 
void add(OpeningInfo_t info)
 
A helper to manage ROOT objects in a art::TFileDirectory. 
 
std::size_t nTriggers() const 
Returns the number of registered triggers. 
 
The data type to uniquely identify a cryostat. 
 
A helper to manage ROOT objects with consistent naming. 
 
decltype(auto) gateIn(Gate &&gate)
Returns the trigger gate (a ReadoutTriggerGate) from the specified gate. 
 
Produces plots about trigger simulation and trigger efficiency.