Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:11:21

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