Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-06 07:51:58

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/Utilities/Logger.hpp"
0013 
0014 #include <algorithm>
0015 #include <array>
0016 #include <cstddef>
0017 #include <cstdint>
0018 #include <limits>
0019 #include <span>
0020 #include <type_traits>
0021 
0022 #include <boost/container/static_vector.hpp>
0023 
0024 namespace Acts {
0025 
0026 /// Status enum
0027 enum class IntersectionStatus : int {
0028   unreachable = 0,
0029   reachable = 1,
0030   onSurface = 2
0031 };
0032 
0033 /// Ostream-operator for the IntersectionStatus enum
0034 inline std::ostream& operator<<(std::ostream& os, IntersectionStatus status) {
0035   constexpr static std::array<const char*, 3> names = {
0036       {"missed/unreachable", "reachable", "onSurface"}};
0037 
0038   os << names[static_cast<std::size_t>(status)];
0039   return os;
0040 }
0041 
0042 ///  @struct Intersection
0043 ///
0044 ///  Intersection struct used for position
0045 template <unsigned int DIM>
0046 class Intersection {
0047  public:
0048   /// Position type
0049   using Position = Eigen::Map<const ActsVector<DIM>>;
0050 
0051   /// Constructor with arguments
0052   ///
0053   /// @param position is the position of the intersection
0054   /// @param pathLength is the path length to the intersection
0055   /// @param status is an enum indicating the status of the intersection
0056   constexpr Intersection(const ActsVector<DIM>& position, double pathLength,
0057                          IntersectionStatus status) noexcept
0058       : Intersection(std::span<const double, DIM>{position.data(), DIM},
0059                      pathLength, status) {}
0060 
0061   constexpr Intersection(const Position& position, double pathLength,
0062                          IntersectionStatus status) noexcept
0063       : Intersection(std::span<const double, DIM>{position.data(), DIM},
0064                      pathLength, status) {}
0065 
0066   constexpr Intersection(std::span<const double, DIM> position,
0067                          double pathLength, IntersectionStatus status) noexcept
0068       : m_pathLength(pathLength), m_status(status) {
0069     std::ranges::copy(position, m_position.begin());
0070   }
0071 
0072   Intersection(const Intersection&) noexcept = default;
0073   Intersection(Intersection&&) noexcept = default;
0074   Intersection& operator=(const Intersection&) noexcept = default;
0075   Intersection& operator=(Intersection&&) noexcept = default;
0076 
0077   /// Returns whether the intersection was successful or not
0078   constexpr bool isValid() const {
0079     return m_status != IntersectionStatus::unreachable;
0080   }
0081 
0082   /// Returns the position of the interseciton
0083   constexpr Position position() const { return Position{m_position.data()}; }
0084 
0085   /// Returns the path length to the interseciton
0086   constexpr double pathLength() const { return m_pathLength; }
0087 
0088   /// Returns the intersection status enum
0089   constexpr IntersectionStatus status() const { return m_status; }
0090 
0091   /// Static factory to creae an invalid instesection
0092   constexpr static Intersection invalid() { return Intersection(); }
0093 
0094   /// Comparison function for path length order i.e. intersection closest to
0095   /// -inf will be first.
0096   constexpr static bool pathLengthOrder(const Intersection& aIntersection,
0097                                         const Intersection& bIntersection) {
0098     auto a = aIntersection.pathLength();
0099     auto b = bIntersection.pathLength();
0100     return a < b;
0101   }
0102 
0103   /// Comparison function for closest order i.e. intersection closest to 0 will
0104   /// be first.
0105   constexpr static bool closestOrder(const Intersection& aIntersection,
0106                                      const Intersection& bIntersection) {
0107     if ((aIntersection.status() == IntersectionStatus::unreachable) &&
0108         (bIntersection.status() != IntersectionStatus::unreachable)) {
0109       return false;
0110     }
0111     if ((aIntersection.status() != IntersectionStatus::unreachable) &&
0112         (bIntersection.status() == IntersectionStatus::unreachable)) {
0113       return true;
0114     }
0115     // both are reachable or onSurface now
0116     auto a = aIntersection.pathLength();
0117     auto b = bIntersection.pathLength();
0118     return std::abs(a) < std::abs(b);
0119   }
0120 
0121   /// Comparison function for closest forward order i.e. intersection closest to
0122   /// 0 with positive path length will be first.
0123   constexpr static bool closestForwardOrder(const Intersection& aIntersection,
0124                                             const Intersection& bIntersection) {
0125     auto a = aIntersection.pathLength();
0126     auto b = bIntersection.pathLength();
0127     return std::signbit(a) == std::signbit(b) ? std::abs(a) < std::abs(b)
0128                                               : a > b;
0129   }
0130 
0131  private:
0132   /// Position of the intersection
0133   std::array<double, DIM> m_position{};
0134   /// Signed path length to the intersection (if valid)
0135   double m_pathLength = std::numeric_limits<double>::infinity();
0136   /// The Status of the intersection
0137   IntersectionStatus m_status = IntersectionStatus::unreachable;
0138 
0139   constexpr Intersection() = default;
0140 };
0141 
0142 using Intersection2D = Intersection<2>;
0143 using Intersection3D = Intersection<3>;
0144 
0145 static_assert(std::is_trivially_move_constructible_v<Intersection2D>);
0146 static_assert(std::is_trivially_copy_constructible_v<Intersection2D>);
0147 static_assert(std::is_trivially_move_assignable_v<Intersection2D>);
0148 
0149 static constexpr std::uint8_t s_maximumNumberOfIntersections = 2;
0150 using MultiIntersection3D =
0151     boost::container::static_vector<Intersection3D,
0152                                     s_maximumNumberOfIntersections>;
0153 
0154 template <typename object_t>
0155 class ObjectIntersection {
0156  public:
0157   /// Object intersection
0158   ///
0159   /// @param intersection is the intersection
0160   /// @param object is the object to be instersected
0161   /// @param index is the intersection index
0162   constexpr ObjectIntersection(const Intersection3D& intersection,
0163                                const object_t* object,
0164                                std::uint8_t index = 0) noexcept
0165       : m_intersection(intersection), m_object(object), m_index(index) {}
0166 
0167   ObjectIntersection(const ObjectIntersection&) noexcept = default;
0168   ObjectIntersection(ObjectIntersection&&) noexcept = default;
0169   ObjectIntersection& operator=(const ObjectIntersection&) noexcept = default;
0170   ObjectIntersection& operator=(ObjectIntersection&&) noexcept = default;
0171 
0172   /// Returns whether the intersection was successful or not
0173   constexpr bool isValid() const { return m_intersection.isValid(); }
0174 
0175   /// Returns the intersection
0176   constexpr const Intersection3D& intersection() const {
0177     return m_intersection;
0178   }
0179 
0180   /// Returns the position of the interseciton
0181   Intersection3D::Position position() const {
0182     return m_intersection.position();
0183   }
0184 
0185   /// Returns the path length to the interseciton
0186   constexpr double pathLength() const { return m_intersection.pathLength(); }
0187 
0188   /// Returns the status of the interseciton
0189   constexpr IntersectionStatus status() const {
0190     return m_intersection.status();
0191   }
0192 
0193   /// Returns the object that has been intersected
0194   constexpr const object_t* object() const { return m_object; }
0195 
0196   constexpr std::uint8_t index() const { return m_index; }
0197 
0198   constexpr static ObjectIntersection invalid(
0199       const object_t* object = nullptr) {
0200     return ObjectIntersection(Intersection3D::invalid(), object);
0201   }
0202 
0203   constexpr static bool pathLengthOrder(
0204       const ObjectIntersection& aIntersection,
0205       const ObjectIntersection& bIntersection) {
0206     return Intersection3D::pathLengthOrder(aIntersection.intersection(),
0207                                            bIntersection.intersection());
0208   }
0209 
0210   constexpr static bool closestOrder(const ObjectIntersection& aIntersection,
0211                                      const ObjectIntersection& bIntersection) {
0212     return Intersection3D::closestOrder(aIntersection.intersection(),
0213                                         bIntersection.intersection());
0214   }
0215 
0216   constexpr static bool closestForwardOrder(
0217       const ObjectIntersection& aIntersection,
0218       const ObjectIntersection& bIntersection) {
0219     return Intersection3D::closestForwardOrder(aIntersection.intersection(),
0220                                                bIntersection.intersection());
0221   }
0222 
0223  private:
0224   /// The intersection itself
0225   Intersection3D m_intersection = Intersection3D::invalid();
0226   /// The object that was (tried to be) intersected
0227   const object_t* m_object = nullptr;
0228   /// The intersection index
0229   std::uint8_t m_index = 0;
0230 
0231   constexpr ObjectIntersection() = default;
0232 };
0233 
0234 static_assert(std::is_trivially_move_constructible_v<ObjectIntersection<int>>);
0235 static_assert(std::is_trivially_move_assignable_v<ObjectIntersection<int>>);
0236 
0237 template <typename object_t>
0238 class ObjectMultiIntersection {
0239  public:
0240   using SplitIntersections =
0241       boost::container::static_vector<ObjectIntersection<object_t>,
0242                                       s_maximumNumberOfIntersections>;
0243 
0244   /// Object intersection
0245   ///
0246   /// @param intersections are the intersections
0247   /// @param object is the object to be instersected
0248   constexpr ObjectMultiIntersection(const MultiIntersection3D& intersections,
0249                                     const object_t* object)
0250       : m_intersections(intersections), m_object(object) {}
0251 
0252   constexpr ObjectIntersection<object_t> operator[](std::uint8_t index) const {
0253     return {m_intersections[index], m_object, index};
0254   }
0255 
0256   constexpr const MultiIntersection3D& intersections() const {
0257     return m_intersections;
0258   }
0259 
0260   constexpr std::size_t size() const { return m_intersections.size(); }
0261 
0262   constexpr const object_t* object() const { return m_object; }
0263 
0264   constexpr SplitIntersections split() const {
0265     SplitIntersections result;
0266     for (std::size_t i = 0; i < size(); ++i) {
0267       result.push_back(operator[](i));
0268     }
0269     return result;
0270   }
0271 
0272   constexpr ObjectIntersection<object_t> closest() const {
0273     auto splitIntersections = split();
0274     return *std::min_element(splitIntersections.begin(),
0275                              splitIntersections.end(),
0276                              ObjectIntersection<object_t>::closestOrder);
0277   }
0278 
0279   constexpr ObjectIntersection<object_t> closestForward() const {
0280     auto splitIntersections = split();
0281     return *std::min_element(splitIntersections.begin(),
0282                              splitIntersections.end(),
0283                              ObjectIntersection<object_t>::closestForwardOrder);
0284   }
0285 
0286  private:
0287   /// The intersections
0288   MultiIntersection3D m_intersections;
0289   /// The object that was (tried to be) intersected
0290   const object_t* m_object = nullptr;
0291 };
0292 
0293 namespace detail {
0294 
0295 /// This function checks if an intersection path length is valid for the
0296 /// specified near-limit and far-limit
0297 ///
0298 /// @param pathLength The path length of the intersection
0299 /// @param nearLimit The minimum path length for an intersection to be considered
0300 /// @param farLimit The maximum path length for an intersection to be considered
0301 /// @param logger A optionally supplied logger which prints out a lot of infos
0302 ///               at VERBOSE level
0303 bool checkPathLength(double pathLength, double nearLimit, double farLimit,
0304                      const Logger& logger = getDummyLogger());
0305 
0306 }  // namespace detail
0307 
0308 }  // namespace Acts