File indexing completed on 2025-08-06 08:18:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include "G4EvtGenDecayer.hh"
0038 #include "PHEvtGenRandomEngine.hh" // for PHEvtGenRandomEngine
0039
0040 #include <EvtGen/EvtGen.hh> // for EvtGen
0041 #include <EvtGenBase/EvtAbsRadCorr.hh> // for EvtAbsRadCorr
0042 #include <EvtGenBase/EvtHepMCEvent.hh> // for EvtHepMCEvent
0043 #include <EvtGenBase/EvtId.hh> // for EvtId
0044 #include <EvtGenBase/EvtPDL.hh> // for EvtPDL
0045 #include <EvtGenBase/EvtParticle.hh> // for EvtParticle
0046 #include <EvtGenBase/EvtParticleFactory.hh> // for EvtParticleFactory
0047 #include <EvtGenBase/EvtRandom.hh> // for EvtRandom
0048 #include <EvtGenBase/EvtVector4R.hh> // for EvtVector4R
0049 #include <EvtGenExternal/EvtExternalGenList.hh> // for EvtExternalGenList
0050
0051 #include <HepMC3/Attribute.h> // for string
0052 #include <HepMC3/FourVector.h> // for FourVector
0053 #include <HepMC3/GenEvent.h> // for GenEvent
0054 #include <HepMC3/GenParticle.h> // for GenParticle
0055 #include <HepMC3/GenParticle_fwd.h> // for GenParticlePtr
0056 #include <HepMC3/GenVertex.h> // for GenVertex
0057 #include <HepMC3/GenVertex_fwd.h> // for GenVertexPtr
0058 #include <HepMC3/Print.h> // for Print
0059
0060 #include <Geant4/G4DecayProducts.hh>
0061 #include <Geant4/G4DynamicParticle.hh>
0062 #include <Geant4/G4ParticleDefinition.hh> // for G4ParticleDefinition
0063 #include <Geant4/G4ParticleTable.hh>
0064 #include <Geant4/G4String.hh> // for G4String
0065 #include <Geant4/G4SystemOfUnits.hh>
0066 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
0067 #include <Geant4/G4Track.hh>
0068 #include <Geant4/G4Types.hh> // for G4int, G4double
0069 #include <Geant4/G4VExtDecayer.hh> // for G4VExtDecayer
0070
0071 #include <algorithm> // for copy, max
0072 #include <cstdlib> // for abs
0073 #include <iostream> // for operator<<, basic_ostream:...
0074 #include <memory> // for __shared_ptr_access
0075 #include <stack> // for operator<<
0076 #include <string> // for operator<<
0077 #include <vector> // for vector
0078
0079 class EvtDecayBase;
0080
0081
0082
0083 G4EvtGenDecayer::G4EvtGenDecayer()
0084 : G4VExtDecayer("G4EvtGenDecayer")
0085 , fVerboseLevel(0)
0086 {
0087 mEvtGenRandomEngine = new PHEvtGenRandomEngine();
0088
0089 EvtRandom::setRandomEngine(static_cast<EvtRandomEngine*>(mEvtGenRandomEngine));
0090
0091 radCorrEngine = genList.getPhotosModel();
0092
0093 extraModels = genList.getListOfModels();
0094
0095
0096 const char* offline_main = getenv("OFFLINE_MAIN");
0097
0098 if (!offline_main)
0099 {
0100 exit(1);
0101 }
0102
0103 string decay = string(offline_main) + "/share/EvtGen/DECAY.DEC";
0104 string evt = string(offline_main) + "/share/EvtGen/evt.pdl";
0105
0106 mEvtGen = new EvtGen(decay, evt, static_cast<EvtRandomEngine*>(mEvtGenRandomEngine), radCorrEngine, &extraModels);
0107 extraModels.clear();
0108 }
0109
0110
0111
0112 G4EvtGenDecayer::~G4EvtGenDecayer()
0113 {
0114 delete mEvtGen;
0115
0116 delete radCorrEngine;
0117 }
0118
0119
0120
0121 G4ParticleDefinition* G4EvtGenDecayer::
0122 GetParticleDefinition(int ParPDGID) const
0123 {
0124
0125
0126
0127 G4int pdgEncoding = ParPDGID;
0128 G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
0129 G4ParticleDefinition* particleDefinition = nullptr;
0130 if (pdgEncoding != 0)
0131 {
0132 particleDefinition = particleTable->FindParticle(pdgEncoding);
0133 }
0134
0135 return particleDefinition;
0136 }
0137
0138
0139
0140 G4DecayProducts* G4EvtGenDecayer::ImportDecayProducts(const G4Track& track)
0141 {
0142
0143
0144 G4ThreeVector momentum = track.GetMomentum();
0145 G4double etot = track.GetDynamicParticle()->GetTotalEnergy();
0146
0147 G4ParticleDefinition* particleDef = track.GetDefinition();
0148 G4int pdgEncoding = particleDef->GetPDGEncoding();
0149
0150 EvtVector4R p_init(etot / GeV, momentum.x() / GeV, momentum.y() / GeV, momentum.z() / GeV);
0151
0152 EvtId parentID = EvtPDL::evtIdFromLundKC(pdgEncoding);
0153
0154 auto mParticle = EvtParticleFactory::particleFactory(parentID, p_init);
0155
0156 mEvtGen->generateDecay(mParticle);
0157
0158 EvtHepMCEvent theEvent;
0159
0160 theEvent.constructEvent(mParticle);
0161
0162 HepMC3::GenEvent* evt = theEvent.getEvent();
0163
0164 G4DecayProducts* decayProducts = new G4DecayProducts(*(track.GetDynamicParticle()));
0165
0166 std::stack<HepMC3::GenParticlePtr> stack;
0167
0168 auto part = evt->particles()[0];
0169
0170 if (part->pdg_id() != pdgEncoding)
0171 {
0172 std::cout << "Issue Found: The first particle in the decay chain is NOT the incoming particle decayed by EvtGen" << std::endl;
0173 }
0174
0175 stack.push(part);
0176
0177 while (!stack.empty())
0178 {
0179 auto particle = stack.top();
0180 stack.pop();
0181
0182 for (const auto& children : particle->children())
0183 {
0184 float EvtWidth = 9999;
0185 int pdg = children->pdg_id();
0186
0187 G4ParticleDefinition* particleDefinition = GetParticleDefinition(pdg);
0188 if (EvtPDL::evtIdFromLundKC(pdg).getId() != -1)
0189 {
0190 EvtWidth = EvtPDL::getWidth(EvtPDL::evtIdFromLundKC(pdg)) * 1000000;
0191 }
0192
0193 if (particleDefinition && EvtWidth < WidthThreshold)
0194 {
0195 bool SameVtxPos = true;
0196
0197 if (children->production_vertex()->position().x() != particle->end_vertex()->position().x() || children->production_vertex()->position().y() != particle->end_vertex()->position().y() || children->production_vertex()->position().z() != particle->end_vertex()->position().z() || children->production_vertex()->position().t() != particle->end_vertex()->position().t())
0198 {
0199 SameVtxPos = false;
0200 }
0201 if (!SameVtxPos)
0202 {
0203 std::cout << "Issue Found: in this vertex, particles pushed to GEANT have different production positions, need to check and understand why!!!" << std::endl;
0204 std::cout << "This is due to the particle PDGID: " << children->pdg_id() << " from the decay vertex of the parent particle:" << particle->pdg_id() << std::endl;
0205 std::cout << "Here is the Event Content" << std::endl;
0206 const HepMC3::GenEvent& CheckEvent = *evt;
0207 HepMC3::Print::content(CheckEvent);
0208 }
0209
0210 G4ThreeVector G4Mom = G4ThreeVector(children->momentum().px() * GeV, children->momentum().py() * GeV, children->momentum().pz() * GeV);
0211 G4DynamicParticle* dynamicParticle = new G4DynamicParticle(particleDefinition, G4Mom);
0212
0213 if (dynamicParticle)
0214 {
0215 if (fVerboseLevel > 0)
0216 {
0217 std::cout << " G4 particle name: "
0218 << dynamicParticle->GetDefinition()->GetParticleName()
0219 << std::endl;
0220 }
0221
0222 decayProducts->PushProducts(dynamicParticle);
0223 }
0224 else
0225 {
0226 std::cout << "Dynamical particle to be pushed from EvtGen to GEANT 4 is not properly defined: need to check why this happens!" << std::endl;
0227 exit(1);
0228 }
0229 }
0230 else
0231 {
0232 stack.push(children);
0233 }
0234 }
0235 }
0236
0237 evt->clear();
0238 mParticle->deleteTree();
0239 return decayProducts;
0240 }
0241
0242
0243
0244 void G4EvtGenDecayer::SetDecayTable(const string& decayTable, bool useXml)
0245 {
0246 mEvtGen->readUDecay(decayTable, useXml);
0247 }