diff --git a/Simulation/G4Atlas/G4AtlasAlg/CMakeLists.txt b/Simulation/G4Atlas/G4AtlasAlg/CMakeLists.txt index 4268da90cdceb9ed5aeec1b7226320f631d7f496..07d5988a9e2bccd70cb40bf9bc9b1ad6257a0c6e 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 ae03695f550476db945defd057fe4a5100791475..2f7363bf51ea56ff9098a293e2a56169fed15676 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 8cc82a1c4e49fc3185d8401b54b77aa2e7559d05..cca09cad531ee1295c6c5ca688f71bc741292195 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 4cc1c15d925fe3f1978a3e79d2b0209c035a2bf9..a2f27d9893be2ef7083ffc0a6422b082fd74fac3 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 0000000000000000000000000000000000000000..4d2c44bfd3a645550fd25efb1fcede4e8db0bb45 --- /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 ce06db315b7ed714840637b02f5550f64e3d8b4b..530a10e9b54fa1692f1e2f8c8b0cf79dc76b087c 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 9521b733f9b51d4c2902a99e939cbcc48c49c9ee..a32f7cb19d4911284be089dbfa7e6fbcf0d5a211 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 adac3554176c79ce430fb5f254363e6643c90120..59e95e1a36f68f4d772805a302a58df41cfa894e 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 87f56f0ed63f4d7f4291673447f94ea2c58a7e2e..5667106c2dcb136a3a1742833e594ffe4c3b629d 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 0000000000000000000000000000000000000000..0043c2d40d5f7a610e638672ffae8e64dfb57e02 --- /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 0000000000000000000000000000000000000000..75474aae62552e05d9c9a1acb984f425cf683f9b --- /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 43ecc77d35105de79a1bbe91495227a4504491cf..779b432aada1e79db68400d30be18547e2e52c2e 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 8816dd31100e14779661cf83eaa19e2d0b8dc6c2..a549b0e3761630286b34d4c0f29563ade23c5889 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 9a5e9371b953c8d2843d8363c5b72a9ea979811f..6c9feecc69d08d69bdb01c2cbdeaa14baa0ca53a 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 d9bd51f920980fee9e73d25bb74bf1e19ddcc5b9..238df3a4189792f19c4ff48eea9de3cba25d94e4 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 2475cfecf7068ad7e58e0031ae9df383dcd133b4..e99e3f198b40fc695a997add7720019efd545d39 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 d3baf0158b7f62bd75135cf8a33bba1e32f448d3..cc30c0cfc1af8b877655207eb5501338d9b2a801 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 b6df2b8b1a1cb6032cc0e301a42784568c625792..a14e475092394113aced48a44629fa6f1ba1555d 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 eec9c3a4f474ff32b24e05878fa8d97b6863bd2d..8bd736077a6b11c536fef7caa5e1664e5c287125 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 b6c0109c4bd858dccda6128feb992b3f2d173506..eeb7bdb17079a07e61bec8ec73f4b69a9428f4f8 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 a7098218854fad33ca6d1f9804667b80c92d40ea..6ceaecd6f98b13d4698e60d44edb1653c02de766 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 e3e425f68a04997d94262247efd08241cd9cd2b3..d5e988b4d74258339f279dac8d424ca3c5d9013d 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):