All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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
12 #include "art/Framework/Core/EDAnalyzer.h"
13 #include "art/Framework/Core/ModuleMacros.h"
14 #include "art/Framework/Principal/Handle.h"
15 #include "art/Framework/Principal/SubRun.h"
16 #include "art/Framework/Principal/SummedValue.h"
17 #include "canvas/Utilities/InputTag.h"
18 #include "fhiclcpp/types/Atom.h"
19 #include "messagefacility/MessageLogger/MessageLogger.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  */
71 class sim::POTaccumulator : public art::EDAnalyzer {
72 public:
73  /// Collection of configuration parameters for the module
74  struct Config {
75  using Name = fhicl::Name;
76  using Comment = fhicl::Comment;
77 
78  fhicl::Atom<art::InputTag> SummaryTag{
79  Name("SummaryTag"),
80  Comment("data product (subrun level) with the summary information"),
81  "generator"};
82 
83  fhicl::Atom<std::string> SummaryCategory{
84  Name("SummaryCategory"),
85  Comment("name of the output category the summary is sent to"),
86  "POTaccumulator" // default value
87  };
88 
89  fhicl::Atom<std::string> RunSummaryCategory{
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_.
98  using Parameters = art::EDAnalyzer::Table<Config>;
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())
163  , fSummaryOutputCategory(config().SummaryCategory())
164  , fRunOutputCategory(config().RunSummaryCategory())
165 {}
166 
167 //------------------------------------------------------------------------------
168 void
169 sim::POTaccumulator::endSubRun(art::SubRun const& subRun)
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)) {
179  ++fMissingSubrunFragments[ID];
180  mf::LogDebug(fSummaryOutputCategory)
181  << "Fragment of subrun " << ID << " has no '" << fPOTtag.encode() << "' POT summary.";
182  return;
183  }
184 
185  ++fPresentSubrunFragments[ID];
186 
187  //
188  // accumulate the information by run
189  //
190  sumdata::POTSummary const& subRunPOT = *summaryHandle;
191 
192  fRunPOT[ID.runID()].update(summaryHandle);
193  MF_LOG_TRACE(fSummaryOutputCategory)
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 
210  if (!fMissingSubrunFragments.empty()) printMissingSubrunList();
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  //
238  mf::LogVerbatim log{fRunOutputCategory};
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;
263  for (art::SubRunID const& ID : fPresentSubrunFragments | ranges::views::keys)
264  ++subrunCount[ID.runID()];
265 
266  mf::LogVerbatim log{fRunOutputCategory};
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
281  mf::LogVerbatim{fSummaryOutputCategory}
282  << "Aggregated POT from " << fRunPOT.size() << " runs (" << fPresentSubrunFragments.size()
283  << " subruns): " << sim::POTaccumulator::to_string(totalPOT);
284 
285 } // sim::POTaccumulator::printSummary()
286 
287 //------------------------------------------------------------------------------
288 std::string
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 //------------------------------------------------------------------------------
298 DEFINE_ART_MODULE(sim::POTaccumulator)
299 
300 //------------------------------------------------------------------------------
fhicl::Atom< art::InputTag > SummaryTag
POTaccumulator(Parameters const &config)
Configuration-checking constructor.
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.
double POT
std::size_t size(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:561
fhicl::Atom< std::string > SummaryCategory
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.
fhicl::Atom< std::string > RunSummaryCategory
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.
void printMissingSubrunList() const
Prints the list of subruns with partial or missing POT information.
BEGIN_PROLOG vertical distance to the surface Name
Prints on console the total Protons On Target from the input subruns.
void aggregate(POTSummary const &other)
Definition: POTSummary.cxx:15
art::EDAnalyzer::Table< Config > Parameters
Type to enable module parameters description by art.
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
virtual void analyze(art::Event const &event) override
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::map< art::SubRunID, unsigned int > fMissingSubrunFragments
Count of subrun fragments without POT information.