Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 07:53:50

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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   // native values
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   // convenience accessors
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   // reflection
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   // phi is ill-defined in forward/backward tracks
0088   phi = ((0 < theta) && (theta < std::numbers::pi)) ? phi : 0.;
0089 
0090   // global direction for reference
0091   const Vector3 dir = makeDirectionFromPhiTheta(phi, theta);
0092   // convert local-to-global for reference
0093   const Vector2 loc(l0, l1);
0094   const Vector3 pos = surface->localToGlobal(geoCtx, loc, dir);
0095   // global four-position as input
0096   Vector4 pos4;
0097   pos4.segment<3>(ePos0) = pos;
0098   pos4[eTime] = time;
0099 
0100   // neutral parameters from local vector
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     // reassign w/ covariance
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   // negative charged parameters from local vector
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     // reassign w/ covariance
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   // positive charged parameters from local vector
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     // reassign w/ covariance
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   // double-negative charged any parameters from local vector
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     // reassign w/ covariance
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   // neutral parameters from global information
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   // negative charged parameters from global information
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   // positive charged parameters from global information
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   // neutral any parameters from global information
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   // double-negative any parameters from global information
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   // triple-positive any parameters from global information
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 // different surfaces
0241 // parameters must be chosen such that all possible local positions (as defined
0242 // in the dataset's header) represent valid points on the surface.
0243 const auto cones = bdata::make({
0244     Surface::makeShared<ConeSurface>(Transform3::Identity(),
0245                                      0.5 /* opening angle */),
0246 });
0247 const auto cylinders = bdata::make({
0248     Surface::makeShared<CylinderSurface>(Transform3::Identity(),
0249                                          10.0 /* radius */, 100 /* half z */),
0250 });
0251 const auto discs = bdata::make({
0252     Surface::makeShared<DiscSurface>(Transform3::Identity(), 0 /* radius min */,
0253                                      100 /* radius max */),
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 /* radius */,
0265                                       200.0 /* half z */),
0266 });
0267 
0268 }  // namespace
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   // TODO extend lz to zero after fixing the transform implementation
0276   // local parameter r*phi has limits that depend on the z position
0277   const auto r = lz * surface->bounds().tanAlpha();
0278   // local coordinates are singular at z = 0 -> normalize local r*phi
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   // local coordinates are singular at r = 0 -> normalize local phi
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   // TODO extend theta to forward/back extreme cases fixing the transform
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   // TODO extend theta to forward/back extreme cases fixing the transform
0315   runTest(surface, lr, lz, time, phi, theta, p);
0316 }
0317 
0318 BOOST_AUTO_TEST_SUITE_END()