Back to home page

EIC code displayed by LXR

 
 

    


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

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/tools/output_test_stream.hpp>
0010 #include <boost/test/unit_test.hpp>
0011 
0012 #include "Acts/Definitions/Algebra.hpp"
0013 #include "Acts/Definitions/Alignment.hpp"
0014 #include "Acts/Definitions/TrackParametrization.hpp"
0015 #include "Acts/EventData/ParticleHypothesis.hpp"
0016 #include "Acts/EventData/TrackParameters.hpp"
0017 #include "Acts/EventData/detail/GenerateParameters.hpp"
0018 #include "Acts/Geometry/GeometryContext.hpp"
0019 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0020 #include "Acts/Propagator/Propagator.hpp"
0021 #include "Acts/Propagator/StraightLineStepper.hpp"
0022 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0023 #include "Acts/Surfaces/LineBounds.hpp"
0024 #include "Acts/Surfaces/Surface.hpp"
0025 #include "Acts/Tests/CommonHelpers/DetectorElementStub.hpp"
0026 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0027 #include "Acts/Tests/CommonHelpers/LineSurfaceStub.hpp"
0028 #include "Acts/Tests/CommonHelpers/PredefinedMaterials.hpp"
0029 #include "Acts/Utilities/BinningType.hpp"
0030 #include "Acts/Utilities/Intersection.hpp"
0031 #include "Acts/Utilities/Result.hpp"
0032 #include "Acts/Utilities/ThrowAssert.hpp"
0033 #include "Acts/Utilities/UnitVectors.hpp"
0034 #include "Acts/Utilities/VectorHelpers.hpp"
0035 
0036 #include <cmath>
0037 #include <memory>
0038 #include <numbers>
0039 #include <optional>
0040 #include <ostream>
0041 #include <tuple>
0042 #include <vector>
0043 
0044 namespace Acts::Test {
0045 
0046 // Create a test context
0047 GeometryContext tgContext = GeometryContext();
0048 
0049 BOOST_AUTO_TEST_SUITE(Surfaces)
0050 
0051 /// Unit test for creating compliant/non-compliant LineSurface object
0052 BOOST_AUTO_TEST_CASE(LineSurface_Constructors_test) {
0053   /// Test default construction
0054   // default construction is deleted
0055 
0056   Translation3 translation{0., 1., 2.};
0057   Transform3 transform(translation);
0058   auto pTransform = Transform3(translation);
0059   const double radius = 2.;
0060   const double halfZ = 20.;
0061   BOOST_CHECK(LineSurfaceStub(pTransform, radius, halfZ).constructedOk());
0062 
0063   /// ctor with nullptr for LineBounds
0064   BOOST_CHECK(LineSurfaceStub(pTransform).constructedOk());
0065 
0066   /// ctor with LineBounds
0067   auto pLineBounds = std::make_shared<const LineBounds>(2., 10.);
0068   BOOST_CHECK(LineSurfaceStub(pTransform, pLineBounds).constructedOk());
0069 
0070   /// ctor with LineBounds, detector element, Identifier
0071   auto pMaterial =
0072       std::make_shared<const HomogeneousSurfaceMaterial>(makePercentSlab());
0073   DetectorElementStub detElement{pTransform, pLineBounds, 0.2, pMaterial};
0074   BOOST_CHECK(LineSurfaceStub(pLineBounds, detElement).constructedOk());
0075   LineSurfaceStub lineToCopy(pTransform, 2., 20.);
0076 
0077   /// Copy ctor
0078   BOOST_CHECK(LineSurfaceStub(lineToCopy).constructedOk());
0079 
0080   /// Copied and transformed ctor
0081   BOOST_CHECK(
0082       LineSurfaceStub(tgContext, lineToCopy, transform).constructedOk());
0083 
0084   /// Construct with nullptr bounds
0085   DetectorElementStub detElem;
0086   BOOST_CHECK_THROW(LineSurfaceStub nullBounds(nullptr, detElem),
0087                     AssertionFailureException);
0088 
0089   BOOST_TEST_MESSAGE(
0090       "All LineSurface constructors are callable without problem");
0091 }
0092 
0093 /// Unit tests of all named methods
0094 BOOST_AUTO_TEST_CASE(LineSurface_allNamedMethods_test) {
0095   // referencePosition()
0096   Translation3 translation{0., 1., 2.};
0097   Transform3 transform(translation);
0098   LineSurfaceStub line(transform, 2., 20.);
0099   Vector3 referencePosition{0., 1., 2.};
0100   CHECK_CLOSE_ABS(referencePosition,
0101                   line.referencePosition(tgContext, AxisDirection::AxisX),
0102                   1e-6);
0103 
0104   // bounds()
0105   auto pLineBounds = std::make_shared<const LineBounds>(2., 10.);
0106   LineSurfaceStub boundedLine(transform, pLineBounds);
0107   const LineBounds& bounds =
0108       dynamic_cast<const LineBounds&>(boundedLine.bounds());
0109   BOOST_CHECK_EQUAL(bounds, LineBounds(2., 10.));
0110 
0111   // globalToLocal()
0112   Vector3 gpos{0., 1., 0.};
0113   const Vector3 mom{20., 0., 0.};  // needs more realistic parameters
0114   Vector2 localPosition =
0115       line.globalToLocal(tgContext, gpos, mom.normalized()).value();
0116   const Vector2 expectedResult{0, -2};
0117   CHECK_CLOSE_ABS(expectedResult, localPosition, 1e-6);
0118 
0119   // intersection
0120   {
0121     const Vector3 direction{0., 1., 2.};
0122     auto sfIntersection =
0123         line.intersect(tgContext, {0., 0., 0.}, direction.normalized(),
0124                        BoundaryTolerance::Infinite())
0125             .closest();
0126     BOOST_CHECK(sfIntersection.isValid());
0127     Vector3 expectedIntersection(0, 1., 2.);
0128     CHECK_CLOSE_ABS(sfIntersection.position(), expectedIntersection,
0129                     1e-6);  // need more tests..
0130     BOOST_CHECK_EQUAL(sfIntersection.object(), &line);
0131   }
0132 
0133   // isOnSurface
0134   const Vector3 insidePosition{0., 2.5, 0.};
0135   BOOST_CHECK(line.isOnSurface(
0136       tgContext, insidePosition, mom,
0137       BoundaryTolerance::Infinite()));  // need better test here
0138   const Vector3 outsidePosition{100., 100., 200.};
0139   BOOST_CHECK(!line.isOnSurface(tgContext, outsidePosition, mom,
0140                                 BoundaryTolerance::None()));
0141 
0142   // localToGlobal
0143   Vector3 returnedGlobalPosition{0., 0., 0.};
0144   // Vector2 localPosition{0., 0.};
0145   const Vector3 momentum{300., 200., 0.};  // find better values!
0146   returnedGlobalPosition =
0147       line.localToGlobal(tgContext, localPosition, momentum.normalized());
0148   const Vector3 expectedGlobalPosition{0, 1, 0};
0149   CHECK_CLOSE_ABS(returnedGlobalPosition, expectedGlobalPosition, 1e-6);
0150 
0151   // referenceFrame
0152   Vector3 globalPosition{0., 0., 0.};
0153   auto returnedRotationMatrix =
0154       line.referenceFrame(tgContext, globalPosition, momentum.normalized());
0155   double v0 = std::cos(std::atan(2. / 3.));
0156   double v1 = std::sin(std::atan(2. / 3.));
0157   RotationMatrix3 expectedRotationMatrix;
0158   expectedRotationMatrix << -v1, 0., v0, v0, 0., v1, 0., 1., -0.;
0159   CHECK_CLOSE_OR_SMALL(returnedRotationMatrix, expectedRotationMatrix, 1e-6,
0160                        1e-9);
0161 
0162   // name()
0163   boost::test_tools::output_test_stream output;
0164   output << line.name();
0165   BOOST_CHECK(output.is_equal("Acts::LineSurface"));
0166 
0167   // normal
0168   // arbitrary position, because should be irrelevant
0169   Vector3 position{5, 5, 5};  // should be irrelevant
0170   {
0171     Vector3 direction{1, 0, 0};
0172     CHECK_CLOSE_ABS(line.normal(tgContext, position, direction), direction,
0173                     1e-6);
0174   }
0175   {
0176     Vector3 direction = Vector3{1, 0, 0.1}.normalized();
0177     CHECK_CLOSE_ABS(line.normal(tgContext, position, direction),
0178                     Vector3::UnitX(), 1e-6);
0179   }
0180   {
0181     Vector3 direction{-1, 0, 0};
0182     CHECK_CLOSE_ABS(line.normal(tgContext, position, direction), direction,
0183                     1e-6);
0184   }
0185   {
0186     Vector3 direction{0, 1, 0};
0187     CHECK_CLOSE_ABS(line.normal(tgContext, position, direction), direction,
0188                     1e-6);
0189   }
0190 
0191   // pathCorrection
0192   Vector3 any3DVector = Vector3::Random();
0193   CHECK_CLOSE_REL(line.pathCorrection(tgContext, any3DVector, any3DVector), 1.,
0194                   1e-6);
0195 }
0196 
0197 /// Unit test for testing LineSurface assignment
0198 BOOST_AUTO_TEST_CASE(LineSurface_assignment_test) {
0199   Translation3 translation{0., 1., 2.};
0200   Transform3 transform(translation);
0201   LineSurfaceStub originalLine(transform, 2., 20.);
0202   LineSurfaceStub assignedLine(transform, 1., 1.);
0203   BOOST_CHECK(assignedLine != originalLine);  // operator != from base
0204   assignedLine = originalLine;
0205   BOOST_CHECK(assignedLine == originalLine);  // operator == from base
0206 }
0207 
0208 /// Unit test for testing LineSurface alignment derivatives
0209 BOOST_AUTO_TEST_CASE(LineSurfaceAlignment) {
0210   Translation3 translation{0., 1., 2.};
0211   Transform3 transform(translation);
0212   LineSurfaceStub line(transform, 2., 20.);
0213 
0214   const auto& rotation = transform.rotation();
0215   // The local frame z axis
0216   const Vector3 localZAxis = rotation.col(2);
0217   // Check the local z axis is aligned to global z axis
0218   CHECK_CLOSE_ABS(localZAxis, Vector3(0., 0., 1.), 1e-15);
0219 
0220   // Define the track (global) position and direction
0221   Vector3 globalPosition{1, 2, 4};
0222   Vector3 momentum{-1, 1, 1};
0223   Vector3 direction = momentum.normalized();
0224 
0225   // (a) Test the derivative of path length w.r.t. alignment parameters
0226   const AlignmentToPathMatrix& alignToPath =
0227       line.alignmentToPathDerivative(tgContext, globalPosition, direction);
0228   // The expected results
0229   AlignmentToPathMatrix expAlignToPath = AlignmentToPathMatrix::Zero();
0230   const double value = std::numbers::sqrt3 / 2;
0231   expAlignToPath << -value, value, 0, -3 * value, -value, 0;
0232   // Check if the calculated derivative is as expected
0233   CHECK_CLOSE_ABS(alignToPath, expAlignToPath, 1e-10);
0234 
0235   // (b) Test the derivative of bound track parameters local position w.r.t.
0236   // position in local 3D Cartesian coordinates
0237   const auto& loc3DToLocBound =
0238       line.localCartesianToBoundLocalDerivative(tgContext, globalPosition);
0239   // Check if the result is as expected
0240   ActsMatrix<2, 3> expLoc3DToLocBound = ActsMatrix<2, 3>::Zero();
0241   expLoc3DToLocBound << 1 / std::numbers::sqrt2, 1 / std::numbers::sqrt2, 0, 0,
0242       0, 1;
0243   CHECK_CLOSE_ABS(loc3DToLocBound, expLoc3DToLocBound, 1e-10);
0244 }
0245 
0246 BOOST_AUTO_TEST_CASE(LineSurfaceTransformRoundTrip) {
0247   LineSurfaceStub surface(Transform3::Identity());
0248 
0249   auto roundTrip = [&surface](const Vector3& pos, const Vector3& dir) {
0250     auto intersection = surface.intersect(tgContext, pos, dir).closest();
0251     Vector3 global = intersection.position();
0252     Vector2 local = *surface.globalToLocal(tgContext, global, dir);
0253     Vector3 global2 = surface.localToGlobal(tgContext, local, dir);
0254     return std::make_tuple(global, local, global2);
0255   };
0256 
0257   {
0258     Vector3 pos = {-0.02801, 0.00475611, 0.285106};
0259     Vector3 dir = Vector3(-0.03951, -0.221457, -0.564298).normalized();
0260 
0261     auto [global, local, global2] = roundTrip(pos, dir);
0262 
0263     CHECK_CLOSE_ABS(global, global2, 1e-10);
0264   }
0265 
0266   {
0267     Vector3 pos = {-64.2892, 65.2697, -0.839014};
0268     Vector3 dir = Vector3(-0.236602, -0.157616, 0.956786).normalized();
0269 
0270     auto [global, local, global2] = roundTrip(pos, dir);
0271 
0272     CHECK_CLOSE_ABS(global, global2, 1e-10);
0273   }
0274 }
0275 
0276 BOOST_AUTO_TEST_CASE(LineSurfaceTransformRoundTripEtaStability) {
0277   LineSurfaceStub surface(Transform3::Identity());
0278 
0279   // eta=6 is already crashing
0280   const std::vector<double> etas = {0, 1, 2, 3, 4, 5};
0281 
0282   for (double eta : etas) {
0283     Vector3 pca = {5, 0, 0};
0284     Vector3 dir = makeDirectionFromPhiEta(std::numbers::pi / 2., eta);
0285     Vector3 pos = pca + dir;
0286 
0287     auto intersection = surface.intersect(tgContext, pos, dir).closest();
0288 
0289     Vector3 global = intersection.position();
0290     Vector2 local = *surface.globalToLocal(tgContext, global, dir);
0291     Vector3 global2 = surface.localToGlobal(tgContext, local, dir);
0292 
0293     CHECK_CLOSE_ABS(global, global2, 1e-10);
0294     CHECK_CLOSE_ABS(pca, global2, 1e-10);
0295   }
0296 }
0297 
0298 BOOST_AUTO_TEST_CASE(LineSurfaceIntersection) {
0299   using namespace Acts::UnitLiterals;
0300 
0301   double eps = 1e-10;
0302 
0303   Vector3 direction = Vector3(1, 1, 100).normalized();
0304   BoundVector boundVector;
0305   boundVector << 1_cm, 1_cm, VectorHelpers::phi(direction),
0306       VectorHelpers::theta(direction), 1, 0;
0307   double pathLimit = 1_cm;
0308 
0309   auto surface = std::make_shared<LineSurfaceStub>(Transform3::Identity());
0310 
0311   BoundTrackParameters initialParams{surface, boundVector, std::nullopt,
0312                                      ParticleHypothesis::pion()};
0313 
0314   using Propagator = Propagator<StraightLineStepper>;
0315   using PropagatorOptions = Propagator::Options<>;
0316 
0317   Propagator propagator({});
0318 
0319   CurvilinearTrackParameters displacedParameters{
0320       Vector4::Zero(), Vector3::Zero(), 1, std::nullopt,
0321       ParticleHypothesis::pion()};
0322   {
0323     PropagatorOptions options(tgContext, {});
0324     options.direction = Acts::Direction::Backward();
0325     options.pathLimit = pathLimit;
0326 
0327     auto result = propagator.propagate(initialParams, options);
0328     BOOST_CHECK(result.ok());
0329     BOOST_CHECK(result.value().endParameters);
0330 
0331     displacedParameters = result.value().endParameters.value();
0332   }
0333 
0334   auto intersection =
0335       surface
0336           ->intersect(tgContext, displacedParameters.position(tgContext),
0337                       displacedParameters.direction())
0338           .closest();
0339   CHECK_CLOSE_ABS(intersection.pathLength(), pathLimit, eps);
0340 
0341   BoundTrackParameters endParameters{surface,
0342                                      detail::Test::someBoundParametersA(),
0343                                      std::nullopt, ParticleHypothesis::pion()};
0344   {
0345     PropagatorOptions options(tgContext, {});
0346     options.direction = Acts::Direction::Forward();
0347     options.stepping.maxStepSize = 1_mm;
0348 
0349     auto result = propagator.propagate(displacedParameters, *surface, options);
0350     BOOST_CHECK(result.ok());
0351     BOOST_CHECK(result.value().endParameters);
0352     CHECK_CLOSE_ABS(result.value().pathLength, pathLimit, eps);
0353     endParameters = result.value().endParameters.value();
0354   }
0355 
0356   CHECK_CLOSE_ABS(initialParams.parameters(), endParameters.parameters(), eps);
0357 }
0358 
0359 BOOST_AUTO_TEST_SUITE_END()
0360 
0361 }  // namespace Acts::Test