10 #include "art/Framework/Core/EDProducer.h"
11 #include "art/Framework/Core/ModuleMacros.h"
12 #include "art/Framework/Principal/Event.h"
13 #include "art/Framework/Principal/Handle.h"
14 #include "art/Framework/Services/Registry/ServiceHandle.h"
15 #include "canvas/Utilities/InputTag.h"
16 #include "canvas/Utilities/Exception.h"
17 #include "messagefacility/MessageLogger/MessageLogger.h"
18 #include "fhiclcpp/types/Sequence.h"
19 #include "fhiclcpp/types/Atom.h"
20 #include "fhiclcpp/types/OptionalAtom.h"
21 #include "fhiclcpp/ParameterSet.h"
23 #include "art/Persistency/Common/PtrMaker.h"
24 #include "canvas/Persistency/Common/Assns.h"
25 #include "canvas/Persistency/Common/FindOneP.h"
38 #include "nusimdata/SimulationBase/MCTruth.h"
39 #include "nusimdata/SimulationBase/MCParticle.h"
47 class MergeSimSources;
57 fhicl::Comment{
"label of the LArG4 products to merge" }
62 fhicl::Comment{
"offset to add to the MC particles from each source" }
67 fhicl::Comment{
"whether to merge also photons from reflections" },
73 fhicl::Comment{
"whether to merge MCParticle" },
79 fhicl::Comment{
"whether to merge SimPhotons" },
85 fhicl::Comment{
"whether to merge SimChannels" },
91 fhicl::Comment{
"whether to merge AuxDetSimChannels" },
98 {
"merges energy deposit collection; if omitted, follows LArG4Parmeters" }
103 fhicl::Comment{
"labels of sim::SimEnergyDeposit collections to merge" },
104 std::vector<std::string>{
"TPCActive",
"Other" }
110 {
"whether to merge aux det hit collections" },
116 fhicl::Comment{
"labels of AuxDetHits collections to merge" },
117 std::vector<std::string>{
"LArG4DetectorServicevolAuxDetSensitiveCRTStripY",
"Other" }
127 void produce(art::Event &
e)
override;
153 template <
typename Optional>
154 std::optional<typename Optional::value_type>
157 using Value_t =
typename Optional::value_type;
159 if (!parameter.hasValue())
return std::nullopt;
175 , fInputSourcesLabels(params().InputSourcesLabels())
177 , fUseLitePhotons(art::ServiceHandle<sim::LArG4Parameters const>()->
UseLitePhotons())
179 , fFillMCParticles(params().FillMCParticles())
180 , fFillSimPhotons(params().FillSimPhotons())
181 , fFillSimChannels(params().FillSimChannels())
182 , fFillAuxDetSimChannels(params().FillAuxDetSimChannels())
183 , fFillSimEnergyDeposits(
185 (art::ServiceHandle<sim::LArG4Parameters const>()->FillSimEnergyDeposits())
187 , fEnergyDepositionInstances(params().EnergyDepositInstanceLabels())
188 , fFillAuxDetHits(params().FillAuxDetHits())
189 , fAuxDetHitsInstanceLabels(params().AuxDetHitsInstanceLabels())
192 if(fInputSourcesLabels.size() != fTrackIDOffsets.size()) {
193 throw art::Exception(art::errors::Configuration)
194 <<
"Unequal input vector sizes: InputSourcesLabels and TrackIDOffsets.\n";
198 for (art::InputTag
const& tag: fInputSourcesLabels) {
200 if (fFillMCParticles) {
201 consumes<std::vector<simb::MCParticle>>(tag);
202 consumes<art::Assns<simb::MCParticle, simb::MCTruth, sim::GeneratedParticleInfo>>(tag);
205 if (fFillSimChannels) {
206 consumes<std::vector<sim::SimChannel>>(tag);
209 if (fFillAuxDetSimChannels) {
210 consumes<std::vector<sim::AuxDetSimChannel>>(tag);
213 if (fFillSimPhotons) {
214 if (!fUseLitePhotons) consumes<std::vector<sim::SimPhotons>>(tag);
215 else consumes<std::vector<sim::SimPhotonsLite>>(tag);
217 if (fStoreReflected) {
218 art::InputTag
const reflected_tag { tag.label(), ReflectedLabel };
219 if (!fUseLitePhotons) consumes<std::vector<sim::SimPhotons>>(reflected_tag);
220 else consumes<std::vector<sim::SimPhotonsLite>>(reflected_tag);
224 if (fFillSimEnergyDeposits) {
225 for (std::string
const& edep_inst: fEnergyDepositionInstances) {
226 art::InputTag
const edep_tag { tag.label(), edep_inst };
227 consumes<std::vector<sim::SimEnergyDeposit>>(edep_tag);
231 if (fFillAuxDetHits) {
232 for (std::string
const& auxdethit_inst: fAuxDetHitsInstanceLabels) {
233 art::InputTag
const auxdethit_tag { tag.label(), auxdethit_inst };
234 consumes<std::vector<sim::AuxDetHit>>(auxdethit_tag);
241 if (fFillMCParticles) {
242 produces< std::vector<simb::MCParticle> >();
243 produces< art::Assns<simb::MCTruth, simb::MCParticle, sim::GeneratedParticleInfo> >();
245 if (fFillSimChannels) {
246 produces< std::vector<sim::SimChannel> >();
248 if (fFillAuxDetSimChannels) {
249 produces< std::vector<sim::AuxDetSimChannel> >();
252 if (fFillSimPhotons) {
253 if(!fUseLitePhotons) produces< std::vector<sim::SimPhotons> >();
254 else produces< std::vector<sim::SimPhotonsLite> >();
256 if (fStoreReflected) {
257 if(!fUseLitePhotons) produces< std::vector<sim::SimPhotons> >(ReflectedLabel);
258 else produces< std::vector<sim::SimPhotonsLite> >(ReflectedLabel);
262 if (fFillSimEnergyDeposits) {
263 for (std::string
const& edep_inst: fEnergyDepositionInstances)
264 produces< std::vector<sim::SimEnergyDeposit> >(edep_inst);
267 if (fFillAuxDetHits) {
268 for (std::string
const& auxdethit_inst: fAuxDetHitsInstanceLabels)
269 produces< std::vector<sim::AuxDetHit> >(auxdethit_inst);
280 auto partCol = std::make_unique<std::vector<simb::MCParticle>>();
281 auto scCol = std::make_unique<std::vector<sim::SimChannel>>();
282 auto PhotonCol = std::make_unique<std::vector<sim::SimPhotons>>();
283 auto LitePhotonCol = std::make_unique<std::vector<sim::SimPhotonsLite>>();
284 auto ReflPhotonCol = std::make_unique<std::vector<sim::SimPhotons>>();
285 auto ReflLitePhotonCol = std::make_unique<std::vector<sim::SimPhotonsLite>>();
286 auto tpassn = std::make_unique<art::Assns<simb::MCTruth, simb::MCParticle, sim::GeneratedParticleInfo>>();
287 auto adCol = std::make_unique<std::vector<sim::AuxDetSimChannel>>();
289 using edeps_t = std::vector<sim::SimEnergyDeposit>;
290 std::vector<edeps_t> edepCols;
291 if (fFillSimEnergyDeposits)
292 edepCols.resize(fEnergyDepositionInstances.size());
294 using aux_det_hits_t = std::vector<sim::AuxDetHit>;
295 std::vector<aux_det_hits_t> auxdethitCols;
297 auxdethitCols.resize(fAuxDetHitsInstanceLabels.size());
302 for(
auto const& [ i_source, input_label ]:
util::enumerate(fInputSourcesLabels)) {
304 if (fFillMCParticles) {
305 art::PtrMaker<simb::MCParticle>
const makePartPtr { e };
306 auto const input_partCol
307 = e.getValidHandle<std::vector<simb::MCParticle>>(input_label);
311 const std::vector<size_t>& assocVectorPrimitive
312 = MergeUtility.GetMCParticleListMap().at(i_source);
313 art::FindOneP<simb::MCTruth, sim::GeneratedParticleInfo> mctAssn(input_partCol,e,input_label);
315 tpassn->addSingle(mctAssn.at(i_p), makePartPtr(assocVectorPrimitive[i_p]), mctAssn.data(i_p).ref());
318 if (fFillSimChannels) {
319 auto const& input_scCol
320 = e.getProduct<std::vector<sim::SimChannel>>(input_label);
321 MergeUtility.MergeSimChannels(*scCol,input_scCol,i_source);
324 if (fFillAuxDetSimChannels) {
325 auto const& input_adCol
326 = e.getProduct<std::vector<sim::AuxDetSimChannel>>(input_label);
327 MergeUtility.MergeAuxDetSimChannels(*adCol,input_adCol,i_source);
330 if (fFillSimPhotons) {
331 if(!fUseLitePhotons){
332 auto const& input_PhotonCol
333 = e.getProduct<std::vector<sim::SimPhotons>>(input_label);
334 MergeUtility.MergeSimPhotons(*PhotonCol,input_PhotonCol);
337 auto const& input_LitePhotonCol
338 = e.getProduct<std::vector<sim::SimPhotonsLite>>(input_label);
339 MergeUtility.MergeSimPhotonsLite(*LitePhotonCol,input_LitePhotonCol);
342 if (fStoreReflected) {
343 art::InputTag
const input_reflected_label
344 { input_label.label(), ReflectedLabel };
345 if(!fUseLitePhotons){
346 auto const& input_PhotonCol
347 = e.getProduct<std::vector<sim::SimPhotons>>(input_reflected_label);
348 MergeUtility.MergeSimPhotons(*ReflPhotonCol,input_PhotonCol);
351 auto const& input_LitePhotonCol
352 = e.getProduct<std::vector<sim::SimPhotonsLite>>(input_reflected_label);
353 MergeUtility.MergeSimPhotonsLite(*ReflLitePhotonCol,input_LitePhotonCol);
359 if (fFillSimEnergyDeposits) {
360 for (
auto const& [ edep_inst, edepCol ]
361 :
util::zip(fEnergyDepositionInstances, edepCols))
363 art::InputTag
const edep_tag { input_label.label(), edep_inst };
364 MergeUtility.MergeSimEnergyDeposits(edepCol,
365 e.getProduct<edeps_t>(edep_tag),
371 if (fFillAuxDetHits) {
372 for (
auto const& [ auxdethit_inst, auxdethitCol ]
373 :
util::zip(fAuxDetHitsInstanceLabels, auxdethitCols))
375 art::InputTag
const auxdethit_tag { input_label.label(), auxdethit_inst };
376 MergeUtility.MergeAuxDetHits(auxdethitCol,
377 e.getProduct<aux_det_hits_t>(auxdethit_tag),
384 if (fFillMCParticles) {
385 e.put(std::move(partCol));
386 e.put(std::move(tpassn));
388 if (fFillSimChannels) {
389 e.put(std::move(scCol));
391 if (fFillAuxDetSimChannels) {
392 e.put(std::move(adCol));
394 if (fFillSimPhotons) {
395 if(!fUseLitePhotons) e.put(std::move(PhotonCol));
396 else e.put(std::move(LitePhotonCol));
397 if(fStoreReflected) {
398 if(!fUseLitePhotons) e.put(std::move(ReflPhotonCol), ReflectedLabel);
399 else e.put(std::move(ReflLitePhotonCol), ReflectedLabel);
403 if(fFillSimEnergyDeposits) {
404 for (
auto&& [ edep_inst, edepCol ]
405 :
util::zip(fEnergyDepositionInstances, edepCols))
407 e.put(std::make_unique<edeps_t>(move(edepCol)), edep_inst);
411 if(fFillAuxDetHits) {
412 for (
auto&& [ auxdethit_inst, auxdethitCol ]
413 :
util::zip(fAuxDetHitsInstanceLabels, auxdethitCols))
415 e.put(std::make_unique<aux_det_hits_t>(move(auxdethitCol)), auxdethit_inst);
424 mf::LogInfo log(
"MergeSimSources");
425 log <<
"Configuration:"
426 <<
"\n - " << fInputSourcesLabels.size() <<
" input sources:";
427 for (
auto const& [ i_source, tag,
offset ]
430 log <<
"\n [" << i_source <<
"] '" << tag.encode()
431 <<
"' (ID offset: " <<
offset <<
")";
433 if (fFillMCParticles) log <<
"\n - filling MCParticles";
435 if (fFillSimChannels) log <<
"\n - filling SimChannels";
437 if (fFillAuxDetSimChannels) log <<
"\n - filling AuxDetSimChannels";
439 if (fFillSimPhotons) {
440 log <<
"\n - filling Simulated Photons";
441 if (fUseLitePhotons) log <<
"\n - using photon summary (`SimPhotonsLite`)";
442 else log <<
"\n - using detailed photons (`SimPhotons`)";
443 if (fStoreReflected) log <<
"\n - also merging reflected light";
446 if (fFillSimEnergyDeposits) {
447 log <<
"\n - filling simulated energy deposits ("
448 << fEnergyDepositionInstances.size() <<
" labels:";
449 for (std::string
const& label: fEnergyDepositionInstances)
450 log <<
" '" << label <<
"'";
454 if (fFillAuxDetHits) {
455 log <<
"\n - filling auxiliary detector hits ("
456 << fAuxDetHitsInstanceLabels.size() <<
" labels:";
457 for (std::string
const& label: fAuxDetHitsInstanceLabels)
458 log <<
" '" << label <<
"'";
bool const fFillSimChannels
bool const fFillMCParticles
Store parameters for running LArG4.
MergeSimSources(Parameters const &config)
fhicl::Sequence< int > TrackIDOffsets
Definition of util::zip().
BEGIN_PROLOG TPC Trig offset(g4 rise time) ProjectToHeight
std::optional< typename Optional::value_type > getOptionalValue(Optional const ¶meter)
Returns the value of an optional parameter as std::optional.
Definition of util::enumerate().
bool const fFillSimEnergyDeposits
fhicl::Atom< bool > FillAuxDetSimChannels
Contains data associated to particles from detector simulation.
art::EDProducer::Table< Config > Parameters
fhicl::OptionalAtom< bool > FillSimEnergyDeposits
fhicl::Atom< bool > FillSimChannels
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
fhicl::Sequence< std::string > EnergyDepositInstanceLabels
std::vector< art::InputTag > const fInputSourcesLabels
bool const fUseLitePhotons
process_name larg4outtime TrackIDOffsets
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.
bool const fFillSimPhotons
fhicl::Atom< bool > FillSimPhotons
BEGIN_PROLOG vertical distance to the surface Name
std::vector< int > const fTrackIDOffsets
Test of util::counter and support utilities.
void dumpConfiguration() const
fhicl::Atom< bool > StoreReflected
void produce(art::Event &e) override
fhicl::Sequence< std::string > AuxDetHitsInstanceLabels
void MergeMCParticles(std::vector< simb::MCParticle > &, const std::vector< simb::MCParticle > &, size_t)
static std::string const ReflectedLabel
fhicl::Atom< bool > FillMCParticles
bool const fStoreReflected
bool const fFillAuxDetHits
contains information for a single step in the detector simulation
BEGIN_PROLOG larg4outtime StoreReflected
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.
fhicl::Atom< bool > FillAuxDetHits
bool const fFillAuxDetSimChannels
fhicl::Sequence< art::InputTag > InputSourcesLabels
services LArG4Parameters UseLitePhotons
std::vector< std::string > const fEnergyDepositionInstances