File indexing completed on 2025-10-13 08:19:32
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/Utilities/UnitVectors.hpp"
0013 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0014
0015 #include <algorithm>
0016 #include <cmath>
0017 #include <limits>
0018 #include <numbers>
0019
0020 using Acts::Vector3;
0021 using namespace Acts;
0022
0023 namespace {
0024 constexpr auto eps = std::numeric_limits<double>::epsilon();
0025 }
0026
0027 namespace ActsTests {
0028
0029 BOOST_AUTO_TEST_SUITE(UtilitiesSuite)
0030
0031 BOOST_AUTO_TEST_CASE(DirectionPhiEta) {
0032
0033 const auto xPos1 = makeDirectionFromPhiEta(0.0, 0.0);
0034 CHECK_CLOSE_REL(xPos1.norm(), 1, eps);
0035 CHECK_CLOSE_REL(xPos1.dot(Vector3(1, 0, 0)), 1, eps);
0036 const auto xPos2 = makeDirectionFromPhiEta(2 * std::numbers::pi, 0.);
0037 CHECK_CLOSE_REL(xPos2.norm(), 1, eps);
0038 CHECK_CLOSE_REL(xPos2.dot(Vector3(1, 0, 0)), 1, eps);
0039
0040 const auto xNeg1 = makeDirectionFromPhiEta(std::numbers::pi, 0.);
0041 CHECK_CLOSE_REL(xNeg1.norm(), 1, eps);
0042 CHECK_CLOSE_REL(xNeg1.dot(Vector3(-1, 0, 0)), 1, eps);
0043 const auto xNeg2 = makeDirectionFromPhiEta(-std::numbers::pi, 0.);
0044 CHECK_CLOSE_REL(xNeg2.norm(), 1, eps);
0045 CHECK_CLOSE_REL(xNeg2.dot(Vector3(-1, 0, 0)), 1, eps);
0046
0047 const auto yPos1 = makeDirectionFromPhiEta(std::numbers::pi / 2., 0.);
0048 CHECK_CLOSE_REL(yPos1.norm(), 1, eps);
0049 CHECK_CLOSE_REL(yPos1.dot(Vector3(0, 1, 0)), 1, eps);
0050 const auto yPos2 = makeDirectionFromPhiEta(-3 * std::numbers::pi / 2., 0.);
0051 CHECK_CLOSE_REL(yPos2.norm(), 1, eps);
0052 CHECK_CLOSE_REL(yPos2.dot(Vector3(0, 1, 0)), 1, eps);
0053
0054 const auto yNeg1 = makeDirectionFromPhiEta(-std::numbers::pi / 2., 0.);
0055 CHECK_CLOSE_REL(yNeg1.norm(), 1, eps);
0056 CHECK_CLOSE_REL(yNeg1.dot(Vector3(0, -1, 0)), 1, eps);
0057 const auto yNeg2 = makeDirectionFromPhiEta(3 * std::numbers::pi / 2., 0.);
0058 CHECK_CLOSE_REL(yNeg2.norm(), 1, eps);
0059 CHECK_CLOSE_REL(yNeg2.dot(Vector3(0, -1, 0)), 1, eps);
0060
0061 const auto inf = std::numeric_limits<double>::infinity();
0062
0063 const auto zPos1 = makeDirectionFromPhiEta(0.0, inf);
0064 CHECK_CLOSE_REL(zPos1.norm(), 1, eps);
0065 CHECK_CLOSE_REL(zPos1.dot(Vector3(0, 0, 1)), 1, eps);
0066 const auto zPos2 = makeDirectionFromPhiEta(std::numbers::pi / 2., inf);
0067 CHECK_CLOSE_REL(zPos2.norm(), 1, eps);
0068 CHECK_CLOSE_REL(zPos2.dot(Vector3(0, 0, 1)), 1, eps);
0069
0070 const auto zNeg1 = makeDirectionFromPhiEta(0.0, -inf);
0071 CHECK_CLOSE_REL(zNeg1.norm(), 1, eps);
0072 CHECK_CLOSE_REL(zNeg1.dot(Vector3(0, 0, -1)), 1, eps);
0073 const auto zNeg2 = makeDirectionFromPhiEta(std::numbers::pi / 2., -inf);
0074 CHECK_CLOSE_REL(zNeg2.norm(), 1, eps);
0075 CHECK_CLOSE_REL(zNeg2.dot(Vector3(0, 0, -1)), 1, eps);
0076
0077
0078 const auto mixed1 = makeDirectionFromPhiEta(std::numbers::pi / 4., 1.);
0079 CHECK_CLOSE_REL(mixed1.norm(), 1, eps);
0080 CHECK_CLOSE_REL(
0081 mixed1.dot(
0082 Vector3(1, 1, std::numbers::sqrt2 * std::sinh(1.0)).normalized()),
0083 1, eps);
0084 const auto mixed2 = makeDirectionFromPhiEta(std::numbers::pi / 4., -1.);
0085 CHECK_CLOSE_REL(mixed2.norm(), 1, eps);
0086 CHECK_CLOSE_REL(
0087 mixed2.dot(
0088 Vector3(1, 1, std::numbers::sqrt2 * std::sinh(-1.0)).normalized()),
0089 1, eps);
0090 const auto mixed3 = makeDirectionFromPhiEta(-std::numbers::pi / 4., -1.);
0091 CHECK_CLOSE_REL(mixed3.norm(), 1, eps);
0092 CHECK_CLOSE_REL(
0093 mixed3.dot(
0094 Vector3(1, -1, std::numbers::sqrt2 * std::sinh(-1.)).normalized()),
0095 1, eps);
0096 }
0097
0098 BOOST_AUTO_TEST_CASE(DirectionPhiTheta) {
0099
0100 const auto xPos1 = makeDirectionFromPhiTheta(0., std::numbers::pi / 2.);
0101 CHECK_CLOSE_REL(xPos1.norm(), 1, eps);
0102 CHECK_CLOSE_REL(xPos1.dot(Vector3(1, 0, 0)), 1, eps);
0103 const auto xPos2 =
0104 makeDirectionFromPhiTheta(2 * std::numbers::pi, std::numbers::pi / 2.);
0105 CHECK_CLOSE_REL(xPos2.norm(), 1, eps);
0106 CHECK_CLOSE_REL(xPos2.dot(Vector3(1, 0, 0)), 1, eps);
0107
0108 const auto xNeg1 =
0109 makeDirectionFromPhiTheta(std::numbers::pi, std::numbers::pi / 2.);
0110 CHECK_CLOSE_REL(xNeg1.norm(), 1, eps);
0111 CHECK_CLOSE_REL(xNeg1.dot(Vector3(-1, 0, 0)), 1, eps);
0112 const auto xNeg2 =
0113 makeDirectionFromPhiTheta(-std::numbers::pi, std::numbers::pi / 2.);
0114 CHECK_CLOSE_REL(xNeg2.norm(), 1, eps);
0115 CHECK_CLOSE_REL(xNeg2.dot(Vector3(-1, 0, 0)), 1, eps);
0116
0117 const auto yPos1 =
0118 makeDirectionFromPhiTheta(std::numbers::pi / 2., std::numbers::pi / 2.);
0119 CHECK_CLOSE_REL(yPos1.norm(), 1, eps);
0120 CHECK_CLOSE_REL(yPos1.dot(Vector3(0, 1, 0)), 1, eps);
0121 const auto yPos2 = makeDirectionFromPhiTheta(-3 * std::numbers::pi / 2.,
0122 std::numbers::pi / 2.);
0123 CHECK_CLOSE_REL(yPos2.norm(), 1, eps);
0124 CHECK_CLOSE_REL(yPos2.dot(Vector3(0, 1, 0)), 1, eps);
0125
0126 const auto yNeg1 =
0127 makeDirectionFromPhiTheta(-std::numbers::pi / 2., std::numbers::pi / 2.);
0128 CHECK_CLOSE_REL(yNeg1.norm(), 1, eps);
0129 CHECK_CLOSE_REL(yNeg1.dot(Vector3(0, -1, 0)), 1, eps);
0130 const auto yNeg2 = makeDirectionFromPhiTheta(3 * std::numbers::pi / 2.,
0131 std::numbers::pi / 2.);
0132 CHECK_CLOSE_REL(yNeg2.norm(), 1, eps);
0133 CHECK_CLOSE_REL(yNeg2.dot(Vector3(0, -1, 0)), 1, eps);
0134
0135
0136 const auto zPos1 = makeDirectionFromPhiTheta(0.0, 0.0);
0137 CHECK_CLOSE_REL(zPos1.norm(), 1, eps);
0138 CHECK_CLOSE_REL(zPos1.dot(Vector3(0, 0, 1)), 1, eps);
0139 const auto zPos2 = makeDirectionFromPhiTheta(std::numbers::pi / 2., 0.);
0140 CHECK_CLOSE_REL(zPos2.norm(), 1, eps);
0141 CHECK_CLOSE_REL(zPos2.dot(Vector3(0, 0, 1)), 1, eps);
0142
0143 const auto zNeg1 = makeDirectionFromPhiTheta(0., std::numbers::pi);
0144 CHECK_CLOSE_REL(zNeg1.norm(), 1, eps);
0145 CHECK_CLOSE_REL(zNeg1.dot(Vector3(0, 0, -1)), 1, eps);
0146 const auto zNeg2 =
0147 makeDirectionFromPhiTheta(std::numbers::pi / 2., std::numbers::pi);
0148 CHECK_CLOSE_REL(zNeg2.norm(), 1, eps);
0149 CHECK_CLOSE_REL(zNeg2.dot(Vector3(0, 0, -1)), 1, eps);
0150
0151
0152 const auto mixed1 =
0153 makeDirectionFromPhiTheta(std::numbers::pi / 4., std::numbers::pi / 4.);
0154 CHECK_CLOSE_REL(mixed1.norm(), 1, eps);
0155 CHECK_CLOSE_REL(mixed1.dot(Vector3(1, 1, std::numbers::sqrt2).normalized()),
0156 1, eps);
0157 const auto mixed2 = makeDirectionFromPhiTheta(std::numbers::pi / 4.,
0158 3 * std::numbers::pi / 4.);
0159 CHECK_CLOSE_REL(mixed2.norm(), 1, eps);
0160 CHECK_CLOSE_REL(mixed2.dot(Vector3(1, 1, -std::numbers::sqrt2).normalized()),
0161 1, eps);
0162 const auto mixed3 = makeDirectionFromPhiTheta(-std::numbers::pi / 4.,
0163 3 * std::numbers::pi / 4.);
0164 CHECK_CLOSE_REL(mixed3.norm(), 1, eps);
0165 CHECK_CLOSE_REL(mixed3.dot(Vector3(1, -1, -std::numbers::sqrt2).normalized()),
0166 1, eps);
0167 }
0168
0169 namespace {
0170 template <typename Direction, typename RefUnitU, typename RefUnitV>
0171 void testCurvilinear(const Eigen::MatrixBase<Direction>& direction,
0172 const Eigen::MatrixBase<RefUnitU>& refU,
0173 const Eigen::MatrixBase<RefUnitV>& refV) {
0174 const auto u = createCurvilinearUnitU(direction);
0175 const auto uv = createCurvilinearUnitVectors(direction);
0176
0177 CHECK_CLOSE_ABS(u.norm(), 1, eps);
0178 CHECK_CLOSE_ABS(uv.first.norm(), 1, eps);
0179 CHECK_CLOSE_ABS(uv.second.norm(), 1, eps);
0180
0181 CHECK_SMALL(u.dot(direction), eps);
0182 CHECK_SMALL(uv.first.dot(direction), eps);
0183 CHECK_SMALL(uv.second.dot(direction), eps);
0184 CHECK_SMALL(uv.first.dot(uv.second), eps);
0185
0186 CHECK_SMALL(u[2], eps);
0187 CHECK_SMALL(uv.first[2], eps);
0188
0189
0190 CHECK_CLOSE_ABS(u.dot(refU), 1, eps);
0191 CHECK_CLOSE_ABS(uv.first.dot(refU), 1, eps);
0192 CHECK_CLOSE_ABS(uv.second.dot(refV), 1, eps);
0193 }
0194 }
0195
0196 BOOST_AUTO_TEST_CASE(CurvilinearTransverse) {
0197
0198 testCurvilinear(Vector3(1, 1, 0), Vector3(-1, 1, 0).normalized(),
0199 Vector3(0, 0, 1).normalized());
0200 }
0201
0202 BOOST_AUTO_TEST_CASE(CurvilinearPositiveZ) {
0203
0204 testCurvilinear(Vector3(0, 0, 1), Vector3(1, 0, 0), Vector3(0, 1, 0));
0205 }
0206
0207 BOOST_AUTO_TEST_CASE(CurvilinearNegativeZ) {
0208
0209 testCurvilinear(Vector3(0, 0, -1), Vector3(1, 0, 0), Vector3(0, -1, 0));
0210 }
0211
0212 BOOST_AUTO_TEST_CASE(CurvilinearCloseToZ) {
0213
0214 testCurvilinear(Vector3(0, 32 * eps, 1 - 32 * eps), Vector3(-1, 0, 0),
0215 Vector3(0, -1, 32 * eps));
0216 }
0217
0218 BOOST_AUTO_TEST_SUITE_END()
0219
0220 }