Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:53

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/detail/VerticesHelper.hpp"
0013 
0014 #include <algorithm>
0015 #include <numbers>
0016 #include <vector>
0017 
0018 #include <Eigen/Geometry>
0019 
0020 namespace Acts::detail::Test {
0021 
0022 BOOST_AUTO_TEST_SUITE(Surfaces)
0023 
0024 BOOST_AUTO_TEST_CASE(VerticesHelperOnHyperPlane) {
0025   {
0026     // 0 points - always on a plane
0027     const std::vector<Vector3> testPlane = {};
0028     BOOST_CHECK(VerticesHelper::onHyperPlane(testPlane));
0029   }
0030   {
0031     // 1 point - always on a plane
0032     const std::vector<Vector3> testPlane = {Vector3(1., 3., 0.)};
0033     BOOST_CHECK(VerticesHelper::onHyperPlane(testPlane));
0034   }
0035   {
0036     // 2 points - always on a plane
0037     const std::vector<Vector3> testPlane = {Vector3(1., 3., 0.),
0038                                             Vector3(-2., 1., 0.)};
0039     BOOST_CHECK(VerticesHelper::onHyperPlane(testPlane));
0040   }
0041   {
0042     // 3 points - always on a plane
0043     const std::vector<Vector3> testPlane = {
0044         Vector3(1., 3., 0.), Vector3(-2., 1., 0.), Vector3(5., 8., 0.)};
0045     BOOST_CHECK(VerticesHelper::onHyperPlane(testPlane));
0046   }
0047   {
0048     // 4 points - these are on the xy-plane
0049     const std::vector<Vector3> testPlane = {
0050         Vector3(1., 3., 0.), Vector3(-2., 1., 0.), Vector3(5., 8., 0.),
0051         Vector3(-9., -9., 0.)};
0052     BOOST_CHECK(VerticesHelper::onHyperPlane(testPlane));
0053   }
0054   {
0055     // 4 points - these are NOT on the xy-plane
0056     const std::vector<Vector3> testPlane = {
0057         Vector3(1., 3., 0.), Vector3(-2., 1., 0.), Vector3(5., 8., 0.),
0058         Vector3(-9., -9., 1.)};
0059     BOOST_CHECK(!VerticesHelper::onHyperPlane(testPlane));
0060   }
0061   {
0062     // Test more points and add later an outlier.
0063     // Start with 6 points on the xy-plane
0064     std::vector<Vector3> testPlane = {
0065         Vector3(1., 3., 0.),   Vector3(-2., 1., 0.), Vector3(5., 8., 0.),
0066         Vector3(-9., -9., 0.), Vector3(5., 0., 0.),  Vector3(3., 1., 0.)};
0067 
0068     // All on a hyper plane
0069     BOOST_CHECK(VerticesHelper::onHyperPlane(testPlane));
0070 
0071     // Create the transform
0072     Transform3 transform(AngleAxis3(0.234, Vector3(0., 1., 0.)) *
0073                          AngleAxis3(-0.734, Vector3(1., 1., 1.).normalized()) *
0074                          Translation3(Vector3(-1., 2., 3.)));
0075 
0076     auto trfSpace = [](std::vector<Vector3>& vtxs,
0077                        const Transform3& trf) -> void {
0078       std::transform(vtxs.begin(), vtxs.end(), vtxs.begin(),
0079                      [&](auto& v) { return (trf * v); });
0080     };
0081 
0082     trfSpace(testPlane, transform);
0083 
0084     // All on a hyper plane
0085     BOOST_CHECK(VerticesHelper::onHyperPlane(testPlane));
0086 
0087     // One outside the s_onSurfaceTolerance
0088     testPlane.push_back(transform * Vector3(3., -4., 0.05));
0089     BOOST_CHECK(!VerticesHelper::onHyperPlane(testPlane));
0090 
0091     // But inside extended tolerance
0092     BOOST_CHECK(VerticesHelper::onHyperPlane(testPlane, 0.6));
0093   }
0094 }
0095 
0096 BOOST_AUTO_TEST_CASE(GeneratePhiSegments) {
0097   // Case (1): a small segment is given, no cartesian maximum vertex
0098   double minPhi = 0.1;
0099   double maxPhi = 0.3;
0100 
0101   auto phis = VerticesHelper::phiSegments(minPhi, maxPhi);
0102   BOOST_CHECK_EQUAL(phis.size(), 2u);
0103   BOOST_CHECK(phis[0] == minPhi);
0104   BOOST_CHECK(phis[1] == maxPhi);
0105 
0106   // Case (2) a small segment is given, with one maximum vertex at phi = 0
0107   minPhi = -0.1;
0108   phis = VerticesHelper::phiSegments(minPhi, maxPhi);
0109   BOOST_CHECK_EQUAL(phis.size(), 3u);
0110   BOOST_CHECK(phis[0] == minPhi);
0111   BOOST_CHECK(phis[1] == 0.);
0112   BOOST_CHECK(phis[2] == maxPhi);
0113 
0114   // Case (3) a small segment is given, with one maximum vertex at phi = 2pi,
0115   // and one extra value
0116   phis = VerticesHelper::phiSegments(minPhi, maxPhi, {0.25});
0117   BOOST_CHECK_EQUAL(phis.size(), 4u);
0118   BOOST_CHECK(phis[0] == minPhi);
0119   BOOST_CHECK(phis[1] == 0.);
0120   BOOST_CHECK(phis[2] == 0.25);
0121   BOOST_CHECK(phis[3] == maxPhi);
0122 
0123   // Case (4) a small segment is given, with one maximum vertex at phi = 2pi,
0124   // and two extra values, one outside & hence throw an exception
0125   BOOST_CHECK_THROW(VerticesHelper::phiSegments(minPhi, maxPhi, {0.25, 0.5}),
0126                     std::invalid_argument);
0127 
0128   // Case (5) an invalid phi range is given
0129   BOOST_CHECK_THROW(VerticesHelper::phiSegments(0.8, 0.2, {0.25, 0.5}),
0130                     std::invalid_argument);
0131 
0132   // Case (6) a wrong number of minimum segments is given
0133   BOOST_CHECK_THROW(VerticesHelper::phiSegments(0.1, 0.3, {0.25, 0.5}, 3),
0134                     std::invalid_argument);
0135 }
0136 
0137 BOOST_AUTO_TEST_CASE(GenerateSegmentVertices) {
0138   // Case (1): a small segment is given, no cartesian maximum vertex & 1 step
0139   // segment
0140   double rx = 10.;
0141   double ry = 10.;
0142   double minPhi = 0.1;
0143   double maxPhi = 0.3;
0144 
0145   auto vertices = VerticesHelper::segmentVertices<Vector3, Transform3>(
0146       {rx, ry}, minPhi, maxPhi, {}, 1);
0147   std::size_t expectedVertices = 2u;
0148   BOOST_CHECK_EQUAL(vertices.size(), expectedVertices);
0149 
0150   // Now with a reference phi value
0151   vertices = VerticesHelper::segmentVertices<Vector3, Transform3>(
0152       {rx, ry}, minPhi, maxPhi, {0.2}, 1);
0153   expectedVertices = 3u;  // the reference is inserted
0154   BOOST_CHECK_EQUAL(vertices.size(), expectedVertices);
0155 
0156   // Now with more vertices - the the two corners and the ones from the
0157   // reference
0158   unsigned int quarterVertices = 36;
0159   vertices = VerticesHelper::segmentVertices<Vector3, Transform3>(
0160       {rx, ry}, minPhi, maxPhi, {}, quarterVertices);
0161   expectedVertices =
0162       static_cast<unsigned int>((maxPhi - minPhi) / (std::numbers::pi / 2.) *
0163                                 quarterVertices) +
0164       2u;
0165   BOOST_CHECK_EQUAL(vertices.size(), expectedVertices);
0166 
0167   // Case (2) a small segment is given, with one maximum vertex at phi = 0
0168   minPhi = -0.1;
0169   vertices = VerticesHelper::segmentVertices<Vector3, Transform3>(
0170       {rx, ry}, minPhi, maxPhi, {}, 1);
0171   expectedVertices = 3u;
0172   BOOST_CHECK_EQUAL(vertices.size(), expectedVertices);
0173 
0174   // Same with more segments
0175   quarterVertices = 12;
0176   vertices = VerticesHelper::segmentVertices<Vector3, Transform3>(
0177       {rx, ry}, minPhi, maxPhi, {}, quarterVertices);
0178   // Extrema will be covered by the segments
0179   expectedVertices =
0180       static_cast<unsigned int>((maxPhi - minPhi) / (std::numbers::pi / 2.) *
0181                                 quarterVertices) +
0182       2u;
0183   BOOST_CHECK_EQUAL(vertices.size(), expectedVertices);
0184 }
0185 
0186 BOOST_AUTO_TEST_CASE(GenerateCircleEllipseVertices) {
0187   // Case (1): A full disc
0188   double ri = 0.;
0189   double ro = 10.;
0190 
0191   // Extreme points in phi - only outer radius
0192   auto vertices =
0193       VerticesHelper::circularVertices(ri, ro, 0., std::numbers::pi, 1u);
0194   unsigned int expectedVertices = 5u;
0195   BOOST_CHECK_EQUAL(vertices.size(), expectedVertices);
0196 
0197   // Case (2): A ring
0198   ri = 3.;
0199 
0200   // Extreme points in phi - only outer radius
0201   vertices = VerticesHelper::circularVertices(ri, ro, 0., std::numbers::pi, 1u);
0202   expectedVertices = 10u;
0203   BOOST_CHECK_EQUAL(vertices.size(), expectedVertices);
0204 
0205   // Now with 10 bins per sector
0206   ri = 0.;
0207 
0208   vertices =
0209       VerticesHelper::circularVertices(ri, ro, 0., std::numbers::pi, 10u);
0210   expectedVertices = 41u;  // 4 sectors + 1 overlap at (-pi/pi)
0211   BOOST_CHECK_EQUAL(vertices.size(), expectedVertices);
0212 
0213   // Now ellipsoid
0214   double riy = 4.;
0215   double roy = 14.;
0216   vertices = VerticesHelper::ellipsoidVertices(ri, riy, ro, roy, 0.,
0217                                                std::numbers::pi, 10u);
0218   expectedVertices = 41u;  // 4 sectors + 1 overlap at (-pi/pi)
0219   BOOST_CHECK_EQUAL(vertices.size(), expectedVertices);
0220 }
0221 
0222 BOOST_AUTO_TEST_SUITE_END()
0223 
0224 }  // namespace Acts::detail::Test