Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:09:08

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2018 CERN for the benefit of the Acts project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Material/ISurfaceMaterial.hpp"
0012 #include "Acts/Material/Material.hpp"
0013 #include "Acts/Material/MaterialProperties.hpp"
0014 #include "Acts/Propagator/ActionList.hpp"
0015 #include "Acts/Surfaces/Surface.hpp"
0016 #include "Fatras/Kernel/PhysicsList.hpp"
0017 #include "detail/RandomNumberDistributions.hpp"
0018 #include <climits>
0019 #include <cmath>
0020 #include <sstream>
0021 #include <utility>
0022 
0023 namespace Fatras {
0024 
0025 struct VoidSelector {
0026 
0027   bool operator()(const Acts::Surface &) const { return false; }
0028 };
0029 
0030 /// The Fatras Interactor
0031 ///
0032 /// This is the Fatras plugin to the ACTS Propagator, it replaces
0033 /// the MaterialInteractor of the reconstruction
0034 ///
0035 /// @tparam generator_t Type of the random generator
0036 /// @tparam particle_t is Type of the particle
0037 /// @tparam hit_t Type of the simulated hit
0038 /// @tparam hit_creator_t Type of the hit creator (does thruth association)
0039 /// @tparam sensitive_selector_t The Selector type to identify sensitive
0040 /// surfaces
0041 /// @tparam physics_list_t Type of Extendable physics list that is called
0042 /// @tparam decay_list_t Type of Extendable decay list that is called
0043 ///
0044 /// The physics list plays a central role in this DetectorInteractor
0045 /// it is called on each process that is defined at compile time
0046 /// if a process triggers an abort, this will be forwarded to
0047 /// the propagation cache.
0048 template <typename generator_t, typename particle_t, typename hit_t,
0049           typename hit_creator_t, typename sensitive_selector_t = VoidSelector,
0050           typename physics_list_t = PhysicsList<>>
0051 struct Interactor {
0052   using PhysicsList_t = physics_list_t;
0053 
0054   /// The random generator to be spawnper event
0055   generator_t *generator = nullptr;
0056 
0057   /// The slector for sensitive surfaces
0058   sensitive_selector_t sensitiveSelector;
0059 
0060   /// The physics list provided for this call
0061   physics_list_t physicsList;
0062 
0063   /// Simple result struct to be returned
0064   particle_t initialParticle;
0065 
0066   /// The hit creator helper class
0067   hit_creator_t hitCreator;
0068 
0069   /// It mainly acts as an internal state cache which is
0070   /// created for every propagation/extrapolation step
0071   struct this_result {
0072 
0073     /// result initialization
0074     bool initialized = false;
0075 
0076     /// The current particle - updated along the way
0077     particle_t particle;
0078 
0079     /// The outgoing particles due to physics processes
0080     std::vector<particle_t> outgoing;
0081 
0082     /// The simulated hits created along the way
0083     std::vector<hit_t> simulatedHits;
0084   };
0085 
0086   typedef this_result result_type;
0087 
0088   /// Interaction with detector material for the ActionList of the Propagator
0089   ///
0090   /// It checks if the cache has a current surface, in which case the action
0091   /// is performed according to the physics list content.
0092   ///
0093   /// Eventual particles produced in electromagnetic or hadronic interactions
0094   /// are stored in the result struct and can thus be retrieved by the caller
0095   ///
0096   /// @tparam  propagator_state_t is the type of Propagtor state
0097   /// @tparam  stepper_t the type of the Stepper for the access to the state
0098   ///
0099   /// @param state is the mutable propagator state object
0100   /// @param stepper is the propagation stepper object
0101   /// @param result is the mutable result cache object
0102   ///
0103   /// return value is void as it is a standard actor in the
0104   /// propagation
0105   template <typename propagator_state_t, typename stepper_t>
0106   void operator()(propagator_state_t &state, stepper_t &stepper,
0107                   result_type &result) const {
0108 
0109     // If we are on target, everything should have been done
0110     if (state.navigation.targetReached)
0111       return;
0112 
0113     // Initialize the result, the state is thread local
0114     if (!result.initialized) {
0115       // set the initial particle parameters
0116       result.particle = initialParticle;
0117       result.initialized = true;
0118     }
0119     // get position and momentum presetp
0120     auto position = stepper.position(state.stepping);
0121     auto direction = stepper.direction(state.stepping);
0122     auto p = stepper.momentum(state.stepping);
0123 
0124     // set the stepping position to the particle
0125     result.particle.update(position, p * direction, 0., 0.,
0126                            stepper.time(state.stepping));
0127 
0128     // Check if the current surrface a senstive one
0129     bool sensitive = state.navigation.currentSurface
0130                          ? sensitiveSelector(*state.navigation.currentSurface)
0131                          : false;
0132     double depositedEnergy = 0.;
0133 
0134     // a current surface has been assigned by the navigator
0135     if (state.navigation.currentSurface &&
0136         state.navigation.currentSurface->surfaceMaterial()) {
0137       // get the surface material and the corresponding material properties
0138       auto sMaterial = state.navigation.currentSurface->surfaceMaterial();
0139       const Acts::MaterialProperties &mProperties =
0140           sMaterial->materialProperties(position);
0141       bool breakIndicator = false;
0142       if (mProperties) {
0143         // run the Fatras physics list - only when there's material
0144         breakIndicator = physicsList(*generator, mProperties, result.particle,
0145                                      result.outgoing);
0146       }
0147     }
0148     // Update the stepper cache with the current particle parameters
0149     position = result.particle.position();
0150     direction = result.particle.momentum().normalized();
0151     stepper.update(state.stepping, position, direction, result.particle.p(),
0152                    result.particle.time());
0153     // create the hit on a senstive element
0154     if (sensitive) {
0155       // create and fill the hit
0156       double htime =
0157           stepper.time(state.stepping); //!< todo calculate from delta time
0158       hit_t simHit =
0159           hitCreator(*state.navigation.currentSurface, position, direction,
0160                      depositedEnergy, htime, result.particle);
0161       result.simulatedHits.push_back(std::move(simHit));
0162     }
0163   }
0164 
0165   /// Pure observer interface
0166   /// This does not apply to the Fatras simulator
0167   template <typename propagator_state_t, typename stepper_t>
0168   void operator()(propagator_state_t &, stepper_t &) const {}
0169 };
0170 } // namespace Fatras