Back to home page

EIC code displayed by LXR

 
 

    


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

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 #include <vector>
0018 
0019 namespace Acts {
0020 
0021 namespace GridAccessHelpers {
0022 
0023 /// Unroll the cast loop
0024 ///
0025 /// @tparam cast_container is the container type of cast objects
0026 /// @tparam Array is the array type to be filled
0027 ///
0028 /// @param position is the position of the update call
0029 /// @param globalCasts is the cast value vector from global to grid position
0030 /// @param ra is the array to be filled
0031 template <typename cast_container, typename Array, std::size_t... idx>
0032 void fillCasts(const Vector3& position, const cast_container& globalCasts,
0033                Array& ra, std::index_sequence<idx...> /*indices*/) {
0034   ((ra[idx] = VectorHelpers::cast(position, globalCasts[idx])), ...);
0035 }
0036 /// Cast into a lookup position
0037 ///
0038 /// This method allows to transform a global position into a grid position
0039 /// that is specified by binning values. It casts the global position info
0040 /// into a format suitable for the grid.
0041 ///
0042 /// @tparam cast_container is the container type of cast objects
0043 /// @tparam Array is the array type to be filled
0044 ///
0045 /// @param position is the position of the update call
0046 /// @param globalCasts is the cast value vector from global to grid position
0047 ///
0048 /// @return a grid point in an appropriate format
0049 template <typename grid_type, typename cast_container>
0050 typename grid_type::point_t castPosition(const Vector3& position,
0051                                          const cast_container& globalCasts) {
0052   // Fill the grid point from global
0053   typename grid_type::point_t casted{};
0054   fillCasts(position, globalCasts, casted,
0055             std::make_integer_sequence<std::size_t, grid_type::DIM>{});
0056   return casted;
0057 }
0058 
0059 /// Unroll the local position loop
0060 ///
0061 /// @param lposition is the local position
0062 /// @param laccess the local accessors
0063 /// @param ra is the array to be filled
0064 ///
0065 /// @note void function that fills the provided array
0066 template <typename Array, typename local_indices, std::size_t... idx>
0067 void fillLocal(const Vector2& lposition, const local_indices& laccess,
0068                Array& ra, std::index_sequence<idx...> /*indices*/) {
0069   ((ra[idx] = lposition[laccess[idx]]), ...);
0070 }
0071 
0072 /// Access local parameters for a propriate lookup position
0073 ///
0074 /// This method allows to transform a local position into a
0075 /// grid position, it only works for 1-D and 2-D grids.
0076 ///
0077 /// @param lposition is the position of the update call
0078 /// @param laccess the local accessors
0079 ///
0080 /// @return an array suitable for the grid
0081 template <typename grid_type, typename local_indices>
0082 typename grid_type::point_t accessLocal(const Vector2& lposition,
0083                                         const local_indices& laccess) {
0084   if constexpr (grid_type::DIM > 2u) {
0085     throw std::invalid_argument(
0086         "GridAccessHelper: only 1-D and 2-D grids are possible for local "
0087         "access.");
0088   }
0089   // Fill the grid point from local according to the accessors
0090   typename grid_type::point_t accessed{};
0091   fillLocal(lposition, laccess, accessed,
0092             std::make_integer_sequence<std::size_t, grid_type::DIM>{});
0093   return accessed;
0094 }
0095 
0096 }  // namespace GridAccessHelpers
0097 
0098 namespace GridAccess {
0099 
0100 /// Interface class for owning delegate
0101 class IGlobalToGridLocal {
0102  public:
0103   virtual ~IGlobalToGridLocal() = default;
0104 };
0105 
0106 /// Interface class for owning delegate
0107 class IBoundToGridLocal {
0108  public:
0109   virtual ~IBoundToGridLocal() = default;
0110 };
0111 
0112 template <typename global_to_grid_local_t>
0113 class Affine3Transformed : public IGlobalToGridLocal {
0114  public:
0115   using grid_local_t = typename global_to_grid_local_t::grid_local_t;
0116 
0117   /// The global to local transformation
0118   global_to_grid_local_t globalToGridLocal;
0119 
0120   /// The transformation matrix
0121   Transform3 transform;
0122 
0123   /// Constructor
0124   ///
0125   /// @param g2gl is the global to grid local transformation
0126   /// @param t is the transformation matrix
0127   Affine3Transformed(global_to_grid_local_t g2gl, const Transform3& t)
0128       : globalToGridLocal(std::move(g2gl)), transform(t) {}
0129 
0130   /// Transform in to the local frame, then the grid local position
0131   ///
0132   /// @param position is the global position
0133   ///
0134   /// @return the grid position
0135   typename global_to_grid_local_t::grid_local_t toGridLocal(
0136       const Vector3& position) const {
0137     return globalToGridLocal.toGridLocal(transform * position);
0138   }
0139 };
0140 
0141 /// @brief A global (potentially casted) sub space of a global
0142 /// position
0143 /// @tparam ...Args
0144 template <AxisDirection... Args>
0145 class GlobalSubspace : public IGlobalToGridLocal {
0146  public:
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