Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:11:20

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