All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DumpTriggerGateData_module.cc
Go to the documentation of this file.
1 /**
2  * @file DumpTriggerGateData_module.cc
3  * @brief Dumps on console the content of a
4  * `icarus::trigger::OpticalTriggerGate::GateData_t` data product.
5  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
6  * @date December 6, 2019
7  */
8 
9 // ICARUS libraries
12 
13 // LArSoft libraries
16 
17 // framework libraries
18 #include "art/Framework/Services/Registry/ServiceHandle.h"
19 #include "art/Framework/Core/ModuleMacros.h"
20 #include "art/Framework/Core/EDAnalyzer.h"
21 #include "art/Framework/Principal/Event.h"
22 #include "art/Framework/Principal/Handle.h"
23 #include "canvas/Utilities/InputTag.h"
24 #include "canvas/Persistency/Common/Assns.h"
25 #include "messagefacility/MessageLogger/MessageLogger.h"
26 #include "fhiclcpp/types/Atom.h"
27 
28 // C/C++ standard libraries
29 #include <vector>
30 #include <string>
31 #include <set>
32 #include <optional>
33 #include <type_traits> // std::decay_t
34 
35 
36 //------------------------------------------------------------------------------
37 namespace icarus::trigger { class DumpTriggerGateData; }
38 
39 /**
40  * @brief Produces plots to inform trigger design.
41  *
42  * This module produces sets of plots based on the configured trigger settings.
43  *
44  *
45  * Input data products
46  * ====================
47  *
48  * * `std::vector<raw::OpDetWaveform>`: a single waveform for each recorded
49  * optical detector activity; the activity belongs to a single channel, but
50  * there may be multiple waveforms on the same channel. The time stamp is
51  * expected to be from the
52  * @ref DetectorClocksElectronicsTime "electronics time scale"
53  * and therefore expressed in microseconds.
54  * * `std::vector<simb::MCTruth>`: generator information, used for categorising
55  * the events for plot sets
56  *
57  *
58  *
59  * Output plots
60  * =============
61  *
62  * For each event category, a set of plots is left into a ROOT subdirectory.
63  *
64  * @todo Document which plots these are!
65  *
66  *
67  *
68  * Configuration parameters
69  * =========================
70  *
71  * A terse description of the parameters is printed by running
72  * `lar --print-description DumpTriggerGateData`.
73  *
74  * @todo Complete the documentation
75  *
76  * * `TriggerGateDataTag` (data product input tag): the tag identifying the
77  * data product to dump; instance names are specified introduced by a colon:
78  * `"modulelabel:instance"`.
79  *
80  *
81  *
82  */
83 class icarus::trigger::DumpTriggerGateData: public art::EDAnalyzer {
84 
85  public:
86 
87  /// The type of data this dumper is dumping.
89 
90 
91  // --- BEGIN Configuration ---------------------------------------------------
92  struct Config {
93 
94  using Name = fhicl::Name;
95  using Comment = fhicl::Comment;
96 
97  fhicl::Atom<art::InputTag> TriggerGateDataTag {
98  Name("TriggerGateDataTag"),
99  Comment("tag of trigger gate data collection")
100  };
101 
102  fhicl::Atom<bool> PrintChannels {
103  Name("PrintChannels"),
104  Comment("whether to print the channel of the gate"),
105  true // default
106  };
107 
108  fhicl::Atom<std::string> OutputCategory {
109  Name("OutputCategory"),
110  Comment("name of the category used for the output"),
111  "DumpTriggerGateData"
112  };
113 
114  }; // struct Config
115 
116  using Parameters = art::EDAnalyzer::Table<Config>;
117  // --- END Configuration -----------------------------------------------------
118 
119 
120  // --- BEGIN Constructors ----------------------------------------------------
121  explicit DumpTriggerGateData(Parameters const& config);
122 
123  // Plugins should not be copied or assigned.
124  DumpTriggerGateData(DumpTriggerGateData const&) = delete;
128 
129  // --- END Constructors ------------------------------------------------------
130 
131 
132  // --- BEGIN Framework hooks -------------------------------------------------
133 
134  /// Fills the plots. Also extracts the information to fill them with.
135  virtual void analyze(art::Event const& event) override;
136 
137  // --- END Framework hooks ---------------------------------------------------
138 
139 
140  private:
141 
142  // --- BEGIN Configuration variables -----------------------------------------
143 
144  art::InputTag fTriggerGateDataTag; ///< Input trigger gate data tag.
145  bool fPrintChannels; ///< Whether to print associated optical waveform info.
146 
147  std::string fOutputCategory; ///< Category used for message facility stream.
148 
149  // --- END Configuration variables -------------------------------------------
150 
151 
152  // --- BEGIN Service variables -----------------------------------------------
153 
154 // detinfo::DetectorClocks const& fDetClocks;
155 // detinfo::DetectorTimings fDetTimings;
156 //
157 // /// Total number of optical channels (PMTs).
158 // unsigned int fNOpDetChannels = 0;
159 // microsecond const fOpDetTickDuration; ///< Optical detector sampling period.
160 
161  // --- END Service variables -------------------------------------------------
162 
163 
164 }; // icarus::trigger::DumpTriggerGateData
165 
166 
167 //------------------------------------------------------------------------------
168 //--- Implementation
169 //------------------------------------------------------------------------------
170 //--- icarus::trigger::DumpTriggerGateData
171 //------------------------------------------------------------------------------
173  (Parameters const& config)
174  : art::EDAnalyzer(config)
175  // configuration
176  , fTriggerGateDataTag(config().TriggerGateDataTag())
177  , fPrintChannels (config().PrintChannels())
178  , fOutputCategory (config().OutputCategory())
179 {
180  consumes<std::vector<TriggerGateData_t>>(fTriggerGateDataTag);
181  if (fPrintChannels) {
182  consumes<art::Assns<TriggerGateData_t, raw::OpDetWaveform>>
183  (fTriggerGateDataTag);
184  }
185 
186 } // icarus::trigger::DumpTriggerGateData::DumpTriggerGateData()
187 
188 
189 //------------------------------------------------------------------------------
190 void icarus::trigger::DumpTriggerGateData::analyze(art::Event const& event) {
191 
192  //
193  // do the work
194  //
195  auto const& gates =
196  *(event.getValidHandle<std::vector<TriggerGateData_t>>(fTriggerGateDataTag));
197  auto const* gateToWaveforms = fPrintChannels
198  ? event.getHandle<art::Assns<TriggerGateData_t, raw::OpDetWaveform>>
199  (fTriggerGateDataTag).product()
200  : nullptr
201  ;
202 
203  auto maybeItOpDetWave { gateToWaveforms
204  ? std::make_optional(gateToWaveforms->begin()): std::nullopt
205  };
206 
207  mf::LogVerbatim log(fOutputCategory);
208  log << event.id() << ": '" << fTriggerGateDataTag.encode() << "' has "
209  << gates.size() << " trigger gates:";
210  for (auto const& [ iGate, gate ]: util::enumerate(gates)) {
211  log << "\n[#" << iGate << "] " << compactdump(gate);
212  if (gateToWaveforms) {
213  auto& itOpDetWave = maybeItOpDetWave.value();
214  auto const owend = gateToWaveforms->end();
215 
216  /*
217  * Associations are expected to be in the same order as the trigger gates;
218  * so we look for the first one matching this gate
219  * (matching by the position in the data product collection)
220  * and then for the last one; if there is none... well, we say so.
221  */
222  while (itOpDetWave != owend) {
223  if (itOpDetWave->first.key() == iGate) break;
224  ++itOpDetWave;
225  } // while
226  if (itOpDetWave == owend) {
227  log << "\n (not associated with any optical detector waveform!)";
228  continue;
229  }
230  auto const firstOpDetWave = itOpDetWave;
231  std::set<raw::Channel_t> channels;
232  while (itOpDetWave != owend) {
233  if (itOpDetWave->first.key() != iGate) break;
234  channels.insert(itOpDetWave->second->ChannelNumber());
235  ++itOpDetWave;
236  } // while
237 
238  log << "\n associated with "
239  << std::distance(firstOpDetWave, itOpDetWave)
240  << " optical detector waveforms on ";
241  if (channels.size() == 1U) {
242  log << "channel " << *(channels.cbegin());
243  }
244  else {
245  log << channels.size() << " channels:";
246  for (auto const& channel: channels) log << " " << channel;
247  }
248 
249  } // if printing associated information
250  } // for
251 
252 } // icarus::trigger::DumpTriggerGateData::analyze()
253 
254 
255 //------------------------------------------------------------------------------
256 DEFINE_ART_MODULE(icarus::trigger::DumpTriggerGateData)
257 
258 
259 //------------------------------------------------------------------------------
Definition of util::enumerate().
bool fPrintChannels
Whether to print associated optical waveform info.
Utilities for TriggerGateData printout.
std::string fOutputCategory
Category used for message facility stream.
virtual void analyze(art::Event const &event) override
Fills the plots. Also extracts the information to fill them with.
DumpTriggerGateData & operator=(DumpTriggerGateData const &)=delete
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:69
Logical multi-level gate associated to one or more readout channels.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
A trigger gate data object for optical detector electronics.
BEGIN_PROLOG vertical distance to the surface Name
Produces plots to inform trigger design.
art::EDAnalyzer::Table< Config > Parameters
OpticalTriggerGateData_t GateData_t
Type for gate data access.
art::InputTag fTriggerGateDataTag
Input trigger gate data tag.
auto compactdump(ReadoutTriggerGate< Tick, TickInterval, ChannelIDType > const &gate) -> details::CompactFormatter< ReadoutTriggerGate< Tick, TickInterval, ChannelIDType >>
Manipulator-like function for compact format of trigger gates.