9 #include "CLHEP/Random/RandFlat.h"
10 #include "CLHEP/Random/RandomEngine.h"
14 using namespace Acts::UnitLiterals;
17 const std::string&
name,
25 ATH_MSG_INFO(
"ISF::ActsFatrasSimTool update with ACTS 32.2.0");
27 if (!m_particleFilter.empty())
ATH_CHECK(m_particleFilter.retrieve());
30 m_logger =
makeActsAthenaLogger(
this, std::string(
"ActsFatras"),std::string(
"ActsFatrasSimTool"));
33 ATH_CHECK(m_trackingGeometryTool.retrieve());
34 m_trackingGeometry = m_trackingGeometryTool->trackingGeometry();
38 ATH_CHECK( m_fieldCacheCondObjInputKey.initialize());
41 if (m_rngSvc.retrieve().isFailure()) {
43 return StatusCode::FAILURE;
46 m_randomEngine = m_rngSvc->getEngine(
this, m_randomEngineName.value());
47 if (!m_randomEngine) {
48 ATH_MSG_FATAL(
"Could not get random engine '" << m_randomEngineName.value() <<
"'");
49 return StatusCode::FAILURE;
52 return StatusCode::SUCCESS;
60 if (!m_particleFilter.empty() && !m_particleFilter->passFilter(isp)) {
61 ATH_MSG_VERBOSE(
"ISFParticle " << isp <<
" does not pass selection. Ignoring.");
62 return StatusCode::SUCCESS;
67 ATH_CHECK(this->simulateVector(ispVector, secondaries, mcEventCollection));
69 return StatusCode::SUCCESS;
77 const EventContext& ctx = Gaudi::Hive::currentContext();
78 m_randomEngine->setSeed(m_randomEngineName, ctx);
79 CLHEP::HepRandomEngine* randomEngine = m_randomEngine->getEngine(ctx);
83 <<
particles.size() <<
" particles for simulation.");
86 Acts::Navigator navigator( Acts::Navigator::Config{ m_trackingGeometry }, m_logger);
87 auto bField = std::make_shared<ATLASMagneticFieldWrapper>();
92 ChargedSimulation simulatorCharged(std::move(chargedPropagator), m_logger->clone());
93 NeutralSimulation simulatorNeutral(std::move(neutralPropagator), m_logger->clone());
97 simulator.charged.maxStepSize = m_maxStepSize;
98 simulator.charged.maxStep = m_maxStep;
99 simulator.charged.pathLimit = m_pathLimit;
100 simulator.charged.maxRungeKuttaStepTrials = m_maxRungeKuttaStepTrials;
101 simulator.charged.loopProtection = m_loopProtection;
102 simulator.charged.loopFraction = m_loopFraction;
103 simulator.charged.targetTolerance = m_tolerance;
104 simulator.charged.stepSizeCutOff = m_stepSizeCutOff;
106 simulator.charged.interactions = ActsFatras::makeStandardChargedElectroMagneticInteractions(m_interact_minPt *
Acts::UnitConstants::MeV);
109 Acts::MagneticFieldContext mctx = getMagneticFieldContext(ctx);
121 std::vector<ActsFatras::Particle>
input = std::vector<ActsFatras::Particle>{
123 HepMC::barcode(isfp)),
static_cast<Acts::PdgParticle
>(isfp->pdgCode()),
125 .setDirection(Acts::makeDirectionFromPhiEta(
126 isfp->momentum().phi(), isfp->momentum().eta()))
128 .setPosition4(isfp->position().x(), isfp->position().y(),
129 isfp->position().z(), isfp->timeStamp())};
130 std::vector<ActsFatras::Particle> simulatedInitial;
131 std::vector<ActsFatras::Particle> simulatedFinal;
132 std::vector<ActsFatras::Hit>
hits;
133 ATH_MSG_DEBUG(
name() <<
" Propagating ActsFatras::Particle vertex|particle|generation|subparticle, " <<
input[0]);
136 auto simulatedFailure=
result.value();
137 if (simulatedFailure.size()>0){
138 for (
const auto& simfail : simulatedFailure){
139 auto errCode = Acts::make_error_code(Acts::PropagatorError(simfail.error.value()));
140 ATH_MSG_WARNING(
name() <<
" Particle id " <<simfail.particle.particleId()<<
": fail to be simulated during Propagation: " << errCode.message());
141 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()));
142 return StatusCode::SUCCESS;
147 ATH_MSG_DEBUG(
name() <<
" No. of particles after ActsFatras simulator: " << simulatedFinal.size());
149 for (
const auto& factsp : simulatedFinal){
150 const auto pos =
Amg::Vector3D(factsp.position()[Acts::ePos0],factsp.position()[Acts::ePos1],factsp.position()[Acts::ePos2]);
153 double charge = factsp.charge();
154 int pdgid = factsp.pdg();
155 double properTime = factsp.properTime();
157 if (factsp.particleId() == simulatedInitial[0].particleId()) {
162 auto secisfp = std::make_unique<ISF::ISFParticle>(
pos,
172 secondaries.push_back(secisfp.release());
178 for (
const auto& hit :
hits) {
185 std::vector<ActsFatras::Particle>().swap(
input);
186 std::vector<ActsFatras::Particle>().swap(simulatedInitial);
187 std::vector<ActsFatras::Particle>().swap(simulatedFinal);
188 std::vector<ActsFatras::Hit>().swap(
hits);
190 return StatusCode::SUCCESS;
195 if (!readHandle.isValid()) {
196 ATH_MSG_ERROR(
name() +
": Failed to retrieve magnetic field condition data " + m_fieldCacheCondObjInputKey.key() +
".");
198 else ATH_MSG_DEBUG(
name() <<
"retrieved magnetic field condition data "<< m_fieldCacheCondObjInputKey.key());
201 return Acts::MagneticFieldContext(fieldCondObj);