POTaccumulator_module.cc
Go to the documentation of this file.
1 /**
2  * @file larsim/EventGenerator/POTaccumulator_module.cc
3  * @brief Module summing all POT from the input files.
4  * @date April 29, 2020
5  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
6  */
7 
8 // LArSoft libraries
10 
11 // framework libraries
18 #include "fhiclcpp/types/Atom.h"
20 #include "range/v3/view.hpp"
21 
22 // C/C++ standard libraries
23 #include <map>
24 #include <string>
25 
26 // -----------------------------------------------------------------------------
27 namespace sim {
28  class POTaccumulator;
29 }
30 
31 /**
32  * @brief Prints on console the total Protons On Target from the input subruns.
33  *
34  * This module collects information from each of the subrun in the input files
35  * and prints the total of the protons on target. It also optionally prints the
36  * total for each observed run.
37  * If a subrun is met more than once, the information from all subrun fragments
38  * are added together (i.e. it is assumed that summary information is
39  * complementary rather than duplicate).
40  *
41  * The output can be printed to the console or a file via the appropriate
42  * message facility configuration.
43  *
44  * Two output streams are used: the one for the run summary and the one for
45  * the total summary. They may coincide.
46  *
47  *
48  * Input
49  * ------
50  *
51  * The module reads information from objects of type `sumdata::POTSummary`
52  * stored in each _subrun_.
53  *
54  *
55  * Configuration
56  * --------------
57  *
58  * The output streams can be managed by configuring message facility to deal
59  * with the relevant category names. All messages are sent with the INFO level.
60  *
61  * * `SummaryTag` (input tag; default: `generator`): data product (subrun level)
62  * with the summary information;
63  * * `SummaryCategory` (string; default: `POTaccumulator`): the name of the
64  * output category the summary is sent to;
65  * * `RunSummaryCategory` (string; default: disabled): if specified, a summary
66  * POT is printed for each run; the summary is sent to the output stream
67  * specified by the value of this parameter.
68  *
69  *
70  */
72 public:
73  /// Collection of configuration parameters for the module
74  struct Config {
75  using Name = fhicl::Name;
77 
79  Name("SummaryTag"),
80  Comment("data product (subrun level) with the summary information"),
81  "generator"};
82 
84  Name("SummaryCategory"),
85  Comment("name of the output category the summary is sent to"),
86  "POTaccumulator" // default value
87  };
88 
90  Name("RunSummaryCategory"),
91  Comment("name of the output category the summary is sent to"),
92  "" // default value
93  };
94 
95  }; // struct Config
96 
97  /// Type to enable module parameters description by _art_.
99 
100  /// Configuration-checking constructor.
101  explicit POTaccumulator(Parameters const& config);
102 
103  // Plugins should not be copied or assigned.
104  POTaccumulator(POTaccumulator const&) = delete;
105  POTaccumulator(POTaccumulator&&) = delete;
106  POTaccumulator& operator=(POTaccumulator const&) = delete;
108 
109  // Nothing to be done at event level.
110  virtual void
111  analyze(art::Event const& event) override
112  {}
113 
114  /// Collects information from each subrun.
115  virtual void endSubRun(art::SubRun const& subRun) override;
116 
117  /// Prints the general summary.
118  virtual void endJob() override;
119 
120 private:
121  // -- BEGIN -- Configuration variables ---------------------------------------
122 
123  art::InputTag fPOTtag; ///< Name of `sumdata::POTSummary` data product.
124  std::string fSummaryOutputCategory; ///< Name of the main stream for output.
125  std::string fRunOutputCategory; ///< Name of the run stream for output.
126 
127  // -- END -- Configuration variables -----------------------------------------
128 
129  // -- BEGIN -- Internal cache variables --------------------------------------
130 
131  /// Count of subrun fragments with POT information.
132  std::map<art::SubRunID, unsigned int> fPresentSubrunFragments;
133 
134  /// Count of subrun fragments without POT information.
135  std::map<art::SubRunID, unsigned int> fMissingSubrunFragments;
136 
137  /// Partial count of POT in the run, per run.
138  std::map<art::RunID, art::SummedValue<sumdata::POTSummary>> fRunPOT;
139 
140  // -- END -- Internal cache variables ----------------------------------------
141 
142  /// Prints the list of subruns with partial or missing POT information.
143  void printMissingSubrunList() const;
144 
145  /// Prints the list of POT per run.
146  void printRunSummary() const;
147 
148  /// Prints the total POT summary `totalPOT`.
149  void printSummary(sumdata::POTSummary const& totalPOT) const;
150 
151  /// Converts the information from `POT` in a compact string.
152  static std::string to_string(sumdata::POTSummary const& POT);
153 
154 }; // class sim::POTaccumulator
155 
156 //------------------------------------------------------------------------------
157 //--- module implementation
158 //---
159 //------------------------------------------------------------------------------
161  : EDAnalyzer(config)
162  , fPOTtag(config().SummaryTag())
165 {}
166 
167 //------------------------------------------------------------------------------
168 void
170 {
171 
172  auto const& ID = subRun.id();
173 
174  //
175  // get the information from the subrun and update the subrun counts
176  //
177  art::Handle<sumdata::POTSummary> summaryHandle;
178  if (!subRun.getByLabel(fPOTtag, summaryHandle)) {
181  << "Fragment of subrun " << ID << " has no '" << fPOTtag.encode() << "' POT summary.";
182  return;
183  }
184 
186 
187  //
188  // accumulate the information by run
189  //
190  sumdata::POTSummary const& subRunPOT = *summaryHandle;
191 
192  fRunPOT[ID.runID()].update(summaryHandle);
194  << "Fragment #" << fPresentSubrunFragments[ID] << " of subrun " << ID << ": "
195  << sim::POTaccumulator::to_string(subRunPOT);
196 
197 } // sim::POTaccumulator::endSubRun()
198 
199 //------------------------------------------------------------------------------
200 void
202 {
203 
204  //
205  // print the run summary
206  //
207 
208  if (!fRunOutputCategory.empty()) {
209 
211 
212  printRunSummary();
213 
214  } // if
215 
216  //
217  // print the total summary
218  //
219 
220  // here we skip _art_ aggregation mechanism
221  // because it can't handle multiple runs
222  sumdata::POTSummary totalPOT;
223  for (auto const& POT : fRunPOT | ranges::views::values)
224  totalPOT.aggregate(POT.value());
225 
226  printSummary(totalPOT);
227 
228 } // sim::POTaccumulator::endJob()
229 
230 //------------------------------------------------------------------------------
231 void
233 {
234 
235  //
236  // missing fragments information
237  //
239  log << size(fMissingSubrunFragments) << " subruns lack POT information:";
240 
241  auto const fend = fPresentSubrunFragments.cend();
242 
243  for (auto const& [id, nMissing] : fMissingSubrunFragments) {
244 
245  // add to the count of fragments the ones which we have actually found
246  unsigned int nFragments = nMissing;
247  auto const iFound = fPresentSubrunFragments.find(id);
248  if (iFound != fend) nFragments += iFound->second;
249 
250  log << "\n" << id << ": " << nMissing << " / " << nFragments << " \"fragments\"";
251 
252  } // for
253 
254 } // sim::POTaccumulator::printMissingSubrunList()
255 
256 //------------------------------------------------------------------------------
257 void
259 {
260 
261  // count subruns in run
262  std::map<art::RunID, unsigned int> subrunCount;
264  ++subrunCount[ID.runID()];
265 
267  log << "POT from " << size(fRunPOT) << " runs:";
268  for (auto const& [id, POT] : fRunPOT) {
269  log << "\n " << id << " (" << subrunCount[id]
270  << " subruns): " << sim::POTaccumulator::to_string(POT.value());
271  } // for
272 
273 } // sim::POTaccumulator::printRunSummary()
274 
275 //------------------------------------------------------------------------------
276 void
278 {
279 
280  // aggregate all run summaries
282  << "Aggregated POT from " << fRunPOT.size() << " runs (" << fPresentSubrunFragments.size()
283  << " subruns): " << sim::POTaccumulator::to_string(totalPOT);
284 
285 } // sim::POTaccumulator::printSummary()
286 
287 //------------------------------------------------------------------------------
290 {
291  using namespace std::string_literals;
292  return std::to_string(POT.totgoodpot) + " good POT ( "s + std::to_string(POT.goodspills) +
293  " spills); total: " + std::to_string(POT.totpot) + " POT ( "s +
294  std::to_string(POT.totspills) + " spills)";
295 } // sim::POTaccumulator::to_string(sumdata::POTSummary)
296 
297 //------------------------------------------------------------------------------
299 
300 //------------------------------------------------------------------------------
fhicl::Atom< art::InputTag > SummaryTag
POTaccumulator(Parameters const &config)
Configuration-checking constructor.
std::string string
Definition: nybbler.cc:12
unsigned int ID
std::string fSummaryOutputCategory
Name of the main stream for output.
std::map< art::RunID, art::SummedValue< sumdata::POTSummary > > fRunPOT
Partial count of POT in the run, per run.
ChannelGroupService::Name Name
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
std::string encode() const
Definition: InputTag.cc:97
fhicl::Atom< std::string > SummaryCategory
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
POTaccumulator & operator=(POTaccumulator const &)=delete
static std::string to_string(sumdata::POTSummary const &POT)
Converts the information from POT in a compact string.
virtual void endJob() override
Prints the general summary.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:633
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
fhicl::Atom< std::string > RunSummaryCategory
static Config * config
Definition: config.cpp:1054
Collection of configuration parameters for the module.
void printRunSummary() const
Prints the list of POT per run.
std::string fRunOutputCategory
Name of the run stream for output.
#define MF_LOG_TRACE(id)
void printMissingSubrunList() const
Prints the list of subruns with partial or missing POT information.
Q_UINT16 values[128]
Code to link reconstructed objects back to the MC truth information.
Prints on console the total Protons On Target from the input subruns.
void aggregate(POTSummary const &other)
Definition: POTSummary.cxx:15
#define Comment
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
virtual void analyze(art::Event const &event) override
SubRunID id() const
Definition: SubRun.cc:21
virtual void endSubRun(art::SubRun const &subRun) override
Collects information from each subrun.
std::map< art::SubRunID, unsigned int > fPresentSubrunFragments
Count of subrun fragments with POT information.
art::InputTag fPOTtag
Name of sumdata::POTSummary data product.
void printSummary(sumdata::POTSummary const &totalPOT) const
Prints the total POT summary totalPOT.
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
static QCString * s
Definition: config.cpp:1042
std::map< art::SubRunID, unsigned int > fMissingSubrunFragments
Count of subrun fragments without POT information.
Event finding and building.