Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:25:36

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/Tolerance.hpp"
0013 #include "Acts/Geometry/GeometryContext.hpp"
0014 #include "Acts/Surfaces/RectangleBounds.hpp"
0015 #include "Acts/Surfaces/Surface.hpp"
0016 #include "Acts/Surfaces/SurfaceBounds.hpp"
0017 #include "Acts/Visualization/GeometryView3D.hpp"
0018 #include "Acts/Visualization/ObjVisualization3D.hpp"
0019 #include "Acts/Visualization/ViewConfig.hpp"
0020 #include "ActsPlugins/Root/TGeoSurfaceConverter.hpp"
0021 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0022 
0023 #include <memory>
0024 #include <utility>
0025 
0026 #include "TGeoBBox.h"
0027 #include "TGeoManager.h"
0028 #include "TGeoMaterial.h"
0029 #include "TGeoMatrix.h"
0030 #include "TGeoMedium.h"
0031 #include "TGeoVolume.h"
0032 #include "TView.h"
0033 
0034 using namespace Acts;
0035 using namespace ActsPlugins;
0036 
0037 namespace ActsTests {
0038 
0039 GeometryContext tgContext = GeometryContext();
0040 
0041 ViewConfig red{.color = {200, 0, 0}};
0042 ViewConfig green{.color = {0, 200, 0}};
0043 ViewConfig blue{.color = {0, 0, 200}};
0044 
0045 BOOST_AUTO_TEST_SUITE(RootSuite)
0046 
0047 /// @brief Unit test to convert a Bbox into a Plane
0048 ///
0049 /// This test also tests:
0050 /// * the "(x/X)(y/Y)(z/Z)" orientations
0051 /// * the scaling functionality
0052 BOOST_AUTO_TEST_CASE(TGeoBBox_to_PlaneSurface) {
0053   ObjVisualization3D objVis;
0054 
0055   // BBox is defined [-dX,dX] x [-dY,dY] x [-dZ,dZ]
0056   double dX = 10.;
0057   double dY = 30.;
0058   double dZ = 1.;
0059 
0060   new TGeoManager("box", "poza1");
0061   TGeoMaterial *mat = new TGeoMaterial("Al", 26.98, 13, 2.7);
0062   TGeoMedium *med = new TGeoMedium("MED", 1, mat);
0063   TGeoVolume *top = gGeoManager->MakeBox("TOP", med, 100, 100, 100);
0064   gGeoManager->SetTopVolume(top);
0065   TGeoVolume *vol = gGeoManager->MakeBox("BOX", med, dX, dY, dZ);
0066   vol->SetLineWidth(2);
0067   top->AddNode(vol, 1);
0068   gGeoManager->CloseGeometry();
0069 
0070   // Upper case ---------------------------------
0071   auto [plane_XYZ, thickness_XYZ] = TGeoSurfaceConverter::toSurface(
0072       *vol->GetShape(), *gGeoIdentity, "XY*", 1);
0073   BOOST_REQUIRE_NE(plane_XYZ, nullptr);
0074   BOOST_CHECK_EQUAL(plane_XYZ->type(), Surface::Plane);
0075   CHECK_CLOSE_ABS(thickness_XYZ, 2 * dZ, s_epsilon);
0076 
0077   auto bounds_XYZ =
0078       dynamic_cast<const RectangleBounds *>(&(plane_XYZ->bounds()));
0079   BOOST_REQUIRE_NE(bounds_XYZ, nullptr);
0080   double maxX = bounds_XYZ->get(RectangleBounds::eMaxX);
0081   double minX = bounds_XYZ->get(RectangleBounds::eMinX);
0082   double maxY = bounds_XYZ->get(RectangleBounds::eMaxY);
0083   double minY = bounds_XYZ->get(RectangleBounds::eMinY);
0084   CHECK_CLOSE_ABS(maxX - minX, 2 * dX, s_epsilon);
0085   CHECK_CLOSE_ABS(maxY - minY, 2 * dY, s_epsilon);
0086 
0087   // Check if the surface is the (negative) identity
0088   auto transform_XYZ = plane_XYZ->transform(tgContext);
0089   auto rotation_XYZ = transform_XYZ.rotation();
0090   BOOST_CHECK(transform_XYZ.isApprox(Transform3::Identity()));
0091 
0092   const Vector3 offset_XYZ{-5.5 * dX, 0., 0.};
0093   GeometryView3D::drawSurface(objVis, *plane_XYZ, tgContext,
0094                               Transform3(Translation3{offset_XYZ}));
0095   const Vector3 center_XYZ = plane_XYZ->center(tgContext) + offset_XYZ;
0096   GeometryView3D::drawArrowForward(
0097       objVis, center_XYZ,
0098       center_XYZ + 0.6 * (maxX - minX) * rotation_XYZ.col(0), 4., 2.5, red);
0099   GeometryView3D::drawArrowForward(
0100       objVis, center_XYZ,
0101       center_XYZ + 0.6 * (maxY - minY) * rotation_XYZ.col(1), 4., 2.5, green);
0102   GeometryView3D::drawArrowForward(
0103       objVis, center_XYZ, center_XYZ + 2 * rotation_XYZ.col(2), 4., 2.5, blue);
0104 
0105   // Lower case ---------------------------------
0106   auto [plane_xyz, thickness_xyz] = TGeoSurfaceConverter::toSurface(
0107       *vol->GetShape(), *gGeoIdentity, "xy*", 1);
0108   BOOST_CHECK_NE(plane_xyz, nullptr);
0109   BOOST_CHECK_EQUAL(plane_xyz->type(), Surface::Plane);
0110   CHECK_CLOSE_ABS(thickness_xyz, 2 * dZ, s_epsilon);
0111 
0112   auto bounds_xyz =
0113       dynamic_cast<const RectangleBounds *>(&(plane_XYZ->bounds()));
0114   BOOST_REQUIRE_NE(bounds_xyz, nullptr);
0115   BOOST_CHECK_EQUAL(bounds_xyz, bounds_XYZ);
0116   auto transform_xyz = plane_xyz->transform(tgContext);
0117   auto rotation_xyz = transform_xyz.rotation();
0118   BOOST_CHECK(rotation_xyz.col(0).isApprox(-1 * rotation_XYZ.col(0)));
0119   BOOST_CHECK(rotation_xyz.col(1).isApprox(-1 * rotation_XYZ.col(1)));
0120   BOOST_CHECK(rotation_xyz.col(2).isApprox(rotation_XYZ.col(2)));
0121 
0122   const Vector3 offset_xyz{-2 * dX, 0., 0.};
0123   GeometryView3D::drawSurface(objVis, *plane_xyz, tgContext,
0124                               Transform3(Translation3{offset_xyz}));
0125   const Vector3 center_xyz = plane_xyz->center(tgContext) + offset_xyz;
0126   GeometryView3D::drawArrowForward(
0127       objVis, center_xyz,
0128       center_xyz + 0.6 * (maxX - minX) * rotation_xyz.col(0), 4., 2.5, red);
0129   GeometryView3D::drawArrowForward(
0130       objVis, center_xyz,
0131       center_xyz + 0.6 * (maxY - minY) * rotation_xyz.col(1), 4., 2.5, green);
0132   GeometryView3D::drawArrowForward(
0133       objVis, center_xyz, center_xyz + 2 * rotation_xyz.col(2), 4., 2.5, blue);
0134 
0135   // Mixed case ---------------------------------
0136   auto [plane_xYz, thickness_xYz] = TGeoSurfaceConverter::toSurface(
0137       *vol->GetShape(), *gGeoIdentity, "xY*", 1);
0138   BOOST_REQUIRE_NE(plane_xYz, nullptr);
0139   BOOST_CHECK_EQUAL(plane_xYz->type(), Surface::Plane);
0140   CHECK_CLOSE_ABS(thickness_xYz, 2 * dZ, s_epsilon);
0141 
0142   auto bounds_xYz =
0143       dynamic_cast<const RectangleBounds *>(&(plane_xYz->bounds()));
0144   BOOST_CHECK_NE(bounds_xYz, nullptr);
0145   BOOST_CHECK_EQUAL(bounds_xYz, bounds_xYz);
0146   auto transform_xYz = plane_xYz->transform(tgContext);
0147   auto rotation_xYz = transform_xYz.rotation();
0148   BOOST_CHECK(rotation_xYz.col(0).isApprox(-1 * rotation_XYZ.col(0)));
0149   BOOST_CHECK(rotation_xYz.col(1).isApprox(rotation_XYZ.col(1)));
0150   BOOST_CHECK(rotation_xYz.col(2).isApprox(-1. * rotation_XYZ.col(2)));
0151 
0152   const Vector3 offset_xYz{2 * dX, 0., 0.};
0153   GeometryView3D::drawSurface(
0154       objVis, *plane_xYz, tgContext,
0155       Translation3{offset_xYz} * Transform3::Identity());
0156   const Vector3 center_xYz = plane_xYz->center(tgContext) + offset_xYz;
0157   GeometryView3D::drawArrowForward(
0158       objVis, center_xYz,
0159       center_xYz + 0.6 * (maxX - minX) * rotation_xYz.col(0), 4., 2.5, red);
0160   GeometryView3D::drawArrowForward(
0161       objVis, center_xYz,
0162       center_xYz + 0.6 * (maxY - minY) * rotation_xYz.col(1), 4., 2.5, green);
0163   GeometryView3D::drawArrowForward(
0164       objVis, center_xYz, center_xYz + 2 * rotation_xYz.col(2), 4., 2.5, blue);
0165 
0166   // Swap case --------------------------------- (x/y) here
0167   auto [plane_YXz, thickness_YXz] = TGeoSurfaceConverter::toSurface(
0168       *vol->GetShape(), *gGeoIdentity, "YX*", 1);
0169   BOOST_REQUIRE_NE(plane_YXz, nullptr);
0170   BOOST_CHECK_EQUAL(plane_YXz->type(), Surface::Plane);
0171   CHECK_CLOSE_ABS(thickness_YXz, 2 * dZ, s_epsilon);
0172 
0173   auto bounds_YXz =
0174       dynamic_cast<const RectangleBounds *>(&(plane_YXz->bounds()));
0175   maxX = bounds_YXz->get(RectangleBounds::eMaxX);
0176   minX = bounds_YXz->get(RectangleBounds::eMinX);
0177   maxY = bounds_YXz->get(RectangleBounds::eMaxY);
0178   minY = bounds_YXz->get(RectangleBounds::eMinY);
0179   CHECK_CLOSE_ABS(maxX - minX, 2 * dY, s_epsilon);
0180   CHECK_CLOSE_ABS(maxY - minY, 2 * dX, s_epsilon);
0181 
0182   auto transform_YXz = plane_YXz->transform(tgContext);
0183   auto rotation_YXz = transform_YXz.rotation();
0184   BOOST_CHECK(rotation_YXz.col(0).isApprox(rotation_XYZ.col(1)));
0185   BOOST_CHECK(rotation_YXz.col(1).isApprox(rotation_XYZ.col(0)));
0186   BOOST_CHECK(rotation_YXz.col(2).isApprox(-1. * rotation_XYZ.col(2)));
0187 
0188   const Vector3 offset_YXz{5.5 * dX, 0., 0.};
0189   GeometryView3D::drawSurface(objVis, *plane_YXz, tgContext,
0190                               Transform3(Translation3{offset_YXz}));
0191   const Vector3 center_YXz = plane_YXz->center(tgContext) + offset_YXz;
0192   GeometryView3D::drawArrowForward(
0193       objVis, center_YXz,
0194       center_YXz + 0.6 * (maxX - minX) * rotation_YXz.col(0), 4., 2.5, red);
0195   GeometryView3D::drawArrowForward(
0196       objVis, center_YXz,
0197       center_YXz + 0.6 * (maxY - minY) * rotation_YXz.col(1), 4., 2.5, green);
0198   GeometryView3D::drawArrowForward(
0199       objVis, center_YXz, center_YXz + 2 * rotation_YXz.col(2), 4., 2.5, blue);
0200 
0201   // Scaling test ---------------------------------
0202   auto [plane_XYZ10, thickness_XYZ10] = TGeoSurfaceConverter::toSurface(
0203       *vol->GetShape(), *gGeoIdentity, "xY*", 10);
0204   BOOST_CHECK_NE(plane_XYZ10, nullptr);
0205   CHECK_CLOSE_ABS(thickness_XYZ10, 20 * dZ, s_epsilon);
0206 
0207   auto bounds_XYZ10 =
0208       dynamic_cast<const RectangleBounds *>(&(plane_XYZ10->bounds()));
0209   double maxX10 = bounds_XYZ10->get(RectangleBounds::eMaxX);
0210   double minX10 = bounds_XYZ10->get(RectangleBounds::eMinX);
0211   double maxY10 = bounds_XYZ10->get(RectangleBounds::eMaxY);
0212   double minY10 = bounds_XYZ10->get(RectangleBounds::eMinY);
0213   CHECK_CLOSE_ABS(maxX10 - minX10, 20 * dX, s_epsilon);
0214   CHECK_CLOSE_ABS(maxY10 - minY10, 20 * dY, s_epsilon);
0215 
0216   objVis.write("TGeoConversion_TGeoBBox_PlaneSurface");
0217 }
0218 
0219 BOOST_AUTO_TEST_SUITE_END()
0220 
0221 }  // namespace ActsTests