From e4b55023761ef40958eb41bb7ea8fdf3e3ae508d Mon Sep 17 00:00:00 2001 From: Joshua Falco Beirer <joshua.falco.beirer@cern.ch> Date: Wed, 15 May 2024 17:46:26 +0200 Subject: [PATCH] Add possiblity to use Geant4 transport instead of ATLAS tracking tools in FCS in G4 Revert "Minor improvements" This reverts commit 27b52b4f15a4d272fd6341603f8e3bea3c23d1aa. --- Simulation/G4Atlas/G4AtlasAlg/CMakeLists.txt | 2 +- .../G4AtlasAlg/python/G4AtlasAlgConfig.py | 9 +- .../G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx | 16 ++ .../G4Atlas/G4AtlasAlg/src/G4AtlasAlg.h | 2 + .../G4AtlasInterfaces/IG4CaloTransportTool.h | 27 +++ .../G4AtlasDetectorConstructionTool.h | 5 +- .../G4AtlasTools/python/G4AtlasToolsConfig.py | 20 ++ .../python/G4GeometryToolConfig.py | 6 +- .../src/G4AtlasDetectorConstructionTool.cxx | 11 ++ .../G4AtlasTools/src/G4CaloTransportTool.cxx | 177 ++++++++++++++++++ .../G4AtlasTools/src/G4CaloTransportTool.h | 63 +++++++ .../src/components/G4AtlasTools_entries.cxx | 2 + .../python/G4FastSimulationConfig.py | 11 ++ .../G4FastSimulation/src/FastCaloSim.cxx | 41 +++- .../G4FastSimulation/src/FastCaloSim.h | 24 ++- .../G4FastSimulation/src/FastCaloSimTool.cxx | 20 +- .../G4FastSimulation/src/FastCaloSimTool.h | 14 +- .../IFastCaloSimCaloExtrapolation.h | 3 + .../src/FastCaloSimCaloExtrapolation.cxx | 24 ++- .../src/FastCaloSimCaloExtrapolation.h | 3 +- .../SimulationConfig/python/SimConfigFlags.py | 1 + .../python/SimulationMetadata.py | 3 + 22 files changed, 451 insertions(+), 33 deletions(-) create mode 100644 Simulation/G4Atlas/G4AtlasInterfaces/G4AtlasInterfaces/IG4CaloTransportTool.h create mode 100644 Simulation/G4Atlas/G4AtlasTools/src/G4CaloTransportTool.cxx create mode 100644 Simulation/G4Atlas/G4AtlasTools/src/G4CaloTransportTool.h diff --git a/Simulation/G4Atlas/G4AtlasAlg/CMakeLists.txt b/Simulation/G4Atlas/G4AtlasAlg/CMakeLists.txt index 4268da90cdc..07d5988a9e2 100644 --- a/Simulation/G4Atlas/G4AtlasAlg/CMakeLists.txt +++ b/Simulation/G4Atlas/G4AtlasAlg/CMakeLists.txt @@ -17,7 +17,7 @@ atlas_add_library( G4AtlasAlgLib PUBLIC_HEADERS G4AtlasAlg INCLUDE_DIRS ${GEANT4_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS} ${XERCESC_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} - LINK_LIBRARIES ${GEANT4_LIBRARIES} ${EIGEN_LIBRARIES} ${XERCESC_LIBRARIES} ${CLHEP_LIBRARIES} AtlasHepMCLib AthenaBaseComps AthenaKernel CxxUtils GaudiKernel G4AtlasInterfaces SGTools StoreGateLib EventInfo GeneratorObjects GeoModelInterfaces HepMC_InterfacesLib ISF_InterfacesLib MCTruthBaseLib ) + LINK_LIBRARIES ${GEANT4_LIBRARIES} ${EIGEN_LIBRARIES} ${XERCESC_LIBRARIES} ${CLHEP_LIBRARIES} AtlasHepMCLib AthenaBaseComps AthenaKernel CxxUtils GaudiKernel G4AtlasInterfaces SGTools StoreGateLib EventInfo GeneratorObjects GeoModelInterfaces HepMC_InterfacesLib ISF_InterfacesLib MCTruthBaseLib PathResolver) set_target_properties( G4AtlasAlgLib PROPERTIES INTERPROCEDURAL_OPTIMIZATION ${ATLAS_GEANT4_USE_LTO} ) # Component(s) in the package: diff --git a/Simulation/G4Atlas/G4AtlasAlg/python/G4AtlasAlgConfig.py b/Simulation/G4Atlas/G4AtlasAlg/python/G4AtlasAlgConfig.py index ae03695f550..2f7363bf51e 100644 --- a/Simulation/G4Atlas/G4AtlasAlg/python/G4AtlasAlgConfig.py +++ b/Simulation/G4Atlas/G4AtlasAlg/python/G4AtlasAlgConfig.py @@ -29,15 +29,22 @@ def G4AtlasAlgCfg(flags, name="G4AtlasAlg", **kwargs): kwargs.setdefault("OutputTruthCollection", "TruthEvent") ## Killing neutrinos - ## Don"t drop the GeoModel + ## Don't drop the GeoModel kwargs.setdefault("ReleaseGeoModel", flags.Sim.ReleaseGeoModel) + from SimulationConfig.SimEnums import LArParameterization + # Configure fast simulation if flags.Sim.LArParameterization is LArParameterization.FastCaloSim: kwargs.setdefault("ExtraInputs", {('CaloDetDescrManager', 'ConditionStore+CaloDetDescrManager'), ('LArfSamplSym', 'ConditionStore+LArfSamplSym'), ('TileSamplingFraction', 'ConditionStore+TileSamplingFraction')}) + # Set the path to the simplified calorimeter geometry for particle transport if provided + if flags.Sim.SimplifiedGeoPath: + kwargs.setdefault('SimplifiedGeoPath', flags.Sim.SimplifiedGeoPath) + kwargs.setdefault("ExtraOutputs", SimHitContainerListCfg(flags)) + ## Record the particle flux during the simulation kwargs.setdefault("RecordFlux", flags.Sim.RecordFlux) diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx index 8cc82a1c4e4..cca09cad531 100644 --- a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx +++ b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx @@ -30,6 +30,7 @@ #include "G4VUserPhysicsList.hh" #include "G4VModularPhysicsList.hh" #include "G4ParallelWorldPhysics.hh" +#include "G4GDMLParser.hh" // CLHEP includes #include "CLHEP/Random/RandomEngine.h" @@ -41,6 +42,8 @@ #include "GeoModelInterfaces/IGeoModelSvc.h" #include "GaudiKernel/IThreadInitTool.h" #include "GeneratorObjects/HepMcParticleLink.h" +#include "PathResolver/PathResolver.h" + // call_once mutexes #include <mutex> @@ -65,6 +68,19 @@ StatusCode G4AtlasAlg::initialize ATLAS_NOT_THREAD_SAFE () { ATH_MSG_DEBUG("Start of initialize()"); + // Read the simplified geometry for FastCaloSim track transportation if requested + if(!m_simplifiedGeoPath.empty()) { + std::string geoFile = PathResolverFindCalibFile(m_simplifiedGeoPath); + + if (geoFile.empty()) { + ATH_MSG_FATAL("Could not find simplified geometry file: " << m_simplifiedGeoPath); + return StatusCode::FAILURE; + } + + G4GDMLParser parser; + parser.Read(geoFile, false); + } + // Create the scoring manager if requested if (m_recordFlux) G4ScoringManager::GetScoringManager(); diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.h b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.h index 4cc1c15d925..a2f27d9893b 100644 --- a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.h +++ b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.h @@ -154,6 +154,8 @@ private: PublicToolHandle<IFastSimulationMasterTool> m_fastSimTool{this, "FastSimMasterTool", "FastSimulationMasterTool", ""}; /// @} PublicToolHandleArray<G4UA::IUserActionTool> m_actionTools{this, "UserActionTools", {}, "User action tools to be added to the G4 Action service."}; + // FastCaloSim in Geant4 configuration + Gaudi::Property<std::string> m_simplifiedGeoPath{this, "SimplifiedGeoPath", "", "Path to the simplified geometry file used to transport particles"}; }; diff --git a/Simulation/G4Atlas/G4AtlasInterfaces/G4AtlasInterfaces/IG4CaloTransportTool.h b/Simulation/G4Atlas/G4AtlasInterfaces/G4AtlasInterfaces/IG4CaloTransportTool.h new file mode 100644 index 00000000000..4d2c44bfd3a --- /dev/null +++ b/Simulation/G4Atlas/G4AtlasInterfaces/G4AtlasInterfaces/IG4CaloTransportTool.h @@ -0,0 +1,27 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef IG4CaloTransportTool_H +#define IG4CaloTransportTool_H + +// Gaudi +#include "GaudiKernel/IAlgTool.h" +/* Input to particle transport will be a G4Track*/ +#include "G4Track.hh" +/* Transport steps will be returned as G4FieldTracks*/ +#include "G4FieldTrack.hh" + +static const InterfaceID IID_IG4CaloTransportTool("IG4CaloTransportTool", 1, 0); + +class IG4CaloTransportTool : virtual public IAlgTool +{ + public: + /** AlgTool interface methods */ + static const InterfaceID& interfaceID() { return IID_IG4CaloTransportTool; } + + virtual std::vector<G4FieldTrack> transport(const G4Track& G4InputTrack) = 0; + virtual StatusCode initializePropagator() = 0; +}; + +#endif // IG4CaloTransportTool_H \ No newline at end of file diff --git a/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/G4AtlasDetectorConstructionTool.h b/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/G4AtlasDetectorConstructionTool.h index ce06db315b7..530a10e9b54 100644 --- a/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/G4AtlasDetectorConstructionTool.h +++ b/Simulation/G4Atlas/G4AtlasTools/G4AtlasTools/G4AtlasDetectorConstructionTool.h @@ -17,6 +17,8 @@ #include "G4AtlasInterfaces/IFieldManagerTool.h" #include "G4AtlasInterfaces/IG4GeometryConfigurationTool.h" #include "G4AtlasInterfaces/ISensitiveDetectorMasterTool.h" +#include "G4AtlasInterfaces/IG4CaloTransportTool.h" + // Geant4 headers #include "G4VUserDetectorConstruction.hh" #include "G4VPhysicalVolume.hh" @@ -56,9 +58,10 @@ class G4AtlasDetectorConstructionTool final : public extends<AthAlgTool, IDetect ToolHandleArray<IG4GeometryConfigurationTool> m_configurationTools{this, "GeometryConfigurationTools", {}, "Tools for geometry configuration"}; PublicToolHandle<ISensitiveDetectorMasterTool> m_senDetTool{this, "SenDetMasterTool", "SensitiveDetectorMasterTool", ""}; ToolHandleArray<IFieldManagerTool> m_fieldManagers{this, "FieldManagers", {}, "field managers used"}; + PublicToolHandle<IG4CaloTransportTool> m_G4CaloTransportTool{this, "G4CaloTransportTool", "", "Tool handle of the Geant4 transport tool for the FastCaloSim in Geant4 implementation"}; Gaudi::Property<bool> m_activateParallelWorlds{this, "ActivateParallelWorlds", false, "Toggle on/off the G4 parallel geometry system"}; std::vector<std::string> m_parallelWorldNames{}; }; -#endif +#endif \ No newline at end of file diff --git a/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfig.py b/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfig.py index 9521b733f9b..a32f7cb19d4 100644 --- a/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfig.py +++ b/Simulation/G4Atlas/G4AtlasTools/python/G4AtlasToolsConfig.py @@ -65,6 +65,26 @@ def EmptyFastSimulationMasterToolCfg(flags, **kwargs): result.setPrivateTools(tool) return result +def G4CaloTransportToolCfg(flags, name='G4CaloTransportTool', **kwargs): + result = ComponentAccumulator() + # Use simplified calorimeter geometry if path to simplified geometry is provided + # Otherwise, use the full geometry for the transport (Note that this will be very slow) + kwargs.setdefault("UseSimplifiedGeo", bool(flags.Sim.SimplifiedGeoPath)) + if flags.Sim.SimplifiedGeoPath: + # What is the name of the logical world volume of the simplified geometry? + kwargs.setdefault('SimplifiedWorldLogName', "WorldLog") + # At what volume will we stop the transport? + kwargs.setdefault('TransportLimitVolume', "Envelope") + # What is the maximum number of Geant4 steps taken in the transport? + kwargs.setdefault('MaxSteps', 100) + else: + # At what volume will be stop the transport? + kwargs.setdefault('TransportLimitVolume', "MuonSys") + # What is the maximum number of Geant4 steps taken in the transport? + kwargs.setdefault('MaxSteps', 5000) + + result.setPrivateTools(CompFactory.G4CaloTransportTool(name, **kwargs)) + return result def FwdSensitiveDetectorListCfg(flags): # TODO: migrate to CA diff --git a/Simulation/G4Atlas/G4AtlasTools/python/G4GeometryToolConfig.py b/Simulation/G4Atlas/G4AtlasTools/python/G4GeometryToolConfig.py index adac3554176..59e95e1a36f 100644 --- a/Simulation/G4Atlas/G4AtlasTools/python/G4GeometryToolConfig.py +++ b/Simulation/G4Atlas/G4AtlasTools/python/G4GeometryToolConfig.py @@ -15,7 +15,7 @@ from G4AtlasTools.G4PhysicsRegionConfig import DriftWallPhysicsRegionToolCfg, Dr #the field config tools from G4AtlasTools.G4FieldConfig import ATLASFieldManagerToolCfg, TightMuonsATLASFieldManagerToolCfg, BeamPipeFieldManagerToolCfg, InDetFieldManagerToolCfg, ITkFieldManagerToolCfg, MuonsOnlyInCaloFieldManagerToolCfg, MuonFieldManagerToolCfg, Q1FwdFieldManagerToolCfg, Q2FwdFieldManagerToolCfg, Q3FwdFieldManagerToolCfg, D1FwdFieldManagerToolCfg, D2FwdFieldManagerToolCfg, Q4FwdFieldManagerToolCfg, Q5FwdFieldManagerToolCfg, Q6FwdFieldManagerToolCfg, Q7FwdFieldManagerToolCfg, Q1HKickFwdFieldManagerToolCfg, Q1VKickFwdFieldManagerToolCfg, Q2HKickFwdFieldManagerToolCfg, Q2VKickFwdFieldManagerToolCfg, Q3HKickFwdFieldManagerToolCfg, Q3VKickFwdFieldManagerToolCfg, Q4VKickAFwdFieldManagerToolCfg, Q4HKickFwdFieldManagerToolCfg, Q4VKickBFwdFieldManagerToolCfg, Q5HKickFwdFieldManagerToolCfg, Q6VKickFwdFieldManagerToolCfg, FwdRegionFieldManagerToolCfg -from G4AtlasTools.G4AtlasToolsConfig import SensitiveDetectorMasterToolCfg +from G4AtlasTools.G4AtlasToolsConfig import SensitiveDetectorMasterToolCfg, G4CaloTransportToolCfg CylindricalEnvelope, PolyconicalEnvelope, MaterialDescriptionTool,VoxelDensityTool,G4AtlasDetectorConstructionTool,BoxEnvelope=CompFactory.getComps("CylindricalEnvelope","PolyconicalEnvelope","MaterialDescriptionTool","VoxelDensityTool","G4AtlasDetectorConstructionTool","BoxEnvelope") @@ -715,6 +715,10 @@ def G4AtlasDetectorConstructionToolCfg(flags, name="G4AtlasDetectorConstructionT kwargs.setdefault("RegionCreators", result.popToolsAndMerge(ATLAS_RegionCreatorListCfg(flags))) if flags.BField.solenoidOn or flags.BField.barrelToroidOn or flags.BField.endcapToroidOn: kwargs.setdefault("FieldManagers", result.popToolsAndMerge(ATLAS_FieldMgrListCfg(flags))) + + if flags.Sim.LArParameterization is LArParameterization.FastCaloSim: + kwargs.setdefault("G4CaloTransportTool", result.addPublicTool(result.popToolsAndMerge(G4CaloTransportToolCfg(flags)))) + result.setPrivateTools(G4AtlasDetectorConstructionTool(name, **kwargs)) return result diff --git a/Simulation/G4Atlas/G4AtlasTools/src/G4AtlasDetectorConstructionTool.cxx b/Simulation/G4Atlas/G4AtlasTools/src/G4AtlasDetectorConstructionTool.cxx index 87f56f0ed63..5667106c2dc 100644 --- a/Simulation/G4Atlas/G4AtlasTools/src/G4AtlasDetectorConstructionTool.cxx +++ b/Simulation/G4Atlas/G4AtlasTools/src/G4AtlasDetectorConstructionTool.cxx @@ -59,6 +59,8 @@ StatusCode G4AtlasDetectorConstructionTool::initialize( ) ATH_MSG_DEBUG( "Setting up field managers" ); ATH_CHECK( m_fieldManagers.retrieve() ); + ATH_CHECK( m_G4CaloTransportTool.retrieve( DisableTool{ m_G4CaloTransportTool.empty() } ) ); + return StatusCode::SUCCESS; } @@ -124,5 +126,14 @@ void G4AtlasDetectorConstructionTool::ConstructSDandField() } } + if (m_G4CaloTransportTool.isEnabled()){ + ATH_MSG_DEBUG("Setting up G4CaloTransportTool"); + if (m_G4CaloTransportTool->initializePropagator().isFailure()) + { + ATH_MSG_FATAL("Failed to initialize G4CaloTransportTool for worker thread."); + return; + } + } + return; } diff --git a/Simulation/G4Atlas/G4AtlasTools/src/G4CaloTransportTool.cxx b/Simulation/G4Atlas/G4AtlasTools/src/G4CaloTransportTool.cxx new file mode 100644 index 00000000000..0043c2d40d5 --- /dev/null +++ b/Simulation/G4Atlas/G4AtlasTools/src/G4CaloTransportTool.cxx @@ -0,0 +1,177 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +#include "G4CaloTransportTool.h" + +// Geant4 includes for for particle extrapolation +#include "G4AtlasTools/ThreadLocalHolder.h" +#include "G4FieldTrack.hh" +#include "G4FieldTrackUpdator.hh" +#include "G4LogicalVolumeStore.hh" +#include "G4PVPlacement.hh" +#include "G4PathFinder.hh" +#include "G4TransportationManager.hh" + +G4CaloTransportTool::G4CaloTransportTool(const std::string& type, + const std::string& name, + const IInterface* parent) + : base_class(type, name, parent) {} + +StatusCode G4CaloTransportTool::initialize() { + if (m_useSimplifiedGeo) { + + ATH_MSG_INFO("Creating simplified world volume for particle transport"); + + // Get the logical world volume of the simplified geometry by name + G4LogicalVolume* logVol = G4LogicalVolumeStore::GetInstance()->GetVolume( + m_simplifiedWorldLogName.value()); + + // Create the physical volume of the simplified world + m_worldVolume = + new G4PVPlacement(nullptr, // no rotation + G4ThreeVector(0, 0, 0), // world centre at (0,0,0) + logVol, // logical volume + "simplifiedWorldPhysVol", // name of physical volume + nullptr, // mother volume + false, // not used + 999, // copy number + false); // overlap check + + } else { + // Get the default Geant4 world volume if we are not using the simplified + // geometry + m_worldVolume = G4TransportationManager::GetTransportationManager() + ->GetNavigatorForTracking() + ->GetWorldVolume(); + } + + if (!m_worldVolume) { + G4Exception("G4CaloTransportTool", "FailedToGetWorldVolume", FatalException, + "G4CaloTransportTool: Failed to get world volume."); + abort(); + } + + ATH_MSG_INFO("Using world volume: " << m_worldVolume->GetName()); + ATH_MSG_INFO("Transport will be stopped at volume: " << m_transportLimitVolume.value()); + ATH_MSG_INFO("Maximum allowed number of steps in particle transport: " << m_maxSteps.value()); + + return StatusCode::SUCCESS; +} + +StatusCode G4CaloTransportTool::finalize() { + + // Delete the world volume if we created it + if (m_useSimplifiedGeo) + delete m_worldVolume; + + // Delete the navigators and propagators for each thread + for (auto& mapPair : m_propagatorHolder.getMap()) { + delete mapPair.second->GetNavigatorForPropagating(); + delete mapPair.second; + } + + return StatusCode::SUCCESS; +} + +StatusCode G4CaloTransportTool::initializePropagator() { + ATH_MSG_INFO("Initializing G4PropagatorInField for thread " << G4Threading::G4GetThreadId()); + + // Check if we already have propagator set up for the current thread + auto propagator = m_propagatorHolder.get(); + // If not, we create one + if (!propagator) { + propagator = makePropagator(); + m_propagatorHolder.set(propagator); + } else { + ATH_MSG_ERROR("G4CaloTransportTool::initializePropagator() Propagator already initialized!"); + } + + return StatusCode::SUCCESS; +} + +G4PropagatorInField* G4CaloTransportTool::makePropagator() { + // Create a new navigator + G4Navigator* navigator = new G4Navigator(); + // Set world volume in which the navigator will operate + navigator->SetWorldVolume(m_worldVolume); + // Get the global field manager + G4FieldManager* fieldMgr = + G4TransportationManager::GetTransportationManager()->GetFieldManager(); + // Create a new magnetic field propagator + G4PropagatorInField* propagator = + new G4PropagatorInField(navigator, fieldMgr); + + return propagator; +} + +void G4CaloTransportTool::doStep(G4FieldTrack& fieldTrack) { + + // Get the propagator and navigator for the current thread + auto propagator = m_propagatorHolder.get(); + auto navigator = propagator->GetNavigatorForPropagating(); + + G4double retSafety = -1.0; + G4double currentMinimumStep = 10.0 * CLHEP::m; + + G4VPhysicalVolume* currentPhysVol = + navigator->LocateGlobalPointAndSetup(fieldTrack.GetPosition(), nullptr); + + G4ThreeVector direction = fieldTrack.GetMomentumDirection(); + // Must be called before calling the computeStep method + navigator->LocateGlobalPointAndSetup(fieldTrack.GetPosition(), &direction); + + if (fieldTrack.GetCharge() == 0) { + /* Neutral particles: transport with navigator */ + + // Compute the step length + G4double stepLength = navigator->ComputeStep( + fieldTrack.GetPosition(), fieldTrack.GetMomentumDirection(), + currentMinimumStep, retSafety); + + // Update the position of the track from the computed step length + fieldTrack.SetPosition(fieldTrack.GetPosition() + + stepLength * + fieldTrack.GetMomentumDirection().unit()); + + } else { + /* Charged particles: transport with magnetic field propagator */ + propagator->ComputeStep(fieldTrack, currentMinimumStep, retSafety, + currentPhysVol); + } + + return; +} + +std::vector<G4FieldTrack> G4CaloTransportTool::transport( + const G4Track& G4InputTrack) { + + // Get the navigator for the current thread + auto navigator = m_propagatorHolder.get()->GetNavigatorForPropagating(); + + // Create a vector to store the output steps + std::vector<G4FieldTrack> outputStepVector; + // Initialize the tmpFieldTrack with the input track + G4FieldTrack tmpFieldTrack('0'); + G4FieldTrackUpdator::Update(&tmpFieldTrack, &G4InputTrack); + // Fill with the initial particle position + outputStepVector.push_back(tmpFieldTrack); + + // Iterate until we reach the maximum number of steps or the requested volume + for (unsigned int iStep = 0; iStep < m_maxSteps; iStep++) { + // Perform a single Geant4 step + doStep(tmpFieldTrack); + // Fill the output vector with the updated track + outputStepVector.push_back(tmpFieldTrack); + // Get the name of the volume in which the particle is located + std::string volName = + navigator + ->LocateGlobalPointAndSetup(tmpFieldTrack.GetPosition(), nullptr) + ->GetName(); + // We stop the track navigation once we have reached the provided volume + if (volName.find(m_transportLimitVolume) != std::string::npos) + break; + } + + return outputStepVector; +} \ No newline at end of file diff --git a/Simulation/G4Atlas/G4AtlasTools/src/G4CaloTransportTool.h b/Simulation/G4Atlas/G4AtlasTools/src/G4CaloTransportTool.h new file mode 100644 index 00000000000..75474aae625 --- /dev/null +++ b/Simulation/G4Atlas/G4AtlasTools/src/G4CaloTransportTool.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef G4ATLASTOOLS_G4CALOTRANSPORTTOOL_H +#define G4ATLASTOOLS_G4CALOTRANSPORTTOOL_H + +#include "AthenaBaseComps/AthAlgTool.h" +#include "G4AtlasInterfaces/IG4CaloTransportTool.h" + +#include "G4Navigator.hh" +#include "G4PropagatorInField.hh" + +#include "G4AtlasTools/ThreadLocalHolder.h" + + +class G4Track; + +/// @class G4CaloTransportTool +/// @brief A tool which transports particles through the Geant4 geometry. +/// +/// @author Joshua Falco Beirer <joshua.falco.beirer@cern.ch> +/// +class G4CaloTransportTool : virtual public extends1<AthAlgTool, IG4CaloTransportTool> +{ + + public: + + G4CaloTransportTool(const std::string&, const std::string&, const IInterface*); + + // Algorithm initialize at begin of job + virtual StatusCode initialize(); + // Algorithm finalize at begin of job + virtual StatusCode finalize(); + // Initialize propagator for the current thread + StatusCode initializePropagator() override final; + // Transport input track through the geometry + virtual std::vector<G4FieldTrack> transport(const G4Track& G4InputTrack) override final; + + private: + // Create and return a new propagator + G4PropagatorInField* makePropagator(); + // Advance track by single Geant4 step in geometry + void doStep(G4FieldTrack& fieldTrack); + // Pointer to the physical volume of the world (either simplified or full geometry) + G4VPhysicalVolume* m_worldVolume; + + // Whether to use simplified geometry for particle transport + Gaudi::Property<bool> m_useSimplifiedGeo{this, "UseSimplifiedGeo", true, "Use simplified geometry for particle transport"}; + // Name of the logical volume of the simplified world as defined in the loaded GDML file + Gaudi::Property<std::string> m_simplifiedWorldLogName{this, "SimplifiedWorldLogName", "Name of the logical volume of the simplified world"}; + // Name of volume until which the particle is tracked in transport + Gaudi::Property<std::string> m_transportLimitVolume{this, "TransportLimitVolume", "Name of the volume until which the particle is transported"}; + // Maximum number of steps in particle transport + Gaudi::Property<unsigned int> m_maxSteps{this, "MaxSteps", 100, "Maximum number of steps in particle transport"}; + // Thread local holder for propagators + thread_utils::ThreadLocalHolder<G4PropagatorInField> m_propagatorHolder; + + +}; // class G4CaloTransportTool + + +#endif // G4ATLASTOOLS_G4CALOTRANSPORTTOOL_H diff --git a/Simulation/G4Atlas/G4AtlasTools/src/components/G4AtlasTools_entries.cxx b/Simulation/G4Atlas/G4AtlasTools/src/components/G4AtlasTools_entries.cxx index 43ecc77d351..779b432aada 100644 --- a/Simulation/G4Atlas/G4AtlasTools/src/components/G4AtlasTools_entries.cxx +++ b/Simulation/G4Atlas/G4AtlasTools/src/components/G4AtlasTools_entries.cxx @@ -12,6 +12,7 @@ #include "../G4ThreadInitTool.h" #include "../MaterialDescriptionTool.h" #include "../VoxelDensityTool.h" +#include "../G4CaloTransportTool.h" DECLARE_COMPONENT( DetectorGeometryBase ) DECLARE_COMPONENT( CylindricalEnvelope ) @@ -27,3 +28,4 @@ DECLARE_COMPONENT( DetectorFieldManagerTool ) DECLARE_COMPONENT( G4ThreadInitTool ) DECLARE_COMPONENT( MaterialDescriptionTool ) DECLARE_COMPONENT( VoxelDensityTool ) +DECLARE_COMPONENT( G4CaloTransportTool ) diff --git a/Simulation/G4Utilities/G4FastSimulation/python/G4FastSimulationConfig.py b/Simulation/G4Utilities/G4FastSimulation/python/G4FastSimulationConfig.py index 8816dd31100..a549b0e3761 100644 --- a/Simulation/G4Utilities/G4FastSimulation/python/G4FastSimulationConfig.py +++ b/Simulation/G4Utilities/G4FastSimulation/python/G4FastSimulationConfig.py @@ -29,5 +29,16 @@ def FastCaloSimCfg(flags, **kwargs): # Name of region where FastCaloSim will be triggered kwargs.setdefault("RegionNames", ["CALO"]) kwargs.setdefault('CaloCellContainerSDName', "ToolSvc.SensitiveDetectorMasterTool.CaloCellContainerSD") + + if flags.Sim.SimplifiedGeoPath: + # Enable Geant4 track transportation only if simplified geometry is provided + kwargs.setdefault('doG4Transport', True) + else: + kwargs.setdefault('doG4Transport', False) + + # Set the G4CaloTransportTool + from G4AtlasTools.G4AtlasToolsConfig import G4CaloTransportToolCfg + kwargs.setdefault("G4CaloTransportTool", result.addPublicTool(result.popToolsAndMerge(G4CaloTransportToolCfg(flags)))) + result.setPrivateTools(CompFactory.FastCaloSimTool(name="FastCaloSim", **kwargs)) return result diff --git a/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSim.cxx b/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSim.cxx index 9a5e9371b95..6c9feecc69d 100644 --- a/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSim.cxx +++ b/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSim.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration */ // Header include @@ -12,10 +12,8 @@ // Random generator includes #include "AthenaKernel/RNGWrapper.h" -// Athena check macros -#include "AthenaBaseComps/AthCheckMacros.h" -// Geant4 includes +// Geant4 particle includes #include "G4Gamma.hh" #include "G4Electron.hh" #include "G4Positron.hh" @@ -32,18 +30,26 @@ #undef FCS_DEBUG + FastCaloSim::FastCaloSim(const std::string& name, const ServiceHandle<IAthRNGSvc>& rndmGenSvc, const Gaudi::Property<std::string>& randomEngineName, + const PublicToolHandle<IFastCaloSimCaloTransportation>& FastCaloSimCaloTransportation, const PublicToolHandle<IFastCaloSimCaloExtrapolation>& FastCaloSimCaloExtrapolation, + const PublicToolHandle<IG4CaloTransportTool>& G4CaloTransportTool, const ServiceHandle<ISF::IFastCaloSimParamSvc>& FastCaloSimSvc, const Gaudi::Property<std::string>& CaloCellContainerSDName, + const Gaudi::Property<bool>& doG4Transport, FastCaloSimTool * FastCaloSimTool) : G4VFastSimulationModel(name), m_rndmGenSvc(rndmGenSvc), m_randomEngineName(randomEngineName), - m_FastCaloSimCaloExtrapolation(FastCaloSimCaloExtrapolation), m_FastCaloSimSvc(FastCaloSimSvc), + m_FastCaloSimCaloTransportation(FastCaloSimCaloTransportation), + m_FastCaloSimCaloExtrapolation(FastCaloSimCaloExtrapolation), + m_G4CaloTransportTool(G4CaloTransportTool), + m_FastCaloSimSvc(FastCaloSimSvc), m_CaloCellContainerSDName(CaloCellContainerSDName), + m_doG4Transport(doG4Transport), m_FastCaloSimTool(FastCaloSimTool) { } @@ -53,9 +59,17 @@ void FastCaloSim::StartOfAthenaEvent(const EventContext& ctx ){ m_rngWrapper = m_rndmGenSvc->getEngine(m_FastCaloSimTool, m_randomEngineName); m_rngWrapper->setSeed( m_randomEngineName, ctx ); + + return; +} + +void FastCaloSim::EndOfAthenaEvent(const EventContext&){ + + return; } + G4bool FastCaloSim::IsApplicable(const G4ParticleDefinition& particleType) { // Check whether we can simulate the particle with FastCaloSim @@ -142,7 +156,7 @@ G4bool FastCaloSim::ModelTrigger(const G4FastTrack& fastTrack) #ifdef FCS_DEBUG if(passMinEkinPions) G4cout<<"[FastCaloSim::ModelTrigger] Model triggered"<<G4endl; - else G4cout<<"[FastCaloSim::ModelTrigger] Pion with Ekin="<<Ekin<<"below the minimum "<<minEkinPions<<" MeV threshold. Model not triggered."<<G4endl; + else G4cout<<"[FastCaloSim::ModelTrigger] Pion with Ekin="<<Ekin<<" below the minimum "<<minEkinPions<<" MeV threshold. Model not triggered."<<G4endl; #endif return passMinEkinPions; @@ -154,7 +168,7 @@ G4bool FastCaloSim::ModelTrigger(const G4FastTrack& fastTrack) #ifdef FCS_DEBUG if(passMinEkinOtherHadrons) G4cout<<"[FastCaloSim::ModelTrigger] Model triggered"<<G4endl; - else G4cout<<"[FastCaloSim::ModelTrigger] Other hadron with Ekin="<<Ekin<<"below the minimum "<<minEkinOtherHadrons<<" MeV threshold. Model not triggered."<<G4endl; + else G4cout<<"[FastCaloSim::ModelTrigger] Other hadron with Ekin="<<Ekin<<" below the minimum "<<minEkinOtherHadrons<<" MeV threshold. Model not triggered."<<G4endl; #endif return passMinEkinOtherHadrons; @@ -209,10 +223,17 @@ void FastCaloSim::DoIt(const G4FastTrack& fastTrack, G4FastStep& fastStep) calculated as Ekin = E() + M() instead of E() - M() this is achieved by setting an Ekin offset of 2*M() to the truth state */ if(pdgID == -2212 || pdgID == -2112) truthState.set_Ekin_off(2 * G4Particle -> GetPDGMass()); - - // Perform the FastCaloSim extrapolation to the calo ID boundary and all other calo layers - m_FastCaloSimCaloExtrapolation->extrapolate(extrapolState, &truthState); + + // Perform particle transportation through calorimeter system eiher with ATLAS tracking tools or with Geant4 + std::vector<G4FieldTrack> caloSteps = m_doG4Transport ? m_G4CaloTransportTool -> transport(*G4PrimaryTrack) + : m_FastCaloSimCaloTransportation -> transport(&truthState, false); + + // Extrapolate transported stepos to ID-Calo boundary and all layers of the calorimeter system + m_FastCaloSimCaloExtrapolation->extrapolate(extrapolState, &truthState, caloSteps); + + + // Do not simulate further if extrapolation to ID - Calo boundary fails if(extrapolState.IDCaloBoundary_eta() == -999){ #ifdef FCS_DEBUG diff --git a/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSim.h b/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSim.h index d9bd51f9209..238df3a4189 100644 --- a/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSim.h +++ b/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSim.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration */ #ifndef G4FASTSIMULATION_FASTCALOSIM_H @@ -7,14 +7,16 @@ // Service handle to define smart pointer to FastCaloSim parametrisation service #include "GaudiKernel/ServiceHandle.h" -// Tool handle to define smart pointer to FastCaloSim extrapolation tool -#include "GaudiKernel/ToolHandle.h" // Geant4 fast simulation base class #include "G4VFastSimulationModel.hh" // FastCaloSim parametrisation service interface #include "ISF_FastCaloSimInterfaces/IFastCaloSimParamSvc.h" // FastCaloSim extrapolation tool interface #include "ISF_FastCaloSimParametrization/IFastCaloSimCaloExtrapolation.h" +// FastCaloSim ATLAS transportation tool interface +#include "ISF_FastCaloSimParametrization/IFastCaloSimCaloTransportation.h" +// Geant4 transportation tool interface +#include "G4AtlasInterfaces/IG4CaloTransportTool.h" // Random generator service interface #include "AthenaKernel/IAthRNGSvc.h" // FastCaloSim tool @@ -22,6 +24,8 @@ class CaloCellContainerSD; +class G4FieldTrack; +class G4SafetyHelper; class FastCaloSim: public G4VFastSimulationModel { @@ -30,15 +34,19 @@ class FastCaloSim: public G4VFastSimulationModel FastCaloSim(const std::string& name, const ServiceHandle<IAthRNGSvc>& rndmGenSvc, const Gaudi::Property<std::string>& randomEngineName, + const PublicToolHandle<IFastCaloSimCaloTransportation>& FastCaloSimCaloTransportation, const PublicToolHandle<IFastCaloSimCaloExtrapolation>& FastCaloSimCaloExtrapolation, + const PublicToolHandle<IG4CaloTransportTool>& G4CaloTransportTool, const ServiceHandle<ISF::IFastCaloSimParamSvc>& FastCaloSimSvc, const Gaudi::Property<std::string>& CaloCellContainerSDName, + const Gaudi::Property<bool>& doG4Transport, FastCaloSimTool * FastCaloSimTool); ~FastCaloSim() {} G4bool IsApplicable(const G4ParticleDefinition&) override final; void DoIt(const G4FastTrack&, G4FastStep&) override final; void StartOfAthenaEvent(const EventContext& ctx); + void EndOfAthenaEvent(const EventContext& ctx); /** Determines the applicability of the fast sim model to this particular track. Checks that geometric location, energy, and particle type are within bounds. Also checks for @@ -57,12 +65,22 @@ class FastCaloSim: public G4VFastSimulationModel ServiceHandle<IAthRNGSvc> m_rndmGenSvc; Gaudi::Property<std::string> m_randomEngineName; ATHRNG::RNGWrapper* m_rngWrapper{}; + + // FastCaloSimCaloTransportation tool to transport particles through the detector with the ATLAS tracking tools + PublicToolHandle<IFastCaloSimCaloTransportation> m_FastCaloSimCaloTransportation; // FastCaloSimCaloExtrapolation tool to extrapolate particle shower positions to layers PublicToolHandle<IFastCaloSimCaloExtrapolation> m_FastCaloSimCaloExtrapolation; + // Geant4 transportation tool + PublicToolHandle<IG4CaloTransportTool> m_G4CaloTransportTool; + + // Main FastCaloSim service ServiceHandle<ISF::IFastCaloSimParamSvc> m_FastCaloSimSvc; // Name of associated CaloCellContainer sensitive detector Gaudi::Property<std::string> m_CaloCellContainerSDName; + // Boolean flag to enable Geant4 transportation + Gaudi::Property<bool> m_doG4Transport; + // Fast simulation FastCaloSimTool FastCaloSimTool * m_FastCaloSimTool; }; diff --git a/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSimTool.cxx b/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSimTool.cxx index 2475cfecf70..e99e3f198b4 100644 --- a/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSimTool.cxx +++ b/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSimTool.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration */ #include "FastCaloSimTool.h" @@ -34,6 +34,22 @@ StatusCode FastCaloSimTool::BeginOfAthenaEvent(){ } StatusCode FastCaloSimTool::EndOfAthenaEvent(){ + + // Get current event context + const EventContext& ctx = Gaudi::Hive::currentContext(); + + if( !getFastSimModel() ){ + ATH_MSG_ERROR ("EndOfAthenaEvent: FastSimModel was never created!"); + return StatusCode::FAILURE; + } + else{ + FastCaloSim *localFastSimModel = dynamic_cast<FastCaloSim*>(getFastSimModel()); + if(!localFastSimModel){ + ATH_MSG_ERROR ("EndOfAthenaEvent: Failed to cast m_FastSimModel into G4VFastSimulationModel."); + return StatusCode::FAILURE; + } + localFastSimModel->EndOfAthenaEvent(ctx); + } return StatusCode::SUCCESS; } @@ -45,5 +61,5 @@ G4VFastSimulationModel* FastCaloSimTool::makeFastSimModel() // Create the FastCaloSim fast simulation model - return new FastCaloSim(name(), m_rndmGenSvc, m_randomEngineName, m_FastCaloSimCaloExtrapolation, m_FastCaloSimSvc, m_CaloCellContainerSDName, this); + return new FastCaloSim(name(), m_rndmGenSvc, m_randomEngineName, m_FastCaloSimCaloTransportation, m_FastCaloSimCaloExtrapolation, m_G4CaloTransportTool, m_FastCaloSimSvc, m_CaloCellContainerSDName, m_doG4Transport, this); } diff --git a/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSimTool.h b/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSimTool.h index d3baf0158b7..cc30c0cfc1a 100644 --- a/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSimTool.h +++ b/Simulation/G4Utilities/G4FastSimulation/src/FastCaloSimTool.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration */ #ifndef G4FASTSIMULATION_FASTCALOSIMTOOL_H @@ -9,8 +9,12 @@ #include "G4AtlasTools/FastSimulationBase.h" /* FastCaloSim parametrization service include */ #include "ISF_FastCaloSimInterfaces/IFastCaloSimParamSvc.h" +/* FastCaloSim calorimeter transportation include */ +#include "ISF_FastCaloSimParametrization/IFastCaloSimCaloTransportation.h" /* FastCaloSim calorimeter extrapolation include */ #include "ISF_FastCaloSimParametrization/IFastCaloSimCaloExtrapolation.h" +/* Geant4 transportation tool */ +#include "G4AtlasInterfaces/IG4CaloTransportTool.h" /* Random generator service include */ #include "AthenaKernel/IAthRNGSvc.h" @@ -38,16 +42,20 @@ protected: // FastCaloSim service ServiceHandle<ISF::IFastCaloSimParamSvc> m_FastCaloSimSvc{this, "ISF_FastCaloSimV2ParamSvc", "ISF_FastCaloSimV2ParamSvc"}; + // FastCaloSim transportation tool + PublicToolHandle<IFastCaloSimCaloTransportation> m_FastCaloSimCaloTransportation{this, "FastCaloSimCaloTransportation", "FastCaloSimCaloTransportation", ""}; // FastCaloSim extrapolation tool PublicToolHandle<IFastCaloSimCaloExtrapolation> m_FastCaloSimCaloExtrapolation{this, "FastCaloSimCaloExtrapolation", "FastCaloSimCaloExtrapolation", ""}; + // Geant4 transportation tool + PublicToolHandle<IG4CaloTransportTool> m_G4CaloTransportTool{this, "G4CaloTransportTool", "G4CaloTransportTool", ""}; // Random generator service ServiceHandle<IAthRNGSvc> m_rndmGenSvc{this, "RandomSvc", "AthRNGSvc", ""}; // Random generator engine name Gaudi::Property<std::string> m_randomEngineName{this, "RandomStream", ""}; // Name of associated CaloCellContainerSD Gaudi::Property<std::string> m_CaloCellContainerSDName{this, "CaloCellContainerSDName", "", "Name of the associated CaloCellContainerSD"}; - + // Flag to enable G4 transportation + Gaudi::Property<bool> m_doG4Transport{this, "doG4Transport", false, "Flag to enable G4 transportation"}; }; #endif //G4FASTSIMULATION_FASTCALOSIMTOOL_H - diff --git a/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/ISF_FastCaloSimParametrization/IFastCaloSimCaloExtrapolation.h b/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/ISF_FastCaloSimParametrization/IFastCaloSimCaloExtrapolation.h index b6df2b8b1a1..a14e4750923 100644 --- a/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/ISF_FastCaloSimParametrization/IFastCaloSimCaloExtrapolation.h +++ b/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/ISF_FastCaloSimParametrization/IFastCaloSimCaloExtrapolation.h @@ -10,6 +10,7 @@ class TFCSTruthState; class TFCSExtrapolationState; +class G4FieldTrack; static const InterfaceID IID_IFastCaloSimCaloExtrapolation("IFastCaloSimCaloExtrapolation", 1, 0); @@ -20,6 +21,8 @@ class IFastCaloSimCaloExtrapolation : virtual public IAlgTool static const InterfaceID& interfaceID() { return IID_IFastCaloSimCaloExtrapolation; } virtual void extrapolate(TFCSExtrapolationState& result,const TFCSTruthState* truth) const = 0; + virtual void extrapolate(TFCSExtrapolationState& result,const TFCSTruthState* truth, const std::vector<G4FieldTrack>& caloSteps) const = 0; + }; #endif // IFastCaloSimCaloExtrapolation_H diff --git a/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/src/FastCaloSimCaloExtrapolation.cxx b/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/src/FastCaloSimCaloExtrapolation.cxx index eec9c3a4f47..8bd736077a6 100644 --- a/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/src/FastCaloSimCaloExtrapolation.cxx +++ b/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/src/FastCaloSimCaloExtrapolation.cxx @@ -68,25 +68,29 @@ StatusCode FastCaloSimCaloExtrapolation::finalize(){ return StatusCode::SUCCESS; } -void FastCaloSimCaloExtrapolation::extrapolate(TFCSExtrapolationState& result, const TFCSTruthState* truth) const{ - - ATH_MSG_DEBUG("Start FastCaloSimCaloExtrapolation::extrapolate"); - std::vector<G4FieldTrack> caloSteps = m_CaloTransportation -> transport(truth, false); - ATH_MSG_DEBUG("Done FastCaloSimCaloExtrapolation::extrapolate: caloHits"); - - ATH_MSG_DEBUG("FastCaloSimCaloExtrapolation::extrapolate:*** Do extrapolation to ID-calo boundary ***"); +void FastCaloSimCaloExtrapolation::extrapolate(TFCSExtrapolationState& result, const TFCSTruthState* truth, const std::vector<G4FieldTrack>& caloSteps) const{ + + ATH_MSG_DEBUG("[extrapolate] Initializing extrapolation to ID-Calo boundary"); extrapolateToID(result, caloSteps, truth); - ATH_MSG_DEBUG("FastCaloSimCaloExtrapolation::extrapolate:*** Do extrapolation ***"); + ATH_MSG_DEBUG("[extrapolate] Initializing extrapolation to calorimeter layers"); extrapolateToLayers(result, caloSteps, truth); - ATH_MSG_DEBUG("FastCaloSimCaloExtrapolation::extrapolate: Truth extrapolation done"); + ATH_MSG_DEBUG("[extrapolate] Extrapolation done"); - ATH_MSG_DEBUG("Done FastCaloSimCaloExtrapolation::extrapolate"); +} +void FastCaloSimCaloExtrapolation::extrapolate(TFCSExtrapolationState& result, const TFCSTruthState* truth) const{ + + ATH_MSG_DEBUG("[extrapolate] Initializing transport of track through calorimeter system with ATLAS tracking tools."); + std::vector<G4FieldTrack> caloSteps = m_CaloTransportation -> transport(truth, false); + ATH_MSG_DEBUG("[extrapolate] Finalized transport of track through calorimeter system with ATLAS tracking tools."); + + extrapolate(result, truth, caloSteps); } + void FastCaloSimCaloExtrapolation::extrapolateToID(TFCSExtrapolationState& result, const std::vector<G4FieldTrack>& caloSteps, const TFCSTruthState* truth) const{ ATH_MSG_DEBUG("Start extrapolateToID()"); diff --git a/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/src/FastCaloSimCaloExtrapolation.h b/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/src/FastCaloSimCaloExtrapolation.h index b6c0109c4bd..eeb7bdb1707 100644 --- a/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/src/FastCaloSimCaloExtrapolation.h +++ b/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/src/FastCaloSimCaloExtrapolation.h @@ -51,7 +51,8 @@ public: ON //hit position is on cylinder bounds }; - virtual void extrapolate(TFCSExtrapolationState& result,const TFCSTruthState* truth) const override final; + virtual void extrapolate(TFCSExtrapolationState& result, const TFCSTruthState* truth, const std::vector<G4FieldTrack>& caloSteps) const override final; + virtual void extrapolate(TFCSExtrapolationState& result, const TFCSTruthState* truth) const override final; protected: diff --git a/Simulation/SimulationConfig/python/SimConfigFlags.py b/Simulation/SimulationConfig/python/SimConfigFlags.py index a7098218854..6ceaecd6f98 100644 --- a/Simulation/SimulationConfig/python/SimConfigFlags.py +++ b/Simulation/SimulationConfig/python/SimConfigFlags.py @@ -69,6 +69,7 @@ def createSimConfigFlags(): # G4AtlasAlg scf.addFlag("Sim.ReleaseGeoModel", False) + scf.addFlag("Sim.SimplifiedGeoPath", "") scf.addFlag("Sim.RecordFlux", False) scf.addFlag("Sim.TruthStrategy", lambda prevFlags : TruthStrategy.Validation if prevFlags.Sim.ISF.ValidationMode else TruthStrategy.MC12, type=TruthStrategy) diff --git a/Simulation/SimulationConfig/python/SimulationMetadata.py b/Simulation/SimulationConfig/python/SimulationMetadata.py index e3e425f68a0..d5e988b4d74 100644 --- a/Simulation/SimulationConfig/python/SimulationMetadata.py +++ b/Simulation/SimulationConfig/python/SimulationMetadata.py @@ -32,6 +32,9 @@ def fillAtlasMetadata(flags, dbFiller): if "FastCalo.ParamsInputFilename" in flag and not flags.Sim.ISF.Simulator.usesFastCaloSim(): # This flag is only written to metadata when FastCaloSim/FastCaloGAN is enabled continue + if "SimplifiedGeoPath" in flag and not flags.Sim.SimplifiedGeoPath: + # This flag is only written to metadata in case the FastCaloSim simplified geometry path is set + continue key = flag.split(".")[-1] #use final part of flag as the key value = flags._get(flag) if isinstance(value, FlagEnum): -- GitLab