Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:42: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/Material/ISurfaceMaterial.hpp"
0013 #include "Acts/Material/MaterialSlab.hpp"
0014 #include "Acts/Utilities/AnyGridView.hpp"
0015 #include "Acts/Utilities/Delegate.hpp"
0016 #include "Acts/Utilities/Grid.hpp"
0017 #include "Acts/Utilities/GridAccessHelpers.hpp"
0018 #include "Acts/Utilities/ProtoAxis.hpp"
0019 
0020 #include <ostream>
0021 #include <stdexcept>
0022 #include <vector>
0023 
0024 namespace Acts {
0025 
0026 /// @brief Base class for material accessors, this is needed
0027 /// for the I/O of the different grid material types, in the actual
0028 /// implementation the material accessor is a template parameter.
0029 struct IGridMaterialAccessor {
0030   virtual ~IGridMaterialAccessor() = default;
0031 };
0032 
0033 /// @brief  This is an accessor for cases where the material is directly stored
0034 /// in the grid, it simply forwards the grid entry in const and non-const way.
0035 struct GridMaterialAccessor : public IGridMaterialAccessor {
0036   /// @brief  Broadcast the type of the material slab
0037   using grid_value_type = MaterialSlab;
0038   /// @brief  Direct const access to the material slap sorted in the grid
0039   /// @tparam grid_type the type of the grid, also defines the point type
0040   /// @param grid the grid
0041   /// @param point the lookup point (already casted from global, or filled from local)
0042   ///
0043   /// @return the material slab from the grid bin associated to the lookup point
0044   template <typename grid_type>
0045   inline const MaterialSlab& slab(
0046       grid_type& grid, const typename grid_type::point_t& point) const {
0047     return grid.atPosition(point);
0048   }
0049 
0050   /// @brief Scale the material (by scaling the thickness)
0051   ///
0052   /// @param grid the grid (ignored)
0053   /// @param scale the amount of the scaling
0054   ///
0055   /// @note this is not particularly fast
0056   template <typename grid_type>
0057   void scale(grid_type& grid, double scale) {
0058     // Loop through the grid bins, get the indices and scale the material
0059     for (std::size_t ib = 0; ib < grid.size(); ++ib) {
0060       grid.at(ib).scaleThickness(static_cast<float>(scale));
0061     }
0062   }
0063 };
0064 
0065 /// @brief  This is an accessor for cases where the material is filled in a vector
0066 /// and then indexed by the grid
0067 struct IndexedMaterialAccessor : public IGridMaterialAccessor {
0068   /// Broadcast the grid_value_type
0069   using grid_value_type = std::size_t;
0070 
0071   /// @brief The internal storage of the material
0072   /// @param mmaterial Vector of material slabs to store and access by index
0073   explicit IndexedMaterialAccessor(std::vector<MaterialSlab>&& mmaterial)
0074       : IGridMaterialAccessor(), material(std::move(mmaterial)) {}
0075 
0076   /// @brief The internal storage of the material
0077   std::vector<MaterialSlab> material;
0078   /// @brief  Direct const access to the material slap sorted in the grid
0079   /// @tparam grid_type the type of the grid, also defines the point type
0080   /// @param grid the grid
0081   /// @param point the lookup point (already casted from global, or filled from local)
0082   ///
0083   /// @return the material slab from the grid bin associated to the lookup point
0084   template <typename grid_type>
0085   inline const MaterialSlab& slab(
0086       const grid_type& grid, const typename grid_type::point_t& point) const {
0087     auto index = grid.atPosition(point);
0088     return material[index];
0089   }
0090 
0091   /// @brief Scale the material (by scaling the thickness)
0092   ///
0093   /// @param scale the amount of the scaling
0094   template <typename grid_type>
0095   void scale(grid_type& /*grid*/, double scale) {
0096     for (auto& m : material) {
0097       m.scaleThickness(static_cast<float>(scale));
0098     }
0099   }
0100 };
0101 
0102 /// @brief  This is an accessor for cases where the material is filled in a global
0103 /// material vector that is accessed from the different material grids.
0104 struct GloballyIndexedMaterialAccessor : public IGridMaterialAccessor {
0105   /// Constructor with global material vector
0106   /// @param gMaterial Shared pointer to global material vector
0107   /// @param shared Whether material entries are shared across grid points
0108   explicit GloballyIndexedMaterialAccessor(
0109       std::shared_ptr<std::vector<MaterialSlab>> gMaterial, bool shared = false)
0110       : IGridMaterialAccessor(),
0111         globalMaterial(std::move(gMaterial)),
0112         sharedEntries(shared) {}
0113 
0114   /// Broadcast the grid_value_type
0115   using grid_value_type = std::size_t;
0116 
0117   /// @brief The internal storage of the material
0118   std::shared_ptr<std::vector<MaterialSlab>> globalMaterial = nullptr;
0119 
0120   /// Indicate if you have entries bins across different grids, e.g. by
0121   /// running a compression/clustering algorithm.
0122   ///
0123   /// It is the responsibility of the user to set this flag correctly.
0124   bool sharedEntries = false;
0125 
0126   /// @brief  Direct const access to the material slap sorted in the grid
0127   ///
0128   /// @tparam grid_type the type of the grid, also defines the point type
0129   ///
0130   /// @param grid the grid holding the indices into the global material vector
0131   /// @param point the lookup point (already casted from global, or filled from local)
0132   ///
0133   /// @return the material slab from the grid bin associated to the lookup point
0134   template <typename grid_type>
0135   inline const MaterialSlab& slab(
0136       const grid_type& grid, const typename grid_type::point_t& point) const {
0137     auto index = grid.atPosition(point);
0138     return (*globalMaterial)[index];
0139   }
0140 
0141   /// @brief Scale the material (by scaling the thickness)
0142   ///
0143   /// @param grid the grid holding the indices into the global material vector
0144   /// @param scale the amount of the scaling
0145   ///
0146   /// @note this will scale only the bins touched by this grid, however,
0147   /// if there are shared bins, then it will throw an exception as the
0148   /// outcome is unpredictable.
0149   ///
0150   template <typename grid_type>
0151   void scale(grid_type& grid, double scale) {
0152     if (sharedEntries) {
0153       throw std::invalid_argument(
0154           "GloballyIndexedMaterialAccessor: shared entry scaling is not "
0155           "supported.");
0156     }
0157     // Loop through the grid bins, get the indices and scale the material
0158     for (std::size_t ib = 0; ib < grid.size(); ++ib) {
0159       auto index = grid.at(ib);
0160       (*globalMaterial)[index].scaleThickness(static_cast<float>(scale));
0161     }
0162   }
0163 };
0164 
0165 /// Base class for the concrete templated grid surface material types.
0166 /// This allows referning to all template instances as the same base class type.
0167 class IGridSurfaceMaterialBase : public ISurfaceMaterial {};
0168 
0169 /// Intermediate interface to the grid surface material given access to the grid
0170 /// and the material accessor.
0171 template <typename grid_value_t>
0172 class IGridSurfaceMaterial : public IGridSurfaceMaterialBase {
0173  public:
0174   /// @brief Accessor to the grid interface
0175   /// @return Reference to the grid interface
0176   virtual const IGrid& grid() const = 0;
0177 
0178   /// @brief Accessor to the material accessor
0179   /// @return Reference to the material accessor
0180   virtual const IGridMaterialAccessor& materialAccessor() const = 0;
0181 
0182   /// @brief Accessor to the bound to grid local delegate
0183   /// @return Reference to the bound to grid local coordinate transformation delegate
0184   virtual const GridAccess::IBoundToGridLocal& boundToGridLocal() const = 0;
0185 
0186   /// @brief Accessor to the global to grid local delegate
0187   /// @return Reference to the global to grid local coordinate transformation delegate
0188   virtual const GridAccess::IGlobalToGridLocal& globalToGridLocal() const = 0;
0189 
0190   /// Return the type erased grid view
0191   /// @return Type-erased grid view for accessing grid contents
0192   virtual AnyGridView<grid_value_t> gridView() = 0;
0193 
0194   /// Return the type erased (const) grid view
0195   /// @return Type-erased const grid view for read-only access to grid contents
0196   virtual AnyGridConstView<grid_value_t> gridConstView() const = 0;
0197 };
0198 
0199 /// @brief GridSurfaceMaterialT
0200 ///
0201 /// It extends the @c ISurfaceMaterial base class and allows to create
0202 /// material maps associated to a grid structure
0203 ///
0204 /// @tparam grid_type is the type of the grid used here
0205 /// @tparam material_accessor_type is the type of the accessor to the material
0206 ///
0207 /// It is templated on the material type and a slab accessor type in order
0208 /// to allow it to be used in the material recording as well.
0209 template <typename grid_t, typename material_accessor_t>
0210 class GridSurfaceMaterialT
0211     : public IGridSurfaceMaterial<
0212           typename material_accessor_t::grid_value_type> {
0213  public:
0214   /// Type alias for bound coordinates to grid local coordinates conversion
0215   /// delegate
0216   using BoundToGridLocalDelegate =
0217       OwningDelegate<typename grid_t::point_t(const Vector2&),
0218                      GridAccess::IBoundToGridLocal>;
0219 
0220   /// Type alias for global coordinates to grid local coordinates conversion
0221   /// delegate
0222   using GlobalToGridLocalDelegate =
0223       OwningDelegate<typename grid_t::point_t(const Vector3&),
0224                      GridAccess::IGlobalToGridLocal>;
0225 
0226   /// Broadcast grid type
0227   using grid_type = grid_t;
0228 
0229   /// Broadcast material accessor type
0230   using material_accessor_type = material_accessor_t;
0231 
0232   /// @brief Constructor for indexed surface material
0233   ///
0234   /// @param grid the index grid steering the access to the material vector
0235   /// @param materialAccessor the material accessor: from grid, from indexed vector
0236   /// @param boundToGridLocal the delegation from bound to grid local frame
0237   /// @param globalToGridLocal the delegation from global into grid local frame
0238   GridSurfaceMaterialT(grid_type&& grid,
0239                        material_accessor_type&& materialAccessor,
0240                        BoundToGridLocalDelegate boundToGridLocal,
0241                        GlobalToGridLocalDelegate globalToGridLocal)
0242       : m_grid(std::move(grid)),
0243         m_materialAccessor(std::move(materialAccessor)),
0244         m_globalToGridLocal(std::move(globalToGridLocal)),
0245         m_boundToGridLocal(std::move(boundToGridLocal)) {
0246     if (!m_globalToGridLocal.connected()) {
0247       throw std::invalid_argument(
0248           "GridSurfaceMaterialT: GlobalToGridLocalDelegate is not connected.");
0249     }
0250     if (!m_boundToGridLocal.connected()) {
0251       throw std::invalid_argument(
0252           "GridSurfaceMaterialT: BoundToGridLocalDelegate is not connected.");
0253     }
0254   }
0255 
0256   /// @copydoc ISurfaceMaterial::materialSlab(const Vector2&) const
0257   const MaterialSlab& materialSlab(const Vector2& lp) const final {
0258     return m_materialAccessor.slab(m_grid, m_boundToGridLocal(lp));
0259   }
0260 
0261   /// @copydoc ISurfaceMaterial::materialSlab(const Vector3&) const
0262   const MaterialSlab& materialSlab(const Vector3& gp) const final {
0263     return m_materialAccessor.slab(m_grid, m_globalToGridLocal(gp));
0264   }
0265 
0266   /// Scale operator
0267   ///
0268   /// @param factor is the scale factor applied
0269   /// @return Reference to this surface material for method chaining
0270   ISurfaceMaterial& scale(double factor) final {
0271     m_materialAccessor.scale(m_grid, factor);
0272     return (*this);
0273   }
0274 
0275   /// Output Method for std::ostream, to be overloaded by child classes
0276   /// @param sl Output stream to write to
0277   /// @return Reference to the output stream
0278   std::ostream& toStream(std::ostream& sl) const final {
0279     sl << "GridSurfaceMaterial - material access via accessor.";
0280     return sl;
0281   }
0282 
0283   /// @brief Accessor to the grid
0284   /// @return Reference to the underlying grid
0285   const grid_type& grid() const final { return m_grid; }
0286 
0287   // Return a type-erased indexed grid view
0288   /// @return Type-erased grid view for accessing grid contents
0289   AnyGridView<typename material_accessor_t::grid_value_type> gridView() final {
0290     return AnyGridView<typename material_accessor_t::grid_value_type>(m_grid);
0291   }
0292 
0293   // Return a type-erased indexed const grid view
0294   /// @return Type-erased const grid view for read-only access to grid contents
0295   AnyGridConstView<typename material_accessor_t::grid_value_type>
0296   gridConstView() const final {
0297     return AnyGridConstView<typename material_accessor_t::grid_value_type>(
0298         m_grid);
0299   }
0300 
0301   /// @brief Accessor to the material accessor
0302   /// @return Reference to the material accessor
0303   const material_accessor_type& materialAccessor() const final {
0304     return m_materialAccessor;
0305   }
0306 
0307   /// @brief Accessor to the bound to grid local delegate
0308   /// @return Reference to the bound to grid local coordinate transformation delegate
0309   const GridAccess::IBoundToGridLocal& boundToGridLocal() const final {
0310     return *(m_boundToGridLocal.instance());
0311   }
0312 
0313   /// @brief Accessor to the bound to grid local delegate
0314   /// @return Reference to the bound to grid local delegate
0315   const BoundToGridLocalDelegate& boundToGridLocalDelegate() const {
0316     return m_boundToGridLocal;
0317   }
0318 
0319   /// @brief Accessor to the global to grid local delegate
0320   /// @return Reference to the global to grid local coordinate transformation delegate
0321   const GridAccess::IGlobalToGridLocal& globalToGridLocal() const final {
0322     return *(m_globalToGridLocal.instance());
0323   }
0324 
0325   /// @brief Accessor to the global to grid local delegate
0326   /// @return Reference to the global to grid local delegate
0327   const GlobalToGridLocalDelegate& globalToGridLocalDelegate() const {
0328     return m_globalToGridLocal;
0329   }
0330 
0331  private:
0332   /// @brief The grid
0333   grid_type m_grid;
0334 
0335   /// @brief The stored material accessor
0336   material_accessor_type m_materialAccessor;
0337 
0338   /// The global to grid local delegate
0339   GlobalToGridLocalDelegate m_globalToGridLocal;
0340 
0341   /// The bound to grid local delegate
0342   BoundToGridLocalDelegate m_boundToGridLocal;
0343 };
0344 
0345 /// @brief Type alias for surface material indexed by local coordinates
0346 /// @details Surface material implementation that uses local coordinate indexing
0347 /// @tparam grid_type The type of grid used for material mapping
0348 template <typename grid_type>
0349 using IndexedSurfaceMaterial =
0350     GridSurfaceMaterialT<grid_type, IndexedMaterialAccessor>;
0351 
0352 /// @brief Type alias for surface material indexed by global coordinates
0353 /// @details Surface material implementation that uses global coordinate indexing
0354 template <typename grid_type>
0355 using GloballyIndexedSurfaceMaterial =
0356     GridSurfaceMaterialT<grid_type, GloballyIndexedMaterialAccessor>;
0357 
0358 /// @brief Type alias for grid-based surface material
0359 /// @details Surface material implementation using a regular grid structure
0360 template <typename grid_type>
0361 using GridSurfaceMaterial =
0362     GridSurfaceMaterialT<grid_type, GridMaterialAccessor>;
0363 
0364 }  // namespace Acts