All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TriggerConfigurationExtraction_module.cc
Go to the documentation of this file.
1 /**
2  * @file TriggerConfigurationExtraction_module.cc
3  * @brief Writes ICARUS configuration from FHiCL into data product.
4  * @author Andrea Scarpelli (ascarpell@bnl.gov)
5  * @date March 23, 2022
6  */
7 
8 // ICARUS libraries
11 
12 // framework libraries
13 #include "canvas/Persistency/Provenance/ProcessConfiguration.h"
14 #include "canvas/Persistency/Provenance/ProcessHistory.h"
15 #include "fhiclcpp/ParameterSet.h"
16 
17 #include "art/Framework/Services/Registry/ServiceHandle.h"
18 #include "art/Framework/Core/EDProducer.h"
19 #include "art/Framework/Core/ModuleMacros.h"
20 #include "art/Framework/Core/FileBlock.h"
21 #include "art/Framework/Principal/Run.h"
22 #include "messagefacility/MessageLogger/MessageLogger.h"
23 #include "fhiclcpp/types/Atom.h"
24 #include "cetlib_except/exception.h"
25 
26 // C/C++ standard libraries
27 #include <memory> // std::unique_ptr<>
28 #include <optional>
29 #include <string>
30 #include <utility> // std::move()
31 #include <cassert>
32 
33 
34 // -----------------------------------------------------------------------------
35 namespace icarus { class TriggerConfigurationExtraction; }
36 /**
37  * @brief Writes trigger configuration from FHiCL into a data product.
38  *
39  * This module reads the configuration related to the Trigger from the FHiCL
40  * configuration of the input runs and puts it into each run as a data product.
41  *
42  * Input
43  * ------
44  *
45  * This module requires any input with _art_ run objects in it.
46  * The format expected for that configuration is defined in
47  * `icarus::TriggerConfigurationExtractor`, which is the utility used for the actual
48  * extraction.
49  *
50  *
51  * Output
52  * -------
53  *
54  * A data product of type `icarus::TriggerConfiguration` is placed in each run.
55  * Note that the module itself does not enforce any coherence in the
56  * configuration.
57  *
58  *
59  * Configuration parameters
60  * -------------------------
61  *
62  * The following configuration parameters are supported:
63  *
64  * * **TriggerFragmentType** (string, default: `ICARUSTriggerV2`):
65  * name of the type of trigger fragment, used to identify the configuration
66  * of the trigger.
67  * * **Verbose** (flag, default: `false`): if set to `true`, it will print in
68  * full the configuration of the trigger the first time it is read and each time
69  * a different one is found.
70  * * **LogCategory** (string, default: `ICARUSConfigurationExtraction`):
71  * category tag used for messages to message facility.
72  *
73  *
74  * Multithreading
75  * ---------------
76  *
77  * This module does not support multithreading, and _art_ does not provide
78  * multithreading for its functionality anyway: the only action is performed
79  * at run and input file level, and the only concurrency in _art_ is currently
80  * (_art_ 3.7) at event level.
81  *
82  */
83 class icarus::TriggerConfigurationExtraction: public art::EDProducer {
84 
85  /// Current Trigger configuration (may be still unassigned).
86  std::optional<icarus::TriggerConfiguration> fTriggerConfig;
87 
88  /// Whether trigger configuration inconsistency is fatal.
89  bool fRequireConsistency = true;
90 
91  std::string fTriggerFragmentType; ///< Name of the trigger fragment type.
92 
93  bool fVerbose = false; ///< Whether to print the configuration we read.
94 
95  std::string fLogCategory; ///< Category tag for messages.
96 
97  public:
98 
99  /// Configuration of the module.
100  struct Config {
101 
102  fhicl::Atom<std::string> TriggerFragmentType {
103  fhicl::Name("TriggerFragmentType"),
104  fhicl::Comment("the name of the type of trigger fragment from DAQ"),
105  "ICARUSTriggerV2" // default
106  };
107 
108  fhicl::Atom<bool> Verbose {
109  fhicl::Name("Verbose"),
110  fhicl::Comment("print in full each new Trigger configuration read"),
111  false // default
112  };
113 
114  fhicl::Atom<std::string> LogCategory {
115  fhicl::Name("LogCategory"),
116  fhicl::Comment("category tag used for messages to message facility"),
117  "TriggerConfigurationExtraction" // default
118  };
119 
120  }; // struct Config
121 
122  using Parameters = art::EDProducer::Table<Config>;
123 
124 
125  /// Constructor: just reads the configuration.
127 
128 
129  /// Action on new run: configuration is written.
130  virtual void beginRun(art::Run& run) override;
131 
132  /// Mandatory method, unused.
133  virtual void produce(art::Event&) override {}
134 
135 
136  private:
137 
138  /// Throws an exception if the `newConfig` is not compatible with the current.
139  bool checkConsistency
140  (icarus::TriggerConfiguration const& newConfig, std::string const& srcName) const;
141 
142 
143 }; // icarus::TriggerConfigurationExtraction
144 
145 
146 // -----------------------------------------------------------------------------
148  (Parameters const& config)
149  : art::EDProducer(config)
150  , fTriggerFragmentType(config().TriggerFragmentType())
151  , fVerbose(config().Verbose())
152  , fLogCategory(config().LogCategory())
153 {
154 
155  // no consummation here (except for FHiCL configuration)
156 
157  produces<icarus::TriggerConfiguration, art::InRun>();
158 
159 } // icarus::TriggerConfigurationExtraction::ICARUSTriggerConfigurationExtraction()
160 
161 
162 // -----------------------------------------------------------------------------
164 
167 
168  checkConsistency(config, "run " + std::to_string(run.run()));
169  if (!fTriggerConfig.has_value() && fVerbose)
170  mf::LogInfo(fLogCategory) << "Trigger readout:" << config;
171 
172  fTriggerConfig = std::move(config);
173 
174  // put a copy of the current configuration
175  run.put(std::make_unique<icarus::TriggerConfiguration>(fTriggerConfig.value()));
176 
177 } // icarus::riggerConfigurationExtraction::beginRun()
178 
179 
180 // -----------------------------------------------------------------------------
182  (icarus::TriggerConfiguration const& config, std::string const& srcName) const
183 {
184  if (!fTriggerConfig.has_value() || (*fTriggerConfig == config)) return true;
185 
186  // see debug information for more details
187  if (fRequireConsistency) {
188  throw cet::exception("icarus::TriggerConfigurationExtraction")
189  << "Configuration from " << srcName
190  << " is incompatible with the previously found configuration.\n"
191  ;
192  } // if consistency is required
193 
194  mf::LogWarning(fLogCategory)
195  << "Configuration from " << srcName
196  << " is incompatible with the previously found configuration.\n"
197  ;
198  if (fVerbose) mf::LogVerbatim(fLogCategory) << "Trigger readout:" << config;
199  return false;
200 
201 
202 } // icarus::TriggerConfigurationExtraction::checkConsistency()
203 
204 
205 // -----------------------------------------------------------------------------
207 
208 
209 // -----------------------------------------------------------------------------
BEGIN_PROLOG Verbose
virtual void beginRun(art::Run &run) override
Action on new run: configuration is written.
bool fRequireConsistency
Whether trigger configuration inconsistency is fatal.
Information from the configuration of the ICARUS trigger readout.
fDetProps &fDetProps fDetProps &fDetProps fLogCategory
virtual void produce(art::Event &) override
Mandatory method, unused.
TriggerConfigurationExtraction(Parameters const &config)
Constructor: just reads the configuration.
std::string fTriggerFragmentType
Name of the trigger fragment type.
std::optional< icarus::TriggerConfiguration > fTriggerConfig
Current Trigger configuration (may be still unassigned).
icarus::TriggerConfiguration extractTriggerReadoutConfiguration(std::string const &srcFileName, icarus::TriggerConfigurationExtractor extractor)
BEGIN_PROLOG vertical distance to the surface Name
Utility to extract Trigger readout configuration from data.
std::string to_string(WindowPattern const &pattern)
Class to extract PMT readout board configuration.
Writes trigger configuration from FHiCL into a data product.
bool checkConsistency(icarus::TriggerConfiguration const &newConfig, std::string const &srcName) const
Throws an exception if the newConfig is not compatible with the current.
bool fVerbose
Whether to print the configuration we read.