File indexing completed on 2025-01-18 09:10:55
0001
0002
0003
0004
0005
0006
0007
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
0029 using grid_type = grid_t;
0030
0031
0032 grid_type grid;
0033
0034
0035 path_generator pgenerator;
0036
0037
0038 std::array<AxisDirection, grid_type::DIM> casts{};
0039
0040
0041 Transform3 transform = Transform3::Identity();
0042
0043
0044
0045
0046
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
0055
0056
0057
0058
0059
0060 void fill(const GeometryContext& gctx, NavigationState& nState) const {
0061
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
0083
0084
0085
0086
0087
0088 void update(const GeometryContext& gctx, NavigationState& nState) const {
0089 fill(gctx, nState);
0090 intitializeCandidates(gctx, nState);
0091 }
0092
0093
0094
0095
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
0105
0106
0107
0108 void resolveDuplicates(const GeometryContext& gctx,
0109 std::vector<const Acts::Surface*>& surfaces) const {
0110
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
0118 surfaces.erase(std::unique(surfaces.begin(), surfaces.end()),
0119 surfaces.end());
0120 }
0121
0122 private:
0123
0124
0125
0126 template <typename Array, std::size_t... idx>
0127 void fillCasts(const Vector3& position, Array& a,
0128 std::index_sequence<idx...> ) const {
0129 ((a[idx] = VectorHelpers::cast(position, casts[idx])), ...);
0130 }
0131 };
0132
0133
0134
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 }