File indexing completed on 2026-05-16 07:35:25
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Utilities/AxisDefinitions.hpp"
0013 #include "Acts/Utilities/Delegate.hpp"
0014 #include "Acts/Utilities/VectorHelpers.hpp"
0015
0016 #include <array>
0017
0018 namespace Acts {
0019
0020 namespace GridAccessHelpers {
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 template <typename cast_container, typename Array, std::size_t... idx>
0031 void fillCasts(const Vector3& position, const cast_container& globalCasts,
0032 Array& ra, std::index_sequence<idx...> ) {
0033 ((ra[idx] = VectorHelpers::cast(position, globalCasts[idx])), ...);
0034 }
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 template <typename grid_type, typename cast_container>
0049 typename grid_type::point_t castPosition(const Vector3& position,
0050 const cast_container& globalCasts) {
0051
0052 typename grid_type::point_t casted{};
0053 fillCasts(position, globalCasts, casted,
0054 std::make_integer_sequence<std::size_t, grid_type::DIM>{});
0055 return casted;
0056 }
0057
0058
0059
0060
0061
0062
0063
0064
0065 template <typename Array, typename local_indices, std::size_t... idx>
0066 void fillLocal(const Vector2& lposition, const local_indices& laccess,
0067 Array& ra, std::index_sequence<idx...> ) {
0068 ((ra[idx] = lposition[laccess[idx]]), ...);
0069 }
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 template <typename grid_type, typename local_indices>
0081 typename grid_type::point_t accessLocal(const Vector2& lposition,
0082 const local_indices& laccess) {
0083 if constexpr (grid_type::DIM > 2u) {
0084 throw std::invalid_argument(
0085 "GridAccessHelper: only 1-D and 2-D grids are possible for local "
0086 "access.");
0087 }
0088
0089 typename grid_type::point_t accessed{};
0090 fillLocal(lposition, laccess, accessed,
0091 std::make_integer_sequence<std::size_t, grid_type::DIM>{});
0092 return accessed;
0093 }
0094
0095 }
0096
0097 namespace GridAccess {
0098
0099
0100 class IGlobalToGridLocal {
0101 public:
0102 virtual ~IGlobalToGridLocal() = default;
0103 };
0104
0105
0106 class IBoundToGridLocal {
0107 public:
0108 virtual ~IBoundToGridLocal() = default;
0109 };
0110
0111
0112 template <typename global_to_grid_local_t>
0113 class Affine3Transformed : public IGlobalToGridLocal {
0114 public:
0115
0116 using grid_local_t = typename global_to_grid_local_t::grid_local_t;
0117
0118
0119 global_to_grid_local_t globalToGridLocal;
0120
0121
0122 Transform3 transform;
0123
0124
0125
0126
0127
0128 Affine3Transformed(global_to_grid_local_t g2gl, const Transform3& t)
0129 : globalToGridLocal(std::move(g2gl)), transform(t) {}
0130
0131
0132
0133
0134
0135
0136 typename global_to_grid_local_t::grid_local_t toGridLocal(
0137 const Vector3& position) const {
0138 return globalToGridLocal.toGridLocal(transform * position);
0139 }
0140 };
0141
0142
0143
0144
0145 template <AxisDirection... Args>
0146 class GlobalSubspace : public IGlobalToGridLocal {
0147 public:
0148
0149 using grid_local_t = std::array<double, sizeof...(Args)>;
0150
0151
0152 static_assert(sizeof...(Args) > 0,
0153 "GlobalSubspace: cannot have an empty binning value list.");
0154
0155
0156 static_assert(sizeof...(Args) <= 3,
0157 "GlobalSubspace: cannot have more than 3 binning values.");
0158
0159
0160 GlobalSubspace() = default;
0161
0162
0163 static constexpr std::array<AxisDirection, sizeof...(Args)> axisDirs = {
0164 Args...};
0165
0166
0167
0168
0169
0170
0171 grid_local_t toGridLocal(const Vector3& position) const {
0172
0173 grid_local_t glocal{};
0174 GridAccessHelpers::fillCasts(
0175 position, axisDirs, glocal,
0176 std::make_integer_sequence<std::size_t, sizeof...(Args)>{});
0177 return glocal;
0178 }
0179 };
0180
0181
0182
0183
0184 template <std::size_t... Args>
0185 class LocalSubspace : public IBoundToGridLocal {
0186 public:
0187
0188 using grid_local_t = std::array<double, sizeof...(Args)>;
0189
0190
0191 static_assert(sizeof...(Args) == 1 || sizeof...(Args) == 2,
0192 "LocalSubspace: only 1 or 2 accessors are allowed.");
0193
0194
0195 static_assert(((Args < 2) && ...),
0196 "LocalSubspace: local access needs to be 0u or 1u");
0197
0198
0199 LocalSubspace() = default;
0200
0201
0202 static constexpr std::array<std::size_t, sizeof...(Args)> accessors = {
0203 Args...};
0204
0205
0206
0207
0208
0209
0210 grid_local_t toGridLocal(const Vector2& lposition) const {
0211
0212 grid_local_t accessed{};
0213 GridAccessHelpers::fillLocal(
0214 lposition, accessors, accessed,
0215 std::make_integer_sequence<std::size_t, sizeof...(Args)>{});
0216 return accessed;
0217 }
0218 };
0219
0220
0221 class BoundCylinderToZPhi : public IBoundToGridLocal {
0222 public:
0223
0224 double radius = 1.;
0225
0226 double shift = 0.;
0227
0228
0229
0230
0231 BoundCylinderToZPhi(double r, double z) : radius(r), shift(z) {}
0232
0233
0234
0235
0236 std::array<double, 2u> toGridLocal(const Vector2& local) const {
0237 return {local[1u] + shift, local[0u] / radius};
0238 }
0239
0240
0241 using BoundDiscToRPhi = LocalSubspace<0u, 1u>;
0242 };
0243
0244
0245
0246 using BoundToGridLocal1DimDelegate =
0247 OwningDelegate<std::array<double, 1u>(const Vector2&),
0248 GridAccess::IBoundToGridLocal>;
0249
0250
0251
0252 using GlobalToGridLocal1DimDelegate =
0253 OwningDelegate<std::array<double, 1u>(const Vector3&),
0254 GridAccess::IGlobalToGridLocal>;
0255
0256
0257
0258 using BoundToGridLocal2DimDelegate =
0259 OwningDelegate<std::array<double, 2u>(const Vector2&),
0260 GridAccess::IBoundToGridLocal>;
0261
0262
0263
0264 using GlobalToGridLocal2DimDelegate =
0265 OwningDelegate<std::array<double, 2u>(const Vector3&),
0266 GridAccess::IGlobalToGridLocal>;
0267
0268 }
0269 }