File indexing completed on 2025-07-08 08:09:55
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012
0013 #include <optional>
0014 #include <type_traits>
0015 #include <variant>
0016
0017 namespace Acts {
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 class BoundaryTolerance {
0057 public:
0058 struct InfiniteParams {};
0059
0060 struct NoneParams {};
0061
0062 struct AbsoluteBoundParams {
0063 double tolerance0{};
0064 double tolerance1{};
0065 };
0066
0067 struct AbsoluteCartesianParams {
0068 double tolerance0{};
0069 double tolerance1{};
0070 };
0071
0072 struct AbsoluteEuclideanParams {
0073 double tolerance{};
0074 };
0075
0076 struct Chi2BoundParams {
0077 double maxChi2{};
0078 std::array<double, 4> weight;
0079
0080 Eigen::Map<SquareMatrix2> weightMatrix() {
0081 return Eigen::Map<SquareMatrix2>(weight.data());
0082 }
0083
0084 Eigen::Map<const SquareMatrix2> weightMatrix() const {
0085 return Eigen::Map<const SquareMatrix2>(weight.data());
0086 }
0087 };
0088
0089 static_assert(std::is_trivially_copyable_v<Chi2BoundParams>);
0090
0091 private:
0092
0093 using Variant = std::variant<InfiniteParams, NoneParams, AbsoluteBoundParams,
0094 AbsoluteCartesianParams, AbsoluteEuclideanParams,
0095 Chi2BoundParams>;
0096 static_assert(std::is_trivially_copyable_v<Variant>);
0097
0098
0099 constexpr explicit BoundaryTolerance(Variant variant) : m_variant{variant} {}
0100
0101 public:
0102
0103 constexpr static auto Infinite() noexcept {
0104 return BoundaryTolerance{InfiniteParams{}};
0105 }
0106
0107
0108 constexpr static auto None() noexcept {
0109 return BoundaryTolerance{NoneParams{}};
0110 }
0111
0112
0113 constexpr static auto AbsoluteBound(double tolerance0, double tolerance1) {
0114 if (tolerance0 < 0 || tolerance1 < 0) {
0115 throw std::invalid_argument(
0116 "AbsoluteBound: Tolerance must be non-negative");
0117 }
0118 return BoundaryTolerance{AbsoluteBoundParams{tolerance0, tolerance1}};
0119 }
0120
0121
0122 constexpr static auto AbsoluteCartesian(double tolerance0,
0123 double tolerance1) {
0124 if (tolerance0 < 0 || tolerance1 < 0) {
0125 throw std::invalid_argument(
0126 "AbsoluteCartesian: Tolerance must be non-negative");
0127 }
0128 if ((tolerance0 == 0) != (tolerance1 == 0)) {
0129 throw std::invalid_argument(
0130 "AbsoluteCartesian: Both tolerances must be zero or non-zero");
0131 }
0132 return BoundaryTolerance{AbsoluteCartesianParams{tolerance0, tolerance1}};
0133 }
0134
0135
0136 constexpr static auto AbsoluteEuclidean(double tolerance) noexcept {
0137 return BoundaryTolerance{AbsoluteEuclideanParams{tolerance}};
0138 }
0139
0140
0141 static auto Chi2Bound(const SquareMatrix2& weight, double maxChi2) noexcept {
0142 Chi2BoundParams tolerance{maxChi2, {}};
0143 tolerance.weightMatrix() = weight;
0144 return BoundaryTolerance{tolerance};
0145 }
0146
0147 BoundaryTolerance(const BoundaryTolerance& other) noexcept = default;
0148 BoundaryTolerance& operator=(const BoundaryTolerance& other) noexcept =
0149 default;
0150 BoundaryTolerance(BoundaryTolerance&& other) noexcept = default;
0151 BoundaryTolerance& operator=(BoundaryTolerance&& other) noexcept = default;
0152
0153 enum class ToleranceMode {
0154 Extend,
0155 None,
0156 Shrink
0157 };
0158
0159
0160 constexpr bool isInfinite() const { return holdsVariant<InfiniteParams>(); }
0161
0162 constexpr bool isNone() const { return holdsVariant<NoneParams>(); }
0163
0164 constexpr bool hasAbsoluteBound(bool isCartesian = false) const {
0165 return holdsVariant<NoneParams>() || holdsVariant<AbsoluteBoundParams>() ||
0166 (isCartesian && holdsVariant<AbsoluteCartesianParams>());
0167 }
0168
0169 constexpr bool hasAbsoluteCartesian() const {
0170 return holdsVariant<AbsoluteCartesianParams>();
0171 }
0172
0173 constexpr bool hasAbsoluteEuclidean() const {
0174 return holdsVariant<AbsoluteEuclideanParams>();
0175 }
0176
0177 constexpr bool hasChi2Bound() const {
0178 return holdsVariant<Chi2BoundParams>();
0179 }
0180
0181
0182 ToleranceMode toleranceMode() const;
0183
0184
0185 AbsoluteBoundParams asAbsoluteBound(bool isCartesian = false) const;
0186
0187 constexpr const AbsoluteCartesianParams& asAbsoluteCartesian() const {
0188 return getVariant<AbsoluteCartesianParams>();
0189 }
0190
0191 constexpr const AbsoluteEuclideanParams& asAbsoluteEuclidean() const {
0192 return getVariant<AbsoluteEuclideanParams>();
0193 }
0194
0195 constexpr const Chi2BoundParams& asChi2Bound() const {
0196 return getVariant<Chi2BoundParams>();
0197 }
0198
0199
0200 constexpr std::optional<AbsoluteBoundParams> asAbsoluteBoundOpt(
0201 bool isCartesian = false) const {
0202 return hasAbsoluteBound(isCartesian)
0203 ? std::optional(asAbsoluteBound(isCartesian))
0204 : std::nullopt;
0205 }
0206
0207
0208 bool isTolerated(const Vector2& distance,
0209 const std::optional<SquareMatrix2>& jacobianOpt) const;
0210
0211
0212 constexpr bool hasMetric(bool hasJacobian) const {
0213 return hasJacobian || hasChi2Bound();
0214 }
0215
0216
0217 SquareMatrix2 getMetric(const std::optional<SquareMatrix2>& jacobian) const;
0218
0219 private:
0220 Variant m_variant;
0221
0222
0223 template <typename T>
0224 constexpr bool holdsVariant() const {
0225 return std::holds_alternative<T>(m_variant);
0226 }
0227
0228
0229 template <typename T>
0230 constexpr const T& getVariant() const {
0231 return std::get<T>(m_variant);
0232 }
0233
0234 template <typename T>
0235 constexpr const T* getVariantPtr() const {
0236 return holdsVariant<T>() ? &getVariant<T>() : nullptr;
0237 }
0238 };
0239
0240 static_assert(std::is_trivially_copyable_v<BoundaryTolerance>);
0241 static_assert(std::is_trivially_move_constructible_v<BoundaryTolerance>);
0242
0243 }