File indexing completed on 2025-08-06 08:11:45
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/data/test_case.hpp>
0010 #include <boost/test/unit_test.hpp>
0011
0012 #include "Acts/Definitions/Algebra.hpp"
0013 #include "Acts/Definitions/Tolerance.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/Plugins/TGeo/TGeoSurfaceConverter.hpp"
0016 #include "Acts/Surfaces/CylinderBounds.hpp"
0017 #include "Acts/Surfaces/RadialBounds.hpp"
0018 #include "Acts/Surfaces/Surface.hpp"
0019 #include "Acts/Surfaces/SurfaceBounds.hpp"
0020 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0021 #include "Acts/Visualization/GeometryView3D.hpp"
0022 #include "Acts/Visualization/ObjVisualization3D.hpp"
0023 #include "Acts/Visualization/ViewConfig.hpp"
0024
0025 #include <cmath>
0026 #include <cstddef>
0027 #include <memory>
0028 #include <stdexcept>
0029 #include <string>
0030 #include <vector>
0031
0032 #include "TGeoManager.h"
0033 #include "TGeoMaterial.h"
0034 #include "TGeoMatrix.h"
0035 #include "TGeoMedium.h"
0036 #include "TGeoTube.h"
0037 #include "TGeoVolume.h"
0038 #include "TView.h"
0039
0040 namespace Acts::Test {
0041
0042 GeometryContext tgContext = GeometryContext();
0043
0044 ViewConfig red({200, 0, 0});
0045 ViewConfig green({0, 200, 0});
0046 ViewConfig blue({0, 0, 200});
0047
0048 std::vector<std::string> allowedAxes = {"XY*", "Xy*", "xy*", "xY*",
0049 "YX*", "yx*", "yX*", "Yx*"};
0050
0051 std::vector<std::string> notAllowedAxes = {"YZ*", "ZX*", "ZY*"};
0052
0053
0054
0055
0056 BOOST_AUTO_TEST_CASE(TGeoTube_to_CylinderSurface) {
0057 ObjVisualization3D objVis;
0058
0059 double rmin = 10.;
0060 double rmax = 11;
0061 double hz = 40.;
0062 double phimin = 45.;
0063 double phimax = -45.;
0064
0065 new TGeoManager("trd1", "poza9");
0066 TGeoMaterial *mat = new TGeoMaterial("Al", 26.98, 13, 2.7);
0067 TGeoMedium *med = new TGeoMedium("MED", 1, mat);
0068 TGeoVolume *top = gGeoManager->MakeBox("TOP", med, 100, 100, 100);
0069 gGeoManager->SetTopVolume(top);
0070 TGeoVolume *vol = gGeoManager->MakeTube("Tube", med, rmin, rmax, hz);
0071 TGeoVolume *vols =
0072 gGeoManager->MakeTubs("Tube", med, rmin, rmax, hz, phimin, phimax);
0073 gGeoManager->CloseGeometry();
0074
0075 std::size_t icyl = 0;
0076 for (const auto &axes : allowedAxes) {
0077 auto [cylinder, thickness] = TGeoSurfaceConverter::toSurface(
0078 *vol->GetShape(), *gGeoIdentity, axes, 1);
0079 BOOST_REQUIRE_NE(cylinder, nullptr);
0080 BOOST_CHECK_EQUAL(cylinder->type(), Surface::Cylinder);
0081 CHECK_CLOSE_ABS(thickness, rmax - rmin, s_epsilon);
0082
0083 auto bounds = dynamic_cast<const CylinderBounds *>(&(cylinder->bounds()));
0084 BOOST_REQUIRE_NE(bounds, nullptr);
0085 double bR = bounds->get(CylinderBounds::eR);
0086 double bhZ = bounds->get(CylinderBounds::eHalfLengthZ);
0087
0088 CHECK_CLOSE_ABS(bR, 10.5, s_epsilon);
0089 CHECK_CLOSE_ABS(bhZ, hz, s_epsilon);
0090
0091 auto transform = cylinder->transform(tgContext);
0092 auto rotation = transform.rotation();
0093
0094
0095 GeometryView3D::drawSurface(objVis, *cylinder, tgContext);
0096 const Vector3 center = cylinder->center(tgContext);
0097 GeometryView3D::drawArrowForward(
0098 objVis, center, center + 1.2 * bR * rotation.col(0), 4., 2.5, red);
0099 GeometryView3D::drawArrowForward(
0100 objVis, center, center + 1.2 * bR * rotation.col(1), 4., 2.5, green);
0101 GeometryView3D::drawArrowForward(
0102 objVis, center, center + 1.2 * bhZ * rotation.col(2), 4., 2.5, blue);
0103
0104 objVis.write("TGeoConversion_TGeoTube_CylinderSurface_" +
0105 std::to_string(icyl));
0106 objVis.clear();
0107
0108 if (icyl < 2) {
0109 auto [cylinderSegment, cThickness] = TGeoSurfaceConverter::toSurface(
0110 *vols->GetShape(), *gGeoIdentity, axes, 1);
0111 BOOST_REQUIRE_NE(cylinderSegment, nullptr);
0112 BOOST_CHECK_EQUAL(cylinderSegment->type(), Surface::Cylinder);
0113 CHECK_CLOSE_ABS(cThickness, rmax - rmin, s_epsilon);
0114
0115 auto boundsSegment =
0116 dynamic_cast<const CylinderBounds *>(&(cylinderSegment->bounds()));
0117 BOOST_REQUIRE_NE(boundsSegment, nullptr);
0118 bR = boundsSegment->get(CylinderBounds::eR);
0119 bhZ = boundsSegment->get(CylinderBounds::eHalfLengthZ);
0120 double hphi = boundsSegment->get(CylinderBounds::eHalfPhiSector);
0121 double mphi = boundsSegment->get(CylinderBounds::eAveragePhi);
0122 CHECK_CLOSE_ABS(bR, 10.5, s_epsilon);
0123 CHECK_CLOSE_ABS(bhZ, hz, s_epsilon);
0124 CHECK_CLOSE_ABS(hphi, 0.25 * M_PI, s_epsilon);
0125 CHECK_CLOSE_ABS(mphi, 0., s_epsilon);
0126 GeometryView3D::drawSurface(objVis, *cylinderSegment, tgContext);
0127 GeometryView3D::drawArrowForward(
0128 objVis, center, center + 1.2 * bR * rotation.col(0), 4., 2.5, red);
0129 GeometryView3D::drawArrowForward(
0130 objVis, center, center + 1.2 * bR * rotation.col(1), 4., 2.5, green);
0131 GeometryView3D::drawArrowForward(
0132 objVis, center, center + 1.2 * bhZ * rotation.col(2), 4., 2.5, blue);
0133 objVis.write("TGeoConversion_TGeoTube_CylinderSegmentSurface_" +
0134 std::to_string(icyl));
0135 objVis.clear();
0136 } else {
0137 BOOST_CHECK_THROW(TGeoSurfaceConverter::toSurface(*vols->GetShape(),
0138 *gGeoIdentity, axes, 1),
0139 std::invalid_argument);
0140 }
0141 ++icyl;
0142 }
0143
0144
0145 for (const auto &naxes : notAllowedAxes) {
0146 BOOST_CHECK_THROW(TGeoSurfaceConverter::toSurface(*vol->GetShape(),
0147 *gGeoIdentity, naxes, 1),
0148 std::invalid_argument);
0149 }
0150 }
0151
0152
0153
0154
0155 BOOST_AUTO_TEST_CASE(TGeoTube_to_DiscSurface) {
0156 ObjVisualization3D objVis;
0157
0158 double rmin = 5.;
0159 double rmax = 25;
0160 double hz = 2.;
0161 double phimin = 45.;
0162 double phimax = -45.;
0163
0164 new TGeoManager("trd1", "poza9");
0165 TGeoMaterial *mat = new TGeoMaterial("Al", 26.98, 13, 2.7);
0166 TGeoMedium *med = new TGeoMedium("MED", 1, mat);
0167 TGeoVolume *top = gGeoManager->MakeBox("TOP", med, 100, 100, 100);
0168 gGeoManager->SetTopVolume(top);
0169 TGeoVolume *vol = gGeoManager->MakeTube("Tube", med, rmin, rmax, hz);
0170 vol->SetLineWidth(2);
0171 TGeoVolume *vols =
0172 gGeoManager->MakeTubs("Tube", med, rmin, rmax, hz, phimin, phimax);
0173 gGeoManager->CloseGeometry();
0174
0175 std::size_t idisc = 0;
0176 for (const auto &axes : allowedAxes) {
0177 auto [disc, thickness] = TGeoSurfaceConverter::toSurface(
0178 *vol->GetShape(), *gGeoIdentity, axes, 1);
0179 BOOST_REQUIRE_NE(disc, nullptr);
0180 BOOST_CHECK_EQUAL(disc->type(), Surface::Disc);
0181 CHECK_CLOSE_ABS(thickness, 2 * hz, s_epsilon);
0182
0183 auto bounds = dynamic_cast<const RadialBounds *>(&(disc->bounds()));
0184 BOOST_REQUIRE_NE(bounds, nullptr);
0185 double bminr = bounds->get(RadialBounds::eMinR);
0186 double bmaxr = bounds->get(RadialBounds::eMaxR);
0187
0188 CHECK_CLOSE_ABS(bminr, rmin, s_epsilon);
0189 CHECK_CLOSE_ABS(bmaxr, rmax, s_epsilon);
0190
0191
0192 GeometryView3D::drawSurface(objVis, *disc, tgContext);
0193 const Vector3 center = disc->center(tgContext);
0194 GeometryView3D::drawArrowForward(
0195 objVis, center, center + 1.2 * rmax * Vector3::UnitX(), 4., 2.5, red);
0196 GeometryView3D::drawArrowForward(
0197 objVis, center, center + 1.2 * rmax * Vector3::UnitY(), 4., 2.5, green);
0198 GeometryView3D::drawArrowForward(
0199 objVis, center, center + 1.2 * hz * Vector3::UnitZ(), 4., 2.5, blue);
0200 objVis.write("TGeoConversion_TGeoTube_DiscSurface_" +
0201 std::to_string(idisc));
0202 objVis.clear();
0203
0204 if (idisc < 2) {
0205 auto [discSegment, dThickness] = TGeoSurfaceConverter::toSurface(
0206 *vols->GetShape(), *gGeoIdentity, axes, 1);
0207 BOOST_REQUIRE_NE(discSegment, nullptr);
0208 BOOST_CHECK_EQUAL(discSegment->type(), Surface::Disc);
0209 CHECK_CLOSE_ABS(dThickness, 2 * hz, s_epsilon);
0210
0211 auto boundsSegment =
0212 dynamic_cast<const RadialBounds *>(&(discSegment->bounds()));
0213 BOOST_REQUIRE_NE(boundsSegment, nullptr);
0214 bminr = boundsSegment->get(RadialBounds::eMinR);
0215 bmaxr = boundsSegment->get(RadialBounds::eMaxR);
0216 double hphi = boundsSegment->get(RadialBounds::eHalfPhiSector);
0217 double mphi = boundsSegment->get(RadialBounds::eAveragePhi);
0218 CHECK_CLOSE_ABS(bminr, rmin, s_epsilon);
0219 CHECK_CLOSE_ABS(bmaxr, rmax, s_epsilon);
0220 CHECK_CLOSE_ABS(hphi, 0.25 * M_PI, s_epsilon);
0221 CHECK_CLOSE_ABS(mphi, 0., s_epsilon);
0222 GeometryView3D::drawSurface(objVis, *discSegment, tgContext);
0223 GeometryView3D::drawArrowForward(objVis, center,
0224 center + 1.2 * bmaxr * Vector3::UnitX(),
0225 4., 2.5, red);
0226 GeometryView3D::drawArrowForward(objVis, center,
0227 center + 1.2 * bmaxr * Vector3::UnitY(),
0228 4., 2.5, green);
0229 GeometryView3D::drawArrowForward(
0230 objVis, center, center + 1.2 * hz * Vector3::UnitZ(), 4., 2.5, blue);
0231 objVis.write("TGeoConversion_TGeoTube_DiscSegmentSurface_" +
0232 std::to_string(idisc));
0233 objVis.clear();
0234
0235 } else {
0236 BOOST_CHECK_THROW(TGeoSurfaceConverter::toSurface(*vols->GetShape(),
0237 *gGeoIdentity, axes, 1),
0238 std::invalid_argument);
0239 }
0240 ++idisc;
0241 }
0242
0243
0244 for (const auto &naxes : notAllowedAxes) {
0245 BOOST_CHECK_THROW(TGeoSurfaceConverter::toSurface(*vol->GetShape(),
0246 *gGeoIdentity, naxes, 1),
0247 std::invalid_argument);
0248 }
0249 }
0250
0251 }