All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TriggerConfigurationExtractor.cxx
Go to the documentation of this file.
1 /**
2  * @file icaruscode/Decode/DecoderTools/ICARUSTriggerConfigurationExtractor.cxx
3  * @brief Utility to extract the ICARUSTrigger readout configuration from data. Inspired by the PMTconfigurationExtractor authored by G. Petrillo
4  * @author Andrea Scarpelli (ascarpell@bnl.gov)
5  * @date March 23, 2022
6  * @see icaruscode/Decode/DecoderTools/ICARUSTriggerConfigurationExtractor.h
7  */
8 
9 
10 // ICARUS libraries
12 
13 // C/C++ standard libraries
14 #include <algorithm> // std::find_if()
15 #include <memory> // std::unique_ptr<>
16 
17 
18 // -----------------------------------------------------------------------------
19 // --- icarus::TriggerConfigurationExtractorBase
20 // -----------------------------------------------------------------------------
21 fhicl::ParameterSet
23  fhicl::ParameterSet const& container,
24  std::string const& configListKey,
25  std::initializer_list<std::regex const> components // TODO template with matcher functor
26 ) {
27 
28  fhicl::ParameterSet const sourceConfig
29  = container.get<fhicl::ParameterSet>(configListKey);
30 
31  fhicl::ParameterSet configDocs;
32  for (auto const& key: sourceConfig.get_names()) {
33  if (!sourceConfig.is_key_to_atom(key)) continue;
34 
35  if (!matchKey(key, components.begin(), components.end())) continue;
36 
37  std::string const psetStr = sourceConfig.get<std::string>(key);
38 
39  fhicl::ParameterSet pset;
40  try {
41  pset = fhicl::ParameterSet::make(psetStr);
42  }
43  catch (cet::exception& e) {
44  throw cet::exception{ "convertConfigurationDocuments", "", e }
45  << "Error parsing the content of key '" << configListKey << "." << key
46  << "'; content was:\n" << psetStr << "\n";
47  }
48 
49  configDocs.put(key, pset);
50 
51  } // for all main keys
52 
53  return configDocs;
54 } // convertConfigurationDocuments()
55 
56 
57 
58 // -----------------------------------------------------------------------------
59 // --- icarus::TriggerConfigurationExtractor
60 // -----------------------------------------------------------------------------
61 std::vector<std::regex> const
63  { std::regex{ "icarustrigger.*" } }
64  ;
65 
66 // -----------------------------------------------------------------------------
68  (fhicl::ParameterSet const& pset, std::string const& key)
69 {
70  return matchKey(key, ConfigurationNames.begin(), ConfigurationNames.end());
71 } // icarus::PMTconfigurationExtractor::isGoodConfiguration()
72 
73 
74 // -----------------------------------------------------------------------------
76  ( std::string prescaleString, std::size_t source ) const
77 {
78 
79  /*
80  * The prescale strings represents the hex econding of a 32-bit number
81  * The first, least significative 16-bit word is the prescale associated
82  * to BNB, while the most significative 16-bits are associated to NuMI.
83  * if the word has only 16-bits (4 character string) then it is the
84  * prescale associated to the calibration gate
85  */
86 
87  using namespace std::string_literals;
88  switch( source ){
89  case icarus::trigger::kBNB: return std::stoul( prescaleString.substr(4,8), nullptr, 16);
90  case icarus::trigger::kNuMI: return std::stoul( prescaleString.substr(0,4), nullptr, 16);
91  case icarus::trigger::kOffBeamBNB: return std::stoul( prescaleString.substr(4,8), nullptr, 16);
92  case icarus::trigger::kOffBeamNuMI: return std::stoul( prescaleString.substr(0,4), nullptr, 16);
93  case icarus::trigger::kCalibration: return std::stoul( prescaleString, nullptr ,16);
94  }
95  throw std::runtime_error(" icarus::TriggerConfigurationExtractor::parsePrescaleString triggerSource{"s
96  + std::to_string(source) + "}): unknown value"s);
97 
98 }
99 
100 
101 // -----------------------------------------------------------------------------
102 unsigned int icarus::TriggerConfigurationExtractor::parseWindowMode(std::string bitStr) const {
103  for (unsigned int bitValue = 0; bitValue < value(sbn::bits::triggerWindowMode::NBits); ++bitValue) {
104  auto const bit = static_cast<sbn::bits::triggerWindowMode>(bitValue);
105  if (bitStr == bitName(bit)) return bitValue;
106  }
107  throw cet::exception{ "TriggerConfigurationExtractor" }
108  << "Trigger window mode '" << bitStr << "' is not known.\n";
109 }
110 
111 
112 // -----------------------------------------------------------------------------
114  (fhicl::ParameterSet const& pset) const
115 {
116 
117  std::optional<icarus::TriggerConfiguration> config;
118 
119  for (std::string const& key: pset.get_names()) {
120 
121  std::optional<fhicl::ParameterSet> triggerConfigPset
122  = readTriggerConfig(pset, key);
123 
124  if (!triggerConfigPset) continue;
125 
126  std::optional triggerConfig
127  = extractTriggerConfiguration(*triggerConfigPset);
128 
129  if (config) {
130  throw cet::exception{ "TriggerConfigurationExtractor" }
131  << "Found multiple configurations for the trigger:"
132  << "\n" << std::string(80, '-') << "\n"
133  << *config
134  << "\n" << std::string(80, '-') << "\n"
135  << "and"
136  << "\n" << std::string(80, '-') << "\n"
137  << *triggerConfig
138  << "\n" << std::string(80, '-') << "\n"
139  ;
140  }
141 
142  config = std::move(triggerConfig);
143 
144  } // for
145  if (!config) {
146  throw cet::exception{ "TriggerConfigurationExtractor" }
147  << "No trigger configuration found (fragment type: '"
148  << fExpectedFragmentType << "').\n";
149  }
150 
151  return *config;
152 } // icarus::PMTconfigurationExtractor::extract()
153 
154 
155 // -----------------------------------------------------------------------------
157  (fhicl::ParameterSet const& pset ) const
159 {
160 
161  auto const& triggerParams
162  = pset.get<fhicl::ParameterSet>("daq.fragment_receiver");
163 
164  auto const& fpgaParams
165  = pset.get<fhicl::ParameterSet>("daq.fragment_receiver.fpga_init_params");
166 
167  auto const& spexiParams
168  = pset.get<fhicl::ParameterSet>("daq.fragment_receiver.spexi_init_params");
169 
170  icarus::TriggerConfiguration rc; // readout config, for friends
171 
172 
173  rc.useWrTime
174  = triggerParams.get<bool>("use_wr_time");
175  rc.wrTimeOffset
176  = triggerParams.get<unsigned int>("wr_time_offset_ns");
177 
178  rc.vetoDelay
179  = fpgaParams.get<unsigned int>("Veto.value");
180 
181  rc.cryoConfig[icarus::trigger::kEast].majLevelInTime
182  = fpgaParams.get<unsigned int>("MajLevelBeamCryo1.value");
183  rc.cryoConfig[icarus::trigger::kEast].majLevelDrift
184  = fpgaParams.get<unsigned int>("MajLevelEnableCryo1.value");
185  rc.cryoConfig[icarus::trigger::kEast].slidingWindow
186  = parseWindowMode( fpgaParams.get<std::string>("SlidingWindowCryo1.value") );
187  rc.cryoConfig[icarus::trigger::kWest].majLevelInTime
188  = fpgaParams.get<unsigned int>("MajLevelBeamCryo2.value");
189  rc.cryoConfig[icarus::trigger::kWest].majLevelDrift
190  = fpgaParams.get<unsigned int>("MajLevelEnableCryo2.value");
191  rc.cryoConfig[icarus::trigger::kWest].slidingWindow
192  = parseWindowMode( fpgaParams.get<std::string>("SlidingWindowCryo2.value") );
193  rc.majorityTriggerType
194  = fpgaParams.get<std::string>( "MajorityTriggerType.value");
195  rc.runType
196  = fpgaParams.get<std::string>( "RunType.value");
197 
198  rc.tpcTriggerDelay
199  = spexiParams.get<unsigned int>("TPCTriggerDelay.value");
200 
201  auto gateSelection = sbn::bits::makeMask<sbn::gateSelection>
202  (std::stoul( spexiParams.get<std::string>("GateSelection.value"), nullptr, 16));
203 
204  // Read the prescale configuraton as string for now
205  auto prescaleMinBiasBeam =
206  spexiParams.get<std::string>("PreScaleBNBNuMI.value");
207  auto prescaleMinBiasOffBeam =
208  spexiParams.get<std::string>("PreScaleOffBeam.value");
209  auto offBeamGateRate =
210  spexiParams.get<std::string>("OffBeamGateRate.value");
211  auto prescaleMinBiasCalibration =
212  spexiParams.get<std::string>("PrescaleZeroBias.value");
213 
214  // BNB Full Config
215  rc.gateConfig[icarus::trigger::kBNB].hasGate
217  rc.gateConfig[icarus::trigger::kBNB].hasDriftGate
219  rc.gateConfig[icarus::trigger::kBNB].hasMinBiasGate
221  rc.gateConfig[icarus::trigger::kBNB].hasMinBiasDriftGate
223  rc.gateConfig[icarus::trigger::kBNB].gateWidth
224  = spexiParams.get<unsigned int>("BNBBeamWidth.value");
225  rc.gateConfig[icarus::trigger::kBNB].driftGateWidth
226  = spexiParams.get<unsigned int>("BNBEnableWidth.value");
227  rc.gateConfig[icarus::trigger::kBNB].prescaleMinBias
228  = parsePrescaleString(prescaleMinBiasBeam, icarus::trigger::kBNB);
229  rc.gateConfig[icarus::trigger::kBNB].earlyWarningOffset
230  = spexiParams.get<unsigned int>("BNBBESOffset.value");
231  rc.gateConfig[icarus::trigger::kBNB].earlyEarlyWarningOffset
232  = spexiParams.get<unsigned int>("BNB1DOffset.value");
233 
234  // OffBeamBNB config
235  rc.gateConfig[icarus::trigger::kOffBeamBNB].hasGate
237  rc.gateConfig[icarus::trigger::kOffBeamBNB].hasDriftGate
239  rc.gateConfig[icarus::trigger::kOffBeamBNB].hasMinBiasGate
241  rc.gateConfig[icarus::trigger::kOffBeamBNB].hasMinBiasDriftGate
243  rc.gateConfig[icarus::trigger::kOffBeamBNB].gateWidth
244  = spexiParams.get<unsigned int>("OffBeamBNBBeamWidth.value");
245  rc.gateConfig[icarus::trigger::kOffBeamBNB].driftGateWidth
246  = spexiParams.get<unsigned int>("OffBeamBNBEnableWidth.value");
247  rc.gateConfig[icarus::trigger::kOffBeamBNB].prescaleMinBias
248  = parsePrescaleString(prescaleMinBiasOffBeam, icarus::trigger::kOffBeamBNB);
249  rc.gateConfig[icarus::trigger::kOffBeamBNB].offBeamGateRate
250  = parsePrescaleString( offBeamGateRate, icarus::trigger::kOffBeamBNB );
251 
252  // NuMI Configuration
253  rc.gateConfig[icarus::trigger::kNuMI].hasGate
255  rc.gateConfig[icarus::trigger::kNuMI].hasDriftGate
257  rc.gateConfig[icarus::trigger::kNuMI].hasMinBiasGate
259  rc.gateConfig[icarus::trigger::kNuMI].hasMinBiasDriftGate
261  rc.gateConfig[icarus::trigger::kNuMI].gateWidth
262  = spexiParams.get<unsigned int>("NuMIBeamWidth.value");
263  rc.gateConfig[icarus::trigger::kNuMI].driftGateWidth
264  = spexiParams.get<unsigned int>("NuMIEnableWidth.value");
265  rc.gateConfig[icarus::trigger::kNuMI].prescaleMinBias
266  = parsePrescaleString(prescaleMinBiasBeam, icarus::trigger::kNuMI);
267  rc.gateConfig[icarus::trigger::kNuMI].earlyWarningOffset
268  = spexiParams.get<unsigned int>("NuMIMIBSOffset.value");
269  rc.gateConfig[icarus::trigger::kNuMI].earlyEarlyWarningOffset
270  = spexiParams.get<unsigned int>("NuMIADOffset.value");
271 
272  // OffbeamNuMI config
273  rc.gateConfig[icarus::trigger::kOffBeamNuMI].hasGate
275  rc.gateConfig[icarus::trigger::kOffBeamNuMI].hasDriftGate
277  rc.gateConfig[icarus::trigger::kOffBeamNuMI].hasMinBiasGate
279  rc.gateConfig[icarus::trigger::kOffBeamNuMI].hasMinBiasDriftGate
281  rc.gateConfig[icarus::trigger::kOffBeamNuMI].gateWidth
282  = spexiParams.get<unsigned int>("OffBeamNuMIBeamWidth.value");
283  rc.gateConfig[icarus::trigger::kOffBeamNuMI].driftGateWidth
284  = spexiParams.get<unsigned int>("OffBeamNuMIEnableWidth.value");
285  rc.gateConfig[icarus::trigger::kOffBeamNuMI].prescaleMinBias
286  = parsePrescaleString(prescaleMinBiasOffBeam, icarus::trigger::kOffBeamNuMI);
287  rc.gateConfig[icarus::trigger::kOffBeamNuMI].offBeamGateRate
288  = parsePrescaleString( offBeamGateRate, icarus::trigger::kOffBeamNuMI );
289 
290  // Calibration configuration
291  rc.gateConfig[icarus::trigger::kCalibration].hasGate
293  rc.gateConfig[icarus::trigger::kCalibration].hasDriftGate
295  rc.gateConfig[icarus::trigger::kCalibration].hasMinBiasGate
297  rc.gateConfig[icarus::trigger::kCalibration].hasMinBiasDriftGate
299  rc.gateConfig[icarus::trigger::kCalibration].gateWidth
300  = spexiParams.get<unsigned int>("ZeroBiasWidth.value");
301  rc.gateConfig[icarus::trigger::kCalibration].driftGateWidth
302  = spexiParams.get<unsigned int>("ZeroBiasEnableWidth.value");
303  rc.gateConfig[icarus::trigger::kCalibration].prescaleMinBias
304  = parsePrescaleString( prescaleMinBiasCalibration, icarus::trigger::kCalibration );
305  rc.gateConfig[icarus::trigger::kCalibration].period
306  = spexiParams.get<unsigned int>("ZeroBiasFreq.value"); //it is actually a period
307 
308  return rc;
309 
310 } // icarus::TriggerConfigurationExtractor::extractTriggerConfiguration()
311 
312 
313 // -----------------------------------------------------------------------------
314 std::optional<fhicl::ParameterSet>
316  (fhicl::ParameterSet const& pset, std::string const& key) const
317 {
318  std::optional<fhicl::ParameterSet> config;
319 
320  do { // fake loop for fast exit
321 
322  // it must be a parameter set
323  if (!pset.has_key(key) || !pset.is_key_to_table(key)) break;
324 
325  auto boardPSet = pset.get<fhicl::ParameterSet>(key);
326 
327  // its "fragment_type" must be the expected one
328  std::string fragmentType;
329  if (!boardPSet.get_if_present("daq.fragment_receiver.generator", fragmentType))
330  break;
331  if (fragmentType != fExpectedFragmentType) break;
332 
333  config.emplace(std::move(boardPSet)); // success
334  } while (false);
335  return config;
336 } // icarus::TriggerConfigurationExtractor::readTriggerConfig()
337 
338 
339 // -----------------------------------------------------------------------------
340 // --- free functions implementation
341 // -----------------------------------------------------------------------------
343  (std::string const& srcFileName, icarus::TriggerConfigurationExtractor extractor)
344 {
345  //
346  // TFile::Open() call is needed to support non-local URL
347  // (e.g. XRootD URL are not supported by TFile constructor).
348  //
350  std::unique_ptr<TFile>{ TFile::Open(srcFileName.c_str(), "READ") }
351  ),
352  std::move(extractor)
353  );
354 } // icarus::extractTriggerReadoutConfiguration(string)
355 
356 
357 // -----------------------------------------------------------------------------
359  (TFile& srcFile, icarus::TriggerConfigurationExtractor extractor)
360 {
361 
363  (util::readConfigurationFromArtFile(srcFile), std::move(extractor));
364 
365 } // icarus::extractTriggerReadoutConfiguration(TFile)
366 
367 
368 // -----------------------------------------------------------------------------
static fhicl::ParameterSet convertConfigurationDocuments(fhicl::ParameterSet const &container, std::string const &configListKey, std::initializer_list< std::regex const > components)
Returns a parameter set with the content of configuration_documents key from container.
static bool matchKey(std::string const &key, RBegin rbegin, REnd rend)
Number of bits currently supported.
static constexpr std::size_t kOffBeamNuMI
Definition: BeamBits.h:370
static constexpr std::size_t kWest
Definition: BeamBits.h:364
Enabke MinBias triggers for the Offbeam BNB stream.
Enable MinBias triggers for the Calibration stream.
constexpr bool hasBitSet(mask_t< EnumType > bitMask, EnumType bit)
Returns whether the specified bit is set in bitMask.
Definition: BeamBits.h:232
do source
Enable Offbeam drift gate NuMI (for light out-of-time in offbeam gates)
gateSelection
Enabled gates in the trigger configuration. See register 0X00050008 in docdb SBN-doc-23778-v1.
Definition: BeamBits.h:149
static bool isGoodConfiguration(fhicl::ParameterSet const &pset, std::string const &key)
Returns whether the specified key of pset is a good configuration.
triggerWindowMode
Trigger window mode.
Definition: BeamBits.h:139
std::map< fhicl::ParameterSetID, fhicl::ParameterSet > readConfigurationFromArtFile(TFile &file)
Reads and returns the art configuration stored in sourceDir.
static constexpr std::size_t kBNB
Definition: BeamBits.h:367
Enable NuMI early warning signal (MIBS$74) to open NuMI gates.
std::string bitName(triggerSource bit)
Returns a mnemonic short name of the beam type.
Definition: BeamBits.h:267
Enable light out-of-time for MinBias triggers in NuMI stream.
Enable light out-of-time for MinBias triggers in BNB stream.
Enable light out-of-time for MinBias triggers in Offbeam NuMI stream.
static constexpr std::size_t kCalibration
Definition: BeamBits.h:371
icarus::TriggerConfiguration extractTriggerReadoutConfigurationImpl(ConfigMap const &configMap, icarus::TriggerConfigurationExtractor extractor)
Enable MinBias triggers for the Offbeam NuMI stream.
icarus::TriggerConfiguration extractTriggerReadoutConfiguration(std::string const &srcFileName, icarus::TriggerConfigurationExtractor extractor)
std::optional< fhicl::ParameterSet > readTriggerConfig(fhicl::ParameterSet const &pset, std::string const &key) const
Returns the specified Trigger readout board configuration.
Enable Offbeam gate for BNB.
static constexpr std::size_t kNuMI
Definition: BeamBits.h:368
unsigned long parsePrescaleString(std::string prescaleString, std::size_t source) const
Utility to extract Trigger readout configuration from data.
Enable Offbeam drift gate BNB (for light out-of-time in offbeam gates)
static std::vector< std::regex > const ConfigurationNames
Regular expressions matching all names of supported Trigger configurations.
unsigned int parseWindowMode(std::string bitStr) const
std::string to_string(WindowPattern const &pattern)
then echo File list $list not found else cat $list while read file do echo $file sed s
Definition: file_to_url.sh:60
Class to extract PMT readout board configuration.
Enable MinBias triggers for the BNB stream.
Enable Calibration drift gate (for light out-of-time in calibration gates)
static constexpr std::size_t kOffBeamBNB
Definition: BeamBits.h:369
do i e
Enable Offbeam gate for NuMI.
Enable BNB early-early warning signal ($1D) for light out-of-time in BNB gates.
temporary value
Enable receiving NuMI early-early warning signal ($AD) for light out-of-time in NuMI gates...
Enable MinBias triggers for the NuMI stream.
static constexpr std::size_t kEast
Definition: BeamBits.h:363
Enable receiving BNB early warning signal (gatedBES) to open BNB gates.
icarus::TriggerConfiguration extractTriggerConfiguration(fhicl::ParameterSet const &pset) const
Extracts trigger readout board configuration from pset.
Enable light out-of-time for MinBias triggers in Calibration stream.
Enable light out-of-time for MinBias triggers in Offbeam BNB stream.
icarus::TriggerConfiguration extract(fhicl::ParameterSet const &config) const
Extracts all supported Trigger configuration from config.