9 #include "CLHEP/Random/RandFlat.h"
10 #include "CLHEP/Random/RandomEngine.h"
15 using namespace Acts::UnitLiterals;
18 const std::string&
name,
26 ATH_MSG_INFO(
"ISF::ActsFatrasSimTool update with ACTS 37.0.0");
28 if (!m_particleFilter.empty())
ATH_CHECK(m_particleFilter.retrieve());
31 m_logger =
makeActsAthenaLogger(
this, std::string(
"ActsFatras"),std::string(
"ActsFatrasSimTool"));
34 ATH_CHECK(m_trackingGeometryTool.retrieve());
35 m_trackingGeometry = m_trackingGeometryTool->trackingGeometry();
39 ATH_CHECK( m_fieldCacheCondObjInputKey.initialize());
42 if (m_rngSvc.retrieve().isFailure()) {
44 return StatusCode::FAILURE;
47 m_randomEngine = m_rngSvc->getEngine(
this, m_randomEngineName.value());
48 if (!m_randomEngine) {
49 ATH_MSG_FATAL(
"Could not get random engine '" << m_randomEngineName.value() <<
"'");
50 return StatusCode::FAILURE;
55 ATH_MSG_DEBUG(
"- Using ISF TruthRecordSvc : " << m_truthRecordSvc.typeAndName() );
56 return StatusCode::SUCCESS;
64 if (!m_particleFilter.empty() && !m_particleFilter->passFilter(isp)) {
65 ATH_MSG_VERBOSE(
"ISFParticle " << isp <<
" does not pass selection. Ignoring.");
66 return StatusCode::SUCCESS;
71 ATH_CHECK(m_truthRecordSvc->initializeTruthCollection());
72 ATH_CHECK(this->simulateVector(ctx, ispVector, secondaries, mcEventCollection));
74 return StatusCode::SUCCESS;
78 const EventContext& ctx,
83 m_randomEngine->setSeed(m_randomEngineName, ctx);
84 CLHEP::HepRandomEngine* randomEngine = m_randomEngine->getEngine(ctx);
88 <<
particles.size() <<
" particles for simulation.");
91 Acts::Navigator navigator( Acts::Navigator::Config{ m_trackingGeometry }, m_logger);
92 auto bField = std::make_shared<ATLASMagneticFieldWrapper>();
97 ChargedSimulation simulatorCharged(std::move(chargedPropagator), m_logger->clone());
98 NeutralSimulation simulatorNeutral(std::move(neutralPropagator), m_logger->clone());
102 simulator.charged.maxStepSize = m_maxStepSize;
103 simulator.charged.maxStep = m_maxStep;
104 simulator.charged.pathLimit = m_pathLimit;
105 simulator.charged.maxRungeKuttaStepTrials = m_maxRungeKuttaStepTrials;
106 simulator.charged.loopProtection = m_loopProtection;
107 simulator.charged.loopFraction = m_loopFraction;
108 simulator.charged.targetTolerance = m_tolerance;
109 simulator.charged.stepSizeCutOff = m_stepSizeCutOff;
111 simulator.charged.interactions = ActsFatras::makeStandardChargedElectroMagneticInteractions(m_interact_minPt *
Acts::UnitConstants::MeV);
114 Acts::MagneticFieldContext mctx = getMagneticFieldContext(ctx);
129 std::vector<ActsFatras::Particle>
input = std::vector<ActsFatras::Particle>{
131 HepMC::barcode(isfp)),
static_cast<Acts::PdgParticle
>(isfp->pdgCode()),
133 .setDirection(Acts::makeDirectionFromPhiEta(
134 isfp->momentum().phi(), isfp->momentum().eta()))
136 .setPosition4(isfp->position().x(), isfp->position().y(),
137 isfp->position().z(), isfp->timeStamp())};
138 std::vector<ActsFatras::Particle> simulatedInitial;
139 std::vector<ActsFatras::Particle> simulatedFinal;
140 std::vector<ActsFatras::Hit>
hits;
141 ATH_MSG_DEBUG(
name() <<
" Convert ISF::Particle " << isfp->barcode() <<
" to ActsFatras::Particle " <<
input[0].particleId().value());
142 ATH_MSG_DEBUG(
name() <<
" Propagating ActsFatras::Particle vertex|particle|generation|subparticle, " <<
input[0]);
145 auto simulatedFailure=
result.value();
146 if (simulatedFailure.size()>0){
147 for (
const auto& simfail : simulatedFailure){
148 auto errCode = Acts::make_error_code(Acts::PropagatorError(simfail.error.value()));
149 ATH_MSG_WARNING(
name() <<
" Particle id " <<simfail.particle.particleId()<<
": fail to be simulated during Propagation: " << errCode.message());
150 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()));
151 return StatusCode::SUCCESS;
158 for (
const auto& hit :
hits) {
163 ATH_MSG_DEBUG(
name() <<
" No. of particles after ActsFatras simulator: " << simulatedFinal.size());
164 if (simulatedFinal.size()>1){
171 ATH_MSG_DEBUG(
name() <<
" secondaries particle " <<
n<<
"/"<< simulatedFinal.size()-1<<
": "<< *itr);
173 const auto pos =
Amg::Vector3D(itr->position()[Acts::ePos0],itr->position()[Acts::ePos1],itr->position()[Acts::ePos2]);
176 double charge = itr->charge();
177 int pdgid = itr->pdg();
178 double properTime = itr->properTime();
181 ATH_MSG_DEBUG(
name() <<
" secondaries particle process code " << itr->process());
183 auto vecsecisfp = std::make_unique<ISF::ISFParticleVector>();
184 vecsecisfp->push_back(secisfp);
189 getATLASProcessCode(itr->process()),
194 m_truthRecordSvc->registerTruthIncident(truth,
true);
196 ATH_MSG_DEBUG(
name() <<
" Create secondariy ISF::Particle " << secisfp->barcode());
197 if (secisfp->getTruthBinding()) {
199 secondaries.push_back(secisfp);
202 ATH_MSG_WARNING(
"Secondary particle not written out to truth.\n Parent (" << isfp <<
")\n Secondary (" << *secisfp <<
")");
208 m_ActsFatrasWriteHandler->createHits(*isfp, m_trackingGeometry,
hits,pixelSiHits,sctSiHits);
210 std::vector<ActsFatras::Particle>().swap(
input);
211 std::vector<ActsFatras::Particle>().swap(simulatedInitial);
212 std::vector<ActsFatras::Particle>().swap(simulatedFinal);
213 std::vector<ActsFatras::Hit>().swap(
hits);
215 std::vector<SiHitCollection> hitcolls;
216 hitcolls.push_back(pixelSiHits);
217 hitcolls.push_back(sctSiHits);
218 ATH_CHECK(m_ActsFatrasWriteHandler->WriteHits(hitcolls,ctx));
219 return StatusCode::SUCCESS;
224 if (!readHandle.isValid()) {
225 ATH_MSG_ERROR(
name() +
": Failed to retrieve magnetic field condition data " + m_fieldCacheCondObjInputKey.key() +
".");
227 else ATH_MSG_DEBUG(
name() <<
"retrieved magnetic field condition data "<< m_fieldCacheCondObjInputKey.key());
230 return Acts::MagneticFieldContext(fieldCondObj);