7 #include "artg4tk/services/ActionHolder_service.hh" 8 #include "nug4/G4Base/PrimaryParticleInformation.h" 12 #include "CLHEP/Vector/LorentzVector.h" 13 #include "Geant4/G4Event.hh" 14 #include "Geant4/G4IonTable.hh" 15 #include "Geant4/G4ParticleDefinition.hh" 16 #include "Geant4/G4ParticleTable.hh" 17 #include "Geant4/G4PrimaryVertex.hh" 26 genie_specific(
int const pdg)
28 constexpr
int genieLoPdg = 2000000001;
29 constexpr
int genieHiPdg = 2000000300;
30 return pdg >= genieLoPdg && pdg <= genieHiPdg;
37 : PrimaryGeneratorActionBase(p.
get<
string>(
"name",
"MCTruthEventActionService"))
44 std::ostringstream badtxt;
46 badtxt <<
"\n Unknown PDG code = " <<
pdg <<
", seen " <<
n <<
" times.";
47 if (genie_specific(
pdg)) { badtxt <<
" (GENIE specific)"; }
50 mf::LogWarning(
"MCTruthEventAction") <<
"The following unknown PDG codes were present in the " 51 <<
"simb::MCTruth input.\n" 52 <<
"They were not processed by Geant4." << badtxt.str();
57 std::ostringstream non1txt;
59 non1txt <<
"\n PDG code = " <<
pdg <<
", seen " <<
n <<
" times.";
60 if (genie_specific(
pdg)) { non1txt <<
" (GENIE specific)"; }
63 mf::LogDebug(
"MCTruthEventAction") <<
"The following PDG codes were present in the " 64 <<
"simb::MCTruth input with Status != 1.\n" 65 <<
"They were not processed by Geant4." << non1txt.str();
70 std::ostringstream goodtxt;
72 goodtxt <<
"\n PDG code = " <<
pdg <<
", seen " <<
n <<
" times.";
74 mf::LogDebug(
"MCTruthEventAction") <<
"The following PDG codes were present in the " 75 <<
"simb::MCTruth input with Status = 1 " 76 <<
"and were processed by Geant4" << goodtxt.str();
87 auto const& mclistHandles = *
fMCLists;
89 size_t mclSize = mclistHandles.size();
90 mf::LogDebug(
"generatePrimaries") <<
"MCTruth Handles Size: " << mclSize;
94 std::map<CLHEP::HepLorentzVector, G4PrimaryVertex*> vertexMap;
95 for (
size_t mcl = 0; mcl < mclSize; ++mcl) {
97 <<
"MCTruth Handle Number: " << (mcl + 1) <<
" of " << mclSize;
101 for (
size_t i = 0; i < mclistHandle->size(); ++i) {
105 <<
"art::Ptr number " << (i + 1) <<
" of " << mclistHandle->size() <<
", Ptr: " << mclist;
107 MF_LOG_INFO(
"generatePrimaries") <<
"Generating " << nPart <<
" particles";
110 for (
int m = 0;
m != nPart; ++
m) {
112 G4int
const pdgCode = particle.
PdgCode();
116 <<
"Status code != 1, skipping particle number with MCTruth index = " 117 <<
"(" << mcl <<
"," << i <<
")" 118 <<
" and particle index = " <<
m;
123 if (((
m + 1) % nPart) < 2)
125 mf::LogDebug(
"generatePrimaries") <<
"Particle Number: " << (
m + 1) <<
" of " << nPart;
136 CLHEP::HepLorentzVector fourpos(x, y, z, t);
139 G4PrimaryVertex*
vertex =
nullptr;
140 auto result = vertexMap.find(fourpos);
141 if (
result == vertexMap.end()) {
143 vertex =
new G4PrimaryVertex(x, y, z, t);
144 vertexMap[fourpos] = vertex;
147 anEvent->AddPrimaryVertex(vertex);
164 G4ParticleDefinition* particleDefinition =
nullptr;
166 if (pdgCode == 0) { particleDefinition =
fParticleTable->FindParticle(
"opticalphoton"); }
171 if (pdgCode >= 2
'000'000
'000) { // If the particle is generator-specific 172 mf::LogDebug("ConvertPrimaryToGeant4") 173 << ": %%% Will skip particle with generator-specific PDG code = " << pdgCode; 174 fUnknownPDG[pdgCode] += 1; 177 if (pdgCode > 1'000
'000'000) {
179 <<
": %%% Nuclear PDG code = " << pdgCode <<
" (x,y,z,t)=(" << x <<
"," << y <<
"," << z
181 <<
" P=" << momentum.P() <<
", E=" << momentum.E();
185 if (!particleDefinition) {
186 int const Z = (pdgCode % 10
'000'000) / 10
'000; // atomic number 187 int const A = (pdgCode % 10'000) / 10;
194 if (particleDefinition ==
nullptr) {
195 mf::LogDebug(
"ConvertPrimaryToGeant4") <<
": %%% Code not found = " << pdgCode;
203 auto* g4particle =
new G4PrimaryParticle(particleDefinition,
209 g4particle->SetCharge(particleDefinition->GetPDGCharge());
210 g4particle->SetPolarization(polarization.x(), polarization.y(), polarization.z());
213 vertex->SetPrimary(g4particle);
220 auto* primaryParticleInfo =
new g4b::PrimaryParticleInformation;
221 primaryParticleInfo->SetMCTruth(mclist.
get(),
index,
m);
225 g4particle->SetUserInformation(primaryParticleInfo);
static constexpr double cm
const TVector3 & Polarization() const
~MCTruthEventActionService()
static G4ParticleTable * fParticleTable
Geant4's table of particle definitions.
std::vector< art::Handle< std::vector< simb::MCTruth > > > const * fMCLists
MCTruthCollection input lists.
static constexpr double GeV
void generatePrimaries(G4Event *anEvent) override
double T(const int i=0) const
std::map< G4int, G4int > fProcessedPDG
PDG codes processed.
#define MF_LOG_INFO(category)
std::map< G4int, G4int > fNon1StatusPDG
PDG codes skipped because not status 1.
const simb::MCParticle & GetParticle(int i) const
double Vx(const int i=0) const
#define DEFINE_ART_SERVICE(svc)
std::map< G4int, G4int > fUnknownPDG
map of unknown PDG codes to instances
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
const TLorentzVector & Momentum(const int i=0) const
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
double Vz(const int i=0) const
MCTruthEventActionService(fhicl::ParameterSet const &)
auto const & get(AssnsNode< L, R, D > const &r)
def momentum(x1, x2, x3, scale=1.)
double Vy(const int i=0) const