Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-01-06 09:23:52

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/Definitions/Direction.hpp"
0013 #include "Acts/Geometry/GenericCuboidVolumeBounds.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Surfaces/PlanarBounds.hpp"
0016 #include "Acts/Surfaces/PlaneSurface.hpp"
0017 #include "Acts/Surfaces/Surface.hpp"
0018 #include "Acts/Surfaces/SurfaceBounds.hpp"
0019 #include "Acts/Utilities/BoundingBox.hpp"
0020 #include "Acts/Utilities/Helpers.hpp"
0021 #include "Acts/Visualization/IVisualization3D.hpp"
0022 #include "Acts/Visualization/PlyVisualization3D.hpp"
0023 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0024 
0025 #include <array>
0026 #include <cmath>
0027 #include <fstream>
0028 #include <memory>
0029 #include <numbers>
0030 #include <utility>
0031 #include <vector>
0032 
0033 using namespace Acts;
0034 
0035 namespace ActsTests {
0036 
0037 GeometryContext gctx = GeometryContext();
0038 
0039 BOOST_AUTO_TEST_SUITE(GeometrySuite)
0040 
0041 BOOST_AUTO_TEST_CASE(construction_test) {
0042   std::array<Vector3, 8> vertices{};
0043   vertices = {{{0, 0, 0},
0044                {2, 0, 0},
0045                {2, 1, 0},
0046                {0, 1, 0},
0047                {0, 0, 1},
0048                {2, 0, 1},
0049                {2, 1, 1},
0050                {0, 1, 1}}};
0051   GenericCuboidVolumeBounds cubo(vertices);
0052 
0053   BOOST_CHECK(cubo.inside({0.5, 0.5, 0.5}));
0054   BOOST_CHECK(cubo.inside({1.5, 0.5, 0.5}));
0055   BOOST_CHECK(!cubo.inside({2.5, 0.5, 0.5}));
0056   BOOST_CHECK(!cubo.inside({0.5, 1.5, 0.5}));
0057   BOOST_CHECK(!cubo.inside({0.5, 0.5, 1.5}));
0058   BOOST_CHECK(!cubo.inside({-0.5, 0.5, 0.5}));
0059 
0060   BOOST_CHECK(!cubo.inside({2.2, 1, 1}, 0.1));
0061   BOOST_CHECK(cubo.inside({2.2, 1, 1}, 0.21));
0062   BOOST_CHECK(cubo.inside({2.2, 1, 1}, 0.3));
0063 }
0064 
0065 BOOST_AUTO_TEST_CASE(GenericCuboidBoundsOrientedSurfaces) {
0066   std::array<Vector3, 8> vertices{};
0067   vertices = {{{0, 0, 0},
0068                {2, 0, 0},
0069                {2, 1, 0},
0070                {0, 1, 0},
0071                {0, 0, 1},
0072                {2, 0, 1},
0073                {2, 1, 1},
0074                {0, 1, 1}}};
0075   GenericCuboidVolumeBounds cubo(vertices);
0076 
0077   auto is_in = [](const auto& tvtx, const auto& vertices_) {
0078     for (const auto& vtx : vertices_) {
0079       if (checkCloseAbs(vtx, tvtx, 1e-9)) {
0080         return true;
0081       }
0082     }
0083     return false;
0084   };
0085 
0086   auto surfaces = cubo.orientedSurfaces(Transform3::Identity());
0087   for (const auto& srf : surfaces) {
0088     auto pbounds = dynamic_cast<const PlanarBounds*>(&srf.surface->bounds());
0089     for (const auto& vtx : pbounds->vertices()) {
0090       Vector3 glob = srf.surface->localToGlobal(gctx, vtx, {});
0091       // check if glob is in actual vertex list
0092       BOOST_CHECK(is_in(glob, vertices));
0093     }
0094   }
0095 
0096   vertices = {{{0, 0, 0},
0097                {2, 0, 0.4},
0098                {2, 1, 0.4},
0099                {0, 1, 0},
0100                {0, 0, 1},
0101                {1.8, 0, 1},
0102                {1.8, 1, 1},
0103                {0, 1, 1}}};
0104   cubo = GenericCuboidVolumeBounds(vertices);
0105 
0106   surfaces = cubo.orientedSurfaces(Transform3::Identity());
0107   for (const auto& srf : surfaces) {
0108     auto pbounds = dynamic_cast<const PlanarBounds*>(&srf.surface->bounds());
0109     for (const auto& vtx : pbounds->vertices()) {
0110       Vector3 glob = srf.surface->localToGlobal(gctx, vtx, {});
0111       // check if glob is in actual vertex list
0112       BOOST_CHECK(is_in(glob, vertices));
0113     }
0114   }
0115 
0116   Transform3 trf;
0117   trf = Translation3(Vector3(0, 8, -5)) *
0118         AngleAxis3(std::numbers::pi / 3., Vector3(1, -3, 9).normalized());
0119 
0120   surfaces = cubo.orientedSurfaces(trf);
0121   for (const auto& srf : surfaces) {
0122     auto pbounds = dynamic_cast<const PlanarBounds*>(&srf.surface->bounds());
0123     for (const auto& vtx : pbounds->vertices()) {
0124       Vector3 glob = srf.surface->localToGlobal(gctx, vtx, {});
0125       // check if glob is in actual vertex list
0126       BOOST_CHECK(is_in(trf.inverse() * glob, vertices));
0127     }
0128   }
0129 }
0130 
0131 BOOST_AUTO_TEST_CASE(ply_test) {
0132   std::array<Vector3, 8> vertices{};
0133   vertices = {{{0, 0, 0},
0134                {2, 0, 0},
0135                {2, 1, 0},
0136                {0, 1, 0},
0137                {0, 0, 1},
0138                {2, 0, 1},
0139                {2, 1, 1},
0140                {0, 1, 1}}};
0141   GenericCuboidVolumeBounds cubo(vertices);
0142   PlyVisualization3D<double> ply;
0143   cubo.draw(ply);
0144 
0145   std::ofstream os("cuboid.ply");
0146   os << ply << std::flush;
0147   os.close();
0148 }
0149 
0150 BOOST_AUTO_TEST_CASE(bounding_box_creation) {
0151   float tol = 1e-4;
0152   std::array<Vector3, 8> vertices{};
0153   vertices = {{{0, 0, 0},
0154                {2, 0, 0.4},
0155                {2, 1, 0.4},
0156                {0, 1, 0},
0157                {0, 0, 1},
0158                {1.8, 0, 1},
0159                {1.8, 1, 1},
0160                {0, 1, 1}}};
0161 
0162   GenericCuboidVolumeBounds gcvb(vertices);
0163   auto bb = gcvb.boundingBox();
0164 
0165   Transform3 rot;
0166   rot = AngleAxis3(std::numbers::pi / 2., Vector3::UnitX());
0167 
0168   BOOST_CHECK_EQUAL(bb.entity(), nullptr);
0169   BOOST_CHECK_EQUAL(bb.max(), Vector3(2, 1, 1));
0170   BOOST_CHECK_EQUAL(bb.min(), Vector3(0., 0., 0.));
0171 
0172   bb = gcvb.boundingBox(&rot);
0173 
0174   BOOST_CHECK_EQUAL(bb.entity(), nullptr);
0175   CHECK_CLOSE_ABS(bb.max(), Vector3(2, 0, 1), tol);
0176   BOOST_CHECK_EQUAL(bb.min(), Vector3(0, -1, 0));
0177 
0178   rot = AngleAxis3(std::numbers::pi / 2., Vector3::UnitZ());
0179   bb = gcvb.boundingBox(&rot);
0180   BOOST_CHECK_EQUAL(bb.entity(), nullptr);
0181   CHECK_CLOSE_ABS(bb.max(), Vector3(0, 2, 1), tol);
0182   CHECK_CLOSE_ABS(bb.min(), Vector3(-1, 0., 0.), tol);
0183 
0184   rot = AngleAxis3(0.542, Vector3::UnitZ()) *
0185         AngleAxis3(std::numbers::pi / 5., Vector3(1, 3, 6).normalized());
0186 
0187   bb = gcvb.boundingBox(&rot);
0188   BOOST_CHECK_EQUAL(bb.entity(), nullptr);
0189   CHECK_CLOSE_ABS(bb.max(), Vector3(1.00976, 2.26918, 1.11988), tol);
0190   CHECK_CLOSE_ABS(bb.min(), Vector3(-0.871397, 0, -0.0867708), tol);
0191 
0192   // Check recreation from bound values
0193   const auto boundValues = gcvb.values();
0194   BOOST_CHECK_EQUAL(boundValues.size(), 24u);
0195 
0196   auto bValueArrray =
0197       toArray<GenericCuboidVolumeBounds::BoundValues::eSize, double>(
0198           boundValues);
0199   GenericCuboidVolumeBounds gcvbCopy(bValueArrray);
0200   BOOST_CHECK_EQUAL(gcvbCopy.values().size(), 24u);
0201 
0202   // Redo the check from above
0203   rot = AngleAxis3(0.542, Vector3::UnitZ()) *
0204         AngleAxis3(std::numbers::pi / 5., Vector3(1, 3, 6).normalized());
0205 
0206   bb = gcvbCopy.boundingBox(&rot);
0207   BOOST_CHECK_EQUAL(bb.entity(), nullptr);
0208   CHECK_CLOSE_ABS(bb.max(), Vector3(1.00976, 2.26918, 1.11988), tol);
0209   CHECK_CLOSE_ABS(bb.min(), Vector3(-0.871397, 0, -0.0867708), tol);
0210 }
0211 
0212 BOOST_AUTO_TEST_CASE(GenericCuboidVolumeBoundarySurfaces) {
0213   std::array<Vector3, 8> vertices{};
0214   vertices = {{{0, 0, 0},
0215                {4, 0, 0},
0216                {4, 2, 0},
0217                {0, 2, 0},
0218                {0, 0, 2},
0219                {4, 0, 2},
0220                {4, 2, 2},
0221                {0, 2, 2}}};
0222 
0223   GenericCuboidVolumeBounds cubo(vertices);
0224 
0225   auto gcvbOrientedSurfaces = cubo.orientedSurfaces(Transform3::Identity());
0226   BOOST_CHECK_EQUAL(gcvbOrientedSurfaces.size(), 6);
0227 
0228   for (auto& os : gcvbOrientedSurfaces) {
0229     auto geoCtx = GeometryContext();
0230     auto osCenter = os.surface->center(geoCtx);
0231     const auto* pSurface = dynamic_cast<const PlaneSurface*>(os.surface.get());
0232     BOOST_REQUIRE_MESSAGE(pSurface != nullptr,
0233                           "The surface is not a plane surface");
0234     auto osNormal = pSurface->normal(geoCtx);
0235     // Check if you step inside the volume with the oriented normal
0236     Vector3 insideGcvb = osCenter + os.direction * osNormal;
0237     Vector3 outsideGcvb = osCenter - os.direction * osNormal;
0238     BOOST_CHECK(cubo.inside(insideGcvb));
0239     BOOST_CHECK(!cubo.inside(outsideGcvb));
0240   }
0241 }
0242 
0243 BOOST_AUTO_TEST_SUITE_END()
0244 }  // namespace ActsTests