Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 08:26:36

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