Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:59

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/Tests/CommonHelpers/FloatComparisons.hpp"
0013 #include "Acts/Utilities/detail/periodic.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 BOOST_DATA_TEST_CASE(DifferencePeriodic, bd::make(kDifferencePeriodicDataset),
0062                      lhs, rhs, range, diff) {
0063   CHECK_CLOSE_ABS(difference_periodic(lhs, rhs, range), diff, tol);
0064   CHECK_CLOSE_ABS(difference_periodic(rhs, lhs, range), -diff, tol);
0065 }
0066 
0067 BOOST_DATA_TEST_CASE(RadianPos, bd::xrange(0.25, std::numbers::pi, 0.5),
0068                      delta) {
0069   // above upper limit folds back just above lower limit
0070   CHECK_CLOSE_ABS(radian_pos(0 - delta), 2 * std::numbers::pi - delta, tol);
0071   // below lower limit folds back just below upper limit
0072   CHECK_CLOSE_ABS(radian_pos(2 * std::numbers::pi + delta), delta, tol);
0073   // same as above but with additional 2pi shifts
0074   CHECK_CLOSE_ABS(radian_pos(-2 * std::numbers::pi - delta),
0075                   2 * std::numbers::pi - delta, tol);
0076   CHECK_CLOSE_ABS(radian_pos(4 * std::numbers::pi + delta), delta, tol);
0077 }
0078 
0079 BOOST_DATA_TEST_CASE(RadianSym, bd::xrange(0.25, std::numbers::pi, 0.5),
0080                      delta) {
0081   // above upper limit folds back just above lower limit
0082   CHECK_CLOSE_ABS(radian_sym(-std::numbers::pi - delta),
0083                   std::numbers::pi - delta, tol);
0084   // below lower limit folds back just below upper limit
0085   CHECK_CLOSE_ABS(radian_sym(std::numbers::pi + delta),
0086                   -std::numbers::pi + delta, tol);
0087   // same as above but with additional 2pi shifts
0088   CHECK_CLOSE_ABS(radian_sym(-std::numbers::pi - delta - 2 * std::numbers::pi),
0089                   std::numbers::pi - delta, tol);
0090   CHECK_CLOSE_ABS(radian_sym(std::numbers::pi + delta + 2 * std::numbers::pi),
0091                   -std::numbers::pi + delta, tol);
0092 }
0093 
0094 BOOST_DATA_TEST_CASE(NormalizePhiThetaInBounds,
0095                      bd::xrange(-std::numbers::pi, std::numbers::pi,
0096                                 std::numbers::pi / 2.) *
0097                          bd::xrange(0., std::numbers::pi,
0098                                     std::numbers::pi / 4.),
0099                      phix, thetax) {
0100   // both phi and theta are in bounds and should remain unchanged
0101   auto [phi, theta] = normalizePhiTheta(phix, thetax);
0102   CHECK_CLOSE_ABS(phi, phix, tol);
0103   CHECK_CLOSE_ABS(theta, thetax, tol);
0104 }
0105 
0106 BOOST_DATA_TEST_CASE(NormalizePhiThetaCyclicPhi,
0107                      bd::xrange(0.25, std::numbers::pi, 0.5) *
0108                          bd::xrange(0., std::numbers::pi,
0109                                     std::numbers::pi / 4.),
0110                      deltaPhi, thetax) {
0111   // phi is outside bounds, but theta is within and should remain unchanged
0112   {
0113     // phi is too large
0114     auto [phi, theta] = normalizePhiTheta(std::numbers::pi + deltaPhi, thetax);
0115     CHECK_CLOSE_ABS(phi, -std::numbers::pi + deltaPhi, tol);
0116     CHECK_CLOSE_ABS(theta, thetax, tol);
0117   }
0118   {
0119     // phi is too small
0120     auto [phi, theta] = normalizePhiTheta(-std::numbers::pi - deltaPhi, thetax);
0121     CHECK_CLOSE_ABS(phi, std::numbers::pi - deltaPhi, tol);
0122     CHECK_CLOSE_ABS(theta, thetax, tol);
0123   }
0124 }
0125 
0126 BOOST_DATA_TEST_CASE(NormalizePhiThetaOutOfBoundsTheta,
0127                      bd::xrange(0., std::numbers::pi, 1.) *
0128                          bd::xrange(0.25, std::numbers::pi, 1.),
0129                      positivePhi, deltaTheta) {
0130   // theta is outside bounds, both phi and theta are updated
0131   {
0132     // theta is too large
0133     auto [phi, theta] =
0134         normalizePhiTheta(positivePhi, std::numbers::pi + deltaTheta);
0135     CHECK_CLOSE_ABS(phi, -std::numbers::pi + positivePhi, tol);
0136     CHECK_CLOSE_ABS(theta, std::numbers::pi - deltaTheta, tol);
0137   }
0138   {
0139     // theta is too small
0140     auto [phi, theta] = normalizePhiTheta(positivePhi, 0. - deltaTheta);
0141     CHECK_CLOSE_ABS(phi, -std::numbers::pi + positivePhi, tol);
0142     CHECK_CLOSE_ABS(theta, deltaTheta, tol);
0143   }
0144 }