Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:11:34

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2019 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #include <boost/test/unit_test.hpp>
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Common.hpp"
0013 #include "Acts/Definitions/TrackParametrization.hpp"
0014 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0015 #include "Acts/Utilities/AlgebraHelpers.hpp"
0016 #include "Acts/Utilities/Helpers.hpp"
0017 #include "Acts/Utilities/StringHelpers.hpp"
0018 #include "Acts/Utilities/VectorHelpers.hpp"
0019 
0020 #include <algorithm>
0021 #include <bitset>
0022 #include <cmath>
0023 #include <cstddef>
0024 #include <limits>
0025 #include <memory>
0026 #include <string>
0027 #include <tuple>
0028 #include <utility>
0029 #include <vector>
0030 
0031 using namespace Acts::VectorHelpers;
0032 
0033 namespace Acts {
0034 namespace Test {
0035 
0036 BOOST_AUTO_TEST_SUITE(Utilities)
0037 
0038 BOOST_AUTO_TEST_CASE(bitset_to_matrix_to_bitset) {
0039   Eigen::Matrix<int, 4, 3> mat;
0040   mat << 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0;
0041 
0042   std::bitset<4 * 3> act = matrixToBitset(mat);
0043   std::bitset<4 * 3> exp{"101001011010"};
0044 
0045   BOOST_CHECK_EQUAL(exp, act);
0046 
0047   Eigen::Matrix<int, 4, 3> cnv;
0048   cnv = bitsetToMatrix<decltype(cnv)>(act);
0049 
0050   BOOST_CHECK_EQUAL(mat, cnv);
0051 }
0052 
0053 struct MyStruct {
0054   double phi() const { return 42; }
0055 };
0056 
0057 BOOST_AUTO_TEST_CASE(phi_helper_test) {
0058   Vector3 v(0, 1, 0);
0059   CHECK_CLOSE_ABS(phi(v), M_PI / 2., 1e-9);
0060 
0061   MyStruct s;
0062   BOOST_CHECK_EQUAL(phi(s), 42u);
0063 }
0064 
0065 BOOST_AUTO_TEST_CASE(perp_helper_test) {
0066   Vector3 v(1, 2, 3);
0067   CHECK_CLOSE_ABS(perp(v), std::sqrt(1 + 2 * 2), 1e-9);
0068 }
0069 
0070 BOOST_AUTO_TEST_CASE(theta_eta_test_helper) {
0071   Vector3 v(1, 2, 3);
0072   CHECK_CLOSE_ABS(theta(v), 0.640522, 1e-5);
0073   CHECK_CLOSE_ABS(eta(v), 1.10359, 1e-5);
0074 }
0075 
0076 BOOST_AUTO_TEST_CASE(cross_test_helper) {
0077   {
0078     Vector3 v(1, 2, 3);
0079     ActsMatrix<3, 3> mat;
0080     mat << 1, 2, 3, 4, 5, 6, 7, 8, 9;
0081 
0082     ActsMatrix<3, 3> act = cross(mat, v);
0083     ActsMatrix<3, 3> exp;
0084     exp << -2, -1, 0, 4, 2, 0, -2, -1, 0;
0085 
0086     CHECK_CLOSE_ABS(act, exp, 1e-9);
0087   }
0088 }
0089 
0090 BOOST_AUTO_TEST_CASE(toString_test_helper) {
0091   ActsMatrix<3, 3> mat;
0092   mat << 1, 2, 3, 4, 5, 6, 7, 8, 9;
0093   std::string out;
0094   out = toString(mat);
0095   BOOST_CHECK(!out.empty());
0096 
0097   Translation3 trl{Vector3{1, 2, 3}};
0098   out = toString(trl);
0099   BOOST_CHECK(!out.empty());
0100 
0101   Transform3 trf;
0102   trf = trl;
0103   out = toString(trf);
0104   BOOST_CHECK(!out.empty());
0105 }
0106 
0107 BOOST_AUTO_TEST_CASE(shared_vector_helper_test) {
0108   {
0109     std::vector<std::shared_ptr<int>> vec;
0110     vec = {std::make_shared<int>(5), std::make_shared<int>(9),
0111            std::make_shared<int>(26), std::make_shared<int>(18473)};
0112 
0113     std::vector<int*> unpacked = unpack_shared_vector(vec);
0114 
0115     std::vector<int*> exp = {
0116         vec[0].get(),
0117         vec[1].get(),
0118         vec[2].get(),
0119         vec[3].get(),
0120     };
0121 
0122     BOOST_CHECK_EQUAL_COLLECTIONS(unpacked.begin(), unpacked.end(), exp.begin(),
0123                                   exp.end());
0124   }
0125 
0126   // same for const
0127   {
0128     std::vector<std::shared_ptr<const int>> vec;
0129     vec = {std::make_shared<const int>(5), std::make_shared<const int>(9),
0130            std::make_shared<const int>(26), std::make_shared<const int>(18473)};
0131 
0132     std::vector<const int*> unpacked = unpack_shared_vector(vec);
0133 
0134     std::vector<const int*> exp = {
0135         vec[0].get(),
0136         vec[1].get(),
0137         vec[2].get(),
0138         vec[3].get(),
0139     };
0140 
0141     BOOST_CHECK_EQUAL_COLLECTIONS(unpacked.begin(), unpacked.end(), exp.begin(),
0142                                   exp.end());
0143   }
0144 }
0145 
0146 BOOST_AUTO_TEST_CASE(VectorHelpersPosition) {
0147   Vector4 pos4 = Vector4::Constant(-1);
0148   pos4[ePos0] = 1;
0149   pos4[ePos1] = 2;
0150   pos4[ePos2] = 3;
0151   BOOST_CHECK_EQUAL(position(pos4), Vector3(1, 2, 3));
0152 
0153   FreeVector params = FreeVector::Constant(-1);
0154   params[eFreePos0] = 1;
0155   params[eFreePos1] = 2;
0156   params[eFreePos2] = 3;
0157   BOOST_CHECK_EQUAL(position(params), Vector3(1, 2, 3));
0158 }
0159 
0160 template <std::size_t I>
0161 struct functor {
0162   static constexpr std::size_t invoke() { return I * I * I; }
0163 };
0164 
0165 BOOST_AUTO_TEST_CASE(test_matrix_dimension_switch) {
0166   constexpr std::size_t imax = 20;
0167   for (std::size_t i = 0; i < imax; i++) {
0168     std::size_t val = template_switch<functor, 0, imax>(i);
0169     BOOST_CHECK_EQUAL(val, i * i * i);
0170   }
0171 }
0172 
0173 using MatrixProductTypes =
0174     std::tuple<std::pair<ActsMatrix<3, 3>, ActsMatrix<3, 3>>,
0175                std::pair<ActsMatrix<4, 4>, ActsMatrix<4, 4>>,
0176                std::pair<ActsMatrix<8, 8>, ActsMatrix<8, 8>>,
0177                std::pair<ActsMatrix<8, 7>, ActsMatrix<7, 4>>>;
0178 
0179 BOOST_AUTO_TEST_CASE_TEMPLATE(BlockedMatrixMultiplication, Matrices,
0180                               MatrixProductTypes) {
0181   using A = typename Matrices::first_type;
0182   using B = typename Matrices::second_type;
0183   using C = ActsMatrix<A::RowsAtCompileTime, B::ColsAtCompileTime>;
0184 
0185   for (std::size_t i = 0; i < 100; ++i) {
0186     A a = A::Random();
0187     B b = B::Random();
0188 
0189     C ref = a * b;
0190     C res = blockedMult(a, b);
0191 
0192     BOOST_CHECK(ref.isApprox(res));
0193     BOOST_CHECK(res.isApprox(ref));
0194   }
0195 }
0196 
0197 BOOST_AUTO_TEST_CASE(min_max) {
0198   std::vector<ActsScalar> ordered = {-3., -2., -1., 0., 1., 2., 3.};
0199   auto [min0, max0] = Acts::min_max(ordered);
0200 
0201   CHECK_CLOSE_ABS(min0, -3., std::numeric_limits<ActsScalar>::epsilon());
0202   CHECK_CLOSE_ABS(max0, 3., std::numeric_limits<ActsScalar>::epsilon());
0203 
0204   std::vector<ActsScalar> unordered = {3., -3., -2., -1., 0., 1., 2.};
0205   auto [min1, max1] = Acts::min_max(unordered);
0206 
0207   CHECK_CLOSE_ABS(min1, -3., std::numeric_limits<ActsScalar>::epsilon());
0208   CHECK_CLOSE_ABS(max1, 3., std::numeric_limits<ActsScalar>::epsilon());
0209 }
0210 
0211 BOOST_AUTO_TEST_CASE(range_medium) {
0212   std::vector<ActsScalar> ordered = {-3., -2., -1., 0., 1., 2., 3.};
0213   auto [range0, medium0] = Acts::range_medium(ordered);
0214 
0215   CHECK_CLOSE_ABS(range0, 6., std::numeric_limits<ActsScalar>::epsilon());
0216   CHECK_CLOSE_ABS(medium0, 0., std::numeric_limits<ActsScalar>::epsilon());
0217 
0218   std::vector<ActsScalar> unordered = {-2., -1., 0., 1., 2., 3., -3.};
0219   auto [range1, medium1] = Acts::range_medium(unordered);
0220 
0221   CHECK_CLOSE_ABS(range1, 6., std::numeric_limits<ActsScalar>::epsilon());
0222   CHECK_CLOSE_ABS(medium1, 0., std::numeric_limits<ActsScalar>::epsilon());
0223 }
0224 
0225 BOOST_AUTO_TEST_CASE(safeInverse) {
0226   {
0227     auto m = Eigen::Matrix3d::Zero().eval();
0228     BOOST_CHECK(!Acts::safeInverse(m));
0229   }
0230 
0231   {
0232     auto m = Eigen::Matrix3d::Identity().eval();
0233     BOOST_CHECK(Acts::safeInverse(m));
0234   }
0235 }
0236 
0237 BOOST_AUTO_TEST_CASE(incidentAnglesTest) {
0238   RotationMatrix3 ref = RotationMatrix3::Identity();
0239 
0240   // Right angle in both planes
0241   for (std::size_t i = 0; i < 3; i++) {
0242     Vector3 dir = Vector3::Zero();
0243     dir[i] = 1;
0244     std::pair<double, double> angles = incidentAngles(dir, ref);
0245     double expect = (i < 2) ? 0 : M_PI_2;
0246     CHECK_CLOSE_ABS(angles.first, expect,
0247                     std::numeric_limits<ActsScalar>::epsilon());
0248     CHECK_CLOSE_ABS(angles.second, expect,
0249                     std::numeric_limits<ActsScalar>::epsilon());
0250   }
0251 
0252   // 45 degree on both axes
0253   {
0254     Vector3 dir = Vector3({1, 1, 1}).normalized();
0255     auto [a0, a1] = incidentAngles(dir, ref);
0256     CHECK_CLOSE_ABS(a0, M_PI_4, std::numeric_limits<ActsScalar>::epsilon());
0257     CHECK_CLOSE_ABS(a1, M_PI_4, std::numeric_limits<ActsScalar>::epsilon());
0258   }
0259 
0260   // 45 degree on first axis
0261   {
0262     Vector3 dir = Vector3({1, 0, 1}).normalized();
0263     auto [a0, a1] = incidentAngles(dir, ref);
0264     CHECK_CLOSE_ABS(a0, M_PI_4, std::numeric_limits<ActsScalar>::epsilon());
0265     CHECK_CLOSE_ABS(a1, M_PI_2, std::numeric_limits<ActsScalar>::epsilon());
0266   }
0267 
0268   // 45 degree on second axis
0269   {
0270     Vector3 dir = Vector3({0, 1, 1}).normalized();
0271     auto [a0, a1] = incidentAngles(dir, ref);
0272     CHECK_CLOSE_ABS(a0, M_PI_2, std::numeric_limits<ActsScalar>::epsilon());
0273     CHECK_CLOSE_ABS(a1, M_PI_4, std::numeric_limits<ActsScalar>::epsilon());
0274   }
0275 
0276   // Reverse crossing
0277   {
0278     Vector3 dir = {0, 0, -1};
0279     auto [a0, a1] = incidentAngles(dir, ref);
0280     CHECK_CLOSE_ABS(a0, -M_PI_2, std::numeric_limits<ActsScalar>::epsilon());
0281     CHECK_CLOSE_ABS(a1, -M_PI_2, std::numeric_limits<ActsScalar>::epsilon());
0282   }
0283 
0284   // 45 degree but different quadrant
0285   {
0286     Vector3 dir = {-1, -1, 1};
0287     auto [a0, a1] = incidentAngles(dir, ref);
0288     CHECK_CLOSE_ABS(a0, 3 * M_PI_4, std::numeric_limits<ActsScalar>::epsilon());
0289     CHECK_CLOSE_ABS(a1, 3 * M_PI_4, std::numeric_limits<ActsScalar>::epsilon());
0290   }
0291 
0292   // 45 degree but different quadrant & other side
0293   {
0294     Vector3 dir = {-1, -1, -1};
0295     auto [a0, a1] = incidentAngles(dir, ref);
0296     CHECK_CLOSE_ABS(a0, -3 * M_PI_4,
0297                     std::numeric_limits<ActsScalar>::epsilon());
0298     CHECK_CLOSE_ABS(a1, -3 * M_PI_4,
0299                     std::numeric_limits<ActsScalar>::epsilon());
0300   }
0301 
0302   // Rotate the reference frame instead
0303   {
0304     double s45 = std::sin(M_PI_4);
0305     double c45 = std::cos(M_PI_4);
0306     RotationMatrix3 ref45;
0307     ref45 << c45, 0, s45, 0, 1, 0, -s45, 0, c45;
0308     Vector3 dir = {0, 0, 1};
0309     auto [a0, a1] = incidentAngles(dir, ref45);
0310     CHECK_CLOSE_ABS(a0, M_PI_4, std::numeric_limits<ActsScalar>::epsilon());
0311     CHECK_CLOSE_ABS(a1, M_PI_2, std::numeric_limits<ActsScalar>::epsilon());
0312   }
0313 }
0314 
0315 BOOST_AUTO_TEST_SUITE_END()
0316 
0317 }  // namespace Test
0318 }  // namespace Acts