Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-17 07:58:51

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/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 /// Unroll the cast loop
0023 ///
0024 /// @tparam cast_container is the container type of cast objects
0025 /// @tparam Array is the array type to be filled
0026 ///
0027 /// @param position is the position of the update call
0028 /// @param globalCasts is the cast value vector from global to grid position
0029 /// @param ra is the array to be filled
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...> /*indices*/) {
0033   ((ra[idx] = VectorHelpers::cast(position, globalCasts[idx])), ...);
0034 }
0035 /// Cast into a lookup position
0036 ///
0037 /// This method allows to transform a global position into a grid position
0038 /// that is specified by binning values. It casts the global position info
0039 /// into a format suitable for the grid.
0040 ///
0041 /// @tparam cast_container is the container type of cast objects
0042 /// @tparam Array is the array type to be filled
0043 ///
0044 /// @param position is the position of the update call
0045 /// @param globalCasts is the cast value vector from global to grid position
0046 ///
0047 /// @return a grid point in an appropriate format
0048 template <typename grid_type, typename cast_container>
0049 typename grid_type::point_t castPosition(const Vector3& position,
0050                                          const cast_container& globalCasts) {
0051   // Fill the grid point from global
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 /// Unroll the local position loop
0059 ///
0060 /// @param lposition is the local position
0061 /// @param laccess the local accessors
0062 /// @param ra is the array to be filled
0063 ///
0064 /// @note void function that fills the provided array
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...> /*indices*/) {
0068   ((ra[idx] = lposition[laccess[idx]]), ...);
0069 }
0070 
0071 /// Access local parameters for a propriate lookup position
0072 ///
0073 /// This method allows to transform a local position into a
0074 /// grid position, it only works for 1-D and 2-D grids.
0075 ///
0076 /// @param lposition is the position of the update call
0077 /// @param laccess the local accessors
0078 ///
0079 /// @return an array suitable for the grid
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   // Fill the grid point from local according to the accessors
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 }  // namespace GridAccessHelpers
0096 
0097 namespace GridAccess {
0098 
0099 /// Interface class for owning delegate
0100 class IGlobalToGridLocal {
0101  public:
0102   virtual ~IGlobalToGridLocal() = default;
0103 };
0104 
0105 /// Interface class for owning delegate
0106 class IBoundToGridLocal {
0107  public:
0108   virtual ~IBoundToGridLocal() = default;
0109 };
0110 
0111 template <typename global_to_grid_local_t>
0112 class Affine3Transformed : public IGlobalToGridLocal {
0113  public:
0114   using grid_local_t = typename global_to_grid_local_t::grid_local_t;
0115 
0116   /// The global to local transformation
0117   global_to_grid_local_t globalToGridLocal;
0118 
0119   /// The transformation matrix
0120   Transform3 transform;
0121 
0122   /// Constructor
0123   ///
0124   /// @param g2gl is the global to grid local transformation
0125   /// @param t is the transformation matrix
0126   Affine3Transformed(global_to_grid_local_t g2gl, const Transform3& t)
0127       : globalToGridLocal(std::move(g2gl)), transform(t) {}
0128 
0129   /// Transform in to the local frame, then the grid local position
0130   ///
0131   /// @param position is the global position
0132   ///
0133   /// @return the grid position
0134   typename global_to_grid_local_t::grid_local_t toGridLocal(
0135       const Vector3& position) const {
0136     return globalToGridLocal.toGridLocal(transform * position);
0137   }
0138 };
0139 
0140 /// @brief A global (potentially casted) sub space of a global
0141 /// position
0142 /// @tparam ...Args
0143 template <AxisDirection... Args>
0144 class GlobalSubspace : public IGlobalToGridLocal {
0145  public:
0146   /// Type alias for grid-local coordinate array
0147   using grid_local_t = std::array<double, sizeof...(Args)>;
0148 
0149   /// Assert that size has to be bigger than 0
0150   static_assert(sizeof...(Args) > 0,
0151                 "GlobalSubspace: cannot have an empty binning value list.");
0152 
0153   /// Assert that size has to be smaller than 4
0154   static_assert(sizeof...(Args) <= 3,
0155                 "GlobalSubspace: cannot have more than 3 binning values.");
0156 
0157   // Constructor
0158   GlobalSubspace() = default;
0159 
0160   /// The axis directions of the subspace
0161   static constexpr std::array<AxisDirection, sizeof...(Args)> axisDirs = {
0162       Args...};
0163 
0164   /// Transform in to the local frame, then the grid local position
0165   ///
0166   /// @param position is the global position
0167   ///
0168   /// @return the grid position
0169   grid_local_t toGridLocal(const Vector3& position) const {
0170     // Fill the grid point from global
0171     grid_local_t glocal{};
0172     GridAccessHelpers::fillCasts(
0173         position, axisDirs, glocal,
0174         std::make_integer_sequence<std::size_t, sizeof...(Args)>{});
0175     return glocal;
0176   }
0177 };
0178 
0179 // The bound to grid local transformation, if only access of a subspace
0180 // is requested
0181 template <std::size_t... Args>
0182 class LocalSubspace : public IBoundToGridLocal {
0183  public:
0184   using grid_local_t = std::array<double, sizeof...(Args)>;
0185 
0186   /// Assert that the accessors are unique
0187   static_assert(sizeof...(Args) == 1 || sizeof...(Args) == 2,
0188                 "LocalSubspace: only 1 or 2 accessors are allowed.");
0189 
0190   /// Only 0 or 1 are allowed
0191   static_assert(((Args < 2) && ...),
0192                 "LocalSubspace: local access needs to be 0u or 1u");
0193 
0194   // Constructor
0195   LocalSubspace() = default;
0196 
0197   static constexpr std::array<std::size_t, sizeof...(Args)> accessors = {
0198       Args...};
0199 
0200   /// Access the local entries
0201   ///
0202   /// @param lposition is the local position
0203   ///
0204   /// @return the grid position
0205   grid_local_t toGridLocal(const Vector2& lposition) const {
0206     // Fill the grid point from local according to the accessors
0207     grid_local_t accessed{};
0208     GridAccessHelpers::fillLocal(
0209         lposition, accessors, accessed,
0210         std::make_integer_sequence<std::size_t, sizeof...(Args)>{});
0211     return accessed;
0212   }
0213 };
0214 
0215 class BoundCylinderToZPhi : public IBoundToGridLocal {
0216  public:
0217   double radius = 1.;
0218   double shift = 0.;
0219 
0220   /// Constructor with arguments
0221   /// @param r the radius
0222   /// @param z the shift
0223   BoundCylinderToZPhi(double r, double z) : radius(r), shift(z) {}
0224 
0225   std::array<double, 2u> toGridLocal(const Vector2& local) const {
0226     return {local[1u] + shift, local[0u] / radius};
0227   }
0228 
0229   using BoundDiscToRPhi = LocalSubspace<0u, 1u>;
0230 };
0231 
0232 // Definition of bound (on surface) to grid local representation delegate
0233 // 1 dimensional local grid
0234 using BoundToGridLocal1DimDelegate =
0235     OwningDelegate<std::array<double, 1u>(const Vector2&),
0236                    GridAccess::IBoundToGridLocal>;
0237 
0238 // Definition of global to grid local representation delegate
0239 // 1 dimensional local grid
0240 using GlobalToGridLocal1DimDelegate =
0241     OwningDelegate<std::array<double, 1u>(const Vector3&),
0242                    GridAccess::IGlobalToGridLocal>;
0243 
0244 // Definition of bound (on surface) to grid local representation delegate
0245 // 2 dimensional local grid
0246 using BoundToGridLocal2DimDelegate =
0247     OwningDelegate<std::array<double, 2u>(const Vector2&),
0248                    GridAccess::IBoundToGridLocal>;
0249 
0250 // Definition of global to grid local representation delegate
0251 // 2 dimensional local grid
0252 using GlobalToGridLocal2DimDelegate =
0253     OwningDelegate<std::array<double, 2u>(const Vector3&),
0254                    GridAccess::IGlobalToGridLocal>;
0255 
0256 }  // namespace GridAccess
0257 }  // namespace Acts