Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-08 08:31:06

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/Surfaces/BoundaryTolerance.hpp"
0014 #include "Acts/Surfaces/CylinderBounds.hpp"
0015 #include "Acts/Surfaces/SurfaceBounds.hpp"
0016 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0017 
0018 #include <algorithm>
0019 #include <array>
0020 #include <cmath>
0021 #include <numbers>
0022 #include <stdexcept>
0023 #include <vector>
0024 
0025 using namespace Acts;
0026 
0027 namespace ActsTests {
0028 
0029 BOOST_AUTO_TEST_SUITE(SurfacesSuite)
0030 /// Unit test for creating compliant/non-compliant CylinderBounds object
0031 
0032 BOOST_AUTO_TEST_CASE(CylinderBoundsConstruction) {
0033   /// Test default construction
0034   // default construction is deleted
0035 
0036   const double radius = 0.5;
0037   const double halfZ = 10.;
0038   const double halfPhi = std::numbers::pi / 2.;
0039   const double averagePhi = std::numbers::pi / 2.;
0040 
0041   BOOST_CHECK_EQUAL(CylinderBounds(radius, halfZ).type(),
0042                     SurfaceBounds::eCylinder);
0043   BOOST_CHECK_EQUAL(CylinderBounds(radius, halfZ, halfPhi).type(),
0044                     SurfaceBounds::eCylinder);
0045   BOOST_CHECK_EQUAL(CylinderBounds(radius, halfZ, halfPhi, averagePhi).type(),
0046                     SurfaceBounds::eCylinder);
0047 
0048   /// Test copy construction;
0049   CylinderBounds cylinderBounds(radius, halfZ);
0050   CylinderBounds copyConstructedCylinderBounds(cylinderBounds);
0051   BOOST_CHECK_EQUAL(copyConstructedCylinderBounds, cylinderBounds);
0052 }
0053 
0054 BOOST_AUTO_TEST_CASE(CylinderBoundsRecreation) {
0055   const double radius = 0.5;
0056   const double halfZ = 10.;
0057 
0058   // Test construction with radii and default sector
0059   auto original = CylinderBounds(radius, halfZ);
0060   auto valvector = original.values();
0061   std::array<double, CylinderBounds::eSize> values{};
0062   std::copy_n(valvector.begin(), CylinderBounds::eSize, values.begin());
0063   CylinderBounds recreated(values);
0064   BOOST_CHECK_EQUAL(original, recreated);
0065 }
0066 
0067 BOOST_AUTO_TEST_CASE(CylinderBoundsException) {
0068   const double radius = 0.5;
0069   const double halfZ = 10.;
0070   const double halfPhi = std::numbers::pi / 2.;
0071   const double averagePhi = std::numbers::pi / 2.;
0072 
0073   /// Negative radius
0074   BOOST_CHECK_THROW(CylinderBounds(-radius, halfZ, halfPhi, averagePhi),
0075                     std::logic_error);
0076 
0077   /// Negative half length in z
0078   BOOST_CHECK_THROW(CylinderBounds(radius, -halfZ, halfPhi, averagePhi),
0079                     std::logic_error);
0080 
0081   /// Negative half sector in phi
0082   BOOST_CHECK_THROW(CylinderBounds(radius, halfZ, -halfPhi, averagePhi),
0083                     std::logic_error);
0084 
0085   /// Half sector in phi out of bounds
0086   BOOST_CHECK_THROW(CylinderBounds(radius, halfZ, 4., averagePhi),
0087                     std::logic_error);
0088 
0089   /// Phi position out of bounds
0090   BOOST_CHECK_THROW(CylinderBounds(radius, halfZ, halfPhi, 4.),
0091                     std::logic_error);
0092 }
0093 
0094 /// Unit tests for CylinderBounds properties
0095 BOOST_AUTO_TEST_CASE(CylinderBoundsProperties) {
0096   // CylinderBounds object of radius 0.5 and halfZ 20
0097   const double radius = 0.5;
0098   const double halfZ = 20.;                      // != 10.
0099   const double halfPhi = std::numbers::pi / 4.;  // != pi/2
0100   const double averagePhi = 0.;                  // != pi/2
0101 
0102   CylinderBounds cylinderBoundsObject(radius, halfZ);
0103   CylinderBounds cylinderBoundsSegment(radius, halfZ, halfPhi, averagePhi);
0104 
0105   /// Test for type()
0106   BOOST_CHECK_EQUAL(cylinderBoundsObject.type(), SurfaceBounds::eCylinder);
0107 
0108   /// Test for inside(), 2D coords are r or phi ,z? : needs clarification
0109   const Vector2 origin{0., 0.};
0110   const Vector2 atPiBy2{std::numbers::pi / 2., 0.};
0111   const Vector2 atPi{std::numbers::pi, 0.};
0112   const Vector2 beyondEnd{0, 30.};
0113   const Vector2 unitZ{0., 1.};
0114   const Vector2 unitPhi{1., 0.};
0115   const BoundaryTolerance tolerance = BoundaryTolerance::AbsoluteEuclidean(0.1);
0116 
0117   BOOST_CHECK(cylinderBoundsObject.inside(atPiBy2, tolerance));
0118   BOOST_CHECK(!cylinderBoundsSegment.inside(unitPhi, tolerance));
0119   BOOST_CHECK(cylinderBoundsObject.inside(origin, tolerance));
0120 
0121   /// Test for r()
0122   CHECK_CLOSE_REL(cylinderBoundsObject.get(CylinderBounds::eR), radius, 1e-6);
0123 
0124   /// Test for averagePhi
0125   CHECK_CLOSE_OR_SMALL(cylinderBoundsObject.get(CylinderBounds::eAveragePhi),
0126                        averagePhi, 1e-6, 1e-6);
0127 
0128   /// Test for halfPhiSector
0129   CHECK_CLOSE_REL(cylinderBoundsSegment.get(CylinderBounds::eHalfPhiSector),
0130                   halfPhi,
0131                   1e-6);  // fail
0132 
0133   /// Test for halflengthZ (NOTE: Naming violation)
0134   CHECK_CLOSE_REL(cylinderBoundsObject.get(CylinderBounds::eHalfLengthZ), halfZ,
0135                   1e-6);
0136 
0137   /// Test for dump
0138   boost::test_tools::output_test_stream dumpOutput;
0139   cylinderBoundsObject.toStream(dumpOutput);
0140   BOOST_CHECK(dumpOutput.is_equal(
0141       "Acts::CylinderBounds: (radius, halfLengthZ, halfPhiSector, "
0142       "averagePhi) = (0.5000000, 20.0000000, 3.1415927, 0.0000000)"));
0143 }
0144 
0145 /// Unit test for testing CylinderBounds assignment
0146 BOOST_AUTO_TEST_CASE(CylinderBoundsAssignment) {
0147   const double radius = 0.5;
0148   const double halfZ = 20.;  // != 10.
0149 
0150   CylinderBounds cylinderBoundsObject(radius, halfZ);
0151   CylinderBounds assignedCylinderBounds(10.5, 6.6);
0152   assignedCylinderBounds = cylinderBoundsObject;
0153 
0154   BOOST_CHECK_EQUAL(assignedCylinderBounds.get(CylinderBounds::eR),
0155                     cylinderBoundsObject.get(CylinderBounds::eR));
0156   BOOST_CHECK_EQUAL(assignedCylinderBounds, cylinderBoundsObject);
0157 }
0158 
0159 BOOST_AUTO_TEST_CASE(CylinderBoundsCenter) {
0160   const double radius = 5.0;
0161   const double halfZ = 10.0;
0162 
0163   // Test full cylinder
0164   CylinderBounds fullCylinder(radius, halfZ);
0165   Vector2 center = fullCylinder.center();
0166   CHECK_CLOSE_ABS(center, Vector2(0., 0.), 1e-6);
0167 
0168   // Test cylinder with average phi offset
0169   const double averagePhi = std::numbers::pi / 4.;
0170   CylinderBounds offsetCylinder(radius, halfZ, std::numbers::pi, averagePhi);
0171   Vector2 centerOffset = offsetCylinder.center();
0172   CHECK_CLOSE_ABS(centerOffset, Vector2(averagePhi, 0.), 1e-6);
0173 }
0174 
0175 BOOST_AUTO_TEST_CASE(CylinderBoundsCoversFullAzimuth) {
0176   const double radius = 0.5;
0177   const double halfZ = 10.;
0178 
0179   BOOST_CHECK(CylinderBounds(radius, halfZ).coversFullAzimuth());
0180   BOOST_CHECK(
0181       CylinderBounds(radius, halfZ, std::numbers::pi).coversFullAzimuth());
0182   BOOST_CHECK(
0183       CylinderBounds(radius, halfZ, std::nextafter(std::numbers::pi, 0.))
0184           .coversFullAzimuth());
0185   BOOST_CHECK(!CylinderBounds(radius, halfZ, std::numbers::pi / 4.)
0186                    .coversFullAzimuth());
0187 }
0188 
0189 BOOST_AUTO_TEST_SUITE_END()
0190 
0191 }  // namespace ActsTests