File indexing completed on 2025-08-06 08:11:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <boost/test/data/test_case.hpp>
0014 #include <boost/test/unit_test.hpp>
0015
0016 #include "Acts/Definitions/Algebra.hpp"
0017 #include "Acts/Definitions/Common.hpp"
0018 #include "Acts/Geometry/GeometryContext.hpp"
0019 #include "Acts/Surfaces/ConeSurface.hpp"
0020 #include "Acts/Surfaces/CylinderSurface.hpp"
0021 #include "Acts/Surfaces/DiscSurface.hpp"
0022 #include "Acts/Surfaces/PerigeeSurface.hpp"
0023 #include "Acts/Surfaces/PlaneSurface.hpp"
0024 #include "Acts/Surfaces/StrawSurface.hpp"
0025 #include "Acts/Surfaces/Surface.hpp"
0026 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0027 #include "Acts/Utilities/Result.hpp"
0028 #include "Acts/Utilities/UnitVectors.hpp"
0029
0030 #include <cmath>
0031 #include <limits>
0032 #include <memory>
0033 #include <ostream>
0034 #include <type_traits>
0035 #include <utility>
0036 #include <vector>
0037
0038 namespace {
0039
0040 namespace bdata = boost::unit_test::data;
0041 using namespace Acts;
0042
0043 constexpr auto eps = 8 * std::numeric_limits<double>::epsilon();
0044 const GeometryContext geoCtx;
0045
0046 void runTest(const Surface& surface, double l0, double l1, double phi,
0047 double theta) {
0048 const Vector3 dir = makeDirectionFromPhiTheta(phi, theta);
0049
0050
0051 Vector3 sentinel = Vector3::Random();
0052 Vector3 pos = surface.localToGlobal(geoCtx, Vector2(l0, l1), dir);
0053 BOOST_CHECK_MESSAGE(pos != sentinel, "Position was not changed");
0054 BOOST_CHECK_MESSAGE(
0055 std::isfinite(pos[0]),
0056 "Position " << pos.transpose() << " contains non-finite entries");
0057 BOOST_CHECK_MESSAGE(
0058 std::isfinite(pos[1]),
0059 "Position " << pos.transpose() << " contains non-finite entries");
0060 BOOST_CHECK_MESSAGE(
0061 std::isfinite(pos[2]),
0062 "Position " << pos.transpose() << " contains non-finite entries");
0063 BOOST_CHECK_MESSAGE(
0064 surface.isOnSurface(geoCtx, pos, dir),
0065 "Position " << pos.transpose() << " is not on the surface");
0066
0067
0068 auto lpResult = surface.globalToLocal(geoCtx, pos, dir);
0069 BOOST_CHECK(lpResult.ok());
0070 CHECK_CLOSE_OR_SMALL(lpResult.value()[ePos0], l0, eps, eps);
0071 CHECK_CLOSE_OR_SMALL(lpResult.value()[ePos1], l1, eps, eps);
0072 }
0073
0074
0075
0076
0077 const auto posAngle = bdata::xrange(-M_PI, M_PI, 0.25);
0078 const auto posPositiveNonzero = bdata::xrange(0.25, 1.0, 0.25);
0079 const auto posPositive = bdata::make(0.0) + posPositiveNonzero;
0080 const auto posSymmetric = bdata::xrange(-1.0, 1.0, 0.25);
0081
0082 const auto phis = bdata::xrange(-M_PI, M_PI, M_PI_4);
0083 const auto thetasNoForwardBackward = bdata::xrange(M_PI_4, M_PI, M_PI_4);
0084 const auto thetas = bdata::make({0.0, M_PI}) + thetasNoForwardBackward;
0085
0086
0087
0088
0089 const auto cones = bdata::make({
0090 Surface::makeShared<ConeSurface>(Transform3::Identity(),
0091 0.5 ),
0092 });
0093 const auto cylinders = bdata::make({
0094 Surface::makeShared<CylinderSurface>(Transform3::Identity(),
0095 10.0 , 100 ),
0096 });
0097 const auto discs = bdata::make({
0098 Surface::makeShared<DiscSurface>(Transform3::Identity(), 0 ,
0099 100 ),
0100 });
0101 const auto perigees = bdata::make({
0102 Surface::makeShared<PerigeeSurface>(Vector3(0, 0, -1.5)),
0103 });
0104 const auto planes = bdata::make({
0105 Surface::makeShared<PlaneSurface>(Vector3(1, 2, 3), Vector3::UnitX()),
0106 Surface::makeShared<PlaneSurface>(Vector3(-2, -3, -4), Vector3::UnitY()),
0107 Surface::makeShared<PlaneSurface>(Vector3(3, -4, 5), Vector3::UnitZ()),
0108 });
0109 const auto straws = bdata::make({
0110 Surface::makeShared<StrawSurface>(Transform3::Identity(), 2.0 ,
0111 200.0 ),
0112 });
0113
0114 }
0115
0116 BOOST_AUTO_TEST_SUITE(SurfaceLocalToGlobalRoundtrip)
0117
0118 BOOST_DATA_TEST_CASE(ConeSurface,
0119 cones* posAngle* posPositiveNonzero* phis* thetas, surface,
0120 lphi, lz, phi, theta) {
0121
0122
0123 const auto r = lz * surface->bounds().tanAlpha();
0124
0125 runTest(*surface, (0 < lz) ? (r * lphi) : 0.0, lz, phi, theta);
0126 }
0127
0128 BOOST_DATA_TEST_CASE(CylinderSurface,
0129 cylinders* posSymmetric* posSymmetric* phis* thetas,
0130 surface, lrphi, lz, phi, theta) {
0131 runTest(*surface, lrphi, lz, phi, theta);
0132 }
0133
0134 BOOST_DATA_TEST_CASE(DiscSurface, discs* posPositive* posAngle* phis* thetas,
0135 surface, lr, lphi, phi, theta) {
0136
0137 runTest(*surface, lr, (0 < lr) ? lphi : 0.0, phi, theta);
0138 }
0139
0140 BOOST_DATA_TEST_CASE(
0141 PerigeeSurface,
0142 perigees* posSymmetric* posSymmetric* phis* thetasNoForwardBackward,
0143 surface, d0, z0, phi, theta) {
0144
0145 runTest(*surface, d0, z0, phi, theta);
0146 }
0147
0148 BOOST_DATA_TEST_CASE(PlaneSurface,
0149 planes* posSymmetric* posSymmetric* phis* thetas, surface,
0150 l0, l1, phi, theta) {
0151 runTest(*surface, l0, l1, phi, theta);
0152 }
0153
0154 BOOST_DATA_TEST_CASE(
0155 StrawSurface,
0156 straws* posSymmetric* posSymmetric* phis* thetasNoForwardBackward, surface,
0157 lr, lz, phi, theta) {
0158
0159 runTest(*surface, lr, lz, phi, theta);
0160 }
0161
0162 BOOST_AUTO_TEST_SUITE_END()