Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-23 08:24:24

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/tools/output_test_stream.hpp>
0011 #include <boost/test/unit_test.hpp>
0012 
0013 #include "Acts/Definitions/Algebra.hpp"
0014 #include "Acts/Definitions/Tolerance.hpp"
0015 #include "Acts/Geometry/Extent.hpp"
0016 #include "Acts/Geometry/GeometryContext.hpp"
0017 #include "Acts/Geometry/Polyhedron.hpp"
0018 #include "Acts/Surfaces/ConeBounds.hpp"
0019 #include "Acts/Surfaces/ConeSurface.hpp"
0020 #include "Acts/Surfaces/Surface.hpp"
0021 #include "Acts/Surfaces/SurfaceBounds.hpp"
0022 #include "Acts/Utilities/BinningType.hpp"
0023 #include "Acts/Utilities/Result.hpp"
0024 #include "Acts/Utilities/ThrowAssert.hpp"
0025 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0026 
0027 #include <cmath>
0028 #include <memory>
0029 #include <numbers>
0030 #include <string>
0031 
0032 using namespace Acts;
0033 namespace ActsTests {
0034 
0035 // Create a test context
0036 GeometryContext tgContext = GeometryContext();
0037 
0038 BOOST_AUTO_TEST_SUITE(SurfacesSuite)
0039 
0040 /// Unit test for creating compliant/non-compliant ConeSurface object
0041 BOOST_AUTO_TEST_CASE(ConeSurfaceConstruction) {
0042   /// Test default construction
0043   // default construction is deleted
0044 
0045   /// Constructor with transform, alpha and symmetry indicator
0046   const double alpha = std::numbers::pi / 8.;
0047   const double halfPhiSector = std::numbers::pi / 16.;
0048   const double zMin = 1.;
0049   const double zMax = 10.;
0050   const bool symmetric = false;
0051   const Translation3 translation{0., 1., 2.};
0052 
0053   auto pTransform = Transform3(translation);
0054   BOOST_CHECK_EQUAL(
0055       Surface::makeShared<ConeSurface>(Transform3::Identity(), alpha, symmetric)
0056           ->type(),
0057       Surface::Cone);
0058   BOOST_CHECK_EQUAL(
0059       Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric)->type(),
0060       Surface::Cone);
0061 
0062   /// Constructor with transform pointer, alpha,z min and max, halfPhiSector
0063   BOOST_CHECK_EQUAL(Surface::makeShared<ConeSurface>(pTransform, alpha, zMin,
0064                                                      zMax, halfPhiSector)
0065                         ->type(),
0066                     Surface::Cone);
0067 
0068   /// Constructor with transform and ConeBounds pointer
0069   auto pConeBounds =
0070       std::make_shared<const ConeBounds>(alpha, zMin, zMax, halfPhiSector, 0.);
0071   BOOST_CHECK_EQUAL(
0072       Surface::makeShared<ConeSurface>(pTransform, pConeBounds)->type(),
0073       Surface::Cone);
0074 
0075   /// Copy constructor
0076   auto coneSurfaceObject =
0077       Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
0078   auto copiedConeSurface = Surface::makeShared<ConeSurface>(*coneSurfaceObject);
0079   BOOST_CHECK_EQUAL(copiedConeSurface->type(), Surface::Cone);
0080   BOOST_CHECK(*copiedConeSurface == *coneSurfaceObject);
0081 
0082   /// Copied and transformed
0083   auto copiedTransformedConeSurface = Surface::makeShared<ConeSurface>(
0084       tgContext, *coneSurfaceObject, pTransform);
0085   BOOST_CHECK_EQUAL(copiedTransformedConeSurface->type(), Surface::Cone);
0086 
0087   /// Construct with nullptr bounds
0088   BOOST_CHECK_THROW(auto nullBounds = Surface::makeShared<ConeSurface>(
0089                         Transform3::Identity(), nullptr),
0090                     AssertionFailureException);
0091 }
0092 
0093 /// Unit test for testing ConeSurface properties
0094 BOOST_AUTO_TEST_CASE(ConeSurfaceProperties) {
0095   /// Test clone method
0096   const double alpha = std::numbers::pi / 8.;
0097   const bool symmetric = false;
0098   const Translation3 translation{0., 1., 2.};
0099 
0100   auto pTransform = Transform3(translation);
0101   auto coneSurfaceObject =
0102       Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
0103 
0104   /// Test type (redundant)
0105   BOOST_CHECK_EQUAL(coneSurfaceObject->type(), Surface::Cone);
0106 
0107   /// Test referencePosition
0108   Vector3 referencePosition{0., 1., 2.};
0109   CHECK_CLOSE_ABS(
0110       coneSurfaceObject->referencePosition(tgContext, AxisDirection::AxisPhi),
0111       referencePosition, 1e-6);
0112 
0113   /// Test referenceFrame
0114   Vector3 globalPosition{2., 2., 2.};
0115   Vector3 momentum{1.e6, 1.e6, 1.e6};
0116   double rootHalf = std::sqrt(0.5);
0117   RotationMatrix3 expectedFrame;
0118   expectedFrame << -rootHalf, 0., rootHalf, rootHalf, 0., rootHalf, 0., 1., 0.;
0119   CHECK_CLOSE_OR_SMALL(
0120       coneSurfaceObject->referenceFrame(tgContext, globalPosition, momentum),
0121       expectedFrame, 1e-6, 1e-9);
0122 
0123   /// Test normal, given 3D position
0124   Vector3 origin{0., 0., 0.};
0125   Vector3 normal3D = {0., -1., 0.};
0126   CHECK_CLOSE_ABS(coneSurfaceObject->normal(tgContext, origin), normal3D, 1e-6);
0127 
0128   /// Test normal given 2D rphi position
0129   Vector2 positionPiBy2(1., std::numbers::pi / 2.);
0130   Vector3 normalAtPiBy2{0.0312768, 0.92335, -0.382683};
0131 
0132   CHECK_CLOSE_OR_SMALL(coneSurfaceObject->normal(tgContext, positionPiBy2),
0133                        normalAtPiBy2, 1e-2, 1e-9);
0134 
0135   /// Test rotational symmetry axis
0136   Vector3 symmetryAxis{0., 0., 1.};
0137   CHECK_CLOSE_ABS(coneSurfaceObject->rotSymmetryAxis(tgContext), symmetryAxis,
0138                   1e-6);
0139 
0140   /// Test bounds
0141   BOOST_CHECK_EQUAL(coneSurfaceObject->bounds().type(), SurfaceBounds::eCone);
0142 
0143   /// Test localToGlobal
0144   Vector2 localPosition{1., std::numbers::pi / 2.};
0145   globalPosition =
0146       coneSurfaceObject->localToGlobal(tgContext, localPosition, momentum);
0147   Vector3 expectedPosition{0.0220268, 1.65027, 3.5708};
0148 
0149   CHECK_CLOSE_REL(globalPosition, expectedPosition, 1e-2);
0150 
0151   /// Testing globalToLocal
0152   localPosition =
0153       coneSurfaceObject->globalToLocal(tgContext, globalPosition, momentum)
0154           .value();
0155   Vector2 expectedLocalPosition{1., std::numbers::pi / 2.};
0156 
0157   CHECK_CLOSE_REL(localPosition, expectedLocalPosition, 1e-6);
0158 
0159   /// Test isOnSurface
0160   Vector3 offSurface{100, 1, 2};
0161   BOOST_CHECK(coneSurfaceObject->isOnSurface(
0162       tgContext, globalPosition, momentum, BoundaryTolerance::None()));
0163   BOOST_CHECK(!coneSurfaceObject->isOnSurface(tgContext, offSurface, momentum,
0164                                               BoundaryTolerance::None()));
0165 
0166   /// Test pathCorrection
0167   CHECK_CLOSE_REL(coneSurfaceObject->pathCorrection(tgContext, offSurface,
0168                                                     momentum.normalized()),
0169                   0.40218866453252877, 0.01);
0170 
0171   /// Test name
0172   BOOST_CHECK_EQUAL(coneSurfaceObject->name(),
0173                     std::string("Acts::ConeSurface"));
0174 
0175   /// Test dump
0176   boost::test_tools::output_test_stream dumpOutput;
0177   dumpOutput << coneSurfaceObject->toStream(tgContext);
0178   BOOST_CHECK(dumpOutput.is_equal(
0179       "Acts::ConeSurface\n"
0180       "     Center position  (x, y, z) = (0.0000, 1.0000, 2.0000)\n"
0181       "     Rotation:             colX = (1.000000, 0.000000, 0.000000)\n"
0182       "                           colY = (0.000000, 1.000000, 0.000000)\n"
0183       "                           colZ = (0.000000, 0.000000, 1.000000)\n"
0184       "     Bounds  : Acts::ConeBounds: (tanAlpha, minZ, maxZ, halfPhiSector, "
0185       "averagePhi) = (0.4142136, 0.0000000, inf, 3.1415927, 0.0000000)"
0186 
0187       ));
0188 }
0189 
0190 BOOST_AUTO_TEST_CASE(ConeSurfaceEqualityOperators) {
0191   const double alpha = std::numbers::pi / 8.;
0192   const bool symmetric = false;
0193   const Translation3 translation{0., 1., 2.};
0194 
0195   auto pTransform = Transform3(translation);
0196   auto coneSurfaceObject =
0197       Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
0198 
0199   auto coneSurfaceObject2 =
0200       Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
0201 
0202   /// Test equality operator
0203   BOOST_CHECK(*coneSurfaceObject == *coneSurfaceObject2);
0204 
0205   BOOST_TEST_CHECKPOINT(
0206       "Create and then assign a ConeSurface object to the existing one");
0207   /// Test assignment
0208   auto assignedConeSurface =
0209       Surface::makeShared<ConeSurface>(Transform3::Identity(), 0.1, true);
0210   *assignedConeSurface = *coneSurfaceObject;
0211   /// Test equality of assigned to original
0212   BOOST_CHECK(*assignedConeSurface == *coneSurfaceObject);
0213 }
0214 
0215 BOOST_AUTO_TEST_CASE(ConeSurfaceExtent) {
0216   const double alpha = std::numbers::pi / 8.;
0217   const double halfPhiSector = std::numbers::pi / 8.;  // != pi/16
0218   const double zMin = 0.;                              // != 1.
0219   const double zMax = 10.;
0220   const Translation3 translation{0., 0., 0.};  // != {0., 1., 2.}
0221 
0222   /// Testing a Full cone
0223   auto pTransform = Transform3(translation);
0224   auto pConeBounds = std::make_shared<const ConeBounds>(alpha, zMin, zMax);
0225   auto pCone = Surface::makeShared<ConeSurface>(pTransform, pConeBounds);
0226   auto pConeExtent = pCone->polyhedronRepresentation(tgContext, 1).extent();
0227 
0228   double rMax = zMax * std::tan(alpha);
0229   CHECK_CLOSE_ABS(zMin, pConeExtent.min(AxisDirection::AxisZ),
0230                   s_onSurfaceTolerance);
0231   CHECK_CLOSE_ABS(zMax, pConeExtent.max(AxisDirection::AxisZ),
0232                   s_onSurfaceTolerance);
0233   CHECK_CLOSE_ABS(0., pConeExtent.min(AxisDirection::AxisR),
0234                   s_onSurfaceTolerance);
0235   CHECK_CLOSE_ABS(rMax, pConeExtent.max(AxisDirection::AxisR),
0236                   s_onSurfaceTolerance);
0237   CHECK_CLOSE_ABS(-rMax, pConeExtent.min(AxisDirection::AxisX),
0238                   s_onSurfaceTolerance);
0239   CHECK_CLOSE_ABS(rMax, pConeExtent.max(AxisDirection::AxisX),
0240                   s_onSurfaceTolerance);
0241   CHECK_CLOSE_ABS(-rMax, pConeExtent.min(AxisDirection::AxisY),
0242                   s_onSurfaceTolerance);
0243   CHECK_CLOSE_ABS(rMax, pConeExtent.max(AxisDirection::AxisY),
0244                   s_onSurfaceTolerance);
0245 
0246   /// Now a sector
0247   pConeBounds =
0248       std::make_shared<const ConeBounds>(alpha, zMin, zMax, halfPhiSector, 0.);
0249   pCone = Surface::makeShared<ConeSurface>(pTransform, pConeBounds);
0250   pConeExtent = pCone->polyhedronRepresentation(tgContext, 1).extent();
0251 
0252   CHECK_CLOSE_ABS(zMin, pConeExtent.min(AxisDirection::AxisZ),
0253                   s_onSurfaceTolerance);
0254   CHECK_CLOSE_ABS(zMax, pConeExtent.max(AxisDirection::AxisZ),
0255                   s_onSurfaceTolerance);
0256   CHECK_CLOSE_ABS(0., pConeExtent.min(AxisDirection::AxisR),
0257                   s_onSurfaceTolerance);
0258   CHECK_CLOSE_ABS(rMax, pConeExtent.max(AxisDirection::AxisR),
0259                   s_onSurfaceTolerance);
0260 }
0261 
0262 /// Unit test for testing ConeSurface alignment derivatives
0263 BOOST_AUTO_TEST_CASE(ConeSurfaceAlignment) {
0264   const double alpha = std::numbers::pi / 8.;
0265   const bool symmetric = false;
0266   const Translation3 translation{0., 1., 2.};
0267 
0268   auto pTransform = Transform3(translation);
0269   auto coneSurfaceObject =
0270       Surface::makeShared<ConeSurface>(pTransform, alpha, symmetric);
0271 
0272   const auto& rotation = pTransform.rotation();
0273   // The local frame z axis
0274   const Vector3 localZAxis = rotation.col(2);
0275   // Check the local z axis is aligned to global z axis
0276   CHECK_CLOSE_ABS(localZAxis, Vector3(0., 0., 1.), 1e-15);
0277 
0278   /// Define the track (global) position and direction
0279   Vector3 globalPosition{0, 1. + std::tan(alpha), 3};
0280 
0281   // Test the derivative of bound track parameters local position w.r.t.
0282   // position in local 3D Cartesian coordinates
0283   const auto& loc3DToLocBound =
0284       coneSurfaceObject->localCartesianToBoundLocalDerivative(tgContext,
0285                                                               globalPosition);
0286   // Check if the result is as expected
0287   ActsMatrix<2, 3> expLoc3DToLocBound = ActsMatrix<2, 3>::Zero();
0288   expLoc3DToLocBound << -1, 0, std::numbers::pi / 2. * std::tan(alpha), 0, 0, 1;
0289   CHECK_CLOSE_ABS(loc3DToLocBound, expLoc3DToLocBound, 1e-10);
0290 }
0291 
0292 BOOST_AUTO_TEST_SUITE_END()
0293 }  // namespace ActsTests