ATLAS Offline Software
InDetGeoModelUtils/src/ServiceVolume.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3  */
4 
5 //
6 // This class to hold general services
7 //
8 // The services support several different shapes. The meaning of the parameters
9 // depends on the particular shape:
10 //
11 //
12 // TUBE or empty
13 // Ignored: RIN2,ROUT2,PHI,WIDTH,REPEAT
14 // TUBS
15 // Ignored: RIN2,ROUT2
16 // PHI: phi start location of tube sector
17 // WIDTH (CLHEP::deg): phi width of sector
18 // REPEAT: Repeat the tube sector this many times in phi with equal distance between them.
19 // CONS, CONE
20 // WIDTH,REPEAT ignored if CONE
21 // RIN2,ROUT2: rmin, rmx at zmax. Same as RIN, ROUT if <=0.
22 // PHI, WIDTH, REPEAT same as TUBS
23 // PGON
24 // Ignored: WIDTH
25 // RIN,ROUT,RIN2,ROUT2 defined at corner of polygon.
26 // PHI: phi start location of a corner
27 // REPEAT: Sides of polygon
28 // PGON2
29 // Ignored: WIDTH
30 // RIN,ROUT,RIN2,ROUT2 defined at side of polygon.
31 // PHI: phi start location of center of side.
32 // REPEAT: Sides of polygon
33 // PGON3 (pgon at outer edge, circular inner edge)
34 // Ignored: WIDTH
35 // RIN,RIN2 radius of inner edge (tube or cone)
36 // ROUT,ROUT2 defined at corner of polygon.
37 // PHI: phi start location of a corner
38 // REPEAT: Sides of polygon
39 // PGON31 (pgon at inner edge, circular outer edge)
40 // Ignored: WIDTH
41 // RIN,RIN2 radius of inner edge (tube or cone)
42 // ROUT,ROUT2 defined at corner of polygon.
43 // PHI: phi start location of a corner
44 // REPEAT: Sides of polygon
45 // PGON4 (pgon at outer edge, circular inner edge)
46 // Ignored: WIDTH
47 // RIN,RIN2 radius of inner edge (tube or cone)
48 // ROUTROUT2 defined at side of polygon.
49 // PHI: phi start location of center of side.
50 // REPEAT: Sides of polygon
51 // ROD
52 // Ignored: ROUT, RIN2, ROUT2
53 // RIN: Radial position of center of tube
54 // PHI: phi position of center
55 // WIDTH (mm): diameter
56 // REPEAT: Repeat this many times in phi with equal distance between them.
57 // ROD2 (hollow tube not centered around Z axis)
58 // Ignored: ROUT, ROUT2
59 // RIN: Radial position of center of tube
60 // RIN2: inner radius
61 // PHI: phi position of center
62 // WIDTH (mm): diameter
63 // REPEAT: Repeat this many times in phi with equal distance between them.
64 // BOX
65 // Ignored: RIN2, ROUT2
66 // ROUT-RIN = thickness of box (radially)
67 // (RIN+ROUT)/2 = radial poistion of center of box
68 // PHI: phi position of center
69 // WIDTH (mm) = width of box
70 // REPEAT: Repeat this many times in phi with equal distance between them.
71 // TRAP
72 // Ignored: RIN2, ROUT2
73 // ROUT-RIN = thickness of trapezoid (radially)
74 // (RIN+ROUT)/2 = radial poistion of center of trapzoid
75 // PHI: phi position of center
76 // WIDTH (mm) = width of trapezoid at center
77 // REPEAT: Repeat this many times in phi with equal distance between them.
78 //
79 // **IMPORTANT NOTE** WIDTH can be in degrees or mm. See OraclePixGeoManager
80 
82 #include "GeoModelKernel/GeoTube.h"
83 #include "GeoModelKernel/GeoTubs.h"
84 #include "GeoModelKernel/GeoCons.h"
85 #include "GeoModelKernel/GeoPgon.h"
86 #include "GeoModelKernel/GeoBox.h"
87 #include "GeoModelKernel/GeoTrap.h"
88 #include "GeoModelKernel/GeoShapeSubtraction.h"
89 #include "GaudiKernel/SystemOfUnits.h"
90 
91 #include <string>
92 #include <iostream>
93 #include <sstream>
94 #include <iomanip>
95 
96 namespace InDetDD {
98  : m_rmin(0),
99  m_rmax(0),
100  m_rmin2(0),
101  m_rmax2(0),
102  m_zmin(0),
103  m_zmax(0),
104  //m_volId(0),
105  m_zsymm(false),
106  m_geoShape(nullptr),
107  m_material(nullptr),
108  m_phiLoc(0),
109  m_phiWidth(0),
110  m_needsRotation(false),
111  m_sides(0),
112  m_nCopies(1),
113  //m_origLength(0),
114  m_origVolume(0),
115  m_volume(0),
116  m_safety(0),
117  m_lockGeoShape(0),
118  m_splittableR(true),
119  m_splittableZ(true),
120  m_envNum(0),
121  m_envParentNum(0),
122  m_zShift(0.),
123  m_mutex()
124  {}
125 
127  : m_rmin(rhs.m_rmin),
128  m_rmax(rhs.m_rmax),
129  m_rmin2(rhs.m_rmin2),
130  m_rmax2(rhs.m_rmax2),
131  m_zmin(rhs.m_zmin),
132  m_zmax(rhs.m_zmax),
133  //m_volId(rhs.m_volId),
134  m_zsymm(rhs.m_zsymm),
135  m_geoShape(rhs.m_geoShape),
136  m_material(rhs.m_material),
137  m_materialName(rhs.m_materialName),
138  m_volName(rhs.m_volName),
139  m_shapeType(rhs.m_shapeType),
140  m_phiLoc(rhs.m_phiLoc),
141  m_phiWidth(rhs.m_phiWidth),
142  m_needsRotation(rhs.m_needsRotation),
143  m_sides(rhs.m_sides),
144  m_nCopies(rhs.m_nCopies),
145  //m_origLength(rhs.m_origLength),
146  m_origVolume(rhs.m_origVolume),
147  m_volume(rhs.m_volume),
148  m_safety(rhs.m_safety),
149  m_region(rhs.m_region),
150  m_label(rhs.m_label),
151  m_lockGeoShape(rhs.m_lockGeoShape),
152  m_splittableR(rhs.m_splittableR),
153  m_splittableZ(rhs.m_splittableZ),
154  m_envNum(rhs.m_envNum),
155  m_envParentNum(rhs.m_envParentNum),
156  m_zShift(rhs.m_zShift),
157  m_mutex()
158  {}
159 
160  void
161  ServiceVolume::reduceSize(double safety) {
162  // Don't do anything if its a very thin volume.
163  if (length() > 4. * safety) {
165  m_safety = safety;
166  }
167  std::lock_guard<std::mutex> lock(m_mutex);
168  m_geoShape = nullptr;
169  }
170 
171  void
172  ServiceVolume::setLabel(const std::string& name, int volId) {
173  std::ostringstream o;
174  o.fill('0');
175  o << name << std::setw(2) << volId;
176  m_label = o.str();
177  }
178 
179  std::string
181  if (m_volName.empty()) return m_label;
182 
183  return m_label + "_" + m_volName;
184  }
185 
186  void
188  std::cout << m_rmin << " "
189  << m_rmax << " "
190  << m_zmin << " "
191  << m_zmax << " "
192  << m_region << " "
193  << fullLabel()
194  << std::endl;
195  }
196 
197  const GeoShape*
199  std::lock_guard<std::mutex> lock(m_mutex);
200 
201  // If prebuilt then return
202  if (m_geoShape.get()) return m_geoShape.get();
203 
204  //
205  // Dimensions
206  //
207  //double rmin = rmin();
208  //double rmax = rmax();
209  //double rmin2 = rmin2();
210  //double rmax2 = rmax2();
211  //double phiLoc = phiLoc();
212  //double phiWidth = phiWidth();
213  //int sides = sides();
214  //const std::string & shapeType = shapeType();
215 
216  double halflength = 0.5 * length();
217 
218  //std::cout << "Building service volume " << logName << ": "
219  // << rmin << ", "
220  // << rmax << ", "
221  // << halflength << ", "
222  // << materialName << std::endl;
223 
224  const GeoShape* serviceShape = nullptr;
225  double volume = 0;
226 
227  // Check if service needs to be shifted
228  // if(fabs(m_zShift)>0.001)
229  // std::cout<<"SHIFTED SERVICE : "<<m_volName<<" "<<m_shapeType<<std::endl;
230 
231  if (m_shapeType.empty() || m_shapeType == "TUBE") {
232  serviceShape = new GeoTube(m_rmin, m_rmax, halflength);
233  } else if (m_shapeType == "TUBS") {
234  serviceShape = new GeoTubs(m_rmin, m_rmax, halflength, m_phiLoc, m_phiWidth);
235  } else if (m_shapeType == "CONS" || m_shapeType == "CONE") {
236  double phiWidthTmp = m_phiWidth;
237  if (m_shapeType == "CONE" || phiWidthTmp == 0) {
238  phiWidthTmp = 2 * M_PI;
239  }
240  serviceShape = new GeoCons(m_rmin, m_rmin2, m_rmax, m_rmax2, halflength, m_phiLoc, phiWidthTmp);
241  } else if (m_shapeType == "PGON") {
242  GeoPgon* shapeTmp = new GeoPgon(m_phiLoc, 2 * M_PI, m_sides);
243  shapeTmp->addPlane(-halflength, m_rmin, m_rmax);
244  shapeTmp->addPlane(halflength, m_rmin2, m_rmax2);
245  serviceShape = shapeTmp;
246  } else if (m_shapeType == "PGON2") {
247  // Radius defined at the side, not the corner
248  double alpha = M_PI / m_sides;
249  double cosalpha = cos(alpha);
250  double rminB = m_rmin / cosalpha;
251  double rmaxB = m_rmax / cosalpha;
252  double rmin2B = m_rmin2 / cosalpha;
253  double rmax2B = m_rmax2 / cosalpha;
254  GeoPgon* shapeTmp = new GeoPgon(m_phiLoc - alpha, 2 * M_PI, m_sides);
255  shapeTmp->addPlane(-halflength, rminB, rmaxB);
256  shapeTmp->addPlane(halflength, rmin2B, rmax2B);
257  serviceShape = shapeTmp;
258  } else if (m_shapeType == "PGON3" || m_shapeType == "PGON4") {
259  // Outer edge
260  GeoPgon* shapeTmp1 = nullptr;
261  if (m_shapeType == "PGON3") {
262  shapeTmp1 = new GeoPgon(m_phiLoc, 2 * M_PI, m_sides);
263  shapeTmp1->addPlane(-halflength, 0, m_rmax);
264  shapeTmp1->addPlane(halflength, 0, m_rmax2);
265  } else { //PGON4
266  double alpha = M_PI / m_sides;
267  double cosalpha = cos(alpha);
268  double rmaxB = m_rmax / cosalpha;
269  double rmax2B = m_rmax2 / cosalpha;
270  shapeTmp1 = new GeoPgon(m_phiLoc - alpha, 2 * M_PI, m_sides);
271  shapeTmp1->addPlane(-halflength, 0, rmaxB);
272  shapeTmp1->addPlane(halflength, 0, rmax2B);
273  }
274  // Don't trust boolean volume calculation.
275  volume = shapeTmp1->volume();
276  // Inner edge
277  GeoShape* shapeTmp2 = nullptr;
278  if (m_rmin == m_rmin2) {
279  shapeTmp2 = new GeoTube(0, m_rmin, halflength + 0.1 * Gaudi::Units::mm);
280  volume -= 2 * M_PI * m_rmin * m_rmin * halflength;
281  } else {
282  shapeTmp2 = new GeoCons(0, 0, m_rmin, m_rmin2, halflength + 0.1 * Gaudi::Units::mm, 0, 2 * M_PI);
283  volume -= 2 * M_PI * pow(0.5 * (m_rmin + m_rmin2), 2) * halflength;
284  }
285  serviceShape = &(shapeTmp1->subtract(*shapeTmp2));
286  }
287 // else if (m_shapeType == "PGON31"){
288 // // Outer edge
289 // GeoTube *shapeTmp1 = new GeoTube(0,m_rmax,halflength);
290 // halflength+=0.1*CLHEP::mm;
291 // double alpha = M_PI/m_sides;
292 // double cosalpha = cos(alpha);
293 // double rmaxB = m_rmin/cosalpha;
294 // double rmax2B = m_rmin2/cosalpha;
295 // GeoPgon* shapeTmp2 = new GeoPgon(m_phiLoc-alpha,2*M_PI,m_sides);
296 // shapeTmp2->addPlane(-halflength,0.,rmaxB);
297 // shapeTmp2->addPlane(halflength,0.,rmax2B);
298 // // Don't trust boolean volume calculation.
299 // volume = shapeTmp1->volume() - shapeTmp2->volume();
300 // serviceShape = &(shapeTmp1->subtract(*shapeTmp2));
301 // }
302  else if (m_shapeType == "ROD") {
303  serviceShape = new GeoTube(0, 0.5 * m_phiWidth, halflength);
304  } else if (m_shapeType == "ROD2") {
305  // std::cout<<"ROD2 : "<<m_rmin<<" "<<m_rmin2<<" "<<0.5*m_phiWidth<<" "<<halflength<<std::endl;
306  serviceShape = new GeoTube(m_rmin2 - m_rmin, 0.5 * m_phiWidth, halflength);
307  } else if (m_shapeType == "BOX") {
308  serviceShape = new GeoBox(0.5 * (m_rmax - m_rmin), 0.5 * m_phiWidth, halflength);
309  } else if (m_shapeType == "TRAP") {
310  double thickness = 0.5 * (m_rmax - m_rmin);
311  double averad = 0.5 * (m_rmin + m_rmax);
312  double w1 = 0.5 * m_phiWidth * m_rmin / averad;
313  double w2 = 0.5 * m_phiWidth * m_rmax / averad;
314  serviceShape = new GeoTrap(halflength, 0, 0, thickness, w1, w2, 0, thickness, w1, w2, 0);
315  } else {
316  // msg(MSG::ERROR) << "Unrecognized shape for services" << m_shapeType << endmsg;
317  std::cout << "ServiceVolume: ERROR: Unrecognized shape for services" << m_shapeType << std::endl;
318  }
319 
320  if (!volume && serviceShape != nullptr) volume = serviceShape->volume();
321 
322  m_volume = volume;
323  m_geoShape = serviceShape;
324  return serviceShape;
325  }
326 
327  double
329  // Make sure shape is already built.
330  getShape();
331  std::lock_guard<std::mutex> lock(m_mutex);
332  return m_volume;
333  }
334 
335  void
336  ServiceVolume::setGeoShape(const GeoShape* geoShape, double volume) {
337  m_geoShape.reset();
338  if (geoShape) {
339  m_volume = volume;
340  // We allow a volume to specified as the volume calculation for some shapes (ie boolean volumes) are unreliable.
341  // If volume is not supplied, get it from the shape itself.
342  if (!m_volume) m_volume = geoShape->volume();
343  m_geoShape = geoShape;
344  m_lockGeoShape = true; // This disables resetGeoShape().
345  setShapeType("CUSTOM");
346  } else {
347  // If pass null pointer we unlock the shape.
348  m_lockGeoShape = false;
349  }
350  }
351 
352  double
354  if (m_origVolume) return m_origVolume;
355 
356  return volume();
357  }
358 
359  void
361  m_splittableR = m_splittableZ = true;
362  if (m_shapeType == "CUSTOM") {
363  m_splittableR = m_splittableZ = false;
364  } else if (!(m_shapeType.empty() || m_shapeType == "TUBE" || m_shapeType == "TUBS")) {
365  m_splittableR = false;
366  }
367  }
368 
369 } // end namespace
InDetDD::ServiceVolume::print
void print() const
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:187
InDetDD::ServiceVolume::reduceSize
void reduceSize(double safety)
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:161
InDetDD::ServiceVolume::m_zmin
double m_zmin
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:105
InDetDD::ServiceVolume::m_phiWidth
double m_phiWidth
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:115
InDetDD::ServiceVolume::m_sides
int m_sides
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:117
InDetDD::ServiceVolume::m_zmax
double m_zmax
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:106
InDetDD::ServiceVolume::setLabel
void setLabel(const std::string &name, int volId)
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:172
InDetDD::ServiceVolume::m_rmin2
double m_rmin2
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:103
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
InDetDD::ServiceVolume::m_splittableR
bool m_splittableR
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:126
InDetDD::ServiceVolume::m_mutex
std::mutex m_mutex
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:133
InDetDD::ServiceVolume::m_rmin
double m_rmin
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:101
M_PI
#define M_PI
Definition: ActiveFraction.h:11
InDetDD::ServiceVolume::getShape
const GeoShape * getShape() const
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:198
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
InDetDD::ServiceVolume::length
double length() const
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:82
InDetDD::ServiceVolume::ServiceVolume
ServiceVolume()
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:97
InDetDD::ServiceVolume::m_origVolume
double m_origVolume
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:120
InDetDD::ServiceVolume::volume
double volume() const
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:328
InDetDD::ServiceVolume::m_splittableZ
bool m_splittableZ
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:127
InDetDD::ServiceVolume::m_shapeType
std::string m_shapeType
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:113
InDetDD::ServiceVolume::origVolume
double origVolume() const
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:353
InDetDD::ServiceVolume::m_safety
double m_safety
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:122
InDetDD::ServiceVolume::m_rmax2
double m_rmax2
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:104
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
InDetDD::ServiceVolume::fullLabel
std::string fullLabel() const
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:180
InDetDD::ServiceVolume::setGeoShape
void setGeoShape(const GeoShape *geoShape, double volume=0)
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:336
InDetDD::ServiceVolume::m_lockGeoShape
bool m_lockGeoShape
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:125
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
InDetDD::ServiceVolume::m_volName
std::string m_volName
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:112
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
InDetDD::ServiceVolume::setSplittable
void setSplittable()
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:360
InDetDD
Message Stream Member.
Definition: FakeTrackBuilder.h:8
InDetDD::ServiceVolume::m_phiLoc
double m_phiLoc
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:114
InDetDD::ServiceVolume::setShapeType
void setShapeType(const std::string &shapeType)
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:40
InDetDD::ServiceVolume::m_rmax
double m_rmax
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:102
ServiceVolume.h
InDetDD::ServiceVolume::m_label
std::string m_label
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:124
InDetDD::ServiceVolume::m_region
std::string m_region
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:123
InDetDD::ServiceVolume
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:24