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.
798{
800
802 if (!truthBinding) {
804 description << G4String(
"getG4PrimaryParticle: ") +
"No ISF::TruthBinding associated with ISParticle (" << isp <<
")";
805 G4Exception(
"iGeant4::TransportTool",
"NoISFTruthBinding", FatalException,
description);
806 return nullptr;
807 }
810
812
813 if (particleDefinition==nullptr) {
814 ATH_MSG_ERROR(
"ISF_to_G4Event particle conversion failed. ISF_Particle PDG code = " << isp.
pdgCode() <<
815 "\n This usually indicates a problem with the evgen step.\n" <<
816 "Please report this to the Generators group, mentioning the release and generator used for evgen and the PDG code above." );
817 return nullptr;
818 }
819
820
821
825 if (useHepMC && currentGenPart) {
826 auto ¤tGenPartMomentum = currentGenPart->momentum();
827 px = currentGenPartMomentum.x();
828 py = currentGenPartMomentum.y();
829 pz = currentGenPartMomentum.z();
830 }
831 else {
833 px = ispMomentum.x();
834 py = ispMomentum.y();
835 pz = ispMomentum.z();
836 }
837
838 std::unique_ptr<G4PrimaryParticle> g4particle = std::make_unique<G4PrimaryParticle>(particleDefinition,px,py,pz);
839
840 std::unique_ptr<PrimaryParticleInformation> primaryPartInfo = std::make_unique<PrimaryParticleInformation>(primaryGenpart,&isp);
841
848 }
849 primaryPartInfo->SetRegenerationNr(regenerationNr);
850
851 if ( currentGenPart ) {
852 if (currentGenPart->end_vertex()) {
853
854
855 ATH_MSG_ERROR (
"getG4PrimaryParticle(): GenParticle has a valid end GenVertexPtr!" );
857 ATH_MSG_ERROR (
"getG4PrimaryParticle(): currentGenPart->end_vertex(): " << currentGenPart->end_vertex() <<
", barcode: " <<
HepMC::barcode(currentGenPart->end_vertex()) );
858 ATH_MSG_FATAL (
"getG4PrimaryParticle(): Passing GenParticles with a valid end GenVertexPtr as input is no longer supported." );
859 abort();
860 }
862 && !currentGenPart->end_vertex()) {
863
864
867 if (!shadowPart) {
868 ATH_MSG_FATAL (
"Found a GenParticle with no matching GenParticle in the shadowGenEvent - something is wrong here!");
869 abort();
870 }
871 if (!shadowPart->end_vertex()) {
872 ATH_MSG_FATAL (
"Found status==2 shadow GenParticle with no end vertex - something is wrong here!");
873 abort();
874 }
876 }
877
879 const double pmass = g4particle->GetMass();
880 CLHEP::Hep3Vector gpv = g4particle->GetMomentum();
881 double g4px=g4particle->GetMomentum().x();
882 double g4py=g4particle->GetMomentum().y();
883 double g4pz=g4particle->GetMomentum().z();
884 if (useHepMC) {
885
889 } else {
890
891 px=currentGenPart->momentum().px();
892 py=currentGenPart->momentum().py();
893 pz=currentGenPart->momentum().pz();
894
895
896
897
898
899
900
901
902
903 if (std::abs(px-g4px)<CLHEP::keV && std::abs(py-g4py)<CLHEP::keV && std::abs(pz-g4pz)<CLHEP::keV) {
907 }
908 }
910 const double pe = std::sqrt(
mag2 + pmass*pmass);
911
912 double originalEnergy=currentGenPart->momentum().e();
913 if (originalEnergy>0.01) {
914 if ((originalEnergy-pe)/originalEnergy>0.01) {
915 double genpx=currentGenPart->momentum().px();
916 double genpy=currentGenPart->momentum().py();
917 double genpz=currentGenPart->momentum().pz();
918 double genp=sqrt(genpx*genpx + genpy*genpy + genpz*genpz);
919 ATH_MSG_WARNING(
"Truth change in energy for: " << currentGenPart<<
" Morg="<<currentGenPart->momentum().m()<<
" Mmod="<<pmass<<
" Eorg="<<originalEnergy<<
" Emod="<<pe<<
" porg="<<genp<<
" pmod="<<gpv.mag());
920 }
921 }
922
923 auto& currentGenPart_nc = currentGenPart;
925 }
926
928 ATH_MSG_VERBOSE(
" GetParticleUniqueID = " << primaryPartInfo->GetParticleUniqueID());
929 ATH_MSG_VERBOSE(
" GetRegenerationNr = " << primaryPartInfo->GetRegenerationNr());
930 ATH_MSG_VERBOSE(
" GetHepMCParticle = " << primaryPartInfo->GetHepMCParticle());
931 ATH_MSG_VERBOSE(
" GetISFParticle = " << primaryPartInfo->GetISFParticle());
932 g4particle->SetUserInformation(primaryPartInfo.release());
933
934 return g4particle.release();
935}
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?
const std::string ShadowParticle
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...
HepMC3::FourVector FourVector
HepMC3::GenParticlePtr GenParticlePtr
HepMC3::ConstGenParticlePtr ConstGenParticlePtr