All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DumpMCTruth_module.cc
Go to the documentation of this file.
1 /**
2  * @file DumpMCTruth_module.cc
3  * @brief Module dumping MCTruth information on screen.
4  * @date February 22nd, 2017
5  * @author Gianluca Petrillo (petrillo@fnal.gov)
6  *
7  * Dedication: to the memory of DumpMCTruth Sr., whose untimely departure by a
8  * rogue `rm -R` deprived us of a useful tool, and the author of a good deal of
9  * good karma.
10  *
11  */
12 
13 // LArSoft libraries
14 #include "lardataalg/MCDumpers/MCDumpers.h" // sim::dump namespace
15 
16 // nusimdata libraries
17 #include "nusimdata/SimulationBase/MCTruth.h"
18 
19 // framework libraries
20 #include "art/Framework/Core/EDAnalyzer.h"
21 #include "art/Framework/Core/ModuleMacros.h"
22 #include "art/Framework/Principal/Event.h"
23 #include "art/Framework/Principal/Handle.h"
24 #include "art/Framework/Principal/Provenance.h"
25 #include "canvas/Utilities/InputTag.h"
26 #include "fhiclcpp/types/Atom.h"
27 #include "fhiclcpp/types/OptionalSequence.h"
28 #include "messagefacility/MessageLogger/MessageLogger.h"
29 
30 #include <numeric> // std::accumulate()
31 
32 namespace sim {
33  class DumpMCTruth;
34 }
35 
36 
37 class sim::DumpMCTruth: public art::EDAnalyzer {
38  public:
39 
40  /// Collection of configuration parameters for the module
41  struct Config {
42  using Name = fhicl::Name;
43  using Comment = fhicl::Comment;
44 
45  fhicl::OptionalSequence<art::InputTag> InputTruth {
46  Name("InputTruth"),
47  Comment("data product with the collection of MC truth to be dumped")
48  };
49 
50  fhicl::Atom<std::string> OutputCategory {
51  Name("OutputCategory"),
52  Comment("name of the output stream (managed by the message facility)"),
53  "DumpMCTruth" /* default value */
54  };
55 
56  fhicl::Atom<unsigned int> PointsPerLine {
57  Name("PointsPerLine"),
58  Comment("trajectory points printed per line (default: 2; 0 = skip them)"),
59  2 /* default value */
60  };
61 
62  }; // struct Config
63 
64  /// Type to enable module parameters description by _art_.
65  using Parameters = art::EDAnalyzer::Table<Config>;
66 
67  /// Configuration-checking constructor.
68  explicit DumpMCTruth(Parameters const& config);
69 
70  // Plugins should not be copied or assigned.
71  DumpMCTruth(DumpMCTruth const&) = delete;
72  DumpMCTruth(DumpMCTruth &&) = delete;
73  DumpMCTruth& operator = (DumpMCTruth const&) = delete;
74  DumpMCTruth& operator = (DumpMCTruth &&) = delete;
75 
76 
77  // Operates on the event
78  void analyze(art::Event const& event) override;
79 
80 
81  /// Returns the name of the product in the form `"module_instance_process"`.
82  template <typename Handle>
83  static std::string productName(Handle const& handle);
84 
85 
86  private:
87 
88  std::vector<art::InputTag> fInputTruth; ///< Name of MCTruth data products.
89  std::string fOutputCategory; ///< Name of the stream for output.
90  bool bAllTruth = false; ///< Whether to process all MCTruth collections.
91 
92  unsigned int fPointsPerLine; ///< trajectory points per output line
93 
94 
95 }; // class sim::DumpMCTruth
96 
97 
98 //------------------------------------------------------------------------------
99 //--- module implementation
100 //---
101 //------------------------------------------------------------------------------
103  : EDAnalyzer(config)
104  , fInputTruth()
105  , fOutputCategory(config().OutputCategory())
106  , bAllTruth(!config().InputTruth(fInputTruth)) // true if InputTruth omitted
107  , fPointsPerLine(config().PointsPerLine())
108  {}
109 
110 
111 //------------------------------------------------------------------------------
112 void sim::DumpMCTruth::analyze(art::Event const& event) {
113 
114  //
115  // prepare the data products to be dumped
116  //
117  struct ProductInfo_t {
118  using Thruths_t = std::vector<simb::MCTruth>;
119  Thruths_t const* truths;
120  std::string name;
121 
122  ProductInfo_t(art::Handle<Thruths_t> const& handle)
123  : truths(handle.provenance()->isPresent()? handle.product(): nullptr)
125  {}
126  ProductInfo_t(art::ValidHandle<Thruths_t> const& handle)
127  : truths(handle.product()), name(sim::DumpMCTruth::productName(handle))
128  {}
129 
130  }; // ProductInfo_t
131 
132  std::vector<ProductInfo_t> AllTruths;
133  if (bAllTruth) {
134  //std::vector<art::Handle<std::vector<simb::MCTruth>>> handles;
135  //event.getManyByType(handles);
136  auto handles = event.getMany<std::vector<simb::MCTruth>>();
137  std::copy(handles.begin(), handles.end(), std::back_inserter(AllTruths));
138  }
139  else {
140  for (auto const& inputTag: fInputTruth) {
141  AllTruths.emplace_back
142  (event.getValidHandle<std::vector<simb::MCTruth>>(inputTag));
143  } // for
144  }
145 
146  //
147  // sanity check
148  //
149  if (AllTruths.empty()) {
150  throw art::Exception(art::errors::ProductNotFound)
151  << "No MC truth found to be dumped!\n";
152  }
153 
154  //
155  // print an introduction
156  //
157  unsigned int const nTruths = std::accumulate(
158  AllTruths.begin(), AllTruths.end(), 0U,
159  [](unsigned int total, auto const& info)
160  { return total + (info.truths? info.truths->size(): 0); }
161  );
162 
163  if (bAllTruth) {
164  mf::LogVerbatim(fOutputCategory) << "Event " << event.id()
165  << " contains " << nTruths << " MC truth blocks in "
166  << AllTruths.size() << " collections";
167  }
168  else if (AllTruths.size() == 1) {
169  mf::LogVerbatim(fOutputCategory) << "Event " << event.id();
170  }
171  else {
172  mf::LogVerbatim(fOutputCategory) << "Dumping " << nTruths
173  << " MC truth blocks from " << AllTruths.size()
174  << " collections in event " << event.id();
175  }
176 
177  //
178  // dump data product by data product
179  //
180  unsigned int nParticles = 0, nNeutrinos = 0;
181  for (ProductInfo_t const& truths_info: AllTruths) {
182 
183  auto const* truths = truths_info.truths;
184  std::string productName = truths_info.name;
185 
186  if (!truths) {
187  mf::LogVerbatim(fOutputCategory)
188  << "Data product '" << productName
189  << "' has been dropped. No information available.";
190  }
191 
192  if (AllTruths.size() > 1) {
193  mf::LogVerbatim(fOutputCategory)
194  << "Data product '" << productName
195  << "' contains " << truths->size() << " truth blocks:";
196  }
197  else if (truths->size() > 1) {
198  mf::LogVerbatim(fOutputCategory)
199  << truths->size() << " truth blocks:";
200  }
201 
202  //
203  // dump each MC truth in the data product
204  //
205  unsigned int iTruth = 0;
206  for (auto const& truth: *truths) {
207 
208  mf::LogVerbatim log (fOutputCategory);
209 
210  if (truths->size() > 1) log << "(#" << iTruth << ") ";
211  sim::dump::DumpMCTruth(log, truth, " ", "");
212 
213  //
214  // update counters
215  //
216  ++iTruth;
217  nParticles += truth.NParticles();
218  if (truth.NeutrinoSet()) ++nNeutrinos;
219 
220  } // for each truth in data product
221 
222  } // for truth data products
223 
224  //
225  // all done
226  //
227  mf::LogVerbatim(fOutputCategory) << nNeutrinos
228  << " neutrinos generated, " << nParticles
229  << " generated particles to be simulated downstream.";
230 
231 } // sim::DumpMCTruth::analyze()
232 
233 
234 //------------------------------------------------------------------------------
235 template <typename Handle>
236 std::string sim::DumpMCTruth::productName(Handle const& handle) {
237  auto const* prov = handle.provenance();
238  return prov->moduleLabel()
239  + '_' + prov->productInstanceName()
240  + '_' + prov->processName()
241  ;
242 } // sim::DumpMCTruth::productName()
243 
244 
245 //------------------------------------------------------------------------------
246 DEFINE_ART_MODULE(sim::DumpMCTruth)
247 
248 //------------------------------------------------------------------------------
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.
unsigned int fPointsPerLine
trajectory points per output line
void analyze(art::Event const &event) override
Utility functions to print MC truth information.
art::EDAnalyzer::Table< Config > Parameters
Type to enable module parameters description by art.
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:346
BEGIN_PROLOG vertical distance to the surface Name
bool bAllTruth
Whether to process all MCTruth collections.
DumpMCTruth(Parameters const &config)
Configuration-checking constructor.
std::string fOutputCategory
Name of the stream for output.
T copy(T const &v)
then echo fcl name
static std::string productName(Handle const &handle)
Returns the name of the product in the form &quot;module_instance_process&quot;.
std::vector< art::InputTag > fInputTruth
Name of MCTruth data products.