Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 07:51:59

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   using grid_local_t = std::array<double, sizeof...(Args)>;
0147 
0148   /// Assert that size has to be bigger than 0
0149   static_assert(sizeof...(Args) > 0,
0150                 "GlobalSubspace: cannot have an empty binning value list.");
0151 
0152   /// Assert that size has to be smaller than 4
0153   static_assert(sizeof...(Args) <= 3,
0154                 "GlobalSubspace: cannot have more than 3 binning values.");
0155 
0156   // Constructor
0157   GlobalSubspace() = default;
0158 
0159   /// The axis directions of the subspace
0160   static constexpr std::array<AxisDirection, sizeof...(Args)> axisDirs = {
0161       Args...};
0162 
0163   /// Transform in to the local frame, then the grid local position
0164   ///
0165   /// @param position is the global position
0166   ///
0167   /// @return the grid position
0168   grid_local_t toGridLocal(const Vector3& position) const {
0169     // Fill the grid point from global
0170     grid_local_t glocal{};
0171     GridAccessHelpers::fillCasts(
0172         position, axisDirs, glocal,
0173         std::make_integer_sequence<std::size_t, sizeof...(Args)>{});
0174     return glocal;
0175   }
0176 };
0177 
0178 // The bound to grid local transformation, if only access of a subspace
0179 // is requested
0180 template <std::size_t... Args>
0181 class LocalSubspace : public IBoundToGridLocal {
0182  public:
0183   using grid_local_t = std::array<double, sizeof...(Args)>;
0184 
0185   /// Assert that the accessors are unique
0186   static_assert(sizeof...(Args) == 1 || sizeof...(Args) == 2,
0187                 "LocalSubspace: only 1 or 2 accessors are allowed.");
0188 
0189   /// Only 0 or 1 are allowed
0190   static_assert(((Args < 2) && ...),
0191                 "LocalSubspace: local access needs to be 0u or 1u");
0192 
0193   // Constructor
0194   LocalSubspace() = default;
0195 
0196   static constexpr std::array<std::size_t, sizeof...(Args)> accessors = {
0197       Args...};
0198 
0199   /// Access the local entries
0200   ///
0201   /// @param lposition is the local position
0202   ///
0203   /// @return the grid position
0204   grid_local_t toGridLocal(const Vector2& lposition) const {
0205     // Fill the grid point from local according to the accessors
0206     grid_local_t accessed{};
0207     GridAccessHelpers::fillLocal(
0208         lposition, accessors, accessed,
0209         std::make_integer_sequence<std::size_t, sizeof...(Args)>{});
0210     return accessed;
0211   }
0212 };
0213 
0214 class BoundCylinderToZPhi : public IBoundToGridLocal {
0215  public:
0216   double radius = 1.;
0217   double shift = 0.;
0218 
0219   /// Constructor with arguments
0220   /// @param r the radius
0221   /// @param z the shift
0222   BoundCylinderToZPhi(double r, double z) : radius(r), shift(z) {}
0223 
0224   std::array<double, 2u> toGridLocal(const Vector2& local) const {
0225     return {local[1u] + shift, local[0u] / radius};
0226   }
0227 
0228   using BoundDiscToRPhi = LocalSubspace<0u, 1u>;
0229 };
0230 
0231 // Definition of bound (on surface) to grid local representation delegate
0232 // 1 dimensional local grid
0233 using BoundToGridLocal1DimDelegate =
0234     OwningDelegate<std::array<double, 1u>(const Vector2&),
0235                    GridAccess::IBoundToGridLocal>;
0236 
0237 // Definition of global to grid local representation delegate
0238 // 1 dimensional local grid
0239 using GlobalToGridLocal1DimDelegate =
0240     OwningDelegate<std::array<double, 1u>(const Vector3&),
0241                    GridAccess::IGlobalToGridLocal>;
0242 
0243 // Definition of bound (on surface) to grid local representation delegate
0244 // 2 dimensional local grid
0245 using BoundToGridLocal2DimDelegate =
0246     OwningDelegate<std::array<double, 2u>(const Vector2&),
0247                    GridAccess::IBoundToGridLocal>;
0248 
0249 // Definition of global to grid local representation delegate
0250 // 2 dimensional local grid
0251 using GlobalToGridLocal2DimDelegate =
0252     OwningDelegate<std::array<double, 2u>(const Vector3&),
0253                    GridAccess::IGlobalToGridLocal>;
0254 
0255 }  // namespace GridAccess
0256 }  // namespace Acts