ATLAS Offline Software
Loading...
Searching...
No Matches
ActsFatrasSimTool.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 ISF_ACTSTOOLS_ACTSFATRASSIMTOOL_H
6#define ISF_ACTSTOOLS_ACTSFATRASSIMTOOL_H
7
8// Gaudi
9#include "GaudiKernel/ServiceHandle.h"
10#include "GaudiKernel/ToolHandle.h"
11
12// Athena
16
17// ISF
26
27// ACTS
28#include "Acts/Utilities/UnitVectors.hpp"
29#include "ActsInterop/Logger.h"
31#include "Acts/Geometry/GeometryContext.hpp"
32#include "Acts/MagneticField/MagneticFieldContext.hpp"
33#include "Acts/EventData/BoundTrackParameters.hpp"
34#include "Acts/Propagator/Navigator.hpp"
35#include "Acts/Propagator/EigenStepper.hpp"
36#include "Acts/Propagator/EigenStepperDefaultExtension.hpp"
37#include "Acts/Propagator/StraightLineStepper.hpp"
38#include "Acts/Propagator/detail/SteppingLogger.hpp"
39#include "Acts/Propagator/ActorList.hpp"
40#include "Acts/Propagator/Propagator.hpp"
41#include "Acts/Definitions/ParticleData.hpp"
42#include "ActsFatras/EventData/GenerationProcess.hpp"
43#include "ActsFatras/Kernel/InteractionList.hpp"
44#include "ActsFatras/Kernel/MultiParticleSimulation.hpp"
45#include "ActsFatras/Kernel/SingleParticleSimulationResult.hpp"
46#include "ActsFatras/Kernel/detail/SimulationActor.hpp"
47#include "ActsFatras/Physics/Decay/NoDecay.hpp"
48#include "ActsFatras/Physics/StandardInteractions.hpp"
49#include "ActsFatras/Physics/ElectroMagnetic/PhotonConversion.hpp"
50#include "ActsFatras/Selectors/SurfaceSelectors.hpp"
51// Tracking
55
56
57#include <algorithm>
58#include <cassert>
59#include <vector>
60
61class AtlasDetectorID;
62
63namespace iFatras {
64 class ISimHitCreator;
65}
66
67namespace ISF {
68class IParticleHelper;
69
75
77
78 public:
82 bool operator()(const Acts::Surface &surface) const {
83 return surface.isSensitive();
84 }
85 };
86 // SingleParticleSimulation
93 template <typename propagator_t, typename interactions_t,
94 typename hit_surface_selector_t, typename decay_t>
97 propagator_t propagator;
99 decay_t decay;
101 interactions_t interactions;
103 hit_surface_selector_t selectHitSurface;
105 double maxStepSize = 3.0; // leght in m
106 double maxStep = 1000;
108 double pathLimit = 100.0; // lenght in cm
109 bool loopProtection = true;
110 double loopFraction = 0.5;
111 double targetTolerance = 0.0001;
112 double stepSizeCutOff = 0.;
113 // parameters for densEnv propagator options
114 double meanEnergyLoss = true;
115 bool includeGgradient = true;
116 double momentumCutOff = 0.;
117
119 std::shared_ptr<const Acts::Logger> localLogger = nullptr;
120
122 SingleParticleSimulation(propagator_t &&propagator_,
123 std::shared_ptr<const Acts::Logger> localLogger_)
124 : propagator(propagator_), localLogger(localLogger_) {}
125
127 const Acts::Logger &logger() const { return *localLogger; }
128
138 template <typename generator_t>
139 Acts::Result<ActsFatras::SingleParticleSimulationResult> simulate(
140 const Acts::GeometryContext &geoCtx,
141 const Acts::MagneticFieldContext &magCtx, generator_t &generator,
142 const ActsFatras::Particle &particle) const {
143 assert(localLogger and "Missing local logger");
144 ACTS_VERBOSE("Using ActsFatrasSimTool simulate()");
145 // propagator-related additional types
146 using SteppingLogger = Acts::detail::SteppingLogger;
147 using SimulationActor = ActsFatras::detail::SimulationActor<generator_t, decay_t, interactions_t, hit_surface_selector_t>;
148 using Result = typename SimulationActor::result_type;
149 using Actions = Acts::ActorList<SteppingLogger, SimulationActor, Acts::EndOfWorldReached>;
150 using PropagatorOptions = typename propagator_t::template Options<Actions>;
151
152 // Construct per-call options.
153 PropagatorOptions options(geoCtx, magCtx);
154 // setup the interactor as part of the propagator options
155 auto &actor = options.actorList.template get<SimulationActor>();
156 actor.generator = &generator;
157 actor.decay = decay;
158 actor.interactions = interactions;
159 actor.selectHitSurface = selectHitSurface;
160 actor.initialParticle = particle;
161 // use AnyCharge to be able to handle neutral and charged parameters
162 Acts::BoundTrackParameters startPoint = Acts::BoundTrackParameters::createCurvilinear(
163 particle.fourPosition(), particle.direction(),
164 particle.qOverP(), std::nullopt, particle.hypothesis());
165 options.pathLimit = pathLimit * Acts::UnitConstants::cm;
166 options.loopProtection = loopProtection;
167 options.maxSteps = maxStep;
168 options.stepping.maxStepSize = maxStepSize * Acts::UnitConstants::m;
169 options.direction = Acts::Direction::Forward();
170
171 auto result = propagator.propagate(startPoint, options);
172 if (not result.ok()) {
173 return result.error();
174 }
175 return result.value().template get<Result>();
176 }
177 };// end of SingleParticleSimulation
178
179 // Standard generator
180 using Generator = std::ranlux48;
181 // Use default navigator
182 using Navigator = Acts::Navigator;
183 // Propagate charged particles numerically in the B-field
184 using ChargedStepper = Acts::EigenStepper<Acts::EigenStepperDefaultExtension>;
185 using ChargedPropagator = Acts::Propagator<ChargedStepper, Navigator>;
186 // Propagate neutral particles in straight lines
187 using NeutralStepper = Acts::StraightLineStepper;
188 using NeutralPropagator = Acts::Propagator<NeutralStepper, Navigator>;
189
190 // ===============================
191 // Setup ActsFatras simulator types
192 // Charged
193 using ChargedSelector = ActsFatras::ChargedSelector;
195 ActsFatras::StandardChargedElectroMagneticInteractions;
198 ActsFatras::NoDecay>;
199 // Neutral
200 using NeutralSelector = ActsFatras::NeutralSelector;
201 using NeutralInteractions = ActsFatras::InteractionList<ActsFatras::PhotonConversion>;
203 NeutralPropagator, NeutralInteractions, ActsFatras::NoSurface,
204 ActsFatras::NoDecay>;
205 // Combined
206 using Simulation = ActsFatras::MultiParticleSimulation<
209 // ===============================
211 inline Amg::Vector3D convertMom3FromActs(const Acts::Vector3& actsMom) {
212 Amg::Vector3D threeMom{Amg::Vector3D::Zero()};
213 threeMom[Amg::x] = ActsTrk::energyToAthena(actsMom[Acts::eMom0]);
214 threeMom[Amg::y] = ActsTrk::energyToAthena(actsMom[Acts::eMom1]);
215 threeMom[Amg::z] = ActsTrk::energyToAthena(actsMom[Acts::eMom2]);
216 return threeMom;
217 }
218
219 inline Amg::Vector3D convertPos3FromActs(const Acts::Vector3& actsPos) {
220 Amg::Vector3D pos{Amg::Vector3D::Zero()};
221 pos[Amg::x] = ActsTrk::lengthToAthena(actsPos[Acts::ePos0]);
222 pos[Amg::y] = ActsTrk::lengthToAthena(actsPos[Acts::ePos1]);
223 pos[Amg::z] = ActsTrk::lengthToAthena(actsPos[Acts::ePos2]);
224 return pos;
225 }
226
227 ActsFatrasSimTool(const std::string& type, const std::string& name,
228 const IInterface* parent);
229 virtual ~ActsFatrasSimTool();
230
231 // ISF BaseSimulatorTool Interface methods
232 virtual StatusCode initialize() override;
233 virtual StatusCode simulate(const EventContext& ctx, ISFParticle& isp, ISFParticleContainer&,
234 McEventCollection*) override;
235 virtual StatusCode simulateVector(
236 const EventContext& ctx,
237 const ISFParticleVector& particles,
238 ISFParticleContainer& secondaries,
239 McEventCollection* mcEventCollection, McEventCollection *shadowTruth=nullptr) override;
240 virtual StatusCode setupEvent(const EventContext&) override {
241 ATH_CHECK(m_truthRecordSvc->initializeTruthCollection());
242 m_pixelSiHits.Clear();
243 m_sctSiHits.Clear();
244 return StatusCode::SUCCESS; };
245 virtual StatusCode releaseEvent(const EventContext& ctx) override {
246 std::vector<SiHitCollection> hitcolls;
247 hitcolls.push_back(m_pixelSiHits);
248 hitcolls.push_back(m_sctSiHits);
249 ATH_CHECK(m_ActsFatrasWriteHandler->WriteHits(hitcolls,ctx));
250 ATH_CHECK(m_truthRecordSvc->releaseEvent());
251 return StatusCode::SUCCESS; };
252 virtual ISF::SimulationFlavor simFlavor() const override{
253 return ISF::Fatras; };
254 private:
257
258 // For sihit creation
261 // Templated tool retrieval
262 template <class T>
263 StatusCode retrieveTool(ToolHandle<T>& thandle) {
264 if (!thandle.empty() && thandle.retrieve().isFailure()) {
265 ATH_MSG_FATAL("Cannot retrieve " << thandle << ". Abort.");
266 return StatusCode::FAILURE;
267 } else ATH_MSG_DEBUG("Successfully retrieved " << thandle);
268 return StatusCode::SUCCESS;
269 }
270
271 bool checkStartSurface(const Acts::MagneticFieldContext& mctx,
272 const Acts::GeometryContext& anygctx,
273 const ChargedPropagator& chargedPropagator,
274 const Acts::BoundTrackParameters& startParameters,
275 Acts::Direction navDir = Acts::Direction::Forward(),
276 double pathLimit = std::numeric_limits<double>::max()) const;
277
278 // Random number service
279 ServiceHandle<IAthRNGSvc> m_rngSvc{this, "RNGService", "AthRNGSvc"};
281 Gaudi::Property<std::string> m_randomEngineName{this, "RandomEngineName",
282 "RandomEngineName", "Name of random number stream"};
283
284 // GeoID service
285 ServiceHandle<ISF::IGeoIDSvc> m_geoIDSvc{this, "GeoIDSvc", "ISF::GeoIDSvc"};
286
287 // ACTS Extrapolator
288 PublicToolHandle<ActsTrk::IExtrapolationTool> m_extrapolationTool{this, "ExtrapolationTool", "ActsExtrapolationTool"};
289
290 // Tracking geometry
291 ServiceHandle<ActsTrk::ITrackingGeometrySvc> m_trackingGeometrySvc{this, "TrackingGeometrySvc", "ActsTrackingGeometrySvc"};
292 std::shared_ptr<const Acts::TrackingGeometry> m_trackingGeometry;
293
294 // Logging
295 std::shared_ptr<const Acts::Logger> m_logger{nullptr};
296
297 // ISF Tools
298 PublicToolHandle<ISF::IParticleFilter> m_particleFilter{
299 this, "ParticleFilter", "", "Particle filter kinematic cuts, etc."};
300
301 ServiceHandle<ISF::ITruthSvc> m_truthRecordSvc{this, "TruthRecordService", "ISF_TruthRecordSvc", ""};
302
303 // ActsFatrasHitConvtTool
304 ToolHandle<ActsFatrasWriteHandler> m_ActsFatrasWriteHandler{
305 this, "ActsFatrasWriteHandler", "ActsFatrasWriteHandler"};
306
307 Gaudi::Property<double> m_interact_minPt{this, "Interact_MinPt", 50.0,
308 "Min pT of the interactions (MeV)"};
309
310 // DensEnviroment Propergator option
311 Gaudi::Property<bool> m_meanEnergyLoss{this, "MeanEnergyLoss", true, "Toggle between mean and mode evaluation of energy loss"};
312 Gaudi::Property<bool> m_includeGgradient{this, "IncludeGgradient", true, "Boolean flag for inclusion of d(dEds)d(q/p) into energy loss"};
313 Gaudi::Property<double> m_momentumCutOff{this, "MomentumCutOff", 0., "Cut-off value for the momentum in SI units"};
314 // Propergator option
315 Gaudi::Property<double> m_maxStep{this, "MaxSteps", 2000,
316 "Max number of steps"};
317 Gaudi::Property<double> m_maxRungeKuttaStepTrials{this, "MaxRungeKuttaStepTrials", 10000,
318 "Maximum number of Runge-Kutta steps for the stepper step call"};
319 Gaudi::Property<double> m_maxStepSize{this, "MaxStepSize", 3.0,
320 "Max step size (converted to Acts::UnitConstants::m)"};
321 Gaudi::Property<double> m_pathLimit{this, "PathLimit", 3000.0,
322 "Track path limit (converted to Acts::UnitConstants::cm)"};
323 Gaudi::Property<bool> m_loopProtection{this, "LoopProtection", true,
324 "Loop protection, it adapts the pathLimit"};
325 Gaudi::Property<double> m_loopFraction{this, "LoopFraction", 0.5,
326 "Allowed loop fraction, 1 is a full loop"};
327 Gaudi::Property<double> m_tolerance{this, "Tolerance", 0.0001,
328 "Tolerance for the error of the integration"};
329 Gaudi::Property<double> m_stepSizeCutOff{this, "StepSizeCutOff", 0.,
330 "Cut-off value for the step size"};
331
332 // https://vmc-project.github.io/geant4_vmc/g4vmc_html/TG4ProcessMapPhysics_8cxx_source.html#:~:text=155%20pMap%2D%3EAdd(DECAY,);%20//%20G4%20value:%20231
333 Gaudi::Property<std::map<int,int>> m_processTypeMap{this, "ProcessTypeMap",
334 {{0,0}, {1,201}, {2,14}, {3,3}, {4,121}}, "proessType map <ActsFatras,G4>"};
335 //{{ActsFatras::GenerationProcess::eUndefined,0}, {ActsFatras::GenerationProcess::eDecay,201}, {ActsFatras::GenerationProcess::ePhotonConversion,14}, {ActsFatras::GenerationProcess::eBremsstrahlung,3}, {ActsFatras::GenerationProcess::eNuclearInteraction,121}}
336 inline int getATLASProcessCode(ActsFatras::GenerationProcess actspt){return m_processTypeMap[static_cast<uint32_t>(actspt)];};
337};
338
339} // namespace ISF
340
341#endif
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_DEBUG(x)
AtlasHitsVector< SiHit > SiHitCollection
Define macros for attributes used to control the static checker.
A wrapper class for event-slot-local random engines.
Definition RNGWrapper.h:56
Utility class to handle the three contexts neeeded in an ACTS reconstruction job 1) GeometryContext -...
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
ActsFatras::StandardChargedElectroMagneticInteractions ChargedInteractions
ActsFatras::NeutralSelector NeutralSelector
Gaudi::Property< double > m_maxStepSize
ActsFatras::ChargedSelector ChargedSelector
Acts::EigenStepper< Acts::EigenStepperDefaultExtension > ChargedStepper
Gaudi::Property< double > m_tolerance
Gaudi::Property< double > m_interact_minPt
StatusCode retrieveTool(ToolHandle< T > &thandle)
Gaudi::Property< bool > m_meanEnergyLoss
ServiceHandle< IAthRNGSvc > m_rngSvc
Acts::Propagator< NeutralStepper, Navigator > NeutralPropagator
virtual StatusCode simulate(const EventContext &ctx, ISFParticle &isp, ISFParticleContainer &, McEventCollection *) override
PublicToolHandle< ActsTrk::IExtrapolationTool > m_extrapolationTool
std::shared_ptr< const Acts::TrackingGeometry > m_trackingGeometry
Gaudi::Property< double > m_momentumCutOff
virtual ISF::SimulationFlavor simFlavor() const override
std::shared_ptr< const Acts::Logger > m_logger
bool checkStartSurface(const Acts::MagneticFieldContext &mctx, const Acts::GeometryContext &anygctx, const ChargedPropagator &chargedPropagator, const Acts::BoundTrackParameters &startParameters, Acts::Direction navDir=Acts::Direction::Forward(), double pathLimit=std::numeric_limits< double >::max()) const
Gaudi::Property< double > m_maxStep
Gaudi::Property< double > m_pathLimit
Gaudi::Property< double > m_stepSizeCutOff
Gaudi::Property< bool > m_loopProtection
Gaudi::Property< std::map< int, int > > m_processTypeMap
ActsTrk::ContextUtility m_ctxProvider
Context provider for geometry, magnetic field and calibration contexts.
ActsFatrasSimTool(const std::string &type, const std::string &name, const IInterface *parent)
int getATLASProcessCode(ActsFatras::GenerationProcess actspt)
virtual StatusCode setupEvent(const EventContext &) override
Setup Event chain - in case of a begin-of event action is needed.
ServiceHandle< ISF::ITruthSvc > m_truthRecordSvc
ATHRNG::RNGWrapper *m_randomEngine ATLAS_THREAD_SAFE
SiHitCollection m_pixelSiHits
Gaudi::Property< bool > m_includeGgradient
ServiceHandle< ActsTrk::ITrackingGeometrySvc > m_trackingGeometrySvc
virtual StatusCode initialize() override
PublicToolHandle< ISF::IParticleFilter > m_particleFilter
SingleParticleSimulation< ChargedPropagator, ChargedInteractions, HitSurfaceSelector, ActsFatras::NoDecay > ChargedSimulation
virtual StatusCode releaseEvent(const EventContext &ctx) override
Release Event chain - in case of an end-of event action is needed.
Amg::Vector3D convertMom3FromActs(const Acts::Vector3 &actsMom)
Convert ACTS momentum to Athena momentum.
ToolHandle< ActsFatrasWriteHandler > m_ActsFatrasWriteHandler
virtual StatusCode simulateVector(const EventContext &ctx, const ISFParticleVector &particles, ISFParticleContainer &secondaries, McEventCollection *mcEventCollection, McEventCollection *shadowTruth=nullptr) override
Simulation call for vectors of particles.
Gaudi::Property< double > m_maxRungeKuttaStepTrials
SingleParticleSimulation< NeutralPropagator, NeutralInteractions, ActsFatras::NoSurface, ActsFatras::NoDecay > NeutralSimulation
Gaudi::Property< double > m_loopFraction
ServiceHandle< ISF::IGeoIDSvc > m_geoIDSvc
ActsFatras::InteractionList< ActsFatras::PhotonConversion > NeutralInteractions
Amg::Vector3D convertPos3FromActs(const Acts::Vector3 &actsPos)
Acts::Propagator< ChargedStepper, Navigator > ChargedPropagator
Gaudi::Property< std::string > m_randomEngineName
Acts::StraightLineStepper NeutralStepper
BaseSimulatorTool(const std::string &type, const std::string &name, const IInterface *parent)
The generic ISF particle definition,.
Definition ISFParticle.h:42
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
The sim hit creator recieves a std::vector of Trk::TrackParameters and uses them to create simulated ...
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:132
constexpr double energyToAthena(const double actsE)
Converts an energy scalar from Acts to Athena units.
constexpr double lengthToAthena(const double actsL)
Converts a length scalar from Acts to Athena units.
Eigen::Matrix< double, 3, 1 > Vector3D
ISFParticleOrderedQueue.
int SimulationFlavor
Identifier type for simulation flavor.
std::list< ISF::ISFParticle * > ISFParticleContainer
generic ISFParticle container (not necessarily a std::list!)
std::vector< ISF::ISFParticle * > ISFParticleVector
ISFParticle vector.
Simple struct to select surfaces where hits should be generated.
bool operator()(const Acts::Surface &surface) const
Check if the surface should be used.
Single particle simulation with fixed propagator, interactions, and decay.
const Acts::Logger & logger() const
Provide access to the local logger instance, e.g. for logging macros.
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.