Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:10:55

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