Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TGeoTubeConversionTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TGeoTubeConversionTests.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 
24 
25 #include <cmath>
26 #include <cstddef>
27 #include <memory>
28 #include <stdexcept>
29 #include <string>
30 #include <vector>
31 
32 #include "TGeoManager.h"
33 #include "TGeoMaterial.h"
34 #include "TGeoMatrix.h"
35 #include "TGeoMedium.h"
36 #include "TGeoTube.h"
37 #include "TGeoVolume.h"
38 #include "TView.h"
39 
40 namespace Acts {
41 
42 namespace Test {
43 
45 
46 ViewConfig red({200, 0, 0});
47 ViewConfig green({0, 200, 0});
48 ViewConfig blue({0, 0, 200});
49 
50 std::vector<std::string> allowedAxes = {"XY*", "Xy*", "xy*", "xY*",
51  "YX*", "yx*", "yX*", "Yx*"};
52 
53 std::vector<std::string> notAllowedAxes = {"YZ*", "ZX*", "ZY*"};
54 
58 BOOST_AUTO_TEST_CASE(TGeoTube_to_CylinderSurface) {
59  ObjVisualization3D objVis;
60 
61  double rmin = 10.;
62  double rmax = 11;
63  double hz = 40.;
64  double phimin = 45.;
65  double phimax = -45.;
66 
67  new TGeoManager("trd1", "poza9");
68  TGeoMaterial *mat = new TGeoMaterial("Al", 26.98, 13, 2.7);
69  TGeoMedium *med = new TGeoMedium("MED", 1, mat);
70  TGeoVolume *top = gGeoManager->MakeBox("TOP", med, 100, 100, 100);
71  gGeoManager->SetTopVolume(top);
72  TGeoVolume *vol = gGeoManager->MakeTube("Tube", med, rmin, rmax, hz);
73  TGeoVolume *vols =
74  gGeoManager->MakeTubs("Tube", med, rmin, rmax, hz, phimin, phimax);
75  gGeoManager->CloseGeometry();
76 
77  size_t icyl = 0;
78  for (const auto &axes : allowedAxes) {
79  auto [cylinder, thickness] = TGeoSurfaceConverter::toSurface(
80  *vol->GetShape(), *gGeoIdentity, axes, 1);
81  BOOST_CHECK_NE(cylinder, nullptr);
82  BOOST_CHECK_EQUAL(cylinder->type(), Surface::Cylinder);
83  CHECK_CLOSE_ABS(thickness, rmax - rmin, s_epsilon);
84 
85  auto bounds = dynamic_cast<const CylinderBounds *>(&(cylinder->bounds()));
86  BOOST_CHECK_NE(bounds, nullptr);
87  double bR = bounds->get(CylinderBounds::eR);
88  double bhZ = bounds->get(CylinderBounds::eHalfLengthZ);
89 
90  CHECK_CLOSE_ABS(bR, 10.5, s_epsilon);
91  CHECK_CLOSE_ABS(bhZ, hz, s_epsilon);
92 
93  auto transform = cylinder->transform(tgContext);
94  auto rotation = transform.rotation();
95 
96  // Check if the surface is the (negative) identity
97  GeometryView3D::drawSurface(objVis, *cylinder, tgContext);
98  const Vector3 center = cylinder->center(tgContext);
100  objVis, center, center + 1.2 * bR * rotation.col(0), 4., 2.5, red);
102  objVis, center, center + 1.2 * bR * rotation.col(1), 4., 2.5, green);
104  objVis, center, center + 1.2 * bhZ * rotation.col(2), 4., 2.5, blue);
105 
106  objVis.write("TGeoConversion_TGeoTube_CylinderSurface_" +
107  std::to_string(icyl));
108  objVis.clear();
109 
110  if (icyl < 2) {
111  auto [cylinderSegment, cThickness] = TGeoSurfaceConverter::toSurface(
112  *vols->GetShape(), *gGeoIdentity, axes, 1);
113  BOOST_CHECK_NE(cylinderSegment, nullptr);
114  BOOST_CHECK_EQUAL(cylinderSegment->type(), Surface::Cylinder);
115  CHECK_CLOSE_ABS(cThickness, rmax - rmin, s_epsilon);
116 
117  auto boundsSegment =
118  dynamic_cast<const CylinderBounds *>(&(cylinderSegment->bounds()));
119  BOOST_CHECK_NE(boundsSegment, nullptr);
120  bR = boundsSegment->get(CylinderBounds::eR);
121  bhZ = boundsSegment->get(CylinderBounds::eHalfLengthZ);
122  double hphi = boundsSegment->get(CylinderBounds::eHalfPhiSector);
123  double mphi = boundsSegment->get(CylinderBounds::eAveragePhi);
124  CHECK_CLOSE_ABS(bR, 10.5, s_epsilon);
125  CHECK_CLOSE_ABS(bhZ, hz, s_epsilon);
126  CHECK_CLOSE_ABS(hphi, 0.25 * M_PI, s_epsilon);
127  CHECK_CLOSE_ABS(mphi, 0., s_epsilon);
128  GeometryView3D::drawSurface(objVis, *cylinderSegment, tgContext);
130  objVis, center, center + 1.2 * bR * rotation.col(0), 4., 2.5, red);
132  objVis, center, center + 1.2 * bR * rotation.col(1), 4., 2.5, green);
134  objVis, center, center + 1.2 * bhZ * rotation.col(2), 4., 2.5, blue);
135  objVis.write("TGeoConversion_TGeoTube_CylinderSegmentSurface_" +
136  std::to_string(icyl));
137  objVis.clear();
138  } else {
139  BOOST_CHECK_THROW(TGeoSurfaceConverter::toSurface(*vols->GetShape(),
140  *gGeoIdentity, axes, 1),
141  std::invalid_argument);
142  }
143  ++icyl;
144  }
145 
146  // Check exceptions for not allowed axis definition
147  for (const auto &naxes : notAllowedAxes) {
148  BOOST_CHECK_THROW(TGeoSurfaceConverter::toSurface(*vol->GetShape(),
149  *gGeoIdentity, naxes, 1),
150  std::invalid_argument);
151  }
152 }
153 
157 BOOST_AUTO_TEST_CASE(TGeoTube_to_DiscSurface) {
158  ObjVisualization3D objVis;
159 
160  double rmin = 5.;
161  double rmax = 25;
162  double hz = 2.;
163  double phimin = 45.;
164  double phimax = -45.;
165 
166  new TGeoManager("trd1", "poza9");
167  TGeoMaterial *mat = new TGeoMaterial("Al", 26.98, 13, 2.7);
168  TGeoMedium *med = new TGeoMedium("MED", 1, mat);
169  TGeoVolume *top = gGeoManager->MakeBox("TOP", med, 100, 100, 100);
170  gGeoManager->SetTopVolume(top);
171  TGeoVolume *vol = gGeoManager->MakeTube("Tube", med, rmin, rmax, hz);
172  vol->SetLineWidth(2);
173  TGeoVolume *vols =
174  gGeoManager->MakeTubs("Tube", med, rmin, rmax, hz, phimin, phimax);
175  gGeoManager->CloseGeometry();
176 
177  size_t idisc = 0;
178  for (const auto &axes : allowedAxes) {
180  *vol->GetShape(), *gGeoIdentity, axes, 1);
181  BOOST_CHECK_NE(disc, nullptr);
182  BOOST_CHECK_EQUAL(disc->type(), Surface::Disc);
184 
185  auto bounds = dynamic_cast<const RadialBounds *>(&(disc->bounds()));
186  BOOST_CHECK_NE(bounds, nullptr);
187  double bminr = bounds->get(RadialBounds::eMinR);
188  double bmaxr = bounds->get(RadialBounds::eMaxR);
189 
190  CHECK_CLOSE_ABS(bminr, rmin, s_epsilon);
191  CHECK_CLOSE_ABS(bmaxr, rmax, s_epsilon);
192 
193  // Check if the surface is the (negative) identity
194  GeometryView3D::drawSurface(objVis, *disc, tgContext);
195  const Vector3 center = disc->center(tgContext);
197  objVis, center, center + 1.2 * rmax * Vector3::UnitX(), 4., 2.5, red);
199  objVis, center, center + 1.2 * rmax * Vector3::UnitY(), 4., 2.5, green);
201  objVis, center, center + 1.2 * hz * Vector3::UnitZ(), 4., 2.5, blue);
202  objVis.write("TGeoConversion_TGeoTube_DiscSurface_" +
203  std::to_string(idisc));
204  objVis.clear();
205 
206  if (idisc < 2) {
207  auto [discSegment, dThickness] = TGeoSurfaceConverter::toSurface(
208  *vols->GetShape(), *gGeoIdentity, axes, 1);
209  BOOST_CHECK_NE(discSegment, nullptr);
210  BOOST_CHECK_EQUAL(discSegment->type(), Surface::Disc);
211  CHECK_CLOSE_ABS(dThickness, 2 * hz, s_epsilon);
212 
213  auto boundsSegment =
214  dynamic_cast<const RadialBounds *>(&(discSegment->bounds()));
215  BOOST_CHECK_NE(boundsSegment, nullptr);
216  bminr = boundsSegment->get(RadialBounds::eMinR);
217  bmaxr = boundsSegment->get(RadialBounds::eMaxR);
218  double hphi = boundsSegment->get(RadialBounds::eHalfPhiSector);
219  double mphi = boundsSegment->get(RadialBounds::eAveragePhi);
220  CHECK_CLOSE_ABS(bminr, rmin, s_epsilon);
221  CHECK_CLOSE_ABS(bmaxr, rmax, s_epsilon);
222  CHECK_CLOSE_ABS(hphi, 0.25 * M_PI, s_epsilon);
223  CHECK_CLOSE_ABS(mphi, 0., s_epsilon);
224  GeometryView3D::drawSurface(objVis, *discSegment, tgContext);
225  GeometryView3D::drawArrowForward(objVis, center,
226  center + 1.2 * bmaxr * Vector3::UnitX(),
227  4., 2.5, red);
228  GeometryView3D::drawArrowForward(objVis, center,
229  center + 1.2 * bmaxr * Vector3::UnitY(),
230  4., 2.5, green);
232  objVis, center, center + 1.2 * hz * Vector3::UnitZ(), 4., 2.5, blue);
233  objVis.write("TGeoConversion_TGeoTube_DiscSegmentSurface_" +
234  std::to_string(idisc));
235  objVis.clear();
236 
237  } else {
238  BOOST_CHECK_THROW(TGeoSurfaceConverter::toSurface(*vols->GetShape(),
239  *gGeoIdentity, axes, 1),
240  std::invalid_argument);
241  }
242  ++idisc;
243  }
244 
245  // Check exceptions for not allowed axis definition
246  for (const auto &naxes : notAllowedAxes) {
247  BOOST_CHECK_THROW(TGeoSurfaceConverter::toSurface(*vol->GetShape(),
248  *gGeoIdentity, naxes, 1),
249  std::invalid_argument);
250  }
251 }
252 
253 } // namespace Test
254 
255 } // namespace Acts