Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-24 08:20:18

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/TrackParametrization.hpp"
0014 #include "Acts/Definitions/Units.hpp"
0015 #include "Acts/EventData/TransformationHelpers.hpp"
0016 #include "Acts/Geometry/GeometryContext.hpp"
0017 #include "Acts/Utilities/UnitVectors.hpp"
0018 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0019 
0020 #include <algorithm>
0021 #include <limits>
0022 #include <numbers>
0023 #include <utility>
0024 #include <vector>
0025 
0026 #include "TrackParametersDatasets.hpp"
0027 
0028 using namespace Acts;
0029 using namespace Acts::UnitLiterals;
0030 
0031 namespace {
0032 constexpr auto eps = std::numeric_limits<double>::epsilon();
0033 }
0034 
0035 namespace ActsTests {
0036 
0037 BOOST_AUTO_TEST_SUITE(EventDataSuite)
0038 
0039 BOOST_DATA_TEST_CASE(
0040     Parameters,
0041     surfaces* posSymmetric* posSymmetric* ts* phis* thetas* ps* qsNonZero,
0042     surface, l0, l1, time, phi, theta, p, q) {
0043   GeometryContext geoCtx;
0044 
0045   Vector2 loc(l0, l1);
0046   Vector3 dir = makeDirectionFromPhiTheta(phi, theta);
0047   // transform reference position
0048   Vector3 pos = surface->localToGlobal(geoCtx, loc, dir);
0049 
0050   const auto qOverP = q / p;
0051 
0052   // construct bound parameters
0053   BoundVector bv = BoundVector::Zero();
0054   bv[eBoundLoc0] = l0;
0055   bv[eBoundLoc1] = l1;
0056   bv[eBoundTime] = time;
0057   bv[eBoundPhi] = phi;
0058   bv[eBoundTheta] = theta;
0059   bv[eBoundQOverP] = qOverP;
0060 
0061   // convert to free parameters
0062   FreeVector fv = transformBoundToFreeParameters(*surface, geoCtx, bv);
0063 
0064   CHECK_CLOSE_OR_SMALL(fv.segment<3>(eFreePos0), pos, eps, eps);
0065   CHECK_CLOSE_OR_SMALL(fv[eFreeTime], bv[eBoundTime], eps, eps);
0066   CHECK_CLOSE_REL(fv.segment<3>(eFreeDir0).norm(), 1, eps);
0067   CHECK_CLOSE_OR_SMALL(fv.segment<3>(eFreeDir0), dir, eps, eps);
0068   CHECK_CLOSE_OR_SMALL(fv[eFreeQOverP], bv[eBoundQOverP], eps, eps);
0069 }
0070 
0071 BOOST_AUTO_TEST_SUITE_END()
0072 
0073 BOOST_AUTO_TEST_SUITE(TransformFreeToBound)
0074 
0075 BOOST_DATA_TEST_CASE(
0076     GlobalToBoundTrackParameters,
0077     surfaces* posSymmetric* posSymmetric* ts* phis* thetas* ps* qsNonZero,
0078     surface, l0, l1, time, phiInput, theta, p, q) {
0079   // phi is ill-defined in forward/backward tracks
0080   const auto phi = ((0 < theta) && (theta < std::numbers::pi)) ? phiInput : 0.;
0081   const auto qOverP = q / p;
0082 
0083   GeometryContext geoCtx;
0084   Vector2 loc(l0, l1);
0085   Vector3 dir = makeDirectionFromPhiTheta(phi, theta);
0086   // transform reference position
0087   Vector3 pos = surface->localToGlobal(geoCtx, loc, dir);
0088 
0089   // convert free parameters to bound parameters
0090   {
0091     BOOST_TEST_INFO("Transform free parameters vector onto surface "
0092                     << surface->name());
0093 
0094     FreeVector fv = FreeVector::Zero();
0095     fv[eFreePos0] = pos[ePos0];
0096     fv[eFreePos1] = pos[ePos1];
0097     fv[eFreePos2] = pos[ePos2];
0098     fv[eFreeTime] = time;
0099     fv[eFreeDir0] = dir[eMom0];
0100     fv[eFreeDir1] = dir[eMom1];
0101     fv[eFreeDir2] = dir[eMom2];
0102     fv[eFreeQOverP] = qOverP;
0103     BoundVector bv =
0104         transformFreeToBoundParameters(fv, *surface, geoCtx).value();
0105     CHECK_CLOSE_OR_SMALL(bv[eBoundLoc0], l0, eps, eps);
0106     CHECK_CLOSE_OR_SMALL(bv[eBoundLoc1], l1, eps, eps);
0107     CHECK_CLOSE_OR_SMALL(bv[eBoundTime], time, eps, eps);
0108     CHECK_CLOSE_OR_SMALL(bv[eBoundPhi], phi, eps, eps);
0109     CHECK_CLOSE_OR_SMALL(bv[eBoundTheta], theta, eps, eps);
0110     CHECK_CLOSE_OR_SMALL(bv[eBoundQOverP], qOverP, eps, eps);
0111   }
0112 
0113   // Assert failure when trying to convert a position that is not on-surface.
0114   {
0115     Vector3 posOff = pos + surface->normal(geoCtx, loc) * 0.5;
0116     BOOST_TEST_INFO("Transform free parameters vector onto surface "
0117                     << surface->name());
0118 
0119     FreeVector fv = FreeVector::Zero();
0120     fv[eFreePos0] = posOff[ePos0];
0121     fv[eFreePos1] = posOff[ePos1];
0122     fv[eFreePos2] = posOff[ePos2];
0123     fv[eFreeTime] = time;
0124     fv[eFreeDir0] = dir[eMom0];
0125     fv[eFreeDir1] = dir[eMom1];
0126     fv[eFreeDir2] = dir[eMom2];
0127     fv[eFreeQOverP] = qOverP;
0128     auto res = transformFreeToBoundParameters(fv, *surface, geoCtx);
0129     BOOST_CHECK(!res.ok());
0130   }
0131 
0132   // convert separate components to bound parameters
0133   {
0134     BOOST_TEST_INFO("Transform free parameters components onto surface "
0135                     << surface->name());
0136 
0137     BoundVector bv =
0138         transformFreeToBoundParameters(pos, time, dir, qOverP, *surface, geoCtx)
0139             .value();
0140     CHECK_CLOSE_OR_SMALL(bv[eBoundLoc0], l0, eps, eps);
0141     CHECK_CLOSE_OR_SMALL(bv[eBoundLoc1], l1, eps, eps);
0142     CHECK_CLOSE_OR_SMALL(bv[eBoundTime], time, eps, eps);
0143     CHECK_CLOSE_OR_SMALL(bv[eBoundPhi], phi, eps, eps);
0144     CHECK_CLOSE_OR_SMALL(bv[eBoundTheta], theta, eps, eps);
0145     CHECK_CLOSE_OR_SMALL(bv[eBoundQOverP], qOverP, eps, eps);
0146   }
0147 
0148   // Assert failure when trying to convert a position that is not on-surface.
0149   {
0150     BOOST_TEST_INFO("Transform free parameters components onto surface "
0151                     << surface->name());
0152 
0153     Vector3 posOff = pos + surface->normal(geoCtx, loc) * 0.5;
0154     auto res = transformFreeToBoundParameters(posOff, time, dir, qOverP,
0155                                               *surface, geoCtx);
0156     BOOST_CHECK(!res.ok());
0157   }
0158 }
0159 
0160 BOOST_DATA_TEST_CASE(GlobalToCurvilinearParameters,
0161                      ts* phis* thetas* ps* qsNonZero, time, phiInput, theta, p,
0162                      q) {
0163   // phi is ill-defined in forward/backward tracks
0164   const auto phi = ((0 < theta) && (theta < std::numbers::pi)) ? phiInput : 0.;
0165   const auto qOverP = q / p;
0166 
0167   GeometryContext geoCtx;
0168   Vector3 dir = makeDirectionFromPhiTheta(phi, theta);
0169 
0170   // convert w/ direction
0171   {
0172     BoundVector bv = transformFreeToCurvilinearParameters(time, dir, qOverP);
0173     CHECK_SMALL(bv[eBoundLoc0], eps);
0174     CHECK_SMALL(bv[eBoundLoc1], eps);
0175     CHECK_CLOSE_OR_SMALL(bv[eBoundTime], time, eps, eps);
0176     CHECK_CLOSE_OR_SMALL(bv[eBoundPhi], phi, eps, eps);
0177     CHECK_CLOSE_OR_SMALL(bv[eBoundTheta], theta, eps, eps);
0178     CHECK_CLOSE_OR_SMALL(bv[eBoundQOverP], qOverP, eps, eps);
0179   }
0180   // convert w/ angles
0181   {
0182     BoundVector bv =
0183         transformFreeToCurvilinearParameters(time, phi, theta, qOverP);
0184     CHECK_SMALL(bv[eBoundLoc0], eps);
0185     CHECK_SMALL(bv[eBoundLoc1], eps);
0186     CHECK_CLOSE_OR_SMALL(bv[eBoundTime], time, eps, eps);
0187     CHECK_CLOSE_OR_SMALL(bv[eBoundPhi], phi, eps, eps);
0188     CHECK_CLOSE_OR_SMALL(bv[eBoundTheta], theta, eps, eps);
0189     CHECK_CLOSE_OR_SMALL(bv[eBoundQOverP], qOverP, eps, eps);
0190   }
0191 }
0192 
0193 BOOST_AUTO_TEST_SUITE_END()
0194 
0195 }  // namespace ActsTests