Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-14 09:39:48

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/Geometry/VolumeBounds.hpp"
0012 #include "Acts/Surfaces/SurfaceBounds.hpp"
0013 #include "Acts/Utilities/Helpers.hpp"
0014 
0015 #include <cassert>
0016 #include <cmath>
0017 #include <limits>
0018 #include <memory>
0019 #include <set>
0020 #include <type_traits>
0021 #include <vector>
0022 
0023 namespace Acts {
0024 namespace detail {
0025 
0026 /// @brief Concept to define the minimal requirements on the bounds to apply the deduplication mechanism
0027 ///        using the BoundFactory.
0028 template <typename BoundsType_t>
0029 concept ComparableBoundConcept = requires(const BoundsType_t& bounds) {
0030   /// @brief Getter function to distinguish the various bound types (e.g box vs. cylinder)
0031   { bounds.type() };
0032   /// @brief Getter function returning all defining parameters of the bounds as an std::vector
0033   { bounds.values() } -> std::same_as<std::vector<double>>;
0034 };
0035 }  // namespace detail
0036 
0037 ///   @brief Factory helper class to construct volume or surface bounds where the constructed bounds
0038 ///          are cached inside the factory and if the same bound parameters are
0039 ///          requested at a later stage the factory automatically returns the
0040 ///          cached bounds. This provides a simple sharing mechanism of the same
0041 ///          bounds across multiple surfaces / volumes
0042 template <detail::ComparableBoundConcept BoundsType_t>
0043 class BoundFactory {
0044  public:
0045   /// @brief Abbreviation of the class return type. If the set is over const
0046   ///        objects, the return type is const as well and non-const otherwise
0047   template <typename T>
0048   using BoundsRet_t =
0049       std::conditional_t<std::is_const_v<BoundsType_t>, const T, T>;
0050   /// @brief Empty default constructor
0051   BoundFactory() = default;
0052   /// @brief Delete the copy constructor
0053   BoundFactory(const BoundFactory& other) = delete;
0054   /// @brief Delete copy assignment
0055   BoundFactory& operator=(const BoundFactory& other) = delete;
0056   /// @brief Pass externally constructed bounds to the factory and run the deduplication
0057   ///        mechanism on them
0058   /// @tparam BoundsImpl_t: Template specification of the bounds to deduplicate
0059   /// @param bounds: Pointer to the bounds to deduplicated
0060   /// @return Pointer to an equivalent bound object
0061   template <typename BoundsImpl_t>
0062   std::shared_ptr<BoundsRet_t<BoundsImpl_t>> insert(
0063       const std::shared_ptr<BoundsImpl_t>& bounds)
0064     requires(std::is_base_of_v<BoundsType_t, BoundsImpl_t>)
0065   {
0066     assert(bounds);
0067     return std::dynamic_pointer_cast<BoundsRet_t<BoundsImpl_t>>(
0068         *m_boundSet.insert(bounds).first);
0069   }
0070   /// @brief Factory method to construct new bounds from the passed arguments
0071   /// @tparam BoundsImpl_t: Explicit template specification of the bounds to construct
0072   /// @param args: List of defining bound parameters
0073   /// @return A pointer to the newly constructed bounds or to an already existing
0074   ///          equivalent bound object
0075   template <typename BoundsImpl_t, class... argList>
0076   std::shared_ptr<BoundsRet_t<BoundsImpl_t>> makeBounds(argList... args)
0077     requires(std::is_base_of_v<BoundsType_t, BoundsImpl_t>)
0078   {
0079     return insert(std::make_shared<BoundsImpl_t>(args...));
0080   }
0081   /// @brief Returns the number of cached objects inside the bound factory
0082   /// @return Number of cached bounds objects in the factory
0083   std::size_t size() const { return m_boundSet.size(); }
0084 
0085  private:
0086   ///  @brief Helper struct to actually perform the deduplication of the passed bound objects.
0087   ///          For a pair of two bound pointers, the struct defines the <
0088   ///          operator which is then exploited by a std::set to deduplicate
0089   ///          equivalent bounds.
0090   struct BoundComparator {
0091    public:
0092     /// @brief Implementation of the comparison operator between two bound pointers
0093     /// @param a: First bound pointer in the comparison
0094     /// @param b: Second bound pointer in the comparison
0095     bool operator()(const std::shared_ptr<BoundsType_t>& a,
0096                     const std::shared_ptr<BoundsType_t>& b) const {
0097       /// If we deal with two fundamental different bound sets, then just
0098       /// cast the type to int and return the comparison
0099       if (a->type() != b->type()) {
0100         return toUnderlying(a->type()) < toUnderlying(b->type());
0101       }
0102       const std::vector<double> avalues{a->values()};
0103       const std::vector<double> bvalues{b->values()};
0104       /// In case of polygon shaped bounds, the vectors may differ
0105       if (avalues.size() != bvalues.size()) {
0106         return avalues.size() < bvalues.size();
0107       }
0108       ///  Loop over the defining parameters of the two bounds and compare them
0109       ///  pairwise. If a difference is spotted, then use it to assign the <
0110       ///  ordering
0111       return std::ranges::lexicographical_compare(
0112           avalues, bvalues,
0113           [](double parA, double parB) { return parA < parB; });
0114     }
0115   };
0116   std::set<std::shared_ptr<BoundsType_t>, BoundComparator> m_boundSet{};
0117 };
0118 
0119 /// @brief Abrivation for a factory to construct surface bounds
0120 using SurfaceBoundFactory = BoundFactory<const SurfaceBounds>;
0121 /// @brief Abrivation for a factory to construct volume bounds
0122 using VolumeBoundFactory = BoundFactory<VolumeBounds>;
0123 
0124 }  // namespace Acts