Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-13 09:23: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/unit_test.hpp>
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Surfaces/AnnulusBounds.hpp"
0013 #include "Acts/Surfaces/BoundaryTolerance.hpp"
0014 #include "Acts/Surfaces/SurfaceBounds.hpp"
0015 #include "Acts/Utilities/VectorHelpers.hpp"
0016 
0017 #include <algorithm>
0018 #include <array>
0019 #include <stdexcept>
0020 #include <vector>
0021 
0022 using namespace Acts;
0023 
0024 namespace ActsTests {
0025 
0026 BOOST_AUTO_TEST_SUITE(SurfacesSuite)
0027 
0028 const double minRadius = 7.2;
0029 const double maxRadius = 12.0;
0030 const double minPhi = 0.74195;
0031 const double maxPhi = 1.33970;
0032 
0033 const Vector2 offset(-2., 2.);
0034 
0035 // Unit tests for AnnulusBounds constructors
0036 BOOST_AUTO_TEST_CASE(AnnulusBoundsConstruction) {
0037   // Test construction with radii and default sector
0038   auto original = AnnulusBounds(minRadius, maxRadius, minPhi, maxPhi, offset);
0039   AnnulusBounds copied(original);
0040   BOOST_CHECK_EQUAL(original, copied);
0041 }
0042 
0043 // Unit tests for AnnulusBounds recreation
0044 BOOST_AUTO_TEST_CASE(AnnulusBoundsRecreation) {
0045   // Test construction with radii and default sector
0046   auto original = AnnulusBounds(minRadius, maxRadius, minPhi, maxPhi, offset);
0047   auto valvector = original.values();
0048   std::array<double, AnnulusBounds::eSize> values{};
0049   std::copy_n(valvector.begin(), AnnulusBounds::eSize, values.begin());
0050   AnnulusBounds recreated(values);
0051   BOOST_CHECK_EQUAL(original, recreated);
0052 }
0053 
0054 // Unit tests for AnnulusBounds exception throwing
0055 BOOST_AUTO_TEST_CASE(AnnulusBoundsExcpetion) {
0056   // Exception for negative inner radius
0057   BOOST_CHECK_THROW(AnnulusBounds(-1., maxRadius, minPhi, maxPhi, offset),
0058                     std::logic_error);
0059   // Exception for negative outer radius
0060   BOOST_CHECK_THROW(AnnulusBounds(minRadius, -1., minPhi, maxPhi, offset),
0061                     std::logic_error);
0062   // Exception for swapped radii
0063   BOOST_CHECK_THROW(AnnulusBounds(maxRadius, minRadius, minPhi, maxPhi, offset),
0064                     std::logic_error);
0065   // Exception for out of range min phi
0066   BOOST_CHECK_THROW(AnnulusBounds(minRadius, maxRadius, -4., maxPhi, offset),
0067                     std::logic_error);
0068   // Exception for out of range max phi
0069   BOOST_CHECK_THROW(AnnulusBounds(minRadius, maxRadius, minPhi, 4., offset),
0070                     std::logic_error);
0071   // Exception for out of range max phi
0072   BOOST_CHECK_THROW(AnnulusBounds(minRadius, maxRadius, maxPhi, minPhi, offset),
0073                     std::logic_error);
0074 }
0075 
0076 /// Unit tests for AnnulusBounds properties
0077 BOOST_AUTO_TEST_CASE(AnnulusBoundsProperties) {
0078   /// Test construction with radii and default sector
0079   AnnulusBounds aBounds(minRadius, maxRadius, minPhi, maxPhi, offset);
0080 
0081   /// Test type() (redundant; already used in constructor confirmation)
0082   BOOST_CHECK_EQUAL(aBounds.type(), SurfaceBounds::eAnnulus);
0083 
0084   /// Test positions inside/outside
0085   // - start from cartesian (from test drawing)
0086   Vector2 inSurfaceXY(7., 7.);
0087   Vector2 outsideXY1(5., 5.);
0088   Vector2 outsideXY2(10., 3.);
0089   Vector2 outsideXY3(10., 10.);
0090   Vector2 outsideXY4(4., 10.);
0091   std::vector<Vector2> testPoints = {inSurfaceXY, outsideXY1, outsideXY2,
0092                                      outsideXY3, outsideXY4};
0093 
0094   auto toStripFrame = [&](const Vector2& xy) -> Vector2 {
0095     auto shifted = xy + offset;
0096     double r = VectorHelpers::perp(shifted);
0097     double phi = VectorHelpers::phi(shifted);
0098     return Vector2(r, phi);
0099   };
0100 
0101   BOOST_CHECK(
0102       aBounds.inside(toStripFrame(inSurfaceXY), BoundaryTolerance::None()));
0103   BOOST_CHECK(
0104       !aBounds.inside(toStripFrame(outsideXY1), BoundaryTolerance::None()));
0105   BOOST_CHECK(
0106       !aBounds.inside(toStripFrame(outsideXY2), BoundaryTolerance::None()));
0107   BOOST_CHECK(
0108       !aBounds.inside(toStripFrame(outsideXY3), BoundaryTolerance::None()));
0109   BOOST_CHECK(
0110       !aBounds.inside(toStripFrame(outsideXY4), BoundaryTolerance::None()));
0111 
0112   // Check radial inside
0113   BOOST_CHECK(!aBounds.insideRadialBounds(0.5));
0114   BOOST_CHECK(aBounds.insideRadialBounds(9.));
0115   BOOST_CHECK(!aBounds.insideRadialBounds(18.));
0116 
0117   // Test rMin
0118   BOOST_CHECK_EQUAL(aBounds.get(AnnulusBounds::eMinR), minRadius);
0119   // Test rMax
0120   BOOST_CHECK_EQUAL(aBounds.get(AnnulusBounds::eMaxR), maxRadius);
0121   // Test phiMin
0122   BOOST_CHECK_EQUAL(aBounds.get(AnnulusBounds::eMinPhiRel), minPhi);
0123   // Test phiMax
0124   BOOST_CHECK_EQUAL(aBounds.get(AnnulusBounds::eMaxPhiRel), maxPhi);
0125 }
0126 
0127 /// Unit tests for AnnulusBounds vertices
0128 BOOST_AUTO_TEST_CASE(AnnulusBoundsVertices) {
0129   /// Test construction with radii and default sector
0130   AnnulusBounds aBounds(minRadius, maxRadius, minPhi, maxPhi, offset);
0131 
0132   // Retrieve the corners
0133   auto corners = aBounds.corners();
0134   BOOST_CHECK_EQUAL(corners.size(), 4);
0135 
0136   // Retrieve the vertices
0137   auto vertices = aBounds.vertices(0u);
0138   BOOST_CHECK_EQUAL(vertices.size(), 4);
0139 
0140   // Now generate with more segments
0141   unsigned int nQuarterSegments = 12;
0142   vertices = aBounds.vertices(nQuarterSegments);
0143   BOOST_CHECK_EQUAL(vertices.size(), 14u);
0144 }
0145 
0146 BOOST_AUTO_TEST_CASE(AnnulusBoundsNegativeTolerance) {
0147   AnnulusBounds aBounds(minRadius, maxRadius, minPhi, maxPhi, offset);
0148   double phiAverage = (minPhi + maxPhi) / 2;
0149 
0150   auto check = [&](const BoundaryTolerance& tolerance, const Vector2& point) {
0151     Vector2 pointAverage(point[0], phiAverage + point[1]);
0152     return aBounds.inside(pointAverage, tolerance);
0153   };
0154 
0155   double midRadius = (minRadius + maxRadius) / 2;
0156   double hlPhi = (maxPhi - minPhi) / 2;
0157 
0158   {
0159     auto tolerance = BoundaryTolerance::AbsoluteEuclidean(1);
0160 
0161     // Test points near radial boundaries
0162     BOOST_CHECK(!check(tolerance, {minRadius - 1.5, 0}));
0163     BOOST_CHECK(check(tolerance, {minRadius - 0.1, 0}));
0164     BOOST_CHECK(check(tolerance, {minRadius + 0.4, 0}));
0165     BOOST_CHECK(check(tolerance, {minRadius + 0.5, 0}));
0166     BOOST_CHECK(check(tolerance, {minRadius + 1.5, 0}));
0167 
0168     BOOST_CHECK(check(tolerance, {maxRadius - 1.5, 0}));
0169     BOOST_CHECK(check(tolerance, {maxRadius - 0.1, 0}));
0170     BOOST_CHECK(check(tolerance, {maxRadius + 0.3, 0}));
0171     BOOST_CHECK(check(tolerance, {maxRadius + 0.55, 0}));
0172     BOOST_CHECK(check(tolerance, {maxRadius + 1.2, 0}));
0173     BOOST_CHECK(!check(tolerance, {maxRadius + 1.7, 0}));
0174 
0175     // Check points near axial boundaries
0176     BOOST_CHECK(!check(tolerance, {midRadius, -hlPhi * 1.5}));
0177     BOOST_CHECK(check(tolerance, {midRadius, -hlPhi * 1.1}));
0178     BOOST_CHECK(check(tolerance, {midRadius, -hlPhi * 0.8}));
0179     BOOST_CHECK(check(tolerance, {midRadius, -hlPhi * 0.5}));
0180 
0181     BOOST_CHECK(check(tolerance, {midRadius, hlPhi * 0.5}));
0182     BOOST_CHECK(check(tolerance, {midRadius, hlPhi * 0.8}));
0183     BOOST_CHECK(check(tolerance, {midRadius, hlPhi * 1.1}));
0184     BOOST_CHECK(!check(tolerance, {midRadius, hlPhi * 1.5}));
0185   }
0186 
0187   {
0188     auto tolerance = BoundaryTolerance::AbsoluteEuclidean(-1);
0189 
0190     // Test points near radial boundaries
0191     BOOST_CHECK(!check(tolerance, {minRadius - 1.5, 0}));
0192     BOOST_CHECK(!check(tolerance, {minRadius - 0.1, 0}));
0193     BOOST_CHECK(!check(tolerance, {minRadius + 0.4, 0}));
0194     BOOST_CHECK(!check(tolerance, {minRadius + 0.5, 0}));
0195     BOOST_CHECK(check(tolerance, {minRadius + 1.5, 0}));
0196 
0197     BOOST_CHECK(check(tolerance, {maxRadius - 1.5, 0}));
0198     BOOST_CHECK(!check(tolerance, {maxRadius - 0.1, 0}));
0199     BOOST_CHECK(!check(tolerance, {maxRadius + 0.3, 0}));
0200     BOOST_CHECK(!check(tolerance, {maxRadius + 0.55, 0}));
0201     BOOST_CHECK(!check(tolerance, {maxRadius + 1.2, 0}));
0202     BOOST_CHECK(!check(tolerance, {maxRadius + 1.7, 0}));
0203 
0204     // Check points near axial boundaries
0205     BOOST_CHECK(!check(tolerance, {midRadius, -hlPhi * 1.5}));
0206     BOOST_CHECK(!check(tolerance, {midRadius, -hlPhi * 1.1}));
0207     BOOST_CHECK(!check(tolerance, {midRadius, -hlPhi * 0.8}));
0208     BOOST_CHECK(check(tolerance, {midRadius, -hlPhi * 0.5}));
0209 
0210     BOOST_CHECK(check(tolerance, {midRadius, hlPhi * 0.5}));
0211     BOOST_CHECK(!check(tolerance, {midRadius, hlPhi * 0.8}));
0212     BOOST_CHECK(!check(tolerance, {midRadius, hlPhi * 1.1}));
0213     BOOST_CHECK(!check(tolerance, {midRadius, hlPhi * 1.5}));
0214   }
0215 
0216   {
0217     auto tolerance =
0218         BoundaryTolerance::Chi2Bound(SquareMatrix2::Identity(), 0.1);
0219 
0220     // Test points near radial boundaries
0221     BOOST_CHECK(!check(tolerance, {minRadius - 1.5, 0}));
0222     BOOST_CHECK(check(tolerance, {minRadius - 0.1, 0}));
0223     BOOST_CHECK(check(tolerance, {minRadius + 0.4, 0}));
0224     BOOST_CHECK(check(tolerance, {minRadius + 0.5, 0}));
0225     BOOST_CHECK(check(tolerance, {minRadius + 1.5, 0}));
0226 
0227     BOOST_CHECK(check(tolerance, {maxRadius - 1.5, 0}));
0228     BOOST_CHECK(check(tolerance, {maxRadius - 0.1, 0}));
0229     BOOST_CHECK(check(tolerance, {maxRadius + 0.3, 0}));
0230     BOOST_CHECK(check(tolerance, {maxRadius + 0.55, 0}));
0231     BOOST_CHECK(!check(tolerance, {maxRadius + 1.2, 0}));
0232     BOOST_CHECK(!check(tolerance, {maxRadius + 1.7, 0}));
0233 
0234     // Check points near axial boundaries
0235     BOOST_CHECK(check(tolerance, {midRadius, -hlPhi * 1.5}));
0236     BOOST_CHECK(check(tolerance, {midRadius, -hlPhi * 1.1}));
0237     BOOST_CHECK(check(tolerance, {midRadius, -hlPhi * 0.8}));
0238     BOOST_CHECK(check(tolerance, {midRadius, -hlPhi * 0.5}));
0239 
0240     BOOST_CHECK(check(tolerance, {midRadius, hlPhi * 0.5}));
0241     BOOST_CHECK(check(tolerance, {midRadius, hlPhi * 0.8}));
0242     BOOST_CHECK(check(tolerance, {midRadius, hlPhi * 1.1}));
0243     BOOST_CHECK(check(tolerance, {midRadius, hlPhi * 1.5}));
0244   }
0245 
0246   {
0247     auto tolerance =
0248         BoundaryTolerance::Chi2Bound(SquareMatrix2::Identity(), -0.1);
0249 
0250     // Test points near radial boundaries
0251     BOOST_CHECK(!check(tolerance, {minRadius - 1.5, 0}));
0252     BOOST_CHECK(!check(tolerance, {minRadius - 0.1, 0}));
0253     BOOST_CHECK(!check(tolerance, {minRadius + 0.4, 0}));
0254     BOOST_CHECK(!check(tolerance, {minRadius + 0.5, 0}));
0255     BOOST_CHECK(check(tolerance, {minRadius + 1.5, 0}));
0256 
0257     BOOST_CHECK(check(tolerance, {maxRadius - 1.5, 0}));
0258     BOOST_CHECK(check(tolerance, {maxRadius - 0.1, 0}));
0259     BOOST_CHECK(!check(tolerance, {maxRadius + 0.3, 0}));
0260     BOOST_CHECK(!check(tolerance, {maxRadius + 0.55, 0}));
0261     BOOST_CHECK(!check(tolerance, {maxRadius + 1.2, 0}));
0262     BOOST_CHECK(!check(tolerance, {maxRadius + 1.7, 0}));
0263 
0264     // Check points near axial boundaries
0265     BOOST_CHECK(!check(tolerance, {midRadius, -hlPhi * 1.5}));
0266     BOOST_CHECK(!check(tolerance, {midRadius, -hlPhi * 1.1}));
0267     BOOST_CHECK(!check(tolerance, {midRadius, -hlPhi * 0.8}));
0268     BOOST_CHECK(!check(tolerance, {midRadius, -hlPhi * 0.5}));
0269 
0270     BOOST_CHECK(!check(tolerance, {midRadius, hlPhi * 0.5}));
0271     BOOST_CHECK(!check(tolerance, {midRadius, hlPhi * 0.8}));
0272     BOOST_CHECK(!check(tolerance, {midRadius, hlPhi * 1.1}));
0273     BOOST_CHECK(!check(tolerance, {midRadius, hlPhi * 1.5}));
0274   }
0275 }
0276 
0277 BOOST_AUTO_TEST_CASE(AnnulusBoundsCenter) {
0278   // Test annulus bounds center calculation
0279   AnnulusBounds annulus(minRadius, maxRadius, minPhi, maxPhi, offset);
0280   Vector2 center = annulus.center();
0281 
0282   // The center should be inside the annulus bounds
0283   BOOST_CHECK(annulus.inside(center));
0284 
0285   // Test with symmetric annulus (no offset)
0286   Vector2 noOffset(0., 0.);
0287   AnnulusBounds symmetricAnnulus(minRadius, maxRadius, minPhi, maxPhi,
0288                                  noOffset);
0289   Vector2 symmetricCenter = symmetricAnnulus.center();
0290 
0291   // For symmetric case, center should also be inside bounds
0292   BOOST_CHECK(symmetricAnnulus.inside(symmetricCenter));
0293 
0294   // The center should be in polar coordinates (r, phi) in strip system
0295   // Verify that r component is reasonable (between min and max radius)
0296   BOOST_CHECK(symmetricCenter.x() >= minRadius);
0297   BOOST_CHECK(symmetricCenter.x() <= maxRadius);
0298 
0299   // Verify that phi component is within phi range
0300   BOOST_CHECK(symmetricCenter.y() >= minPhi);
0301   BOOST_CHECK(symmetricCenter.y() <= maxPhi);
0302 
0303   // Test with non-zero average phi to verify proper rotation handling
0304   double avgPhi = 0.5;  // Non-zero average phi
0305   AnnulusBounds rotatedAnnulus(minRadius, maxRadius, minPhi, maxPhi, noOffset,
0306                                avgPhi);
0307   Vector2 rotatedCenter = rotatedAnnulus.center();
0308 
0309   // The center should still be inside the bounds after rotation
0310   BOOST_CHECK(rotatedAnnulus.inside(rotatedCenter));
0311 
0312   // Center should be in strip polar coordinates
0313   BOOST_CHECK(rotatedCenter.x() >= minRadius);
0314   BOOST_CHECK(rotatedCenter.x() <= maxRadius);
0315 }
0316 
0317 BOOST_AUTO_TEST_SUITE_END()
0318 
0319 }  // namespace ActsTests