File indexing completed on 2025-01-18 09:12:50
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/execution_monitor.hpp>
0010 #include <boost/test/unit_test.hpp>
0011
0012 #include "Acts/Definitions/Algebra.hpp"
0013 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0014 #include "Acts/Surfaces/detail/BoundaryCheckHelper.hpp"
0015 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0016 #include "Acts/Utilities/Helpers.hpp"
0017
0018 #include <algorithm>
0019 #include <cstddef>
0020 #include <fstream>
0021 #include <limits>
0022 #include <optional>
0023 #include <random>
0024 #include <vector>
0025
0026 namespace Acts::Test {
0027
0028 BOOST_AUTO_TEST_SUITE(Surfaces)
0029
0030 BOOST_AUTO_TEST_CASE(BoundaryToleranceConstructors) {
0031 using enum BoundaryTolerance::ToleranceMode;
0032 {
0033
0034 BoundaryTolerance tolerance = BoundaryTolerance::None();
0035 BOOST_CHECK(tolerance.toleranceMode() == None);
0036 }
0037
0038
0039 {
0040
0041 auto tolerance = BoundaryTolerance::AbsoluteBound(1.0, 2.0);
0042 BOOST_CHECK_EQUAL(tolerance.asAbsoluteBound().tolerance0, 1.0);
0043 BOOST_CHECK_EQUAL(tolerance.asAbsoluteBound().tolerance1, 2.0);
0044 BOOST_CHECK(tolerance.toleranceMode() == Extend);
0045 BOOST_CHECK(BoundaryTolerance::AbsoluteBound(0.0, 0.0).toleranceMode() ==
0046 None);
0047
0048
0049 BOOST_CHECK_THROW(BoundaryTolerance::AbsoluteBound(-1.0, 2.0),
0050 std::invalid_argument);
0051 BOOST_CHECK_THROW(BoundaryTolerance::AbsoluteBound(1.0, -2.0),
0052 std::invalid_argument);
0053 }
0054
0055
0056 {
0057
0058 auto tolerance = BoundaryTolerance::AbsoluteEuclidean(1.0);
0059 BOOST_CHECK_EQUAL(tolerance.asAbsoluteEuclidean().tolerance, 1.0);
0060 BOOST_CHECK(tolerance.toleranceMode() == Extend);
0061 BOOST_CHECK(BoundaryTolerance::AbsoluteEuclidean(0.0).toleranceMode() ==
0062 None);
0063
0064
0065 tolerance = BoundaryTolerance::AbsoluteEuclidean(-1.0);
0066 BOOST_CHECK_EQUAL(tolerance.asAbsoluteEuclidean().tolerance, -1.0);
0067 BOOST_CHECK(tolerance.toleranceMode() == Shrink);
0068 }
0069
0070
0071 {
0072
0073 auto tolerance = BoundaryTolerance::AbsoluteCartesian(1.0, 2.0);
0074 BOOST_CHECK_EQUAL(tolerance.asAbsoluteCartesian().tolerance0, 1.0);
0075 BOOST_CHECK_EQUAL(tolerance.asAbsoluteCartesian().tolerance1, 2.0);
0076 BOOST_CHECK(tolerance.toleranceMode() == Extend);
0077 BOOST_CHECK(
0078 BoundaryTolerance::AbsoluteCartesian(0.0, 0.0).toleranceMode() == None);
0079
0080
0081 BOOST_CHECK_THROW(BoundaryTolerance::AbsoluteCartesian(-1.0, 2.0),
0082 std::invalid_argument);
0083 BOOST_CHECK_THROW(BoundaryTolerance::AbsoluteCartesian(1.0, -2.0),
0084 std::invalid_argument);
0085 }
0086
0087
0088 {
0089 SquareMatrix2 cov;
0090 cov << 1, 0.5, 0.5, 2;
0091
0092
0093 auto tolerance = BoundaryTolerance::Chi2Bound(cov, 3.0);
0094 BOOST_CHECK_EQUAL(tolerance.asChi2Bound().maxChi2, 3.0);
0095 BOOST_CHECK(tolerance.toleranceMode() == Extend);
0096 BOOST_CHECK(BoundaryTolerance::Chi2Bound(cov, 0.0).toleranceMode() == None);
0097
0098
0099 tolerance = BoundaryTolerance::Chi2Bound(cov, -3.0);
0100 BOOST_CHECK_EQUAL(tolerance.asChi2Bound().maxChi2, -3.0);
0101 BOOST_CHECK(tolerance.toleranceMode() == Shrink);
0102 }
0103
0104
0105 BoundaryTolerance::None();
0106 }
0107
0108
0109
0110
0111 BOOST_AUTO_TEST_CASE(BoundaryCheckBoxSimple) {
0112 Vector2 ll(-1, -1);
0113 Vector2 ur(1, 1);
0114 auto tolerance = BoundaryTolerance::None();
0115 BOOST_CHECK(
0116 detail::insideAlignedBox(ll, ur, tolerance, {0, 0}, std::nullopt));
0117 BOOST_CHECK(
0118 !detail::insideAlignedBox(ll, ur, tolerance, {2, 2}, std::nullopt));
0119 BOOST_CHECK(
0120 !detail::insideAlignedBox(ll, ur, tolerance, {0, 2}, std::nullopt));
0121 BOOST_CHECK(
0122 !detail::insideAlignedBox(ll, ur, tolerance, {2, 0}, std::nullopt));
0123 }
0124
0125
0126 BOOST_AUTO_TEST_CASE(BoundaryCheckBoxToleranceLoc0) {
0127 boost::execution_monitor em;
0128 em.p_detect_fp_exceptions.set(boost::fpe::BOOST_FPE_ALL);
0129
0130 em.execute([]() {
0131 Vector2 ll(-1, -1);
0132 Vector2 ur(1, 1);
0133 auto tolerance = BoundaryTolerance::AbsoluteBound(
0134 1.5, std::numeric_limits<double>::infinity());
0135 BOOST_CHECK(
0136 detail::insideAlignedBox(ll, ur, tolerance, {0, 0}, std::nullopt));
0137 BOOST_CHECK(
0138 detail::insideAlignedBox(ll, ur, tolerance, {2, 2}, std::nullopt));
0139 BOOST_CHECK(
0140 !detail::insideAlignedBox(ll, ur, tolerance, {4, 4}, std::nullopt));
0141 BOOST_CHECK(
0142 detail::insideAlignedBox(ll, ur, tolerance, {0, 2}, std::nullopt));
0143 BOOST_CHECK(
0144 detail::insideAlignedBox(ll, ur, tolerance, {2, 0}, std::nullopt));
0145
0146 return 0;
0147 });
0148 }
0149
0150
0151 BOOST_AUTO_TEST_CASE(BoundaryCheckBoxCovariance) {
0152 SquareMatrix2 cov;
0153 cov << 1, 0.5, 0.5, 2;
0154 Vector2 ll(-1, -1);
0155 Vector2 ur(1, 1);
0156 auto tolerance = BoundaryTolerance::Chi2Bound(cov.inverse(), 3.);
0157 BOOST_CHECK(
0158 detail::insideAlignedBox(ll, ur, tolerance, {0, 0}, std::nullopt));
0159 BOOST_CHECK(
0160 detail::insideAlignedBox(ll, ur, tolerance, {2, 2}, std::nullopt));
0161 BOOST_CHECK(
0162 !detail::insideAlignedBox(ll, ur, tolerance, {4, 4}, std::nullopt));
0163 BOOST_CHECK(
0164 detail::insideAlignedBox(ll, ur, tolerance, {0, 3}, std::nullopt));
0165 BOOST_CHECK(
0166 detail::insideAlignedBox(ll, ur, tolerance, {3, 0}, std::nullopt));
0167 }
0168
0169
0170 BOOST_AUTO_TEST_CASE(BoundaryCheckTriangleSimple) {
0171 Vector2 vertices[] = {{-2, 0}, {2, 0}, {0, 2}};
0172 auto tolerance = BoundaryTolerance::None();
0173 BOOST_CHECK(detail::insidePolygon(vertices, tolerance, {0, 0}, std::nullopt));
0174 BOOST_CHECK(detail::insidePolygon(vertices, tolerance, {0, 1}, std::nullopt));
0175 BOOST_CHECK(
0176 !detail::insidePolygon(vertices, tolerance, {2, 2}, std::nullopt));
0177 BOOST_CHECK(
0178 !detail::insidePolygon(vertices, tolerance, {0, -1}, std::nullopt));
0179 }
0180
0181 BOOST_AUTO_TEST_CASE(BoundaryCheckTriangleCovariance) {
0182 Vector2 vertices[] = {{-2, 0}, {2, 0}, {0, 2}};
0183 SquareMatrix2 cov;
0184 cov << 0.5, 0, 0, 0.5;
0185 auto tolerance = BoundaryTolerance::Chi2Bound(cov.inverse(), 4.1);
0186 BOOST_CHECK(detail::insidePolygon(vertices, tolerance, {0, 0}, std::nullopt));
0187 BOOST_CHECK(detail::insidePolygon(vertices, tolerance, {0, 1}, std::nullopt));
0188 BOOST_CHECK(detail::insidePolygon(vertices, tolerance, {0, 2}, std::nullopt));
0189 BOOST_CHECK(detail::insidePolygon(vertices, tolerance, {0, 3}, std::nullopt));
0190 BOOST_CHECK(detail::insidePolygon(vertices, tolerance, {0, 4}, std::nullopt));
0191 BOOST_CHECK(
0192 !detail::insidePolygon(vertices, tolerance, {0, 5}, std::nullopt));
0193 }
0194
0195 BOOST_AUTO_TEST_CASE(BoundaryCheckDifferentTolerances) {
0196 Vector2 ll(-1, -1);
0197 Vector2 ur(1, 1);
0198
0199 {
0200 auto tolerance = BoundaryTolerance::None();
0201 BOOST_CHECK(
0202 detail::insideAlignedBox(ll, ur, tolerance, {0, 0}, std::nullopt));
0203 BOOST_CHECK(
0204 !detail::insideAlignedBox(ll, ur, tolerance, {2, 2}, std::nullopt));
0205 BOOST_CHECK(
0206 !detail::insideAlignedBox(ll, ur, tolerance, {0, 2}, std::nullopt));
0207 BOOST_CHECK(
0208 !detail::insideAlignedBox(ll, ur, tolerance, {2, 0}, std::nullopt));
0209 }
0210
0211 {
0212 auto tolerance = BoundaryTolerance::Infinite();
0213 BOOST_CHECK(
0214 detail::insideAlignedBox(ll, ur, tolerance, {0, 0}, std::nullopt));
0215 BOOST_CHECK(
0216 detail::insideAlignedBox(ll, ur, tolerance, {2, 2}, std::nullopt));
0217 BOOST_CHECK(
0218 detail::insideAlignedBox(ll, ur, tolerance, {0, 2}, std::nullopt));
0219 BOOST_CHECK(
0220 detail::insideAlignedBox(ll, ur, tolerance, {2, 0}, std::nullopt));
0221 }
0222
0223 {
0224 auto tolerance = BoundaryTolerance::AbsoluteBound(0.5, 0.5);
0225 BOOST_CHECK(
0226 detail::insideAlignedBox(ll, ur, tolerance, {0, 0}, std::nullopt));
0227 BOOST_CHECK(
0228 detail::insideAlignedBox(ll, ur, tolerance, {1.1, 1.1}, std::nullopt));
0229 BOOST_CHECK(
0230 detail::insideAlignedBox(ll, ur, tolerance, {0, 1.1}, std::nullopt));
0231 BOOST_CHECK(
0232 detail::insideAlignedBox(ll, ur, tolerance, {1.1, 0}, std::nullopt));
0233 BOOST_CHECK(
0234 !detail::insideAlignedBox(ll, ur, tolerance, {2, 2}, std::nullopt));
0235 BOOST_CHECK(
0236 !detail::insideAlignedBox(ll, ur, tolerance, {0, 2}, std::nullopt));
0237 BOOST_CHECK(
0238 !detail::insideAlignedBox(ll, ur, tolerance, {2, 0}, std::nullopt));
0239 }
0240
0241 {
0242 auto tolerance = BoundaryTolerance::AbsoluteCartesian(0.5, 0.5);
0243 BOOST_CHECK(
0244 detail::insideAlignedBox(ll, ur, tolerance, {0, 0}, std::nullopt));
0245 BOOST_CHECK(
0246 detail::insideAlignedBox(ll, ur, tolerance, {1.1, 1.1}, std::nullopt));
0247 BOOST_CHECK(
0248 detail::insideAlignedBox(ll, ur, tolerance, {0, 1.1}, std::nullopt));
0249 BOOST_CHECK(
0250 detail::insideAlignedBox(ll, ur, tolerance, {1.1, 0}, std::nullopt));
0251 BOOST_CHECK(
0252 !detail::insideAlignedBox(ll, ur, tolerance, {2, 2}, std::nullopt));
0253 BOOST_CHECK(
0254 !detail::insideAlignedBox(ll, ur, tolerance, {0, 2}, std::nullopt));
0255 BOOST_CHECK(
0256 !detail::insideAlignedBox(ll, ur, tolerance, {2, 0}, std::nullopt));
0257 }
0258
0259 {
0260 auto tolerance = BoundaryTolerance::AbsoluteEuclidean(1.1);
0261 BOOST_CHECK(
0262 detail::insideAlignedBox(ll, ur, tolerance, {0, 0}, std::nullopt));
0263 BOOST_CHECK(
0264 !detail::insideAlignedBox(ll, ur, tolerance, {2, 2}, std::nullopt));
0265 BOOST_CHECK(
0266 detail::insideAlignedBox(ll, ur, tolerance, {0, 2}, std::nullopt));
0267 BOOST_CHECK(
0268 detail::insideAlignedBox(ll, ur, tolerance, {2, 0}, std::nullopt));
0269 }
0270
0271 {
0272 auto tolerance =
0273 BoundaryTolerance::Chi2Bound(SquareMatrix2::Identity(), 1.);
0274 BOOST_CHECK(
0275 detail::insideAlignedBox(ll, ur, tolerance, {0, 0}, std::nullopt));
0276 BOOST_CHECK(
0277 detail::insideAlignedBox(ll, ur, tolerance, {2, 2}, std::nullopt));
0278 BOOST_CHECK(
0279 detail::insideAlignedBox(ll, ur, tolerance, {0, 2}, std::nullopt));
0280 BOOST_CHECK(
0281 detail::insideAlignedBox(ll, ur, tolerance, {2, 0}, std::nullopt));
0282 BOOST_CHECK(
0283 !detail::insideAlignedBox(ll, ur, tolerance, {3, 3}, std::nullopt));
0284 }
0285 }
0286
0287 BOOST_AUTO_TEST_CASE(BoundaryCheckNegativeToleranceRect) {
0288
0289 Vector2 ll(1, 1);
0290 Vector2 ur(3, 3);
0291
0292 auto check = [&ll, &ur](const BoundaryTolerance& tolerance,
0293 const Vector2& point) {
0294 return detail::insideAlignedBox(ll, ur, tolerance, point, std::nullopt);
0295 };
0296
0297 {
0298 auto tolerance = BoundaryTolerance::AbsoluteEuclidean(-0.25);
0299
0300 BOOST_CHECK(!check(tolerance, {2.8, 2}));
0301 BOOST_CHECK(!check(tolerance, {3.1, 2}));
0302 BOOST_CHECK(check(tolerance, {2.7, 2}));
0303 BOOST_CHECK(!check(tolerance, {2, 3.1}));
0304 BOOST_CHECK(!check(tolerance, {2, 2.8}));
0305 BOOST_CHECK(check(tolerance, {2, 2.7}));
0306
0307 BOOST_CHECK(!check(tolerance, {0.8, 2}));
0308 BOOST_CHECK(!check(tolerance, {1.2, 2}));
0309 BOOST_CHECK(check(tolerance, {1.5, 2}));
0310 BOOST_CHECK(!check(tolerance, {2, 0.8}));
0311 BOOST_CHECK(!check(tolerance, {2, 1.2}));
0312 BOOST_CHECK(check(tolerance, {2, 1.5}));
0313 }
0314
0315 {
0316 auto tolerance =
0317 BoundaryTolerance::Chi2Bound(SquareMatrix2::Identity(), -0.1);
0318
0319 BOOST_CHECK(!check(tolerance, {2.8, 2}));
0320 BOOST_CHECK(!check(tolerance, {3.1, 2}));
0321 BOOST_CHECK(check(tolerance, {2.5, 2}));
0322 BOOST_CHECK(!check(tolerance, {2, 3.1}));
0323 BOOST_CHECK(!check(tolerance, {2, 2.8}));
0324 BOOST_CHECK(check(tolerance, {2, 2.5}));
0325
0326 BOOST_CHECK(!check(tolerance, {0.8, 2}));
0327 BOOST_CHECK(!check(tolerance, {1.4, 2}));
0328 BOOST_CHECK(check(tolerance, {1.5, 2}));
0329 BOOST_CHECK(!check(tolerance, {2, 0.8}));
0330 BOOST_CHECK(!check(tolerance, {2, 1.4}));
0331 BOOST_CHECK(check(tolerance, {2, 1.5}));
0332 }
0333 }
0334
0335 BOOST_AUTO_TEST_CASE(BoundaryCheckNegativeToleranceTrap) {
0336 Vector2 vertices[] = {{1.5, 1}, {2.5, 1}, {3, 3}, {1, 3}};
0337
0338 auto check = [&vertices](const BoundaryTolerance& tolerance,
0339 const Vector2& point) {
0340 return detail::insidePolygon(vertices, tolerance, point, std::nullopt);
0341 };
0342
0343 {
0344 auto tolerance = BoundaryTolerance::AbsoluteEuclidean(0.25);
0345
0346 BOOST_CHECK(!check(tolerance, {3.1, 2}));
0347 BOOST_CHECK(check(tolerance, {2.75, 2}));
0348 BOOST_CHECK(check(tolerance, {2.5, 2}));
0349 BOOST_CHECK(check(tolerance, {2.25, 2}));
0350 BOOST_CHECK(check(tolerance, {2, 3.1}));
0351 BOOST_CHECK(check(tolerance, {2, 2.75}));
0352 BOOST_CHECK(check(tolerance, {2, 2.5}));
0353 BOOST_CHECK(check(tolerance, {2, 2.25}));
0354 BOOST_CHECK(check(tolerance, {2, 2}));
0355
0356
0357 BOOST_CHECK(check(tolerance, {3.1, 3.2}));
0358 BOOST_CHECK(check(tolerance, {0.9, 3.2}));
0359 BOOST_CHECK(check(tolerance, {1.5, 0.8}));
0360 BOOST_CHECK(check(tolerance, {2.5, 0.8}));
0361 }
0362
0363 {
0364 auto tolerance = BoundaryTolerance::AbsoluteEuclidean(-0.25);
0365
0366 BOOST_CHECK(!check(tolerance, {3.0, 2}));
0367 BOOST_CHECK(!check(tolerance, {2.5, 2}));
0368 BOOST_CHECK(check(tolerance, {2.25, 2}));
0369 BOOST_CHECK(!check(tolerance, {2, 3.1}));
0370 BOOST_CHECK(!check(tolerance, {2, 2.9}));
0371 BOOST_CHECK(check(tolerance, {2, 2.7}));
0372
0373
0374 BOOST_CHECK(!check(tolerance, {2.7, 2.9}));
0375 BOOST_CHECK(check(tolerance, {2.4, 2.6}));
0376 BOOST_CHECK(!check(tolerance, {1.3, 2.9}));
0377 BOOST_CHECK(check(tolerance, {1.6, 2.6}));
0378 BOOST_CHECK(!check(tolerance, {2.4, 1.1}));
0379 BOOST_CHECK(check(tolerance, {1.75, 1.4}));
0380 BOOST_CHECK(!check(tolerance, {1.6, 1.1}));
0381 BOOST_CHECK(check(tolerance, {2.25, 1.4}));
0382 }
0383 }
0384
0385 BOOST_AUTO_TEST_SUITE_END()
0386
0387 }