Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:10:05

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2022 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/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Common.hpp"
0013 #include "Acts/Detector/Portal.hpp"
0014 #include "Acts/Navigation/NavigationDelegates.hpp"
0015 #include "Acts/Navigation/NavigationState.hpp"
0016 #include "Acts/Surfaces/Surface.hpp"
0017 #include "Acts/Utilities/BinningType.hpp"
0018 #include "Acts/Utilities/Enumerate.hpp"
0019 #include "Acts/Utilities/GridAccessHelpers.hpp"
0020 #include "Acts/Utilities/IAxis.hpp"
0021 #include "Acts/Utilities/VectorHelpers.hpp"
0022 
0023 #include <array>
0024 #include <memory>
0025 
0026 namespace Acts::Experimental {
0027 
0028 /// Helper method to update the candidates (portals/surfaces),
0029 /// this can be called for initial surface/portal estimation,
0030 /// but also during the navigation to update the current list
0031 /// of candidates.
0032 ///
0033 /// @param gctx is the Geometry context of this call
0034 /// @param nState [in,out] is the navigation state to be updated
0035 ///
0036 /// @todo for surfaces skip the non-reached ones, while keep for portals
0037 inline void updateCandidates(const GeometryContext& gctx,
0038                              NavigationState& nState) {
0039   const auto& position = nState.position;
0040   const auto& direction = nState.direction;
0041 
0042   NavigationState::SurfaceCandidates nextSurfaceCandidates;
0043 
0044   for (NavigationState::SurfaceCandidate c : nState.surfaceCandidates) {
0045     // Get the surface representation: either native surface of portal
0046     const Surface& sRep =
0047         c.surface != nullptr ? *c.surface : c.portal->surface();
0048 
0049     // Get the intersection @todo make a templated intersector
0050     // TODO surface tolerance
0051     auto sIntersection = sRep.intersect(gctx, position, direction,
0052                                         c.boundaryCheck, s_onSurfaceTolerance);
0053     for (auto& si : sIntersection.split()) {
0054       c.objectIntersection = si;
0055       if (c.objectIntersection &&
0056           c.objectIntersection.pathLength() > nState.overstepTolerance) {
0057         nextSurfaceCandidates.emplace_back(c);
0058       }
0059     }
0060   }
0061 
0062   nState.surfaceCandidates = std::move(nextSurfaceCandidates);
0063 }
0064 
0065 /// @brief  This sets a single object, e.g. single surface or single volume
0066 /// @tparam object_type the type of the object to be filled
0067 /// @tparam filler_type is the helper to fill the object into nState
0068 template <typename object_type, typename filler_type>
0069 class SingleObjectImpl : public INavigationDelegate {
0070  public:
0071   /// Convenience constructor
0072   /// @param so the single object
0073   SingleObjectImpl(const object_type* so) : object(so) {}
0074 
0075   /// @brief updates the navigation state with a single object that is filled in
0076   ///
0077   /// @param gctx is the Geometry context of this call
0078   /// @param nState the navigation state to which the surfaces are attached
0079   ///
0080   /// @note this is attaching objects without intersecting nor checking
0081   void update([[maybe_unused]] const GeometryContext& gctx,
0082               NavigationState& nState) const {
0083     filler_type::fill(nState, object);
0084   }
0085 
0086  private:
0087   // The object to be filled in
0088   const object_type* object = nullptr;
0089 };
0090 
0091 /// @brief This uses state less extractor and fillers to manipulate
0092 /// the navigation state
0093 ///
0094 /// @tparam extractor_type the helper to extract the objects from
0095 /// @tparam filler_type is the helper to fill the object into nState
0096 template <typename extractor_type, typename filler_type>
0097 class StaticUpdaterImpl : public INavigationDelegate {
0098  public:
0099   /// @brief updates the navigation state with a single object that is filled in
0100   ///
0101   /// @param gctx is the Geometry context of this call
0102   /// @param nState the navigation state to which the surfaces are attached
0103   ///
0104   /// @note this is attaching objects without intersecting nor checking
0105   void update([[maybe_unused]] const GeometryContext& gctx,
0106               NavigationState& nState) const {
0107     auto extracted = extractor_type::extract(gctx, nState);
0108     filler_type::fill(nState, extracted);
0109   }
0110 };
0111 
0112 /// @brief  This is an index grid based navigation state updator, it uses
0113 /// an extractor type and a filler type to handle the navigation state
0114 ///
0115 /// @note a transform is applied `p3l = transform * p3` in order to allow
0116 /// shifted, transformed grids
0117 ///
0118 /// It can be used for volumes, surfaces at convenience
0119 ///
0120 /// @tparam grid_t is the type of the grid
0121 /// @tparam extractor_type is the helper to extract the object
0122 /// @tparam filler_type is the helper to fill the object into the nState
0123 template <typename grid_t, typename extractor_type, typename filler_type>
0124 class IndexedUpdaterImpl : public INavigationDelegate {
0125  public:
0126   /// Broadcast the grid type
0127   using grid_type = grid_t;
0128 
0129   /// An extractor helper to get the object(s) from the volume
0130   extractor_type extractor;
0131 
0132   /// The grid where the indices are stored
0133   grid_type grid;
0134 
0135   /// These are the cast parameters - copied from constructor
0136   std::array<BinningValue, grid_type::DIM> casts{};
0137 
0138   /// A transform to be applied to the position
0139   Transform3 transform = Transform3::Identity();
0140 
0141   /// @brief  Constructor for a grid based surface attacher
0142   /// @param igrid the grid that is moved into this attacher
0143   /// @param icasts is the cast values array
0144   /// @param itr a transform applied to the global position
0145   IndexedUpdaterImpl(grid_type&& igrid,
0146                      const std::array<BinningValue, grid_type::DIM>& icasts,
0147                      const Transform3& itr = Transform3::Identity())
0148       : grid(std::move(igrid)), casts(icasts), transform(itr) {}
0149 
0150   IndexedUpdaterImpl() = delete;
0151 
0152   /// @brief updates the navigation state with objects from the grid according
0153   /// to the filling type AFTER applying `p3loc = transform * p3`
0154   ///
0155   /// @param gctx is the Geometry context of this call
0156   /// @param nState the navigation state to which the surfaces are attached
0157   ///
0158   /// @note this is attaching objects without intersecting nor checking
0159   void update(const GeometryContext& gctx, NavigationState& nState) const {
0160     // Extract the index grid entry
0161     const auto& entry =
0162         grid.atPosition(GridAccessHelpers::castPosition<grid_type>(
0163             transform * nState.position, casts));
0164     auto extracted = extractor.extract(gctx, nState, entry);
0165     filler_type::fill(nState, extracted);
0166 
0167     updateCandidates(gctx, nState);
0168   }
0169 };
0170 
0171 /// This is a chained extractor/filler implementation
0172 /// Since there is no control whether it is a static or
0173 /// payload extractor, these have to be provided by a tuple
0174 ///
0175 /// @tparam updators_t the updators that will be called in sequence
0176 template <typename... updators_t>
0177 class ChainedUpdaterImpl : public INavigationDelegate {
0178  public:
0179   /// The stored updators
0180   std::tuple<updators_t...> updators;
0181 
0182   /// Constructor for chained updators in a tuple, this will unroll
0183   /// the tuple and call them in sequence
0184   ///
0185   /// @param upts the updators to be called in chain
0186   ChainedUpdaterImpl(const std::tuple<updators_t...>&& upts)
0187       : updators(std::move(upts)) {}
0188 
0189   /// A combined navigation state updator w/o intersection specifics
0190   ///
0191   /// @param gctx is the Geometry context of this call
0192   /// @param nState the navigation state to which the objects are attached
0193   ///
0194   void update(const GeometryContext& gctx, NavigationState& nState) const {
0195     // Unfold the tuple and add the attachers
0196     std::apply(
0197         [&](auto&&... updator) { ((updator.update(gctx, nState)), ...); },
0198         updators);
0199   }
0200 };
0201 
0202 }  // namespace Acts::Experimental