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