File indexing completed on 2025-07-14 08:12:02
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/Definitions/Units.hpp"
0015 #include "Acts/EventData/TrackParameters.hpp"
0016 #include "Acts/Geometry/GeometryContext.hpp"
0017 #include "Acts/Surfaces/PlaneSurface.hpp"
0018 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0019 #include "Acts/Utilities/UnitVectors.hpp"
0020 #include "Acts/Utilities/detail/periodic.hpp"
0021
0022 #include <cmath>
0023 #include <limits>
0024 #include <numbers>
0025
0026 #include "TrackParametersDatasets.hpp"
0027
0028 namespace {
0029
0030 using namespace Acts;
0031 using namespace Acts::UnitLiterals;
0032
0033 constexpr auto eps = 8 * std::numeric_limits<double>::epsilon();
0034 const GeometryContext geoCtx;
0035 const BoundSquareMatrix cov = BoundSquareMatrix::Identity();
0036
0037 void checkParameters(const BoundTrackParameters& params, double phi,
0038 double theta, double p, double q, const Vector4& pos4,
0039 const Vector3& unitDir) {
0040 const auto qOverP = (q != 0) ? (q / p) : (1 / p);
0041 const auto pos = pos4.segment<3>(ePos0);
0042
0043 const auto* referenceSurface =
0044 dynamic_cast<const PlaneSurface*>(¶ms.referenceSurface());
0045 BOOST_REQUIRE_MESSAGE(referenceSurface != nullptr,
0046 "Reference surface is not a plane");
0047
0048
0049 CHECK_SMALL(params.template get<eBoundLoc0>(), eps);
0050 CHECK_SMALL(params.template get<eBoundLoc1>(), eps);
0051 CHECK_CLOSE_OR_SMALL(params.template get<eBoundTime>(), pos4[eTime], eps,
0052 eps);
0053 CHECK_CLOSE_OR_SMALL(detail::radian_sym(params.template get<eBoundPhi>()),
0054 detail::radian_sym(phi), eps, eps);
0055 CHECK_CLOSE_OR_SMALL(params.template get<eBoundTheta>(), theta, eps, eps);
0056 CHECK_CLOSE_OR_SMALL(params.template get<eBoundQOverP>(), qOverP, eps, eps);
0057
0058 CHECK_CLOSE_OR_SMALL(params.fourPosition(geoCtx), pos4, eps, eps);
0059 CHECK_CLOSE_OR_SMALL(params.position(geoCtx), pos, eps, eps);
0060 CHECK_CLOSE_OR_SMALL(params.time(), pos4[eTime], eps, eps);
0061 CHECK_CLOSE_OR_SMALL(params.direction(), unitDir, eps, eps);
0062 CHECK_CLOSE_OR_SMALL(params.absoluteMomentum(), p, eps, eps);
0063 CHECK_CLOSE_OR_SMALL(params.transverseMomentum(), p * std::sin(theta), eps,
0064 eps);
0065 CHECK_CLOSE_OR_SMALL(params.momentum(), p * unitDir, eps, eps);
0066 BOOST_CHECK_EQUAL(params.charge(), q);
0067
0068 CHECK_CLOSE_OR_SMALL(referenceSurface->center(geoCtx), pos, eps, eps);
0069 CHECK_CLOSE_OR_SMALL(referenceSurface->normal(geoCtx), unitDir, eps, eps);
0070
0071
0072 BoundTrackParameters reflectedParams = params;
0073 reflectedParams.reflectInPlace();
0074 CHECK_CLOSE_OR_SMALL(params.reflect().parameters(),
0075 reflectedParams.parameters(), eps, eps);
0076 CHECK_CLOSE_OR_SMALL(reflectedParams.reflect().parameters(),
0077 params.parameters(), eps, eps);
0078
0079
0080 }
0081
0082 }
0083
0084 BOOST_AUTO_TEST_SUITE(EventDataCurvilinearTrackParameters)
0085
0086 BOOST_DATA_TEST_CASE(
0087 NeutralConstruct,
0088 posSymmetric* posSymmetric* posSymmetric* ts* phis* thetas* ps, x, y, z,
0089 time, phiInput, theta, p) {
0090
0091 const auto phi = ((0 < theta) && (theta < std::numbers::pi)) ? phiInput : 0.;
0092 const Vector4 pos4(x, y, z, time);
0093 const Vector3 dir = makeDirectionFromPhiTheta(phi, theta);
0094
0095 BoundTrackParameters params = BoundTrackParameters::createCurvilinear(
0096 pos4, dir, 1 / p, std::nullopt, ParticleHypothesis::pion0());
0097 checkParameters(params, phi, theta, p, 0_e, pos4, dir);
0098 BOOST_CHECK(!params.covariance());
0099
0100
0101 params = BoundTrackParameters::createCurvilinear(pos4, dir, 1 / p, cov,
0102 ParticleHypothesis::pion0());
0103 BOOST_CHECK(params.covariance());
0104 BOOST_CHECK_EQUAL(params.covariance().value(), cov);
0105 }
0106
0107 BOOST_DATA_TEST_CASE(
0108 ChargedConstruct,
0109 posSymmetric* posSymmetric* posSymmetric* ts* phis* thetas* ps* qsNonZero,
0110 x, y, z, time, phiInput, theta, p, q) {
0111
0112 const auto phi = ((0 < theta) && (theta < std::numbers::pi)) ? phiInput : 0.;
0113 const Vector4 pos4(x, y, z, time);
0114 const Vector3 dir = makeDirectionFromPhiTheta(phi, theta);
0115
0116 BoundTrackParameters params = BoundTrackParameters::createCurvilinear(
0117 pos4, dir, q / p, std::nullopt,
0118 ParticleHypothesis::pionLike(std::abs(q)));
0119 checkParameters(params, phi, theta, p, q, pos4, dir);
0120 BOOST_CHECK(!params.covariance());
0121
0122
0123 params = BoundTrackParameters::createCurvilinear(
0124 pos4, dir, q / p, cov, ParticleHypothesis::pionLike(std::abs(q)));
0125 BOOST_CHECK(params.covariance());
0126 BOOST_CHECK_EQUAL(params.covariance().value(), cov);
0127 }
0128
0129 BOOST_DATA_TEST_CASE(
0130 AnyConstruct,
0131 posSymmetric* posSymmetric* posSymmetric* ts* phis* thetas* ps* qsAny, x, y,
0132 z, time, phiInput, theta, p, q) {
0133
0134 const auto phi = ((0 < theta) && (theta < std::numbers::pi)) ? phiInput : 0.;
0135 const Vector4 pos4(x, y, z, time);
0136 const Vector3 dir = makeDirectionFromPhiTheta(phi, theta);
0137
0138 auto particleHypothesis = ParticleHypothesis::pionLike(std::abs(q));
0139 auto qOverP = particleHypothesis.qOverP(p, q);
0140
0141 BoundTrackParameters params = BoundTrackParameters::createCurvilinear(
0142 pos4, dir, qOverP, std::nullopt, particleHypothesis);
0143 checkParameters(params, phi, theta, p, q, pos4, dir);
0144 BOOST_CHECK(!params.covariance());
0145
0146
0147 params = BoundTrackParameters::createCurvilinear(pos4, dir, qOverP, cov,
0148 particleHypothesis);
0149 BOOST_CHECK(params.covariance());
0150 BOOST_CHECK_EQUAL(params.covariance().value(), cov);
0151 }
0152
0153 BOOST_AUTO_TEST_SUITE_END()