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
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/TrackParameters.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/ProcessType.hpp"
43#include "ActsFatras/Kernel/InteractionList.hpp"
44#include "ActsFatras/Kernel/Simulation.hpp"
45#include "ActsFatras/Kernel/SimulationResult.hpp"
46#include "ActsFatras/Physics/Decay/NoDecay.hpp"
47#include "ActsFatras/Physics/StandardInteractions.hpp"
48#include "ActsFatras/Physics/ElectroMagnetic/PhotonConversion.hpp"
49#include "ActsFatras/Selectors/SurfaceSelectors.hpp"
50// Tracking
53
54#include <algorithm>
55#include <cassert>
56#include <vector>
57
58class AtlasDetectorID;
59
60namespace iFatras {
61 class ISimHitCreator;
62}
63
64namespace ISF {
65class IParticleHelper;
66
72
74
75 public:
79 bool operator()(const Acts::Surface &surface) const {
80 return surface.isSensitive();
81 }
82 };
83 // SingleParticleSimulation
90 template <typename propagator_t, typename interactions_t,
91 typename hit_surface_selector_t, typename decay_t>
94 propagator_t propagator;
96 decay_t decay;
98 interactions_t interactions;
100 hit_surface_selector_t selectHitSurface;
102 double maxStepSize = 3.0; // leght in m
103 double maxStep = 1000;
105 double pathLimit = 100.0; // lenght in cm
106 bool loopProtection = true;
107 double loopFraction = 0.5;
108 double targetTolerance = 0.0001;
109 double stepSizeCutOff = 0.;
110 // parameters for densEnv propagator options
111 double meanEnergyLoss = true;
112 bool includeGgradient = true;
113 double momentumCutOff = 0.;
114
116 std::shared_ptr<const Acts::Logger> localLogger = nullptr;
117
119 SingleParticleSimulation(propagator_t &&propagator_,
120 std::shared_ptr<const Acts::Logger> localLogger_)
121 : propagator(propagator_), localLogger(localLogger_) {}
122
124 const Acts::Logger &logger() const { return *localLogger; }
125
135 template <typename generator_t>
136 Acts::Result<ActsFatras::SimulationResult> simulate(
137 const Acts::GeometryContext &geoCtx,
138 const Acts::MagneticFieldContext &magCtx, generator_t &generator,
139 const ActsFatras::Particle &particle) const {
140 assert(localLogger and "Missing local logger");
141 ACTS_VERBOSE("Using ActsFatrasSimTool simulate()");
142 // propagator-related additional types
143 using SteppingLogger = Acts::detail::SteppingLogger;
144 using SimulationActor = ActsFatras::detail::SimulationActor<generator_t, decay_t, interactions_t, hit_surface_selector_t>;
145 using Result = typename SimulationActor::result_type;
146 using Actions = Acts::ActorList<SteppingLogger, SimulationActor, Acts::EndOfWorldReached>;
147 using PropagatorOptions = typename propagator_t::template Options<Actions>;
148
149 // Construct per-call options.
150 PropagatorOptions options(geoCtx, magCtx);
151 // setup the interactor as part of the propagator options
152 auto &actor = options.actorList.template get<SimulationActor>();
153 actor.generator = &generator;
154 actor.decay = decay;
155 actor.interactions = interactions;
156 actor.selectHitSurface = selectHitSurface;
157 actor.initialParticle = particle;
158 // use AnyCharge to be able to handle neutral and charged parameters
159 Acts::BoundTrackParameters startPoint = Acts::BoundTrackParameters::createCurvilinear(
160 particle.fourPosition(), particle.direction(),
161 particle.qOverP(), std::nullopt, particle.hypothesis());
162 options.pathLimit = pathLimit * Acts::UnitConstants::cm;
163 options.loopProtection = loopProtection;
164 options.maxSteps = maxStep;
165 options.stepping.maxStepSize = maxStepSize * Acts::UnitConstants::m;
166 options.direction = Acts::Direction::Forward();
167
168 auto result = propagator.propagate(startPoint, options);
169 if (not result.ok()) {
170 return result.error();
171 }
172 return result.value().template get<Result>();
173 }
174 };// end of SingleParticleSimulation
175
176 // Standard generator
177 using Generator = std::ranlux48;
178 // Use default navigator
179 using Navigator = Acts::Navigator;
180 // Propagate charged particles numerically in the B-field
181 using ChargedStepper = Acts::EigenStepper<Acts::EigenStepperDefaultExtension>;
182 using ChargedPropagator = Acts::Propagator<ChargedStepper, Navigator>;
183 // Propagate neutral particles in straight lines
184 using NeutralStepper = Acts::StraightLineStepper;
185 using NeutralPropagator = Acts::Propagator<NeutralStepper, Navigator>;
186
187 // ===============================
188 // Setup ActsFatras simulator types
189 // Charged
190 using ChargedSelector = ActsFatras::ChargedSelector;
192 ActsFatras::StandardChargedElectroMagneticInteractions;
195 ActsFatras::NoDecay>;
196 // Neutral
197 using NeutralSelector = ActsFatras::NeutralSelector;
198 using NeutralInteractions = ActsFatras::InteractionList<ActsFatras::PhotonConversion>;
200 NeutralPropagator, NeutralInteractions, ActsFatras::NoSurface,
201 ActsFatras::NoDecay>;
202 // Combined
203 using Simulation = ActsFatras::Simulation<ChargedSelector, ChargedSimulation,
205 // ===============================
207 inline Amg::Vector3D convertMom3FromActs(const Acts::Vector3& actsMom) {
208 Amg::Vector3D threeMom{Amg::Vector3D::Zero()};
209 threeMom[Amg::x] = ActsTrk::energyToAthena(actsMom[Acts::eMom0]);
210 threeMom[Amg::y] = ActsTrk::energyToAthena(actsMom[Acts::eMom1]);
211 threeMom[Amg::z] = ActsTrk::energyToAthena(actsMom[Acts::eMom2]);
212 return threeMom;
213 }
214
215 inline Amg::Vector3D convertPos3FromActs(const Acts::Vector3& actsPos) {
216 Amg::Vector3D pos{Amg::Vector3D::Zero()};
217 pos[Amg::x] = ActsTrk::lengthToAthena(actsPos[Acts::ePos0]);
218 pos[Amg::y] = ActsTrk::lengthToAthena(actsPos[Acts::ePos1]);
219 pos[Amg::z] = ActsTrk::lengthToAthena(actsPos[Acts::ePos2]);
220 return pos;
221 }
222
223 ActsFatrasSimTool(const std::string& type, const std::string& name,
224 const IInterface* parent);
225 virtual ~ActsFatrasSimTool();
226
227 // ISF BaseSimulatorTool Interface methods
228 virtual StatusCode initialize() override;
229 virtual StatusCode simulate(const EventContext& ctx, ISFParticle& isp, ISFParticleContainer&,
230 McEventCollection*) override;
231 virtual StatusCode simulateVector(
232 const EventContext& ctx,
233 const ISFParticleVector& particles,
234 ISFParticleContainer& secondaries,
235 McEventCollection* mcEventCollection, McEventCollection *shadowTruth=nullptr) override;
236 virtual StatusCode setupEvent(const EventContext&) override {
237 ATH_CHECK(m_truthRecordSvc->initializeTruthCollection());
238 m_pixelSiHits.Clear();
239 m_sctSiHits.Clear();
240 return StatusCode::SUCCESS; };
241 virtual StatusCode releaseEvent(const EventContext& ctx) override {
242 std::vector<SiHitCollection> hitcolls;
243 hitcolls.push_back(m_pixelSiHits);
244 hitcolls.push_back(m_sctSiHits);
245 ATH_CHECK(m_ActsFatrasWriteHandler->WriteHits(hitcolls,ctx));
246 ATH_CHECK(m_truthRecordSvc->releaseEvent());
247 return StatusCode::SUCCESS; };
248 virtual ISF::SimulationFlavor simFlavor() const override{
249 return ISF::Fatras; };
250
251 virtual Acts::MagneticFieldContext getMagneticFieldContext(
252 const EventContext&) const;
253
254 private:
255 // For sihit creation
258 // Templated tool retrieval
259 template <class T>
260 StatusCode retrieveTool(ToolHandle<T>& thandle) {
261 if (!thandle.empty() && thandle.retrieve().isFailure()) {
262 ATH_MSG_FATAL("Cannot retrieve " << thandle << ". Abort.");
263 return StatusCode::FAILURE;
264 } else ATH_MSG_DEBUG("Successfully retrieved " << thandle);
265 return StatusCode::SUCCESS;
266 }
267
268 bool checkStartSurface(const Acts::MagneticFieldContext& mctx,
269 const Acts::GeometryContext& anygctx,
270 const ChargedPropagator& chargedPropagator,
271 const Acts::BoundTrackParameters& startParameters,
272 Acts::Direction navDir = Acts::Direction::Forward(),
273 double pathLimit = std::numeric_limits<double>::max()) const;
274
275 // Random number service
276 ServiceHandle<IAthRNGSvc> m_rngSvc{this, "RNGService", "AthRNGSvc"};
278 Gaudi::Property<std::string> m_randomEngineName{this, "RandomEngineName",
279 "RandomEngineName", "Name of random number stream"};
280
281 // GeoID service
282 ServiceHandle<ISF::IGeoIDSvc> m_geoIDSvc{this, "GeoIDSvc", "ISF::GeoIDSvc"};
283
284 // ACTS Extrapolator
285 PublicToolHandle<ActsTrk::IExtrapolationTool> m_extrapolationTool{this, "ExtrapolationTool", "ActsExtrapolationTool"};
286
287 // Tracking geometry
288 PublicToolHandle<ActsTrk::ITrackingGeometryTool> m_trackingGeometryTool{
289 this, "TrackingGeometryTool", "ActsTrackingGeometryTool"};
290 std::shared_ptr<const Acts::TrackingGeometry> m_trackingGeometry;
291
292 // Magnetic field
293 SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCacheCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"};
294
295 // Logging
296 std::shared_ptr<const Acts::Logger> m_logger{nullptr};
297
298 // ISF Tools
299 PublicToolHandle<ISF::IParticleFilter> m_particleFilter{
300 this, "ParticleFilter", "", "Particle filter kinematic cuts, etc."};
301
302 ServiceHandle<ISF::ITruthSvc> m_truthRecordSvc{this, "TruthRecordService", "ISF_TruthRecordSvc", ""};
303
304 // ActsFatrasHitConvtTool
305 ToolHandle<ActsFatrasWriteHandler> m_ActsFatrasWriteHandler{
306 this, "ActsFatrasWriteHandler", "ActsFatrasWriteHandler"};
307
308 Gaudi::Property<double> m_interact_minPt{this, "Interact_MinPt", 50.0,
309 "Min pT of the interactions (MeV)"};
310
311 // DensEnviroment Propergator option
312 Gaudi::Property<bool> m_meanEnergyLoss{this, "MeanEnergyLoss", true, "Toggle between mean and mode evaluation of energy loss"};
313 Gaudi::Property<bool> m_includeGgradient{this, "IncludeGgradient", true, "Boolean flag for inclusion of d(dEds)d(q/p) into energy loss"};
314 Gaudi::Property<double> m_momentumCutOff{this, "MomentumCutOff", 0., "Cut-off value for the momentum in SI units"};
315 // Propergator option
316 Gaudi::Property<double> m_maxStep{this, "MaxSteps", 1000,
317 "Max number of steps"};
318 Gaudi::Property<double> m_maxRungeKuttaStepTrials{this, "MaxRungeKuttaStepTrials", 10000,
319 "Maximum number of Runge-Kutta steps for the stepper step call"};
320 Gaudi::Property<double> m_maxStepSize{this, "MaxStepSize", 3.0,
321 "Max step size (converted to Acts::UnitConstants::m)"};
322 Gaudi::Property<double> m_pathLimit{this, "PathLimit", 100.0,
323 "Track path limit (converted to Acts::UnitConstants::cm)"};
324 Gaudi::Property<bool> m_loopProtection{this, "LoopProtection", true,
325 "Loop protection, it adapts the pathLimit"};
326 Gaudi::Property<double> m_loopFraction{this, "LoopFraction", 0.5,
327 "Allowed loop fraction, 1 is a full loop"};
328 Gaudi::Property<double> m_tolerance{this, "Tolerance", 0.0001,
329 "Tolerance for the error of the integration"};
330 Gaudi::Property<double> m_stepSizeCutOff{this, "StepSizeCutOff", 0.,
331 "Cut-off value for the step size"};
332
333 // https://vmc-project.github.io/geant4_vmc/g4vmc_html/TG4ProcessMapPhysics_8cxx_source.html#:~:text=155%20pMap%2D%3EAdd(DECAY,);%20//%20G4%20value:%20231
334 Gaudi::Property<std::map<int,int>> m_processTypeMap{this, "ProcessTypeMap",
335 {{0,0}, {1,201}, {2,14}, {3,3}, {4,121}}, "proessType map <ActsFatras,G4>"};
336 //{{ActsProcessType::eUndefined,0}, {ActsProcessType::eDecay,201}, {ActsProcessType::ePhotonConversion,14}, {ActsProcessType::eBremsstrahlung,3}, {ActsProcessType::eNuclearInteraction,121}}
337 inline int getATLASProcessCode(ActsFatras::ProcessType actspt){return m_processTypeMap[static_cast<uint32_t>(actspt)];};
338};
339
340} // namespace ISF
341
342#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
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
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.
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
virtual Acts::MagneticFieldContext getMagneticFieldContext(const EventContext &) const
Gaudi::Property< double > m_loopFraction
ServiceHandle< ISF::IGeoIDSvc > m_geoIDSvc
ActsFatras::InteractionList< ActsFatras::PhotonConversion > NeutralInteractions
ActsFatras::StandardChargedElectroMagneticInteractions ChargedInteractions
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:130
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::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.