ATLAS Offline Software
Loading...
Searching...
No Matches
ActsFatrasSimTool.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 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
23
24// ACTS
25#include "Acts/Utilities/UnitVectors.hpp"
26#include "ActsInterop/Logger.h"
28#include "Acts/Geometry/GeometryContext.hpp"
29#include "Acts/MagneticField/MagneticFieldContext.hpp"
30#include "Acts/EventData/TrackParameters.hpp"
31#include "Acts/Propagator/Navigator.hpp"
32#include "Acts/Propagator/EigenStepper.hpp"
33#include "Acts/Propagator/EigenStepperDefaultExtension.hpp"
34#include "Acts/Propagator/StraightLineStepper.hpp"
35#include "Acts/Propagator/detail/SteppingLogger.hpp"
36#include "Acts/Propagator/ActorList.hpp"
37#include "Acts/Propagator/Propagator.hpp"
38#include "Acts/Definitions/ParticleData.hpp"
39#include "ActsFatras/EventData/ProcessType.hpp"
40#include "ActsFatras/Kernel/InteractionList.hpp"
41#include "ActsFatras/Kernel/Simulation.hpp"
42#include "ActsFatras/Kernel/SimulationResult.hpp"
43#include "ActsFatras/Physics/Decay/NoDecay.hpp"
44#include "ActsFatras/Physics/StandardInteractions.hpp"
45#include "ActsFatras/Physics/ElectroMagnetic/PhotonConversion.hpp"
46#include "ActsFatras/Selectors/SurfaceSelectors.hpp"
47// Tracking
50
51#include <algorithm>
52#include <cassert>
53#include <vector>
54
55class AtlasDetectorID;
56
57namespace iFatras {
58 class ISimHitCreator;
59}
60
61namespace ISF {
62class IParticleHelper;
63
69
71
72 public:
76 bool operator()(const Acts::Surface &surface) const {
77 bool isSensitive = surface.associatedDetectorElement() != nullptr;
78 return isSensitive;
79 }
80 };
81 // SingleParticleSimulation
88 template <typename propagator_t, typename interactions_t,
89 typename hit_surface_selector_t, typename decay_t>
92 propagator_t propagator;
94 decay_t decay;
96 interactions_t interactions;
98 hit_surface_selector_t selectHitSurface;
100 double maxStepSize = 3.0; // leght in m
101 double maxStep = 1000;
103 double pathLimit = 100.0; // lenght in cm
104 bool loopProtection = true;
105 double loopFraction = 0.5;
106 double targetTolerance = 0.0001;
107 double stepSizeCutOff = 0.;
108 // parameters for densEnv propagator options
109 double meanEnergyLoss = true;
110 bool includeGgradient = true;
111 double momentumCutOff = 0.;
112
114 std::shared_ptr<const Acts::Logger> localLogger = nullptr;
115
117 SingleParticleSimulation(propagator_t &&propagator_,
118 std::shared_ptr<const Acts::Logger> localLogger_)
119 : propagator(propagator_), localLogger(localLogger_) {}
120
122 const Acts::Logger &logger() const { return *localLogger; }
123
133 template <typename generator_t>
134 Acts::Result<ActsFatras::SimulationResult> simulate(
135 const Acts::GeometryContext &geoCtx,
136 const Acts::MagneticFieldContext &magCtx, generator_t &generator,
137 const ActsFatras::Particle &particle) const {
138 assert(localLogger and "Missing local logger");
139 ACTS_VERBOSE("Using ActsFatrasSimTool simulate()");
140 // propagator-related additional types
141 using SteppingLogger = Acts::detail::SteppingLogger;
142 using SimulationActor = ActsFatras::detail::SimulationActor<generator_t, decay_t, interactions_t, hit_surface_selector_t>;
143 using Result = typename SimulationActor::result_type;
144 using Actions = Acts::ActorList<SteppingLogger, SimulationActor, Acts::EndOfWorldReached>;
145 using PropagatorOptions = typename propagator_t::template Options<Actions>;
146
147 // Construct per-call options.
148 PropagatorOptions options(geoCtx, magCtx);
149 // setup the interactor as part of the propagator options
150 auto &actor = options.actorList.template get<SimulationActor>();
151 actor.generator = &generator;
152 actor.decay = decay;
153 actor.interactions = interactions;
154 actor.selectHitSurface = selectHitSurface;
155 actor.initialParticle = particle;
156 // use AnyCharge to be able to handle neutral and charged parameters
157 Acts::BoundTrackParameters startPoint = Acts::BoundTrackParameters::createCurvilinear(
158 particle.fourPosition(), particle.direction(),
159 particle.qOverP(), std::nullopt, particle.hypothesis());
160 options.pathLimit = pathLimit * Acts::UnitConstants::cm;
161 options.loopProtection = loopProtection;
162 options.maxSteps = maxStep;
163 options.stepping.maxStepSize = maxStepSize * Acts::UnitConstants::m;
164
165 auto result = propagator.propagate(startPoint, options);
166 if (not result.ok()) {
167 return result.error();
168 }
169 return result.value().template get<Result>();
170 }
171 };// end of SingleParticleSimulation
172
173 // Standard generator
174 using Generator = std::ranlux48;
175 // Use default navigator
176 using Navigator = Acts::Navigator;
177 // Propagate charged particles numerically in the B-field
178 using ChargedStepper = Acts::EigenStepper<Acts::EigenStepperDefaultExtension>;
179 using ChargedPropagator = Acts::Propagator<ChargedStepper, Navigator>;
180 // Propagate neutral particles in straight lines
181 using NeutralStepper = Acts::StraightLineStepper;
182 using NeutralPropagator = Acts::Propagator<NeutralStepper, Navigator>;
183
184 // ===============================
185 // Setup ActsFatras simulator types
186 // Charged
187 using ChargedSelector = ActsFatras::ChargedSelector;
189 ActsFatras::StandardChargedElectroMagneticInteractions;
192 ActsFatras::NoDecay>;
193 // Neutral
194 using NeutralSelector = ActsFatras::NeutralSelector;
195 using NeutralInteractions = ActsFatras::InteractionList<ActsFatras::PhotonConversion>;
197 NeutralPropagator, NeutralInteractions, ActsFatras::NoSurface,
198 ActsFatras::NoDecay>;
199 // Combined
200 using Simulation = ActsFatras::Simulation<ChargedSelector, ChargedSimulation,
202 // ===============================
203
204 ActsFatrasSimTool(const std::string& type, const std::string& name,
205 const IInterface* parent);
206 virtual ~ActsFatrasSimTool();
207
208 // ISF BaseSimulatorTool Interface methods
209 virtual StatusCode initialize() override;
210 virtual StatusCode simulate(const EventContext& ctx, ISFParticle& isp, ISFParticleContainer&,
211 McEventCollection*) override;
212 virtual StatusCode simulateVector(
213 const EventContext& ctx,
214 const ISFParticleVector& particles,
215 ISFParticleContainer& secondaries,
216 McEventCollection* mcEventCollection, McEventCollection *shadowTruth=nullptr) override;
217 virtual StatusCode setupEvent(const EventContext&) override {
218 ATH_CHECK(m_truthRecordSvc->initializeTruthCollection());
219 m_pixelSiHits.Clear();
220 m_sctSiHits.Clear();
221 return StatusCode::SUCCESS; };
222 virtual StatusCode releaseEvent(const EventContext& ctx) override {
223 std::vector<SiHitCollection> hitcolls;
224 hitcolls.push_back(m_pixelSiHits);
225 hitcolls.push_back(m_sctSiHits);
226 ATH_CHECK(m_ActsFatrasWriteHandler->WriteHits(hitcolls,ctx));
227 ATH_CHECK(m_truthRecordSvc->releaseEvent());
228 return StatusCode::SUCCESS; };
229 virtual ISF::SimulationFlavor simFlavor() const override{
230 return ISF::Fatras; };
231
232 virtual Acts::MagneticFieldContext getMagneticFieldContext(
233 const EventContext&) const;
234
235 private:
236 // For sihit creation
239 // Templated tool retrieval
240 template <class T>
241 StatusCode retrieveTool(ToolHandle<T>& thandle) {
242 if (!thandle.empty() && thandle.retrieve().isFailure()) {
243 ATH_MSG_FATAL("Cannot retrieve " << thandle << ". Abort.");
244 return StatusCode::FAILURE;
245 } else ATH_MSG_DEBUG("Successfully retrieved " << thandle);
246 return StatusCode::SUCCESS;
247 }
248
249 // Random number service
250 ServiceHandle<IAthRNGSvc> m_rngSvc{this, "RNGService", "AthRNGSvc"};
252 Gaudi::Property<std::string> m_randomEngineName{this, "RandomEngineName",
253 "RandomEngineName", "Name of random number stream"};
254
255 // Tracking geometry
256 PublicToolHandle<ActsTrk::ITrackingGeometryTool> m_trackingGeometryTool{
257 this, "TrackingGeometryTool", "ActsTrackingGeometryTool"};
258 std::shared_ptr<const Acts::TrackingGeometry> m_trackingGeometry;
259
260 // Magnetic field
261 SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCacheCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"};
262
263 // Logging
264 std::shared_ptr<const Acts::Logger> m_logger{nullptr};
265
266 // ISF Tools
267 PublicToolHandle<ISF::IParticleFilter> m_particleFilter{
268 this, "ParticleFilter", "", "Particle filter kinematic cuts, etc."};
269
270 ServiceHandle<ISF::ITruthSvc> m_truthRecordSvc{this, "TruthRecordService", "ISF_TruthRecordSvc", ""};
271
272 // ActsFatrasHitConvtTool
273 ToolHandle<ActsFatrasWriteHandler> m_ActsFatrasWriteHandler{
274 this, "ActsFatrasWriteHandler", "ActsFatrasWriteHandler"};
275
276 Gaudi::Property<double> m_interact_minPt{this, "Interact_MinPt", 50.0,
277 "Min pT of the interactions (MeV)"};
278
279 // DensEnviroment Propergator option
280 Gaudi::Property<bool> m_meanEnergyLoss{this, "MeanEnergyLoss", true, "Toggle between mean and mode evaluation of energy loss"};
281 Gaudi::Property<bool> m_includeGgradient{this, "IncludeGgradient", true, "Boolean flag for inclusion of d(dEds)d(q/p) into energy loss"};
282 Gaudi::Property<double> m_momentumCutOff{this, "MomentumCutOff", 0., "Cut-off value for the momentum in SI units"};
283 // Propergator option
284 Gaudi::Property<double> m_maxStep{this, "MaxSteps", 1000,
285 "Max number of steps"};
286 Gaudi::Property<double> m_maxRungeKuttaStepTrials{this, "MaxRungeKuttaStepTrials", 10000,
287 "Maximum number of Runge-Kutta steps for the stepper step call"};
288 Gaudi::Property<double> m_maxStepSize{this, "MaxStepSize", 3.0,
289 "Max step size (converted to Acts::UnitConstants::m)"};
290 Gaudi::Property<double> m_pathLimit{this, "PathLimit", 100.0,
291 "Track path limit (converted to Acts::UnitConstants::cm)"};
292 Gaudi::Property<bool> m_loopProtection{this, "LoopProtection", true,
293 "Loop protection, it adapts the pathLimit"};
294 Gaudi::Property<double> m_loopFraction{this, "LoopFraction", 0.5,
295 "Allowed loop fraction, 1 is a full loop"};
296 Gaudi::Property<double> m_tolerance{this, "Tolerance", 0.0001,
297 "Tolerance for the error of the integration"};
298 Gaudi::Property<double> m_stepSizeCutOff{this, "StepSizeCutOff", 0.,
299 "Cut-off value for the step size"};
300
301 Gaudi::Property<std::map<int,int>> m_processTypeMap{this, "ProcessTypeMap",
302 {{0,0}, {1,201}, {2,14}, {3,3}, {4,121}}, "proessType map <ActsFatras,G4>"};
303 //{{ActsProcessType::eUndefined,0}, {ActsProcessType::eDecay,201}, {ActsProcessType::ePhotonConversion,14}, {ActsProcessType::eBremsstrahlung,3}, {ActsProcessType::eNuclearInteraction,121}}
304 inline int getATLASProcessCode(ActsFatras::ProcessType actspt){return m_processTypeMap[static_cast<uint32_t>(actspt)];};
305};
306
307} // namespace ISF
308
309#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
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
ActsFatras::NeutralSelector NeutralSelector
Gaudi::Property< double > m_maxStepSize
ActsFatras::ChargedSelector ChargedSelector
Acts::EigenStepper< Acts::EigenStepperDefaultExtension > ChargedStepper
PublicToolHandle< ActsTrk::ITrackingGeometryTool > m_trackingGeometryTool
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
SingleParticleSimulation< NeutralPropagator, NeutralInteractions, ActsFatras::NoSurface, ActsFatras::NoDecay > NeutralSimulation
Acts::Propagator< NeutralStepper, Navigator > NeutralPropagator
virtual StatusCode simulate(const EventContext &ctx, ISFParticle &isp, ISFParticleContainer &, McEventCollection *) override
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
Gaudi::Property< double > m_maxStep
int getATLASProcessCode(ActsFatras::ProcessType actspt)
Gaudi::Property< double > m_pathLimit
Gaudi::Property< double > m_stepSizeCutOff
Gaudi::Property< bool > m_loopProtection
Gaudi::Property< std::map< int, int > > m_processTypeMap
ActsFatrasSimTool(const std::string &type, const std::string &name, const IInterface *parent)
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
SingleParticleSimulation< ChargedPropagator, ChargedInteractions, HitSurfaceSelector, ActsFatras::NoDecay > ChargedSimulation
virtual StatusCode initialize() override
PublicToolHandle< ISF::IParticleFilter > m_particleFilter
virtual StatusCode releaseEvent(const EventContext &ctx) override
Release Event chain - in case of an end-of event action is needed.
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
virtual Acts::MagneticFieldContext getMagneticFieldContext(const EventContext &) const
Gaudi::Property< double > m_loopFraction
ActsFatras::InteractionList< ActsFatras::PhotonConversion > NeutralInteractions
ActsFatras::StandardChargedElectroMagneticInteractions ChargedInteractions
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:130
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::SimulationResult > 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.