Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:23:34

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   /// Parameters for absolute Euclidean boundary tolerance.
0056   struct AbsoluteEuclideanParams {
0057     /// Tolerance value
0058     double tolerance{};
0059   };
0060 
0061   /// Parameters for chi2 boundary tolerance in bound coordinates.
0062   struct Chi2BoundParams {
0063     /// Maximum chi2 value
0064     double maxChi2{};
0065     /// Weight matrix stored as flat array
0066     std::array<double, 4> weight{};
0067 
0068     /// Get weight matrix as Eigen matrix
0069     /// @return Mapped weight matrix
0070     Eigen::Map<SquareMatrix2> weightMatrix() {
0071       return Eigen::Map<SquareMatrix2>(weight.data());
0072     }
0073 
0074     /// Get weight matrix as const Eigen matrix
0075     /// @return Mapped weight matrix
0076     Eigen::Map<const SquareMatrix2> weightMatrix() const {
0077       return Eigen::Map<const SquareMatrix2>(weight.data());
0078     }
0079   };
0080 
0081   /// Parameters for chi2 boundary tolerance in Cartesian coordinates.
0082   struct Chi2CartesianParams {
0083     /// Maximum chi2 value
0084     double maxChi2{};
0085     /// Weight matrix stored as flat array
0086     std::array<double, 4> weight{};
0087 
0088     /// Get weight matrix as Eigen matrix
0089     /// @return Mapped weight matrix
0090     Eigen::Map<SquareMatrix2> weightMatrix() {
0091       return Eigen::Map<SquareMatrix2>(weight.data());
0092     }
0093 
0094     /// Get weight matrix as const Eigen matrix
0095     /// @return Mapped weight matrix
0096     Eigen::Map<const SquareMatrix2> weightMatrix() const {
0097       return Eigen::Map<const SquareMatrix2>(weight.data());
0098     }
0099   };
0100 
0101   static_assert(std::is_trivially_copyable_v<Chi2BoundParams>);
0102 
0103  private:
0104   /// Underlying variant type
0105   using Variant =
0106       std::variant<InfiniteParams, NoneParams, AbsoluteEuclideanParams,
0107                    Chi2BoundParams, Chi2CartesianParams>;
0108   static_assert(std::is_trivially_copyable_v<Variant>);
0109 
0110   /// Construct from variant
0111   constexpr explicit BoundaryTolerance(Variant variant) : m_variant{variant} {}
0112 
0113  public:
0114   /// Infinite tolerance i.e. no boundary check
0115   /// @return BoundaryTolerance configured for infinite tolerance
0116   constexpr static auto Infinite() noexcept {
0117     return BoundaryTolerance{InfiniteParams{}};
0118   }
0119 
0120   /// No tolerance i.e. exact boundary check
0121   /// @return BoundaryTolerance configured for no tolerance (exact checking)
0122   constexpr static auto None() noexcept {
0123     return BoundaryTolerance{NoneParams{}};
0124   }
0125 
0126   /// Absolute tolerance in Euclidean distance
0127   /// @param tolerance The tolerance value in Euclidean distance
0128   /// @return BoundaryTolerance configured for absolute Euclidean tolerance
0129   constexpr static auto AbsoluteEuclidean(double tolerance) noexcept {
0130     return BoundaryTolerance{AbsoluteEuclideanParams{tolerance}};
0131   }
0132 
0133   /// Chi2 tolerance in bound coordinates
0134   /// @param weight The weight matrix for the chi2 calculation
0135   /// @param maxChi2 The maximum chi2 value allowed
0136   /// @return BoundaryTolerance configured for chi2 tolerance in bound coordinates
0137   static auto Chi2Bound(const SquareMatrix2& weight, double maxChi2) noexcept {
0138     Chi2BoundParams tolerance{maxChi2, {}};
0139     tolerance.weightMatrix() = weight;
0140     return BoundaryTolerance{tolerance};
0141   }
0142 
0143   /// Chi2 tolerance in Cartesian coordinates
0144   /// @param weight The weight matrix for the chi2 calculation
0145   /// @param maxChi2 The maximum chi2 value allowed
0146   /// @return BoundaryTolerance configured for chi2 tolerance in Cartesian coordinates
0147   static auto Chi2Cartesian(const SquareMatrix2& weight,
0148                             double maxChi2) noexcept {
0149     Chi2CartesianParams tolerance{maxChi2, {}};
0150     tolerance.weightMatrix() = weight;
0151     return BoundaryTolerance{tolerance};
0152   }
0153 
0154   /// Copy constructor
0155   /// @param other The BoundaryTolerance object to copy
0156   BoundaryTolerance(const BoundaryTolerance& other) noexcept = default;
0157   /// Copy assignment operator
0158   /// @param other The BoundaryTolerance object to copy
0159   /// @return Reference to this BoundaryTolerance after copying
0160   BoundaryTolerance& operator=(const BoundaryTolerance& other) noexcept =
0161       default;
0162   /// Move constructor
0163   /// @param other The BoundaryTolerance object to move
0164   BoundaryTolerance(BoundaryTolerance&& other) noexcept = default;
0165   /// Move assignment operator
0166   /// @param other The BoundaryTolerance object to move
0167   /// @return Reference to this BoundaryTolerance after moving
0168   BoundaryTolerance& operator=(BoundaryTolerance&& other) noexcept = default;
0169 
0170   /// @enum ToleranceMode
0171   /// Enumeration defining how tolerance should be applied to boundaries
0172   enum class ToleranceMode {
0173     Extend,  //< Extend the boundary
0174     None,    //< No tolerance
0175     Shrink   //< Shrink the boundary
0176   };
0177 
0178   /// Check if the tolerance is infinite.
0179   /// @return True if configured for infinite tolerance, false otherwise
0180   constexpr bool isInfinite() const { return holdsVariant<InfiniteParams>(); }
0181   /// Check if the is no tolerance.
0182   /// @return True if configured for no tolerance (exact checking), false otherwise
0183   constexpr bool isNone() const { return holdsVariant<NoneParams>(); }
0184   /// Check if the tolerance is absolute with Euclidean distance.
0185   /// @return True if configured for absolute Euclidean tolerance, false otherwise
0186   constexpr bool hasAbsoluteEuclidean() const {
0187     return holdsVariant<AbsoluteEuclideanParams>();
0188   }
0189   /// Check if the tolerance is chi2 with bound coordinates.
0190   /// @return True if configured for chi2 tolerance in bound coordinates, false otherwise
0191   constexpr bool hasChi2Bound() const {
0192     return holdsVariant<Chi2BoundParams>();
0193   }
0194   /// Check if the tolerance is chi2 with Cartesian coordinates.
0195   /// @return True if configured for chi2 tolerance in Cartesian coordinates, false otherwise
0196   constexpr bool hasChi2Cartesian() const {
0197     return holdsVariant<Chi2CartesianParams>();
0198   }
0199 
0200   /// Get the tolerance mode.
0201   /// @return ToleranceMode indicating how the tolerance should be applied
0202   ToleranceMode toleranceMode() const;
0203 
0204   /// Get the tolerance as absolute Euclidean.
0205   /// @return Reference to the absolute Euclidean tolerance parameters
0206   constexpr const AbsoluteEuclideanParams& asAbsoluteEuclidean() const {
0207     return getVariant<AbsoluteEuclideanParams>();
0208   }
0209   /// Get the tolerance as chi2 bound.
0210   /// @return Reference to the chi2 bound tolerance parameters
0211   constexpr const Chi2BoundParams& asChi2Bound() const {
0212     return getVariant<Chi2BoundParams>();
0213   }
0214   /// Get the tolerance as chi2 Cartesian.
0215   /// @return Reference to the chi2 Cartesian tolerance parameters
0216   constexpr const Chi2CartesianParams& asChi2Cartesian() const {
0217     return getVariant<Chi2CartesianParams>();
0218   }
0219 
0220   /// Check if the bound position delta is tolerated.
0221   /// @param boundDelta The delta in bound coordinates
0222   /// @param boundToCartesian The transformation matrix from bound to Cartesian
0223   /// @return True if the delta is within tolerance, false otherwise
0224   bool isTolerated(const Vector2& boundDelta,
0225                    const SquareMatrix2& boundToCartesian) const;
0226 
0227  private:
0228   Variant m_variant;
0229 
0230   /// Check if the boundary check is of a specific type.
0231   template <typename T>
0232   constexpr bool holdsVariant() const {
0233     return std::holds_alternative<T>(m_variant);
0234   }
0235 
0236   /// Get the specific underlying type.
0237   template <typename T>
0238   constexpr const T& getVariant() const {
0239     return std::get<T>(m_variant);
0240   }
0241 
0242   template <typename T>
0243   constexpr const T* getVariantPtr() const {
0244     return holdsVariant<T>() ? &getVariant<T>() : nullptr;
0245   }
0246 };
0247 
0248 static_assert(std::is_trivially_copyable_v<BoundaryTolerance>);
0249 static_assert(std::is_trivially_move_constructible_v<BoundaryTolerance>);
0250 
0251 }  // namespace Acts