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