File indexing completed on 2025-07-01 07:53:50
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/data/test_case.hpp>
0010 #include <boost/test/unit_test.hpp>
0011
0012 #include "Acts/Definitions/Algebra.hpp"
0013 #include "Acts/Definitions/Common.hpp"
0014 #include "Acts/Definitions/TrackParametrization.hpp"
0015 #include "Acts/Definitions/Units.hpp"
0016 #include "Acts/EventData/GenericBoundTrackParameters.hpp"
0017 #include "Acts/EventData/ParticleHypothesis.hpp"
0018 #include "Acts/EventData/TrackParameters.hpp"
0019 #include "Acts/Geometry/GeometryContext.hpp"
0020 #include "Acts/Surfaces/ConeSurface.hpp"
0021 #include "Acts/Surfaces/CylinderSurface.hpp"
0022 #include "Acts/Surfaces/DiscSurface.hpp"
0023 #include "Acts/Surfaces/PerigeeSurface.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 #include "Acts/Utilities/detail/periodic.hpp"
0030
0031 #include <cmath>
0032 #include <limits>
0033 #include <memory>
0034 #include <numbers>
0035 #include <optional>
0036
0037 #include "TrackParametersDatasets.hpp"
0038
0039 namespace {
0040
0041 namespace bdata = boost::unit_test::data;
0042 using namespace Acts;
0043 using namespace Acts::UnitLiterals;
0044
0045 constexpr auto eps = 8 * std::numeric_limits<double>::epsilon();
0046 const GeometryContext geoCtx;
0047 const BoundSquareMatrix cov = BoundSquareMatrix::Identity();
0048
0049 void checkParameters(const BoundTrackParameters& params, double l0, double l1,
0050 double time, double phi, double theta, double p, double q,
0051 const Vector3& pos, const Vector3& unitDir) {
0052 const auto particleHypothesis = ParticleHypothesis::pionLike(std::abs(q));
0053
0054 const auto qOverP = particleHypothesis.qOverP(p, q);
0055 const auto pos4 = VectorHelpers::makeVector4(pos, time);
0056
0057
0058 CHECK_CLOSE_OR_SMALL(params.template get<eBoundLoc0>(), l0, eps, eps);
0059 CHECK_CLOSE_OR_SMALL(params.template get<eBoundLoc1>(), l1, eps, eps);
0060 CHECK_CLOSE_OR_SMALL(params.template get<eBoundTime>(), time, eps, eps);
0061 CHECK_CLOSE_OR_SMALL(detail::radian_sym(params.template get<eBoundPhi>()),
0062 detail::radian_sym(phi), eps, eps);
0063 CHECK_CLOSE_OR_SMALL(params.template get<eBoundTheta>(), theta, eps, eps);
0064 CHECK_CLOSE_OR_SMALL(params.template get<eBoundQOverP>(), qOverP, eps, eps);
0065
0066 CHECK_CLOSE_OR_SMALL(params.fourPosition(geoCtx), pos4, eps, eps);
0067 CHECK_CLOSE_OR_SMALL(params.position(geoCtx), pos, eps, eps);
0068 CHECK_CLOSE_OR_SMALL(params.time(), time, eps, eps);
0069 CHECK_CLOSE_OR_SMALL(params.direction(), unitDir, eps, eps);
0070 CHECK_CLOSE_OR_SMALL(params.absoluteMomentum(), p, eps, eps);
0071 CHECK_CLOSE_OR_SMALL(params.transverseMomentum(), p * std::sin(theta), eps,
0072 eps);
0073 CHECK_CLOSE_OR_SMALL(params.momentum(), p * unitDir, eps, eps);
0074 BOOST_CHECK_EQUAL(params.charge(), q);
0075
0076
0077 BoundTrackParameters reflectedParams = params;
0078 reflectedParams.reflectInPlace();
0079 CHECK_CLOSE_OR_SMALL(params.reflect().parameters(),
0080 reflectedParams.parameters(), eps, eps);
0081 CHECK_CLOSE_OR_SMALL(reflectedParams.reflect().parameters(),
0082 params.parameters(), eps, eps);
0083 }
0084
0085 void runTest(const std::shared_ptr<const Surface>& surface, double l0,
0086 double l1, double time, double phi, double theta, double p) {
0087
0088 phi = ((0 < theta) && (theta < std::numbers::pi)) ? phi : 0.;
0089
0090
0091 const Vector3 dir = makeDirectionFromPhiTheta(phi, theta);
0092
0093 const Vector2 loc(l0, l1);
0094 const Vector3 pos = surface->localToGlobal(geoCtx, loc, dir);
0095
0096 Vector4 pos4;
0097 pos4.segment<3>(ePos0) = pos;
0098 pos4[eTime] = time;
0099
0100
0101 {
0102 BoundVector vector = BoundVector::Zero();
0103 vector[eBoundLoc0] = l0;
0104 vector[eBoundLoc1] = l1;
0105 vector[eBoundTime] = time;
0106 vector[eBoundPhi] = phi;
0107 vector[eBoundTheta] = theta;
0108 vector[eBoundQOverP] = 1 / p;
0109 BoundTrackParameters params(surface, vector, std::nullopt,
0110 ParticleHypothesis::pion0());
0111 checkParameters(params, l0, l1, time, phi, theta, p, 0_e, pos, dir);
0112 BOOST_CHECK(!params.covariance());
0113
0114
0115 params =
0116 BoundTrackParameters(surface, vector, cov, ParticleHypothesis::pion0());
0117 checkParameters(params, l0, l1, time, phi, theta, p, 0_e, pos, dir);
0118 BOOST_CHECK(params.covariance());
0119 BOOST_CHECK_EQUAL(params.covariance().value(), cov);
0120 }
0121
0122 {
0123 BoundVector vector = BoundVector::Zero();
0124 vector[eBoundLoc0] = l0;
0125 vector[eBoundLoc1] = l1;
0126 vector[eBoundTime] = time;
0127 vector[eBoundPhi] = phi;
0128 vector[eBoundTheta] = theta;
0129 vector[eBoundQOverP] = -1_e / p;
0130 BoundTrackParameters params(surface, vector, std::nullopt,
0131 ParticleHypothesis::pion());
0132 checkParameters(params, l0, l1, time, phi, theta, p, -1_e, pos, dir);
0133 BOOST_CHECK(!params.covariance());
0134
0135
0136 params =
0137 BoundTrackParameters(surface, vector, cov, ParticleHypothesis::pion());
0138 checkParameters(params, l0, l1, time, phi, theta, p, -1_e, pos, dir);
0139 BOOST_CHECK(params.covariance());
0140 BOOST_CHECK_EQUAL(params.covariance().value(), cov);
0141 }
0142
0143 {
0144 BoundVector vector = BoundVector::Zero();
0145 vector[eBoundLoc0] = l0;
0146 vector[eBoundLoc1] = l1;
0147 vector[eBoundTime] = time;
0148 vector[eBoundPhi] = phi;
0149 vector[eBoundTheta] = theta;
0150 vector[eBoundQOverP] = 1_e / p;
0151 BoundTrackParameters params(surface, vector, std::nullopt,
0152 ParticleHypothesis::pion());
0153 checkParameters(params, l0, l1, time, phi, theta, p, 1_e, pos, dir);
0154 BOOST_CHECK(!params.covariance());
0155
0156
0157 params =
0158 BoundTrackParameters(surface, vector, cov, ParticleHypothesis::pion());
0159 checkParameters(params, l0, l1, time, phi, theta, p, 1_e, pos, dir);
0160 BOOST_CHECK(params.covariance());
0161 BOOST_CHECK_EQUAL(params.covariance().value(), cov);
0162 }
0163
0164 {
0165 BoundVector vector = BoundVector::Zero();
0166 vector[eBoundLoc0] = l0;
0167 vector[eBoundLoc1] = l1;
0168 vector[eBoundTime] = time;
0169 vector[eBoundPhi] = phi;
0170 vector[eBoundTheta] = theta;
0171 vector[eBoundQOverP] = -2_e / p;
0172 BoundTrackParameters params(surface, vector, std::nullopt,
0173 ParticleHypothesis::pionLike(2_e));
0174 checkParameters(params, l0, l1, time, phi, theta, p, -2_e, pos, dir);
0175 BOOST_CHECK(!params.covariance());
0176
0177
0178 params = BoundTrackParameters(surface, vector, cov,
0179 ParticleHypothesis::pionLike(2_e));
0180 checkParameters(params, l0, l1, time, phi, theta, p, -2_e, pos, dir);
0181 BOOST_CHECK(params.covariance());
0182 BOOST_CHECK_EQUAL(params.covariance().value(), cov);
0183 }
0184
0185 {
0186 auto params =
0187 BoundTrackParameters::create(geoCtx, surface, pos4, dir, 1 / p,
0188 std::nullopt, ParticleHypothesis::pion0())
0189 .value();
0190 checkParameters(params, l0, l1, time, phi, theta, p, 0_e, pos, dir);
0191 BOOST_CHECK(!params.covariance());
0192 }
0193
0194 {
0195 auto params =
0196 BoundTrackParameters::create(geoCtx, surface, pos4, dir, -1_e / p,
0197 std::nullopt, ParticleHypothesis::pion())
0198 .value();
0199 checkParameters(params, l0, l1, time, phi, theta, p, -1_e, pos, dir);
0200 BOOST_CHECK(!params.covariance());
0201 }
0202
0203 {
0204 auto params =
0205 BoundTrackParameters::create(geoCtx, surface, pos4, dir, 1_e / p,
0206 std::nullopt, ParticleHypothesis::pion())
0207 .value();
0208 checkParameters(params, l0, l1, time, phi, theta, p, 1_e, pos, dir);
0209 BOOST_CHECK(!params.covariance());
0210 }
0211
0212 {
0213 auto params =
0214 BoundTrackParameters::create(geoCtx, surface, pos4, dir, 1 / p,
0215 std::nullopt, ParticleHypothesis::pion0())
0216 .value();
0217 checkParameters(params, l0, l1, time, phi, theta, p, 0_e, pos, dir);
0218 BOOST_CHECK(!params.covariance());
0219 }
0220
0221 {
0222 auto params = BoundTrackParameters::create(
0223 geoCtx, surface, pos4, dir, -2_e / p, std::nullopt,
0224 ParticleHypothesis::pionLike(2_e))
0225 .value();
0226 checkParameters(params, l0, l1, time, phi, theta, p, -2_e, pos, dir);
0227 BOOST_CHECK(!params.covariance());
0228 }
0229
0230 {
0231 auto params = BoundTrackParameters::create(
0232 geoCtx, surface, pos4, dir, 3_e / p, std::nullopt,
0233 ParticleHypothesis::pionLike(3_e))
0234 .value();
0235 checkParameters(params, l0, l1, time, phi, theta, p, 3_e, pos, dir);
0236 BOOST_CHECK(!params.covariance());
0237 }
0238 }
0239
0240
0241
0242
0243 const auto cones = bdata::make({
0244 Surface::makeShared<ConeSurface>(Transform3::Identity(),
0245 0.5 ),
0246 });
0247 const auto cylinders = bdata::make({
0248 Surface::makeShared<CylinderSurface>(Transform3::Identity(),
0249 10.0 , 100 ),
0250 });
0251 const auto discs = bdata::make({
0252 Surface::makeShared<DiscSurface>(Transform3::Identity(), 0 ,
0253 100 ),
0254 });
0255 const auto perigees = bdata::make({
0256 Surface::makeShared<PerigeeSurface>(Vector3(0, 0, -1.5)),
0257 });
0258 const auto planes = bdata::make({
0259 CurvilinearSurface(Vector3(1, 2, 3), Vector3::UnitX()).planeSurface(),
0260 CurvilinearSurface(Vector3(-2, -3, -4), Vector3::UnitY()).planeSurface(),
0261 CurvilinearSurface(Vector3(3, -4, 5), Vector3::UnitZ()).planeSurface(),
0262 });
0263 const auto straws = bdata::make({
0264 Surface::makeShared<StrawSurface>(Transform3::Identity(), 2.0 ,
0265 200.0 ),
0266 });
0267
0268 }
0269
0270 BOOST_AUTO_TEST_SUITE(EventDataBoundTrackParameters)
0271
0272 BOOST_DATA_TEST_CASE(ConeSurface,
0273 cones* posAngle* posPositiveNonzero* ts* phis* thetas* ps,
0274 surface, lphi, lz, time, phi, theta, p) {
0275
0276
0277 const auto r = lz * surface->bounds().tanAlpha();
0278
0279 runTest(surface, (0 < lz) ? (r * lphi) : 0.0, lz, time, phi, theta, p);
0280 }
0281
0282 BOOST_DATA_TEST_CASE(
0283 CylinderSurface,
0284 cylinders* posSymmetric* posSymmetric* ts* phis* thetas* ps, surface, lrphi,
0285 lz, time, phi, theta, p) {
0286 runTest(surface, lrphi, lz, time, phi, theta, p);
0287 }
0288
0289 BOOST_DATA_TEST_CASE(DiscSurface,
0290 discs* posPositive* posAngle* ts* phis* thetas* ps,
0291 surface, lr, lphi, time, phi, theta, p) {
0292
0293 runTest(surface, lr, (0 < lr) ? lphi : 0.0, time, phi, theta, p);
0294 }
0295
0296 BOOST_DATA_TEST_CASE(
0297 PerigeeSurface,
0298 perigees* posSymmetric* posSymmetric* ts* phis* thetasNoForwardBackward* ps,
0299 surface, d0, z0, time, phi, theta, p) {
0300
0301 runTest(surface, d0, z0, time, phi, theta, p);
0302 }
0303
0304 BOOST_DATA_TEST_CASE(PlaneSurface,
0305 planes* posSymmetric* posSymmetric* ts* phis* thetas* ps,
0306 surface, l0, l1, time, phi, theta, p) {
0307 runTest(surface, l0, l1, time, phi, theta, p);
0308 }
0309
0310 BOOST_DATA_TEST_CASE(
0311 StrawSurface,
0312 straws* posPositive* posSymmetric* ts* phis* thetasNoForwardBackward* ps,
0313 surface, lr, lz, time, phi, theta, p) {
0314
0315 runTest(surface, lr, lz, time, phi, theta, p);
0316 }
0317
0318 BOOST_AUTO_TEST_SUITE_END()