Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:28

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