diff --git a/Fatras/include/ActsFatras/Kernel/Interactor.hpp b/Fatras/include/ActsFatras/Kernel/Interactor.hpp index 1c6c61f94726d6317c35a074922da97295416934..5a06a82be31c3db9186481b2db0e3e258a30e8d7 100644 --- a/Fatras/include/ActsFatras/Kernel/Interactor.hpp +++ b/Fatras/include/ActsFatras/Kernel/Interactor.hpp @@ -27,6 +27,28 @@ struct EverySurface { constexpr bool operator()(const Acts::Surface &) const { return true; } }; +/// Interactor result (and intermediate state). +/// +/// The result struct does not depend on the template arguments of the +/// Interactor. Defining it independently gives greater flexibility for its +/// usage. +struct InteractorResult { + /// Whether the simulation can continue, i.e. particle is still alive. + bool isAlive = true; + /// Accumulated material during the propagation. + /// The initial particle can already have some passed material. We need the + /// particle to store the full material path but still keep track of the + /// additional accumulated material during simulation. + Particle::Scalar pathInX0 = 0; + Particle::Scalar pathInL0 = 0; + /// Propagated particle state. + Particle particle; + /// Additional particles generated by interactions. + std::vector<Particle> generatedParticles; + /// Hits created by the propagated particle. + std::vector<Hit> hits; +}; + /// Fatras interactor plugin for the Acts propagator. /// /// This plugin must be added to the action list of the propagator and is the @@ -41,32 +63,7 @@ struct EverySurface { template <typename generator_t, typename physics_list_t, typename hit_surface_selector_t = NoSurface> struct Interactor { - /// Random number generator used for the simulation. - generator_t *generator = nullptr; - /// Physics list detailing the simulated interactions and processes. - physics_list_t physics; - /// Selector for surfaces that should generate hits. - hit_surface_selector_t selectHitSurface; - /// Initial particle state. - Particle particle; - - /// Interaction result (and intermediate state). - struct result_type { - /// Whether the simulation can continue, i.e. particle is still alive. - bool isAlive = true; - /// Accumulated material during the propagation. - /// The initial particle can already have some passed material. We need the - /// particle to store the full material path but still keep track of the - /// additional accumulated material during simulation. - Particle::Scalar pathInX0 = 0; - Particle::Scalar pathInL0 = 0; - /// Propagated particle state. - Particle particle; - /// Additional particles generated by interactions. - std::vector<Particle> generatedParticles; - /// Hits created by the propagated particle. - std::vector<Hit> hits; - }; + using result_type = InteractorResult; /// Abort if the particle was killed during a previous interaction. struct ParticleNotAlive { @@ -80,6 +77,15 @@ struct Interactor { } }; + /// Random number generator used for the simulation. + generator_t *generator = nullptr; + /// Physics list detailing the simulated interactions and processes. + physics_list_t physics; + /// Selector for surfaces that should generate hits. + hit_surface_selector_t selectHitSurface; + /// Initial particle state. + Particle particle; + /// Simulate the interaction with a single surface. /// /// @tparam propagator_state_t is propagator state diff --git a/Fatras/include/ActsFatras/Kernel/Simulator.hpp b/Fatras/include/ActsFatras/Kernel/Simulator.hpp index d7004efd268335025dda8f4c69ebc0c190124736..5a821b32d31793660885b7c9a032a763623a5732 100644 --- a/Fatras/include/ActsFatras/Kernel/Simulator.hpp +++ b/Fatras/include/ActsFatras/Kernel/Simulator.hpp @@ -65,17 +65,15 @@ struct ParticleSimulator { /// /// @tparam generator_t is the type of the random number generator template <typename generator_t> - Acts::Result<typename Interactor<generator_t, physics_list_t, - hit_surface_selector_t>::result_type> - simulate(const Acts::GeometryContext &geoCtx, - const Acts::MagneticFieldContext &magCtx, generator_t &generator, - const Particle &particle) const { + Acts::Result<InteractorResult> simulate( + const Acts::GeometryContext &geoCtx, + const Acts::MagneticFieldContext &magCtx, generator_t &generator, + const Particle &particle) const { assert(localLogger and "Missing local logger"); // propagator-related additional types using Interact = Interactor<generator_t, physics_list_t, hit_surface_selector_t>; - using InteractResult = typename Interact::result_type; using Actions = Acts::ActionList<Interact, Acts::detail::DebugOutputActor>; using Abort = Acts::AbortList<typename Interact::ParticleNotAlive, Acts::detail::EndOfWorldReached>; @@ -103,7 +101,7 @@ struct ParticleSimulator { particle.time()); auto result = propagator.propagate(start, options); if (result.ok()) { - return result.value().template get<InteractResult>(); + return result.value().template get<InteractorResult>(); } else { return result.error(); } @@ -113,7 +111,7 @@ struct ParticleSimulator { particle.absMomentum() * particle.unitDirection(), particle.time()); auto result = propagator.propagate(start, options); if (result.ok()) { - return result.value().template get<InteractResult>(); + return result.value().template get<InteractorResult>(); } else { return result.error(); } @@ -252,11 +250,10 @@ struct Simulator { /// Copy Interactor results to output containers. /// - /// @tparam interactor_result_t is an Interactor result struct /// @tparam particles_t is a SequenceContainer for particles /// @tparam hits_t is a SequenceContainer for hits - template <typename interactor_result_t, typename particles_t, typename hits_t> - void copyOutputs(const interactor_result_t &result, + template <typename particles_t, typename hits_t> + void copyOutputs(const InteractorResult &result, particles_t &particlesInitial, particles_t &particlesFinal, hits_t &hits) const { // initial particle state was already pushed to the container before