LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
DumpMCTruth_module.cc
Go to the documentation of this file.
1 
13 // LArSoft libraries
14 #include "lardataalg/MCDumpers/MCDumpers.h" // sim::dump namespace
15 
16 // nusimdata libraries
18 
19 // framework libraries
26 #include "fhiclcpp/types/Atom.h"
29 
30 #include <numeric> // std::accumulate()
31 
32 namespace sim {
33  class DumpMCTruth;
34 }
35 
37 public:
39  struct Config {
40  using Name = fhicl::Name;
42 
44  Name("InputTruth"),
45  Comment("data product with the collection of MC truth to be dumped")};
46 
48  Name("OutputCategory"),
49  Comment("name of the output stream (managed by the message facility)"),
50  "DumpMCTruth" /* default value */
51  };
52 
54  Name("PointsPerLine"),
55  Comment("trajectory points printed per line (default: 2; 0 = skip them)"),
56  2 /* default value */
57  };
58 
59  }; // struct Config
60 
63 
65  explicit DumpMCTruth(Parameters const& config);
66 
67  // Plugins should not be copied or assigned.
68  DumpMCTruth(DumpMCTruth const&) = delete;
69  DumpMCTruth(DumpMCTruth&&) = delete;
70  DumpMCTruth& operator=(DumpMCTruth const&) = delete;
71  DumpMCTruth& operator=(DumpMCTruth&&) = delete;
72 
73  // Operates on the event
74  void analyze(art::Event const& event) override;
75 
77  template <typename Handle>
78  static std::string productName(Handle const& handle);
79 
80 private:
81  std::vector<art::InputTag> fInputTruth;
82  std::string fOutputCategory;
83  bool bAllTruth = false;
84 
85  unsigned int fPointsPerLine;
86 
87 }; // class sim::DumpMCTruth
88 
89 //------------------------------------------------------------------------------
90 //--- module implementation
91 //---
92 //------------------------------------------------------------------------------
94  : EDAnalyzer(config)
95  , fInputTruth()
96  , fOutputCategory(config().OutputCategory())
97  , bAllTruth(!config().InputTruth(fInputTruth)) // true if InputTruth omitted
98  , fPointsPerLine(config().PointsPerLine())
99 {}
100 
101 //------------------------------------------------------------------------------
103 {
104 
105  //
106  // prepare the data products to be dumped
107  //
108  struct ProductInfo_t {
109  using Thruths_t = std::vector<simb::MCTruth>;
110  Thruths_t const* truths;
111  std::string name;
112 
113  ProductInfo_t(art::Handle<Thruths_t> const& handle)
114  : truths(handle.provenance()->isPresent() ? handle.product() : nullptr)
115  , name(sim::DumpMCTruth::productName(handle))
116  {}
117  ProductInfo_t(art::ValidHandle<Thruths_t> const& handle)
118  : truths(handle.product()), name(sim::DumpMCTruth::productName(handle))
119  {}
120 
121  }; // ProductInfo_t
122 
123  std::vector<ProductInfo_t> AllTruths;
124  if (bAllTruth) {
125  //std::vector<art::Handle<std::vector<simb::MCTruth>>> handles;
126  //event.getManyByType(handles);
127  auto handles = event.getMany<std::vector<simb::MCTruth>>();
128  std::copy(handles.begin(), handles.end(), std::back_inserter(AllTruths));
129  }
130  else {
131  for (auto const& inputTag : fInputTruth) {
132  AllTruths.emplace_back(event.getValidHandle<std::vector<simb::MCTruth>>(inputTag));
133  } // for
134  }
135 
136  //
137  // sanity check
138  //
139  if (AllTruths.empty()) {
140  throw art::Exception(art::errors::ProductNotFound) << "No MC truth found to be dumped!\n";
141  }
142 
143  //
144  // print an introduction
145  //
146  unsigned int const nTruths = std::accumulate(
147  AllTruths.begin(), AllTruths.end(), 0U, [](unsigned int total, auto const& info) {
148  return total + (info.truths ? info.truths->size() : 0);
149  });
150 
151  if (bAllTruth) {
153  << "Event " << event.id() << " contains " << nTruths << " MC truth blocks in "
154  << AllTruths.size() << " collections";
155  }
156  else if (AllTruths.size() == 1) {
157  mf::LogVerbatim(fOutputCategory) << "Event " << event.id();
158  }
159  else {
160  mf::LogVerbatim(fOutputCategory) << "Dumping " << nTruths << " MC truth blocks from "
161  << AllTruths.size() << " collections in event " << event.id();
162  }
163 
164  //
165  // dump data product by data product
166  //
167  unsigned int nParticles = 0, nNeutrinos = 0;
168  for (ProductInfo_t const& truths_info : AllTruths) {
169 
170  auto const* truths = truths_info.truths;
171  std::string productName = truths_info.name;
172 
173  if (!truths) {
175  << "Data product '" << productName << "' has been dropped. No information available.";
176  }
177 
178  if (AllTruths.size() > 1) {
180  << "Data product '" << productName << "' contains " << truths->size() << " truth blocks:";
181  }
182  else if (truths->size() > 1) {
183  mf::LogVerbatim(fOutputCategory) << truths->size() << " truth blocks:";
184  }
185 
186  //
187  // dump each MC truth in the data product
188  //
189  unsigned int iTruth = 0;
190  for (auto const& truth : *truths) {
191 
193 
194  if (truths->size() > 1) log << "(#" << iTruth << ") ";
195  sim::dump::DumpMCTruth(log, truth, " ", "");
196 
197  //
198  // update counters
199  //
200  ++iTruth;
201  nParticles += truth.NParticles();
202  if (truth.NeutrinoSet()) ++nNeutrinos;
203 
204  } // for each truth in data product
205 
206  } // for truth data products
207 
208  //
209  // all done
210  //
211  mf::LogVerbatim(fOutputCategory) << nNeutrinos << " neutrinos generated, " << nParticles
212  << " generated particles to be simulated downstream.";
213 
214 } // sim::DumpMCTruth::analyze()
215 
216 //------------------------------------------------------------------------------
217 template <typename Handle>
218 std::string sim::DumpMCTruth::productName(Handle const& handle)
219 {
220  auto const* prov = handle.provenance();
221  return prov->moduleLabel() + '_' + prov->productInstanceName() + '_' + prov->processName();
222 } // sim::DumpMCTruth::productName()
223 
224 //------------------------------------------------------------------------------
226 
227 //------------------------------------------------------------------------------
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
fhicl::Atom< unsigned int > PointsPerLine
DumpMCTruth & operator=(DumpMCTruth const &)=delete
fhicl::OptionalSequence< art::InputTag > InputTruth
fhicl::Atom< std::string > OutputCategory
Collection of configuration parameters for the module.
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.cc:6
unsigned int fPointsPerLine
trajectory points per output line
T const * product() const
Definition: Handle.h:363
void analyze(art::Event const &event) override
T const * product() const
Definition: Handle.h:174
Utility functions to print MC truth information.
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
Provenance const * provenance() const
Definition: Handle.h:217
void DumpMCTruth(Stream &&out, simb::MCTruth const &truth, unsigned int pointsPerLine, std::string indent, std::string firstIndent)
Dumps the content of the specified MC truth in the output stream.
Definition: MCDumpers.h:338
bool bAllTruth
Whether to process all MCTruth collections.
DumpMCTruth(Parameters const &config)
Configuration-checking constructor.
Monte Carlo Simulation.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
std::string fOutputCategory
Name of the stream for output.
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
static std::string productName(Handle const &handle)
Returns the name of the product in the form "module_instance_process".
Event finding and building.
std::vector< art::InputTag > fInputTruth
Name of MCTruth data products.