21 #include "nug4/G4Base/G4Helper.h"
31 #include "art/Framework/Core/EDProducer.h"
32 #include "art/Framework/Core/ModuleMacros.h"
33 #include "art/Framework/Principal/Event.h"
34 #include "art/Framework/Principal/Handle.h"
35 #include "art/Framework/Services/Registry/ServiceHandle.h"
36 #include "art/Persistency/Common/PtrMaker.h"
37 #include "canvas/Persistency/Common/Assns.h"
38 #include "canvas/Persistency/Common/Ptr.h"
39 #include "canvas/Utilities/Exception.h"
40 #include "cetlib/search_path.h"
41 #include "cetlib_except/exception.h"
42 #include "fhiclcpp/ParameterSet.h"
43 #include "messagefacility/MessageLogger/MessageLogger.h"
46 #include "nurandom/RandomUtils/NuRandomService.h"
73 #include "nug4/G4Base/UserActionManager.h"
74 #include "nug4/ParticleNavigation/ParticleList.h"
75 #include "nusimdata/SimulationBase/MCTruth.h"
79 #include "Geant4/G4LogicalVolumeStore.hh"
80 #include "Geant4/G4RunManager.hh"
81 #include "Geant4/G4SDManager.hh"
82 #include "Geant4/G4VSensitiveDetector.hh"
83 #include "Geant4/G4VUserDetectorConstruction.hh"
89 #include "boost/algorithm/string.hpp"
95 class LArVoxelListAction;
315 class LArG4 :
public art::EDProducer {
317 explicit LArG4(fhicl::ParameterSet
const& pset);
325 void beginRun(art::Run& run)
override;
327 std::unique_ptr<g4b::G4Helper>
fG4Help{
nullptr};
345 std::vector<std::string>
360 std::set<std::string>
const& vol_names)
const;
386 template <
typename T>
388 append(std::vector<T>& dest, std::vector<T>&&
source)
394 source = std::vector<T>{};
407 : art::EDProducer{pset}
408 , fG4PhysListName(pset.get<std::string>(
"G4PhysListName",
"larg4::PhysicsList"))
409 , fCheckOverlaps(pset.get<
bool>(
"CheckOverlaps",
false))
410 , fMakeMCParticles(pset.get<
bool>(
"MakeMCParticles",
true))
411 , fStoreDroppedMCParticles(pset.get<
bool>(
"StoreDroppedMCParticles",
false))
412 , fdumpParticleList(pset.get<
bool>(
"DumpParticleList",
false))
413 , fdumpSimChannels(pset.get<
bool>(
"DumpSimChannels",
false))
414 , fSmartStacking(pset.get<
int>(
"SmartStacking", 0))
415 , fOffPlaneMargin(pset.get<
double>(
"ChargeRecoveryMargin", 0.0))
416 , fKeepParticlesInVolumes(pset.get<std::vector<std::string>>(
"KeepParticlesInVolumes", {}))
418 ,
fEngine(art::ServiceHandle<rndm::NuRandomService> {}
419 ->createEngine(*
this,
"HepJamesRandom",
"propagation", pset,
"PropagationSeed"))
420 ,
fDetProp{art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob()}
423 MF_LOG_DEBUG(
"LArG4") <<
"Debug: LArG4()";
424 art::ServiceHandle<art::RandomNumberGenerator const> rng;
426 if (!fMakeMCParticles) {
427 if (fdumpParticleList) {
428 throw art::Exception(art::errors::Configuration)
429 <<
"Option `DumpParticleList` can't be set if `MakeMCParticles` is unset.\n";
431 if (!fKeepParticlesInVolumes.empty()) {
432 throw art::Exception(art::errors::Configuration)
433 <<
"Option `KeepParticlesInVolumes` can't be set if `MakeMCParticles` is unset.\n";
437 if (pset.has_key(
"Seed")) {
438 throw art::Exception(art::errors::Configuration)
439 <<
"The configuration of LArG4 module has the discontinued 'Seed' parameter.\n"
440 "Seeds are now controlled by two parameters: 'GEANTSeed' and 'PropagationSeed'.";
447 (
void)art::ServiceHandle<rndm::NuRandomService>()->createEngine(
448 *
this,
"G4Engine",
"GEANT", pset,
"GEANTSeed");
452 bool useInputLabels =
453 pset.get_if_present<std::vector<std::string>>(
"InputLabels", fInputLabels);
454 if (!useInputLabels) fInputLabels.resize(0);
456 art::ServiceHandle<sim::LArG4Parameters const> lgp;
457 fUseLitePhotons = lgp->UseLitePhotons();
459 if (!lgp->NoPhotonPropagation()) {
461 art::ServiceHandle<phot::PhotonVisibilityService const> pvs;
462 fStoreReflected = pvs->StoreReflected();
464 catch (art::Exception
const&
e) {
468 if (e.categoryCode() != art::errors::ServiceNotFound)
throw;
471 if (!fUseLitePhotons) {
472 produces<std::vector<sim::SimPhotons>>();
473 if (fStoreReflected) { produces<std::vector<sim::SimPhotons>>(
"Reflected"); }
476 produces<std::vector<sim::SimPhotonsLite>>();
477 produces<std::vector<sim::OpDetBacktrackerRecord>>();
478 if (fStoreReflected) {
479 produces<std::vector<sim::SimPhotonsLite>>(
"Reflected");
480 produces<std::vector<sim::OpDetBacktrackerRecord>>(
"Reflected");
485 if (lgp->FillSimEnergyDeposits()) {
486 produces<std::vector<sim::SimEnergyDeposit>>(
"TPCActive");
487 produces<std::vector<sim::SimEnergyDeposit>>(
"Other");
490 if (fMakeMCParticles) {
491 produces<std::vector<simb::MCParticle>>();
492 produces<art::Assns<simb::MCTruth, simb::MCParticle, sim::GeneratedParticleInfo>>();
494 if (fStoreDroppedMCParticles) {
495 produces<std::vector<sim::MCParticleLite>>();
497 if (!lgp->NoElectronPropagation()) produces<std::vector<sim::SimChannel>>();
498 produces<std::vector<sim::AuxDetSimChannel>>();
501 cet::search_path sp(
"FW_SEARCH_PATH");
503 sp.find_file(pset.get<std::string>(
"GeantCommandFile"), fG4MacroPath);
505 if (fG4MacroPath.empty() ||
stat(fG4MacroPath.c_str(), &sb) != 0)
507 throw cet::exception(
"NoG4Macro") <<
"G4 macro file " << fG4MacroPath <<
" not found!\n";
514 fG4Help = std::make_unique<g4b::G4Helper>(fG4MacroPath, fG4PhysListName);
516 if (fCheckOverlaps) fG4Help->SetOverlapCheck(
true);
518 art::ServiceHandle<geo::Geometry const> geom;
519 fG4Help->ConstructDetector(geom->GDMLFile());
524 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob();
529 std::vector<G4VUserParallelWorld*> pworlds;
532 fG4Help->InitPhysics();
540 LArVoxelReadoutGeometry::Setup_t readoutGeomSetupData;
541 readoutGeomSetupData.readoutSetup.offPlaneMargin = fOffPlaneMargin;
542 readoutGeomSetupData.readoutSetup.propGen = &
fEngine;
544 fVoxelReadoutGeometry =
545 new LArVoxelReadoutGeometry(
"LArVoxelReadoutGeometry", readoutGeomSetupData);
546 pworlds.push_back(fVoxelReadoutGeometry);
548 new OpDetReadoutGeometry(geom->OpDetGeoName(),
"OpDetReadoutGeometry", fUseLitePhotons));
549 pworlds.push_back(
new AuxDetReadoutGeometry(
"AuxDetReadoutGeometry"));
551 fG4Help->SetParallelWorlds(pworlds);
555 fG4Help->InitPhysics();
558 g4b::UserActionManager* uaManager = g4b::UserActionManager::Instance();
561 art::ServiceHandle<sim::LArG4Parameters const> lgp;
566 lgp->StoreTrajectories(),
567 lgp->KeepEMShowerDaughters(),
569 fStoreDroppedMCParticles);
570 uaManager->AddAndAdoptAction(fparticleListAction);
573 fG4Help->SetUserAction();
577 if (fSmartStacking > 0) {
579 fG4Help->GetRunManager()->SetUserAction(stacking_action);
584 LArG4::beginRun(art::Run& run)
587 std::set<std::string> volnameset(fKeepParticlesInVolumes.begin(),
588 fKeepParticlesInVolumes.end());
589 fparticleListAction->ParticleFilter(CreateParticleVolumeFilter(volnameset));
592 std::unique_ptr<util::PositionInVolumeFilter>
593 LArG4::CreateParticleVolumeFilter(std::set<std::string>
const& vol_names)
const
596 if (
empty(vol_names))
return {};
598 auto const& geom = *art::ServiceHandle<geo::Geometry const>();
600 std::vector<std::vector<TGeoNode const*>> node_paths = geom.FindAllVolumePaths(vol_names);
604 GeoVolumePairs.reserve(node_paths.size());
608 for (
size_t iVolume = 0; iVolume < node_paths.size(); ++iVolume) {
609 std::vector<TGeoNode const*>
path = node_paths[iVolume];
611 auto pTransl =
new TGeoTranslation(0., 0., 0.);
612 auto pRot =
new TGeoRotation();
613 for (TGeoNode
const* node : path) {
614 TGeoTranslation thistranslate(*node->GetMatrix());
615 TGeoRotation thisrotate(*node->GetMatrix());
616 pTransl->Add(&thistranslate);
617 *pRot = *pRot * thisrotate;
622 auto pTransl2 =
new TGeoTranslation(
623 pTransl->GetTranslation()[0], pTransl->GetTranslation()[1], pTransl->GetTranslation()[2]);
624 double phi = 0., theta = 0., psi = 0.;
625 pRot->GetAngles(phi, theta, psi);
626 auto pRot2 =
new TGeoRotation();
627 pRot2->SetAngles(phi, theta, psi);
629 auto pTransf =
new TGeoCombiTrans(*pTransl2, *pRot2);
630 GeoVolumePairs.emplace_back(node_paths[iVolume].back()->GetVolume(), pTransf);
633 return std::make_unique<util::PositionInVolumeFilter>(std::move(GeoVolumePairs));
637 LArG4::produce(art::Event&
evt)
639 MF_LOG_DEBUG(
"LArG4") <<
"produce()";
640 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
642 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt, clockData);
643 LArVoxelReadoutGeometry::Sentry
const set_for_event{fVoxelReadoutGeometry, clockData,
detProp};
647 auto scCol = std::make_unique<std::vector<sim::SimChannel>>();
648 auto adCol = std::make_unique<std::vector<sim::AuxDetSimChannel>>();
651 std::make_unique<art::Assns<simb::MCTruth, simb::MCParticle, sim::GeneratedParticleInfo>>() :
655 std::make_unique<std::vector<simb::MCParticle>>() :
657 auto droppedPartCol =
658 fStoreDroppedMCParticles ?
659 std::make_unique<std::vector<sim::MCParticleLite>>() :
661 auto PhotonCol = std::make_unique<std::vector<sim::SimPhotons>>();
662 auto PhotonColRefl = std::make_unique<std::vector<sim::SimPhotons>>();
663 auto LitePhotonCol = std::make_unique<std::vector<sim::SimPhotonsLite>>();
664 auto LitePhotonColRefl = std::make_unique<std::vector<sim::SimPhotonsLite>>();
665 auto cOpDetBacktrackerRecordCol = std::make_unique<std::vector<sim::OpDetBacktrackerRecord>>();
666 auto cOpDetBacktrackerRecordColRefl =
667 std::make_unique<std::vector<sim::OpDetBacktrackerRecord>>();
669 std::optional<art::PtrMaker<simb::MCParticle>> makeMCPartPtr;
670 if (fMakeMCParticles) makeMCPartPtr.emplace(evt);
673 auto edepCol_TPCActive = std::make_unique<std::vector<sim::SimEnergyDeposit>>();
674 auto edepCol_Other = std::make_unique<std::vector<sim::SimEnergyDeposit>>();
677 art::ServiceHandle<sim::LArG4Parameters const> lgp;
678 art::ServiceHandle<geo::Geometry const> geom;
681 OpDetPhotonTable::Instance()->ClearTable(geom->NOpDets());
682 if (lgp->FillSimEnergyDeposits()) OpDetPhotonTable::Instance()->ClearEnergyDeposits();
685 fparticleListAction->ResetTrackIDOffset();
689 std::vector<art::Handle<std::vector<simb::MCTruth>>> mclists;
690 if (
empty(fInputLabels))
692 mclists = evt.getMany<std::vector<simb::MCTruth>>();
694 mclists.resize(fInputLabels.size());
695 for (
size_t i = 0; i < fInputLabels.size(); i++)
696 evt.getByLabel(fInputLabels[i], mclists[i]);
699 unsigned int nGeneratedParticles = 0;
702 for (
size_t mcl = 0; mcl < mclists.size(); ++mcl) {
704 art::Handle<std::vector<simb::MCTruth>> mclistHandle = mclists[mcl];
706 for (
size_t m = 0;
m < mclistHandle->size(); ++
m) {
707 art::Ptr<simb::MCTruth> mct(mclistHandle,
m);
709 MF_LOG_DEBUG(
"LArG4") << *(mct.get());
714 if (!partCol)
continue;
718 sim::ParticleList particleList = fparticleListAction->YieldList();
720 for (
auto const& partPair : particleList) {
721 simb::MCParticle&
p = *(partPair.second);
722 ++nGeneratedParticles;
727 if (ParticleListAction::isDropped(&p))
continue;
730 fparticleListAction->GetPrimaryTruthIndex(p.TrackId())};
731 if (!truthInfo.hasGeneratedParticleIndex() && (p.Mother() == 0)) {
733 art::Exception
error(art::errors::LogicError);
734 error <<
"Failed to match primary particle:\n";
736 error <<
"\nwith particles from the truth record '"
737 << mclistHandle.provenance()->inputTag() <<
"':\n";
745 partCol->push_back(std::move(p));
747 tpassn->addSingle(mct, (*makeMCPartPtr)(partCol->size() - 1), truthInfo);
751 if (fStoreDroppedMCParticles && droppedPartCol) {
754 sim::ParticleList droppedParticleList = fparticleListAction->YieldDroppedList();
755 droppedPartCol->reserve(droppedParticleList.size());
757 for (
auto const& partPair : droppedParticleList) {
758 simb::MCParticle& p = *(partPair.second);
759 if (ParticleListAction::isDropped(&p))
continue;
760 if (p.StatusCode() != 1)
continue;
763 mini_mcp.Origin( mct->Origin() );
765 droppedPartCol->push_back(std::move(mini_mcp));
770 if (fdumpParticleList) {
771 mf::LogInfo(
"LArG4") <<
"Dump sim::ParticleList; size()=" << particleList.size() <<
"\n"
780 G4SDManager* sdManager = G4SDManager::GetSDMpointer();
783 auto theOpDetDet =
dynamic_cast<OpDetSensitiveDetector*
>(
784 sdManager->FindSensitiveDetector(
"OpDetSensitiveDetector"));
790 if (!lgp->NoPhotonPropagation()) {
792 for (
int Reflected = 0; Reflected <= 1; Reflected++) {
793 if (Reflected && !fStoreReflected)
continue;
795 if (!fUseLitePhotons) {
796 MF_LOG_DEBUG(
"Optical") <<
"Storing OpDet Hit Collection in Event";
797 std::vector<sim::SimPhotons>& ThePhotons =
798 OpDetPhotonTable::Instance()->GetPhotons(Reflected);
800 PhotonColRefl->reserve(ThePhotons.size());
802 PhotonCol->reserve(ThePhotons.size());
803 for (
auto& it : ThePhotons) {
805 PhotonColRefl->push_back(std::move(it));
807 PhotonCol->push_back(std::move(it));
811 MF_LOG_DEBUG(
"Optical") <<
"Storing OpDet Hit Collection in Event";
813 std::map<int, std::map<int, int>> ThePhotons =
814 OpDetPhotonTable::Instance()->GetLitePhotons(Reflected);
816 if (
size(ThePhotons) > 0) {
817 LitePhotonCol->reserve(ThePhotons.size());
818 for (
auto const& [opChannel, detectedPhotons] : ThePhotons) {
823 LitePhotonColRefl->push_back(std::move(ph));
825 LitePhotonCol->push_back(std::move(ph));
830 *cOpDetBacktrackerRecordColRefl =
831 OpDetPhotonTable::Instance()->YieldReflectedOpDetBacktrackerRecords();
833 *cOpDetBacktrackerRecordCol =
834 OpDetPhotonTable::Instance()->YieldOpDetBacktrackerRecords();
838 if (lgp->FillSimEnergyDeposits()) {
840 auto edepMap = OpDetPhotonTable::Instance()->YieldSimEnergyDeposits();
841 for (
auto& [volumeName, edepCol] : edepMap) {
843 auto const& destColl =
844 boost::contains(volumeName,
"TPCActive") ? edepCol_TPCActive : edepCol_Other;
845 append(*destColl, std::move(edepCol));
850 if (!lgp->NoElectronPropagation()) {
855 std::set<LArVoxelReadout*> ReadoutList;
857 for (
unsigned int c = 0; c < geom->Ncryostats(); ++c) {
863 std::map<unsigned int, unsigned int> channelToscCol;
865 unsigned int ntpcs = geom->Cryostat(c).NTPC();
866 for (
unsigned int t = 0; t < ntpcs; ++t) {
867 std::string
name(
"LArVoxelSD");
868 std::ostringstream sstr;
869 sstr <<
name <<
"_Cryostat" << c <<
"_TPC" << t;
873 G4VSensitiveDetector* sd = sdManager->FindSensitiveDetector(sstr.str(),
false);
875 if (!sd) sd = sdManager->FindSensitiveDetector(
name,
false);
879 throw cet::exception(
"LArG4")
880 <<
"Sensitive detector for cryostat " << c <<
" TPC " << t <<
" not found (neither '"
881 << sstr.str() <<
"' nor '" <<
name <<
"' exist)\n";
885 auto larVoxelReadout =
dynamic_cast<LArVoxelReadout*
>(sd);
889 if (!larVoxelReadout) {
890 throw cet::exception(
"LArG4")
891 <<
"Sensitive detector '" << sd->GetName() <<
"' is not a LArVoxelReadout object\n";
894 LArVoxelReadout::ChannelMap_t& channels = larVoxelReadout->GetSimChannelMap(c, t);
895 if (!
empty(channels)) {
896 MF_LOG_DEBUG(
"LArG4") <<
"now put " << channels.size() <<
" SimChannels from C=" << c
897 <<
" T=" << t <<
" into the event";
900 for (
auto ch_pair : channels) {
907 unsigned int ichan = sc.
Channel();
908 auto itertest = channelToscCol.find(ichan);
909 if (itertest == channelToscCol.end()) {
910 channelToscCol[ichan] = scCol->size();
911 scCol->emplace_back(std::move(sc));
914 unsigned int idtest = itertest->second;
916 for (
auto const& tdcide : tdcideMap) {
917 for (
auto const& ide : tdcide.second) {
918 double xyz[3] = {ide.x, ide.y, ide.z};
919 scCol->at(idtest).AddIonizationElectrons(
920 ide.trackID, tdcide.first, ide.numElectrons, xyz, ide.energy, ide.origTrackID);
926 scCol->emplace_back(std::move(sc));
931 ReadoutList.insert(const_cast<LArVoxelReadout*>(larVoxelReadout));
936 for (LArVoxelReadout* larVoxelReadout : ReadoutList) {
937 larVoxelReadout->ClearSimChannels();
944 adCol->reserve(geom->NAuxDets());
945 for (
unsigned int a = 0;
a < geom->NAuxDets(); ++
a) {
950 for (
size_t sv = 0; sv < geom->AuxDet(
a).NSensitiveVolume(); ++sv) {
954 std::stringstream
name;
955 name <<
"AuxDetSD_AuxDet" <<
a <<
"_" << sv;
956 G4VSensitiveDetector* sd = sdManager->FindSensitiveDetector(name.str().c_str());
958 throw cet::exception(
"LArG4")
959 <<
"Sensitive detector '" << name.str() <<
"' does not exist\n";
965 MF_LOG_DEBUG(
"LArG4") <<
"now put the AuxDetSimTracks in the event";
968 adCol->push_back(adsc);
969 auxDetReadout->
clear();
974 mf::LogInfo(
"LArG4") <<
"Geant4 simulated " << nGeneratedParticles <<
" MC particles, we keep "
975 << partCol->size() <<
" .";
978 if (fdumpSimChannels) {
979 mf::LogVerbatim(
"DumpSimChannels")
980 <<
"Event " << evt.id() <<
": " << scCol->size() <<
" channels with signal";
981 unsigned int nChannels = 0;
983 mf::LogVerbatim out(
"DumpSimChannels");
984 out <<
" #" << nChannels <<
": ";
991 if (!lgp->NoElectronPropagation()) evt.put(std::move(scCol));
993 evt.put(std::move(adCol));
994 if (partCol) evt.put(std::move(partCol));
995 if (droppedPartCol) {
996 std::cout <<
"LArG4 dropped particles length = " << droppedPartCol->size() << std::endl;
997 evt.put(std::move(droppedPartCol));
999 if (tpassn) evt.put(std::move(tpassn));
1000 if (!lgp->NoPhotonPropagation()) {
1001 if (!fUseLitePhotons) {
1002 evt.put(std::move(PhotonCol));
1003 if (fStoreReflected) evt.put(std::move(PhotonColRefl),
"Reflected");
1006 evt.put(std::move(LitePhotonCol));
1007 evt.put(std::move(cOpDetBacktrackerRecordCol));
1008 if (fStoreReflected) {
1009 evt.put(std::move(LitePhotonColRefl),
"Reflected");
1010 evt.put(std::move(cOpDetBacktrackerRecordColRefl),
"Reflected");
1015 if (lgp->FillSimEnergyDeposits()) {
1016 evt.put(std::move(edepCol_TPCActive),
"TPCActive");
1017 evt.put(std::move(edepCol_Other),
"Other");
std::vector< std::string > fInputLabels
std::unique_ptr< g4b::G4Helper > fG4Help
G4 interface object.
Store parameters for running LArG4.
bool fStoreDroppedMCParticles
Whether to keep a sim::MCParticleLite list of dropped particles.
Energy deposited on a readout channel by simulated tracks.
Stores material properties and sends them to GEANT4 geometry.
void Dump(Stream &&out, std::string indent, std::string first_indent) const
Dumps the full content of the SimChannel into a stream.
void GetPropertiesFromServices(detinfo::DetectorPropertiesData const &detProp)
Imports properties from LArSoft services.
std::vector< VolumeInfo_t > AllVolumeInfo_t
bool fMakeMCParticles
Whether to keep a sim::MCParticle list.
std::size_t size(FixedBins< T, C > const &) noexcept
Class def header for MCParticleLite data container.
Contains data associated to particles from detector simulation.
Runs Geant4 simulation and propagation of electrons and photons to readout.
std::unique_ptr< util::PositionInVolumeFilter > CreateParticleVolumeFilter(std::set< std::string > const &vol_names) const
Pointer used for correctly updating the clock data state.
tuple m
now if test mode generate materials, CRT shell, world, gdml header else just generate CRT shell for u...
std::vector< std::string > fKeepParticlesInVolumes
Only write particles that have trajectories through these volumes.
std::map< int, int > DetectedPhotons
Number of photons detected at each given time: time tick -> photons.
Define the "parallel" geometry that's seen by the LAr Voxels.
bool fSparsifyTrajectories
Sparsify MCParticle Trajectories.
BEGIN_PROLOG triggeremu_data_config_icarus settings PMTADCthresholds sequence::icarus_stage0_multiTPC_TPC physics sequence::icarus_stage0_EastHits_TPC physics sequence::icarus_stage0_WestHits_TPC physics producers purityana0 caloskimCalorimetryCryoE physics caloskimCalorimetryCryoW physics path
int fSmartStacking
Whether to instantiate and use class to.
Collection of particles crossing one auxiliary detector cell.
bool fdumpSimChannels
Whether each event's sim::Channel will be displayed.
larg4::ParticleListAction * fparticleListAction
Geant4 user action to particle information.
Simulation objects for optical detectors.
object containing MC truth information necessary for making RawDigits and doing back tracking ...
Use Geant4's user "hooks" to maintain a list of particles generated by Geant4.
Utility functions to print MC truth information.
LArG4(fhicl::ParameterSet const &pset)
auto end(FixedBins< T, C > const &) noexcept
fEngine(art::ServiceHandle< rndm::NuRandomService >() ->createEngine(*this, pset,"Seed"))
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.
int OpChannel
Optical detector channel associated to this data.
bool fdumpParticleList
Whether each event's sim::ParticleList will be displayed.
auto begin(FixedBins< T, C > const &) noexcept
void UpdateGeometry(G4LogicalVolumeStore *lvs)
Updates the material properties with the collected values.
raw::ChannelID_t Channel() const
Returns the readout channel this object describes.
A Geant4 sensitive detector that accumulates voxel information.
Define the "parallel" geometry that's seen by the AuxDet.
fSparsifyTrajectories(p.get< bool >("SparsifyTrajectories", false))
Compact representation of photons on a channel.
Singleton to access a unified treatment of ionization and scintillation in LAr.
Contains information about a generated particle.
contains information for a single step in the detector simulation
void produce(art::Event &evt) override
object containing MC truth information necessary for making RawDigits and doing back tracking ...
std::string fG4PhysListName
predefined physics list to use if not making a custom one
bool fCheckOverlaps
Whether to use the G4 overlap checker.
TDCIDEs_t const & TDCIDEMap() const
Returns all the deposited energy information as stored.
Defines classes to filter particles based on their trajectory.
AllPhysicsLists fAllPhysicsLists
detinfo::DetectorPropertiesData fDetProp
Must outlive fAllPhysicsLists!
CLHEP::HepRandomEngine & fEngine
void beginRun(art::Run &run) override
bool empty(FixedBins< T, C > const &) noexcept
A Geant4 sensitive detector that accumulates information.
sim::AuxDetSimChannel const GetAuxDetSimChannel() const
art framework interface to geometry description
BEGIN_PROLOG could also be cout
void DumpMCParticle(Stream &&out, simb::MCParticle const &particle, std::string indent, std::string firstIndent)
Dumps the content of the specified particle in the output stream.
LArVoxelReadoutGeometry * fVoxelReadoutGeometry