Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TGeoBBoxConversionTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TGeoBBoxConversionTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2020-2023 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #include <boost/test/data/test_case.hpp>
10 #include <boost/test/unit_test.hpp>
11 
23 
24 #include <memory>
25 #include <utility>
26 
27 #include "TGeoBBox.h"
28 #include "TGeoManager.h"
29 #include "TGeoMaterial.h"
30 #include "TGeoMatrix.h"
31 #include "TGeoMedium.h"
32 #include "TGeoVolume.h"
33 #include "TView.h"
34 
35 namespace bdata = boost::unit_test::data;
36 namespace tt = boost::test_tools;
37 
38 namespace Acts {
39 
40 namespace Test {
41 
43 
44 ViewConfig red({200, 0, 0});
45 ViewConfig green({0, 200, 0});
46 ViewConfig blue({0, 0, 200});
47 
53 BOOST_AUTO_TEST_CASE(TGeoBBox_to_PlaneSurface) {
54  ObjVisualization3D objVis;
55 
56  // BBox is defined [-dX,dX] x [-dY,dY] x [-dZ,dZ]
57  double dX = 10.;
58  double dY = 30.;
59  double dZ = 1.;
60 
61  new TGeoManager("box", "poza1");
62  TGeoMaterial *mat = new TGeoMaterial("Al", 26.98, 13, 2.7);
63  TGeoMedium *med = new TGeoMedium("MED", 1, mat);
64  TGeoVolume *top = gGeoManager->MakeBox("TOP", med, 100, 100, 100);
65  gGeoManager->SetTopVolume(top);
66  TGeoVolume *vol = gGeoManager->MakeBox("BOX", med, dX, dY, dZ);
67  vol->SetLineWidth(2);
68  top->AddNode(vol, 1);
69  gGeoManager->CloseGeometry();
70 
71  // Upper case ---------------------------------
72  auto [plane_XYZ, thickness_XYZ] = TGeoSurfaceConverter::toSurface(
73  *vol->GetShape(), *gGeoIdentity, "XY*", 1);
74  BOOST_CHECK_NE(plane_XYZ, nullptr);
75  BOOST_CHECK_EQUAL(plane_XYZ->type(), Surface::Plane);
76  CHECK_CLOSE_ABS(thickness_XYZ, 2 * dZ, s_epsilon);
77 
78  auto bounds_XYZ =
79  dynamic_cast<const RectangleBounds *>(&(plane_XYZ->bounds()));
80  BOOST_CHECK_NE(bounds_XYZ, nullptr);
81  double maxX = bounds_XYZ->get(RectangleBounds::eMaxX);
82  double minX = bounds_XYZ->get(RectangleBounds::eMinX);
83  double maxY = bounds_XYZ->get(RectangleBounds::eMaxY);
84  double minY = bounds_XYZ->get(RectangleBounds::eMinY);
85  CHECK_CLOSE_ABS(maxX - minX, 2 * dX, s_epsilon);
86  CHECK_CLOSE_ABS(maxY - minY, 2 * dY, s_epsilon);
87 
88  // Check if the surface is the (negative) identity
89  auto transform_XYZ = plane_XYZ->transform(tgContext);
90  auto rotation_XYZ = transform_XYZ.rotation();
91  BOOST_CHECK(transform_XYZ.isApprox(Transform3::Identity()));
92 
93  const Vector3 offset_XYZ{-5.5 * dX, 0., 0.};
94  GeometryView3D::drawSurface(objVis, *plane_XYZ, tgContext,
95  Transform3(Translation3{offset_XYZ}));
96  const Vector3 center_XYZ = plane_XYZ->center(tgContext) + offset_XYZ;
98  objVis, center_XYZ,
99  center_XYZ + 0.6 * (maxX - minX) * rotation_XYZ.col(0), 4., 2.5, red);
101  objVis, center_XYZ,
102  center_XYZ + 0.6 * (maxY - minY) * rotation_XYZ.col(1), 4., 2.5, green);
104  objVis, center_XYZ, center_XYZ + 2 * rotation_XYZ.col(2), 4., 2.5, blue);
105 
106  // Lower case ---------------------------------
107  auto [plane_xyz, thickness_xyz] = TGeoSurfaceConverter::toSurface(
108  *vol->GetShape(), *gGeoIdentity, "xy*", 1);
109  BOOST_CHECK_NE(plane_xyz, nullptr);
110  BOOST_CHECK_EQUAL(plane_xyz->type(), Surface::Plane);
111  CHECK_CLOSE_ABS(thickness_xyz, 2 * dZ, s_epsilon);
112 
113  auto bounds_xyz =
114  dynamic_cast<const RectangleBounds *>(&(plane_XYZ->bounds()));
115  BOOST_CHECK_NE(bounds_xyz, nullptr);
116  BOOST_CHECK_EQUAL(bounds_xyz, bounds_XYZ);
117  auto transform_xyz = plane_xyz->transform(tgContext);
118  auto rotation_xyz = transform_xyz.rotation();
119  BOOST_CHECK(rotation_xyz.col(0).isApprox(-1 * rotation_XYZ.col(0)));
120  BOOST_CHECK(rotation_xyz.col(1).isApprox(-1 * rotation_XYZ.col(1)));
121  BOOST_CHECK(rotation_xyz.col(2).isApprox(rotation_XYZ.col(2)));
122 
123  const Vector3 offset_xyz{-2 * dX, 0., 0.};
124  GeometryView3D::drawSurface(objVis, *plane_xyz, tgContext,
125  Transform3(Translation3{offset_xyz}));
126  const Vector3 center_xyz = plane_xyz->center(tgContext) + offset_xyz;
128  objVis, center_xyz,
129  center_xyz + 0.6 * (maxX - minX) * rotation_xyz.col(0), 4., 2.5, red);
131  objVis, center_xyz,
132  center_xyz + 0.6 * (maxY - minY) * rotation_xyz.col(1), 4., 2.5, green);
134  objVis, center_xyz, center_xyz + 2 * rotation_xyz.col(2), 4., 2.5, blue);
135 
136  // Mixed case ---------------------------------
137  auto [plane_xYz, thickness_xYz] = TGeoSurfaceConverter::toSurface(
138  *vol->GetShape(), *gGeoIdentity, "xY*", 1);
139  BOOST_CHECK_NE(plane_xYz, nullptr);
140  BOOST_CHECK_EQUAL(plane_xYz->type(), Surface::Plane);
141  CHECK_CLOSE_ABS(thickness_xYz, 2 * dZ, s_epsilon);
142 
143  auto bounds_xYz =
144  dynamic_cast<const RectangleBounds *>(&(plane_xYz->bounds()));
145  BOOST_CHECK_NE(bounds_xYz, nullptr);
146  BOOST_CHECK_EQUAL(bounds_xYz, bounds_xYz);
147  auto transform_xYz = plane_xYz->transform(tgContext);
148  auto rotation_xYz = transform_xYz.rotation();
149  BOOST_CHECK(rotation_xYz.col(0).isApprox(-1 * rotation_XYZ.col(0)));
150  BOOST_CHECK(rotation_xYz.col(1).isApprox(rotation_XYZ.col(1)));
151  BOOST_CHECK(rotation_xYz.col(2).isApprox(-1. * rotation_XYZ.col(2)));
152 
153  const Vector3 offset_xYz{2 * dX, 0., 0.};
155  objVis, *plane_xYz, tgContext,
156  Translation3{offset_xYz} * Transform3::Identity());
157  const Vector3 center_xYz = plane_xYz->center(tgContext) + offset_xYz;
159  objVis, center_xYz,
160  center_xYz + 0.6 * (maxX - minX) * rotation_xYz.col(0), 4., 2.5, red);
162  objVis, center_xYz,
163  center_xYz + 0.6 * (maxY - minY) * rotation_xYz.col(1), 4., 2.5, green);
165  objVis, center_xYz, center_xYz + 2 * rotation_xYz.col(2), 4., 2.5, blue);
166 
167  // Swap case --------------------------------- (x/y) here
168  auto [plane_YXz, thickness_YXz] = TGeoSurfaceConverter::toSurface(
169  *vol->GetShape(), *gGeoIdentity, "YX*", 1);
170  BOOST_CHECK_NE(plane_YXz, nullptr);
171  BOOST_CHECK_EQUAL(plane_YXz->type(), Surface::Plane);
172  CHECK_CLOSE_ABS(thickness_YXz, 2 * dZ, s_epsilon);
173 
174  auto bounds_YXz =
175  dynamic_cast<const RectangleBounds *>(&(plane_YXz->bounds()));
176  maxX = bounds_YXz->get(RectangleBounds::eMaxX);
177  minX = bounds_YXz->get(RectangleBounds::eMinX);
178  maxY = bounds_YXz->get(RectangleBounds::eMaxY);
179  minY = bounds_YXz->get(RectangleBounds::eMinY);
180  CHECK_CLOSE_ABS(maxX - minX, 2 * dY, s_epsilon);
181  CHECK_CLOSE_ABS(maxY - minY, 2 * dX, s_epsilon);
182 
183  auto transform_YXz = plane_YXz->transform(tgContext);
184  auto rotation_YXz = transform_YXz.rotation();
185  BOOST_CHECK(rotation_YXz.col(0).isApprox(rotation_XYZ.col(1)));
186  BOOST_CHECK(rotation_YXz.col(1).isApprox(rotation_XYZ.col(0)));
187  BOOST_CHECK(rotation_YXz.col(2).isApprox(-1. * rotation_XYZ.col(2)));
188 
189  const Vector3 offset_YXz{5.5 * dX, 0., 0.};
190  GeometryView3D::drawSurface(objVis, *plane_YXz, tgContext,
191  Transform3(Translation3{offset_YXz}));
192  const Vector3 center_YXz = plane_YXz->center(tgContext) + offset_YXz;
194  objVis, center_YXz,
195  center_YXz + 0.6 * (maxX - minX) * rotation_YXz.col(0), 4., 2.5, red);
197  objVis, center_YXz,
198  center_YXz + 0.6 * (maxY - minY) * rotation_YXz.col(1), 4., 2.5, green);
200  objVis, center_YXz, center_YXz + 2 * rotation_YXz.col(2), 4., 2.5, blue);
201 
202  // Scaling test ---------------------------------
203  auto [plane_XYZ10, thickness_XYZ10] = TGeoSurfaceConverter::toSurface(
204  *vol->GetShape(), *gGeoIdentity, "xY*", 10);
205  BOOST_CHECK_NE(plane_XYZ10, nullptr);
206  CHECK_CLOSE_ABS(thickness_XYZ10, 20 * dZ, s_epsilon);
207 
208  auto bounds_XYZ10 =
209  dynamic_cast<const RectangleBounds *>(&(plane_XYZ10->bounds()));
210  double maxX10 = bounds_XYZ10->get(RectangleBounds::eMaxX);
211  double minX10 = bounds_XYZ10->get(RectangleBounds::eMinX);
212  double maxY10 = bounds_XYZ10->get(RectangleBounds::eMaxY);
213  double minY10 = bounds_XYZ10->get(RectangleBounds::eMinY);
214  CHECK_CLOSE_ABS(maxX10 - minX10, 20 * dX, s_epsilon);
215  CHECK_CLOSE_ABS(maxY10 - minY10, 20 * dY, s_epsilon);
216 
217  objVis.write("TGeoConversion_TGeoBBox_PlaneSurface");
218 }
219 
220 } // namespace Test
221 
222 } // namespace Acts