Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-13 08:14:43

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/Surfaces/BoundaryTolerance.hpp"
0015 #include "Acts/Surfaces/RectangleBounds.hpp"
0016 #include "Acts/Surfaces/SurfaceBounds.hpp"
0017 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0018 #include "Acts/Surfaces/detail/VerticesHelper.hpp"
0019 
0020 #include <algorithm>
0021 #include <array>
0022 #include <random>
0023 #include <stdexcept>
0024 #include <vector>
0025 
0026 namespace bdata = boost::unit_test::data;
0027 
0028 namespace Acts::Test {
0029 
0030 BOOST_AUTO_TEST_SUITE(Surfaces)
0031 
0032 const double minHalfX = 1.;
0033 const double maxHalfX = 6.;
0034 const double halfY = 2.;
0035 
0036 /// Unit test for creating compliant/non-compliant TrapezoidBounds object
0037 BOOST_AUTO_TEST_CASE(TrapezoidBoundsConstruction) {
0038   /// Test default construction
0039   // default construction is deleted
0040 
0041   /// Test construction with defining half lengths
0042   BOOST_CHECK_EQUAL(TrapezoidBounds(minHalfX, maxHalfX, halfY).type(),
0043                     SurfaceBounds::eTrapezoid);
0044   /// Copy constructor
0045   TrapezoidBounds original(minHalfX, maxHalfX, halfY);
0046   TrapezoidBounds copied(original);
0047   BOOST_CHECK_EQUAL(copied, original);
0048 }
0049 
0050 /// Unit test for creating compliant/non-compliant TrapezoidBounds object
0051 BOOST_AUTO_TEST_CASE(TrapezoidBoundsRecreated) {
0052   /// Copy constructor
0053   TrapezoidBounds original(minHalfX, maxHalfX, halfY);
0054   // const bool symmetric(false);
0055   auto valvector = original.values();
0056   std::array<double, TrapezoidBounds::eSize> values{};
0057   std::copy_n(valvector.begin(), TrapezoidBounds::eSize, values.begin());
0058   TrapezoidBounds recreated(values);
0059   BOOST_CHECK_EQUAL(original, recreated);
0060 }
0061 
0062 // Exception tests
0063 BOOST_AUTO_TEST_CASE(TrapezoidBoundsException) {
0064   // Negative x at min y
0065   BOOST_CHECK_THROW(TrapezoidBounds(-minHalfX, maxHalfX, halfY),
0066                     std::logic_error);
0067 
0068   // Negative x at max y
0069   BOOST_CHECK_THROW(TrapezoidBounds(minHalfX, -maxHalfX, halfY),
0070                     std::logic_error);
0071 
0072   // Negative x at miny and max y
0073   BOOST_CHECK_THROW(TrapezoidBounds(-minHalfX, -maxHalfX, halfY),
0074                     std::logic_error);
0075 
0076   // Negative y
0077   BOOST_CHECK_THROW(TrapezoidBounds(minHalfX, maxHalfX, -halfY),
0078                     std::logic_error);
0079 }
0080 
0081 /// Unit tests for TrapezoidBounds properties
0082 BOOST_AUTO_TEST_CASE(TrapezoidBoundsProperties) {
0083   TrapezoidBounds trapezoidBoundsObject(minHalfX, maxHalfX, halfY);
0084 
0085   /// Test type() (redundant; already used in constructor confirmation)
0086   BOOST_CHECK_EQUAL(trapezoidBoundsObject.type(), SurfaceBounds::eTrapezoid);
0087 
0088   /// Test minHalflengthX
0089   BOOST_CHECK_EQUAL(
0090       trapezoidBoundsObject.get(TrapezoidBounds::eHalfLengthXnegY), minHalfX);
0091 
0092   /// Test maxHalfLengthX
0093   BOOST_CHECK_EQUAL(
0094       trapezoidBoundsObject.get(TrapezoidBounds::eHalfLengthXposY), maxHalfX);
0095 
0096   /// Test halflengthY
0097   BOOST_CHECK_EQUAL(trapezoidBoundsObject.get(TrapezoidBounds::eHalfLengthY),
0098                     halfY);
0099 
0100   /// Test distanceToBoundary
0101   Vector2 outside(30., 0.);
0102   Vector2 inRectangle(2., 0.5);
0103 
0104   /// Test vertices
0105   std::vector<Vector2> expectedVertices{
0106       {-1., -2.}, {1., -2.}, {6., 2.}, {-6., 2.}};
0107   const auto& actualVertices = trapezoidBoundsObject.vertices();
0108   BOOST_CHECK_EQUAL_COLLECTIONS(actualVertices.cbegin(), actualVertices.cend(),
0109                                 expectedVertices.cbegin(),
0110                                 expectedVertices.cend());
0111 
0112   /// Test boundingBox
0113   BOOST_CHECK_EQUAL(trapezoidBoundsObject.boundingBox(),
0114                     RectangleBounds(6., 2.));
0115 
0116   /// Test dump
0117   boost::test_tools::output_test_stream dumpOutput;
0118   trapezoidBoundsObject.toStream(dumpOutput);
0119   BOOST_CHECK(dumpOutput.is_equal(
0120       "Acts::TrapezoidBounds:  (halfXnegY, halfXposY, halfY, rotAngle) = "
0121       "(1.0000000, 6.0000000, 2.0000000, 0.0000000)"));
0122 
0123   /// Test inside
0124   BOOST_CHECK(
0125       trapezoidBoundsObject.inside(inRectangle, BoundaryTolerance::None()));
0126   BOOST_CHECK(
0127       !trapezoidBoundsObject.inside(outside, BoundaryTolerance::None()));
0128 
0129   const auto vertices = trapezoidBoundsObject.vertices();
0130 
0131   std::vector<Vector2> testPoints = {
0132       // inside
0133       {0, 1},
0134       {0, -1},
0135       {2, 0.5},
0136       {2, 0},
0137       {-2, 0},
0138       {-2, 0.5},
0139       {3, 1},
0140       {-3, 1},
0141       {4, 1},
0142       {-4, 1},
0143       {-6, 2},
0144 
0145       // outside
0146       {0, 2.5},
0147       {0, -2.5},
0148       {2, 2.5},
0149       {-2, 2.5},
0150       {2, -2.5},
0151       {-2, -2.5},
0152       {4, -1},
0153       {-4, -1},
0154       {-7, 0},
0155       {7, 0},
0156       {5, -3},
0157       {5, 3},
0158       {-5, -3},
0159       {-5, 3},
0160       {6, 2},
0161   };
0162 
0163   for (const auto& p : testPoints) {
0164     BOOST_TEST_CONTEXT("p=" << p.transpose()) {
0165       BOOST_CHECK_EQUAL(
0166           detail::VerticesHelper::isInsidePolygon(p, vertices),
0167           trapezoidBoundsObject.inside(p, BoundaryTolerance::None()));
0168     }
0169   }
0170 }
0171 
0172 BOOST_DATA_TEST_CASE(
0173     TrapezoidInsideCheck,
0174     bdata::random(
0175         (bdata::engine = std::mt19937(), bdata::seed = 21,
0176          bdata::distribution = std::uniform_real_distribution<double>(-7, 7))) ^
0177         bdata::random((bdata::engine = std::mt19937(), bdata::seed = 22,
0178                        bdata::distribution =
0179                            std::uniform_real_distribution<double>(-3, 3))) ^
0180         bdata::xrange(1000),
0181     x, y, index) {
0182   (void)index;
0183 
0184   static const TrapezoidBounds trapezoidBoundsObject(minHalfX, maxHalfX, halfY);
0185   static const auto vertices = trapezoidBoundsObject.vertices();
0186 
0187   BOOST_CHECK_EQUAL(
0188       detail::VerticesHelper::isInsidePolygon(Vector2{x, y}, vertices),
0189       trapezoidBoundsObject.inside({x, y}, BoundaryTolerance::None()));
0190 }
0191 
0192 /// Unit test for testing TrapezoidBounds assignment
0193 BOOST_AUTO_TEST_CASE(TrapezoidBoundsAssignment) {
0194   TrapezoidBounds trapezoidBoundsObject(minHalfX, maxHalfX, halfY);
0195 
0196   /// Test operator ==
0197   // not implemented in this class
0198 
0199   /// Test assignment
0200   TrapezoidBounds assignedTrapezoidBoundsObject(10., 20., 14.2);
0201   assignedTrapezoidBoundsObject = trapezoidBoundsObject;
0202   BOOST_CHECK_EQUAL(assignedTrapezoidBoundsObject, trapezoidBoundsObject);
0203 }
0204 
0205 BOOST_AUTO_TEST_CASE(TrapezoidBoundsCenter) {
0206   // Test unrotated trapezoid
0207   TrapezoidBounds trap(minHalfX, maxHalfX, halfY);
0208   Vector2 center = trap.center();
0209   BOOST_CHECK_EQUAL(center.x(), 0.0);
0210   BOOST_CHECK_EQUAL(center.y(), 0.0);
0211 
0212   // Test rotated trapezoid
0213   const double rotAngle = 0.3;
0214   TrapezoidBounds trapRotated(minHalfX, maxHalfX, halfY, rotAngle);
0215   Vector2 centerRotated = trapRotated.center();
0216   // For a rotated trapezoid symmetric about origin, centroid should still be at
0217   // origin
0218   BOOST_CHECK_EQUAL(centerRotated.x(), 0.0);
0219   BOOST_CHECK_EQUAL(centerRotated.y(), 0.0);
0220 }
0221 
0222 BOOST_AUTO_TEST_SUITE_END()
0223 
0224 }  // namespace Acts::Test