All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TriggerEmulationTree_module.cc
Go to the documentation of this file.
1 /**
2  * @file TriggerEmulationTree_module.cc
3  * @authors Gianluca Petrillo (SLAC, petrillo@slac.stanford.edu)
4  * @date February 18, 2022
5  *
6  * Borrowed from `TriggerEmulationTree` module used for trigger efficiency
7  * analysis in data.
8  */
9 
10 
11 // ICARUS libraries
14 
15 // LArSoft libraries
16 #include "lardataobj/RawData/TriggerData.h" // raw::Trigger
18 
19 // framework libraries
20 #include "art_root_io/TFileService.h"
21 #include "art/Framework/Services/Registry/ServiceHandle.h"
22 #include "art/Framework/Core/EDAnalyzer.h"
23 #include "art/Framework/Core/ModuleMacros.h"
24 #include "art/Framework/Principal/Event.h"
25 #include "canvas/Persistency/Provenance/EventID.h"
26 #include "canvas/Utilities/InputTag.h"
27 #include "messagefacility/MessageLogger/MessageLogger.h"
28 #include "fhiclcpp/types/TableAs.h"
29 #include "fhiclcpp/types/Sequence.h"
30 #include "fhiclcpp/types/Atom.h"
31 
32 // ROOT libraries
33 #include "TTree.h"
34 
35 // C/C++ libraries
36 #include <vector>
37 #include <string>
38 
39 
40 
41 // -----------------------------------------------------------------------------
42 namespace sbn { class TriggerEmulationTree; }
43 /**
44  * @brief Fills a ROOT tree with trigger emulation results.
45  *
46  *
47  * Trigger information
48  * ====================
49  *
50  * There are two distinct groups of information about triggers in the tree.
51  * The first one is the hardware trigger, that is the trigger that was actually
52  * used to decide to record the event.
53  * The other group of information is from trigger logic "emulation" on the
54  * collected data (optical detector waveforms): there may be multiple branches
55  * in this group, one for each emulated trigger logic, threshold and gate.
56  *
57  *
58  * Simulated trigger information
59  * ------------------------------
60  *
61  * A branch is added for each configured trigger logic.
62  * This module actually ignores the details of the logic yielding the results:
63  * a trigger result is a group of data products under the same tag.
64  * For example, a tag `M1` (presumably, a very loose trigger logic requiring
65  * just one PMT pair above threshold anywhere in the detector, with no hint of
66  * which that threshold is) will produce a branch with name `"M1"` including
67  * information from the `M1` data products (so far, only a collection of
68  * `raw::Trigger` is read).
69  * Note that a trigger object is expected to be present _regardless whether
70  * the trigger fired or not_. It is assumed that the trigger fired if at least
71  * one of the `raw::Trigger::TriggerBits()` is set, not fired otherwise.
72  *
73  * Each branch mirrors a data record, `TriggerInfo_t`, reporting the response
74  * for one simulated trigger logic.
75  * The structure and interpretation of the trigger response branch is described
76  * in ROOT TTree code by the string in
77  * `TriggerInfo_t::TriggerResponseBranchStructure`, and its meaning is:
78  * * `fired` (boolean): whether this trigger has triggered at all during the
79  * considered trigger gate.
80  * * `time` (double): time of the trigger, taken directly from
81  * `raw::Trigger::TriggerTime()`; it is expected to be measured in
82  * microseconds and relative to the nominal time reference of the event,
83  * which for data is the hardware trigger time and for simulation is the
84  * "hardware" beam gate time (however that is defined).
85  * * `gate` (double): start time of the gate where the trigger logic was
86  * simulated. It is in the same time scale as the trigger time, and
87  * directly taken from `raw::Trigger::BeamGateTime()`.
88  *
89  */
90 class sbn::TriggerEmulationTree: public art::EDAnalyzer {
91 
92  using TriggerInputSpec_t
94 
95  public:
96 
97  /// Data record the trigger response branch is based on.
99 
100  struct Config {
101  using Name = fhicl::Name;
102  using Comment = fhicl::Comment;
103 
104  /// Information on a single trigger source for the tree.
106 
107  fhicl::Atom<std::string> Name {
108  fhicl::Name("Name"),
109  Comment("name of the trigger (e.g. `\"M5O3\"`), used for branch name")
110  };
111  fhicl::Atom<art::InputTag> TriggerTag {
112  fhicl::Name("TriggerTag"),
113  Comment("tag of the input trigger info data product")
114  };
115 
116  }; // TriggerSpecConfig
118  = fhicl::TableAs<TriggerInputSpec_t, TriggerSpecConfig>;
119 
120  fhicl::Atom<art::InputTag> BeamGateProducer {
121  Name("BeamGateProducer"),
122  Comment("tag of beam gate information")
123  // mandatory
124  };
125 
126  fhicl::Atom<art::InputTag> TriggerProducer {
127  Name("TriggerProducer"),
128  Comment("tag of hardware trigger information")
129  // mandatory
130  };
131 
132  fhicl::Sequence<TriggerSpecConfigTable> EmulatedTriggers {
133  Name("EmulatedTriggers"),
134  Comment("the emulated triggers to include in the tree")
135  };
136 
137  fhicl::Atom<std::string> TreeName {
138  Name("TreeName"),
139  Comment("name of the output ROOT tree"),
140  "TriggerEmu" // default
141  };
142 
143  fhicl::Atom<std::string> LogCategory {
144  Name("LogCategory"),
145  Comment("label for output messages of this module instance"),
146  "TriggerEmulationTree" // default
147  };
148 
149  }; // Config
150 
151  using Parameters = art::EDAnalyzer::Table<Config>;
152 
153  explicit TriggerEmulationTree(Parameters const& config);
154 
155  void analyze(art::Event const& event) override;
156 
157  void endJob() override;
158 
159  private:
160 
161  // --- BEGIN -- Tree data structures -----------------------------------------
162 
163  /// Data structure for the beam gate data in the tree.
164  struct BeamInfo_t {
165  static constexpr char branchDef[]
166  = "beamGateStart/l:beamGateDuration/F:beamGateType/i";
167 
168  std::uint64_t beamGateSimStart = 0;
169  float beamGateDuration = -1.0;
170  unsigned int beamGateType = 999;
171  }; // BeamInfo_t
172 
173  /// Data structure for the global trigger data in the tree.
175  static constexpr char branchDef[]
176  = "beamType/i:triggerTime/l:beamGateTime/l:triggerID/i:gateID/i";
177 
178  unsigned int beamType = 0U;
179  std::uint64_t triggerTime = 0ULL;
180  std::uint64_t beamGateTime = 0ULL;
181  unsigned int triggerID = 0U;
182  unsigned int gateID = 0U;
183  }; // GlobalTriggerInfo_t
184 
185  // --- END ---- Tree data structures -----------------------------------------
186 
187  // --- BEGIN -- Configuration parameters -------------------------------------
188 
189  art::InputTag const fBeamGateProducer;
190  art::InputTag const fTriggerProducer;
191  std::string const fLogCategory;
192 
193  // --- END ---- Configuration parameters -------------------------------------
194 
195  // --- BEGIN -- Tree buffers -------------------------------------------------
196 
197  struct {
198  unsigned int run;
199  unsigned int subRun;
200  unsigned int event;
201  } fEventID; // anonymous
202 
204  GlobalTriggerInfo_t fGlobalTriggerInfo; ///< Data for global trigger in tree.
205 
206  // --- END ---- Tree buffers -------------------------------------------------
207 
208  TTree *fStoreTree = nullptr;
209 
210  unsigned int fTotalProcessed = 0U;
211 
212 
213  // `convert()` needs to be a free function
215 
216 
217  // --- BEGIN -- Trigger response branches ------------------------------------
218 
219  ///< Manages filling of trigger result branches.
221 
222  // --- END ---- Trigger response branches ------------------------------------
223 
224 }; // sbn::TriggerEmulationTree
225 
226 
227 // -----------------------------------------------------------------------------
228 namespace sbn {
229 
232  {
233  return {
234  config.Name() // name
235  , config.TriggerTag() // inputTag
236  };
237  } // convert(sbn::TriggerSpecConfig)
238 
239 } // namespace sbn
240 
241 
242 // -----------------------------------------------------------------------------
244  : art::EDAnalyzer{ config }
245  // configuration
246  , fBeamGateProducer { config().BeamGateProducer() }
247  , fTriggerProducer { config().TriggerProducer() }
248  , fLogCategory { config().LogCategory() }
249  // algorithms
250  , fStoreTree {
251  art::ServiceHandle<art::TFileService>()->make<TTree>
252  (config().TreeName().c_str(), "Trigger emulation results")
253  }
254  , fTriggerResponses
255  { config().EmulatedTriggers(), consumesCollector(), *fStoreTree }
256 {
257 
258  //
259  // declaration of input
260  //
261 
262  consumes<std::vector<sim::BeamGateInfo>>(fBeamGateProducer);
263 
264  //
265  // tree population
266  //
267  fStoreTree->Branch("run", &fEventID.run);
268  fStoreTree->Branch("subrun", &fEventID.subRun);
269  fStoreTree->Branch("event", &fEventID.event);
270  fStoreTree->Branch("beamInfo", &fBeamInfo, BeamInfo_t::branchDef);
271  fStoreTree->Branch
272  ("globalTrigger", &fGlobalTriggerInfo, GlobalTriggerInfo_t::branchDef);
273 
274 } // sbn::TriggerEmulationTree::TriggerEmulationTree()
275 
276 
277 void sbn::TriggerEmulationTree::analyze(art::Event const& event)
278 {
279  // Implementation of required member function here.
280  fEventID = { event.run(), event.subRun(), event.event() };
281 
282  //
283  // beam gate
284  //
285  fBeamInfo = {};
286 
287  auto const& beamgate
288  = event.getProduct<std::vector<sim::BeamGateInfo>>(fBeamGateProducer);
289  if(beamgate.empty())
290  mf::LogWarning(fLogCategory) << "No Beam Gate Information!";
291  if(beamgate.size() > 1U)
292  mf::LogWarning(fLogCategory) << "Event has multiple beam gate info labels! (maybe this changes later to be standard)";
293  fBeamInfo.beamGateSimStart = beamgate.front().Start();
294  fBeamInfo.beamGateDuration = beamgate.front().Width();
295  fBeamInfo.beamGateType = beamgate.front().BeamType();
296 
297  //
298  // hardware trigger
299  //
300  auto const& triggerinfo
301  = event.getProduct<sbn::ExtraTriggerInfo>(fTriggerProducer);
302  fGlobalTriggerInfo.beamType
303  = static_cast<unsigned int>(triggerinfo.sourceType);
304  fGlobalTriggerInfo.triggerTime = triggerinfo.triggerTimestamp;
305  fGlobalTriggerInfo.beamGateTime = triggerinfo.beamGateTimestamp;
306  fGlobalTriggerInfo.triggerID = triggerinfo.triggerID;
307  fGlobalTriggerInfo.gateID = triggerinfo.gateID;
308 
309  // get an extractor bound to this event
310  sbn::details::TriggerResponseManager::Extractors triggerResponseExtractors
311  = fTriggerResponses.extractorsFor(event);
312 
313  triggerResponseExtractors.fetch(0); // only the first trigger in each list
314 
315  ++fTotalProcessed;
316  fStoreTree->Fill();
317 
318 } // sbn::TriggerEmulationTree::analyze()
319 
320 
321 // -----------------------------------------------------------------------------
323 
324  mf::LogInfo(fLogCategory) << "Processed " << fTotalProcessed << " events.";
325 
326 } // sbn::TriggerEmulationTree::endJob()
327 
328 
329 // -----------------------------------------------------------------------------
330 
331 DEFINE_ART_MODULE(sbn::TriggerEmulationTree)
friend TriggerInputSpec_t convert(Config::TriggerSpecConfig const &config)
fhicl::Sequence< TriggerSpecConfigTable > EmulatedTriggers
GlobalTriggerInfo_t fGlobalTriggerInfo
Data for global trigger in tree.
Manages extraction of trigger results and filling of their branches.
struct sbn::TriggerEmulationTree::@0 fEventID
Helper managing the trigger response part of a TTree.
Fills a ROOT tree with trigger emulation results.
art::EDAnalyzer::Table< Config > Parameters
fDetProps &fDetProps fDetProps &fDetProps fLogCategory
Additional information on trigger.
fhicl::Atom< art::InputTag > TriggerProducer
BEGIN_PROLOG vertical distance to the surface Name
fhicl::TableAs< TriggerInputSpec_t, TriggerSpecConfig > TriggerSpecConfigTable
Information about a single trigger logic (hardware or emulated).
Information on a single trigger source for the tree.
fhicl::Atom< art::InputTag > BeamGateProducer
Data product holding additional trigger information.
sbn::details::TriggerResponseManager fTriggerResponses
&lt; Manages filling of trigger result branches.
void analyze(art::Event const &event) override
TriggerEmulationTree(Parameters const &config)
std::uint64_t triggerTimestamp
Absolute timestamp of this trigger [ns].
Data structure for the beam gate data in the tree.
Configuration specifications for the emulation of a trigger logic.
TimeTrackTreeStorage::TriggerInputSpec_t convert(TimeTrackTreeStorage::Config::TriggerSpecConfig const &config)
Data structure for the global trigger data in the tree.
fDetProps &fDetProps fDetProps &fDetProps consumesCollector())