EIC 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 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 
20 
21 #include "TGeoBBox.h"
22 #include "TGeoManager.h"
23 #include "TGeoMaterial.h"
24 #include "TGeoMatrix.h"
25 #include "TGeoMedium.h"
26 #include "TGeoVolume.h"
27 #include "TView.h"
28 
29 namespace bdata = boost::unit_test::data;
30 namespace tt = boost::test_tools;
31 
32 namespace Acts {
33 
34 namespace Test {
35 
37 
38 ViewConfig red({200, 0, 0});
39 ViewConfig green({0, 200, 0});
40 ViewConfig blue({0, 0, 200});
41 
47 BOOST_AUTO_TEST_CASE(TGeoBBox_to_PlaneSurface) {
48  ObjVisualization3D objVis;
49 
50  double x = 10.;
51  double y = 30.;
52  double z = 1.;
53 
54  new TGeoManager("box", "poza1");
55  TGeoMaterial *mat = new TGeoMaterial("Al", 26.98, 13, 2.7);
56  TGeoMedium *med = new TGeoMedium("MED", 1, mat);
57  TGeoVolume *top = gGeoManager->MakeBox("TOP", med, 100, 100, 100);
58  gGeoManager->SetTopVolume(top);
59  TGeoVolume *vol = gGeoManager->MakeBox("BOX", med, x, y, z);
60  vol->SetLineWidth(2);
61  top->AddNode(vol, 1);
62  gGeoManager->CloseGeometry();
63 
64  // Upper case ---------------------------------
65  auto plane_XYZ = TGeoSurfaceConverter::toSurface(*vol->GetShape(),
66  *gGeoIdentity, "XY*", 1);
67  BOOST_CHECK_NE(plane_XYZ, nullptr);
68  BOOST_CHECK_EQUAL(plane_XYZ->type(), Surface::Plane);
69 
70  auto bounds_XYZ =
71  dynamic_cast<const RectangleBounds *>(&(plane_XYZ->bounds()));
72  BOOST_CHECK_NE(bounds_XYZ, nullptr);
73  double maxX = bounds_XYZ->get(RectangleBounds::eMaxX);
74  double minX = bounds_XYZ->get(RectangleBounds::eMinX);
75  double maxY = bounds_XYZ->get(RectangleBounds::eMaxY);
76  double minY = bounds_XYZ->get(RectangleBounds::eMinY);
77  CHECK_CLOSE_ABS(maxX - minX, 2 * x, s_epsilon);
78  CHECK_CLOSE_ABS(maxY - minY, 2 * y, s_epsilon);
79 
80  // Check if the surface is the (negative) identity
81  auto transform_XYZ = plane_XYZ->transform(tgContext);
82  auto rotation_XYZ = transform_XYZ.rotation();
83  BOOST_CHECK(transform_XYZ.isApprox(Transform3D::Identity()));
84 
85  const Vector3D offset_XYZ{-5.5 * x, 0., 0.};
86  GeometryView3D::drawSurface(objVis, *plane_XYZ, tgContext,
87  Transform3D(Translation3D{offset_XYZ}));
88  const Vector3D center_XYZ = plane_XYZ->center(tgContext) + offset_XYZ;
90  objVis, center_XYZ,
91  center_XYZ + 0.6 * (maxX - minX) * rotation_XYZ.col(0), 4., 2.5, red);
93  objVis, center_XYZ,
94  center_XYZ + 0.6 * (maxY - minY) * rotation_XYZ.col(1), 4., 2.5, green);
96  objVis, center_XYZ, center_XYZ + 2 * rotation_XYZ.col(2), 4., 2.5, blue);
97 
98  // Lower case ---------------------------------
99  auto plane_xyz = TGeoSurfaceConverter::toSurface(*vol->GetShape(),
100  *gGeoIdentity, "xy*", 1);
101  BOOST_CHECK_NE(plane_xyz, nullptr);
102  BOOST_CHECK_EQUAL(plane_xyz->type(), Surface::Plane);
103 
104  auto bounds_xyz =
105  dynamic_cast<const RectangleBounds *>(&(plane_XYZ->bounds()));
106  BOOST_CHECK_NE(bounds_xyz, nullptr);
107  BOOST_CHECK_EQUAL(bounds_xyz, bounds_XYZ);
108  auto transform_xyz = plane_xyz->transform(tgContext);
109  auto rotation_xyz = transform_xyz.rotation();
110  BOOST_CHECK(rotation_xyz.col(0).isApprox(-1 * rotation_XYZ.col(0)));
111  BOOST_CHECK(rotation_xyz.col(1).isApprox(-1 * rotation_XYZ.col(1)));
112  BOOST_CHECK(rotation_xyz.col(2).isApprox(rotation_XYZ.col(2)));
113 
114  const Vector3D offset_xyz{-2 * x, 0., 0.};
115  GeometryView3D::drawSurface(objVis, *plane_xyz, tgContext,
116  Transform3D(Translation3D{offset_xyz}));
117  const Vector3D center_xyz = plane_xyz->center(tgContext) + offset_xyz;
119  objVis, center_xyz,
120  center_xyz + 0.6 * (maxX - minX) * rotation_xyz.col(0), 4., 2.5, red);
122  objVis, center_xyz,
123  center_xyz + 0.6 * (maxY - minY) * rotation_xyz.col(1), 4., 2.5, green);
125  objVis, center_xyz, center_xyz + 2 * rotation_xyz.col(2), 4., 2.5, blue);
126 
127  // Mixed case ---------------------------------
128  auto plane_xYz = TGeoSurfaceConverter::toSurface(*vol->GetShape(),
129  *gGeoIdentity, "xY*", 1);
130  BOOST_CHECK_NE(plane_xYz, nullptr);
131  BOOST_CHECK_EQUAL(plane_xYz->type(), Surface::Plane);
132 
133  auto bounds_xYz =
134  dynamic_cast<const RectangleBounds *>(&(plane_xYz->bounds()));
135  BOOST_CHECK_NE(bounds_xYz, nullptr);
136  BOOST_CHECK_EQUAL(bounds_xYz, bounds_xYz);
137  auto transform_xYz = plane_xYz->transform(tgContext);
138  auto rotation_xYz = transform_xYz.rotation();
139  BOOST_CHECK(rotation_xYz.col(0).isApprox(-1 * rotation_XYZ.col(0)));
140  BOOST_CHECK(rotation_xYz.col(1).isApprox(rotation_XYZ.col(1)));
141  BOOST_CHECK(rotation_xYz.col(2).isApprox(-1. * rotation_XYZ.col(2)));
142 
143  const Vector3D offset_xYz{2 * x, 0., 0.};
145  objVis, *plane_xYz, tgContext,
146  Translation3D{offset_xYz} * Transform3D::Identity());
147  const Vector3D center_xYz = plane_xYz->center(tgContext) + offset_xYz;
149  objVis, center_xYz,
150  center_xYz + 0.6 * (maxX - minX) * rotation_xYz.col(0), 4., 2.5, red);
152  objVis, center_xYz,
153  center_xYz + 0.6 * (maxY - minY) * rotation_xYz.col(1), 4., 2.5, green);
155  objVis, center_xYz, center_xYz + 2 * rotation_xYz.col(2), 4., 2.5, blue);
156 
157  // Swap case --------------------------------- (x/y) here
158  auto plane_YXz = TGeoSurfaceConverter::toSurface(*vol->GetShape(),
159  *gGeoIdentity, "YX*", 1);
160  BOOST_CHECK_NE(plane_YXz, nullptr);
161  BOOST_CHECK_EQUAL(plane_YXz->type(), Surface::Plane);
162  auto bounds_YXz =
163  dynamic_cast<const RectangleBounds *>(&(plane_YXz->bounds()));
164  maxX = bounds_YXz->get(RectangleBounds::eMaxX);
165  minX = bounds_YXz->get(RectangleBounds::eMinX);
166  maxY = bounds_YXz->get(RectangleBounds::eMaxY);
167  minY = bounds_YXz->get(RectangleBounds::eMinY);
168  CHECK_CLOSE_ABS(maxX - minX, 2 * y, s_epsilon);
169  CHECK_CLOSE_ABS(maxY - minY, 2 * x, s_epsilon);
170 
171  auto transform_YXz = plane_YXz->transform(tgContext);
172  auto rotation_YXz = transform_YXz.rotation();
173  BOOST_CHECK(rotation_YXz.col(0).isApprox(rotation_XYZ.col(1)));
174  BOOST_CHECK(rotation_YXz.col(1).isApprox(rotation_XYZ.col(0)));
175  BOOST_CHECK(rotation_YXz.col(2).isApprox(-1. * rotation_XYZ.col(2)));
176 
177  const Vector3D offset_YXz{5.5 * x, 0., 0.};
178  GeometryView3D::drawSurface(objVis, *plane_YXz, tgContext,
179  Transform3D(Translation3D{offset_YXz}));
180  const Vector3D center_YXz = plane_YXz->center(tgContext) + offset_YXz;
182  objVis, center_YXz,
183  center_YXz + 0.6 * (maxX - minX) * rotation_YXz.col(0), 4., 2.5, red);
185  objVis, center_YXz,
186  center_YXz + 0.6 * (maxY - minY) * rotation_YXz.col(1), 4., 2.5, green);
188  objVis, center_YXz, center_YXz + 2 * rotation_YXz.col(2), 4., 2.5, blue);
189 
190  // Scaling test ---------------------------------
191  auto plane_XYZ10 = TGeoSurfaceConverter::toSurface(*vol->GetShape(),
192  *gGeoIdentity, "xY*", 10);
193  BOOST_CHECK_NE(plane_XYZ10, nullptr);
194 
195  auto bounds_XYZ10 =
196  dynamic_cast<const RectangleBounds *>(&(plane_XYZ10->bounds()));
197  double maxX10 = bounds_XYZ10->get(RectangleBounds::eMaxX);
198  double minX10 = bounds_XYZ10->get(RectangleBounds::eMinX);
199  double maxY10 = bounds_XYZ10->get(RectangleBounds::eMaxY);
200  double minY10 = bounds_XYZ10->get(RectangleBounds::eMinY);
201  CHECK_CLOSE_ABS(maxX10 - minX10, 20 * x, s_epsilon);
202  CHECK_CLOSE_ABS(maxY10 - minY10, 20 * y, s_epsilon);
203 
204  objVis.write("TGeoConversion_TGeoBBox_PlaneSurface");
205 }
206 
207 } // namespace Test
208 
209 } // namespace Acts