ATLAS Offline Software
Loading...
Searching...
No Matches
ActsFatrasSimTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4#include <algorithm>
5#include <random>
6
7#include "ActsFatrasSimTool.h"
8#include "Acts/ActsVersion.hpp"
9#include <Acts/Utilities/StringHelpers.hpp>
10#include "Acts/Definitions/PdgParticle.hpp"
11
12#include "CLHEP/Random/RandFlat.h"
13#include "CLHEP/Random/RandomEngine.h"
14
17
18using namespace Acts::UnitLiterals;
19
21 const std::string& name,
22 const IInterface* parent)
23 : BaseSimulatorTool(type, name, parent) {}
24
26
29 ATH_CHECK(m_ctxProvider.initialize());
30 ATH_MSG_INFO("ISF::ActsFatrasSimTool update with ACTS version: v"
31 << Acts::VersionMajor << "." << Acts::VersionMinor << "."
32 << Acts::VersionPatch << " [" << Acts::CommitHash.value_or("unknown hash") << "]");
33 // Retrieve particle filter
34 ATH_CHECK(m_particleFilter.retrieve());
35 ATH_MSG_INFO("Using particle filter: " << m_particleFilter.typeAndName());
36 // setup logger
37 m_logger = makeActsAthenaLogger(this, std::string("ActsFatras"),std::string("ActsFatrasSimTool"));
38
39 // Geometry identifier service
40 if ( !m_geoIDSvc.empty() && m_geoIDSvc.retrieve().isFailure()){
41 ATH_MSG_FATAL ("Could not retrieve " << m_geoIDSvc);
42 return StatusCode::FAILURE;
43 }
44
45 // retrive tracking geo tool
47 m_trackingGeometry = m_trackingGeometrySvc->trackingGeometry();
48
49 // Acts Extrapolator
51 ATH_MSG_INFO( "- ActsExtrapolationTool : " << m_extrapolationTool.typeAndName() );
52
53 //retrive Magnetfield tool
54 ATH_MSG_VERBOSE("Using ATLAS magnetic field service");
55
56 // Random number service
57 if (m_rngSvc.retrieve().isFailure()) {
58 ATH_MSG_FATAL("Could not retrieve " << m_rngSvc);
59 return StatusCode::FAILURE;
60 }
61 // Get own engine with own seeds
62 m_randomEngine = m_rngSvc->getEngine(this, m_randomEngineName.value());
63 if (!m_randomEngine) {
64 ATH_MSG_FATAL("Could not get random engine '" << m_randomEngineName.value() << "'");
65 return StatusCode::FAILURE;
66 }
67
68 // ISF truth service
69 ATH_CHECK (m_truthRecordSvc.retrieve());
70 ATH_MSG_DEBUG( "- Using ISF TruthRecordSvc : " << m_truthRecordSvc.typeAndName() );
71 return StatusCode::SUCCESS;
72}
73
74StatusCode ISF::ActsFatrasSimTool::simulate(const EventContext& ctx,
75 ISFParticle& isp, ISFParticleContainer& secondaries,
76 McEventCollection* mcEventCollection) {
77 ATH_MSG_VERBOSE("Particle " << isp << " received for simulation.");
78 // Check if particle passes filter, if there is one
79 if (!m_particleFilter.empty() && !m_particleFilter->passFilter(isp)) {
80 ATH_MSG_VERBOSE("ISFParticle " << isp << " does not pass selection. Ignoring.");
81 return StatusCode::SUCCESS;
82 }
83 // Process ParticleState from particle stack
84 // Wrap the input ISFParticle in an STL vector with size of 1
85 const ISF::ISFParticleVector ispVector(1, &isp);
86 ATH_CHECK(this->simulateVector(ctx, ispVector, secondaries, mcEventCollection));
87 ATH_MSG_VERBOSE("Simulation done");
88 return StatusCode::SUCCESS;
89}
90
92 const EventContext& ctx,
93 const ISFParticleVector& particles,
94 ISFParticleContainer& secondaries,
95 McEventCollection* /*mcEventCollection*/, McEventCollection *) {
96 // filter particles
97 std::vector<ISFParticle*> selectedParticles;
98 for (const auto isfp : particles) {
99 if (!m_particleFilter.empty() && !m_particleFilter->passFilter(*isfp)) {
100 ATH_MSG_VERBOSE("ISFParticle " << *isfp << " does not pass selection. Ignoring.");
101 continue;
102 }
103 selectedParticles.push_back(isfp);
104 }
105 if (selectedParticles.empty()) {
106 ATH_MSG_VERBOSE("No particles passed selection. Ignoring.");
107 return StatusCode::SUCCESS;
108 }
109 // Set random seed for current event
110 m_randomEngine->setSeed(m_randomEngineName, ctx);
111 CLHEP::HepRandomEngine* randomEngine = m_randomEngine->getEngine(ctx);
112 Generator generator(CLHEP::RandFlat::shoot(randomEngine->flat()));
113 ATH_MSG_VERBOSE(name() << " RNG seed " << CLHEP::RandFlat::shoot(randomEngine->flat()));
114 ATH_MSG_VERBOSE(name() << " received vector of size "
115 << selectedParticles.size() << " particles for simulation.");
116
117 // construct the ACTS simulator
118 Acts::Navigator navigator( Acts::Navigator::Config{ m_trackingGeometry }, m_logger);
119 auto bField = std::make_shared<ATLASMagneticFieldWrapper>();
120 auto chargedStepper = ChargedStepper(std::move(bField));
121 auto neutralStepper = NeutralStepper();
122 auto chargedPropagator = ChargedPropagator(chargedStepper, navigator, m_logger);
123 auto neutralPropagator = NeutralPropagator(neutralStepper, navigator, m_logger);
124 ChargedSimulation simulatorCharged(std::move(chargedPropagator), m_logger);
125 NeutralSimulation simulatorNeutral(std::move(neutralPropagator), m_logger);
126 Simulation simulator=Simulation(std::move(simulatorCharged),std::move(simulatorNeutral));
127 ATH_MSG_VERBOSE(name() << " Min pT for interaction " << m_interact_minPt * Acts::UnitConstants::MeV << " GeV");
128 // Acts propagater options
129 simulator.charged.maxStepSize = m_maxStepSize;
130 simulator.charged.maxStep = m_maxStep;
131 simulator.charged.pathLimit = m_pathLimit;
132 simulator.charged.maxRungeKuttaStepTrials = m_maxRungeKuttaStepTrials;
133 simulator.charged.loopProtection = m_loopProtection;
134 simulator.charged.loopFraction = m_loopFraction;
135 simulator.charged.targetTolerance = m_tolerance;
136 simulator.charged.stepSizeCutOff = m_stepSizeCutOff;
137 // Create interaction list
138 simulator.charged.interactions = ActsFatras::makeStandardChargedElectroMagneticInteractions(m_interact_minPt * Acts::UnitConstants::MeV);
139
140 // Construct the ACTS propagator for starting surface check
141 auto surfaceCheckPropagator = ChargedPropagator(chargedStepper, navigator);
142
143 // get Geo and Mag map
144 ATH_MSG_VERBOSE(name() << " Getting per event Geo and Mag map");
145 auto mctx = m_ctxProvider.getMagneticFieldContext(ctx);
146 auto anygctx = m_ctxProvider.getGeometryContext(ctx);
147 // Loop over ISFParticleVector and process each separately
148 ATH_MSG_VERBOSE(name() << " Processing particles in ISFParticleVector.");
149 for (const auto isfp : selectedParticles) {
150 // ====ACTSFatras Simulation====
151 // //
152 // input/output particle and hits containers
153 // Convert to ActsFatras::Particle
154 // ISF: Energy, mass, and momentum are in MeV, position in mm
155 // Acts: Energy, mass, and momentum are in GeV, position in mm
156 ATH_MSG_DEBUG(name() << " Convert ISF::Particle(mass) " << isfp->id()<<"|" << *isfp<<"(" << isfp->mass() << ")");
157 std::vector<ActsFatras::Particle> input = std::vector<ActsFatras::Particle>{
158 ActsFatras::Particle(ActsFatras::Barcode().withVertexPrimary(0).withParticle(isfp->id()), static_cast<Acts::PdgParticle>(isfp->pdgCode()),
159 isfp->charge(),isfp->mass() * Acts::UnitConstants::MeV)
160 .setDirection(Acts::makeDirectionFromPhiEta(isfp->momentum().phi(), isfp->momentum().eta()))
161 .setAbsoluteMomentum(isfp->momentum().mag() * Acts::UnitConstants::MeV)
162 .setPosition4(ActsTrk::convertPosToActs(isfp->position(), isfp->timeStamp()))};
163 ATH_MSG_DEBUG(name() << " Propagating ActsFatras::Particle vertex|particle|generation|subparticle, " << input[0]);
164 std::vector<ActsFatras::Particle> simulatedInitial;
165 std::vector<ActsFatras::Particle> simulatedFinal;
166 std::vector<ActsFatras::Hit> hits;
167 // simulate
168 auto result=simulator.simulate(anygctx, mctx, generator, input, simulatedInitial, simulatedFinal, hits);
169 auto simulatedFailure=result.value();
170 if (simulatedFailure.size()>0){
171 for (const auto& simfail : simulatedFailure){
172 auto errCode = Acts::make_error_code(Acts::PropagatorError(simfail.error.value()));
173 ATH_MSG_WARNING(name() << " Particle id " <<simfail.particle.particleId()<< ": fail to be simulated during Propagation: " << errCode.message());
174 ATH_MSG_WARNING(name() << " Particle vertex|particle|generation|subparticle"<<simfail.particle << " starts from position" << Acts::toString(simfail.particle.position()) << " and direction " << Acts::toString(simfail.particle.direction()));
175 return StatusCode::SUCCESS;
176 }
177 }
178
179 ATH_MSG_DEBUG(name() << " initial particle " << simulatedInitial[0]);
180 ATH_MSG_DEBUG(name() << " ActsFatras simulator hits: " << hits.size());
181 int i = 0;
182 for (const auto& hit : hits) {
183 ATH_MSG_DEBUG(name() << " hit pos: " << hit.position() );
184 ++i;
185 if (i>5) break;
186 }
187 ATH_MSG_DEBUG(name() << " No. of particles after ActsFatras simulator: " << simulatedFinal.size());
188 if (!simulatedFinal.empty()){
189 ATH_MSG_DEBUG(name() << " start procesing secondaries");
190 auto itr = simulatedFinal.begin();
191 // Save hits of isfp
192 std::vector<ActsFatras::Hit> particle_hits;
193 if (itr->numberOfHits() > 0) {
194 std::copy(hits.begin(), hits.begin()+itr->numberOfHits(), std::back_inserter(particle_hits));
196 }
197 // Process secondaries
198 auto isKilled = !itr->isAlive();
199 int maxGeneration = simulatedFinal.back().particleId().generation();
200 ATH_MSG_DEBUG(name() << " maxGeneration: "<< maxGeneration);
201 for (int gen = 0; gen <= maxGeneration; ++gen){
202 ATH_MSG_DEBUG(name() << " start with generation "<< gen << "|" << maxGeneration << ": "<< *itr);
203 auto vecsecisfp = std::make_unique<ISF::ISFParticleVector>();
204 std::unique_ptr<ISF::ISFParticle> newisfp = nullptr; // Boundary crossing particle
205
206 while (itr != simulatedFinal.end() && static_cast<int>(itr->particleId().generation()) == gen) {
207 ATH_MSG_DEBUG(name() << " genration "<< gen << "|" << maxGeneration << ": "<< *itr);
208 if(itr->isSecondary()){
209 // convert final particles to ISF::particle
210 const auto pos = ActsTrk::convertPosFromActs(itr->fourPosition()).first;
211 const auto mom = ActsTrk::convertMomFromActs(itr->fourMomentum()).first;
212 double mass = itr->mass() / Acts::UnitConstants::MeV;
213 double charge = itr->charge();
214 int pdgid = itr->pdg();
215 auto properTime = ActsTrk::timeToAthena(itr->time());
216 const int status = 1 + HepMC::SIM_STATUS_THRESHOLD;
217 const int id = HepMC::UNDEFINED_ID;
218 auto secisfp = std::make_unique<ISF::ISFParticle>(pos,mom,mass,charge,pdgid,status,properTime,*isfp,id);
219 secisfp->setNextGeoID(m_geoIDSvc->identifyNextGeoID(*secisfp));
220 ATH_MSG_DEBUG(name() <<" secondaries particle (ACTS): "<<*itr<< "("<<itr->momentum()<<")|time "<<itr->time()<<"|process "<< getATLASProcessCode(itr->process()));
221 ATH_MSG_DEBUG(name() <<" secondaries particle (ISF): pdg=" << secisfp->pdgCode()
222 << " pos=" << secisfp->position() << " mom=" << secisfp->momentum()
223 << " GeoID=" << m_geoIDSvc->identifyNextGeoID(*secisfp));
224 vecsecisfp->push_back(secisfp.release());
225 }
226 else{
227 // Primary particle handling
228 ATH_MSG_DEBUG(name() <<" primary particle found with generation ("<< gen <<")");
229 // After simulation, check particle's final state
230 if (!isKilled) {
231 auto fisfp = std::make_unique<ISF::ISFParticle>(*isfp);
232 fisfp->updateMomentum(ActsTrk::convertMomFromActs(itr->fourMomentum()).first);
233 fisfp->updatePosition(ActsTrk::convertPosFromActs(itr->fourPosition()).first);
234 ATH_MSG_DEBUG(name() << " After simulation, primary particle state: " << *fisfp);
235 if (!m_particleFilter.empty() && !m_particleFilter->passFilter(*fisfp)) {
236 ATH_MSG_VERBOSE("ISFParticle" << fisfp << " after simulation does not pass selection. Ignoring for boundary check.");
237 continue;
238 }
239 ATH_MSG_DEBUG(name() << " [ISF] original GeoID: " << m_geoIDSvc->identifyGeoID(*isfp)
240 << " new particle GeoID: " << m_geoIDSvc->identifyGeoID(*fisfp)
241 << ", nextGeoID: " << m_geoIDSvc->identifyNextGeoID(*fisfp));
242
243 // Use ActsExtrapolationTool
244 ATH_MSG_DEBUG(name() << " Extrapolating using ActsExtrapolationTool");
245
246 // Convert to ACTS BoundTrackParameters for extrapolation
247 Acts::BoundTrackParameters startParams = Acts::BoundTrackParameters::createCurvilinear(
248 itr->fourPosition(), itr->direction(), itr->qOverP(), std::nullopt, itr->hypothesis());
249
250 //=============== try if a starting surface exist before passing to Extrapolator ==
251 auto do_exit_startsurface = checkStartSurface(mctx, anygctx, surfaceCheckPropagator, startParams);
252 ATH_MSG_DEBUG(name() << " checkStartSurface returned: " << do_exit_startsurface);
253 if (do_exit_startsurface) {
254 ATH_MSG_DEBUG(name() << " Particle starts at a valid surface, doing extrapolation...");
255
256 // Extrapolate and get propagation steps
258 Amg::Vector3D entryPos{Amg::Vector3D::Zero()};
259 try {
260 auto stepsResult = m_extrapolationTool->propagationSteps(ctx, startParams, Acts::Direction::Forward());
261 auto steps = stepsResult.value().first;
262 ATH_MSG_DEBUG(name() << " Number of propagation steps: " << steps.size());
263 if (steps.size() != 0) {
264 for (const auto& step : steps) {
265 ATH_MSG_DEBUG(name() << " [Acts] Step at position " << step.position
266 << " (eta " << Acts::VectorHelpers::eta(step.position)
267 << ") with GeoID " << step.geoID);
268 entryPos = convertPos3FromActs(step.position);
269 nextGeoID = m_geoIDSvc->identifyGeoID(entryPos);
270 ATH_MSG_DEBUG(name() << " [Acts] GeoID from service: " << nextGeoID);
271 if (nextGeoID > AtlasDetDescr::fAtlasID) { // Valid boundary crossing
272 ATH_MSG_DEBUG(name() << " Boundary crossing detected at GeoID " << nextGeoID);
273 break;
274 }
275 }
276 } else {
277 ATH_MSG_WARNING(name() << " No propagation steps returned by ActsExtrapolationTool");
278 }
279 }
280 catch (const std::exception& e) {
281 ATH_MSG_WARNING(name() << " extrapolation [" << m_extrapolationTool.name() << "] failed: " << e.what() << "\nSkip boundary check for " << *fisfp);
282 break; // Skip boundary check for this particle and continue with next one
283 }
284
285 if (fisfp && nextGeoID > AtlasDetDescr::fAtlasID){
286 const auto mom = ActsTrk::convertMomFromActs(itr->fourMomentum()).first;
287 double mass = itr->mass() / Acts::UnitConstants::MeV;
288 double charge = itr->charge();
289 int pdgid = itr->pdg();
290 auto properTime = ActsTrk::timeToAthena(itr->time());
291
292 // Create boundary crossing particle
293 newisfp = std::make_unique<ISF::ISFParticle>(entryPos, mom, mass, charge, pdgid, isfp->status(), properTime, *isfp, isfp->id(), isfp->barcode());
294 newisfp->setNextGeoID(nextGeoID);
295 ATH_MSG_DEBUG(name() << " Truthbinding of parent ISFParticle: " << (isfp->getTruthBinding() ? "exists" : "null"));
296 if (isfp->getTruthBinding()) {
297 ATH_MSG_DEBUG(name() << " Current GenParticle: " << isfp->getTruthBinding()->getCurrentGenParticle());
298 }
299 ATH_MSG_DEBUG(name() << " Created new ISFParticle at boundary with nextGeoID: "
301 << "(" << nextGeoID << ")");
302 }
303
304 // Handle boundary crossing particle separately - DON'T add to vecsecisfp yet
305 if (newisfp && nextGeoID > AtlasDetDescr::fAtlasID) {
306 ATH_MSG_DEBUG(name() << " [ISF] Processing boundary particle with nextGeoID: "
307 << AtlasDetDescr::AtlasRegionHelper::getName(newisfp->nextGeoID())
308 << "(" << newisfp->nextGeoID() << ")");
309
310 // Identify Entrylayer
312
313 switch(nextGeoID) {
315 entryLayer = ISF::fAtlasCaloEntry;
316 ATH_MSG_DEBUG("Particle crossing to Calorimeter");
317 break;
319 entryLayer = ISF::fAtlasMuonEntry;
320 ATH_MSG_DEBUG("Particle crossing to Muon System");
321 break;
322 default:
323 ATH_MSG_DEBUG("Particle at unspecified boundary");
324 break;
325 }
326
327 if (entryLayer != ISF::fUnsetEntryLayer) {
328 vecsecisfp->push_back(newisfp.release()); // Add boundary crossing particle to secondaries vector
329 } else {
330 ATH_MSG_WARNING("Invalid entry layer for boundary particle");
331 }
332 }
333 }
334 else {
335 ATH_MSG_DEBUG(name() << " No starting surface found, skipping boundary check and extrapolation.");
336 }
337 } // end of !isKilled
338 } // end of primary vs secondary
339 ++itr;
340 } // end of while loop over particles in generation
341
342 // Process truth for this generation
343 if (!vecsecisfp->empty()) {
344 // Determine process code and geoID based on whether we have boundary crossing
345 int processCode = 0;
347 auto isParentKilled = ISF::fPrimarySurvives;
348
349 if (newisfp) {
350 // Boundary crossing - use boundary info
351 processCode = 91; // Boundary crossing has no process
352 geoID = newisfp->nextGeoID();
353 isParentKilled = ISF::fKillsPrimary;
354 } else {
355 // Regular secondaries - use process from last particle
356 processCode = getATLASProcessCode((itr-1)->process());
357 geoID = (isfp->nextGeoID() <= AtlasDetDescr::fUndefinedAtlasRegion) ?
358 AtlasDetDescr::fAtlasID : isfp->nextGeoID();
359 isParentKilled = isKilled && gen==maxGeneration ? ISF::fKillsPrimary : ISF::fPrimarySurvives;
360 }
361
362 ISF::ISFTruthIncident truth(*isfp,
363 *vecsecisfp,
364 processCode,
365 geoID,
366 isParentKilled);
367
368 ATH_MSG_DEBUG(name() << " Truth incident parentPt2(MinPt2) " << truth.parentPt2() <<" (100 MeV)");
369 ATH_MSG_DEBUG(name() << " Truth incident ChildPt2(MinPt2) " << truth.childrenPt2Pass(300) <<" (300 MeV)");
370 m_truthRecordSvc->registerTruthIncident(truth, true);
373 for (auto *secisfp : *vecsecisfp){
374 if (secisfp->getTruthBinding()) {
375 secondaries.push_back(secisfp);
376 ATH_MSG_DEBUG(name() << " Secondary particle written out to truth.\n Parent ("
377 << *isfp << ")\n Secondary (" << *secisfp <<")");
378
379 ATH_MSG_DEBUG("Secondary particle push back to ISF, TruthBinding: " << secisfp->getTruthBinding()->getCurrentGenParticle() << " (current) | " << secisfp->getTruthBinding()->getPrimaryGenParticle() << " (primary) | " << secisfp->getTruthBinding()->getGenerationZeroGenParticle() << " (zero)");
380 if (secisfp->getTruthBinding()->getCurrentGenParticle() != nullptr) ATH_MSG_DEBUG("Secondary particle GenParticle EndVertex: " << (secisfp->getTruthBinding()->getCurrentGenParticle()->end_vertex() ? HepMC::barcode(secisfp->getTruthBinding()->getCurrentGenParticle()->end_vertex()) : 1));
381 } else {
382 ATH_MSG_WARNING("Secondary particle not written out to truth.\n Parent ("
383 << *isfp << ")\n Secondary (" << *secisfp <<")");
384 delete secisfp; // Clean up particles without truth binding
385 }
386 }
387 }
388 } // end of generation loop
389 } // end of !simulatedFinal.empty()
390 ATH_MSG_VERBOSE(name() << " No. of secondaries: " << secondaries.size());
391 ATH_MSG_DEBUG(name() << " End of particle " << isfp->id());
392
393 std::vector<ActsFatras::Particle>().swap(input);
394 std::vector<ActsFatras::Particle>().swap(simulatedInitial);
395 std::vector<ActsFatras::Particle>().swap(simulatedFinal);
396 std::vector<ActsFatras::Hit>().swap(hits);
397 } // end of isfp loop
398 return StatusCode::SUCCESS;
399}
400
401bool ISF::ActsFatrasSimTool::checkStartSurface(const Acts::MagneticFieldContext& mctx,
402 const Acts::GeometryContext& anygctx,
403 const ChargedPropagator& chargedPropagator,
404 const Acts::BoundTrackParameters& startParameters,
405 Acts::Direction navDir /*= Acts::Direction::Forward()*/,
406 double pathLimit /*= std::numeric_limits<double>::max()*/) const
407{
408
409 ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " begin");
410 using ActorList =
411 Acts::ActorList<Acts::detail::SteppingLogger, Acts::MaterialInteractor>;
412 using PropagatorOptions = typename ChargedPropagator::template Options<ActorList>;
413
414 ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " Setting up propagator options for start surface check.");
415 PropagatorOptions options(anygctx, mctx);
416 options.loopProtection = (Acts::VectorHelpers::perp(startParameters.momentum()) < 300 * 1_MeV);
417 options.direction = navDir;
418 options.pathLimit = pathLimit;
419
420 // The state creation triggers the initial volume/surface lookup
421 ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " Initializing propagator state with start parameters: position "
422 << startParameters.position(anygctx).transpose() << ", momentum "
423 << startParameters.momentum().transpose());
424 auto state = chargedPropagator.makeState(options);
425 ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " Created propagator state. Now initializing with start parameters.");
426 auto initResult = chargedPropagator.initialize(state, startParameters);
427 if (!initResult.ok()) {
428 ATH_MSG_WARNING(name() << "::" << __FUNCTION__ << " Failed to initialize propagator state: "
429 << initResult.error().message());
430 return false;
431 }
432 return true;
433}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
double charge(const T &p)
Definition AtlasPID.h:997
std::unique_ptr< const Acts::Logger > makeActsAthenaLogger(IMessageSvc *svc, const std::string &name, int level, std::optional< std::string > parent_name)
static const char * getName(int region)
Gaudi::Property< double > m_maxStepSize
Acts::EigenStepper< Acts::EigenStepperDefaultExtension > ChargedStepper
Gaudi::Property< double > m_tolerance
Gaudi::Property< double > m_interact_minPt
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
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
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)
ServiceHandle< ISF::ITruthSvc > m_truthRecordSvc
SiHitCollection m_pixelSiHits
ServiceHandle< ActsTrk::ITrackingGeometrySvc > m_trackingGeometrySvc
virtual StatusCode initialize() override
PublicToolHandle< ISF::IParticleFilter > m_particleFilter
SingleParticleSimulation< ChargedPropagator, ChargedInteractions, HitSurfaceSelector, ActsFatras::NoDecay > ChargedSimulation
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
Amg::Vector3D convertPos3FromActs(const Acts::Vector3 &actsPos)
Acts::Propagator< ChargedStepper, Navigator > ChargedPropagator
Gaudi::Property< std::string > m_randomEngineName
Acts::StraightLineStepper NeutralStepper
virtual StatusCode initialize() override
BaseSimulatorTool(const std::string &type, const std::string &name, const IInterface *parent)
The generic ISF particle definition,.
Definition ISFParticle.h:42
Interface class for all truth incidents handled by the ISF.
void updateChildParticleProperties()
Update the id and particleLink properties of the child particles (to be called after registerTruthInc...
double parentPt2() const override final
Return pT^2 of the parent particle.
void updateParentAfterIncidentProperties()
Update the id and particleLink properties of the parentAfterIncident (to be called after registerTrut...
bool childrenPt2Pass(double pt2cut)
Return true if at least one child particle passes the given pT^2 cut (= at least one child with pT^2 ...
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
const std::string process
std::pair< Amg::Vector3D, double > convertMomFromActs(const Acts::Vector4 &actsMom)
Converts an Acts four-momentum vector into an pair of an Athena three-momentum and the paritcle's ene...
constexpr double timeToAthena(T actsT)
Converts a time unit from Acts to Athena units.
std::pair< Amg::Vector3D, double > convertPosFromActs(const Acts::Vector4 &actsPos)
Converts an Acts 4-vector into a pair of an Athena spatial vector and the passed time.
Acts::Vector4 convertPosToActs(const Amg::Vector3D &athenaPos, const double athenaTime=0.)
Converts a position vector & time from Athena units into Acts units.
Eigen::Matrix< double, 3, 1 > Vector3D
AtlasRegion
A simple enum of ATLAS regions and sub-detectors.
Definition AtlasRegion.h:21
int barcode(const T *p)
Definition Barcode.h:15
constexpr int UNDEFINED_ID
constexpr int SIM_STATUS_THRESHOLD
Constant definiting the status threshold for simulated particles, eg. can be used to separate generat...
EntryLayer
Identifiers for the TrackRecordCollections on the boundaries between CaloEntry: Inner Detector - Calo...
Definition EntryLayer.h:31
@ fUnsetEntryLayer
Definition EntryLayer.h:33
@ fAtlasCaloEntry
Definition EntryLayer.h:37
@ fAtlasMuonEntry
Definition EntryLayer.h:38
@ fKillsPrimary
@ fPrimarySurvives
std::list< ISF::ISFParticle * > ISFParticleContainer
generic ISFParticle container (not necessarily a std::list!)
std::vector< ISF::ISFParticle * > ISFParticleVector
ISFParticle vector.