Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-14 08:12:05

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 
0013 #include <type_traits>
0014 #include <variant>
0015 
0016 namespace Acts {
0017 
0018 /// @brief Variant-like type to capture different types of boundary tolerances
0019 ///
0020 /// Since our track hypothesis comes with uncertainties, we sometimes need to
0021 /// check if the track is not just within the boundary of the surface but also
0022 /// within a certain tolerance. This class captures different parameterizations
0023 /// of such tolerances. The surface class will then use these tolerances to
0024 /// check if a ray is within the boundary+tolerance of the surface.
0025 ///
0026 /// Different types of boundary tolerances implemented:
0027 /// - Infinite: Infinite tolerance i.e. no boundary check will be performed.
0028 /// - None: No tolerance i.e. exact boundary check will be performed.
0029 /// - AbsoluteEuclidean: Absolute tolerance in Euclidean distance.
0030 ///   The tolerance is defined as a single absolute value for the Euclidean
0031 ///   distance. The Euclidean distance can be calculated via the local bound
0032 ///   Jacobian and the bound coordinate residual. If the distance is within
0033 ///   the tolerance, the boundary check is considered as passed.
0034 /// - Chi2Bound: Chi2 tolerance in bound coordinates.
0035 ///   The tolerance is defined as a maximum chi2 value and a weight matrix,
0036 ///   which is the inverse of the bound covariance matrix. The chi2 value is
0037 ///   calculated from the bound coordinates residual and the weight matrix.
0038 ///   If the chi2 value is below the maximum chi2 value, the boundary check
0039 ///   is considered as passed.
0040 /// - Chi2Cartesian: Chi2 tolerance in Cartesian coordinates.
0041 ///   Similar to Chi2Bound, but the chi2 value is calculated in Cartesian
0042 ///   coordinates.
0043 ///
0044 /// The bound coordinates residual is defined as the difference between the
0045 /// point checked and the closest point on the boundary. The Jacobian is the
0046 /// derivative of the bound coordinates with respect to the Cartesian
0047 /// coordinates.
0048 ///
0049 class BoundaryTolerance {
0050  public:
0051   struct InfiniteParams {};
0052 
0053   struct NoneParams {};
0054 
0055   struct AbsoluteEuclideanParams {
0056     double tolerance{};
0057   };
0058 
0059   struct Chi2BoundParams {
0060     double maxChi2{};
0061     std::array<double, 4> weight{};
0062 
0063     Eigen::Map<SquareMatrix2> weightMatrix() {
0064       return Eigen::Map<SquareMatrix2>(weight.data());
0065     }
0066 
0067     Eigen::Map<const SquareMatrix2> weightMatrix() const {
0068       return Eigen::Map<const SquareMatrix2>(weight.data());
0069     }
0070   };
0071 
0072   struct Chi2CartesianParams {
0073     double maxChi2{};
0074     std::array<double, 4> weight{};
0075 
0076     Eigen::Map<SquareMatrix2> weightMatrix() {
0077       return Eigen::Map<SquareMatrix2>(weight.data());
0078     }
0079 
0080     Eigen::Map<const SquareMatrix2> weightMatrix() const {
0081       return Eigen::Map<const SquareMatrix2>(weight.data());
0082     }
0083   };
0084 
0085   static_assert(std::is_trivially_copyable_v<Chi2BoundParams>);
0086 
0087  private:
0088   /// Underlying variant type
0089   using Variant =
0090       std::variant<InfiniteParams, NoneParams, AbsoluteEuclideanParams,
0091                    Chi2BoundParams, Chi2CartesianParams>;
0092   static_assert(std::is_trivially_copyable_v<Variant>);
0093 
0094   /// Construct from variant
0095   constexpr explicit BoundaryTolerance(Variant variant) : m_variant{variant} {}
0096 
0097  public:
0098   /// Infinite tolerance i.e. no boundary check
0099   constexpr static auto Infinite() noexcept {
0100     return BoundaryTolerance{InfiniteParams{}};
0101   }
0102 
0103   /// No tolerance i.e. exact boundary check
0104   constexpr static auto None() noexcept {
0105     return BoundaryTolerance{NoneParams{}};
0106   }
0107 
0108   /// Absolute tolerance in Euclidean distance
0109   constexpr static auto AbsoluteEuclidean(double tolerance) noexcept {
0110     return BoundaryTolerance{AbsoluteEuclideanParams{tolerance}};
0111   }
0112 
0113   /// Chi2 tolerance in bound coordinates
0114   static auto Chi2Bound(const SquareMatrix2& weight, double maxChi2) noexcept {
0115     Chi2BoundParams tolerance{maxChi2, {}};
0116     tolerance.weightMatrix() = weight;
0117     return BoundaryTolerance{tolerance};
0118   }
0119 
0120   /// Chi2 tolerance in Cartesian coordinates
0121   static auto Chi2Cartesian(const SquareMatrix2& weight,
0122                             double maxChi2) noexcept {
0123     Chi2CartesianParams tolerance{maxChi2, {}};
0124     tolerance.weightMatrix() = weight;
0125     return BoundaryTolerance{tolerance};
0126   }
0127 
0128   BoundaryTolerance(const BoundaryTolerance& other) noexcept = default;
0129   BoundaryTolerance& operator=(const BoundaryTolerance& other) noexcept =
0130       default;
0131   BoundaryTolerance(BoundaryTolerance&& other) noexcept = default;
0132   BoundaryTolerance& operator=(BoundaryTolerance&& other) noexcept = default;
0133 
0134   enum class ToleranceMode {
0135     Extend,  //< Extend the boundary
0136     None,    //< No tolerance
0137     Shrink   //< Shrink the boundary
0138   };
0139 
0140   /// Check if the tolerance is infinite.
0141   constexpr bool isInfinite() const { return holdsVariant<InfiniteParams>(); }
0142   /// Check if the is no tolerance.
0143   constexpr bool isNone() const { return holdsVariant<NoneParams>(); }
0144   /// Check if the tolerance is absolute with Euclidean distance.
0145   constexpr bool hasAbsoluteEuclidean() const {
0146     return holdsVariant<AbsoluteEuclideanParams>();
0147   }
0148   /// Check if the tolerance is chi2 with bound coordinates.
0149   constexpr bool hasChi2Bound() const {
0150     return holdsVariant<Chi2BoundParams>();
0151   }
0152   /// Check if the tolerance is chi2 with Cartesian coordinates.
0153   constexpr bool hasChi2Cartesian() const {
0154     return holdsVariant<Chi2CartesianParams>();
0155   }
0156 
0157   /// Get the tolerance mode.
0158   ToleranceMode toleranceMode() const;
0159 
0160   /// Get the tolerance as absolute Euclidean.
0161   constexpr const AbsoluteEuclideanParams& asAbsoluteEuclidean() const {
0162     return getVariant<AbsoluteEuclideanParams>();
0163   }
0164   /// Get the tolerance as chi2 bound.
0165   constexpr const Chi2BoundParams& asChi2Bound() const {
0166     return getVariant<Chi2BoundParams>();
0167   }
0168   /// Get the tolerance as chi2 Cartesian.
0169   constexpr const Chi2CartesianParams& asChi2Cartesian() const {
0170     return getVariant<Chi2CartesianParams>();
0171   }
0172 
0173   /// Check if the bound position delta is tolerated.
0174   bool isTolerated(const Vector2& boundDelta,
0175                    const SquareMatrix2& boundToCartesian) const;
0176 
0177  private:
0178   Variant m_variant;
0179 
0180   /// Check if the boundary check is of a specific type.
0181   template <typename T>
0182   constexpr bool holdsVariant() const {
0183     return std::holds_alternative<T>(m_variant);
0184   }
0185 
0186   /// Get the specific underlying type.
0187   template <typename T>
0188   constexpr const T& getVariant() const {
0189     return std::get<T>(m_variant);
0190   }
0191 
0192   template <typename T>
0193   constexpr const T* getVariantPtr() const {
0194     return holdsVariant<T>() ? &getVariant<T>() : nullptr;
0195   }
0196 };
0197 
0198 static_assert(std::is_trivially_copyable_v<BoundaryTolerance>);
0199 static_assert(std::is_trivially_move_constructible_v<BoundaryTolerance>);
0200 
0201 }  // namespace Acts