Back to home page

EIC code displayed by LXR

 
 

    


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