Back to home page

EIC code displayed by LXR

 
 

    


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

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