Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HelpersTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file HelpersTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019 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/unit_test.hpp>
10 
19 
20 #include <algorithm>
21 #include <bitset>
22 #include <cmath>
23 #include <cstddef>
24 #include <limits>
25 #include <memory>
26 #include <string>
27 #include <tuple>
28 #include <utility>
29 #include <vector>
30 
31 using namespace Acts::VectorHelpers;
32 
33 namespace Acts {
34 namespace Test {
35 
36 BOOST_AUTO_TEST_SUITE(Utilities)
37 
38 BOOST_AUTO_TEST_CASE(bitset_to_matrix_to_bitset) {
39  Eigen::Matrix<int, 4, 3> mat;
40  mat << 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0;
41 
42  std::bitset<4 * 3> act = matrixToBitset(mat);
43  std::bitset<4 * 3> exp{"101001011010"};
44 
45  BOOST_CHECK_EQUAL(exp, act);
46 
47  Eigen::Matrix<int, 4, 3> cnv;
48  cnv = bitsetToMatrix<decltype(cnv)>(act);
49 
50  BOOST_CHECK_EQUAL(mat, cnv);
51 }
52 
53 struct MyStruct {
54  double phi() const { return 42; }
55 };
56 
57 BOOST_AUTO_TEST_CASE(phi_helper_test) {
58  Vector3 v(0, 1, 0);
59  CHECK_CLOSE_ABS(phi(v), M_PI / 2., 1e-9);
60 
61  MyStruct s;
62  BOOST_CHECK_EQUAL(phi(s), 42u);
63 }
64 
65 BOOST_AUTO_TEST_CASE(perp_helper_test) {
66  Vector3 v(1, 2, 3);
67  CHECK_CLOSE_ABS(perp(v), std::sqrt(1 + 2 * 2), 1e-9);
68 }
69 
70 BOOST_AUTO_TEST_CASE(theta_eta_test_helper) {
71  Vector3 v(1, 2, 3);
72  CHECK_CLOSE_ABS(theta(v), 0.640522, 1e-5);
73  CHECK_CLOSE_ABS(eta(v), 1.10359, 1e-5);
74 }
75 
76 BOOST_AUTO_TEST_CASE(cross_test_helper) {
77  {
78  Vector3 v(1, 2, 3);
79  ActsMatrix<3, 3> mat;
80  mat << 1, 2, 3, 4, 5, 6, 7, 8, 9;
81 
82  ActsMatrix<3, 3> act = cross(mat, v);
83  ActsMatrix<3, 3> exp;
84  exp << -2, -1, 0, 4, 2, 0, -2, -1, 0;
85 
86  CHECK_CLOSE_ABS(act, exp, 1e-9);
87  }
88 }
89 
90 BOOST_AUTO_TEST_CASE(toString_test_helper) {
91  ActsMatrix<3, 3> mat;
92  mat << 1, 2, 3, 4, 5, 6, 7, 8, 9;
94  out = toString(mat);
95  BOOST_CHECK(!out.empty());
96 
97  Translation3 trl{Vector3{1, 2, 3}};
98  out = toString(trl);
99  BOOST_CHECK(!out.empty());
100 
101  Transform3 trf;
102  trf = trl;
103  out = toString(trf);
104  BOOST_CHECK(!out.empty());
105 }
106 
107 BOOST_AUTO_TEST_CASE(shared_vector_helper_test) {
108  {
109  std::vector<std::shared_ptr<int>> vec;
110  vec = {std::make_shared<int>(5), std::make_shared<int>(9),
111  std::make_shared<int>(26), std::make_shared<int>(18473)};
112 
113  std::vector<int*> unpacked = unpack_shared_vector(vec);
114 
115  std::vector<int*> exp = {
116  vec[0].get(),
117  vec[1].get(),
118  vec[2].get(),
119  vec[3].get(),
120  };
121 
122  BOOST_CHECK_EQUAL_COLLECTIONS(unpacked.begin(), unpacked.end(), exp.begin(),
123  exp.end());
124  }
125 
126  // same for const
127  {
128  std::vector<std::shared_ptr<const int>> vec;
129  vec = {std::make_shared<const int>(5), std::make_shared<const int>(9),
130  std::make_shared<const int>(26), std::make_shared<const int>(18473)};
131 
132  std::vector<const int*> unpacked = unpack_shared_vector(vec);
133 
134  std::vector<const int*> exp = {
135  vec[0].get(),
136  vec[1].get(),
137  vec[2].get(),
138  vec[3].get(),
139  };
140 
141  BOOST_CHECK_EQUAL_COLLECTIONS(unpacked.begin(), unpacked.end(), exp.begin(),
142  exp.end());
143  }
144 }
145 
146 BOOST_AUTO_TEST_CASE(VectorHelpersPosition) {
147  Vector4 pos4 = Vector4::Constant(-1);
148  pos4[ePos0] = 1;
149  pos4[ePos1] = 2;
150  pos4[ePos2] = 3;
151  BOOST_CHECK_EQUAL(position(pos4), Vector3(1, 2, 3));
152 
153  FreeVector params = FreeVector::Constant(-1);
154  params[eFreePos0] = 1;
155  params[eFreePos1] = 2;
156  params[eFreePos2] = 3;
157  BOOST_CHECK_EQUAL(position(params), Vector3(1, 2, 3));
158 }
159 
160 template <size_t I>
161 struct functor {
162  static constexpr size_t invoke() { return I * I * I; }
163 };
164 
165 BOOST_AUTO_TEST_CASE(test_matrix_dimension_switch) {
166  constexpr size_t imax = 20;
167  for (size_t i = 0; i < imax; i++) {
168  size_t val = template_switch<functor, 0, imax>(i);
169  BOOST_CHECK_EQUAL(val, i * i * i);
170  }
171 }
172 
173 using MatrixProductTypes =
174  std::tuple<std::pair<ActsMatrix<3, 3>, ActsMatrix<3, 3>>,
175  std::pair<ActsMatrix<4, 4>, ActsMatrix<4, 4>>,
176  std::pair<ActsMatrix<8, 8>, ActsMatrix<8, 8>>,
177  std::pair<ActsMatrix<8, 7>, ActsMatrix<7, 4>>>;
178 
179 BOOST_AUTO_TEST_CASE_TEMPLATE(BlockedMatrixMultiplication, Matrices,
181  using A = typename Matrices::first_type;
182  using B = typename Matrices::second_type;
184 
185  for (std::size_t i = 0; i < 100; ++i) {
186  A a = A::Random();
187  B b = B::Random();
188 
189  C ref = a * b;
190  C res = blockedMult(a, b);
191 
192  BOOST_CHECK(ref.isApprox(res));
193  BOOST_CHECK(res.isApprox(ref));
194  }
195 }
196 
198  std::vector<ActsScalar> ordered = {-3., -2., -1., 0., 1., 2., 3.};
199  auto [min0, max0] = Acts::min_max(ordered);
200 
201  CHECK_CLOSE_ABS(min0, -3., std::numeric_limits<ActsScalar>::epsilon());
202  CHECK_CLOSE_ABS(max0, 3., std::numeric_limits<ActsScalar>::epsilon());
203 
204  std::vector<ActsScalar> unordered = {3., -3., -2., -1., 0., 1., 2.};
205  auto [min1, max1] = Acts::min_max(unordered);
206 
207  CHECK_CLOSE_ABS(min1, -3., std::numeric_limits<ActsScalar>::epsilon());
208  CHECK_CLOSE_ABS(max1, 3., std::numeric_limits<ActsScalar>::epsilon());
209 }
210 
212  std::vector<ActsScalar> ordered = {-3., -2., -1., 0., 1., 2., 3.};
213  auto [range0, medium0] = Acts::range_medium(ordered);
214 
215  CHECK_CLOSE_ABS(range0, 6., std::numeric_limits<ActsScalar>::epsilon());
216  CHECK_CLOSE_ABS(medium0, 0., std::numeric_limits<ActsScalar>::epsilon());
217 
218  std::vector<ActsScalar> unordered = {-2., -1., 0., 1., 2., 3., -3.};
219  auto [range1, medium1] = Acts::range_medium(unordered);
220 
221  CHECK_CLOSE_ABS(range1, 6., std::numeric_limits<ActsScalar>::epsilon());
222  CHECK_CLOSE_ABS(medium1, 0., std::numeric_limits<ActsScalar>::epsilon());
223 }
224 
226  {
227  auto m = Eigen::Matrix3d::Zero().eval();
228  BOOST_CHECK(!Acts::safeInverse(m));
229  }
230 
231  {
232  auto m = Eigen::Matrix3d::Identity().eval();
233  BOOST_CHECK(Acts::safeInverse(m));
234  }
235 }
236 
237 BOOST_AUTO_TEST_CASE(incidentAnglesTest) {
238  RotationMatrix3 ref = RotationMatrix3::Identity();
239 
240  // Right angle in both planes
241  for (size_t i = 0; i < 3; i++) {
242  Vector3 dir = Vector3::Zero();
243  dir[i] = 1;
244  std::pair<double, double> angles = incidentAngles(dir, ref);
245  double expect = (i < 2) ? 0 : M_PI_2;
246  CHECK_CLOSE_ABS(angles.first, expect,
247  std::numeric_limits<ActsScalar>::epsilon());
248  CHECK_CLOSE_ABS(angles.second, expect,
249  std::numeric_limits<ActsScalar>::epsilon());
250  }
251 
252  // 45 degree on both axes
253  {
254  Vector3 dir = Vector3({1, 1, 1}).normalized();
255  auto [a0, a1] = incidentAngles(dir, ref);
256  CHECK_CLOSE_ABS(a0, M_PI_4, std::numeric_limits<ActsScalar>::epsilon());
257  CHECK_CLOSE_ABS(a1, M_PI_4, std::numeric_limits<ActsScalar>::epsilon());
258  }
259 
260  // 45 degree on first axis
261  {
262  Vector3 dir = Vector3({1, 0, 1}).normalized();
263  auto [a0, a1] = incidentAngles(dir, ref);
264  CHECK_CLOSE_ABS(a0, M_PI_4, std::numeric_limits<ActsScalar>::epsilon());
265  CHECK_CLOSE_ABS(a1, M_PI_2, std::numeric_limits<ActsScalar>::epsilon());
266  }
267 
268  // 45 degree on second axis
269  {
270  Vector3 dir = Vector3({0, 1, 1}).normalized();
271  auto [a0, a1] = incidentAngles(dir, ref);
272  CHECK_CLOSE_ABS(a0, M_PI_2, std::numeric_limits<ActsScalar>::epsilon());
273  CHECK_CLOSE_ABS(a1, M_PI_4, std::numeric_limits<ActsScalar>::epsilon());
274  }
275 
276  // Reverse crossing
277  {
278  Vector3 dir = {0, 0, -1};
279  auto [a0, a1] = incidentAngles(dir, ref);
280  CHECK_CLOSE_ABS(a0, -M_PI_2, std::numeric_limits<ActsScalar>::epsilon());
281  CHECK_CLOSE_ABS(a1, -M_PI_2, std::numeric_limits<ActsScalar>::epsilon());
282  }
283 
284  // 45 degree but different quadrant
285  {
286  Vector3 dir = {-1, -1, 1};
287  auto [a0, a1] = incidentAngles(dir, ref);
288  CHECK_CLOSE_ABS(a0, 3 * M_PI_4, std::numeric_limits<ActsScalar>::epsilon());
289  CHECK_CLOSE_ABS(a1, 3 * M_PI_4, std::numeric_limits<ActsScalar>::epsilon());
290  }
291 
292  // 45 degree but different quadrant & other side
293  {
294  Vector3 dir = {-1, -1, -1};
295  auto [a0, a1] = incidentAngles(dir, ref);
296  CHECK_CLOSE_ABS(a0, -3 * M_PI_4,
297  std::numeric_limits<ActsScalar>::epsilon());
298  CHECK_CLOSE_ABS(a1, -3 * M_PI_4,
299  std::numeric_limits<ActsScalar>::epsilon());
300  }
301 
302  // Rotate the reference frame instead
303  {
304  double s45 = std::sin(M_PI_4);
305  double c45 = std::cos(M_PI_4);
306  RotationMatrix3 ref45;
307  ref45 << c45, 0, s45, 0, 1, 0, -s45, 0, c45;
308  Vector3 dir = {0, 0, 1};
309  auto [a0, a1] = incidentAngles(dir, ref45);
310  CHECK_CLOSE_ABS(a0, M_PI_4, std::numeric_limits<ActsScalar>::epsilon());
311  CHECK_CLOSE_ABS(a1, M_PI_2, std::numeric_limits<ActsScalar>::epsilon());
312  }
313 }
314 
315 BOOST_AUTO_TEST_SUITE_END()
316 
317 } // namespace Test
318 } // namespace Acts