Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-02 08:16:43

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Geometry/IndexGrid.hpp"
0012 #include "Acts/Geometry/ReferenceGenerators.hpp"
0013 #include "Acts/Geometry/TrackingVolume.hpp"
0014 #include "Acts/Navigation/INavigationPolicy.hpp"
0015 #include "Acts/Navigation/NavigationStream.hpp"
0016 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0017 #include "Acts/Utilities/Grid.hpp"
0018 #include "Acts/Utilities/GridAccessHelpers.hpp"
0019 #include "Acts/Utilities/ProtoAxis.hpp"
0020 
0021 namespace Acts {
0022 
0023 /// Configuration for the index-grid based navigation policy.
0024 class IndexGridNavigationConfig {
0025  public:
0026   /// The binning expansion for grid neighbor lookups
0027   std::vector<std::size_t> binExpansion = {};
0028 
0029   /// The reference expansion
0030   std::vector<double> referenceExpansion = {};
0031 
0032   /// A potential lookup surface - this would be intersected first,
0033   /// assumption is always closest forward
0034   std::shared_ptr<Surface> surface = nullptr;
0035 
0036   /// The reference generator
0037   std::shared_ptr<IReferenceGenerator> referenceGenerator =
0038       std::make_shared<PolyhedronReferenceGenerator>();
0039 };
0040 
0041 /// A navigation policy that uses grid based navigation for indexed surfaces
0042 /// Navigate through a multilayer structure by creating an artificial path on
0043 /// the grid.
0044 template <typename GridType>
0045 class IndexGridNavigationPolicy : public INavigationPolicy {
0046  public:
0047   /// Index grid type
0048   using IndexGridType = IndexGrid<GridType>;
0049 
0050   /// Main constructor, which expects the grid and will fill it with the
0051   /// surfaces from the volume passed
0052   /// @note Expects that the grid is defined but not filled - it will be filled here with the surfaces assigned to the @p volume
0053   /// @param gctx The geometrycontext object
0054   /// @param volume The tracking volume holding the surfaces that will be the indexed objects
0055   /// @param logger A logging instance
0056   /// @param config The configuration of the Navigation Policy
0057   /// @param grid The index grid to use for navigation
0058   explicit IndexGridNavigationPolicy(const GeometryContext& gctx,
0059                                      const TrackingVolume& volume,
0060                                      const Logger& logger,
0061                                      const IndexGridNavigationConfig& config,
0062                                      const IndexGridType& grid)
0063       : m_cfg(config), m_volume(volume), m_indexGrid(grid) {
0064     ACTS_VERBOSE("Constructing IndexGridNavigationPolicy for volume '"
0065                  << m_volume.volumeName() << "'");
0066 
0067     // Fill the grid with the surfaces from the volume
0068     IndexGridFiller filler{m_cfg.binExpansion, m_cfg.referenceExpansion,
0069                            getDefaultLogger("IndexGridFiller", logger.level())};
0070     const auto& surfaces = m_volume.surfaces();
0071     // Fill the grid with surfaces
0072     std::vector<std::shared_ptr<const Surface>> surfacePtrs = {};
0073     surfacePtrs.reserve(surfaces.size());
0074     for (const auto& surface : surfaces) {
0075       surfacePtrs.push_back(surface.getSharedPtr());
0076     }
0077     filler.fill(gctx, m_indexGrid, surfacePtrs, *m_cfg.referenceGenerator);
0078   }
0079 
0080   /// Update the navigation state from the surface array
0081   /// @param gctx the geometry context
0082   /// @param args The navigation arguments
0083   /// @param state The navigation policy state
0084   /// @param stream The navigation stream to update
0085   /// @param logger The logger
0086   void initializeCandidates(const GeometryContext& gctx,
0087                             const NavigationArguments& args,
0088                             NavigationPolicyState& state,
0089                             AppendOnlyNavigationStream& stream,
0090                             const Logger& logger) const {
0091     static_cast<void>(state);  // unused
0092     ACTS_VERBOSE(
0093         "IndexGridNavigationPolicy: candidates initialization for volume '"
0094         << m_volume.volumeName() << "'");
0095 
0096     // Nominal or intersected position
0097     Vector3 position = args.position;
0098     if (m_cfg.surface) {
0099       auto multiIntersection = m_cfg.surface->intersect(
0100           gctx, position, args.direction, BoundaryTolerance::Infinite());
0101       position = multiIntersection.closestForward().position();
0102     }
0103 
0104     // The indexing is guaranteed
0105     const auto& surfaces = m_volume.surfaces();
0106     const auto& indices =
0107         m_indexGrid.grid.atPosition(GridAccessHelpers::castPosition<GridType>(
0108             m_indexGrid.transform * position, m_indexGrid.casts));
0109     // Fill the navigation stream with the container
0110     for (const auto& idx : indices) {
0111       stream.addSurfaceCandidate(surfaces[idx], args.tolerance);
0112     }
0113   }
0114 
0115   /// Connect this policy with a navigation delegate
0116   /// @param delegate The navigation delegate to connect to
0117   void connect(NavigationDelegate& delegate) const override {
0118     connectDefault<IndexGridNavigationPolicy>(delegate);
0119   }
0120 
0121   /// @brief  Give const access to the index grid
0122   /// @return
0123   const IndexGridType& indexGrid() const { return m_indexGrid; }
0124 
0125  private:
0126   // Keep the config
0127   IndexGridNavigationConfig m_cfg;
0128   // The tracking volume
0129   const TrackingVolume& m_volume;
0130   // The index grid
0131   IndexGridType m_indexGrid;
0132 };
0133 
0134 /// Regular cylinder grid in phi and z
0135 using RegularCylinderIndexGrid =
0136     Grid<std::vector<std::size_t>,
0137          Axis<AxisType::Equidistant, AxisBoundaryType::Closed>,
0138          Axis<AxisType::Equidistant, AxisBoundaryType::Bound>>;
0139 /// Navigation policy for regular cylinder grids
0140 using RegularCylinderIndexGridNavigationPolicy =
0141     IndexGridNavigationPolicy<RegularCylinderIndexGrid>;
0142 
0143 static_assert(
0144     NavigationPolicyConcept<RegularCylinderIndexGridNavigationPolicy>);
0145 
0146 /// Regular ring grid in phi
0147 using RegularRingIndexGrid =
0148     Grid<std::vector<std::size_t>,
0149          Axis<AxisType::Equidistant, AxisBoundaryType::Closed>>;
0150 /// Navigation policy for regular ring grids
0151 using RegularRingIndexGridNavigationPolicy =
0152     IndexGridNavigationPolicy<RegularRingIndexGrid>;
0153 
0154 /// Regular disc grid in r and phi
0155 using RegularDiscIndexGrid =
0156     Grid<std::vector<std::size_t>,
0157          Axis<AxisType::Equidistant, AxisBoundaryType::Bound>,
0158          Axis<AxisType::Equidistant, AxisBoundaryType::Closed>>;
0159 /// Navigation policy for regular disc grids
0160 using RegularDiscIndexGridNavigationPolicy =
0161     IndexGridNavigationPolicy<RegularDiscIndexGrid>;
0162 
0163 static_assert(NavigationPolicyConcept<RegularDiscIndexGridNavigationPolicy>);
0164 
0165 /// Regular planar grid in x and y
0166 using RegularPlaneIndexGrid =
0167     Grid<std::vector<std::size_t>,
0168          Axis<AxisType::Equidistant, AxisBoundaryType::Bound>,
0169          Axis<AxisType::Equidistant, AxisBoundaryType::Bound>>;
0170 /// Navigation policy for regular planar grids
0171 using RegularPlaneIndexGridNavigationPolicy =
0172     IndexGridNavigationPolicy<RegularPlaneIndexGrid>;
0173 static_assert(NavigationPolicyConcept<RegularPlaneIndexGridNavigationPolicy>);
0174 
0175 }  // namespace Acts