Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-02 08:44:28

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