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