Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-13 08:28:00

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/Delegate.hpp"
0015 #include "Acts/Utilities/GridAccessHelpers.hpp"
0016 
0017 #include <ostream>
0018 #include <stdexcept>
0019 #include <vector>
0020 
0021 namespace Acts {
0022 
0023 /// @brief  This is an accessor for cases where the material is directly stored
0024 /// in the grid, it simply forwards the grid entry in const and non-const way.
0025 struct GridMaterialAccessor {
0026   /// @brief  Direct const access to the material slap sorted in the grid
0027   /// @tparam grid_type the type of the grid, also defines the point type
0028   /// @param grid the grid
0029   /// @param point the lookup point (already casted from global, or filled from local)
0030   ///
0031   /// @return the material slab from the grid bin associated to the lookup point
0032   template <typename grid_type>
0033   inline const MaterialSlab& slab(
0034       grid_type& grid, const typename grid_type::point_t& point) const {
0035     return grid.atPosition(point);
0036   }
0037 
0038   /// @brief Scale the material (by scaling the thickness)
0039   ///
0040   /// @param grid the grid (ignored)
0041   /// @param scale the amount of the scaling
0042   ///
0043   /// @note this is not particularly fast
0044   template <typename grid_type>
0045   void scale(grid_type& grid, double scale) {
0046     // Loop through the grid bins, get the indices and scale the material
0047     for (std::size_t ib = 0; ib < grid.size(); ++ib) {
0048       grid.at(ib).scaleThickness(scale);
0049     }
0050   }
0051 };
0052 
0053 /// @brief  This is an accessor for cases where the material is filled in a vector
0054 /// and then indexed by the grid
0055 struct IndexedMaterialAccessor {
0056   /// @brief The internal storage of the material
0057   std::vector<MaterialSlab> material;
0058   /// @brief  Direct const access to the material slap sorted in the grid
0059   /// @tparam grid_type the type of the grid, also defines the point type
0060   /// @param grid the grid
0061   /// @param point the lookup point (already casted from global, or filled from local)
0062   ///
0063   /// @return the material slab from the grid bin associated to the lookup point
0064   template <typename grid_type>
0065   inline const MaterialSlab& slab(
0066       const grid_type& grid, const typename grid_type::point_t& point) const {
0067     auto index = grid.atPosition(point);
0068     return material[index];
0069   }
0070 
0071   /// @brief Scale the material (by scaling the thickness)
0072   ///
0073   /// @param scale the amount of the scaling
0074   template <typename grid_type>
0075   void scale(grid_type& /*grid*/, double scale) {
0076     for (auto& m : material) {
0077       m.scaleThickness(scale);
0078     }
0079   }
0080 };
0081 
0082 /// @brief  This is an accessor for cases where the material is filled in a global
0083 /// material vector that is accessed from the different material grids.
0084 struct GloballyIndexedMaterialAccessor {
0085   /// @brief The internal storage of the material
0086   std::shared_ptr<std::vector<MaterialSlab>> globalMaterial = nullptr;
0087 
0088   /// Indicate if you have entries bins across different grids, e.g. by
0089   /// running a compression/clustering algorithm.
0090   ///
0091   /// It is the responsibility of the user to set this flag correctly.
0092   bool sharedEntries = false;
0093 
0094   /// @brief  Direct const access to the material slap sorted in the grid
0095   ///
0096   /// @tparam grid_type the type of the grid, also defines the point type
0097   ///
0098   /// @param grid the grid holding the indices into the global material vector
0099   /// @param point the lookup point (already casted from global, or filled from local)
0100   ///
0101   /// @return the material slab from the grid bin associated to the lookup point
0102   template <typename grid_type>
0103   inline const MaterialSlab& slab(
0104       const grid_type& grid, const typename grid_type::point_t& point) const {
0105     auto index = grid.atPosition(point);
0106     return (*globalMaterial)[index];
0107   }
0108 
0109   /// @brief Scale the material (by scaling the thickness)
0110   ///
0111   /// @param grid the grid holding the indices into the global material vector
0112   /// @param scale the amount of the scaling
0113   ///
0114   /// @note this will scale only the bins touched by this grid, however,
0115   /// if there are shared bins, then it will throw an exception as the
0116   /// outcome is unpredictable.
0117   ///
0118   template <typename grid_type>
0119   void scale(grid_type& grid, double scale) {
0120     if (sharedEntries) {
0121       throw std::invalid_argument(
0122           "GloballyIndexedMaterialAccessor: shared entry scaling is not "
0123           "supported.");
0124     }
0125     // Loop through the grid bins, get the indices and scale the material
0126     for (std::size_t ib = 0; ib < grid.size(); ++ib) {
0127       auto index = grid.at(ib);
0128       (*globalMaterial)[index].scaleThickness(scale);
0129     }
0130   }
0131 };
0132 
0133 /// @brief GridSurfaceMaterialT
0134 ///
0135 /// It extends the @c ISurfaceMaterial base class and allows to create
0136 /// material maps associated to a grid structure
0137 ///
0138 /// @tparam grid_type is the type of the grid used here
0139 /// @tparam material_accessor_type is the type of the accessor to the material
0140 ///
0141 /// It is templated on the material type and a slab accessor type in order
0142 /// to allow it to be used in the material recording as well.
0143 template <typename grid_t, typename material_accessor_t = GridMaterialAccessor>
0144 class GridSurfaceMaterialT : public ISurfaceMaterial {
0145  public:
0146   // Definition of bound (on surface) to grid local representation delegate
0147   using BoundToGridLocalDelegate =
0148       OwningDelegate<typename grid_t::point_t(const Vector2&),
0149                      GridAccess::IBoundToGridLocal>;
0150 
0151   // Definition of global to grid local representation delegate
0152   using GlobalToGridLocalDelegate =
0153       OwningDelegate<typename grid_t::point_t(const Vector3&),
0154                      GridAccess::IGlobalToGridLocal>;
0155 
0156   /// Broadcast grid type
0157   using grid_type = grid_t;
0158 
0159   /// Broadcast material accessor type
0160   using material_accessor_type = material_accessor_t;
0161 
0162   /// @brief Constructor for indexed surface material
0163   ///
0164   /// @param grid the index grid steering the access to the material vector
0165   /// @param materialAccessor the material accessor: from grid, from indexed vector
0166   /// @param boundToGridLocal the delegation from bound to grid local frame
0167   /// @param globalToGridLocal the delegation from global into grid local frame
0168   GridSurfaceMaterialT(grid_type&& grid,
0169                        material_accessor_type&& materialAccessor,
0170                        BoundToGridLocalDelegate boundToGridLocal,
0171                        GlobalToGridLocalDelegate globalToGridLocal)
0172       : m_grid(std::move(grid)),
0173         m_materialAccessor(std::move(materialAccessor)),
0174         m_globalToGridLocal(std::move(globalToGridLocal)),
0175         m_boundToGridLocal(std::move(boundToGridLocal)) {
0176     if (!m_globalToGridLocal.connected()) {
0177       throw std::invalid_argument(
0178           "GridSurfaceMaterialT: GlobalToGridLocalDelegate is not connected.");
0179     }
0180     if (!m_boundToGridLocal.connected()) {
0181       throw std::invalid_argument(
0182           "GridSurfaceMaterialT: BoundToGridLocalDelegate is not connected.");
0183     }
0184   }
0185 
0186   /// @copydoc ISurfaceMaterial::materialSlab(const Vector2&) const
0187   const MaterialSlab& materialSlab(const Vector2& lp) const final {
0188     return m_materialAccessor.slab(m_grid, m_boundToGridLocal(lp));
0189   }
0190 
0191   /// @copydoc ISurfaceMaterial::materialSlab(const Vector3&) const
0192   const MaterialSlab& materialSlab(const Vector3& gp) const final {
0193     return m_materialAccessor.slab(m_grid, m_globalToGridLocal(gp));
0194   }
0195 
0196   /// Scale operator
0197   ///
0198   /// @param factor is the scale factor applied
0199   ISurfaceMaterial& scale(double factor) final {
0200     m_materialAccessor.scale(m_grid, factor);
0201     return (*this);
0202   }
0203 
0204   /// Output Method for std::ostream, to be overloaded by child classes
0205   std::ostream& toStream(std::ostream& sl) const final {
0206     sl << "GridSurfaceMaterial - material access via accessor.";
0207     return sl;
0208   }
0209 
0210   /// @brief Accessor to the grid
0211   const grid_type& grid() const { return m_grid; }
0212 
0213   /// @brief Accessor to the material accessor
0214   const material_accessor_type& materialAccessor() const {
0215     return m_materialAccessor;
0216   }
0217 
0218   /// @brief Accessor to the bound to grid local delegate
0219   const BoundToGridLocalDelegate& boundToGridLocal() const {
0220     return m_boundToGridLocal;
0221   }
0222 
0223   /// @brief Accessor to the global to grid local delegate
0224   const GlobalToGridLocalDelegate& globalToGridLocal() const {
0225     return m_globalToGridLocal;
0226   }
0227 
0228  private:
0229   /// @brief The grid
0230   grid_type m_grid;
0231 
0232   /// @brief The stored material accessor
0233   material_accessor_type m_materialAccessor;
0234 
0235   /// The global to grid local delegate
0236   GlobalToGridLocalDelegate m_globalToGridLocal;
0237 
0238   /// The bound to grid local delegate
0239   BoundToGridLocalDelegate m_boundToGridLocal;
0240 };
0241 
0242 // Indexed Surface material
0243 template <typename grid_type>
0244 using IndexedSurfaceMaterial =
0245     GridSurfaceMaterialT<grid_type, IndexedMaterialAccessor>;
0246 
0247 // Globally Indexed Surface material
0248 template <typename grid_type>
0249 using GloballyIndexedSurfaceMaterial =
0250     GridSurfaceMaterialT<grid_type, GloballyIndexedMaterialAccessor>;
0251 
0252 // Grid Surface material
0253 template <typename grid_type>
0254 using GridSurfaceMaterial = GridSurfaceMaterialT<grid_type>;
0255 
0256 }  // namespace Acts