In the case that particles are being passed back to Geant4 then we may have particles which have already interacted, so we should set the regeneration number accordingly.
993{
995
997 if (!truthBinding) {
999 description << G4String(
"getG4PrimaryParticle: ") +
"No ISF::TruthBinding associated with ISParticle (" << isp <<
")";
1000 G4Exception(
"iGeant4::TransportTool",
"NoISFTruthBinding", FatalException,
description);
1001 return nullptr;
1002 }
1005
1007
1008 if (particleDefinition==nullptr) {
1009 ATH_MSG_ERROR(
"ISF_to_G4Event particle conversion failed. ISF_Particle PDG code = " << isp.
pdgCode() <<
1010 "\n This usually indicates a problem with the evgen step.\n" <<
1011 "Please report this to the Generators group, mentioning the release and generator used for evgen and the PDG code above." );
1012 return nullptr;
1013 }
1014
1015
1016
1020 if (useHepMC && currentGenPart) {
1021 auto ¤tGenPartMomentum = currentGenPart->momentum();
1022 px = currentGenPartMomentum.x();
1023 py = currentGenPartMomentum.y();
1024 pz = currentGenPartMomentum.z();
1025 }
1026 else {
1027 auto &ispMomentum = isp.
momentum();
1028 px = ispMomentum.x();
1029 py = ispMomentum.y();
1030 pz = ispMomentum.z();
1031 }
1032
1033 std::unique_ptr<G4PrimaryParticle> g4particle = std::make_unique<G4PrimaryParticle>(particleDefinition,px,py,pz);
1034
1035 std::unique_ptr<PrimaryParticleInformation> primaryPartInfo = std::make_unique<PrimaryParticleInformation>(primaryGenpart,&isp);
1036
1043 }
1044 primaryPartInfo->SetRegenerationNr(regenerationNr);
1045
1046 if ( currentGenPart ) {
1047 if (currentGenPart->end_vertex()) {
1048
1049
1050 ATH_MSG_ERROR (
"getG4PrimaryParticle(): GenParticle has a valid end GenVertexPtr!" );
1051 ATH_MSG_ERROR (
"getG4PrimaryParticle(): currentGenPart: " << currentGenPart <<
", barcode: " <<
HepMC::barcode(currentGenPart) );
1052 ATH_MSG_ERROR (
"getG4PrimaryParticle(): currentGenPart->end_vertex(): " << currentGenPart->end_vertex() <<
", barcode: " <<
HepMC::barcode(currentGenPart->end_vertex()) );
1053 ATH_MSG_FATAL (
"getG4PrimaryParticle(): Passing GenParticles with a valid end GenVertexPtr as input is no longer supported." );
1054 abort();
1055 }
1057 && !currentGenPart->end_vertex()) {
1058
1059
1060#ifdef HEPMC3
1061 auto A_part = currentGenPart->attribute<HepMC::ShadowParticle>("ShadowParticle");
1063#else
1065#endif
1066 if (!shadowPart) {
1067 ATH_MSG_FATAL (
"Found a GenParticle with no matching GenParticle in the shadowGenEvent - something is wrong here!");
1068 abort();
1069 }
1070 if (!shadowPart->end_vertex()) {
1071 ATH_MSG_FATAL (
"Found status==2 shadow GenParticle with no end vertex - something is wrong here!");
1072 abort();
1073 }
1074#ifdef HEPMC3
1076#else
1078#endif
1079 }
1080
1082 const double pmass = g4particle->GetMass();
1083 CLHEP::Hep3Vector gpv = g4particle->GetMomentum();
1084 double g4px=g4particle->GetMomentum().x();
1085 double g4py=g4particle->GetMomentum().y();
1086 double g4pz=g4particle->GetMomentum().z();
1087 if (useHepMC) {
1088
1092 } else {
1093
1094 px=currentGenPart->momentum().px();
1095 py=currentGenPart->momentum().py();
1096 pz=currentGenPart->momentum().pz();
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106 if (std::abs(px-g4px)<CLHEP::keV && std::abs(py-g4py)<CLHEP::keV && std::abs(pz-g4pz)<CLHEP::keV) {
1110 }
1111 }
1113 const double pe = std::sqrt(
mag2 + pmass*pmass);
1114
1115 double originalEnergy=currentGenPart->momentum().e();
1116 if (originalEnergy>0.01) {
1117 if ((originalEnergy-pe)/originalEnergy>0.01) {
1118 double genpx=currentGenPart->momentum().px();
1119 double genpy=currentGenPart->momentum().py();
1120 double genpz=currentGenPart->momentum().pz();
1121 double genp=sqrt(genpx*genpx + genpy*genpy + genpz*genpz);
1122 ATH_MSG_WARNING(
"Truth change in energy for: " << currentGenPart<<
" Morg="<<currentGenPart->momentum().m()<<
" Mmod="<<pmass<<
" Eorg="<<originalEnergy<<
" Emod="<<pe<<
" porg="<<genp<<
" pmod="<<gpv.mag());
1123 }
1124 }
1125
1126#ifdef HEPMC3
1127 auto& currentGenPart_nc = currentGenPart;
1128#else
1129 auto* currentGenPart_nc = currentGenPart;
1130#endif
1131 currentGenPart_nc->set_momentum(HepMC::FourVector(px,py,pz,pe));
1132 }
1133
1135 ATH_MSG_VERBOSE(
" GetParticleUniqueID = " << primaryPartInfo->GetParticleUniqueID());
1136 ATH_MSG_VERBOSE(
" GetRegenerationNr = " << primaryPartInfo->GetRegenerationNr());
1137 ATH_MSG_VERBOSE(
" GetHepMCParticle = " << primaryPartInfo->GetHepMCParticle());
1138 ATH_MSG_VERBOSE(
" GetISFParticle = " << primaryPartInfo->GetISFParticle());
1139 g4particle->SetUserInformation(primaryPartInfo.release());
1140
1141 return g4particle.release();
1142}
Scalar mag2() const
mag2 method - forward to squaredNorm()
const TruthBinding * getTruthBinding() const
pointer to the simulation truth - optional, can be 0
const Amg::Vector3D & momentum() const
The current momentum vector of the ISFParticle.
int pdgCode() const
PDG value.
HepMC::GenParticlePtr getCurrentGenParticle()
pointer to the particle in the simulation truth
std::string description
glabal timer - how long have I taken so far?
int generations(const T &p)
Method to return how many interactions a particle has undergone during simulation (only to be used in...
int generations(const T &p)
Method to return how many interactions a particle has undergone during simulation based on the status...
const GenParticle * ConstGenParticlePtr