Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/Acts/Navigation/NavigationStateUpdaters.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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 /// into the navigation state
0067 ///
0068 /// @tparam navigation_type distinguishes between internal and external navigation
0069 /// @tparam object_type the type of the object to be filled
0070 /// @tparam filler_type is the helper to fill the object into nState
0071 ///
0072 template <typename navigation_type, typename object_type, typename filler_type>
0073 class SingleObjectNavigation : public navigation_type {
0074  public:
0075   /// Convenience constructor
0076   /// @param so the single object
0077   SingleObjectNavigation(const object_type* so) : m_object(so) {
0078     if (so == nullptr) {
0079       throw std::invalid_argument("SingleObjectNavigation: object is nullptr");
0080     }
0081   }
0082 
0083   /// @brief updates the navigation state with a single object that is filled in
0084   ///
0085   /// @param gctx is the Geometry context of this call
0086   /// @param nState the navigation state to which the surfaces are attached
0087   ///
0088   /// @note this is attaching objects without intersecting nor checking
0089   void update([[maybe_unused]] const GeometryContext& gctx,
0090               NavigationState& nState) const {
0091     filler_type::fill(nState, m_object);
0092   }
0093 
0094   /// Const Access to the object
0095   const object_type* object() const { return m_object; }
0096 
0097  private:
0098   // The object to be filled in
0099   const object_type* m_object = nullptr;
0100 };
0101 
0102 /// @brief This uses state less extractor and fillers to manipulate
0103 /// the navigation state
0104 ///
0105 /// @tparam navigation_type distinguishes between internal and external navigation
0106 /// @tparam extractor_type the helper to extract the objects from
0107 /// @tparam filler_type is the helper to fill the object into nState
0108 ///
0109 template <typename navigation_type, typename extractor_type,
0110           typename filler_type>
0111 class StaticAccessNavigation : public navigation_type {
0112  public:
0113   /// @brief updates the navigation state with a single object that is filled in
0114   ///
0115   /// @param gctx is the Geometry context of this call
0116   /// @param nState the navigation state to which the surfaces are attached
0117   ///
0118   /// @note this is attaching objects without intersecting nor checking
0119   void update([[maybe_unused]] const GeometryContext& gctx,
0120               NavigationState& nState) const {
0121     auto extracted = extractor_type::extract(gctx, nState);
0122     filler_type::fill(nState, extracted);
0123   }
0124 };
0125 
0126 /// @brief  This is an index grid based navigation state updator, it uses
0127 /// an extractor type and a filler type to handle the navigation state
0128 ///
0129 /// @note a transform is applied `p3l = transform * p3` in order to allow
0130 /// shifted, transformed grids
0131 ///
0132 /// It can be used for volumes, surfaces at convenience
0133 ///
0134 /// @tparam navigation_type distinguishes between internal and external navigation
0135 /// @tparam grid_t is the type of the grid
0136 /// @tparam extractor_type is the helper to extract the object
0137 /// @tparam filler_type is the helper to fill the object into the nState
0138 ///
0139 template <typename navigation_type, typename grid_t, typename extractor_type,
0140           typename filler_type>
0141 class IndexedGridNavigation : public navigation_type {
0142  public:
0143   /// Broadcast the grid type
0144   using grid_type = grid_t;
0145 
0146   /// An extractor helper to get the object(s) from the volume
0147   extractor_type extractor;
0148 
0149   /// The grid where the indices are stored
0150   grid_type grid;
0151 
0152   /// These are the cast parameters - copied from constructor
0153   std::array<BinningValue, grid_type::DIM> casts{};
0154 
0155   /// A transform to be applied to the position
0156   Transform3 transform = Transform3::Identity();
0157 
0158   /// @brief  Constructor for a grid based surface attacher
0159   /// @param igrid the grid that is moved into this attacher
0160   /// @param icasts is the cast values array
0161   /// @param itr a transform applied to the global position
0162   IndexedGridNavigation(grid_type&& igrid,
0163                         const std::array<BinningValue, grid_type::DIM>& icasts,
0164                         const Transform3& itr = Transform3::Identity())
0165       : grid(std::move(igrid)), casts(icasts), transform(itr) {}
0166 
0167   IndexedGridNavigation() = delete;
0168 
0169   /// @brief updates the navigation state with objects from the grid according
0170   /// to the filling type AFTER applying `p3loc = transform * p3`
0171   ///
0172   /// @param gctx is the Geometry context of this call
0173   /// @param nState the navigation state to which the surfaces are attached
0174   ///
0175   /// @note this is attaching objects without intersecting nor checking
0176   void update(const GeometryContext& gctx, NavigationState& nState) const {
0177     // Extract the index grid entry
0178     const auto& entry =
0179         grid.atPosition(GridAccessHelpers::castPosition<grid_type>(
0180             transform * nState.position, casts));
0181     auto extracted = extractor.extract(gctx, nState, entry);
0182     filler_type::fill(nState, extracted);
0183 
0184     // If the delegate type is of type IInternalNavigation
0185     if constexpr (std::is_base_of_v<IInternalNavigation, navigation_type>) {
0186       // Update the candidates
0187       updateCandidates(gctx, nState);
0188     }
0189   }
0190 };
0191 
0192 /// This is a chained extractor/filler implementation
0193 /// Since there is no control whether it is a static or
0194 /// payload extractor, these have to be provided by a tuple
0195 ///
0196 /// @tparam navigation_type distinguishes between internal and external navigation
0197 /// @tparam updators_t the updators that will be called in sequence
0198 ///
0199 template <typename navigation_type, typename... updators_t>
0200 class ChainedNavigation : public navigation_type {
0201  public:
0202   /// The stored updators
0203   std::tuple<updators_t...> updators;
0204 
0205   /// Constructor for chained updators in a tuple, this will unroll
0206   /// the tuple and call them in sequence
0207   ///
0208   /// @param upts the updators to be called in chain
0209   ChainedNavigation(const std::tuple<updators_t...>&& upts)
0210       : updators(std::move(upts)) {}
0211 
0212   /// A combined navigation state updator w/o intersection specifics
0213   ///
0214   /// @param gctx is the Geometry context of this call
0215   /// @param nState the navigation state to which the objects are attached
0216   ///
0217   void update(const GeometryContext& gctx, NavigationState& nState) const {
0218     // Unfold the tuple and add the attachers
0219     std::apply(
0220         [&](auto&&... updator) { ((updator.update(gctx, nState)), ...); },
0221         updators);
0222   }
0223 };
0224 
0225 }  // namespace Acts::Experimental