43 #include <system_error>
47 #include <boost/version.hpp>
52 struct HitSurfaceSelector {
53 bool sensitive =
false;
63 bool isPassive = not(isSensitive or isMaterial);
64 return (isSensitive and sensitive) or (isMaterial and
material) or
77 ActsExamples::SimParticleContainer::sequence_type &,
78 ActsExamples::SimParticleContainer::sequence_type &,
79 ActsExamples::SimHitContainer::sequence_type &)
const = 0;
98 using ChargedSelector = CutPMin;
108 using NeutralSelector = CutPMin;
109 using NeutralInteractions =
117 NeutralSelector, NeutralSimulation>;
119 Simulation simulation;
129 NeutralPropagator(NeutralStepper(),
132 using namespace ActsFatras;
133 using namespace ActsFatras::detail;
137 simulation.selectCharged.valMin =
cfg.pMin;
138 simulation.selectNeutral.valMin =
cfg.pMin;
139 simulation.charged.interactions =
143 if (not
cfg.emScattering) {
144 simulation.charged.interactions.template disable<StandardScattering>();
146 if (not
cfg.emEnergyLossIonisation) {
147 simulation.charged.interactions.template disable<StandardBetheBloch>();
149 if (not
cfg.emEnergyLossRadiation) {
150 simulation.charged.interactions.template disable<StandardBetheHeitler>();
152 if (not
cfg.emPhotonConversion) {
153 simulation.neutral.interactions.template disable<PhotonConversion>();
157 simulation.charged.selectHitSurface.sensitive =
cfg.generateHitsOnSensitive;
158 simulation.charged.selectHitSurface.material =
cfg.generateHitsOnMaterial;
159 simulation.charged.selectHitSurface.passive =
cfg.generateHitsOnPassive;
161 ~FatrasSimulationT() final =
default;
168 &simulatedParticlesInitial,
170 &simulatedParticlesFinal,
172 return simulation.simulate(geoCtx, magCtx, rng, inputParticles,
173 simulatedParticlesInitial,
174 simulatedParticlesFinal, simHits);
189 ACTS_WARNING(
"FatrasSimulation not configured to generate any hits!");
193 throw std::invalid_argument{
"Missing tracking geometry"};
196 throw std::invalid_argument{
"Missing magnetic field"};
199 throw std::invalid_argument(
"Missing random numbers tool");
203 m_sim = std::make_unique<FatrasSimulationT>(
m_cfg, lvl);
222 SimParticleContainer::sequence_type particlesInitialUnordered;
223 SimParticleContainer::sequence_type particlesFinalUnordered;
224 SimHitContainer::sequence_type simHitsUnordered;
229 m_cfg.averageHitsPerParticle);
232 auto rng =
m_cfg.randomNumbers->spawnGenerator(ctx);
235 particlesFinalUnordered, simHitsUnordered);
240 return ProcessCode::ABORT;
245 for (
const auto &failed : ret.value()) {
247 <<
" failed to simulate with error " << failed.error
248 <<
": " << failed.error.message());
252 <<
" simulated particles (initial state)");
254 <<
" simulated particles (final state)");
255 ACTS_DEBUG(simHitsUnordered.size() <<
" simulated hits");
258 #if BOOST_VERSION >= 107800
260 particlesInitialUnordered.end());
262 particlesFinalUnordered.end());
263 SimHitContainer simHits(simHitsUnordered.begin(), simHitsUnordered.end());
272 particlesInitial.reserve(particlesInitialUnordered.size());
273 particlesFinal.reserve(particlesFinalUnordered.size());
274 simHits.reserve(simHitsUnordered.size());
276 for (
const auto &
p : particlesInitialUnordered) {
277 particlesInitial.insert(
p);
279 for (
const auto &
p : particlesFinalUnordered) {
280 particlesFinal.insert(
p);
282 for (
const auto &
h : simHitsUnordered) {
288 m_outputParticlesInitial(ctx,
std::move(particlesInitial));
289 m_outputParticlesFinal(ctx,
std::move(particlesFinal));
290 m_outputSimHits(ctx,
std::move(simHits));