diff --git a/Simulation/ISF/ISF_Core/ISF_Event/ISF_Event/ISFTruthIncident.h b/Simulation/ISF/ISF_Core/ISF_Event/ISF_Event/ISFTruthIncident.h index 8942bfb186cb3f76dd73a19c36719f96169d1626..0e43f15f085185e43880d885cf707df1354f5314 100644 --- a/Simulation/ISF/ISF_Core/ISF_Event/ISF_Event/ISFTruthIncident.h +++ b/Simulation/ISF/ISF_Core/ISF_Event/ISF_Event/ISFTruthIncident.h @@ -86,6 +86,8 @@ namespace ISF { double childEkin(unsigned short index) const override final; /** Return the PDG Code of the i-th child particle */ int childPdgCode(unsigned short index) const override final; + /** Return the barcode of the i-th child particle (if defined as part of the TruthIncident) otherwise return 0 */ + Barcode::ParticleBarcode childBarcode(unsigned short) const override final {return 0;}; /** Return the i-th child as a HepMC particle type and assign the given Barcode to the simulator particle (usually only called for particles that will enter the HepMC truth event) */ diff --git a/Simulation/ISF/ISF_Core/ISF_Event/ISF_Event/ITruthIncident.h b/Simulation/ISF/ISF_Core/ISF_Event/ISF_Event/ITruthIncident.h index 4bb601624a7accfe356fc034b62cd91ae4ddf7e7..610b4f420bd6eb1042b3cd7182000a40a3411564 100644 --- a/Simulation/ISF/ISF_Core/ISF_Event/ISF_Event/ITruthIncident.h +++ b/Simulation/ISF/ISF_Core/ISF_Event/ISF_Event/ITruthIncident.h @@ -95,6 +95,8 @@ namespace ISF { virtual double childEkin(unsigned short index) const = 0; /** Return the PDG Code of the i-th child particle */ virtual int childPdgCode(unsigned short index) const = 0; + /** Return the barcode of the i-th child particle (if defined as part of the TruthIncident) otherwise return 0 */ + virtual Barcode::ParticleBarcode childBarcode(unsigned short index) const = 0; /** Return true if at least one child particle passes the given p^2 cut (= at least one child with p^2 >= pt2cut) */ inline bool childrenP2Pass(double p2cut); diff --git a/Simulation/ISF/ISF_Core/ISF_Services/src/TruthSvc.cxx b/Simulation/ISF/ISF_Core/ISF_Services/src/TruthSvc.cxx index 30b80472263e37b57be98316bc2809c8d7e9f18b..6c6363c59edf5dd1097c1bfdf7dca476d375e953 100644 --- a/Simulation/ISF/ISF_Core/ISF_Services/src/TruthSvc.cxx +++ b/Simulation/ISF/ISF_Core/ISF_Services/src/TruthSvc.cxx @@ -291,10 +291,16 @@ void ISF::TruthSvc::recordIncidentToMCTruth( ISF::ITruthIncident& ti, bool passW tmpVtx->add_particle_in( parentBeforeIncident ); tmpVtx->add_particle_out( parentAfterIncident ); vtx->add_particle_in( parentAfterIncident ); +#ifdef HEPMC3 + HepMC::suggest_barcode( parentAfterIncident, newPrimBC ); // TODO check this works correctly +#endif vtx = tmpVtx; } else { vtx->add_particle_out( parentAfterIncident ); +#ifdef HEPMC3 + HepMC::suggest_barcode( parentAfterIncident, newPrimBC ); // TODO check this works correctly +#endif } } @@ -366,9 +372,18 @@ void ISF::TruthSvc::recordIncidentToMCTruth( ISF::ITruthIncident& ti, bool passW abort(); } } - p = ti.childParticle( i, secBC ); + p = ti.childParticle( i, secBC ); // potentially overrides secBC // add particle to vertex vtx->add_particle_out( p); +#ifdef HEPMC3 + Barcode::ParticleBarcode secBCFromTI = ti.childBarcode(i); + if (secBCFromTI) { + HepMC::suggest_barcode( p, secBCFromTI ); + } + else { + HepMC::suggest_barcode( p, secBC ); + } +#endif } ATH_MSG_VERBOSE ( "Writing out " << i << "th child particle: " << p); } // <-- if write out child particle diff --git a/Simulation/ISF/ISF_Core/ISF_Services/test/TruthSvc_test.cxx b/Simulation/ISF/ISF_Core/ISF_Services/test/TruthSvc_test.cxx index 7a8f9d15479f659f3ca735f562c54f30640ea6c1..9997fe341dd55c0231f6b95a8e83891c35f456ef 100644 --- a/Simulation/ISF/ISF_Core/ISF_Services/test/TruthSvc_test.cxx +++ b/Simulation/ISF/ISF_Core/ISF_Services/test/TruthSvc_test.cxx @@ -109,6 +109,8 @@ namespace ISFTesting { virtual double childEkin(unsigned short) const {return 1.0;}; /** Return the PDG Code of the i-th child particle */ virtual int childPdgCode(unsigned short) const {return 1;}; + /** Return the barcode of the i-th child particle (if defined as part of the TruthIncident) otherwise return 0 */ + Barcode::ParticleBarcode childBarcode(unsigned short) const override final {return 0;}; /** Return the i-th child as a HepMC particle type and assign the given Barcode to the simulator particle (only called for particles that will enter the HepMC truth event) */ diff --git a/Simulation/ISF/ISF_Geant4/ISF_Geant4Event/ISF_Geant4Event/Geant4TruthIncident.h b/Simulation/ISF/ISF_Geant4/ISF_Geant4Event/ISF_Geant4Event/Geant4TruthIncident.h index 344497caddda8ad8d445ae0bf5961420a1ed08b7..263b0a62e5d04362fa540c6671369bf06a36fe8a 100644 --- a/Simulation/ISF/ISF_Geant4/ISF_Geant4Event/ISF_Geant4Event/Geant4TruthIncident.h +++ b/Simulation/ISF/ISF_Geant4/ISF_Geant4Event/ISF_Geant4Event/Geant4TruthIncident.h @@ -80,6 +80,8 @@ namespace iGeant4 { double childEkin(unsigned short index) const override final; /** Return the PDG Code of the i-th child particle */ int childPdgCode(unsigned short index) const override final; + /** Return the barcode of the i-th child particle (if defined as part of the TruthIncident) otherwise return 0 */ + Barcode::ParticleBarcode childBarcode(unsigned short index) const override final; /** Set the the barcode of all child particles to the given bc */ void setAllChildrenBarcodes(Barcode::ParticleBarcode bc) override final; @@ -114,7 +116,7 @@ namespace iGeant4 { /** check if the given G4Track represents a particle that is alive in ISF or ISF-G4 */ inline bool particleAlive(const G4Track *track) const; - HepMC::GenParticlePtr convert(const G4Track *particle, const int barcode, const bool secondary) const; //*AS* might be put static + HepMC::GenParticlePtr convert(const G4Track *particle, const int barcode, const bool secondary) const; bool m_positionSet; HepMC::FourVector m_position; diff --git a/Simulation/ISF/ISF_Geant4/ISF_Geant4Event/src/Geant4TruthIncident.cxx b/Simulation/ISF/ISF_Geant4/ISF_Geant4Event/src/Geant4TruthIncident.cxx index a0717f3767d444a853f08d777636fc6f65d5d213..e044b2559b15fdf8e521a1a5384bf7f0ada08537 100644 --- a/Simulation/ISF/ISF_Geant4/ISF_Geant4Event/src/Geant4TruthIncident.cxx +++ b/Simulation/ISF/ISF_Geant4/ISF_Geant4Event/src/Geant4TruthIncident.cxx @@ -204,6 +204,23 @@ int iGeant4::Geant4TruthIncident::childPdgCode(unsigned short i) const { return m_children[i]->GetDefinition()->GetPDGEncoding(); } +Barcode::ParticleBarcode iGeant4::Geant4TruthIncident::childBarcode(unsigned short index) const { + // the G4Track instance for the current child particle + const G4Track* track = m_children[index]; + // This should be a *secondary* track. If it has a primary, it was a decay and + // we are running with quasi-stable particle simulation. Note that if the primary + // track is passed in as a secondary that survived the interaction, then this was + // *not* a decay and we should not treat it in this way + if (track->GetDynamicParticle() && + track->GetDynamicParticle()->GetPrimaryParticle() && + track->GetDynamicParticle()->GetPrimaryParticle()->GetUserInformation()){ + // Then the new particle should use the same barcode as the old one!! + PrimaryParticleInformation* ppi = dynamic_cast<PrimaryParticleInformation*>( track->GetDynamicParticle()->GetPrimaryParticle()->GetUserInformation() ); + return ppi->GetParticleBarcode(); + } + return 0; +} + void iGeant4::Geant4TruthIncident::setAllChildrenBarcodes(Barcode::ParticleBarcode) { G4ExceptionDescription description; description << G4String("setAllChildrenBarcodes: ") + "Shared child particle barcodes are not implemented in ISF_Geant4 at this point."; @@ -219,17 +236,16 @@ HepMC::GenParticlePtr iGeant4::Geant4TruthIncident::childParticle(unsigned short // secondary could decay right away and create further particles which pass the // truth strategies. - HepMC::GenParticlePtr hepParticle = convert( thisChildTrack , newBarcode , true ); - + HepMC::GenParticlePtr hepParticle = convert( thisChildTrack, newBarcode, true ); TrackHelper tHelper(thisChildTrack); TrackInformation *trackInfo = tHelper.GetTrackInformation(); // needed to make AtlasG4 work with ISF TruthService - if(trackInfo==nullptr) { - trackInfo = new TrackInformation( hepParticle ); - thisChildTrack->SetUserInformation( trackInfo ); - } - + if (trackInfo==nullptr) { + trackInfo = new TrackInformation( hepParticle ); + thisChildTrack->SetUserInformation( trackInfo ); + } + trackInfo->SetParticle(hepParticle); trackInfo->SetClassification(RegisteredSecondary); trackInfo->SetRegenerationNr(0); @@ -296,8 +312,11 @@ bool iGeant4::Geant4TruthIncident::particleAlive(const G4Track *track) const { return true; } - +#ifdef HEPMC3 +HepMC::GenParticlePtr iGeant4::Geant4TruthIncident::convert(const G4Track *track, const int, const bool) const { +#else HepMC::GenParticlePtr iGeant4::Geant4TruthIncident::convert(const G4Track *track, const int barcode, const bool secondary) const { +#endif const G4ThreeVector & mom = track->GetMomentum(); const double energy = track->GetTotalEnergy(); @@ -307,7 +326,8 @@ HepMC::GenParticlePtr iGeant4::Geant4TruthIncident::convert(const G4Track *track const int status = 1; // stable particle not decayed by EventGenerator HepMC::GenParticlePtr newParticle = HepMC::newGenParticlePtr(fourMomentum, pdgCode, status); - // This should be a *secondary* track. If it has a primary, it was a decay and +#ifndef HEPMC3 + // This should be a *secondary* track. If it has a primary, it was a decay and // we are running with quasi-stable particle simulation. Note that if the primary // track is passed in as a secondary that survived the interaction, then this was // *not* a decay and we should not treat it in this way @@ -321,6 +341,7 @@ HepMC::GenParticlePtr iGeant4::Geant4TruthIncident::convert(const G4Track *track } else { HepMC::suggest_barcode( newParticle, barcode ); } +#endif return newParticle; }