Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:23:24

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2024 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/EventData/TrackParameters.hpp"
0012 #include "Acts/Geometry/GeometryContext.hpp"
0013 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0014 #include "Acts/Material/interface/IAssignmentFinder.hpp"
0015 #include "Acts/Propagator/AbortList.hpp"
0016 #include "Acts/Propagator/ActionList.hpp"
0017 #include "Acts/Propagator/Propagator.hpp"
0018 #include "Acts/Propagator/SurfaceCollector.hpp"
0019 #include "Acts/Surfaces/Surface.hpp"
0020 #include "Acts/Utilities/Logger.hpp"
0021 #include "Acts/Utilities/VectorHelpers.hpp"
0022 
0023 #include <utility>
0024 #include <vector>
0025 
0026 namespace Acts {
0027 
0028 /// @brief selector for finding surface
0029 ///
0030 /// This is to be used with a SurfaceCollector<>
0031 struct MaterialSurfaceIdentifier {
0032   /// check if the surface has material
0033   bool operator()(const Surface& sf) const {
0034     return (sf.surfaceMaterial() != nullptr);
0035   }
0036 };
0037 
0038 /// An Interaction volume collector with unique counting
0039 struct InteractionVolumeCollector {
0040   /// Simple result struct that holds the collected volumes
0041   ///
0042   /// @note the map is to avoid double counting as this is
0043   /// called in an action list
0044   struct this_result {
0045     std::map<GeometryIdentifier, IAssignmentFinder::VolumeAssignment> collected;
0046   };
0047 
0048   using result_type = this_result;
0049 
0050   /// Collector action for the ActionList of the Propagator
0051   /// It checks if the propagator state has a current volume,
0052   /// in which case the action is performed:
0053   /// - it records the volume given the configuration
0054   ///
0055   /// @tparam propagator_state_t is the type of Propagator state
0056   /// @tparam stepper_t Type of the stepper used for the propagation
0057   /// @tparam navigator_t Type of the navigator used for the propagation
0058   ///
0059   /// @param [in,out] state is the mutable stepper state object
0060   /// @param [in] stepper The stepper in use
0061   /// @param [in] navigator The navigator in use
0062   /// @param [in,out] result is the mutable result object
0063   template <typename propagator_state_t, typename stepper_t,
0064             typename navigator_t>
0065   void operator()(propagator_state_t& state, const stepper_t& stepper,
0066                   const navigator_t& navigator, result_type& result,
0067                   const Logger& /*logger*/) const {
0068     // Retrieve the current volume
0069     auto currentVolume = navigator.currentVolume(state.navigation);
0070 
0071     // The current volume has been assigned by the navigator
0072     if (currentVolume != nullptr) {
0073       auto collIt = result.collected.find(currentVolume->geometryId());
0074       // Check if the volume has been collected and if it has material
0075       if (collIt == result.collected.end() &&
0076           currentVolume->volumeMaterial() != nullptr) {
0077         Vector3 entryPosition = stepper.position(state.stepping);
0078         Vector3 exitPosition = entryPosition;
0079         IAssignmentFinder::VolumeAssignment vAssignment{
0080             InteractionVolume(currentVolume), entryPosition, exitPosition};
0081         result.collected.emplace(currentVolume->geometryId(), vAssignment);
0082       } else if (collIt != result.collected.end()) {
0083         // Update the exit position
0084         (collIt->second).exit = stepper.position(state.stepping);
0085       }
0086     }
0087   }
0088 };
0089 
0090 /// @class PropagatorMaterialAssigner
0091 ///
0092 /// A Propagator based material assigner that uses the navigation and
0093 /// transport of the propagator to assign the material to the surface
0094 /// or the volume.
0095 ///
0096 /// @note eventual navigation problems would affect he material mapping
0097 template <typename propagator_t>
0098 class PropagatorMaterialAssigner final : public IAssignmentFinder {
0099  public:
0100   /// @brief  Construct with propagator
0101   /// @param propagator
0102   PropagatorMaterialAssigner(propagator_t propagator)
0103       : m_propagator(std::move(propagator)) {}
0104 
0105   /// @brief Method for generating assignment candidates for the
0106   /// material interaction assignment to surfaces or volumes
0107   ///
0108   /// @param gctx is the geometry context
0109   /// @param mctx is the magnetic field context
0110   /// @param position is the position of the initial ray
0111   /// @param direction is the direction of initial ray
0112   ///
0113   /// @return a vector of Surface Assignments and Volume Assignments
0114   std::pair<std::vector<IAssignmentFinder::SurfaceAssignment>,
0115             std::vector<IAssignmentFinder::VolumeAssignment>>
0116   assignmentCandidates(const GeometryContext& gctx,
0117                        const MagneticFieldContext& mctx,
0118                        const Vector3& position,
0119                        const Vector3& direction) const final {
0120     // Return container
0121     std::pair<std::vector<IAssignmentFinder::SurfaceAssignment>,
0122               std::vector<IAssignmentFinder::VolumeAssignment>>
0123         candidates;
0124 
0125     using VectorHelpers::makeVector4;
0126     // Neutral curvilinear parameters
0127     NeutralCurvilinearTrackParameters start(
0128         makeVector4(position, 0), direction, 1, std::nullopt,
0129         NeutralParticleHypothesis::geantino());
0130 
0131     // Prepare Action list and abort list
0132     using MaterialSurfaceCollector =
0133         SurfaceCollector<MaterialSurfaceIdentifier>;
0134     using ActionList =
0135         ActionList<MaterialSurfaceCollector, InteractionVolumeCollector>;
0136     using AbortList = AbortList<EndOfWorldReached>;
0137 
0138     PropagatorOptions<ActionList, AbortList> options(gctx, mctx);
0139 
0140     const auto& result = m_propagator.propagate(start, options).value();
0141 
0142     // The surface collection results
0143     auto scResult =
0144         result.template get<MaterialSurfaceCollector::result_type>();
0145     auto mappingSurfaces = scResult.collected;
0146 
0147     for (auto& mSurface : mappingSurfaces) {
0148       candidates.first.push_back(IAssignmentFinder::SurfaceAssignment{
0149           mSurface.surface, mSurface.position, direction});
0150     }
0151 
0152     // The volume collection results
0153     auto vcResult =
0154         result.template get<InteractionVolumeCollector::result_type>();
0155     for (auto [geoId, vIntersection] : vcResult.collected) {
0156       candidates.second.push_back(vIntersection);
0157     }
0158 
0159     // Return the candidates
0160     return candidates;
0161   }
0162 
0163  private:
0164   propagator_t m_propagator;
0165 };
0166 
0167 }  // namespace Acts