Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:34

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/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   // native values
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   // convenience accessors
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   // reflection
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   // phi is ill-defined in forward/backward tracks
0093   phi = ((0 < theta) && (theta < std::numbers::pi)) ? phi : 0.;
0094 
0095   // global direction for reference
0096   const Vector3 dir = makeDirectionFromPhiTheta(phi, theta);
0097   // convert local-to-global for reference
0098   const Vector2 loc(l0, l1);
0099   const Vector3 pos = surface->localToGlobal(geoCtx, loc, dir);
0100   // global four-position as input
0101   Vector4 pos4;
0102   pos4.segment<3>(ePos0) = pos;
0103   pos4[eTime] = time;
0104 
0105   // neutral parameters from local vector
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     // reassign w/ covariance
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   // negative charged parameters from local vector
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     // reassign w/ covariance
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   // positive charged parameters from local vector
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     // reassign w/ covariance
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   // double-negative charged any parameters from local vector
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     // reassign w/ covariance
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   // neutral parameters from global information
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   // negative charged parameters from global information
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   // positive charged parameters from global information
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   // neutral any parameters from global information
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   // double-negative any parameters from global information
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   // triple-positive any parameters from global information
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 // different surfaces
0246 // parameters must be chosen such that all possible local positions (as defined
0247 // in the dataset's header) represent valid points on the surface.
0248 const auto cones = bdata::make({
0249     Surface::makeShared<ConeSurface>(Transform3::Identity(),
0250                                      0.5 /* opening angle */),
0251 });
0252 const auto cylinders = bdata::make({
0253     Surface::makeShared<CylinderSurface>(Transform3::Identity(),
0254                                          10.0 /* radius */, 100 /* half z */),
0255 });
0256 const auto discs = bdata::make({
0257     Surface::makeShared<DiscSurface>(Transform3::Identity(), 0 /* radius min */,
0258                                      100 /* radius max */),
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 /* radius */,
0270                                       200.0 /* half z */),
0271 });
0272 
0273 }  // namespace
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   // TODO extend lz to zero after fixing the transform implementation
0281   // local parameter r*phi has limits that depend on the z position
0282   const auto r = lz * surface->bounds().tanAlpha();
0283   // local coordinates are singular at z = 0 -> normalize local r*phi
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   // local coordinates are singular at r = 0 -> normalize local phi
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   // TODO extend theta to forward/back extreme cases fixing the transform
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   // TODO extend theta to forward/back extreme cases fixing the transform
0320   runTest(surface, lr, lz, time, phi, theta, p);
0321 }
0322 
0323 BOOST_AUTO_TEST_SUITE_END()