Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PeriodicTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PeriodicTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2020 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #include <boost/test/data/monomorphic.hpp>
10 #include <boost/test/data/test_case.hpp>
11 #include <boost/test/unit_test.hpp>
12 
15 
16 #include <cmath>
17 #include <limits>
18 #include <tuple>
19 #include <utility>
20 
25 namespace bd = boost::unit_test::data;
26 
27 namespace {
28 constexpr auto tol = std::numeric_limits<double>::epsilon();
29 }
30 
31 namespace {
32 // Test dataset for periodic difference calculation, each entry is
33 //
34 // lhs, rhs, periodic range, expected difference
35 //
36 constexpr std::tuple<double, double, double, double>
37  kDifferencePeriodicDataset[] = {
38  // lhs,rhs are exactly n periods apart
39  {0.0, 1.0, 1.0, 0.0},
40  {0.5, 1.5, 1.0, 0.0},
41  {-1.5, 1.5, 1.0, 0.0},
42  {0.0, 4.0, 1.0, 0.0},
43  {0.5, 3.5, 1.0, 0.0},
44  {-1.5, -125.5, 1.0, 0.0},
45  // lhs,rhs are within one period and close together
46  {0.75, 1.25, 2.0, -0.5},
47  {4.25, 4.75, 2.0, -0.5},
48  // lhs,rhs are within one period but far apart
49  {0.25, 1.75, 2.0, 0.5},
50  {-0.75, 0.75, 2.0, 0.5},
51  // lhs,rhs are not within one period and close together
52  {0.75, 5.25, 2.0, -0.5},
53  {1.25, -2.5, 2.0, -0.25},
54  // one of lhs,rhs is over the edge and close together
55  {-0.25, +0.25, 2 * M_PI, -0.5},
56  {+0.25, -0.25, 2 * M_PI, +0.5},
57  {2 * M_PI - 0.25, 2 * M_PI + 0.25, 2 * M_PI, -0.5},
58 };
59 } // namespace
60 BOOST_DATA_TEST_CASE(DifferencePeriodic, bd::make(kDifferencePeriodicDataset),
61  lhs, rhs, range, diff) {
62  CHECK_CLOSE_ABS(difference_periodic(lhs, rhs, range), diff, tol);
63  CHECK_CLOSE_ABS(difference_periodic(rhs, lhs, range), -diff, tol);
64 }
65 
66 BOOST_DATA_TEST_CASE(RadianPos, bd::xrange(0.25, M_PI, 0.5), delta) {
67  // above upper limit folds back just above lower limit
68  CHECK_CLOSE_ABS(radian_pos(0 - delta), 2 * M_PI - delta, tol);
69  // below lower limit folds back just below upper limit
70  CHECK_CLOSE_ABS(radian_pos(2 * M_PI + delta), delta, tol);
71  // same as above but with additional 2pi shifts
72  CHECK_CLOSE_ABS(radian_pos(-2 * M_PI - delta), 2 * M_PI - delta, tol);
73  CHECK_CLOSE_ABS(radian_pos(4 * M_PI + delta), delta, tol);
74 }
75 
76 BOOST_DATA_TEST_CASE(RadianSym, bd::xrange(0.25, M_PI, 0.5), delta) {
77  // above upper limit folds back just above lower limit
78  CHECK_CLOSE_ABS(radian_sym(-M_PI - delta), M_PI - delta, tol);
79  // below lower limit folds back just below upper limit
80  CHECK_CLOSE_ABS(radian_sym(M_PI + delta), -M_PI + delta, tol);
81  // same as above but with additional 2pi shifts
82  CHECK_CLOSE_ABS(radian_sym(-M_PI - delta - 2 * M_PI), M_PI - delta, tol);
83  CHECK_CLOSE_ABS(radian_sym(M_PI + delta + 2 * M_PI), -M_PI + delta, tol);
84 }
85 
86 BOOST_DATA_TEST_CASE(NormalizePhiThetaInBounds,
87  bd::xrange(-M_PI, M_PI, M_PI_2) *
88  bd::xrange(0.0, M_PI, M_PI_4),
89  phix, thetax) {
90  // both phi and theta are in bounds and should remain unchanged
91  auto [phi, theta] = normalizePhiTheta(phix, thetax);
92  CHECK_CLOSE_ABS(phi, phix, tol);
93  CHECK_CLOSE_ABS(theta, thetax, tol);
94 }
95 
96 BOOST_DATA_TEST_CASE(NormalizePhiThetaCyclicPhi,
97  bd::xrange(0.25, M_PI, 0.5) *
98  bd::xrange(0.0, M_PI, M_PI_4),
99  deltaPhi, thetax) {
100  // phi is outside bounds, but theta is within and should remain unchanged
101  {
102  // phi is too large
103  auto [phi, theta] = normalizePhiTheta(M_PI + deltaPhi, thetax);
104  CHECK_CLOSE_ABS(phi, -M_PI + deltaPhi, tol);
105  CHECK_CLOSE_ABS(theta, thetax, tol);
106  }
107  {
108  // phi is too small
109  auto [phi, theta] = normalizePhiTheta(-M_PI - deltaPhi, thetax);
110  CHECK_CLOSE_ABS(phi, M_PI - deltaPhi, tol);
111  CHECK_CLOSE_ABS(theta, thetax, tol);
112  }
113 }
114 
115 BOOST_DATA_TEST_CASE(NormalizePhiThetaOutOfBoundsTheta,
116  bd::xrange(0.0, M_PI, 1.0) * bd::xrange(0.25, M_PI, 1.0),
117  positivePhi, deltaTheta) {
118  // theta is outside bounds, both phi and theta are updated
119  {
120  // theta is too large
121  auto [phi, theta] = normalizePhiTheta(positivePhi, M_PI + deltaTheta);
122  CHECK_CLOSE_ABS(phi, -M_PI + positivePhi, tol);
123  CHECK_CLOSE_ABS(theta, M_PI - deltaTheta, tol);
124  }
125  {
126  // theta is too small
127  auto [phi, theta] = normalizePhiTheta(positivePhi, 0.0 - deltaTheta);
128  CHECK_CLOSE_ABS(phi, -M_PI + positivePhi, tol);
129  CHECK_CLOSE_ABS(theta, deltaTheta, tol);
130  }
131 }