Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-15 08:03:31

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   /// @return BoundaryTolerance configured for infinite tolerance
0100   constexpr static auto Infinite() noexcept {
0101     return BoundaryTolerance{InfiniteParams{}};
0102   }
0103 
0104   /// No tolerance i.e. exact boundary check
0105   /// @return BoundaryTolerance configured for no tolerance (exact checking)
0106   constexpr static auto None() noexcept {
0107     return BoundaryTolerance{NoneParams{}};
0108   }
0109 
0110   /// Absolute tolerance in Euclidean distance
0111   /// @param tolerance The tolerance value in Euclidean distance
0112   /// @return BoundaryTolerance configured for absolute Euclidean tolerance
0113   constexpr static auto AbsoluteEuclidean(double tolerance) noexcept {
0114     return BoundaryTolerance{AbsoluteEuclideanParams{tolerance}};
0115   }
0116 
0117   /// Chi2 tolerance in bound coordinates
0118   /// @param weight The weight matrix for the chi2 calculation
0119   /// @param maxChi2 The maximum chi2 value allowed
0120   /// @return BoundaryTolerance configured for chi2 tolerance in bound coordinates
0121   static auto Chi2Bound(const SquareMatrix2& weight, double maxChi2) noexcept {
0122     Chi2BoundParams tolerance{maxChi2, {}};
0123     tolerance.weightMatrix() = weight;
0124     return BoundaryTolerance{tolerance};
0125   }
0126 
0127   /// Chi2 tolerance in Cartesian coordinates
0128   /// @param weight The weight matrix for the chi2 calculation
0129   /// @param maxChi2 The maximum chi2 value allowed
0130   /// @return BoundaryTolerance configured for chi2 tolerance in Cartesian coordinates
0131   static auto Chi2Cartesian(const SquareMatrix2& weight,
0132                             double maxChi2) noexcept {
0133     Chi2CartesianParams tolerance{maxChi2, {}};
0134     tolerance.weightMatrix() = weight;
0135     return BoundaryTolerance{tolerance};
0136   }
0137 
0138   /// Copy constructor
0139   /// @param other The BoundaryTolerance object to copy
0140   BoundaryTolerance(const BoundaryTolerance& other) noexcept = default;
0141   /// Copy assignment operator
0142   /// @param other The BoundaryTolerance object to copy
0143   /// @return Reference to this BoundaryTolerance after copying
0144   BoundaryTolerance& operator=(const BoundaryTolerance& other) noexcept =
0145       default;
0146   /// Move constructor
0147   /// @param other The BoundaryTolerance object to move
0148   BoundaryTolerance(BoundaryTolerance&& other) noexcept = default;
0149   /// Move assignment operator
0150   /// @param other The BoundaryTolerance object to move
0151   /// @return Reference to this BoundaryTolerance after moving
0152   BoundaryTolerance& operator=(BoundaryTolerance&& other) noexcept = default;
0153 
0154   /// @enum ToleranceMode
0155   /// Enumeration defining how tolerance should be applied to boundaries
0156   enum class ToleranceMode {
0157     Extend,  //< Extend the boundary
0158     None,    //< No tolerance
0159     Shrink   //< Shrink the boundary
0160   };
0161 
0162   /// Check if the tolerance is infinite.
0163   /// @return True if configured for infinite tolerance, false otherwise
0164   constexpr bool isInfinite() const { return holdsVariant<InfiniteParams>(); }
0165   /// Check if the is no tolerance.
0166   /// @return True if configured for no tolerance (exact checking), false otherwise
0167   constexpr bool isNone() const { return holdsVariant<NoneParams>(); }
0168   /// Check if the tolerance is absolute with Euclidean distance.
0169   /// @return True if configured for absolute Euclidean tolerance, false otherwise
0170   constexpr bool hasAbsoluteEuclidean() const {
0171     return holdsVariant<AbsoluteEuclideanParams>();
0172   }
0173   /// Check if the tolerance is chi2 with bound coordinates.
0174   /// @return True if configured for chi2 tolerance in bound coordinates, false otherwise
0175   constexpr bool hasChi2Bound() const {
0176     return holdsVariant<Chi2BoundParams>();
0177   }
0178   /// Check if the tolerance is chi2 with Cartesian coordinates.
0179   /// @return True if configured for chi2 tolerance in Cartesian coordinates, false otherwise
0180   constexpr bool hasChi2Cartesian() const {
0181     return holdsVariant<Chi2CartesianParams>();
0182   }
0183 
0184   /// Get the tolerance mode.
0185   /// @return ToleranceMode indicating how the tolerance should be applied
0186   ToleranceMode toleranceMode() const;
0187 
0188   /// Get the tolerance as absolute Euclidean.
0189   /// @return Reference to the absolute Euclidean tolerance parameters
0190   constexpr const AbsoluteEuclideanParams& asAbsoluteEuclidean() const {
0191     return getVariant<AbsoluteEuclideanParams>();
0192   }
0193   /// Get the tolerance as chi2 bound.
0194   /// @return Reference to the chi2 bound tolerance parameters
0195   constexpr const Chi2BoundParams& asChi2Bound() const {
0196     return getVariant<Chi2BoundParams>();
0197   }
0198   /// Get the tolerance as chi2 Cartesian.
0199   /// @return Reference to the chi2 Cartesian tolerance parameters
0200   constexpr const Chi2CartesianParams& asChi2Cartesian() const {
0201     return getVariant<Chi2CartesianParams>();
0202   }
0203 
0204   /// Check if the bound position delta is tolerated.
0205   /// @param boundDelta The delta in bound coordinates
0206   /// @param boundToCartesian The transformation matrix from bound to Cartesian
0207   /// @return True if the delta is within tolerance, false otherwise
0208   bool isTolerated(const Vector2& boundDelta,
0209                    const SquareMatrix2& boundToCartesian) const;
0210 
0211  private:
0212   Variant m_variant;
0213 
0214   /// Check if the boundary check is of a specific type.
0215   template <typename T>
0216   constexpr bool holdsVariant() const {
0217     return std::holds_alternative<T>(m_variant);
0218   }
0219 
0220   /// Get the specific underlying type.
0221   template <typename T>
0222   constexpr const T& getVariant() const {
0223     return std::get<T>(m_variant);
0224   }
0225 
0226   template <typename T>
0227   constexpr const T* getVariantPtr() const {
0228     return holdsVariant<T>() ? &getVariant<T>() : nullptr;
0229   }
0230 };
0231 
0232 static_assert(std::is_trivially_copyable_v<BoundaryTolerance>);
0233 static_assert(std::is_trivially_move_constructible_v<BoundaryTolerance>);
0234 
0235 }  // namespace Acts