ATLAS Offline Software
InDetGeoModelUtils/src/ServiceVolume.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 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 <format>
92 #include <iostream>
93 #include <string>
94 
95 namespace InDetDD {
97  : m_rmin(0),
98  m_rmax(0),
99  m_rmin2(0),
100  m_rmax2(0),
101  m_zmin(0),
102  m_zmax(0),
103  //m_volId(0),
104  m_zsymm(false),
105  m_geoShape(nullptr),
106  m_material(nullptr),
107  m_phiLoc(0),
108  m_phiWidth(0),
109  m_needsRotation(false),
110  m_sides(0),
111  m_nCopies(1),
112  //m_origLength(0),
113  m_origVolume(0),
114  m_volume(0),
115  m_safety(0),
116  m_lockGeoShape(0),
117  m_splittableR(true),
118  m_splittableZ(true),
119  m_envNum(0),
120  m_envParentNum(0),
121  m_zShift(0.),
122  m_mutex()
123  {}
124 
126  : m_rmin(rhs.m_rmin),
127  m_rmax(rhs.m_rmax),
128  m_rmin2(rhs.m_rmin2),
129  m_rmax2(rhs.m_rmax2),
130  m_zmin(rhs.m_zmin),
131  m_zmax(rhs.m_zmax),
132  //m_volId(rhs.m_volId),
133  m_zsymm(rhs.m_zsymm),
134  m_geoShape(rhs.m_geoShape),
135  m_material(rhs.m_material),
136  m_materialName(rhs.m_materialName),
137  m_volName(rhs.m_volName),
138  m_shapeType(rhs.m_shapeType),
139  m_phiLoc(rhs.m_phiLoc),
140  m_phiWidth(rhs.m_phiWidth),
141  m_needsRotation(rhs.m_needsRotation),
142  m_sides(rhs.m_sides),
143  m_nCopies(rhs.m_nCopies),
144  //m_origLength(rhs.m_origLength),
145  m_origVolume(rhs.m_origVolume),
146  m_volume(rhs.m_volume),
147  m_safety(rhs.m_safety),
148  m_region(rhs.m_region),
149  m_label(rhs.m_label),
150  m_lockGeoShape(rhs.m_lockGeoShape),
151  m_splittableR(rhs.m_splittableR),
152  m_splittableZ(rhs.m_splittableZ),
153  m_envNum(rhs.m_envNum),
154  m_envParentNum(rhs.m_envParentNum),
155  m_zShift(rhs.m_zShift),
156  m_mutex()
157  {}
158 
159  void
160  ServiceVolume::reduceSize(double safety) {
161  // Don't do anything if its a very thin volume.
162  if (length() > 4. * safety) {
164  m_safety = safety;
165  }
166  std::lock_guard<std::mutex> lock(m_mutex);
167  m_geoShape = nullptr;
168  }
169 
170  void
171  ServiceVolume::setLabel(const std::string& name, int volId) {
172  m_label = std::format("{:s}{:02d}", name, volId);
173  }
174 
175  std::string
177  if (m_volName.empty()) return m_label;
178 
179  return m_label + "_" + m_volName;
180  }
181 
182  void
184  std::cout << m_rmin << " "
185  << m_rmax << " "
186  << m_zmin << " "
187  << m_zmax << " "
188  << m_region << " "
189  << fullLabel()
190  << std::endl;
191  }
192 
193  const GeoShape*
195  std::lock_guard<std::mutex> lock(m_mutex);
196 
197  // If prebuilt then return
198  if (m_geoShape.get()) return m_geoShape.get();
199 
200  //
201  // Dimensions
202  //
203  //double rmin = rmin();
204  //double rmax = rmax();
205  //double rmin2 = rmin2();
206  //double rmax2 = rmax2();
207  //double phiLoc = phiLoc();
208  //double phiWidth = phiWidth();
209  //int sides = sides();
210  //const std::string & shapeType = shapeType();
211 
212  double halflength = 0.5 * length();
213 
214  //std::cout << "Building service volume " << logName << ": "
215  // << rmin << ", "
216  // << rmax << ", "
217  // << halflength << ", "
218  // << materialName << std::endl;
219 
220  const GeoShape* serviceShape = nullptr;
221  double volume = 0;
222 
223  // Check if service needs to be shifted
224  // if(fabs(m_zShift)>0.001)
225  // std::cout<<"SHIFTED SERVICE : "<<m_volName<<" "<<m_shapeType<<std::endl;
226 
227  if (m_shapeType.empty() || m_shapeType == "TUBE") {
228  serviceShape = new GeoTube(m_rmin, m_rmax, halflength);
229  } else if (m_shapeType == "TUBS") {
230  serviceShape = new GeoTubs(m_rmin, m_rmax, halflength, m_phiLoc, m_phiWidth);
231  } else if (m_shapeType == "CONS" || m_shapeType == "CONE") {
232  double phiWidthTmp = m_phiWidth;
233  if (m_shapeType == "CONE" || phiWidthTmp == 0) {
234  phiWidthTmp = 2 * M_PI;
235  }
236  serviceShape = new GeoCons(m_rmin, m_rmin2, m_rmax, m_rmax2, halflength, m_phiLoc, phiWidthTmp);
237  } else if (m_shapeType == "PGON") {
238  GeoPgon* shapeTmp = new GeoPgon(m_phiLoc, 2 * M_PI, m_sides);
239  shapeTmp->addPlane(-halflength, m_rmin, m_rmax);
240  shapeTmp->addPlane(halflength, m_rmin2, m_rmax2);
241  serviceShape = shapeTmp;
242  } else if (m_shapeType == "PGON2") {
243  // Radius defined at the side, not the corner
244  double alpha = M_PI / m_sides;
245  double cosalpha = cos(alpha);
246  double rminB = m_rmin / cosalpha;
247  double rmaxB = m_rmax / cosalpha;
248  double rmin2B = m_rmin2 / cosalpha;
249  double rmax2B = m_rmax2 / cosalpha;
250  GeoPgon* shapeTmp = new GeoPgon(m_phiLoc - alpha, 2 * M_PI, m_sides);
251  shapeTmp->addPlane(-halflength, rminB, rmaxB);
252  shapeTmp->addPlane(halflength, rmin2B, rmax2B);
253  serviceShape = shapeTmp;
254  } else if (m_shapeType == "PGON3" || m_shapeType == "PGON4") {
255  // Outer edge
256  GeoPgon* shapeTmp1 = nullptr;
257  if (m_shapeType == "PGON3") {
258  shapeTmp1 = new GeoPgon(m_phiLoc, 2 * M_PI, m_sides);
259  shapeTmp1->addPlane(-halflength, 0, m_rmax);
260  shapeTmp1->addPlane(halflength, 0, m_rmax2);
261  } else { //PGON4
262  double alpha = M_PI / m_sides;
263  double cosalpha = cos(alpha);
264  double rmaxB = m_rmax / cosalpha;
265  double rmax2B = m_rmax2 / cosalpha;
266  shapeTmp1 = new GeoPgon(m_phiLoc - alpha, 2 * M_PI, m_sides);
267  shapeTmp1->addPlane(-halflength, 0, rmaxB);
268  shapeTmp1->addPlane(halflength, 0, rmax2B);
269  }
270  // Don't trust boolean volume calculation.
271  volume = shapeTmp1->volume();
272  // Inner edge
273  GeoShape* shapeTmp2 = nullptr;
274  if (m_rmin == m_rmin2) {
275  shapeTmp2 = new GeoTube(0, m_rmin, halflength + 0.1 * Gaudi::Units::mm);
276  volume -= 2 * M_PI * m_rmin * m_rmin * halflength;
277  } else {
278  shapeTmp2 = new GeoCons(0, 0, m_rmin, m_rmin2, halflength + 0.1 * Gaudi::Units::mm, 0, 2 * M_PI);
279  volume -= 2 * M_PI * pow(0.5 * (m_rmin + m_rmin2), 2) * halflength;
280  }
281  serviceShape = &(shapeTmp1->subtract(*shapeTmp2));
282  }
283 // else if (m_shapeType == "PGON31"){
284 // // Outer edge
285 // GeoTube *shapeTmp1 = new GeoTube(0,m_rmax,halflength);
286 // halflength+=0.1*CLHEP::mm;
287 // double alpha = M_PI/m_sides;
288 // double cosalpha = cos(alpha);
289 // double rmaxB = m_rmin/cosalpha;
290 // double rmax2B = m_rmin2/cosalpha;
291 // GeoPgon* shapeTmp2 = new GeoPgon(m_phiLoc-alpha,2*M_PI,m_sides);
292 // shapeTmp2->addPlane(-halflength,0.,rmaxB);
293 // shapeTmp2->addPlane(halflength,0.,rmax2B);
294 // // Don't trust boolean volume calculation.
295 // volume = shapeTmp1->volume() - shapeTmp2->volume();
296 // serviceShape = &(shapeTmp1->subtract(*shapeTmp2));
297 // }
298  else if (m_shapeType == "ROD") {
299  serviceShape = new GeoTube(0, 0.5 * m_phiWidth, halflength);
300  } else if (m_shapeType == "ROD2") {
301  // std::cout<<"ROD2 : "<<m_rmin<<" "<<m_rmin2<<" "<<0.5*m_phiWidth<<" "<<halflength<<std::endl;
302  serviceShape = new GeoTube(m_rmin2 - m_rmin, 0.5 * m_phiWidth, halflength);
303  } else if (m_shapeType == "BOX") {
304  serviceShape = new GeoBox(0.5 * (m_rmax - m_rmin), 0.5 * m_phiWidth, halflength);
305  } else if (m_shapeType == "TRAP") {
306  double thickness = 0.5 * (m_rmax - m_rmin);
307  double averad = 0.5 * (m_rmin + m_rmax);
308  double w1 = 0.5 * m_phiWidth * m_rmin / averad;
309  double w2 = 0.5 * m_phiWidth * m_rmax / averad;
310  serviceShape = new GeoTrap(halflength, 0, 0, thickness, w1, w2, 0, thickness, w1, w2, 0);
311  } else {
312  // msg(MSG::ERROR) << "Unrecognized shape for services" << m_shapeType << endmsg;
313  std::cout << "ServiceVolume: ERROR: Unrecognized shape for services" << m_shapeType << std::endl;
314  }
315 
316  if (!volume && serviceShape != nullptr) volume = serviceShape->volume();
317 
318  m_volume = volume;
319  m_geoShape = serviceShape;
320  return serviceShape;
321  }
322 
323  double
325  // Make sure shape is already built.
326  getShape();
327  std::lock_guard<std::mutex> lock(m_mutex);
328  return m_volume;
329  }
330 
331  void
332  ServiceVolume::setGeoShape(const GeoShape* geoShape, double volume) {
333  m_geoShape.reset();
334  if (geoShape) {
335  m_volume = volume;
336  // We allow a volume to specified as the volume calculation for some shapes (ie boolean volumes) are unreliable.
337  // If volume is not supplied, get it from the shape itself.
338  if (!m_volume) m_volume = geoShape->volume();
339  m_geoShape = geoShape;
340  m_lockGeoShape = true; // This disables resetGeoShape().
341  setShapeType("CUSTOM");
342  } else {
343  // If pass null pointer we unlock the shape.
344  m_lockGeoShape = false;
345  }
346  }
347 
348  double
350  if (m_origVolume) return m_origVolume;
351 
352  return volume();
353  }
354 
355  void
357  m_splittableR = m_splittableZ = true;
358  if (m_shapeType == "CUSTOM") {
359  m_splittableR = m_splittableZ = false;
360  } else if (!(m_shapeType.empty() || m_shapeType == "TUBE" || m_shapeType == "TUBS")) {
361  m_splittableR = false;
362  }
363  }
364 
365 } // end namespace
InDetDD::ServiceVolume::print
void print() const
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:183
InDetDD::ServiceVolume::reduceSize
void reduceSize(double safety)
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:160
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
vtune_athena.format
format
Definition: vtune_athena.py:14
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:171
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:194
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:96
InDetDD::ServiceVolume::m_origVolume
double m_origVolume
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:120
InDetDD::ServiceVolume::volume
double volume() const
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:324
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:349
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:176
InDetDD::ServiceVolume::setGeoShape
void setGeoShape(const GeoShape *geoShape, double volume=0)
Definition: InDetGeoModelUtils/src/ServiceVolume.cxx:332
InDetDD::ServiceVolume::m_lockGeoShape
bool m_lockGeoShape
Definition: InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h:125
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
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:356
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