Back to home page

EIC code displayed by LXR

 
 

    


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

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