File indexing completed on 2025-07-05 08:11:35
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012
0013 #include <stdexcept>
0014
0015 namespace Acts {
0016
0017 BoundaryTolerance::BoundaryTolerance(Variant variant) : m_variant{variant} {}
0018
0019 bool BoundaryTolerance::isInfinite() const {
0020 return holdsVariant<InfiniteParams>();
0021 }
0022
0023 bool BoundaryTolerance::isNone() const {
0024 return holdsVariant<NoneParams>();
0025 }
0026
0027 bool BoundaryTolerance::hasAbsoluteBound(bool isCartesian) const {
0028 return holdsVariant<NoneParams>() || holdsVariant<AbsoluteBoundParams>() ||
0029 (isCartesian && holdsVariant<AbsoluteCartesianParams>());
0030 }
0031
0032 bool BoundaryTolerance::hasAbsoluteCartesian() const {
0033 return holdsVariant<AbsoluteCartesianParams>();
0034 }
0035
0036 bool BoundaryTolerance::hasAbsoluteEuclidean() const {
0037 return holdsVariant<AbsoluteEuclideanParams>();
0038 }
0039
0040 bool BoundaryTolerance::hasChi2Bound() const {
0041 return holdsVariant<Chi2BoundParams>();
0042 }
0043
0044 BoundaryTolerance::ToleranceMode BoundaryTolerance::toleranceMode() const {
0045 using enum ToleranceMode;
0046 if (isInfinite()) {
0047 return Extend;
0048 }
0049
0050 if (isNone()) {
0051 return None;
0052 }
0053
0054 if (const auto* absoluteBound = getVariantPtr<AbsoluteBoundParams>();
0055 absoluteBound != nullptr) {
0056 if (absoluteBound->tolerance0 == 0. && absoluteBound->tolerance1 == 0.) {
0057 return None;
0058 }
0059
0060 return Extend;
0061 }
0062
0063 if (const auto* absoluteCartesian = getVariantPtr<AbsoluteCartesianParams>();
0064 absoluteCartesian != nullptr) {
0065 if (absoluteCartesian->tolerance0 == 0. &&
0066 absoluteCartesian->tolerance1 == 0.) {
0067 return None;
0068 }
0069
0070 return Extend;
0071 }
0072
0073 if (const auto* absoluteEuclidean = getVariantPtr<AbsoluteEuclideanParams>();
0074 absoluteEuclidean != nullptr) {
0075 if (absoluteEuclidean->tolerance == 0.) {
0076 return None;
0077 } else if (absoluteEuclidean->tolerance > 0.) {
0078 return Extend;
0079 } else {
0080 return Shrink;
0081 }
0082 }
0083
0084 if (const auto* chi2Bound = getVariantPtr<Chi2BoundParams>();
0085 chi2Bound != nullptr) {
0086 if (chi2Bound->maxChi2 == 0.) {
0087 return None;
0088 } else if (chi2Bound->maxChi2 >= 0.) {
0089 return Extend;
0090 } else {
0091 return Shrink;
0092 }
0093 }
0094
0095 assert(false && "Unsupported tolerance type");
0096 return None;
0097 }
0098
0099 BoundaryTolerance::AbsoluteBoundParams BoundaryTolerance::asAbsoluteBound(
0100 bool isCartesian) const {
0101 if (isNone()) {
0102 return AbsoluteBoundParams{0., 0.};
0103 }
0104
0105 if (isCartesian && hasAbsoluteCartesian()) {
0106 const auto& cartesian = getVariant<AbsoluteCartesianParams>();
0107 return AbsoluteBoundParams{cartesian.tolerance0, cartesian.tolerance1};
0108 }
0109
0110 return getVariant<AbsoluteBoundParams>();
0111 }
0112
0113 const BoundaryTolerance::AbsoluteCartesianParams&
0114 BoundaryTolerance::asAbsoluteCartesian() const {
0115 return getVariant<AbsoluteCartesianParams>();
0116 }
0117
0118 const BoundaryTolerance::AbsoluteEuclideanParams&
0119 BoundaryTolerance::asAbsoluteEuclidean() const {
0120 return getVariant<AbsoluteEuclideanParams>();
0121 }
0122
0123 const BoundaryTolerance::Chi2BoundParams& BoundaryTolerance::asChi2Bound()
0124 const {
0125 return getVariant<Chi2BoundParams>();
0126 }
0127
0128 std::optional<BoundaryTolerance::AbsoluteBoundParams>
0129 BoundaryTolerance::asAbsoluteBoundOpt(bool isCartesian) const {
0130 return hasAbsoluteBound(isCartesian)
0131 ? std::optional(asAbsoluteBound(isCartesian))
0132 : std::nullopt;
0133 }
0134
0135 bool BoundaryTolerance::isTolerated(
0136 const Vector2& distance,
0137 const std::optional<SquareMatrix2>& jacobianOpt) const {
0138 if (isInfinite()) {
0139 return true;
0140 }
0141
0142 if (isNone()) {
0143 return distance == Vector2::Zero();
0144 }
0145
0146 if (const auto* absoluteBound = getVariantPtr<AbsoluteBoundParams>();
0147 absoluteBound != nullptr) {
0148 return std::abs(distance[0]) <= absoluteBound->tolerance0 &&
0149 std::abs(distance[1]) <= absoluteBound->tolerance1;
0150 }
0151
0152 if (const auto* chi2Bound = getVariantPtr<Chi2BoundParams>();
0153 chi2Bound != nullptr) {
0154
0155 double chi2 = distance.transpose() * chi2Bound->weightMatrix() * distance;
0156 if (chi2Bound->maxChi2 < 0) {
0157 return chi2 > 2 * std::abs(chi2Bound->maxChi2);
0158 } else {
0159 return chi2 <= 2 * chi2Bound->maxChi2;
0160 }
0161 }
0162
0163 bool isCartesian = !jacobianOpt.has_value();
0164 Vector2 cartesianDistance;
0165 if (isCartesian) {
0166 cartesianDistance = distance;
0167 } else {
0168 const auto& jacobian = *jacobianOpt;
0169 cartesianDistance = jacobian * distance;
0170 }
0171
0172 if (const auto* absoluteCartesian = getVariantPtr<AbsoluteCartesianParams>();
0173 absoluteCartesian != nullptr) {
0174 return std::abs(cartesianDistance[0]) <= absoluteCartesian->tolerance0 &&
0175 std::abs(cartesianDistance[1]) <= absoluteCartesian->tolerance1;
0176 }
0177
0178 if (const auto* absoluteEuclidean = getVariantPtr<AbsoluteEuclideanParams>();
0179 absoluteEuclidean != nullptr) {
0180 if (absoluteEuclidean->tolerance < 0) {
0181 return cartesianDistance.norm() > std::abs(absoluteEuclidean->tolerance);
0182 } else {
0183 return cartesianDistance.norm() <= absoluteEuclidean->tolerance;
0184 }
0185 }
0186
0187 throw std::logic_error("Unsupported tolerance type");
0188 }
0189
0190 bool BoundaryTolerance::hasMetric(bool hasJacobian) const {
0191 return hasJacobian || hasChi2Bound();
0192 }
0193
0194 SquareMatrix2 BoundaryTolerance::getMetric(
0195 const std::optional<SquareMatrix2>& jacobianOpt) const {
0196 bool isCartesian = !jacobianOpt.has_value();
0197 SquareMatrix2 metric = SquareMatrix2::Identity();
0198
0199 if (const auto* chi2Bound =
0200 getVariantPtr<BoundaryTolerance::Chi2BoundParams>();
0201 chi2Bound != nullptr) {
0202 metric = chi2Bound->weightMatrix();
0203 } else if (!isCartesian) {
0204 const auto& jacobian = *jacobianOpt;
0205 metric = jacobian.transpose() * jacobian;
0206 }
0207
0208 return metric;
0209 }
0210
0211 }