LArSoft  v10_06_00
Liquid Argon Software toolkit - https://larsoft.org/
MergeSimSources_module.cc
Go to the documentation of this file.
1 // Class: MergeSimSources
3 // Module Type: producer
4 // File: MergeSimSources_module.cc
5 //
6 // Generated at Tue Feb 17 12:16:35 2015 by Wesley Ketchum using artmod
7 // from cetpkgsupport v1_08_02.
9 
17 #include "fhiclcpp/ParameterSet.h"
18 #include "fhiclcpp/types/Atom.h"
22 
26 
27 #include "range/v3/view/zip.hpp"
28 
29 #include <memory>
30 #include <optional>
31 #include <string>
32 #include <utility>
33 #include <vector>
34 
35 #include "MergeSimSources.h"
46 
47 namespace sim {
48  class MergeSimSources;
49 }
50 
52 public:
53  struct Config {
54 
56  fhicl::Name{"InputSourcesLabels"},
57  fhicl::Comment{"label of the LArG4 products to merge"}};
58 
60  fhicl::Name{"TrackIDOffsets"},
61  fhicl::Comment{"offset to add to the MC particles from each source"}};
62 
64  fhicl::Name{"StoreReflected"},
65  fhicl::Comment{"whether to merge also photons from reflections"},
66  false // default
67  };
68 
70  fhicl::Name{"FillMCParticles"},
71  fhicl::Comment{"whether to merge MCParticle"},
72  true // default
73  };
74 
76  fhicl::Name{"FillSimPhotons"},
77  fhicl::Comment{"whether to merge SimPhotons"},
78  true // default
79  };
80 
82  fhicl::Name{"FillSimChannels"},
83  fhicl::Comment{"whether to merge SimChannels"},
84  true // default
85  };
86 
88  fhicl::Name{"SkipTrackIDOffsets"},
89  fhicl::Comment{"skip the application of trackID offsets"},
90  false // default
91  };
92 
94  fhicl::Name{"FillAuxDetSimChannels"},
95  fhicl::Comment{"whether to merge AuxDetSimChannels"},
96  true // default
97  };
98 
100  fhicl::Name{"FillSimEnergyDeposits"},
101  fhicl::Comment{"merges energy deposit collection; if omitted, follows LArG4Parmeters"}};
102 
104  fhicl::Name{"EnergyDepositInstanceLabels"},
105  fhicl::Comment{"labels of sim::SimEnergyDeposit collections to merge"},
106  std::vector<std::string>{"TPCActive", "Other"} // default
107  };
108 
110  fhicl::Name{"FillAuxDetHits"},
111  fhicl::Comment{"whether to merge aux det hit collections"},
112  false // default
113  };
114 
116  fhicl::Name{"AuxDetHitsInstanceLabels"},
117  fhicl::Comment{"labels of AuxDetHits collections to merge"},
118  std::vector<std::string>{"LArG4DetectorServicevolAuxDetSensitiveCRTStripY",
119  "Other"} // default
120  };
121 
123  fhicl::Name{"FillParticleAncestryMaps"},
124  fhicl::Comment{"whether to merge particle ancestry maps"},
125  true};
126 
127  }; // struct Config
128 
130 
131  explicit MergeSimSources(Parameters const& config);
132 
133  // Required functions.
134  void produce(art::Event& e) override;
135 
136 private:
137  std::vector<art::InputTag> const fInputSourcesLabels;
138  std::vector<int> const fTrackIDOffsets;
139  bool const fUseLitePhotons;
140  bool const fStoreReflected;
141  bool const fFillMCParticles;
142  bool const fFillSimPhotons;
143  bool const fFillSimChannels;
147  std::vector<std::string> const fEnergyDepositionInstances;
148  bool const fFillAuxDetHits;
149  std::vector<std::string> const fAuxDetHitsInstanceLabels;
151 
152  static std::string const ReflectedLabel;
153 
154  void dumpConfiguration() const;
155 };
156 
157 namespace {
158 
159  template <typename Optional>
160  std::optional<typename Optional::value_type> getOptionalValue(Optional const& parameter)
161  {
162 
163  using Value_t = typename Optional::value_type;
164 
165  if (!parameter.hasValue()) return std::nullopt;
166 
167  Value_t value;
168  parameter(value);
169  return {value};
170 
171  } // getOptionalValue(Optional& parameter)
172 
173 } // local namespace
174 
175 std::string const sim::MergeSimSources::ReflectedLabel{"Reflected"};
176 
178  : EDProducer{params}
179  , fInputSourcesLabels(params().InputSourcesLabels())
180  , fTrackIDOffsets(params().TrackIDOffsets())
182  , fStoreReflected(params().StoreReflected())
183  , fFillMCParticles(params().FillMCParticles())
184  , fFillSimPhotons(params().FillSimPhotons())
185  , fFillSimChannels(params().FillSimChannels())
186  , fSkipTrackIDOffsets(params().SkipTrackIDOffsets())
187  , fFillAuxDetSimChannels(params().FillAuxDetSimChannels())
189  getOptionalValue(params().FillSimEnergyDeposits)
190  .value_or(art::ServiceHandle<sim::LArG4Parameters const>()->FillSimEnergyDeposits()))
191  , fEnergyDepositionInstances(params().EnergyDepositInstanceLabels())
192  , fFillAuxDetHits(params().FillAuxDetHits())
193  , fAuxDetHitsInstanceLabels(params().AuxDetHitsInstanceLabels())
194  , fFillParticleAncestryMaps(params().FillParticleAncestryMaps())
195 {
196 
197  if (fSkipTrackIDOffsets == false && fInputSourcesLabels.size() != fTrackIDOffsets.size()) {
199  << "Unequal input vector sizes: InputSourcesLabels and TrackIDOffsets.\n";
200  }
201 
202  for (art::InputTag const& tag : fInputSourcesLabels) {
203 
204  if (fFillMCParticles) {
205  consumes<std::vector<simb::MCParticle>>(tag);
206  consumes<art::Assns<simb::MCParticle, simb::MCTruth, sim::GeneratedParticleInfo>>(tag);
207  }
208 
209  if (fFillSimChannels) { consumes<std::vector<sim::SimChannel>>(tag); }
210 
211  if (fFillAuxDetSimChannels) { consumes<std::vector<sim::AuxDetSimChannel>>(tag); }
212 
213  if (fFillSimPhotons) {
214  if (!fUseLitePhotons)
215  consumes<std::vector<sim::SimPhotons>>(tag);
216  else
217  consumes<std::vector<sim::SimPhotonsLite>>(tag);
218 
219  if (fStoreReflected) {
220  art::InputTag const reflected_tag{tag.label(), ReflectedLabel};
221  if (!fUseLitePhotons)
222  consumes<std::vector<sim::SimPhotons>>(reflected_tag);
223  else
224  consumes<std::vector<sim::SimPhotonsLite>>(reflected_tag);
225  }
226  }
227 
229  for (std::string const& edep_inst : fEnergyDepositionInstances) {
230  art::InputTag const edep_tag{tag.label(), edep_inst};
231  consumes<std::vector<sim::SimEnergyDeposit>>(edep_tag);
232  }
233  } // if fill energy deposits
234 
235  if (fFillAuxDetHits) {
236  for (std::string const& auxdethit_inst : fAuxDetHitsInstanceLabels) {
237  art::InputTag const auxdethit_tag{tag.label(), auxdethit_inst};
238  consumes<std::vector<sim::AuxDetHit>>(auxdethit_tag);
239  }
240  }
241 
242  if (fFillParticleAncestryMaps) { consumes<sim::ParticleAncestryMap>(tag); }
243 
244  } // for input labels
245 
246  if (fFillMCParticles) {
247  produces<std::vector<simb::MCParticle>>();
248  produces<art::Assns<simb::MCTruth, simb::MCParticle, sim::GeneratedParticleInfo>>();
249  }
250  if (fFillSimChannels) { produces<std::vector<sim::SimChannel>>(); }
251  if (fFillAuxDetSimChannels) { produces<std::vector<sim::AuxDetSimChannel>>(); }
252 
253  if (fFillSimPhotons) {
254  if (!fUseLitePhotons)
255  produces<std::vector<sim::SimPhotons>>();
256  else
257  produces<std::vector<sim::SimPhotonsLite>>();
258 
259  if (fStoreReflected) {
260  if (!fUseLitePhotons)
261  produces<std::vector<sim::SimPhotons>>(ReflectedLabel);
262  else
263  produces<std::vector<sim::SimPhotonsLite>>(ReflectedLabel);
264  }
265  }
266 
268  for (std::string const& edep_inst : fEnergyDepositionInstances)
269  produces<std::vector<sim::SimEnergyDeposit>>(edep_inst);
270  } // if
271 
272  if (fFillAuxDetHits) {
273  for (std::string const& auxdethit_inst : fAuxDetHitsInstanceLabels)
274  produces<std::vector<sim::AuxDetHit>>(auxdethit_inst);
275  }
276 
277  if (fFillParticleAncestryMaps) { produces<std::vector<sim::ParticleAncestryMap>>(); }
278 
280 }
281 
283 {
284 
285  auto partCol = std::make_unique<std::vector<simb::MCParticle>>();
286  auto scCol = std::make_unique<std::vector<sim::SimChannel>>();
287  auto PhotonCol = std::make_unique<std::vector<sim::SimPhotons>>();
288  auto LitePhotonCol = std::make_unique<std::vector<sim::SimPhotonsLite>>();
289  auto ReflPhotonCol = std::make_unique<std::vector<sim::SimPhotons>>();
290  auto ReflLitePhotonCol = std::make_unique<std::vector<sim::SimPhotonsLite>>();
291  auto tpassn =
292  std::make_unique<art::Assns<simb::MCTruth, simb::MCParticle, sim::GeneratedParticleInfo>>();
293  auto adCol = std::make_unique<std::vector<sim::AuxDetSimChannel>>();
294  auto pamCol = std::make_unique<std::vector<sim::ParticleAncestryMap>>();
295 
296  using edeps_t = std::vector<sim::SimEnergyDeposit>;
297  std::vector<edeps_t> edepCols;
298  if (fFillSimEnergyDeposits) edepCols.resize(fEnergyDepositionInstances.size());
299 
300  using aux_det_hits_t = std::vector<sim::AuxDetHit>;
301  std::vector<aux_det_hits_t> auxdethitCols;
302  if (fFillAuxDetHits) auxdethitCols.resize(fAuxDetHitsInstanceLabels.size());
303 
305 
306  for (auto const& [i_source, input_label] : fInputSourcesLabels | ranges::views::enumerate) {
307 
308  if (fFillMCParticles) {
309  art::PtrMaker<simb::MCParticle> const makePartPtr{e};
310  auto const input_partCol = e.getValidHandle<std::vector<simb::MCParticle>>(input_label);
311  MergeUtility.MergeMCParticles(*partCol, *input_partCol, i_source);
312 
313  //truth-->particle assoc stuff here
314  const std::vector<size_t>& assocVectorPrimitive =
315  MergeUtility.GetMCParticleListMap().at(i_source);
317  input_partCol, e, input_label);
318  for (auto const i_p : util::counter(mctAssn.size()))
319  tpassn->addSingle(
320  mctAssn.at(i_p), makePartPtr(assocVectorPrimitive[i_p]), mctAssn.data(i_p).ref());
321  }
322 
323  if (fFillSimChannels) {
324  auto const& input_scCol = e.getProduct<std::vector<sim::SimChannel>>(input_label);
325  MergeUtility.MergeSimChannels(*scCol, input_scCol, i_source, fSkipTrackIDOffsets);
326 
327  /*
328  for (auto& simChannel : *scCol) {
329  auto& tdcIDEMap = simChannel.TDCIDEMap();
330  std::map<int, std::vector<sim::IDE>> sortedTDCIDEMap;
331  for (auto& entry : tdcIDEMap) {
332  sortedTDCIDEMap[entry.first] = std::move(entry.second);
333  }
334  simChannel.SetTDCIDEMap(std::move(sortedTDCIDEMap));
335  }
336  */
337  }
338 
340  auto const& input_adCol = e.getProduct<std::vector<sim::AuxDetSimChannel>>(input_label);
341  MergeUtility.MergeAuxDetSimChannels(*adCol, input_adCol, i_source);
342  }
343 
344  if (fFillSimPhotons) {
345  if (!fUseLitePhotons) {
346  auto const& input_PhotonCol = e.getProduct<std::vector<sim::SimPhotons>>(input_label);
347  MergeUtility.MergeSimPhotons(*PhotonCol, input_PhotonCol);
348  }
349  else {
350  auto const& input_LitePhotonCol =
351  e.getProduct<std::vector<sim::SimPhotonsLite>>(input_label);
352  MergeUtility.MergeSimPhotonsLite(*LitePhotonCol, input_LitePhotonCol);
353  }
354 
355  if (fStoreReflected) {
356  art::InputTag const input_reflected_label{input_label.label(), ReflectedLabel};
357  if (!fUseLitePhotons) {
358  auto const& input_PhotonCol =
359  e.getProduct<std::vector<sim::SimPhotons>>(input_reflected_label);
360  MergeUtility.MergeSimPhotons(*ReflPhotonCol, input_PhotonCol);
361  }
362  else {
363  auto const& input_LitePhotonCol =
364  e.getProduct<std::vector<sim::SimPhotonsLite>>(input_reflected_label);
365  MergeUtility.MergeSimPhotonsLite(*ReflLitePhotonCol, input_LitePhotonCol);
366  }
367  }
368  }
369 
371  for (auto const& [edep_inst, edepCol] :
373  art::InputTag const edep_tag{input_label.label(), edep_inst};
374  MergeUtility.MergeSimEnergyDeposits(edepCol, e.getProduct<edeps_t>(edep_tag), i_source);
375  } // for edep
376  } // if fill energy depositions
377 
378  if (fFillAuxDetHits) {
379  for (auto const& [auxdethit_inst, auxdethitCol] :
381  art::InputTag const auxdethit_tag{input_label.label(), auxdethit_inst};
382  MergeUtility.MergeAuxDetHits(
383  auxdethitCol, e.getProduct<aux_det_hits_t>(auxdethit_tag), i_source);
384  }
385 
387  auto const& input_pamCol = e.getProduct<sim::ParticleAncestryMap>(input_label);
388  MergeUtility.MergeParticleAncestryMaps(*pamCol, input_pamCol, i_source);
389  }
390  }
391  }
392 
393  if (fFillMCParticles) {
394  e.put(std::move(partCol));
395  e.put(std::move(tpassn));
396  }
397  if (fFillSimChannels) { e.put(std::move(scCol)); }
398  if (fFillAuxDetSimChannels) { e.put(std::move(adCol)); }
399  if (fFillSimPhotons) {
400  if (!fUseLitePhotons)
401  e.put(std::move(PhotonCol));
402  else
403  e.put(std::move(LitePhotonCol));
404  if (fStoreReflected) {
405  if (!fUseLitePhotons)
406  e.put(std::move(ReflPhotonCol), ReflectedLabel);
407  else
408  e.put(std::move(ReflLitePhotonCol), ReflectedLabel);
409  }
410  }
411 
413  for (auto&& [edep_inst, edepCol] : ranges::views::zip(fEnergyDepositionInstances, edepCols)) {
414  e.put(std::make_unique<edeps_t>(move(edepCol)), edep_inst);
415  } // for
416  } // if fill energy deposits
417 
418  if (fFillAuxDetHits) {
419  for (auto&& [auxdethit_inst, auxdethitCol] :
421  e.put(std::make_unique<aux_det_hits_t>(move(auxdethitCol)), auxdethit_inst);
422  }
423  }
424 
425  if (fFillParticleAncestryMaps) { e.put(std::move(pamCol)); }
426 }
427 
429 {
430 
431  mf::LogInfo log("MergeSimSources");
432  log << "Configuration:"
433  << "\n - " << fInputSourcesLabels.size() << " input sources:";
434  for (auto const& [i_source, tag, offset] :
436  log << "\n [" << i_source << "] '" << tag.encode() << "' (ID offset: " << offset << ")";
437  } // for
438  if (fFillMCParticles) log << "\n - filling MCParticles";
439 
440  if (fFillSimChannels) log << "\n - filling SimChannels";
441 
442  if (fFillAuxDetSimChannels) log << "\n - filling AuxDetSimChannels";
443 
444  if (fFillSimPhotons) {
445  log << "\n - filling Simulated Photons";
446  if (fUseLitePhotons)
447  log << "\n - using photon summary (`SimPhotonsLite`)";
448  else
449  log << "\n - using detailed photons (`SimPhotons`)";
450  if (fStoreReflected) log << "\n - also merging reflected light";
451  }
452 
454  log << "\n - filling simulated energy deposits (" << fEnergyDepositionInstances.size()
455  << " labels:";
456  for (std::string const& label : fEnergyDepositionInstances)
457  log << " '" << label << "'";
458  log << ")";
459  }
460 
461  if (fFillAuxDetHits) {
462  log << "\n - filling auxiliary detector hits (" << fAuxDetHitsInstanceLabels.size()
463  << " labels:";
464  for (std::string const& label : fAuxDetHitsInstanceLabels)
465  log << " '" << label << "'";
466  log << ")";
467  }
468 
469  if (fFillParticleAncestryMaps) log << "\n - filling ParticleAncestryMaps";
470 
471 } // sim::MergeSimSources::dumpConfiguration()
472 
Store parameters for running LArG4.
MergeSimSources(Parameters const &config)
fhicl::Sequence< int > TrackIDOffsets
Definition of util::enumerate().
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.cc:6
fhicl::Atom< bool > FillAuxDetSimChannels
Contains data associated to particles from detector simulation.
Particle class.
fhicl::OptionalAtom< bool > FillSimEnergyDeposits
fhicl::Sequence< std::string > EnergyDepositInstanceLabels
std::vector< art::InputTag > const fInputSourcesLabels
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: Event.h:77
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:49
std::string const & label() const noexcept
Definition: InputTag.cc:79
Simulation objects for optical detectors.
std::vector< std::string > const fAuxDetHitsInstanceLabels
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Definition: counter.h:292
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
std::vector< int > const fTrackIDOffsets
Test of util::counter and support utilities.
Monte Carlo Simulation.
double value
Definition: spectrum.C:18
void produce(art::Event &e) override
fhicl::Sequence< std::string > AuxDetHitsInstanceLabels
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
static std::string const ReflectedLabel
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
contains information for a single step in the detector simulation
object containing MC truth information necessary for making RawDigits and doing back tracking ...
auto zip(Iterables &&...iterables)
Range-for loop helper iterating across many collections at the same time.
Definition: zip.h:232
cet::maybe_ref< Data const > data(size_type i) const
Definition: FindOneP.h:491
fhicl::Atom< bool > FillParticleAncestryMaps
Float_t e
Definition: plot.C:35
PROD const & getProduct(InputTag const &tag) const
fhicl::Sequence< art::InputTag > InputSourcesLabels
std::vector< std::string > const fEnergyDepositionInstances