All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SlidingWindowTriggerSimulation_module.cc
Go to the documentation of this file.
1 /**
2  * @file SlidingWindowTriggerSimulation_module.cc
3  * @brief Production of triggers data products based on PMT sliding windows.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date March 27, 2021
6  */
7 
8 
9 // ICARUS libraries
11 #include "icaruscode/PMT/Trigger/Algorithms/WindowTopologyAlg.h" // WindowTopologyManager
19 #include "icaruscode/PMT/Trigger/Utilities/TriggerDataUtils.h" // FillTriggerGates()
21 #include "icaruscode/IcarusObj/OpDetWaveformMeta.h" // sbn::OpDetWaveformMeta
22 #include "icarusalg/Utilities/ROOTutils.h" // util::ROOT
24 #include "icaruscode/Utilities/DetectorClocksHelpers.h" // makeDetTimings()...
27 #include "icarusalg/Utilities/ChangeMonitor.h" // ThreadSafeChangeMonitor
28 #include "icarusalg/Utilities/rounding.h" // icarus::ns::util::roundup()
29 
30 // LArSoft libraries
33 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
36 #include "lardataalg/DetectorInfo/DetectorTimingTypes.h" // optical_tick...
37 #include "lardataalg/Utilities/quantities/spacetime.h" // microseconds, ...
38 #include "lardataalg/Utilities/intervals_fhicl.h" // microseconds from FHiCL
42 #include "larcorealg/CoreUtils/values.h" // util::const_values()
43 #include "larcorealg/CoreUtils/get_elements.h" // util::get_elements()
45 #include "larcorealg/CoreUtils/StdUtils.h" // util::to_string()
46 #include "lardataobj/RawData/TriggerData.h" // raw::Trigger
47 #include "lardataobj/RawData/OpDetWaveform.h" // raw::ADC_Count_t
48 #include "larcoreobj/SimpleTypesAndConstants/geo_types.h" // geo::CryostatID
49 
50 // framework libraries
51 #include "art_root_io/TFileService.h"
52 #include "art_root_io/TFileDirectory.h"
53 #include "art/Framework/Services/Registry/ServiceHandle.h"
54 #include "art/Framework/Core/EDProducer.h"
55 #include "art/Framework/Core/ModuleMacros.h"
56 #include "art/Framework/Principal/Event.h"
57 #include "canvas/Utilities/InputTag.h"
58 #include "canvas/Utilities/Exception.h"
59 #include "messagefacility/MessageLogger/MessageLogger.h"
60 #include "fhiclcpp/types/Sequence.h"
61 #include "fhiclcpp/types/OptionalAtom.h"
62 #include "fhiclcpp/types/Atom.h"
63 
64 // ROOT libraries
65 #include "TEfficiency.h"
66 #include "TH1F.h"
67 #include "TH2F.h"
68 #include "TGraph.h"
69 
70 // C/C++ standard libraries
71 #include <ostream>
72 #include <algorithm> // std::fill()
73 #include <map>
74 #include <vector>
75 #include <memory> // std::make_unique()
76 #include <string>
77 #include <atomic>
78 #include <optional>
79 #include <utility> // std::pair<>, std::move()
80 #include <cmath> // std::ceil()
81 #include <cstddef> // std::size_t
82 #include <cassert>
83 
84 
85 //------------------------------------------------------------------------------
86 using namespace util::quantities::time_literals;
87 
88 
89 //------------------------------------------------------------------------------
90 namespace icarus::trigger { class SlidingWindowTriggerSimulation; }
91 /**
92  * @brief Simulates a sliding window trigger.
93  *
94  * This module produces `raw::Trigger` objects each representing the outcome of
95  * some trigger logic applied to a discriminated input ("trigger primitives").
96  *
97  * A trigger primitive is a two-level function of time which describes when
98  * that primitive is on and when it is off. Trigger primitives are given as
99  * input to this module and their origin may vary, but the standard source in
100  * ICARUS is @ref ICARUSPMTTriggerGlossary "single trigger request (LVDS)".
101  *
102  * This module applies a sliding window pattern to the input: the pattern
103  * consists of a requirement on the main window and optional additional
104  * requirements on the neighbouring windows. This module rebases the configured
105  * pattern on each of the available windows, evaluates the requirement of the
106  * pattern in that configuration, and decides whether those requirements are
107  * met. The general trigger is considered passed if _any_ of the rebased
108  * patterns satisfies the requirement at any time, and no special treatment is
109  * performed in case multiple windows fulfil them, except that the trigger time
110  * is driven by the earliest of the satisfied patterns.
111  *
112  * A single trigger pattern is configured for each instance of the module,
113  * while multiple input sets (e.g. with different discrimination thresholds)
114  * can be processed on the same pattern by the same module instance.
115  * Conversely, testing a different pattern requires the instantiation of a new
116  * module.
117  *
118  *
119  * Configuration
120  * ==============
121  *
122  * * `TriggerGatesTag` (string, mandatory): name of the module instance which
123  * produced the trigger primitives to be used as input; it must not include
124  * any instance name, as the instance names will be automatically added from
125  * `Thresholds` parameter.
126  * The typical trigger primitives used as input are LVDS discriminated
127  * output combined into trigger windows (e.g. from
128  * `icarus::trigger::SlidingWindowTrigger` module).
129  * * `Thresholds` (list of names, mandatory): list of the discrimination
130  * thresholds to consider. A data product containing a digital signal is
131  * read for each one of the thresholds, and the tag of the data product is
132  * expected to be the instance name in this configuration parameter for the
133  * module label set in `TriggerGatesTag` (e.g. for a threshold of
134  * `"60"`, supposedly 60 ADC counts, and with `TriggerGatesTag` set to
135  * `"TrigSlidingWindows"`, the data product tag would be
136  * `TrigSlidingWindows:60`).
137  * * `KeepThresholdName` (flag, optional): by default, output data products have
138  * each an instance name according to their threshold (from the `Threshold`
139  * parameter), unless there is only one threshold specified. If this
140  * parameter is specified as `true`, the output data product always
141  * includes the threshold instance name, even when there is only one
142  * threshold specified. If this parameter is specified as `false`, if there
143  * is only one threshold the default behaviour (of not adding an instance
144  * name) is confirmed; otherwise, it is a configuration error to have this
145  * parameter set to `false`.
146  * * `Pattern` (configuration table, mandatory): describes the sliding window
147  * pattern; the configuration format for a pattern is described under
148  * `icarus::trigger::ns::fhicl::WindowPatternConfig`.
149  * * `BeamGateDuration` (time, _mandatory_): the duration of the beam
150  * gate; _the time requires the unit to be explicitly specified_: use
151  * `"1.6 us"` for BNB, `9.5 us` for NuMI (also available as
152  * `BNB_settings.spill_duration` and `NuMI_settings.spill_duration` in
153  * `trigger_icarus.fcl`);
154  * * `BeamGateStart` (time, default: `0_us`): how long after the
155  * * @ref DetectorClocksBeamGateOpening "nominal beam gate opening time"
156  * the actual beam gate opens at;
157  * * `BeamBits` (bitmask as 32-bit integral number): bits to be set in the
158  * produced `raw::Trigger` objects (see also `daq::TriggerDecoder` tool).
159  * * `LogCategory` (string, default `SlidingWindowTriggerSimulation`): name of
160  * category used to stream messages from this module into message facility.
161  *
162  * An example job configuration is provided as
163  * `simulate_sliding_window_trigger_icarus.fcl`.
164  *
165  *
166  * Output data products
167  * =====================
168  *
169  * * `std::vector<raw::Trigger>` (one instance per ADC threshold):
170  * list of triggers fired according to the configured trigger definition;
171  * there is one collection (and data product) per ADC threshold, and the
172  * data product has the same instance name as the input data one, unless
173  * there is only one threshold (see `TriggerGatesTag`, `Thresholds` and
174  * `KeepThresholdName` configuration parameters);
175  * currently only at most one trigger is emitted, with time stamp matching
176  * the first time the trigger criteria are satisfied. All triggers feature
177  * the bits specified in `BeamBits` configuration parameter.
178  *
179  *
180  *
181  * Trigger logic algorithm
182  * ========================
183  *
184  * @anchor SlidingWindowTriggerSimulation_Algorithm
185  *
186  * This section describes the trigger logic algorithm used in
187  * `icarus::trigger::SlidingWindowTriggerSimulation` and its assumptions.
188  * Nevertheless, more up-to-date information can be found in
189  * `SlidingWindowTrigger` module (for the combination of the LVDS signals into
190  * window-wide gates) and in `icarus::trigger::SlidingWindowPatternAlg`,
191  * which applies the configured pattern logic to the input.
192  *
193  * The module receives as input a multi-level trigger gate for each of the
194  * windows to be considered.
195  * On the first input (i.e. the first event), that input is parsed to learn
196  * the windows and their relative position from the input trigger gates.
197  * This topology will be used to apply the configured patterns. On the following
198  * events, their input is checked to confirm the compatibility of the
199  * composition of its windows with the one from that first event (both aspects
200  * are handled by an `icarus::trigger::WindowTopologyManager` object).
201  *
202  * All multi-level gates are set in coincidence with the beam gate by
203  * multiplying the multi-level and the beam gates. Because of this, trigger
204  * gates are suppressed everywhere except than during the beam gate.
205  * The beam gate opens at a time configured in `DetectorClocks` service provider
206  * (`detinfo::DetectorClocks::BeamGateTime()`), optionally offset
207  * (`BeamGateStart`), and has a duration configured in this module
208  * (`BeamGateDuration`).
209  *
210  * The algorithm handles independently multiple trigger patterns.
211  * On each input, each configured pattern is applied based on the window
212  * topology. Each pattern describes a minimum level of the trigger
213  * gate in the window, that usually means the number of LVDS signals in
214  * coincidence at any given time ("majority"). A pattern may have requirements
215  * on the neighbouring windows in addition to the main one. The pattern is
216  * satisfied if all involved windows pass their specific requirements at the
217  * same time (coincidence between windows).
218  * Each pattern is applied in turn to each of the windows (which is the "main"
219  * window). The neighborhood described in the pattern is applied with respect to
220  * that main window. The trigger fires if one or more of the windows satisfy
221  * the pattern, and the trigger time is the one of the earliest satisfied
222  * pattern (more precisely, the earliest tick when the coincidence required
223  * by that pattern is satisfied).*
224  * All windows in the detector are considered independently, but the supported
225  * patterns may only include components in the same cryostat. Therefore,
226  * triggers are effectively on a single cryostat.
227  * An object of class `icarus::trigger::SlidingWindowPatternAlg` applies this
228  * logic: see its documentation for the most up-to-date details.
229  *
230  * Eventually, for each event there are as many different trigger responses as
231  * how many different patterns are configured (`Patterns` configuration
232  * parameter), _times_ how many ADC thresholds are provided in input,
233  * configured in `Thresholds`.
234  *
235  *
236  * Technical aspects of the module
237  * --------------------------------
238  *
239  * @anchor SlidingWindowTriggerSimulation_Tech
240  *
241  * This module does not build the trigger gates of the sliding windows, but
242  * rather it takes them as input (see e.g. `SlidingWindowTrigger` module).
243  * Window topology (size of the windows and their relations) is stored in
244  * `icarus::trigger::WindowChannelMap` objects, and its construction is
245  * delegated to `icarus::trigger::WindowTopologyAlg` (under the hood of the
246  * `WindowTopologyManager` class) which learns it from the actual trigger gate
247  * input rather than on explicit configuration. Pattern definitions and
248  * configuration are defined in `icarus::trigger::WindowPattern` and
249  * `icarus::trigger::ns::fhicl::WindowPatternConfig` respectively. Trigger
250  * simulation is delegated to `icarus::trigger::SlidingWindowPatternAlg`.
251  *
252  */
254  : public art::EDProducer
256 {
257 
258  public:
259 
262 
263 
264  // --- BEGIN Configuration ---------------------------------------------------
265  struct Config {
266 
267  using Name = fhicl::Name;
268  using Comment = fhicl::Comment;
269 
270  fhicl::Atom<std::string> TriggerGatesTag {
271  Name("TriggerGatesTag"),
272  Comment("label of the input trigger gate data product (no instance name)")
273  };
274 
275  fhicl::Sequence<std::string> Thresholds {
276  Name("Thresholds"),
277  Comment("tags of the thresholds to consider")
278  };
279 
280  fhicl::OptionalAtom<bool> KeepThresholdName {
281  Name("KeepThresholdName"),
282  Comment
283  ("add threshold to output product tag even with only one threshold")
284  };
285 
287  Name("Pattern"),
288  Comment("trigger requirements as a trigger window pattern")
289  };
290 
291  fhicl::Atom<microseconds> BeamGateDuration {
292  Name("BeamGateDuration"),
293  Comment("length of time interval when optical triggers are accepted")
294  };
295 
296  fhicl::Atom<microseconds> BeamGateStart {
297  Name("BeamGateStart"),
298  Comment("open the beam gate this long after the nominal beam gate time"),
299  microseconds{ 0.0 }
300  };
301 
302  fhicl::Atom<std::uint32_t> BeamBits {
303  Name("BeamBits"),
304  Comment("bits to be set in the trigger object as beam identified")
305  };
306 
307  fhicl::Atom<nanoseconds> TriggerTimeResolution {
308  Name("TriggerTimeResolution"),
309  Comment("resolution of trigger in time"),
310  25_ns
311  };
312 
313  fhicl::Atom<double> EventTimeBinning {
314  Name("EventTimeBinning"),
315  Comment("binning for the trigger time plot [second]"),
316  300 // 5 minutes
317  };
318 
319  fhicl::Atom<std::string> LogCategory {
320  Name("LogCategory"),
321  Comment("name of the category used for the output"),
322  "SlidingWindowTriggerSimulation" // default
323  };
324 
325  }; // struct Config
326 
327  using Parameters = art::EDProducer::Table<Config>;
328  // --- END Configuration -----------------------------------------------------
329 
330 
331  // --- BEGIN Constructors ----------------------------------------------------
332  explicit SlidingWindowTriggerSimulation(Parameters const& config);
333 
334  // --- END Constructors ------------------------------------------------------
335 
336 
337  // --- BEGIN Framework hooks -------------------------------------------------
338 
339  /// Initializes the plots.
340  virtual void beginJob() override;
341 
342  /// Runs the simulation and saves the results into the _art_ event.
343  virtual void produce(art::Event& event) override;
344 
345  /// Prints end-of-job summaries.
346  virtual void endJob() override;
347 
348  // --- END Framework hooks ---------------------------------------------------
349 
350 
351  private:
352 
353  using TriggerInfo_t = details::TriggerInfo_t; ///< Type alias.
354 
355  /// Type of trigger gate extracted from the input event.
356  using InputTriggerGate_t
358 
359  /// List of trigger gates.
360  using TriggerGates_t
362 
363  /// Data structure to communicate internally a trigger response.
364  using WindowTriggerInfo_t
366 
367  /// Content for future histograms, binned.
369 
370  /// All information needed to generate plots for a specific threshold.
376  };
377 
378 
379  // --- BEGIN Configuration variables -----------------------------------------
380 
381  /// Name of ADC thresholds to read, and the input tag connected to their data.
382  std::map<std::string, art::InputTag> fADCthresholds;
383 
384  /// Configured sliding window requirement pattern.
386 
387  /// Duration of the gate during with global optical triggers are accepted.
389 
390  /// Start of the beam gate with respect to `BeamGate()`.
392 
393  std::uint32_t fBeamBits; ///< Bits for the beam gate being simulated.
394 
395  nanoseconds fTriggerTimeResolution; ///< Trigger resolution in time.
396 
397  double fEventTimeBinning; ///< Trigger time plot binning [s]
398 
399  /// Message facility stream category for output.
400  std::string const fLogCategory;
401 
402  // --- END Configuration variables -------------------------------------------
403 
404 
405  // --- BEGIN Service variables -----------------------------------------------
406 
407  /// ROOT directory where all the plots are written.
408  art::TFileDirectory fOutputDir;
409 
410  // --- END Service variables -------------------------------------------------
411 
412 
413  // --- BEGIN Internal variables ----------------------------------------------
414 
415  /// Output data product instance names (same order as `fADCthresholds`).
416  std::vector<std::string> fOutputInstances;
417 
418  /// Mapping of each sliding window with location and topological information.
419  // mutable = not thread-safe
421 
422  /// Pattern algorithm.
423  std::optional<icarus::trigger::SlidingWindowPatternAlg> fPatternAlg;
424 
425  /// All plots in one practical sandbox.
427 
428  /// Proto-histogram information in a convenient packet; event-wide.
430 
431  /// Proto-histogram information in a not-so-practical array; per threshold.
432  std::vector<ThresholdPlotInfo_t> fThresholdPlots;
433 
434  ///< Count of fired triggers, per threshold.
435  std::vector<std::atomic<unsigned int>> fTriggerCount;
436  std::atomic<unsigned int> fTotalEvents { 0U }; ///< Count of opened gates.
437 
438 
439  /// Functor returning whether a gate has changed.
442 
443  // --- END Internal variables ------------------------------------------------
444 
445 
446  // --- BEGIN --- Plot infrastructure -----------------------------------------
447 
448  /// @brief Initializes the full set of plots (all ADC thresholds).
449  void initializePlots();
450 
451  /// Creates summary plots from proto-histogram data.
452  void finalizePlots();
453 
454  /// Creates in `plots` sandbox all plots for threshold `threshold` from data
455  /// in `plotInfo`.
456  void makeThresholdPlots(
457  std::string const& threshold,
459  ThresholdPlotInfo_t const& plotInfo
460  );
461 
462  /// Creates in the main sandbox all event-wide plots.
463  void makeEventPlots();
464 
465  /// Fills event-wide plots.
466  void plotEvent
467  (art::Event const& event, detinfo::DetectorTimings const& detTimings);
468 
469  /// Fills the plots for threshold index `iThr` with trigger information.
470  void plotTriggerResponse(
471  std::size_t iThr, std::string const& thrTag,
472  WindowTriggerInfo_t const& triggerInfo,
474  );
475 
476  // --- END ----- Plot infrastructure -----------------------------------------
477 
478  /**
479  * @brief Performs the simulation for the specified ADC threshold.
480  * @param event _art_ event to read data from and put results into
481  * @param iThr index of the threshold in the configuration
482  * @param thr value of the threshold (ADC counts)
483  * @return the trigger response information
484  *
485  * For the given threshold, the simulation of the configured trigger is
486  * performed.
487  * The input data is read from the event (the source tag is from the module
488  * configuration), simulation is performed, auxiliary plots are drawn and
489  * a `raw::Trigger` collection is stored into the event.
490  *
491  * The stored collection contains either one or zero `raw::Trigger` elements.
492  *
493  * The simulation itself is performed by the `simulate()` method.
494  */
495  WindowTriggerInfo_t produceForThreshold(
496  art::Event& event,
498  ApplyBeamGateClass const& beamGate,
499  std::size_t const iThr, std::string const& thrTag
500  );
501 
502  /**
503  * @brief Converts the trigger information into a `raw::Trigger` object.
504  * @param triggerNumber the unique number to assign to this trigger
505  * @param info the information about the fired trigger
506  * @return a `raw::Trigger` object with all the information encoded
507  *
508  * The trigger described by `info` is encoded into a `raw::Trigger` object.
509  * The trigger _must_ have fired.
510  */
511  raw::Trigger triggerInfoToTriggerData(
513  unsigned int triggerNumber, WindowTriggerInfo_t const& info
514  ) const;
515 
516 
517  /// Prints the summary of fired triggers on screen.
518  void printSummary() const;
519 
520  /// Creates and returns a 1D histogram filled with `binnedContent`.
521  TH1* makeHistogramFromBinnedContent(
523  std::string const& name, std::string const& title,
524  BinnedContent_t const& binnedContent
525  ) const;
526 
527  //@{
528  /// Shortcut to create an `ApplyBeamGate` with the current configuration.
531  {
532  return makeApplyBeamGate(
533  fBeamGateDuration, fBeamGateStart,
534  std::move(data),
536  );
537  }
539  (art::Event const* event = nullptr) const
540  { return makeMyBeamGate(icarus::ns::util::makeDetClockData(event)); }
542  (art::Event const& event) const { return makeMyBeamGate(&event); }
543  //@}
544 
545 
546  /// Reads a set of input gates from the `event`
547  /// @return trigger gates, converted into `InputTriggerGate_t`
548  static TriggerGates_t readTriggerGates
549  (art::Event const& event, art::InputTag const& dataTag);
550 
551  //@{
552  /// Returns the time of the event in seconds from The Epoch.
553  static double eventTimestampInSeconds(art::Timestamp const& time);
554  static double eventTimestampInSeconds(art::Event const& event);
555  //@}
556 
557 }; // icarus::trigger::SlidingWindowTriggerSimulation
558 
559 
560 
561 //------------------------------------------------------------------------------
562 //--- Implementation
563 //------------------------------------------------------------------------------
565  (Parameters const& config)
566  : art::EDProducer (config)
567  // configuration
568  , fPattern (config().Pattern())
569  , fBeamGateDuration (config().BeamGateDuration())
570  , fBeamGateStart (config().BeamGateStart())
571  , fBeamBits (config().BeamBits())
572  , fTriggerTimeResolution(config().TriggerTimeResolution())
573  , fEventTimeBinning (config().EventTimeBinning())
574  , fLogCategory (config().LogCategory())
575  // services
576  , fOutputDir (*art::ServiceHandle<art::TFileService>())
577  // internal and cached
578  , fWindowMapMan
579  { *lar::providerFrom<geo::Geometry>(), fLogCategory + "_WindowMapManager" }
580  , fPlots(
581  fOutputDir, "", "requirement: " + fPattern.description()
582  )
583  , fEventPlotInfo{
584  BinnedContent_t{ fEventTimeBinning } // eventTimes
585  , BinnedContent_t{ // HWtrigTimeVsBeam
586  fTriggerTimeResolution.convertInto
587  <detinfo::timescales::trigger_time::interval_t>().value()
588  }
589  , BinnedContent_t{ // triggerTimesVsHWtrig
590  fTriggerTimeResolution.convertInto
591  <detinfo::timescales::trigger_time::interval_t>().value()
592  }
593  , BinnedContent_t{ // triggerTimesVsBeam
594  fTriggerTimeResolution.convertInto
595  <detinfo::timescales::trigger_time::interval_t>().value()
596  }
597  }
598 {
599 
600  //
601  // more complex parameter parsing
602  //
603  std::string const& discrModuleLabel = config().TriggerGatesTag();
604  for (std::string const& threshold: config().Thresholds())
605  fADCthresholds[threshold] = art::InputTag{ discrModuleLabel, threshold };
606 
607  // initialization of a vector of atomic is not as trivial as it sounds...
608  fTriggerCount = std::vector<std::atomic<unsigned int>>(fADCthresholds.size());
609  std::fill(fTriggerCount.begin(), fTriggerCount.end(), 0U);
610 
611  //
612  // input data declaration
613  //
614  using icarus::trigger::OpticalTriggerGateData_t; // for convenience
615 
616  // trigger primitives
617  for (art::InputTag const& inputDataTag: util::const_values(fADCthresholds)) {
618  consumes<std::vector<OpticalTriggerGateData_t>>(inputDataTag);
619  consumes<art::Assns<OpticalTriggerGateData_t, sbn::OpDetWaveformMeta>>
620  (inputDataTag);
621  } // for
622 
623  //
624  // output data declaration
625  //
626  // keepThresholdName is true if we write instance name in output data products
627  bool const keepThresholdName
628  = config().KeepThresholdName().value_or(config().Thresholds().size() > 1);
629  if (!keepThresholdName && (config().Thresholds().size() > 1)) {
630  throw art::Exception(art::errors::Configuration)
631  << config().KeepThresholdName.name()
632  << " can be set to `true` only when a single threshold is specified ("
633  << config().Thresholds.name() << " has " << config().Thresholds().size()
634  << ")";
635  }
636 
637  for (auto const& inputDataTag: util::const_values(fADCthresholds)) {
638  std::string const outputInstance
639  = keepThresholdName? inputDataTag.instance(): "";
640  produces<std::vector<raw::Trigger>>(outputInstance);
641  fOutputInstances.push_back(outputInstance);
642  }
643 
644  {
645  mf::LogInfo log(fLogCategory);
646  log << "\nConfigured " << fADCthresholds.size() << " thresholds (ADC):";
647  for (auto const& [ thresholdTag, dataTag ]: fADCthresholds)
648  log << "\n * " << thresholdTag << " (from '" << dataTag.encode() << "')";
649 
650  } // local block
651 
652 
653 } // icarus::trigger::SlidingWindowTriggerSimulation::SlidingWindowTriggerSimulation()
654 
655 
656 //------------------------------------------------------------------------------
658 
659  initializePlots();
660 
661 } // icarus::trigger::SlidingWindowTriggerSimulation::beginJob()
662 
663 
664 //------------------------------------------------------------------------------
666 {
667 
668  detinfo::DetectorClocksData const clockData
669  = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(event);
670  detinfo::DetectorTimings const detTimings{clockData};
671  auto const beamGate = makeMyBeamGate(clockData);
672 
673  if (auto oldGate = fGateChangeCheck(beamGate); oldGate) {
674  MF_LOG_DEBUG(fLogCategory)
675  << "Beam gate has changed from " << *oldGate << " to " << beamGate;
676  }
677 
678 
679  mf::LogDebug log(fLogCategory); // this will print at the end of produce()
680  log << "Event " << event.id() << ":";
681 
682  for (auto const& [ iThr, thrTag ]
683  : util::enumerate(util::get_elements<0U>(fADCthresholds))
684  ) {
685 
686  WindowTriggerInfo_t const triggerInfo
687  = produceForThreshold(event, detTimings, beamGate, iThr, thrTag);
688 
689  log << "\n * threshold " << thrTag << ": ";
690  if (triggerInfo) log << "trigger at " << triggerInfo.info.atTick();
691  else log << "not triggered";
692 
693  } // for
694 
695  plotEvent(event, detTimings);
696 
697  ++fTotalEvents;
698 
699 } // icarus::trigger::SlidingWindowTriggerSimulation::produce()
700 
701 
702 //------------------------------------------------------------------------------
704 
705  finalizePlots();
706 
707  printSummary();
708 
709 } // icarus::trigger::SlidingWindowTriggerSimulation::endJob()
710 
711 
712 //------------------------------------------------------------------------------
714 
715  //
716  // overview plots with different settings
717  //
718 
719  std::vector<std::string> thresholdLabels;
720  thresholdLabels.reserve(size(fADCthresholds));
721  for (std::string thr: util::get_elements<0U>(fADCthresholds))
722  thresholdLabels.push_back(std::move(thr));
723 
724  auto const beamGate = makeMyBeamGate();
725  fGateChangeCheck(beamGate);
726  mf::LogInfo(fLogCategory)
727  << "Beam gate for plots: " << beamGate.asSimulationTime()
728  << " (simulation time), " << beamGate.tickRange()
729  << " (optical ticks)"
730  ;
731 
732  //
733  // Triggering efficiency vs. ADC threshold.
734  //
735  auto* NTriggers = fPlots.make<TH1F>(
736  "NTriggers",
737  "Number of triggering events"
738  ";PMT discrimination threshold [ ADC counts ]"
739  ";events",
740  thresholdLabels.size(), 0.0, double(thresholdLabels.size())
741  );
742  util::ROOT::applyAxisLabels(NTriggers->GetXaxis(), thresholdLabels);
743 
744  auto* Eff = fPlots.make<TEfficiency>(
745  "Eff",
746  "Triggering pass fraction"
747  ";PMT discrimination threshold [ ADC counts ]"
748  ";trigger pass fraction",
749  thresholdLabels.size(), 0.0, double(thresholdLabels.size())
750  );
751  // people are said to have earned hell for things like this;
752  // but TEfficiency really does not expose the interface to assign labels to
753  // its axes, which supposedly could be done had we chosen to create it by
754  // histograms instead of directly as recommended.
756  (const_cast<TH1*>(Eff->GetTotalHistogram())->GetXaxis(), thresholdLabels);
757 
758  detinfo::timescales::optical_time_ticks const triggerResolutionTicks{
759  icarus::ns::util::makeDetTimings().toOpticalTicks(fTriggerTimeResolution)
760  };
761 
762  auto const& beamGateTicks = beamGate.tickRange();
763  auto* TrigTime = fPlots.make<TH2F>(
764  "TriggerTick",
765  "Trigger time tick"
766  ";optical time tick [ /" + util::to_string(triggerResolutionTicks) + " ]"
767  ";PMT discrimination threshold [ ADC counts ]"
768  ";events",
769  static_cast<int>(std::ceil(beamGate.lengthTicks()/triggerResolutionTicks)),
770  beamGateTicks.start().value(),
772  (beamGateTicks.start() + beamGate.lengthTicks(), triggerResolutionTicks)
773  .value(),
774  thresholdLabels.size(), 0.0, double(thresholdLabels.size())
775  );
776  util::ROOT::applyAxisLabels(TrigTime->GetYaxis(), thresholdLabels);
777 
778 
779  // we allow some fixed margin in the plot, just in case:
780  constexpr microseconds beamPlotPadding { 4_us };
781 
783 
784  // hardware trigger may happen at any place within the beam gate,
785  // and in this plot range I want to include the full beam gate;
786  // so I take a beam gate worth of time before the trigger time,
787  // and as much after it; since this plot is relative to the hardware trigger,
788  // the hardware trigger time itself is 0
789  icarus::ns::util::BinningSpecs const HWtrigBinning = alignBinningTo(
791  (- beamGate.length() - beamPlotPadding).value(),
792  (beamGate.length() + beamPlotPadding).value(),
793  fTriggerTimeResolution.convertInto<trigger_time::interval_t>().value()
794  },
795  0.0
796  );
797  fPlots.make<TH2F>(
798  "TriggerTimeVsHWTrig",
799  "Time of the trigger"
800  ";trigger time (relative to hardware trigger) [ #mus ]"
801  ";PMT discrimination threshold [ ADC counts ]"
802  ";triggers",
803  HWtrigBinning.nBins(), HWtrigBinning.lower(), HWtrigBinning.upper(),
804  thresholdLabels.size(), 0.0, double(thresholdLabels.size())
805  );
806 
807  icarus::ns::util::BinningSpecs const beamGateBinning = alignBinningTo(
809  (-beamPlotPadding).value(),
810  (beamGate.length() + beamPlotPadding).value(),
811  fTriggerTimeResolution.convertInto<trigger_time::interval_t>().value()
812  },
813  0.0
814  );
815  fPlots.make<TH2F>(
816  "TriggerTimeVsBeamGate",
817  "Time of the trigger"
818  ";trigger time (relative to beam gate opening) [ #mus ]"
819  ";PMT discrimination threshold [ ADC counts ]"
820  ";triggers",
821  beamGateBinning.nBins(), beamGateBinning.lower(), beamGateBinning.upper(),
822  thresholdLabels.size(), 0.0, double(thresholdLabels.size())
823  );
824 
825  //
826  // per-threshold plots; should this initialization be set into its own method?
827  //
828  for (auto const& [ thr, info ]
829  : util::zip(util::get_elements<0U>(fADCthresholds), fThresholdPlots))
830  {
832  = fPlots.addSubSandbox("Thr" + thr, "Threshold: " + thr);
833 
834  plots.make<TGraph>(
835  "TriggerTimeVsHWTrigVsBeam",
836  "Time of the trigger: emulated vs. hardware"
837  ";hardware trigger time (relative to beam gate opening) [ #mus ]"
838  ";emulated trigger time (relative to beam gate opening) [ #mus ]"
839  );
840 
841  } // for thresholds
842 
843  fThresholdPlots.resize(
844  size(fADCthresholds),
845  {
846  BinnedContent_t{ fEventTimeBinning }, // eventTimes
847  BinnedContent_t{ HWtrigBinning.binWidth() }, // HWtrigTimeVsBeam
848  BinnedContent_t{ HWtrigBinning.binWidth() }, // triggerTimesVsHWtrig
849  BinnedContent_t{ beamGateBinning.binWidth() } // triggerTimesVsBeam
850  }
851  );
852 
853 } // icarus::trigger::SlidingWindowTriggerSimulation::initializePlots()
854 
855 
856 //------------------------------------------------------------------------------
858 
859  for (auto const& [ thr, info ]
860  : util::zip(util::get_elements<0U>(fADCthresholds), fThresholdPlots))
861  {
862  icarus::trigger::PlotSandbox& plots = fPlots.demandSandbox("Thr" + thr);
863  makeThresholdPlots(thr, plots, info);
864  if (plots.empty()) fPlots.deleteSubSandbox(plots.name());
865  } // for thresholds
866 
867  makeEventPlots();
868 
869 } // icarus::trigger::SlidingWindowTriggerSimulation::finalizePlots()
870 
871 
872 //------------------------------------------------------------------------------
874  std::string const& threshold,
876  ThresholdPlotInfo_t const& plotInfo
877 ) {
878 
879  BinnedContent_t const* content;
880 
881  content = &(plotInfo.eventTimes);
882  makeHistogramFromBinnedContent(plots,
883  "TriggerTime",
884  "Time of the triggered events"
885  ";time"
886  ";triggered events [ / " + std::to_string(content->binWidth())
887  + "\" ]",
888  *content
889  );
890 
891  content = &(plotInfo.HWtrigTimeVsBeam);
892  makeHistogramFromBinnedContent(plots,
893  "HWTrigVsBeam",
894  "Time of the hardware trigger"
895  ";trigger time (relative to beam gate) [ #mus ]"
896  ";events [ / " + std::to_string(content->binWidth())
897  + " #mus ]",
898  *content
899  );
900 
901  content = &(plotInfo.triggerTimesVsHWtrig);
902  makeHistogramFromBinnedContent(plots,
903  "TriggerTimeVsHWTrig",
904  "Time of the trigger"
905  ";trigger time (relative to hardware trigger) [ #mus ]"
906  ";triggers [ / " + std::to_string(content->binWidth())
907  + " #mus ]",
908  *content
909  );
910 
911  content = &(plotInfo.triggerTimesVsBeam);
912  makeHistogramFromBinnedContent(plots,
913  "TriggerTimeVsBeamGate",
914  "Time of the trigger"
915  ";trigger time (relative to beam gate opening) [ #mus ]"
916  ";triggers [ / " + std::to_string(content->binWidth())
917  + " #mus ]",
918  *content
919  );
920 
921 } // icarus::trigger::SlidingWindowTriggerSimulation::makeThresholdPlots()
922 
923 
924 
925 //------------------------------------------------------------------------------
927 
928  BinnedContent_t const* content;
929 
930  content = &(fEventPlotInfo.eventTimes);
931  makeHistogramFromBinnedContent(fPlots,
932  "EventTime",
933  "Time of the events"
934  ";time"
935  ";events [ / " + std::to_string(content->binWidth())
936  + "\" ]",
937  *content
938  );
939 
940  content = &(fEventPlotInfo.HWtrigTimeVsBeam);
941  makeHistogramFromBinnedContent(fPlots,
942  "HWTrigVsBeam",
943  "Time of the hardware trigger"
944  ";trigger time (relative to beam gate) [ #mus ]"
945  ";events [ / " + std::to_string(content->binWidth())
946  + " #mus ]",
947  *content
948  );
949 
950 } // icarus::trigger::SlidingWindowTriggerSimulation::makeEventPlots()
951 
952 
953 //------------------------------------------------------------------------------
955  art::Event& event,
957  ApplyBeamGateClass const& beamGate,
958  std::size_t const iThr, std::string const& thrTag
959 ) -> WindowTriggerInfo_t {
960 
961  auto& plotInfo = fThresholdPlots[iThr];
962 
963  //
964  // get the input
965  //
966  art::InputTag const& dataTag = fADCthresholds.at(thrTag);
967  auto const& gates = readTriggerGates(event, dataTag);
968 
969 
970  // extract or verify the topology of the trigger windows
971  if (fWindowMapMan(gates))
972  fPatternAlg.emplace(*fWindowMapMan, fPattern, fLogCategory);
973  assert(fPatternAlg);
974 
975  //
976  // simulate the trigger response
977  //
978  WindowTriggerInfo_t const triggerInfo
979  = fPatternAlg->simulateResponse(beamGate.applyToAll(gates));
980  if (triggerInfo) {
981  ++fTriggerCount[iThr]; // keep the unique count
982  plotInfo.eventTimes.add(eventTimestampInSeconds(event));
983  }
984 
985  //
986  // fill the plots
987  //
988  plotTriggerResponse(iThr, thrTag, triggerInfo, detTimings);
989 
990  //
991  // create and store the data product
992  //
993  auto triggers = std::make_unique<std::vector<raw::Trigger>>();
994  if (triggerInfo.info.fired()) {
995  triggers->push_back
996  (triggerInfoToTriggerData(detTimings, fTriggerCount[iThr], triggerInfo));
997  } // if
998  event.put(std::move(triggers), fOutputInstances[iThr]);
999 
1000  return triggerInfo;
1001 
1002 } // icarus::trigger::SlidingWindowTriggerSimulation::produceForThreshold()
1003 
1004 
1005 //------------------------------------------------------------------------------
1007  (art::Event const& event, detinfo::DetectorTimings const& detTimings)
1008 {
1009 
1010  detinfo::timescales::trigger_time const beamGateTime
1011  { detTimings.toTriggerTime(detTimings.BeamGateTime()) };
1012 
1013  fEventPlotInfo.eventTimes.add(eventTimestampInSeconds(event));
1014  fEventPlotInfo.HWtrigTimeVsBeam.add(-beamGateTime.value());
1015 
1016 } // icarus::trigger::SlidingWindowTriggerSimulation::plotEvent()
1017 
1018 
1019 //------------------------------------------------------------------------------
1021  std::size_t iThr, std::string const& thrTag,
1022  WindowTriggerInfo_t const& triggerInfo,
1023  detinfo::DetectorTimings const& detTimings
1024 ) {
1025 
1026  bool const fired = triggerInfo.info.fired();
1027 
1028  fPlots.demand<TEfficiency>("Eff").Fill(fired, iThr);
1029 
1030  if (fired) {
1031  using namespace detinfo::timescales;
1032 
1033  // time of the beam gate in hardware trigger time scale
1034  trigger_time const beamGateTime
1035  { detTimings.toTriggerTime(detTimings.BeamGateTime()) };
1036 
1037  optical_tick const thisTriggerTick { triggerInfo.info.atTick() };
1038  trigger_time const thisTriggerTimeVsHWtrig
1039  { detTimings.toTriggerTime(thisTriggerTick) };
1040  time_interval const thisTriggerTimeVsBeamGate
1041  { thisTriggerTimeVsHWtrig - beamGateTime };
1042 
1043  mf::LogTrace(fLogCategory)
1044  << "Trigger " << fPattern.tag() << " at tick " << thisTriggerTick
1045  << " (" << thisTriggerTimeVsHWtrig << " vs. HW trigger, "
1046  << thisTriggerTimeVsBeamGate << " vs. beam gate)"
1047  ;
1048 
1049  fPlots.demand<TH1>("NTriggers").Fill(iThr);
1050  fPlots.demand<TH2>("TriggerTick").Fill(thisTriggerTick.value(), iThr);
1051  fPlots.demand<TH2>("TriggerTimeVsHWTrig").Fill
1052  (thisTriggerTimeVsHWtrig.value(), iThr);
1053  fPlots.demand<TH2>("TriggerTimeVsBeamGate").Fill
1054  (thisTriggerTimeVsBeamGate.value(), iThr);
1055 
1056  icarus::trigger::PlotSandbox& plots{ fPlots.demandSandbox("Thr" + thrTag) };
1057 // plots.demand<TGraph>("TriggerTimeVsHWTrigVsBeam").AddPoint( // ROOT 6.24?
1058  TGraph& graph = plots.demand<TGraph>("TriggerTimeVsHWTrigVsBeam");
1059  graph.SetPoint(graph.GetN(),
1060  -beamGateTime.value(), thisTriggerTimeVsBeamGate.value()
1061  );
1062 
1063  ThresholdPlotInfo_t& plotInfo { fThresholdPlots[iThr] };
1064  plotInfo.HWtrigTimeVsBeam.add(-beamGateTime.value());
1065  plotInfo.triggerTimesVsHWtrig.add(thisTriggerTimeVsHWtrig.value());
1066  plotInfo.triggerTimesVsBeam.add(thisTriggerTimeVsBeamGate.value());
1067 
1068  }
1069 
1070 } // icarus::trigger::SlidingWindowTriggerSimulation::plotTriggerResponse()
1071 
1072 
1073 //------------------------------------------------------------------------------
1075 
1076  //
1077  // summary from our internal counters
1078  //
1079  mf::LogInfo log(fLogCategory);
1080  log
1081  << "Summary of triggers for " << fTriggerCount.size()
1082  << " thresholds (ADC) with pattern: " << fPattern.description()
1083  ;
1084  for (auto const& [ count, thr ]
1085  : util::zip(fTriggerCount, util::get_elements<0U>(fADCthresholds)))
1086  {
1087  log << "\n threshold " << thr
1088  << ": " << count;
1089  if (fTotalEvents > 0U) {
1090  log << "/" << fTotalEvents
1091  << " (" << (double(count) / fTotalEvents * 100.0) << "%)";
1092  }
1093  else log << " events triggered";
1094  } // for
1095 
1096 } // icarus::trigger::SlidingWindowTriggerSimulation::printSummary()
1097 
1098 
1099 //------------------------------------------------------------------------------
1102  (detinfo::DetectorTimings const& detTimings,
1103  unsigned int triggerNumber, WindowTriggerInfo_t const& info) const
1104 {
1105  assert(info.info.fired());
1106 
1107  return {
1108  triggerNumber, // counter
1109  double(detTimings.toElectronicsTime(info.info.atTick())), // trigger time
1110  double(detTimings.BeamGateTime()), // beam gate in electronics time scale
1111  fBeamBits // bits
1112  };
1113 
1114 } // icarus::trigger::SlidingWindowTriggerSimulation::triggerInfoToTriggerData()
1115 
1116 
1117 //------------------------------------------------------------------------------
1119  (art::Event const& event, art::InputTag const& dataTag)
1120  -> TriggerGates_t
1121 {
1122 
1123  using icarus::trigger::OpticalTriggerGateData_t; // for convenience
1124 
1125  // currently the associations are a waste of time memory...
1126  auto const& gates
1127  = event.getProduct<std::vector<OpticalTriggerGateData_t>>(dataTag);
1128  auto const& gateToWaveforms = event.getProduct
1129  <art::Assns<OpticalTriggerGateData_t, sbn::OpDetWaveformMeta>>(dataTag);
1130 
1131  try {
1132  return icarus::trigger::FillTriggerGates(gates, gateToWaveforms);
1133  }
1134  catch (cet::exception const& e) {
1135  throw cet::exception("SlidingWindowTriggerSimulation", "", e)
1136  << "Error encountered while reading data products from '"
1137  << dataTag.encode() << "'\n";
1138  }
1139 
1140 } // icarus::trigger::SlidingWindowTriggerSimulation::readTriggerGates()
1141 
1142 
1143 //------------------------------------------------------------------------------
1144 TH1*
1147  std::string const& name, std::string const& title,
1148  BinnedContent_t const& binnedContent
1149 ) const {
1150 
1151  if (binnedContent.empty()) return nullptr;
1152 
1153  TH1* hist = plots.make<TH1F>(
1154  name, title,
1155  binnedContent.nBins(), binnedContent.min(), binnedContent.max()
1156  );
1157 
1158  // directly transfer the content bin by bin
1159  unsigned int total = 0U;
1160  for (auto [ iBin, count ]: util::enumerate(binnedContent)) {
1161  hist->SetBinContent(iBin + 1, count);
1162  total += count;
1163  }
1164  hist->SetEntries(static_cast<double>(total));
1165  return hist;
1166 } // icarus::trigger::SlidingWindowTriggerSimulation::makeHistogramFromBinnedContent
1167 
1168 
1169 //------------------------------------------------------------------------------
1171  (art::Timestamp const& time)
1172 {
1173  // high value: seconds from the Epoch (Jan 1, 1970 UTC?);
1174  // low value: nanoseconds after that the start of that second
1175  return static_cast<double>(time.timeHigh())
1176  + static_cast<double>(time.timeHigh()) * 1e-9;
1177 } // icarus::trigger::SlidingWindowTriggerSimulation::eventTimestampInSeconds()
1178 
1179 
1180 //------------------------------------------------------------------------------
1182  (art::Event const& event)
1183  { return eventTimestampInSeconds(event.time()); }
1184 
1185 
1186 //------------------------------------------------------------------------------
1188 
1189 
1190 //------------------------------------------------------------------------------
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: PlotSandbox.h:701
void plotEvent(art::Event const &event, detinfo::DetectorTimings const &detTimings)
Fills event-wide plots.
icarus::trigger::WindowTopologyManager fWindowMapMan
Mapping of each sliding window with location and topological information.
electronics_time BeamGateTime() const
An empty class that can&#39;t be copied nor moved.
void makeThresholdPlots(std::string const &threshold, icarus::trigger::PlotSandbox &plots, ThresholdPlotInfo_t const &plotInfo)
Utilities related to art service access.
Utilities for the conversion of trigger gate data formats.
Assembles the topology of trigger windows.
Class to extract and verify a window topology from trigger gates.
ApplyBeamGateClass makeApplyBeamGate(util::quantities::intervals::microseconds duration, util::quantities::intervals::microseconds delay, detinfo::DetectorClocksData const &clockData, std::string const &logCategory="ApplyBeamGateClass")
Returns a new ApplyBeamGateClass object with the specified gate.
constexpr T roundup(T const value, U const quantum, T const offset=T{})
Returns the value, rounded up.
Definition: rounding.h:112
Definition of util::get_elements() and util::get_const_elements().
virtual void produce(art::Event &event) override
Runs the simulation and saves the results into the art event.
TH1 * makeHistogramFromBinnedContent(icarus::trigger::PlotSandbox &plots, std::string const &name, std::string const &title, BinnedContent_t const &binnedContent) const
Creates and returns a 1D histogram filled with binnedContent.
Definition of util::enumerate().
A wrapper to trigger gate objects tracking the input of operations.
microseconds_as<> microseconds
Type of time interval stored in microseconds, in double precision.
Definition: spacetime.h:259
Defines classes that can&#39;t be copied nor moved.
Simple utility for human-friendly binning.
std::uint32_t fBeamBits
Bits for the beam gate being simulated.
trigger_time toTriggerTime(FromTime time) const
Converts a time point into trigger time scale.
icarus::trigger::SlidingWindowPatternAlg::TriggerGates_t TriggerGates_t
List of trigger gates.
void printSummary() const
Prints the summary of fired triggers on screen.
Base class facilitating logging to message facility.
BinIndex_t add(Data_t value)
Increases by a unit the count at the bin including value.
Definition: FixedBins.h:338
void finalizePlots()
Creates summary plots from proto-histogram data.
Derivative information from raw::OpDetWaveform data.
Helper to manage a beam gate.
decltype(auto) const_values(Coll &&coll)
Range-for loop helper iterating across the constant values of the specified collection.
Utilities for numerical rounding.
std::map< std::string, art::InputTag > fADCthresholds
Name of ADC thresholds to read, and the input tag connected to their data.
void makeEventPlots()
Creates in the main sandbox all event-wide plots.
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).
Definition: ROOTutils.h:175
Data_t max() const noexcept
Definition: FixedBins.h:422
std::string const & name() const
Returns the sandbox name.
Definition: PlotSandbox.h:196
Helper applying a beam gate to any gate.
Definition: ApplyBeamGate.h:85
double lower() const
Returns the value of the lower end of the first bin.
Definition: BinningSpecs.h:187
Helper to check if an object has changed. Thread-safe.
static TriggerGates_t readTriggerGates(art::Event const &event, art::InputTag const &dataTag)
Data_t min() const noexcept
Definition: FixedBins.h:416
Helper data structure to store transient trigger result.
Definition: TriggerInfo_t.h:50
std::vector< ThresholdPlotInfo_t > fThresholdPlots
Proto-histogram information in a not-so-practical array; per threshold.
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:69
BinningSpecs alignBinningTo(BinningSpecs const &binning, double boundary, bool extendCoverage=true)
Returns a binning shifted to align with the specified boundary.
timescale_traits< OpticalTimeCategory >::tick_interval_t optical_time_ticks
Interface to detinfo::DetectorClocks.
Specification of the requirement of sliding window firing pattern.
Definition: WindowPattern.h:51
fDetProps &fDetProps fDetProps &fDetProps fLogCategory
void initializePlots()
Initializes the full set of plots (all ADC thresholds).
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
void plotTriggerResponse(std::size_t iThr, std::string const &thrTag, WindowTriggerInfo_t const &triggerInfo, detinfo::DetectorTimings const &detTimings)
Fills the plots for threshold index iThr with trigger information.
Access the description of detector geometry.
timescale_traits< TriggerTimeCategory >::time_point_t trigger_time
A point in time on the trigger time scale.
bool empty() const noexcept
Returns whether there is no storage at all.
Definition: FixedBins.h:360
All information needed to generate plots for a specific threshold.
Data structure holding binning information.
Definition: BinningSpecs.h:170
double binWidth() const
Returns the width of the bins (all bins have the same width).
Definition: BinningSpecs.h:199
icarus::trigger::PlotSandbox fPlots
All plots in one practical sandbox.
electronics_time toElectronicsTime(FromTime time) const
Converts a time point into electronics time scale.
Ticks toOpticalTicks(time_interval time) const
Returns the optical ticks corresponding to a time interval.
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
bool empty() const
Returns if the sandbox is empty (neither it nor subboxes hold objects).
Simple functions to streamline the creation of DetectorClocksData.
Defines a (sliding) window trigger pattern.
raw::Trigger triggerInfoToTriggerData(detinfo::DetectorTimings const &detTimings, unsigned int triggerNumber, WindowTriggerInfo_t const &info) const
Converts the trigger information into a raw::Trigger object.
Simple type definitions for trigger algorithms.
A trigger gate data object for optical detector electronics.
icarus::trigger::ReadoutTriggerGate< TriggerGateTick_t, TriggerGateTicks_t, raw::Channel_t > OpticalTriggerGateData_t
Type of trigger gate data serialized into art data products.
A bunch of diverse utilities and futilities related to ROOT.
std::vector< PlotDef > plots
Definition: demo.h:54
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
BEGIN_PROLOG vertical distance to the surface Name
Test of util::counter and support utilities.
art::TFileDirectory fOutputDir
ROOT directory where all the plots are written.
An interval (duration, length, distance) between two quantity points.
Definition: intervals.h:114
Definition of data types for geometry description.
Class with extensible fix-sized binning.
FHiCL configuration structure for icarus::trigger::WindowPattern.
std::size_t nBins() const noexcept
Returns how many bins currently have storage.
Definition: FixedBins.h:354
nanoseconds_as<> nanoseconds
Type of time interval stored in nanoseconds, in double precision.
Definition: spacetime.h:270
double upper() const
Returns the value of the upper end of the last bin.
Definition: BinningSpecs.h:190
microseconds fBeamGateStart
Start of the beam gate with respect to BeamGate().
::fhicl::TableAs< icarus::trigger::WindowPattern, WindowPatternConfig > WindowPatternTable
Configuration element for a trigger window.
Utilities to read interval and point quantity FHiCL configuration.
timescale_traits< OpticalTimeCategory >::tick_t optical_tick
Classes to detect the change of object values.
optical_tick atTick() const
Returns the time of the trigger (undefined if !fired()).
Contains all timing reference information for the detector.
WindowPattern const fPattern
Configured sliding window requirement pattern.
std::string to_string(WindowPattern const &pattern)
Dimensioned variables representing space or time quantities.
WindowTriggerInfo_t produceForThreshold(art::Event &event, detinfo::DetectorTimings const &detTimings, ApplyBeamGateClass const &beamGate, std::size_t const iThr, std::string const &thrTag)
Performs the simulation for the specified ADC threshold.
Helper class to store transient trigger result.
A class exposing an upgraded interface of detinfo::DetectorClocksData.
Data types for detinfo::DetectorTimings.
virtual void endJob() override
Prints end-of-job summaries.
Functions pulling in STL customization if available.
Class to create an object representing a beam gate.
microseconds fBeamGateDuration
Duration of the gate during with global optical triggers are accepted.
std::vector< InputTriggerGate_t > TriggerGates_t
A list of trigger gates from input.
std::string const fLogCategory
Message facility stream category for output.
do i e
icarus::trigger::TrackedOpticalTriggerGate< sbn::OpDetWaveformMeta > InputTriggerGate_t
Type of trigger gate provided as input.
std::vector< icarus::trigger::TrackedOpticalTriggerGate< OpDetInfo > > FillTriggerGates(std::vector< icarus::trigger::OpticalTriggerGateData_t > const &gates, art::Assns< icarus::trigger::OpticalTriggerGateData_t, OpDetInfo > const &gateToWaveformInfo)
Creates a gate object out of trigger gate data products.
std::vector< std::string > fOutputInstances
Output data product instance names (same order as fADCthresholds).
then echo fcl name
auto zip(Iterables &&...iterables)
Range-for loop helper iterating across many collections at the same time.
Definition: zip.h:295
temporary value
fDetProps &fDetProps fDetProps &fDetProps detTimings
Definition of util::values() and util::const_values().
BEGIN_PROLOG triggeremu_data_config_icarus settings sequence::triggeremu_data_config_icarus settings PMTADCthresholds sequence::triggeremu_data_config_icarus settings PMTADCthresholds sequence::triggeremu_data_config_icarus settings PMTADCthresholds Pattern
unsigned long nBins() const
Returns the number of bins.
Definition: BinningSpecs.h:196
std::size_t count(Cont const &cont)
detinfo::DetectorClocksData makeDetClockData(art::Event const *event)
Returns a detinfo::DetectorClocksData from DetectorClocksService.
std::optional< icarus::trigger::SlidingWindowPatternAlg > fPatternAlg
Pattern algorithm.
Complete information from this algorithm, standard + non-standard (extra).
static double eventTimestampInSeconds(art::Timestamp const &time)
Returns the time of the event in seconds from The Epoch.
Applies sliding window trigger patterns.
icarus::ns::util::ThreadSafeChangeMonitor< icarus::trigger::ApplyBeamGateClass > fGateChangeCheck
Functor returning whether a gate has changed.
A helper to manage ROOT objects in a art::TFileDirectory.
art framework interface to geometry description
detinfo::DetectorTimings makeDetTimings(art::Event const *event)
Returns a detinfo::DetectorTimings from DetectorClocksService.
A helper to manage ROOT objects with consistent naming.
Definition: PlotSandbox.h:95
ThresholdPlotInfo_t fEventPlotInfo
Proto-histogram information in a convenient packet; event-wide.
Interval_t binWidth() const noexcept
Returns the width of the bins.
Definition: FixedBins.h:366