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