Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-19 07:59:13

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