Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-01 08:21:02

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