Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-21 08:08:47

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