Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-24 08:20:43

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 <boost/test/data/test_case.hpp>
0010 #include <boost/test/unit_test.hpp>
0011 
0012 #include "Acts/Utilities/detail/periodic.hpp"
0013 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0014 
0015 #include <cmath>
0016 #include <limits>
0017 #include <numbers>
0018 #include <tuple>
0019 #include <utility>
0020 
0021 using Acts::detail::difference_periodic;
0022 using Acts::detail::normalizePhiTheta;
0023 using Acts::detail::radian_pos;
0024 using Acts::detail::radian_sym;
0025 namespace bd = boost::unit_test::data;
0026 
0027 namespace {
0028 constexpr auto tol = std::numeric_limits<double>::epsilon();
0029 }
0030 
0031 namespace {
0032 // Test dataset for periodic difference calculation, each entry is
0033 //
0034 //     lhs, rhs, periodic range, expected difference
0035 //
0036 constexpr std::tuple<double, double, double, double>
0037     kDifferencePeriodicDataset[] = {
0038         // lhs,rhs are exactly n periods apart
0039         {0.0, 1.0, 1.0, 0.0},
0040         {0.5, 1.5, 1.0, 0.0},
0041         {-1.5, 1.5, 1.0, 0.0},
0042         {0.0, 4.0, 1.0, 0.0},
0043         {0.5, 3.5, 1.0, 0.0},
0044         {-1.5, -125.5, 1.0, 0.0},
0045         // lhs,rhs are within one period and close together
0046         {0.75, 1.25, 2.0, -0.5},
0047         {4.25, 4.75, 2.0, -0.5},
0048         // lhs,rhs are within one period but far apart
0049         {0.25, 1.75, 2.0, 0.5},
0050         {-0.75, 0.75, 2.0, 0.5},
0051         // lhs,rhs are not within one period and close together
0052         {0.75, 5.25, 2.0, -0.5},
0053         {1.25, -2.5, 2.0, -0.25},
0054         // one of lhs,rhs is over the edge and close together
0055         {-0.25, +0.25, 2 * std::numbers::pi, -0.5},
0056         {+0.25, -0.25, 2 * std::numbers::pi, +0.5},
0057         {2 * std::numbers::pi - 0.25, 2 * std::numbers::pi + 0.25,
0058          2 * std::numbers::pi, -0.5},
0059 };
0060 }  // namespace
0061 
0062 namespace ActsTests {
0063 
0064 BOOST_AUTO_TEST_SUITE(UtilitiesSuite)
0065 
0066 BOOST_DATA_TEST_CASE(DifferencePeriodic, bd::make(kDifferencePeriodicDataset),
0067                      lhs, rhs, range, diff) {
0068   CHECK_CLOSE_ABS(difference_periodic(lhs, rhs, range), diff, tol);
0069   CHECK_CLOSE_ABS(difference_periodic(rhs, lhs, range), -diff, tol);
0070 }
0071 
0072 BOOST_DATA_TEST_CASE(RadianPos, bd::xrange(0.25, std::numbers::pi, 0.5),
0073                      delta) {
0074   // above upper limit folds back just above lower limit
0075   CHECK_CLOSE_ABS(radian_pos(0 - delta), 2 * std::numbers::pi - delta, tol);
0076   // below lower limit folds back just below upper limit
0077   CHECK_CLOSE_ABS(radian_pos(2 * std::numbers::pi + delta), delta, tol);
0078   // same as above but with additional 2pi shifts
0079   CHECK_CLOSE_ABS(radian_pos(-2 * std::numbers::pi - delta),
0080                   2 * std::numbers::pi - delta, tol);
0081   CHECK_CLOSE_ABS(radian_pos(4 * std::numbers::pi + delta), delta, tol);
0082 }
0083 
0084 BOOST_DATA_TEST_CASE(RadianSym, bd::xrange(0.25, std::numbers::pi, 0.5),
0085                      delta) {
0086   // above upper limit folds back just above lower limit
0087   CHECK_CLOSE_ABS(radian_sym(-std::numbers::pi - delta),
0088                   std::numbers::pi - delta, tol);
0089   // below lower limit folds back just below upper limit
0090   CHECK_CLOSE_ABS(radian_sym(std::numbers::pi + delta),
0091                   -std::numbers::pi + delta, tol);
0092   // same as above but with additional 2pi shifts
0093   CHECK_CLOSE_ABS(radian_sym(-std::numbers::pi - delta - 2 * std::numbers::pi),
0094                   std::numbers::pi - delta, tol);
0095   CHECK_CLOSE_ABS(radian_sym(std::numbers::pi + delta + 2 * std::numbers::pi),
0096                   -std::numbers::pi + delta, tol);
0097 }
0098 
0099 BOOST_DATA_TEST_CASE(NormalizePhiThetaInBounds,
0100                      bd::xrange(-std::numbers::pi, std::numbers::pi,
0101                                 std::numbers::pi / 2.) *
0102                          bd::xrange(0., std::numbers::pi,
0103                                     std::numbers::pi / 4.),
0104                      phix, thetax) {
0105   // both phi and theta are in bounds and should remain unchanged
0106   auto [phi, theta] = normalizePhiTheta(phix, thetax);
0107   CHECK_CLOSE_ABS(phi, phix, tol);
0108   CHECK_CLOSE_ABS(theta, thetax, tol);
0109 }
0110 
0111 BOOST_DATA_TEST_CASE(NormalizePhiThetaCyclicPhi,
0112                      bd::xrange(0.25, std::numbers::pi, 0.5) *
0113                          bd::xrange(0., std::numbers::pi,
0114                                     std::numbers::pi / 4.),
0115                      deltaPhi, thetax) {
0116   // phi is outside bounds, but theta is within and should remain unchanged
0117   {
0118     // phi is too large
0119     auto [phi, theta] = normalizePhiTheta(std::numbers::pi + deltaPhi, thetax);
0120     CHECK_CLOSE_ABS(phi, -std::numbers::pi + deltaPhi, tol);
0121     CHECK_CLOSE_ABS(theta, thetax, tol);
0122   }
0123   {
0124     // phi is too small
0125     auto [phi, theta] = normalizePhiTheta(-std::numbers::pi - deltaPhi, thetax);
0126     CHECK_CLOSE_ABS(phi, std::numbers::pi - deltaPhi, tol);
0127     CHECK_CLOSE_ABS(theta, thetax, tol);
0128   }
0129 }
0130 
0131 BOOST_DATA_TEST_CASE(NormalizePhiThetaOutOfBoundsTheta,
0132                      bd::xrange(0., std::numbers::pi, 1.) *
0133                          bd::xrange(0.25, std::numbers::pi, 1.),
0134                      positivePhi, deltaTheta) {
0135   // theta is outside bounds, both phi and theta are updated
0136   {
0137     // theta is too large
0138     auto [phi, theta] =
0139         normalizePhiTheta(positivePhi, std::numbers::pi + deltaTheta);
0140     CHECK_CLOSE_ABS(phi, -std::numbers::pi + positivePhi, tol);
0141     CHECK_CLOSE_ABS(theta, std::numbers::pi - deltaTheta, tol);
0142   }
0143   {
0144     // theta is too small
0145     auto [phi, theta] = normalizePhiTheta(positivePhi, 0. - deltaTheta);
0146     CHECK_CLOSE_ABS(phi, -std::numbers::pi + positivePhi, tol);
0147     CHECK_CLOSE_ABS(theta, deltaTheta, tol);
0148   }
0149 }
0150 
0151 BOOST_AUTO_TEST_SUITE_END()
0152 
0153 }  // namespace ActsTests