ATLAS Offline Software
Loading...
Searching...
No Matches
ActsFatrasG4Tool.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef G4ATLASTOOLS_ACTSFATRASG4TOOL_H
6#define G4ATLASTOOLS_ACTSFATRASG4TOOL_H
7
15
16// interfaces
19
20// Gaudi, StoreGate and Athena
21#include "GaudiKernel/ToolHandle.h"
22#include "GaudiKernel/ServiceHandle.h"
23#include "GaudiKernel/EventContext.h"
32
33// ATLAS (for the hits)
37#include "InDetSimEvent/SiHit.h"
38
39// ACTS
40#include "Acts/Utilities/UnitVectors.hpp"
41#include "ActsInterop/Logger.h"
43#include "Acts/Geometry/TrackingGeometry.hpp"
44#include "Acts/Geometry/GeometryContext.hpp"
45#include "Acts/MagneticField/MagneticFieldContext.hpp"
46#include "Acts/EventData/BoundTrackParameters.hpp"
47#include "Acts/Propagator/Navigator.hpp"
48#include "Acts/Propagator/EigenStepper.hpp"
49#include "Acts/Propagator/EigenStepperDefaultExtension.hpp"
50#include "Acts/Propagator/StraightLineStepper.hpp"
51#include "Acts/Propagator/detail/SteppingLogger.hpp"
52#include "Acts/Propagator/ActorList.hpp"
53#include "Acts/Propagator/Propagator.hpp"
54#include "Acts/Definitions/ParticleData.hpp"
55#include <Acts/Definitions/Algebra.hpp>
56// ActsFatras
57#include "ActsFatras/EventData/Particle.hpp"
58#include "ActsFatras/EventData/Hit.hpp"
59#include "ActsFatras/EventData/GenerationProcess.hpp"
60#include "ActsFatras/Kernel/InteractionList.hpp"
61#include "ActsFatras/Kernel/SingleParticleSimulation.hpp"
62#include "ActsFatras/Kernel/MultiParticleSimulation.hpp"
63#include "ActsFatras/Kernel/SingleParticleSimulationResult.hpp"
64#include "ActsFatras/Kernel/detail/SimulationActor.hpp"
65#include "ActsFatras/Physics/Decay/NoDecay.hpp"
66#include "ActsFatras/Physics/StandardInteractions.hpp"
67#include "ActsFatras/Physics/ElectroMagnetic/PhotonConversion.hpp"
68#include "ActsFatras/Selectors/SurfaceSelectors.hpp"
69
70// Tracking
74
75// Geant4
76#include "G4FastTrack.hh"
77#include "G4FastStep.hh"
78#include "G4Track.hh"
79
80// C++ STL
81#include <utility>
82#include <array>
83#include <string>
84#include <algorithm>
85#include <cassert>
86#include <vector>
87#include <map>
88
89class ActsFatrasG4Tool : virtual public extends<AthAlgTool, IActsFatrasG4Tool, IPhysicsInitializationTool>
90{
91 public:
92 using base_class::base_class;
93 virtual ~ActsFatrasG4Tool () = default;
94
96 virtual StatusCode initialize() override;
98 virtual StatusCode finalize() override;
100 StatusCode initializePhysics() override;
101
103 virtual void simulateFatrasTrack(const G4FastTrack& fastTrack, G4FastStep& fastStep) override;
104
106 virtual const std::vector<SiHit>& getPixelHitsCache(const EventContext& ctx) const override;
107 virtual const std::vector<SiHit>& getSCTHitsCache(const EventContext& ctx) const override;
108 virtual void clearCaches(const EventContext& ctx) const override;
109
110 private:
111
114
118 bool operator()(const Acts::Surface &surface) const {
119 return surface.isSensitive();
120 }
121 };
122
123 // SingleParticleSimulation
130 template <typename propagator_t, typename interactions_t, typename hit_surface_selector_t, typename decay_t>
133 propagator_t propagator;
135 decay_t decay;
137 interactions_t interactions;
139 hit_surface_selector_t selectHitSurface;
141 double maxStepSize = 3.0; // leght in m
142 double maxStep = 1000;
144 double pathLimit = 100.0; // lenght in cm
145 bool loopProtection = true;
146 double loopFraction = 0.5;
147 double targetTolerance = 0.0001;
148 double stepSizeCutOff = 0.;
149 // parameters for densEnv propagator options
150 double meanEnergyLoss = true;
151 bool includeGgradient = true;
152 double momentumCutOff = 0.;
153
155 std::shared_ptr<const Acts::Logger> localLogger = nullptr;
156
158 SingleParticleSimulation(propagator_t &&propagator_, std::shared_ptr<const Acts::Logger> localLogger_)
159 : propagator(std::move(propagator_)), localLogger(std::move(localLogger_)) {}
160
162 const Acts::Logger &logger() const { return *localLogger; }
163
173 template <typename generator_t>
174 Acts::Result<ActsFatras::SingleParticleSimulationResult> simulate(const Acts::GeometryContext &geoCtx,
175 const Acts::MagneticFieldContext &magCtx, generator_t &generator,
176 const ActsFatras::Particle &particle) const
177 {
178 assert(localLogger and "Missing local logger");
179 ACTS_VERBOSE("Using ActsFatrasSimTool simulate()");
180 // propagator-related additional types
181 using SteppingLogger = Acts::detail::SteppingLogger;
182 using SimulationActor = ActsFatras::detail::SimulationActor<generator_t, decay_t, interactions_t, hit_surface_selector_t>;
183 using Result = typename SimulationActor::result_type;
184 using Actions = Acts::ActorList<SteppingLogger, SimulationActor, Acts::EndOfWorldReached>;
185 using PropagatorOptions = typename propagator_t::template Options<Actions>;
186
187 // Construct per-call options.
188 PropagatorOptions options(geoCtx, magCtx);
189 // setup the interactor as part of the propagator options
190 auto &actor = options.actorList.template get<SimulationActor>();
191 actor.generator = &generator;
192 actor.decay = decay;
193 actor.interactions = interactions;
194 actor.selectHitSurface = selectHitSurface;
195 actor.initialParticle = particle;
196 // use AnyCharge to be able to handle neutral and charged parameters
197 Acts::BoundTrackParameters startPoint = Acts::BoundTrackParameters::createCurvilinear(particle.fourPosition(),
198 particle.direction(),
199 particle.qOverP(), std::nullopt,
200 particle.hypothesis()
201 );
202 options.pathLimit = pathLimit * Acts::UnitConstants::cm;
203 options.loopProtection = loopProtection;
204 options.maxSteps = maxStep;
205 options.stepping.maxStepSize = maxStepSize * Acts::UnitConstants::m;
206 auto result = propagator.propagate(startPoint, options);
207 if (not result.ok()) {return result.error();}
208 return result.value().template get<Result>();
209 }
210 };// end of SingleParticleSimulation
211
212 // ===============================
213 // Random number generator
214 // ===============================
215 using Generator = std::ranlux48;
216 // ===============================
217 // Setup ActsFatras simulator types
218 // ===============================
219 // Use default navigator
220 using Navigator = Acts::Navigator;
221 // propagate charged particles numerically in the B-field
222 using ChargedStepper = Acts::EigenStepper<Acts::EigenStepperDefaultExtension>;
223 using ChargedPropagator = Acts::Propagator<ChargedStepper, Navigator>;
224 // propagate neutral particles with just straight lines
225 using NeutralStepper = Acts::StraightLineStepper;
226 using NeutralPropagator = Acts::Propagator<NeutralStepper, Navigator>;
227 // charged simulation with EM interactions
228 using ChargedSelector = ActsFatras::ChargedSelector;
229 using ChargedInteractions = ActsFatras::StandardChargedElectroMagneticInteractions;
232 ActsFatras::NoDecay>;
233 // neutral simulation with photon conversion
234 using NeutralSelector = ActsFatras::NeutralSelector;
235 using NeutralInteractions = ActsFatras::InteractionList<ActsFatras::PhotonConversion>;
237 ActsFatras::NoSurface,
238 ActsFatras::NoDecay>;
239 // full simulator type for charged and neutrals
240 using Simulation = ActsFatras::MultiParticleSimulation<ChargedSelector, ChargedSimulation,
242
243 // ==============================
244 // Acts navigation / field
245 // ==============================
246 std::unique_ptr<Navigator> m_navigator;
247 std::shared_ptr<ATLASMagneticFieldWrapper> m_bField;
248
249 // ==============================
250 // Top-level simulator
251 // ==============================
252 std::unique_ptr<Simulation> m_simulator;
253
254 // ==============================
255 // Methods
256 // ==============================
257 StatusCode configureSimulator();
258 void debugTrackRegion(const G4FastTrack& fastTrack) const;
259 std::vector<ActsFatras::Particle> buildActsInputFromG4(const G4Track& track);
260 void handleSimulationFailures(const Acts::Result<ActsFatras::SingleParticleSimulationResult>& result);
261 StatusCode applyPrimaryUpdate(const G4Track&, const std::vector<ActsFatras::Particle>& simulatedFinalParticles, G4FastStep& fastStep);
262 StatusCode spawnSecondaries(const std::vector<ActsFatras::Particle>& simulatedFinal, const G4Track&, G4FastStep& fastStep);
263
264 // Make hits cache, to be written to SG
265 StatusCode createHitsFromG4(
266 const EventContext& ctx,
267 const G4Track& track,
268 const Acts::TrackingGeometry& trackingGeometry,
269 const std::vector<ActsFatras::Hit>& hits
270 ) const;
271 // inject fake (muons) particles
272 StatusCode runDebugInjection(
273 const EventContext& ctx,
274 const G4Track& track,
275 const Acts::GeometryContext& anygctx,
276 const Acts::MagneticFieldContext& mctx,
277 Generator& generator,
278 G4FastStep& fastStep
279 );
280
281 // ==============================
282 // Properties
283 // ==============================
284 // Random number service
285 ServiceHandle<IAthRNGSvc> m_rngSvc{this, "RNGService", "AthRNGSvc"};
287 Gaudi::Property<std::string> m_randomEngineName{this, "RandomEngineName", "RandomEngineName", "Name of random number stream"};
288
289 // Tracking geometry
290 ServiceHandle<ActsTrk::ITrackingGeometrySvc> m_trackingGeometrySvc{this, "TrackingGeometrySvc", "ActsTrackingGeometrySvc"};
291 std::shared_ptr<const Acts::TrackingGeometry> m_trackingGeometry;
292
293
294 // Logging
295 std::shared_ptr<const Acts::Logger> m_logger{nullptr};
296
297 // ** Other Gaudi properties ** //
298 Gaudi::Property<double> m_interact_minPt{this, "Interact_MinPt", 50.0, "Min pT of the interactions (MeV)"};
299 // Propagator options
300 Gaudi::Property<bool> m_meanEnergyLoss{this, "MeanEnergyLoss", true, "Toggle between mean and mode evaluation of energy loss"};
301 Gaudi::Property<bool> m_includeGradient{this, "IncludeGradient", true, "Boolean flag for inclusion of d(dEds)d(q/p) into energy loss"};
302 Gaudi::Property<double> m_momentumCutOff{this, "MomentumCutOff", 0., "Cut-off value for the momentum in SI units"};
303 // Propagator options
304 Gaudi::Property<double> m_maxStep{this, "MaxSteps", 2000, "Max number of steps"};
305 Gaudi::Property<double> m_maxRungeKuttaStepTrials{this, "MaxRungeKuttaStepTrials", 10000, "Max number of Runge-Kutta steps for the stepper step call"};
306 Gaudi::Property<double> m_maxStepSize{this, "MaxStepSize", 3.0, "Max step size (converted to Acts::UnitConstants::m)"};
307 Gaudi::Property<double> m_pathLimit{this, "PathLimit", 3000.0, "Track path limit (converted to Acts::UnitConstants::cm)"};
308 Gaudi::Property<bool> m_loopProtection{this, "LoopProtection", true, "Loop protection, it adapts the pathLimit"};
309 Gaudi::Property<double> m_loopFraction{this, "LoopFraction", 0.5, "Allowed loop fraction, 1 is a full loop"};
310 Gaudi::Property<double> m_tolerance{this, "Tolerance", 0.0001, "Tolerance for the error of the integration"};
311 Gaudi::Property<double> m_stepSizeCutOff{this, "StepSizeCutOff", 0., "Cut-off value for the step size"};
312 Gaudi::Property<std::map<int,int>> m_processTypeMap{this, "ProcessTypeMap",
313 {{0,0}, {1,201}, {2,14}, {3,3}, {4,121}},
314 "proessType map <ActsFatras,G4>"
315 };
316 //{{ActsFatras::GenerationProcess::eUndefined,0}, {ActsFatras::GenerationProcess::eDecay,201}, {ActsFatras::GenerationProcess::ePhotonConversion,14}, {ActsFatras::GenerationProcess::eBremsstrahlung,3}, {ActsFatras::GenerationProcess::eNuclearInteraction,121}}
317 inline int getATLASProcessCode(ActsFatras::GenerationProcess actspt){return m_processTypeMap[static_cast<uint32_t>(actspt)];};
318
319 // ==============================
320 // Hits writing
321 // ==============================
322 struct EventCache {
323 std::vector<SiHit> pixelHits;
324 std::vector<SiHit> sctHits;
325 };
327 EventCache& getCache(const EventContext& ctx) const;
328
329 // set to false always for non-test
330 Gaudi::Property<bool> m_debugInject{this, "DebugInjectParticle", false};
331
332 protected:
333 // ==============================
334 // Hits cache
335 // ==============================
336 // For SiHit creation
337 const PixelID* m_pixIdHelper{nullptr};
338 const SCT_ID* m_sctIdHelper{nullptr};
339
340}; // end of ActsFatrasG4Tool class
341
342#endif // G4ATLASTOOLS_ACTSFATRASG4TOOL_H
343
344
345
346
347
348
Maintain a set of objects, one per slot.
Hash map from integers/pointers allowing concurrent, lockless reads.
This is an Identifier helper class for the Pixel subdetector.
This is an Identifier helper class for the SCT subdetector.
Property holding a SG store/key/clid from which a WriteHandle is made.
Define macros for attributes used to control the static checker.
A wrapper class for event-slot-local random engines.
Definition RNGWrapper.h:56
Tool for ACTS Fatras G4.
virtual const std::vector< SiHit > & getPixelHitsCache(const EventContext &ctx) const override
for saving si hits caches, expose to the interface
std::unique_ptr< Navigator > m_navigator
SingleParticleSimulation< ChargedPropagator, ChargedInteractions, HitSurfaceSelector, ActsFatras::NoDecay > ChargedSimulation
ActsFatras::InteractionList< ActsFatras::PhotonConversion > NeutralInteractions
std::ranlux48 Generator
Gaudi::Property< double > m_pathLimit
std::shared_ptr< const Acts::TrackingGeometry > m_trackingGeometry
Gaudi::Property< bool > m_debugInject
StatusCode spawnSecondaries(const std::vector< ActsFatras::Particle > &simulatedFinal, const G4Track &, G4FastStep &fastStep)
const SCT_ID * m_sctIdHelper
the SCT ID helper
Gaudi::Property< double > m_maxRungeKuttaStepTrials
const PixelID * m_pixIdHelper
the Pixel ID helper
Gaudi::Property< double > m_maxStep
Acts::Propagator< NeutralStepper, Navigator > NeutralPropagator
Gaudi::Property< double > m_maxStepSize
StatusCode configureSimulator()
StatusCode applyPrimaryUpdate(const G4Track &, const std::vector< ActsFatras::Particle > &simulatedFinalParticles, G4FastStep &fastStep)
ActsTrk::ContextUtility m_ctxProvider
Context provider for geometry, magnetic field and calibration contexts.
int getATLASProcessCode(ActsFatras::GenerationProcess actspt)
EventCache & getCache(const EventContext &ctx) const
ServiceHandle< IAthRNGSvc > m_rngSvc
Gaudi::Property< double > m_loopFraction
Acts::EigenStepper< Acts::EigenStepperDefaultExtension > ChargedStepper
virtual StatusCode finalize() override
AlgTool finalize method.
ServiceHandle< ActsTrk::ITrackingGeometrySvc > m_trackingGeometrySvc
Gaudi::Property< bool > m_includeGradient
SingleParticleSimulation< NeutralPropagator, NeutralInteractions, ActsFatras::NoSurface, ActsFatras::NoDecay > NeutralSimulation
Gaudi::Property< double > m_momentumCutOff
Gaudi::Property< bool > m_meanEnergyLoss
StatusCode initializePhysics() override
AlgTool initializePhysics method.
virtual StatusCode initialize() override
AlgTool initialize method.
ActsFatras::ChargedSelector ChargedSelector
Gaudi::Property< std::string > m_randomEngineName
virtual void clearCaches(const EventContext &ctx) const override
Gaudi::Property< double > m_interact_minPt
Acts::Navigator Navigator
Gaudi::Property< std::map< int, int > > m_processTypeMap
std::shared_ptr< ATLASMagneticFieldWrapper > m_bField
Acts::StraightLineStepper NeutralStepper
void handleSimulationFailures(const Acts::Result< ActsFatras::SingleParticleSimulationResult > &result)
Gaudi::Property< double > m_stepSizeCutOff
ActsFatras::NeutralSelector NeutralSelector
Gaudi::Property< bool > m_loopProtection
Gaudi::Property< double > m_tolerance
StatusCode runDebugInjection(const EventContext &ctx, const G4Track &track, const Acts::GeometryContext &anygctx, const Acts::MagneticFieldContext &mctx, Generator &generator, G4FastStep &fastStep)
void debugTrackRegion(const G4FastTrack &fastTrack) const
Acts::Propagator< ChargedStepper, Navigator > ChargedPropagator
ATHRNG::RNGWrapper *m_randomEngine ATLAS_THREAD_SAFE
std::shared_ptr< const Acts::Logger > m_logger
virtual const std::vector< SiHit > & getSCTHitsCache(const EventContext &ctx) const override
std::unique_ptr< Simulation > m_simulator
virtual ~ActsFatrasG4Tool()=default
std::vector< ActsFatras::Particle > buildActsInputFromG4(const G4Track &track)
ActsFatras::StandardChargedElectroMagneticInteractions ChargedInteractions
StatusCode createHitsFromG4(const EventContext &ctx, const G4Track &track, const Acts::TrackingGeometry &trackingGeometry, const std::vector< ActsFatras::Hit > &hits) const
virtual void simulateFatrasTrack(const G4FastTrack &fastTrack, G4FastStep &fastStep) override
create ActsFatras track, exposed via interface
Utility class to handle the three contexts neeeded in an ACTS reconstruction job 1) GeometryContext -...
This is an Identifier helper class for the Pixel subdetector.
Definition PixelID.h:69
This is an Identifier helper class for the SCT subdetector.
Definition SCT_ID.h:68
Maintain a set of objects, one per slot.
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:132
STL namespace.
std::vector< SiHit > pixelHits
Simple struct to select surfaces where hits should be generated.
bool operator()(const Acts::Surface &surface) const
Single particle simulation with fixed propagator, interactions, and decay.
Acts::Result< ActsFatras::SingleParticleSimulationResult > simulate(const Acts::GeometryContext &geoCtx, const Acts::MagneticFieldContext &magCtx, generator_t &generator, const ActsFatras::Particle &particle) const
Simulate a single particle without secondaries.
SingleParticleSimulation(propagator_t &&propagator_, std::shared_ptr< const Acts::Logger > localLogger_)
Alternatively construct the simulator with an external logger.
const Acts::Logger & logger() const
Provide access to the local logger instance, e.g. for logging macros.