diff --git a/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/python/ISF_Geant4ToolsConfig.py b/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/python/ISF_Geant4ToolsConfig.py index 6eabd876dd4795486013c91a659eeecddc92c7ef..5cf4d28446574f7463f1797fcf72c691e954ece5 100644 --- a/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/python/ISF_Geant4ToolsConfig.py +++ b/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/python/ISF_Geant4ToolsConfig.py @@ -134,6 +134,8 @@ def getG4TransportTool(name='ISFG4TransportTool', **kwargs): else: is_hive = False kwargs.setdefault('MultiThreading', is_hive) + # Set commands for the G4AtlasAlg + kwargs.setdefault("G4Commands", simFlags.G4Commands.get_Value()) from ISF_Geant4Tools.ISF_Geant4ToolsConf import iGeant4__G4TransportTool return iGeant4__G4TransportTool(name, **kwargs) ### Specialized Versions diff --git a/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/Geant4TruthIncident.cxx b/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/Geant4TruthIncident.cxx index fb097294339e5890f8fc51fbed7bfb0d66265265..e9423a38b2276b385b4ca6b3b9313c1da4969fa3 100644 --- a/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/Geant4TruthIncident.cxx +++ b/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/Geant4TruthIncident.cxx @@ -17,6 +17,7 @@ #include "MCTruth/TrackBarcodeInfo.h" #include "MCTruth/TrackHelper.h" #include "MCTruth/TrackInformation.h" +#include "MCTruth/PrimaryParticleInformation.h" #include "SimHelpers/SecondaryTracksHelper.h" // Units @@ -161,12 +162,10 @@ HepMC::GenParticle* iGeant4::Geant4TruthIncident::parentParticleAfterIncident(Ba if ( !m_parentParticleAfterIncident ) { // create new HepMC particle, using momentum and energy // from G4DynamicParticle (which should be equivalent to postStep) - m_parentParticleAfterIncident = convert(track); + m_parentParticleAfterIncident = convert(track, newBarcode, false); m_eventInfo->SetCurrentlyTraced( m_parentParticleAfterIncident ); - m_parentParticleAfterIncident->suggest_barcode( newBarcode ); - // store (new) hepmc particle in track's UserInformation TrackHelper tHelper(track); TrackInformation *tInfo = tHelper.GetTrackInformation(); @@ -260,8 +259,7 @@ HepMC::GenParticle* iGeant4::Geant4TruthIncident::childParticle(unsigned short i // secondary could decay right away and create further particles which pass the // truth strategies. - HepMC::GenParticle* hepParticle = convert( thisChildTrack ); - hepParticle->suggest_barcode( newBarcode ); + HepMC::GenParticle* hepParticle = convert( thisChildTrack , newBarcode , true ); TrackHelper tHelper(thisChildTrack); TrackInformation *trackInfo = tHelper.GetTrackInformation(); @@ -292,7 +290,7 @@ bool iGeant4::Geant4TruthIncident::particleAlive(const G4Track *track) const { } -HepMC::GenParticle* iGeant4::Geant4TruthIncident::convert(const G4Track *track) const { +HepMC::GenParticle* iGeant4::Geant4TruthIncident::convert(const G4Track *track, const int barcode, const bool secondary) const { const G4ThreeVector & mom = track->GetMomentum(); const double energy = track->GetTotalEnergy(); @@ -302,6 +300,21 @@ HepMC::GenParticle* iGeant4::Geant4TruthIncident::convert(const G4Track *track) int status = 1; // stable particle not decayed by EventGenerator HepMC::GenParticle* newParticle = new HepMC::GenParticle(fourMomentum, pdgCode, status); + // 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 (secondary && + 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() ); + newParticle->suggest_barcode( ppi->GetParticleBarcode() ); + } else { + newParticle->suggest_barcode( barcode ); + } + return newParticle; } diff --git a/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/Geant4TruthIncident.h b/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/Geant4TruthIncident.h index 5d4d94a692c1fa9840cfe6eba4a05d185ac42677..9379e9931de674a05e373db841046f486dd027dc 100644 --- a/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/Geant4TruthIncident.h +++ b/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/Geant4TruthIncident.h @@ -103,7 +103,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::GenParticle* convert(const G4Track *particle) const; //*AS* might be put static + HepMC::GenParticle* convert(const G4Track *particle, const int barcode, const bool secondary) const; //*AS* might be put static mutable bool m_positionSet; mutable HepMC::FourVector m_position; diff --git a/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/TransportTool.cxx b/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/TransportTool.cxx index 8b35a622847e52c30933a6a6a2ee0132e963273c..61b643a5752fb7d438afd076d8bf3256217d25ab 100644 --- a/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/TransportTool.cxx +++ b/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/TransportTool.cxx @@ -87,6 +87,9 @@ iGeant4::G4TransportTool::G4TransportTool(const std::string& t, // Multi-threading specific settings declareProperty("MultiThreading", m_useMT=false); + // Commands to send to the G4UI + declareProperty("G4Commands", m_g4commands); + } //________________________________________________________________________ @@ -214,6 +217,11 @@ StatusCode iGeant4::G4TransportTool::initialize() ATH_MSG_INFO("Random nr. generator is set to Geant4"); } + // Send UI commands + for (auto g4command : m_g4commands){ + ui->ApplyCommand( g4command ); + } + ATH_MSG_DEBUG("initalize"); /* if (m_particleBroker.retrieve().isSuccess()) @@ -428,6 +436,10 @@ G4PrimaryParticle* iGeant4::G4TransportTool::getPrimaryParticle(const HepMC::Gen particle->SetProperTime( (lv1-lv0).mag()/CLHEP::c_light ); } + // Set the user information for this primary to point to the HepMcParticleLink... + PrimaryParticleInformation* ppi = new PrimaryParticleInformation(&gp); + particle->SetUserInformation(ppi); + return particle; } @@ -543,14 +555,10 @@ G4PrimaryParticle* iGeant4::G4TransportTool::getPrimaryParticle(const ISF::ISFPa // Set the lifetime appropriately - this is slow but rigorous, and we // don't want to end up with something like vertex time that we have // to validate for every generator on earth... - G4LorentzVector lv0 ( genpart->production_vertex()->position().x(), - genpart->production_vertex()->position().y(), - genpart->production_vertex()->position().z(), - genpart->production_vertex()->position().t() ); - G4LorentzVector lv1 ( genpart->end_vertex()->position().x(), - genpart->end_vertex()->position().y(), - genpart->end_vertex()->position().z(), - genpart->end_vertex()->position().t() ); + const auto& prodVtx = genpart->production_vertex()->position(); + const auto& endVtx = genpart->end_vertex()->position(); + const G4LorentzVector lv0( prodVtx.x(), prodVtx.y(), prodVtx.z(), prodVtx.t() ); + const G4LorentzVector lv1( endVtx.x(), endVtx.y(), endVtx.z(), endVtx.t() ); particle->SetProperTime( (lv1-lv0).mag()/CLHEP::c_light ); } // particle had an end vertex } // Truth was detected diff --git a/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/TransportTool.h b/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/TransportTool.h index 3cfdb95d1136ea1d077a444cc2ac5973acf48d43..3ed8f6a42ede8997fb8b06cae2b96266207519d4 100644 --- a/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/TransportTool.h +++ b/Simulation/ISF/ISF_Geant4/ISF_Geant4Tools/src/TransportTool.h @@ -128,6 +128,9 @@ namespace iGeant4 //simulation G4VSolid *m_worldSolid; // the Geant4 world volume solid + + /// Commands to send to the G4 UI + std::vector<std::string> m_g4commands; };