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/Units.hpp"
0012 #include "Acts/Geometry/DiamondVolumeBounds.hpp"
0013 #include "Acts/Geometry/TrackingVolume.hpp"
0014 #include "Acts/Surfaces/PlaneSurface.hpp"
0015 #include "Acts/Visualization/ObjVisualization3D.hpp"
0016 
0017 using namespace Acts;
0018 using namespace Acts::UnitLiterals;
0019 
0020 namespace ActsTests {
0021 
0022 GeometryContext gctx = GeometryContext();
0023 
0024 BOOST_AUTO_TEST_SUITE(GeometrySuite)
0025 BOOST_AUTO_TEST_CASE(DiamondVolumeBoundsCreation) {
0026   // Create a DiamondVolumeBounds
0027   double halfX1 = 10.0;
0028   double halfX2 = 12.0;
0029   double halfX3 = 12.0;
0030   double halfY1 = 5.0;
0031   double halfY2 = 10.0;
0032   double halfZ = 2.0;
0033 
0034   DiamondVolumeBounds polygonBounds(halfX1, halfX2, halfX3, halfY1, halfY2,
0035                                     halfZ);
0036 
0037   // Test correct parameter return
0038   BOOST_CHECK_EQUAL(polygonBounds.get(DiamondVolumeBounds::eHalfLengthX1),
0039                     halfX1);
0040   BOOST_CHECK_EQUAL(polygonBounds.get(DiamondVolumeBounds::eHalfLengthX2),
0041                     halfX2);
0042   BOOST_CHECK_EQUAL(polygonBounds.get(DiamondVolumeBounds::eHalfLengthX3),
0043                     halfX3);
0044   BOOST_CHECK_EQUAL(polygonBounds.get(DiamondVolumeBounds::eLengthY1), halfY1);
0045   BOOST_CHECK_EQUAL(polygonBounds.get(DiamondVolumeBounds::eLengthY2), halfY2);
0046   BOOST_CHECK_EQUAL(polygonBounds.get(DiamondVolumeBounds::eHalfLengthZ),
0047                     halfZ);
0048 
0049   BOOST_CHECK_EQUAL(polygonBounds.type(), VolumeBounds::eDiamond);
0050 
0051   // try to create a volume with this bounds and visualize it
0052 
0053   Transform3 transform = Transform3(Translation3(100., 25., -250.));
0054   // add a rotation also
0055   transform.rotate(AngleAxis3(30._degree, Vector3::UnitZ()));
0056 
0057   auto trackingVolume = std::make_unique<TrackingVolume>(
0058       transform, std::make_shared<DiamondVolumeBounds>(polygonBounds),
0059       "TestDiamondVolume");
0060 
0061   Acts::ObjVisualization3D helper;
0062   trackingVolume->visualize(helper, gctx, {.visible = true}, {.visible = true},
0063                             {.visible = true});
0064   helper.write(trackingVolume->volumeName() + ".obj");
0065 }
0066 BOOST_AUTO_TEST_CASE(DiamondVolumeBoundsInside) {
0067   // Create a DiamondVolumeBounds
0068   double halfX1 = 10.0;
0069   double halfX2 = 12.0;
0070   double halfX3 = 5.0;
0071   double halfY1 = 5.0;
0072   double halfY2 = 10.0;
0073   double halfZ = 2.0;
0074 
0075   DiamondVolumeBounds polygonBounds(halfX1, halfX2, halfX3, halfY1, halfY2,
0076                                     halfZ);
0077 
0078   // Points inside
0079   BOOST_CHECK(polygonBounds.inside(Vector3::Zero(), 0.1));
0080   BOOST_CHECK(polygonBounds.inside(Vector3(5.0, 2.0, 1.0), 0.1));
0081   BOOST_CHECK(polygonBounds.inside(Vector3(-5.0, -2.0, -1.0), 0.1));
0082   BOOST_CHECK(polygonBounds.inside(Vector3(8.5, 4.0, 0.0),
0083                                    0.0));  // check side inclided faces
0084 
0085   // Points outside
0086   BOOST_CHECK(!polygonBounds.inside(Vector3(15.0, 0.0, 0.0), 0.1));
0087   BOOST_CHECK(!polygonBounds.inside(Vector3(-13., 15.0, 0.0), 0.1));
0088   BOOST_CHECK(!polygonBounds.inside(Vector3(0.0, 0.0, 5.0), 0.1));
0089   BOOST_CHECK(!polygonBounds.inside(Vector3(-12., 5.0, 0.0), 0.1));
0090   BOOST_CHECK(!polygonBounds.inside(Vector3(8.5, 7.0, 0.0),
0091                                     0.0));  // check side inclided faces
0092 }
0093 
0094 BOOST_AUTO_TEST_CASE(DiamondBoundarySurfaces) {
0095   // Create a DiamondVolumeBounds
0096   double halfX1 = 10.0;
0097   double halfX2 = 12.0;
0098   double halfX3 = 8.0;
0099   double halfY1 = 5.0;
0100   double halfY2 = 10.0;
0101   double halfZ = 2.0;
0102 
0103   DiamondVolumeBounds polygonBounds(halfX1, halfX2, halfX3, halfY1, halfY2,
0104                                     halfZ);
0105 
0106   Transform3 transform = Transform3::Identity();
0107 
0108   auto surfaces = polygonBounds.orientedSurfaces(transform);
0109 
0110   // There should be 8 boundary surfaces
0111   BOOST_CHECK_EQUAL(surfaces.size(), 8);
0112 
0113   // Check if the normal vector is correct
0114   for (auto& os : surfaces) {
0115     auto osCenter = os.surface->center(gctx);
0116     // cast into PlaneSurface
0117     const auto* pSurface = dynamic_cast<const PlaneSurface*>(os.surface.get());
0118     BOOST_CHECK(pSurface != nullptr);
0119     auto osNormal = pSurface->normal(gctx);
0120     Vector3 insideTvb = osCenter + os.direction * osNormal;
0121     Vector3 outsideTvb = osCenter - os.direction * osNormal;
0122     BOOST_CHECK(polygonBounds.inside(insideTvb));
0123     BOOST_CHECK(!polygonBounds.inside(outsideTvb));
0124   }
0125 
0126   // Test orientation of the boundary surfaces
0127   const Vector3 xaxis = Vector3::UnitX();
0128   const Vector3 yaxis = Vector3::UnitY();
0129   const Vector3 zaxis = Vector3::UnitZ();
0130 
0131   using enum DiamondVolumeBounds::Face;
0132   using enum DiamondVolumeBounds::BoundValues;
0133 
0134   auto pFaceXY = surfaces[toUnderlying(PositiveZFaceXY)]
0135                      .surface->transform(gctx)
0136                      .rotation();
0137   BOOST_CHECK(pFaceXY.col(0).isApprox(xaxis));
0138   BOOST_CHECK(pFaceXY.col(1).isApprox(yaxis));
0139   BOOST_CHECK(pFaceXY.col(2).isApprox(zaxis));
0140 
0141   auto nFaceXY = surfaces[toUnderlying(NegativeZFaceXY)]
0142                      .surface->transform(gctx)
0143                      .rotation();
0144   BOOST_CHECK(nFaceXY.col(0).isApprox(xaxis));
0145   BOOST_CHECK(nFaceXY.col(1).isApprox(yaxis));
0146   BOOST_CHECK(nFaceXY.col(2).isApprox(zaxis));
0147 
0148   auto pFaceXZ = surfaces[toUnderlying(PositiveYFaceZX)]
0149                      .surface->transform(gctx)
0150                      .rotation();
0151   BOOST_CHECK(pFaceXZ.col(0).isApprox(zaxis));
0152   BOOST_CHECK(pFaceXZ.col(1).isApprox(xaxis));
0153   BOOST_CHECK(pFaceXZ.col(2).isApprox(yaxis));
0154 
0155   auto nFaceXZ = surfaces[toUnderlying(NegativeYFaceZX)]
0156                      .surface->transform(gctx)
0157                      .rotation();
0158   BOOST_CHECK(nFaceXZ.col(0).isApprox(zaxis));
0159   BOOST_CHECK(nFaceXZ.col(1).isApprox(xaxis));
0160   BOOST_CHECK(nFaceXZ.col(2).isApprox(yaxis));
0161 
0162   // these are the surfaces in positive y attached to x2 and x3 (rotation with
0163   // beta angle)
0164 
0165   auto pFaceYZ23 = surfaces[toUnderlying(PositiveXFaceYZ23)]
0166                        .surface->transform(gctx)
0167                        .rotation();
0168 
0169   // use the vertices to check the expected rotation
0170   Vector3 vertA(polygonBounds.get(eHalfLengthX3), polygonBounds.get(eLengthY2),
0171                 0.);
0172   Vector3 vertB(polygonBounds.get(eHalfLengthX2), 0., 0.);
0173 
0174   Vector3 vecAB = (vertA - vertB).normalized();
0175   BOOST_CHECK(pFaceYZ23.col(0).isApprox(vecAB));
0176   BOOST_CHECK(pFaceYZ23.col(1).isApprox(zaxis));
0177   BOOST_CHECK(pFaceYZ23.col(2).isApprox(vecAB.cross(zaxis)));
0178 
0179   // this is expected to be rotated by the beta angle (angle between x3 and x2
0180   // edges) along z axis
0181   auto nFaceYZ23 = surfaces[toUnderlying(NegativeXFaceYZ23)]
0182                        .surface->transform(gctx)
0183                        .rotation();
0184   vertA = Vector3(-polygonBounds.get(eHalfLengthX3),
0185                   polygonBounds.get(eLengthY2), 0.);
0186   vertB = Vector3(-polygonBounds.get(eHalfLengthX2), 0., 0.);
0187   vecAB = (vertA - vertB).normalized();
0188   BOOST_CHECK(nFaceYZ23.col(0).isApprox(vecAB));
0189   BOOST_CHECK(nFaceYZ23.col(1).isApprox(zaxis));
0190   BOOST_CHECK(nFaceYZ23.col(2).isApprox(vecAB.cross(zaxis)));
0191 
0192   // these are the face surfaces in negative y attached to x1 and x2 (rotation
0193   // with alpha angle)
0194   auto pFaceYZ12 = surfaces[toUnderlying(PositiveXFaceYZ12)]
0195                        .surface->transform(gctx)
0196                        .rotation();
0197 
0198   vertA = Vector3(polygonBounds.get(eHalfLengthX1),
0199                   -polygonBounds.get(eLengthY1), 0.);
0200   vertB = Vector3(polygonBounds.get(eHalfLengthX2), 0., 0.);
0201   vecAB = (vertA - vertB).normalized();
0202   BOOST_CHECK(pFaceYZ12.col(0).isApprox(-vecAB));
0203   BOOST_CHECK(pFaceYZ12.col(1).isApprox(zaxis));
0204   BOOST_CHECK(pFaceYZ12.col(2).isApprox(vecAB.cross(-zaxis)));
0205 
0206   auto nFaceYZ12 = surfaces[toUnderlying(NegativeXFaceYZ12)]
0207                        .surface->transform(gctx)
0208                        .rotation();
0209   vertA = Vector3(-polygonBounds.get(eHalfLengthX1),
0210                   -polygonBounds.get(eLengthY1), 0.);
0211   vertB = Vector3(-polygonBounds.get(eHalfLengthX2), 0., 0.);
0212   vecAB = (vertA - vertB).normalized();
0213   BOOST_CHECK(nFaceYZ12.col(0).isApprox(-vecAB));
0214   BOOST_CHECK(nFaceYZ12.col(1).isApprox(zaxis));
0215   BOOST_CHECK(nFaceYZ12.col(2).isApprox(vecAB.cross(-zaxis)));
0216 }
0217 BOOST_AUTO_TEST_SUITE_END()
0218 }  // namespace ActsTests