Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-03 08:07:04

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/Detector/DetectorVolume.hpp"
0012 #include "Acts/Navigation/NavigationDelegates.hpp"
0013 #include "Acts/Navigation/NavigationStateFillers.hpp"
0014 #include "Acts/Navigation/NavigationStateUpdaters.hpp"
0015 #include "Acts/Utilities/VectorHelpers.hpp"
0016 
0017 #include <array>
0018 #include <memory>
0019 
0020 namespace Acts::Experimental {
0021 
0022 template <typename grid_t, typename path_generator>
0023 class MultiLayerNavigation : public IInternalNavigation {
0024  public:
0025   /// Broadcast the grid type
0026   using grid_type = grid_t;
0027 
0028   /// The grid where the indices are stored
0029   grid_type grid;
0030 
0031   /// The path generator
0032   path_generator pgenerator;
0033 
0034   /// These are the cast parameters - copied from constructor
0035   std::array<BinningValue, grid_type::DIM> casts{};
0036 
0037   /// An inverse transform to be applied to the position
0038   Transform3 transform = Transform3::Identity();
0039 
0040   /// @brief  Constructor for a grid based surface attacher
0041   /// @param igrid the grid that is moved into this attacher
0042   /// @param icasts is the cast values array
0043   /// @param itr a transform applied to the global position
0044   MultiLayerNavigation(grid_type igrid,
0045                        const std::array<BinningValue, grid_type::DIM>& icasts,
0046                        const Transform3& itr = Transform3::Identity())
0047       : grid(std::move(igrid)), casts(icasts), transform(itr) {}
0048 
0049   MultiLayerNavigation() = delete;
0050 
0051   /// Fill the navigation state
0052   ///
0053   /// @note no initialization is done here (sorting and update)
0054   ///
0055   /// @param gctx is the geometry context
0056   /// @param nState is the navigation state
0057   void fill(const GeometryContext& gctx, NavigationState& nState) const {
0058     // get the local position and direction
0059     auto lposition = transform * nState.position;
0060     auto ldirection = transform.linear() * nState.direction;
0061 
0062     auto step = std::sqrt(std::pow(grid.binWidth()[0], 2) +
0063                           std::pow(grid.binWidth()[1], 2));
0064     auto path = pgenerator(lposition, ldirection, step, grid.numLocalBins()[1]);
0065 
0066     std::vector<const Acts::Surface*> surfCandidates = {};
0067 
0068     for (const auto& p : path) {
0069       const auto& entry = grid.atPosition(castPosition(p));
0070       const auto extracted =
0071           IndexedSurfacesExtractor::extract(gctx, nState, entry);
0072       surfCandidates.insert(surfCandidates.end(), extracted.begin(),
0073                             extracted.end());
0074     }
0075 
0076     resolveDuplicates(gctx, surfCandidates);
0077     SurfacesFiller::fill(nState, surfCandidates);
0078   }
0079   /// Fill the update the navigation state with candidates
0080   ///
0081   /// @note initialization is done here (sorting and update)
0082   ///
0083   /// @param gctx is the geometry context
0084   /// @param nState is the navigation state
0085   void update(const GeometryContext& gctx, NavigationState& nState) const {
0086     fill(gctx, nState);
0087     intitializeCandidates(gctx, nState);
0088   }
0089 
0090   /// Cast into a lookup position
0091   ///
0092   /// @param position is the position of the update call
0093   std::array<ActsScalar, grid_type::DIM> castPosition(
0094       const Vector3& position) const {
0095     std::array<ActsScalar, grid_type::DIM> casted{};
0096     fillCasts(position, casted,
0097               std::make_integer_sequence<std::size_t, grid_type::DIM>{});
0098     return casted;
0099   }
0100 
0101   /// Resolve duplicate on surface candidates
0102   ///
0103   /// @param gctx The geometry context of the current geometry
0104   /// @param surfaces is the surface candidates to check and resolve for duplicates
0105   void resolveDuplicates(const GeometryContext& gctx,
0106                          std::vector<const Acts::Surface*>& surfaces) const {
0107     // sorting the surfaces according to their radial distance
0108     std::sort(surfaces.begin(), surfaces.end(),
0109               [&gctx](const auto& surf1, const auto& surf2) {
0110                 if (surf1->center(gctx).x() != surf2->center(gctx).x()) {
0111                   return surf1->center(gctx).x() < surf2->center(gctx).x();
0112                 }
0113                 if (surf1->center(gctx).y() != surf2->center(gctx).y()) {
0114                   return surf1->center(gctx).y() < surf2->center(gctx).y();
0115                 }
0116                 return surf1->center(gctx).z() < surf2->center(gctx).z();
0117               });
0118 
0119     // Remove the duplicates
0120     surfaces.erase(std::unique(surfaces.begin(), surfaces.end()),
0121                    surfaces.end());
0122   }
0123 
0124  private:
0125   /// Unroll the cast loop
0126   /// @param position is the position of the update call
0127   /// @param a is the array to be filled
0128   template <typename Array, std::size_t... idx>
0129   void fillCasts(const Vector3& position, Array& a,
0130                  std::index_sequence<idx...> /*indices*/) const {
0131     ((a[idx] = VectorHelpers::cast(position, casts[idx])), ...);
0132   }
0133 };
0134 
0135 /// A path generator that generates a straight path along a direction
0136 /// in the grid
0137 struct PathGridSurfacesGenerator {
0138   std::vector<Vector3> operator()(Vector3 startPosition,
0139                                   const Vector3& direction, ActsScalar stepSize,
0140                                   std::size_t numberOfSteps) const {
0141     std::vector<Vector3> pathCoordinates = {};
0142     pathCoordinates.reserve(numberOfSteps);
0143 
0144     Vector3 position = std::move(startPosition);
0145     Vector3 step = stepSize * direction;
0146 
0147     for (std::size_t i = 0; i < numberOfSteps; i++) {
0148       pathCoordinates.push_back(position);
0149       position = position + step;
0150     }
0151 
0152     return pathCoordinates;
0153   }
0154 };
0155 
0156 }  // namespace Acts::Experimental