Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:23:23

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