Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:11

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