Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:23:41

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2016-2023 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   constexpr explicit operator bool() const {
0064     return m_status != Status::missed;
0065   }
0066 
0067   constexpr const Position& position() const { return m_position; }
0068 
0069   constexpr ActsScalar pathLength() const { return m_pathLength; }
0070 
0071   constexpr Status status() const { return m_status; }
0072 
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() == Status::unreachable) &&
0089         (bIntersection.status() != Status::unreachable)) {
0090       return false;
0091     }
0092     if ((aIntersection.status() != Status::unreachable) &&
0093         (bIntersection.status() == Status::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   ActsScalar m_pathLength = std::numeric_limits<double>::infinity();
0117   /// The Status of the intersection
0118   Status m_status = Status::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 explicit operator bool() const {
0145     return m_intersection.operator bool();
0146   }
0147 
0148   constexpr const Intersection3D& intersection() const {
0149     return m_intersection;
0150   }
0151 
0152   constexpr const Intersection3D::Position& position() const {
0153     return m_intersection.position();
0154   }
0155 
0156   constexpr ActsScalar pathLength() const {
0157     return m_intersection.pathLength();
0158   }
0159 
0160   constexpr Intersection3D::Status status() const {
0161     return m_intersection.status();
0162   }
0163 
0164   constexpr const object_t* object() const { return m_object; }
0165 
0166   constexpr std::uint8_t index() const { return m_index; }
0167 
0168   constexpr static ObjectIntersection invalid() { return ObjectIntersection(); }
0169 
0170   constexpr static bool pathLengthOrder(
0171       const ObjectIntersection& aIntersection,
0172       const ObjectIntersection& bIntersection) {
0173     return Intersection3D::pathLengthOrder(aIntersection.intersection(),
0174                                            bIntersection.intersection());
0175   }
0176 
0177   constexpr static bool closestOrder(const ObjectIntersection& aIntersection,
0178                                      const ObjectIntersection& bIntersection) {
0179     return Intersection3D::closestOrder(aIntersection.intersection(),
0180                                         bIntersection.intersection());
0181   }
0182 
0183   constexpr static bool closestForwardOrder(
0184       const ObjectIntersection& aIntersection,
0185       const ObjectIntersection& bIntersection) {
0186     return Intersection3D::closestForwardOrder(aIntersection.intersection(),
0187                                                bIntersection.intersection());
0188   }
0189 
0190  private:
0191   /// The intersection itself
0192   Intersection3D m_intersection = Intersection3D::invalid();
0193   /// The object that was (tried to be) intersected
0194   const object_t* m_object = nullptr;
0195   /// The intersection index
0196   std::uint8_t m_index = 0;
0197 
0198   constexpr ObjectIntersection() = default;
0199 };
0200 
0201 template <typename object_t>
0202 class ObjectMultiIntersection {
0203  public:
0204   using SplitIntersections =
0205       boost::container::static_vector<ObjectIntersection<object_t>,
0206                                       s_maximumNumberOfIntersections>;
0207 
0208   /// Object intersection
0209   ///
0210   /// @param intersections are the intersections
0211   /// @param object is the object to be instersected
0212   constexpr ObjectMultiIntersection(const MultiIntersection3D& intersections,
0213                                     const object_t* object)
0214       : m_intersections(intersections), m_object(object) {}
0215 
0216   constexpr ObjectIntersection<object_t> operator[](std::uint8_t index) const {
0217     return {m_intersections[index], m_object, index};
0218   }
0219 
0220   constexpr const MultiIntersection3D& intersections() const {
0221     return m_intersections;
0222   }
0223 
0224   constexpr std::size_t size() const { return m_intersections.size(); }
0225 
0226   constexpr const object_t* object() const { return m_object; }
0227 
0228   constexpr SplitIntersections split() const {
0229     SplitIntersections result;
0230     for (std::size_t i = 0; i < size(); ++i) {
0231       result.push_back(operator[](i));
0232     }
0233     return result;
0234   }
0235 
0236   constexpr ObjectIntersection<object_t> closest() const {
0237     auto splitIntersections = split();
0238     return *std::min_element(splitIntersections.begin(),
0239                              splitIntersections.end(),
0240                              ObjectIntersection<object_t>::closestOrder);
0241   }
0242 
0243   constexpr ObjectIntersection<object_t> closestForward() const {
0244     auto splitIntersections = split();
0245     return *std::min_element(splitIntersections.begin(),
0246                              splitIntersections.end(),
0247                              ObjectIntersection<object_t>::closestForwardOrder);
0248   }
0249 
0250  private:
0251   /// The intersections
0252   MultiIntersection3D m_intersections;
0253   /// The object that was (tried to be) intersected
0254   const object_t* m_object = nullptr;
0255 };
0256 
0257 namespace detail {
0258 
0259 /// This function checks if an intersection is valid for the specified
0260 /// path-limit and overstep-limit
0261 ///
0262 /// @tparam intersection_t Type of the intersection object
0263 ///
0264 /// @param intersection The intersection to check
0265 /// @param nearLimit The minimum distance for an intersection to be considered
0266 /// @param farLimit The maximum distance for an intersection to be considered
0267 /// @param logger A optionally supplied logger which prints out a lot of infos
0268 ///               at VERBOSE level
0269 template <typename intersection_t>
0270 bool checkIntersection(const intersection_t& intersection, double nearLimit,
0271                        double farLimit,
0272                        const Logger& logger = getDummyLogger()) {
0273   const double distance = intersection.pathLength();
0274   // TODO why?
0275   const double tolerance = s_onSurfaceTolerance;
0276 
0277   ACTS_VERBOSE(" -> near limit, far limit, distance: "
0278                << nearLimit << ", " << farLimit << ", " << distance);
0279 
0280   const bool coCriterion = distance > nearLimit;
0281   const bool cpCriterion = distance < farLimit + tolerance;
0282 
0283   const bool accept = coCriterion && cpCriterion;
0284 
0285   if (accept) {
0286     ACTS_VERBOSE("Intersection is WITHIN limit");
0287   } else {
0288     ACTS_VERBOSE("Intersection is OUTSIDE limit because: ");
0289     if (!coCriterion) {
0290       ACTS_VERBOSE("- intersection path length "
0291                    << distance << " <= near limit " << nearLimit);
0292     }
0293     if (!cpCriterion) {
0294       ACTS_VERBOSE("- intersection path length "
0295                    << distance << " is over the far limit "
0296                    << (farLimit + tolerance) << " (including tolerance of "
0297                    << tolerance << ")");
0298     }
0299   }
0300 
0301   return accept;
0302 }
0303 
0304 }  // namespace detail
0305 
0306 }  // namespace Acts