All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DumpTrigger_module.cc
Go to the documentation of this file.
1 /**
2  * @file DumpTrigger_module.cc
3  * @brief Dumps on console the content of trigger data products.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date March 22, 2022
6  */
7 
8 // SBN libraries
9 #include "icaruscode/Utilities/StreamIndenter.h" // util::addIndent()
11 #include "sbnobj/Common/Trigger/BeamBits.h" // sbn::triggerSource
12 
13 // LArSoft libraries
14 #include "lardataalg/DetectorInfo/DetectorTimingTypes.h" // simulation_time
18 #include "lardataobj/RawData/TriggerData.h" // raw::Trigger
19 
20 // framework libraries
21 #include "art/Framework/Core/ModuleMacros.h"
22 #include "art/Framework/Core/EDAnalyzer.h"
23 #include "art/Framework/Principal/Event.h"
24 #include "canvas/Persistency/Provenance/EventID.h"
25 #include "canvas/Utilities/InputTag.h"
26 #include "messagefacility/MessageLogger/MessageLogger.h"
27 #include "fhiclcpp/types/OptionalAtom.h"
28 #include "fhiclcpp/types/Atom.h"
29 
30 // C/C++ standard libraries
31 #include <iomanip> // std::setfill(), std::setw()
32 #include <vector>
33 #include <optional>
34 #include <utility> // std::pair
35 #include <string>
36 
37 
38 //------------------------------------------------------------------------------
39 namespace sbn { class DumpTrigger; }
40 
41 /**
42  * @brief Dumps on console the content of trigger data products.
43  *
44  * Supported trigger types are:
45  * * `std::vector<raw::Trigger>`
46  * * `std::vector<raw::ExternalTrigger>`
47  * * `std::vector<sim::BeamGateInfo>`
48  * * `std::vector<sbn::ExtraTriggerInfo>`
49  *
50  *
51  * Input data products
52  * ====================
53  *
54  * * `std::vector<raw::Trigger>`: simple trigger information
55  * * `std::vector<sim::BeamGateInfo>`: beam gate information
56  * * `std::vector<raw::ExternalTrigger>`: additional trigger information
57  * * `sbn::ExtraTriggerInfo`: detailed trigger information
58  *
59  *
60  * Configuration parameters
61  * =========================
62  *
63  * All data product tags are optional, but at least one needs to be specified.
64  * If a tag is not specified, the same tag as `TriggerTag` will be attempted
65  * (if specified).
66  * A terse description of the parameters is printed by running
67  * `lar --print-description DumpTrigger`.
68  *
69  * * `TriggerTag` (data product input tag, optional): the tag identifying the
70  * data product of the simple trigger information to dump.
71  * * `BeamGateTag` (data product input tag, optional): the tag identifying the
72  * data product of the beam gate; if explicitly empty, this type of data
73  * product will not be dumped; if omitted, an attempt to dump a data
74  * product with the same tag as `TriggerTag` will be performed, and in case
75  * of failure no message will be printed.
76  * * `ExternalTriggerTag` (data product input tag, optional): the tag
77  * identifying the data product of the additional standard trigger
78  * information; this is a standard LArSoft data product that ICARUS abuses
79  * to store information in a portable way. If explicitly empty, this type of
80  * data product will not be dumped; if omitted, an attempt to dump a data
81  * product with the same tag as `TriggerTag` will be performed, and in case
82  * of failure no message will be printed.
83  * * `ExtraTriggerTag` (data product input tag, optional): the tag identifying
84  * the data product of the detailed trigger information; this is
85  * SBN-specific. If explicitly empty, this type of data product will not be
86  * dumped; if omitted, an attempt to dump a data product with the same tag
87  * as `TriggerTag` will be performed, and in case of failure no message will
88  * be printed.
89  * * `Verbosity` (integral, default: maximum): verbosity level used in the
90  * dump; see `sbn::PMTconfiguration::dump()` for details.
91  * * `OutputCategory` (string, default: `DumpTrigger`): name of the
92  * message facility output stream to dump the information into.
93  *
94  */
95 class sbn::DumpTrigger: public art::EDAnalyzer {
96 
97  public:
98 
99  // --- BEGIN Configuration ---------------------------------------------------
100  struct Config {
101 
102  using Name = fhicl::Name;
103  using Comment = fhicl::Comment;
104 
105  fhicl::OptionalAtom<art::InputTag> TriggerTag {
106  Name{ "TriggerTag" },
107  Comment
108  { "tag of the simple trigger data product (raw::Trigger collection)" }
109  };
110 
111  fhicl::OptionalAtom<art::InputTag> BeamGateTag {
112  Name{ "BeamGateTag" },
113  Comment{ "tag of the beam gate information data product" }
114  };
115 
116  fhicl::OptionalAtom<art::InputTag> ExternalTriggerTag {
117  Name{ "ExternalTriggerTag" },
118  Comment{
119  "tag of additional trigger information data product"
120  " (raw::ExternalTrigger collection)"
121  }
122  };
123 
124  fhicl::OptionalAtom<art::InputTag> ExtraTriggerTag {
125  Name{ "ExtraTriggerTag" },
126  Comment{ "tag of detailed SBN-specific trigger information data product" }
127  };
128 
129  fhicl::Atom<unsigned int> Verbosity {
130  Name{ "Verbosity" },
131  Comment{ "verbosity level [default: maximum]" },
132  std::numeric_limits<unsigned int>::max() // default
133  };
134 
135  fhicl::Atom<std::string> OutputCategory {
136  Name{ "OutputCategory" },
137  Comment{ "name of the category used for the output" },
138  "DumpTrigger"
139  };
140 
141  }; // struct Config
142 
143  using Parameters = art::EDAnalyzer::Table<Config>;
144 
145  // --- END Configuration -----------------------------------------------------
146 
147 
148  // --- BEGIN Constructors ----------------------------------------------------
149  explicit DumpTrigger(Parameters const& config);
150 
151  // --- END Constructors ------------------------------------------------------
152 
153 
154  // --- BEGIN Framework hooks -------------------------------------------------
155 
156  /// Does the dumping.
157  virtual void analyze(art::Event const& event) override;
158 
159  // --- END Framework hooks ---------------------------------------------------
160 
161 
162  private:
163 
166 
167 
168  // --- BEGIN Configuration variables -----------------------------------------
169 
170  std::optional<art::InputTag> const fTriggerTag; ///< Input trigger tag.
171 
172  std::optional<art::InputTag> const fBeamGateTag; ///< Input beam gate tag.
173 
174  /// Input additional trigger tag.
175  std::optional<art::InputTag> const fExternalTag;
176 
177  std::optional<art::InputTag> const fExtraTag; /// Input extra trigger tag.
178 
179  unsigned int const fVerbosity; ///< Verbosity level used for dumping.
180 
181  /// Category used for message facility stream.
182  std::string const fOutputCategory;
183 
184  // --- END Configuration variables -------------------------------------------
185 
186 
187  /// Dumps a simple LArSoft trigger data product.
188  void dumpTrigger(std::vector<raw::Trigger> const& triggers) const;
189 
190  /// Dumps a LArSoft external trigger data product.
191  void dumpTrigger(std::vector<raw::ExternalTrigger> const& triggers) const;
192 
193  /// Dumps a LArSoft beam gate information data product.
194  void dumpBeamGate(std::vector<sim::BeamGateInfo> const& gates) const;
195 
196  /// Dumps a SBN trigger information data product.
197  void dumpTrigger(sbn::ExtraTriggerInfo const& trigger) const;
198 
199 
200  /// Returns the tag to try, and whether it is mandatory to find it.
201  std::pair<art::InputTag, bool> inputTag
202  (std::optional<art::InputTag> const& tag) const;
203 
204 
205  /// Returns `1` if the data product of type `T` specified by `param` must
206  /// be available, `0` otherwise. It also declares it will consume it.
207  template <typename T>
208  unsigned int countConsume(std::optional<art::InputTag> const& param);
209 
210 }; // sbn::DumpTrigger
211 
212 
213 //------------------------------------------------------------------------------
214 //--- Implementation
215 //------------------------------------------------------------------------------
216 namespace {
217  struct dumpTimestamp {
219  dumpTimestamp(raw::TriggerTimeStamp_t ts): ts{ ts } {}
220  }; // dumpTimestamp
221 
222  std::ostream& operator<< (std::ostream& out, dumpTimestamp tsw) {
223  return out << (tsw.ts / 1'000'000'000) << "." << std::setfill('0')
224  << std::setw(9) << (tsw.ts % 1'000'000'000) << std::setfill(' ');
225  } // operator<< (dumpTimestamp)
226 
227 
228 
229 } // local namespace
230 
231 //------------------------------------------------------------------------------
232 //--- sbn::DumpTrigger
233 //------------------------------------------------------------------------------
235  (Parameters const& config)
236  : art::EDAnalyzer(config)
237  // configuration
238  , fTriggerTag { config().TriggerTag() }
239  , fBeamGateTag { config().BeamGateTag() }
240  , fExternalTag { config().ExternalTriggerTag() }
241  , fExtraTag { config().ExtraTriggerTag() }
242  , fVerbosity { config().Verbosity() }
243  , fOutputCategory{ config().OutputCategory() }
244 {
245 
246  unsigned int nRequiredTriggers = 0U; // count of required data products
247 
248  /*
249  * data product usage declaration
250  */
251  nRequiredTriggers += countConsume<std::vector<raw::Trigger>>(fTriggerTag);
252  nRequiredTriggers
253  += countConsume<std::vector<sim::BeamGateInfo>>(fBeamGateTag);
254  nRequiredTriggers
255  += countConsume<std::vector<raw::ExternalTrigger>>(fExternalTag);
256  nRequiredTriggers += countConsume<sbn::ExtraTriggerInfo>(fExtraTag);
257 
258  /*
259  * parameter check
260  */
261  if (nRequiredTriggers == 0U) {
262  throw art::Exception{ art::errors::Configuration }
263  << "At least one trigger data product needs to be specified.\n";
264  }
265 
266  /*
267  * print configuration
268  */
269  mf::LogInfo log{ fOutputCategory };
270  log << "Configuration:\n * dump:";
271 
272  if (fTriggerTag) log << "\n - '" << fTriggerTag->encode() << "' (raw::Trigger)";
273 
274  if (auto const [ tag, req ] = inputTag(fExternalTag); !tag.empty()) {
275  log << "\n - '" << tag.encode() << "' (raw::ExternalTrigger)";
276  if (!req) log << " (if available)";
277  }
278 
279  if (auto const [ tag, req ] = inputTag(fExtraTag); !tag.empty()) {
280  log << "\n - '" << tag.encode() << "' (sbn::ExtraTriggerInfo)";
281  if (!req) log << " (if available)";
282  }
283 
284  if (auto const [ tag, req ] = inputTag(fBeamGateTag); !tag.empty()) {
285  log << "\n - '" << tag.encode() << "' (sim::BeamGateInfo)";
286  if (!req) log << " (if available)";
287  }
288 
289 } // sbn::DumpTrigger::DumpTrigger()
290 
291 
292 //------------------------------------------------------------------------------
293 void sbn::DumpTrigger::analyze(art::Event const& event) {
294 
295  mf::LogVerbatim{ fOutputCategory }
296  << "Trigger information in " << event.id() << ":";
297 
298  if (auto const [ tag, req ] = inputTag(fTriggerTag); !tag.empty()) {
299 
300  auto const& handle = event.getHandle<std::vector<raw::Trigger>>(tag);
301  if (handle) {
302  mf::LogVerbatim{ fOutputCategory }
303  << "* raw::Trigger ('" << tag.encode() << "'):";
304  dumpTrigger(*handle);
305  }
306  else if (req) throw *(handle.whyFailed());
307  } // simple trigger
308 
309 
310  if (auto const [ tag, req ] = inputTag(fExternalTag); !tag.empty()) {
311 
312  auto const& handle
313  = event.getHandle<std::vector<raw::ExternalTrigger>>(tag);
314  if (handle) {
315  mf::LogVerbatim{ fOutputCategory }
316  << "* raw::ExternalTrigger ('" << tag.encode() << "'):";
317  dumpTrigger(*handle);
318  }
319  else if (req) throw *(handle.whyFailed());
320  } // external trigger info
321 
322 
323  if (auto const [ tag, req ] = inputTag(fExtraTag); !tag.empty()) {
324 
325  auto const& handle = event.getHandle<sbn::ExtraTriggerInfo>(tag);
326  if (handle) {
327  mf::LogVerbatim{ fOutputCategory }
328  << "* sbn::ExtraTriggerInfo ('" << tag.encode() << "'):";
329  dumpTrigger(*handle);
330  }
331  else if (req) throw *(handle.whyFailed());
332  } // extra trigger info
333 
334 
335  if (auto const [ tag, req ] = inputTag(fBeamGateTag); !tag.empty()) {
336 
337  auto const& handle = event.getHandle<std::vector<sim::BeamGateInfo>>(tag);
338  if (handle) {
339  mf::LogVerbatim{ fOutputCategory }
340  << "* sim::BeamGateInfo ('" << tag.encode() << "'):";
341  dumpBeamGate(*handle);
342  }
343  else if (req) throw *(handle.whyFailed());
344  } // beam gate
345 
346 
347 } // sbn::DumpTrigger::analyze()
348 
349 
350 //------------------------------------------------------------------------------
352  (std::vector<raw::Trigger> const& triggers) const
353 {
354  static std::string const indent(4U, ' ');
355 
356  if (triggers.empty()) {
357  mf::LogVerbatim{ fOutputCategory } << indent << "no triggers.";
358  return;
359  }
360  if (triggers.size() > 1) {
361  mf::LogVerbatim{ fOutputCategory }
362  << indent << "[" << triggers.size() << " triggers]";
363  }
364 
365  for (auto const& [ iTrigger, trigger]: util::enumerate(triggers)) {
366  mf::LogVerbatim log { fOutputCategory };
367  log << indent;
368  if (triggers.size() > 1) log << "[" << iTrigger << "] ";
369  log << "trigger #" << trigger.TriggerNumber() << " at "
370  << electronics_time{ trigger.TriggerTime() }
371  << ", beam gate at " << electronics_time{ trigger.BeamGateTime() }
372  << ", bits:";
373  if (sbn::bits::triggerSourceMask const bitMask{ trigger.TriggerBits() }) {
374  log << " {";
375  for (std::string const& name: names(bitMask)) log << " " << name;
376  log << " }";
377  }
378  else log << " none";
379 
380  } // for
381 
382 } // sbn::DumpTrigger::dumpTrigger()
383 
384 
385 //------------------------------------------------------------------------------
387  (std::vector<raw::ExternalTrigger> const& triggers) const
388 {
389 
390  static std::string const indent(4U, ' ');
391 
392  if (triggers.empty()) {
393  mf::LogVerbatim{ fOutputCategory } << indent << "no triggers.";
394  return;
395  }
396  if (triggers.size() > 1) {
397  mf::LogVerbatim{ fOutputCategory }
398  << indent << "[" << triggers.size() << " triggers]";
399  }
400 
401  for (auto const& [ iTrigger, trigger]: util::enumerate(triggers)) {
402  mf::LogVerbatim log { fOutputCategory };
403  log << indent;
404  if (triggers.size() > 1) log << "[" << iTrigger << "] ";
405  log << "trigger ID=" << trigger.GetTrigID()
406  << " at " << dumpTimestamp(trigger.GetTrigTime());
407 
408  } // for
409 
410 } // sbn::DumpTrigger::dumpTrigger(ExternalTrigger)
411 
412 
413 //------------------------------------------------------------------------------
415  (std::vector<sim::BeamGateInfo> const& gates) const
416 {
417 
418  static std::string const indent(4U, ' ');
419 
420  if (gates.empty()) {
421  mf::LogVerbatim{ fOutputCategory } << indent << "no beam gates.";
422  return;
423  }
424  if (gates.size() > 1) {
425  mf::LogVerbatim{ fOutputCategory }
426  << indent << "[" << gates.size() << " beam gates]";
427  }
428 
429  for (auto const& [ iGate, gate]: util::enumerate(gates)) {
430  mf::LogVerbatim log { fOutputCategory };
431  log << indent;
432  simulation_time const start { gate.Start() };
433  simulation_time const end { gate.Start() + gate.Width() };
434  if (gates.size() > 1) log << "[" << iGate << "] ";
435  log << "beam gate [ " << start << " -- " << end << " ] (duration: "
436  << (end - start) << ") of type ";
437  switch (gate.BeamType()) {
438  case sim::kBNB: log << "BNB"; break;
439  case sim::kNuMI: log << "NuMI"; break;
440  case sim::kUnknown: log << "unknown"; break;
441  default:
442  log << "unsupported [code=" << static_cast<int>(gate.BeamType()) << "]";
443  } // switch
444 
445  } // for
446 
447 } // sbn::DumpTrigger::dumpBeamGate()
448 
449 
450 //------------------------------------------------------------------------------
452 
453  static std::string const indent(4U, ' ');
454 
455  mf::LogVerbatim{ fOutputCategory } << util::addIndent(indent) << trigger;
456 
457 } // sbn::DumpTrigger::dumpTrigger(ExtraTriggerInfo)
458 
459 
460 //------------------------------------------------------------------------------
461 std::pair<art::InputTag, bool> sbn::DumpTrigger::inputTag
462  (std::optional<art::InputTag> const& tag) const
463 {
464  return
465  { tag.value_or(fTriggerTag.value_or(art::InputTag{})), tag.has_value() };
466 } // sbn::DumpTrigger::inputTag()
467 
468 
469 //------------------------------------------------------------------------------
470 template <typename T>
472  (std::optional<art::InputTag> const& param)
473 {
474  auto const [ tag, required ] = inputTag(param);
475  if (tag.empty()) return 0;
476  if (required) consumes<T>(tag);
477  else mayConsume<T>(tag);
478  return required? 1: 0;
479 } // sbn::DumpTrigger::countConsume()
480 
481 
482 //------------------------------------------------------------------------------
483 DEFINE_ART_MODULE(sbn::DumpTrigger)
484 
485 
486 //------------------------------------------------------------------------------
Definitions of the trigger bits for SBN.
long long TriggerTimeStamp_t
type of trigger time stamp
std::string const fOutputCategory
Category used for message facility stream.
Definition of util::enumerate().
std::optional< art::InputTag > const fExtraTag
DumpTrigger(Parameters const &config)
Utility to have simple indentation in a stream.
std::pair< art::InputTag, bool > inputTag(std::optional< art::InputTag > const &tag) const
Returns the tag to try, and whether it is mandatory to find it.
virtual void analyze(art::Event const &event) override
Does the dumping.
fhicl::OptionalAtom< art::InputTag > ExtraTriggerTag
Unknown beam type.
Definition: BeamTypes.h:10
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:69
NuMI.
Definition: BeamTypes.h:12
Stream modifier that makes it &quot;indented&quot;.
fhicl::OptionalAtom< art::InputTag > ExternalTriggerTag
std::optional< art::InputTag > const fExternalTag
Input additional trigger tag.
art::EDAnalyzer::Table< Config > Parameters
Additional information on trigger.
timescale_traits< SimulationTimeCategory >::time_point_t simulation_time
A point in time on the simulation time scale.
fhicl::Atom< unsigned int > Verbosity
unsigned int countConsume(std::optional< art::InputTag > const &param)
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
void dumpBeamGate(std::vector< sim::BeamGateInfo > const &gates) const
Dumps a LArSoft beam gate information data product.
BEGIN_PROLOG vertical distance to the surface Name
Dumps on console the content of trigger data products.
fhicl::OptionalAtom< art::InputTag > BeamGateTag
fhicl::Atom< std::string > OutputCategory
unsigned int const fVerbosity
Input extra trigger tag.
std::optional< art::InputTag > const fTriggerTag
Input trigger tag.
void dumpTrigger(std::vector< raw::Trigger > const &triggers) const
Dumps a simple LArSoft trigger data product.
std::optional< art::InputTag > const fBeamGateTag
Input beam gate tag.
static const std::vector< std::string > names
BNB.
Definition: BeamTypes.h:11
detinfo::timescales::simulation_time simulation_time
Data types for detinfo::DetectorTimings.
detinfo::timescales::electronics_time electronics_time
then echo fcl name
Data product holding additional trigger information.
fhicl::OptionalAtom< art::InputTag > TriggerTag
std::ostream & operator<<(std::ostream &out, lar::example::CheatTrack const &track)
Definition: CheatTrack.h:153
timescale_traits< ElectronicsTimeCategory >::time_point_t electronics_time
A point in time on the electronics time scale.