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