Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 08:11:35

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 #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     // Mahalanobis distances mean is 2 in 2-dim. cut is 1-d sigma.
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 }  // namespace Acts