25 #include "nug4/G4Base/G4Helper.h" 26 #include "nug4/G4Base/ConvertMCTruthToG4.h" 48 #include "cetlib_except/exception.h" 53 #include "nug4/ParticleNavigation/ParticleList.h" 54 #include "nug4/G4Base/DetectorConstruction.h" 55 #include "nug4/G4Base/UserActionManager.h" 56 #include "nurandom/RandomUtils/NuRandomService.h" 66 #include "Utilities/AssociationUtil.h" 71 #include "CoreUtils/ServiceUtil.h" 74 #include "Geant4/G4RunManager.hh" 75 #include "Geant4/G4UImanager.hh" 76 #include "Geant4/G4VUserDetectorConstruction.hh" 77 #include "Geant4/G4VUserPrimaryGeneratorAction.hh" 78 #include "Geant4/G4VUserPhysicsList.hh" 79 #include "Geant4/G4UserRunAction.hh" 80 #include "Geant4/G4UserEventAction.hh" 81 #include "Geant4/G4UserTrackingAction.hh" 82 #include "Geant4/G4UserSteppingAction.hh" 83 #include "Geant4/G4UserStackingAction.hh" 84 #include "Geant4/G4VisExecutive.hh" 85 #include "Geant4/G4VUserPhysicsList.hh" 86 #include "Geant4/G4SDManager.hh" 87 #include "Geant4/G4LogicalVolumeStore.hh" 88 #include "Geant4/G4RegionStore.hh" 89 #include "Geant4/Randomize.hh" 90 #include "Geant4/G4SDManager.hh" 91 #include "Geant4/G4VSensitiveDetector.hh" 92 #include "Geant4/globals.hh" 93 #include "Geant4/G4ProductionCuts.hh" 94 #include "Geant4/G4UserLimits.hh" 97 #include "TGeoManager.h" 102 class G4VisExecutive;
109 class ParticleListAction;
188 (std::set<std::string>
const& vol_names)
const;
213 ,
fDetRegionNames (pset.get< std::vector< std::string > >(
"DetRegionName", {}) )
218 ,
fMaxStepSize (pset.get< std::vector< float > >(
"MaxStepSize", {} ) )
223 geo = providerFrom<geo::GeometryGAr>();
242 bool useInputLabels = pset.get_if_present< std::vector<std::string> >(
"InputLabels",
fInputLabels);
245 produces< std::vector<simb::MCParticle> >();
246 produces< ::art::Assns<simb::MCTruth, simb::MCParticle> >();
248 produces< std::vector<sdp::LArDeposit> >();
249 produces< std::vector<sdp::EnergyDeposit> >();
251 if(
geo->HasECALDetector())
252 produces< std::vector<sdp::CaloDeposit> >(
"ECAL");
253 if(
geo->HasTrackerScDetector())
254 produces< std::vector<sdp::CaloDeposit> >(
"TrackerSc");
255 if(
geo->HasMuonDetector())
256 produces< std::vector<sdp::CaloDeposit> >(
"MuID");
286 <<
"Step size vector has " 288 <<
" elements != DetRegionName has " 291 <<
" will use default step size of 2 mm";
294 unsigned int index = 0;
297 G4Region* aRegion =
new G4Region(
name);
298 G4LogicalVolume* calorLogical = G4LogicalVolumeStore::GetInstance()->GetVolume(
name);
299 calorLogical->SetRegion(aRegion);
300 aRegion->AddRootLogicalVolume(calorLogical);
302 G4Region*
reg = G4RegionStore::GetInstance()->GetRegion(
name);
305 <<
"Setting production cuts for region " 307 <<
" production cut set to " 311 G4ProductionCuts* cuts =
new G4ProductionCuts();
313 reg->SetProductionCuts(cuts);
315 G4UserLimits*
limits =
new G4UserLimits();
318 limits->SetMaxAllowedStep(2.0*CLHEP::mm);
321 <<
"Setting user limits for region " 323 <<
" max step length set to " 329 reg->SetUserLimits(limits);
343 G4LogicalVolumeStore *store = G4LogicalVolumeStore::GetInstance();
344 if(store ==
nullptr) {
346 <<
"G4LogicalVolumeStore::GetInstance() not available";
360 g4b::UserActionManager* uaManager = g4b::UserActionManager::Instance();
367 g4SimPars->StoreTrajectories(),
368 g4SimPars->KeepEMShowerDaughters(),
369 g4SimPars->EMShowerDaughterMatRegex());
409 if (vol_names.empty())
return {};
410 std::vector<std::vector<TGeoNode const*>> node_paths =
geo->FindAllVolumePaths(vol_names);
414 GeoVolumePairs.reserve(node_paths.size());
418 for(
auto const& path : node_paths){
420 TGeoTranslation* pTransl =
new TGeoTranslation(0.,0.,0.);
421 TGeoRotation* pRot =
new TGeoRotation();
422 for (TGeoNode
const* node: path) {
423 TGeoTranslation thistranslate(*node->GetMatrix());
424 TGeoRotation thisrotate(*node->GetMatrix());
425 pTransl->Add(&thistranslate);
426 *pRot=*pRot * thisrotate;
431 TGeoTranslation* pTransl2 =
new TGeoTranslation(pTransl->GetTranslation()[0],
432 pTransl->GetTranslation()[1],
433 pTransl->GetTranslation()[2]);
434 double phi=0.,
theta=0.,psi=0.;
435 pRot->GetAngles(phi,
theta,psi);
436 TGeoRotation* pRot2 =
new TGeoRotation();
437 pRot2->SetAngles(phi,
theta,psi);
439 TGeoCombiTrans* pTransf =
new TGeoCombiTrans(*pTransl2,*pRot2);
441 GeoVolumePairs.emplace_back(path.back()->GetVolume(), pTransf);
445 return std::make_unique<PositionInVolumeFilter>(
std::move(GeoVolumePairs));
456 std::unique_ptr< std::vector<simb::MCParticle> > partCol(
new std::vector<simb::MCParticle> );
457 std::unique_ptr< std::vector<sdp::EnergyDeposit> > TPCCol (
new std::vector<sdp::EnergyDeposit> );
458 std::unique_ptr< ::art::Assns<simb::MCTruth, simb::MCParticle> > tpassn (new ::art::Assns<simb::MCTruth, simb::MCParticle>);
459 std::unique_ptr< std::vector< sdp::CaloDeposit > > ECALCol (
new std::vector<sdp::CaloDeposit> );
460 std::unique_ptr< std::vector< sdp::CaloDeposit > > MuIDCol (
new std::vector<sdp::CaloDeposit> );
461 std::unique_ptr< std::vector< sdp::LArDeposit > > LArCol (
new std::vector<sdp::LArDeposit> );
468 std::vector< ::art::Handle< std::vector<simb::MCTruth> > > mclists;
471 mclists = evt.
getMany< std::vector<simb::MCTruth> >();
482 std::vector< ::art::Ptr<simb::MCTruth> > mctPtrs;
483 std::vector< const simb::MCTruth* > mcts;
485 for(
size_t mc = 0; mc < mclists.size(); ++mc){
486 for(
size_t i = 0; i < mclists[mc]->size(); ++i){
488 mctPtrs.push_back(ptr);
489 mcts .push_back(ptr.
get());
502 size_t nGeneratedParticles = 0;
507 <<
"Dump sim::ParticleList; size() = " 508 << particleList.size()
513 auto iPartPair = particleList.begin();
514 while (iPartPair != particleList.end()) {
520 if( trackIDToMCT.count(trackID) > 0){
522 mctidx = trackIDToMCT.find(trackID)->second;
529 nGeneratedParticles);
533 <<
"Cannot find MCTruth for Track Id: " 535 <<
" to create association between Particle and MCTruth";
541 iPartPair = particleList.erase(iPartPair);
543 ++nGeneratedParticles;
550 <<
"adding TPC deposits for track id: " 553 TPCCol->emplace_back(tpc);
558 if (
geo->HasTrackerScDetector())
561 for (
auto const &
hit : deposits)
564 <<
"adding calo deposits for track id: " 567 ECALCol->emplace_back(
hit);
574 <<
"adding muid deposits for track id: " 577 MuIDCol->emplace_back(
hit);
584 <<
"adding LAr deposits for track id: " 587 LArCol->emplace_back(
hit);
593 if(
geo->HasTrackerScDetector())
594 instanceName =
"TrackerSc";
598 if(
geo->HasMuonDetector())
617 #endif // GARG4GARG4H
GArG4(fhicl::ParameterSet const &pset)
Standard constructor and destructor for an FMWK module.
base_engine_t & createEngine(seed_t seed)
std::vector< gar::sdp::CaloDeposit > const & CaloDeposits() const
std::unique_ptr< PositionInVolumeFilter > CreateParticleVolumeFilter(std::set< std::string > const &vol_names) const
Configures and returns a particle filter.
Runs Geant4 simulation and propagation of electrons and photons to readout.
std::vector< gar::sdp::CaloDeposit > const & MuIDDeposits() const
Handle< PROD > getHandle(SelectorBase const &) const
void ResetTrackIDOffset()
const geo::GeometryCore * geo
static G4SimulationParameters * Instance()
EDProducer(fhicl::ParameterSet const &pset)
void UpdateGeometry(G4LogicalVolumeStore *)
void produces(std::string const &instanceName={}, Persistable const persistable=Persistable::Yes)
Description of geometry of one entire detector.
list of energy deposits from Geant4
std::map< int, size_t > TrackIDToMCTruthIndexMap() const
std::string fG4PhysListName
predefined physics list to use if not making a custom one
sim::ParticleList && YieldList()
std::string fG4MacroPath
executed before main MC processing.
bool fdumpParticleList
Whether each event's sim::ParticleList will be displayed.
std::vector< std::string > fInputLabels
fhicl::ParameterSet fEDepActionPSet
configuration for GArAction
#define DEFINE_ART_MODULE(klass)
garg4::EnergyDepositAction * fEDepAction
Geant4 user action to handle GAr energy depositions.
std::vector< std::string > fDetRegionNames
Name of the volumes used to defined regions.
std::vector< std::string > fKeepParticlesInVolumes
Only write particles that have trajectories through these volumes.
std::vector< Handle< PROD > > getMany(SelectorBase const &selector=MatchAllSelector{}) const
CLHEP::HepRandomEngine & fEngine
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
static int max(int a, int b)
#define MF_LOG_INFO(category)
Detector simulation of raw signals on wires.
void beginRun(::art::Run &run)
int fSmartStacking
dictate how tracks are put on stack.
std::vector< VolumeInfo_t > AllVolumeInfo_t
General GArSoft Utilities.
g4b::G4Helper * fG4Help
G4 interface object.
std::vector< gar::sdp::LArDeposit > const & LArDeposits() const
void GetPropertiesFromServices()
std::vector< gar::sdp::EnergyDeposit > const & EnergyDeposits() const
garg4::ParticleListAction * fParticleListAction
Geant4 user action to particle information.
std::vector< float > fMaxStepSize
maximum step size in mm per sub-detector region
std::string find_file(std::string const &filename) const
void produce(::art::Event &evt)
static constexpr double mm
list of energy deposits from Geant4
void ParticleFilter(std::unique_ptr< PositionInVolumeFilter > &&filter)
Grabs a particle filter.
float fProductionCut
G4 will check if a produced particle should travel this far and drop it if not.
bool fCheckOverlaps
Whether to use the G4 overlap checker.
void SetLimitsAndCuts()
Set the user limits and production cuts per region.
LArSoft geometry interface.
art framework interface to geometry description
std::vector< gar::sdp::CaloDeposit > const & TrackerScDeposits() const
static ServiceHandle< RandomNumberGenerator > & rng()
garg4::AuxDetAction * fAuxDetAction
Geant4 user action to handle GAr energy depositions.
cet::coded_exception< error, detail::translate > exception
static G4SimulationParameters * CreateInstance(fhicl::ParameterSet const &pset)
fhicl::ParameterSet fAuxDetActionPSet
configuration for AuxAction