ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_Module.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "SCT_Module.h"
6
7#include "SCT_Identifier.h"
9
10#include "SCT_GeometryManager.h"
13
14#include "SCT_Sensor.h"
15#include "SCT_Hybrid.h"
16#include "SCT_Pigtail.h"
17#include "SCT_InnerSide.h"
18#include "SCT_OuterSide.h"
19#include "SCT_BaseBoard.h"
20
22
23#include "GeoModelRead/ReadGeoModel.h"
24#include "GeoModelKernel/GeoShape.h"
25#include "GeoModelKernel/GeoShapeShift.h"
26#include "GeoModelKernel/GeoShapeUnion.h"
27#include "GeoModelKernel/GeoBox.h"
28#include "GeoModelKernel/GeoLogVol.h"
29#include "GeoModelKernel/GeoPhysVol.h"
30#include "GeoModelKernel/GeoVPhysVol.h"
31#include "GeoModelKernel/GeoFullPhysVol.h"
32#include "GeoModelKernel/GeoNameTag.h"
33#include "GeoModelKernel/GeoIdentifierTag.h"
34#include "GeoModelKernel/GeoTransform.h"
35#include "GeoModelKernel/GeoAlignableTransform.h"
36#include "GeoModelKernel/GeoDefinitions.h"
37#include "GaudiKernel/SystemOfUnits.h"
38#include "GeoModelKernel/GeoShapeSubtraction.h"
39
40#include <cmath>
41#include <utility>
42
43SCT_Module::SCT_Module(const std::string & name,
44 InDetDD::SCT_DetectorManager* detectorManager,
45 SCT_GeometryManager* geometryManager,
46 SCT_MaterialManager* materials,
47 GeoModelIO::ReadGeoModel* sqliteReader,
48 std::shared_ptr<std::map<std::string, GeoFullPhysVol*>> mapFPV,
49 std::shared_ptr<std::map<std::string, GeoAlignableTransform*>> mapAX)
50: SCT_UniqueComponentFactory(name, detectorManager, geometryManager, materials, sqliteReader, std::move(mapFPV), std::move(mapAX))
51{
54}
55
56
60
61
62void
64{
65 const SCT_BarrelModuleParameters * parameters = m_geometryManager->barrelModuleParameters();
66 const SCT_GeneralParameters * generalParameters = m_geometryManager->generalParameters();
67 m_safety = generalParameters->safety();
68
69 m_sensorGap = parameters->moduleSensorToSensorGap();
70
71 m_stereoAngle = parameters->moduleStereoAngle();
72 int sign = parameters->moduleStereoUpperSign();
73 m_upperSide = parameters->moduleUpperSideNumber();
76
77 m_baseBoardOffsetY = parameters->baseBoardOffsetY();
78 m_baseBoardOffsetZ = parameters->baseBoardOffsetZ();
79}
80
81
82const GeoLogVol *
84{
85 // Create child components
86 m_outerSide = std::make_unique<SCT_OuterSide>("OuterSide", m_detectorManager, m_geometryManager, m_materials, m_sqliteReader, m_mapFPV, m_mapAX);
87 m_innerSide = std::make_unique<SCT_InnerSide>("InnerSide", m_detectorManager, m_geometryManager, m_materials, m_sqliteReader, m_mapFPV, m_mapAX);
88
89 if(m_sqliteReader) return nullptr;
90
91 m_baseBoard = std::make_unique<SCT_BaseBoard>("BaseBoard", m_detectorManager, m_geometryManager, m_materials);
92 //
93 // We have 2 envelopes.
94 // 1. It contains two sensors and baseBoard.
95 // 2. It contains hybrid and pigtail.
96 //
97 // See "doc/cornerName.ps".
98 //
99
100 // We need to take into account the safety incorporated in the inner and outer side
101 // envelopes.
102 double sensorWidth = m_innerSide->sensor()->width() + m_safety;
103 double sensorLength = m_innerSide->sensor()->length() + m_safety;
104 double innerSideHybridWidth = m_innerSide->hybrid()->width() + m_safety;
105 double innerSideHybridLength = m_innerSide->hybrid()->length() + m_safety;
106 double outerSideHybridWidth = m_outerSide->hybrid()->width() + m_safety;
107 double outerSideHybridLength = m_outerSide->hybrid()->length() + m_safety;
108 double baseBoardWidth = m_baseBoard->width() + m_safety;
109 double baseBoardLength = m_baseBoard->length() + m_safety;
110 double outerSidePigtailLength = m_outerSide->pigtail()->length() + m_safety;
111
112
113 // Define constants for convenience.
114 // for corner of outer side sensor.
115 GeoTrf::Vector3D a(0.0, 0.5 * sensorWidth, 0.5 * sensorLength);
116 GeoTrf::Vector3D b(0.0, -0.5 * sensorWidth, a.z());
117 GeoTrf::Vector3D c(0.0, b.y(),-0.5 * sensorLength);
118 GeoTrf::Vector3D d(0.0, a.y(), c.z());
119
120 // for corner of inner side sensor.
121 GeoTrf::Vector3D e(0.0, a.y(), a.z());
122 GeoTrf::Vector3D f(0.0, b.y(), b.z());
123 GeoTrf::Vector3D g(0.0, c.y(), c.z());
124 GeoTrf::Vector3D h(0.0, d.y(), d.z());
125
126 // for corner of base board.
127 GeoTrf::Vector3D u(0.0,
128 m_baseBoardOffsetY + 0.5*baseBoardWidth,
129 m_baseBoardOffsetZ + 0.5*baseBoardLength);
130 GeoTrf::Vector3D v(0.0, m_baseBoardOffsetY - 0.5*baseBoardWidth, u.z());
131 GeoTrf::Vector3D w(0.0, v.y(), m_baseBoardOffsetZ - 0.5*baseBoardLength);
132 GeoTrf::Vector3D x(0.0, u.y(),w.z());
133
134 // for corner of hybrid, connectorouter and pigtail of outer side.
135 GeoTrf::Vector3D i(0.0,
136 0.5*outerSideHybridWidth,
137 m_outerSide->hybridOffsetZ() + 0.5*outerSidePigtailLength);
138 GeoTrf::Vector3D l(0.0,
139 -0.5*outerSideHybridWidth - m_outerSide->pigtail()->width(), i.z());
140 GeoTrf::Vector3D m(0.0, l.y(),
141 m_outerSide->hybridOffsetZ() - 0.5*outerSidePigtailLength);
142 GeoTrf::Vector3D p(0.0, i.y(),
143 m.z());
144
145
146
147 // for corner of hybrid and interConnect of inner side.
148 GeoTrf::Vector3D q(0.0, 0.5*outerSideHybridWidth, m_outerSide->hybridOffsetZ() + 0.5*outerSideHybridLength );
149 GeoTrf::Vector3D r(0.0, -0.5*innerSideHybridWidth, q.z());
150 GeoTrf::Vector3D s(0.0, r.y(), m_innerSide->hybridOffsetZ() - 0.5*innerSideHybridLength);
151 GeoTrf::Vector3D t(0.0, q.y(), s.z());
152
153 // All points turn +-20 mGaudi::Units::rad around physical center of module.
154 a = GeoTrf::RotateX3D(m_stereoOuter/Gaudi::Units::radian)*a;
155 b = GeoTrf::RotateX3D(m_stereoOuter/Gaudi::Units::radian)*b;
156 c = GeoTrf::RotateX3D(m_stereoOuter/Gaudi::Units::radian)*c;
157 d = GeoTrf::RotateX3D(m_stereoOuter/Gaudi::Units::radian)*d;
158
159 e = GeoTrf::RotateX3D(m_stereoInner/Gaudi::Units::radian)*e;
160 f = GeoTrf::RotateX3D(m_stereoInner/Gaudi::Units::radian)*f;
161 g = GeoTrf::RotateX3D(m_stereoInner/Gaudi::Units::radian)*g;
162 h = GeoTrf::RotateX3D(m_stereoInner/Gaudi::Units::radian)*h;
163
164 i = GeoTrf::RotateX3D(m_stereoOuter/Gaudi::Units::radian)*i;
165 //k.rotateX(m_stereoOuter/Gaudi::Units::radian);
166 l = GeoTrf::RotateX3D(m_stereoOuter/Gaudi::Units::radian)*l;
167 m = GeoTrf::RotateX3D(m_stereoOuter/Gaudi::Units::radian)*m;
168 //n.rotateX(m_stereoOuter/Gaudi::Units::radian);
169 p = GeoTrf::RotateX3D(m_stereoOuter/Gaudi::Units::radian)*p;
170
171 q = GeoTrf::RotateX3D(m_stereoInner/Gaudi::Units::radian)*q;
172 r = GeoTrf::RotateX3D(m_stereoInner/Gaudi::Units::radian)*r;
173 s = GeoTrf::RotateX3D(m_stereoInner/Gaudi::Units::radian)*s;
174 t = GeoTrf::RotateX3D(m_stereoInner/Gaudi::Units::radian)*t;
175
176 // Calculate demension of envelope1.
177 const double z_ab = std::max(a.z(), b.z());
178 const double z_ef = std::max(e.z(), f.z());
179 const double z_cd = std::min(c.z(), d.z());
180 const double z_gh = std::min(g.z(), h.z());
181
182 const double y_ad = std::max(a.y(), d.y());
183 const double y_eh = std::max(e.y(), h.y());
184 const double y_bc = std::min(b.y(), c.y());
185 const double y_fg = std::min(f.y(), g.y());
186
187 const double zmaxEnv1 = std::max(z_ab, z_ef);
188 const double zminEnv1 = std::min(z_cd, z_gh);
189
190 const double ypre_maxEnv1 = std::max(y_ad, y_eh);
191 const double ypre_minEnv1 = std::min(y_bc, y_fg);
192
193 const double ymaxEnv1 = std::max(ypre_maxEnv1, u.y());
194 const double yminEnv1 = std::min(ypre_minEnv1, v.y());
195
196 // some temporary value.
197 const double thicknessEnv1 = m_sensorGap + 2.0*m_outerSide->sensor()->thickness();
198 const double lengthEnv1 = zmaxEnv1 - zminEnv1;
199 const double widthEnv1 = ymaxEnv1 - yminEnv1;
200
201 // Center of evnelope1.
202 const double xCenterEnv1 = 0.0;
203 const double yCenterEnv1 = yminEnv1 + 0.5*widthEnv1;
204 const double zCenterEnv1 = zmaxEnv1 - 0.5*lengthEnv1;
205
206 m_env1RefPointVector = std::make_unique<GeoTrf::Vector3D>(-xCenterEnv1, -yCenterEnv1, -zCenterEnv1);
207
208 // Calculate demension of envelope2.
209 const double z_ikl = std::max(i.z(), l.z());
210 const double z_qr = std::max(q.z(), r.z());
211 const double z_mnp = std::min(m.z(), p.z());
212 const double z_st = std::min(s.z(), t.z());
213
214 const double y_ip = std::max(i.y(), p.y());
215 const double y_qt = std::max(q.y(), t.y());
216 const double y_lm = std::min(l.y(), m.y());
217 const double y_rs = std::min(r.y(), s.y());
218
219 const double zmaxEnv2 = std::max(z_ikl, z_qr);
220 const double zminEnv2 = std::min(z_mnp, z_st);
221
222 const double ymaxEnv2 = std::max(y_ip, y_qt);
223 const double yminEnv2 = std::min(y_lm, y_rs);
224
225 const double thicknessEnv2 = 2.0*(m_outerSide->hybridOffsetX() +
226 0.5*m_innerSide->sensor()->thickness() +
227 0.5*m_sensorGap +
228 0.5*m_outerSide->hybrid()->thickness());
229 const double lengthEnv2 = zmaxEnv2 - zminEnv2;
230 const double widthEnv2 = ymaxEnv2 - yminEnv2;
231
232 // Center of envelope2.
233 const double xCenterEnv2 = 0.0;
234 const double yCenterEnv2 = ymaxEnv2 - 0.5*widthEnv2;
235 const double zCenterEnv2 = zmaxEnv2 - 0.5*lengthEnv2;
236
237 m_env2RefPointVector = std::make_unique<GeoTrf::Vector3D>(-xCenterEnv2, -yCenterEnv2, -zCenterEnv2);
238
239 // Calculate dimension of subbox
240 const double xmaxSubBox = - 0.5*m_baseBoard->thickness() - m_safety;
241 const double xminSubBox = - 0.5*thicknessEnv2 - 2.0*m_safety;
242
243 const double ymaxSubBox = std::min(r.y(), s.y()) - m_safety;
244 const double yminSubBox = yminEnv2 - 2.0*m_safety;
245
246 const double zmaxSubBox = zmaxEnv1 + 2.0*m_safety;
247 const double zminSubBox = zminEnv1 - 2.0*m_safety;
248
249 const double thicknessSubBox = xmaxSubBox - xminSubBox;
250 const double widthSubBox = ymaxSubBox - yminSubBox;
251 const double lengthSubBox = zmaxSubBox - zminSubBox;
252
253 // Center of subbox.
254 const double xCenterSubBox = xmaxSubBox - 0.5*thicknessSubBox;
255 const double yCenterSubBox = ymaxSubBox - 0.5*widthSubBox;
256 const double zCenterSubBox = zmaxSubBox - 0.5*lengthSubBox;
257
258
259 m_env1Thickness = thicknessEnv1 + 2*m_safety;
260 m_env1Width = widthEnv1 + 2*m_safety;
261 m_env1Length = lengthEnv1 + 2*m_safety;
262
263 m_env2Thickness = thicknessEnv2 + 2*m_safety;
264 m_env2Width = widthEnv2 + 2*m_safety;
265 m_env2Length = lengthEnv2 + 2*m_safety;
266
267 // Envelope 2 defines the overall thickness. NB. The ski assumes the
268 // the envelope "thickness" is centered on x, which it is.
273
274 // Calculate a few things.
275 const double OSPosX = 0.5*m_sensorGap + 0.5*m_innerSide->sensor()->thickness();
276 const double ISPosX = -(0.5*m_sensorGap + 0.5*m_innerSide->sensor()->thickness());
277
278 //
279 // Make an envelope for the whole module.
280 //
281 const GeoBox * envelope1 = new GeoBox(0.5*m_env1Thickness, 0.5*m_env1Width, 0.5*m_env1Length);
282 const GeoBox * envelope2 = new GeoBox(0.5*m_env2Thickness, 0.5*m_env2Width, 0.5*m_env2Length);
283
284 const GeoBox * subBox = new GeoBox(0.5*thicknessSubBox, 0.5*widthSubBox, 0.6*lengthSubBox);
285
286 // In the following, envelope1 and envelope2 are added and SUBBOX is pulled.
287 const GeoShape & moduleEnvelope = (*envelope1 << GeoTrf::Translate3D(xCenterEnv1, yCenterEnv1, zCenterEnv1)).
288 add(*envelope2 << GeoTrf::Translate3D(xCenterEnv2, yCenterEnv2, zCenterEnv2)).
289 subtract(*subBox << GeoTrf::Translate3D(xCenterSubBox, yCenterSubBox, zCenterSubBox));
290
291 const GeoLogVol * moduleLog = new GeoLogVol(getName(), &moduleEnvelope, m_materials->gasMaterial());
292
293 //
294 // inner side
295 //
296 GeoTrf::Transform3D rotInner = GeoTrf::RotateX3D(m_stereoInner) * GeoTrf::RotateZ3D(180*Gaudi::Units::deg);
297 m_innerSidePos = std::make_unique<GeoTrf::Transform3D>(GeoTrf::Transform3D(GeoTrf::Translation3D(ISPosX, 0.0, 0.0)*rotInner));
298
299 //
300 // outer side
301 //
302 GeoTrf::RotateX3D rotOuter(m_stereoOuter);
303 m_outerSidePos = std::make_unique<GeoTrf::Transform3D>(GeoTrf::Transform3D(GeoTrf::Translation3D(OSPosX, 0.0, 0.0)*rotOuter));
304
305 //
306 // base board
307 //
308 const double baseBoardPosY = m_baseBoardOffsetY;
309 const double baseBoardPosZ = m_baseBoardOffsetZ;
310 m_baseBoardPos = std::make_unique<GeoTrf::Translate3D>(0.0, baseBoardPosY, baseBoardPosZ);
311
312 return moduleLog;
313}
314
315
316GeoVPhysVol *
318{
319 GeoFullPhysVol * module=nullptr;
320
321 if(!m_sqliteReader){
322
323 module=new GeoFullPhysVol(m_logVolume);
324
325
326 // We make these fullPhysVols for the alignment code.
327 // We probably should make the transform for the sensor
328 // alignable rather than the "side" to save making an extra full phys volume.
329
330 //
331 // Build the module
332 //
333 // Add Baseboard
334 GeoTransform * baseBoardTransform = new GeoTransform(*m_baseBoardPos);
335 module->add(baseBoardTransform);
336 module->add(m_baseBoard->getVolume());
337
338 // Add innerside
339 GeoAlignableTransform * innerTransform = new GeoAlignableTransform(*m_innerSidePos);
340 module->add(innerTransform);
341 int innerSideNumber = (m_upperSide) ? 0 : 1;
342 module->add(new GeoNameTag("Side#"+intToString(innerSideNumber))); // Identifier side=0
343 module->add(new GeoIdentifierTag(innerSideNumber));
344 id.setSide(innerSideNumber);
345 Identifier innerId = id.getWaferId();
346 GeoVPhysVol * innerSide = m_innerSide->build(id);
347 module->add(innerSide);
348 // Store alignable transform
349 m_detectorManager->addAlignableTransform(0, innerId, innerTransform, innerSide);
350
351 // Add outerside
352 GeoAlignableTransform * outerTransform = new GeoAlignableTransform(*m_outerSidePos);
353 module->add(outerTransform);
354 int outerSideNumber = m_upperSide;
355 module->add(new GeoNameTag("Side#"+intToString(outerSideNumber))); // Identifier side=1
356 module->add(new GeoIdentifierTag(outerSideNumber));
357 id.setSide(outerSideNumber);
358 Identifier outerId = id.getWaferId();
359 GeoVPhysVol * outerSide = m_outerSide->build(id);
360 module->add(outerSide);
361 // Store alignable transform
362 m_detectorManager->addAlignableTransform(0, outerId, outerTransform, outerSide);
363 } else
364 {
365
366 // Add innerside
367 int innerSideNumber = (m_upperSide) ? 0 : 1;
368 id.setSide(innerSideNumber);
369 // Store alignable transform
370 Identifier innerId = id.getWaferId();
371 m_innerSide->build(id);
372
373 std::string key="Side#"+intToString(innerSideNumber)+"_"+std::to_string(id.getBarrelEC())+"_"+std::to_string(id.getLayerDisk())+"_"+std::to_string(id.getEtaModule())+"_"+std::to_string(id.getPhiModule());
374 m_detectorManager->addAlignableTransform(0, innerId, (*m_mapAX)[key], (*m_mapFPV)[key]);
375
376
377 // Add outerside
378 int outerSideNumber = m_upperSide;
379 id.setSide(outerSideNumber);
380 // Store alignable transform
381 Identifier outerId = id.getWaferId();
382 m_outerSide->build(id);
383
384 key="Side#"+intToString(outerSideNumber)+"_"+std::to_string(id.getBarrelEC())+"_"+std::to_string(id.getLayerDisk())+"_"+std::to_string(id.getEtaModule())+"_"+std::to_string(id.getPhiModule());
385 m_detectorManager->addAlignableTransform(0, outerId, (*m_mapAX)[key], (*m_mapFPV)[key]);
386
387 }
388 return module;
389}
static Double_t a
int sign(int a)
#define x
Header file for AthHistogramAlgorithm.
Dedicated detector manager extending the functionality of the SiDetectorManager with dedicated SCT in...
const std::string & getName() const
std::string intToString(int i) const
InDetDD::SCT_DetectorManager * m_detectorManager
SCT_GeometryManager * m_geometryManager
SCT_MaterialManager * m_materials
const SCT_OuterSide * outerSide() const
Definition SCT_Module.h:69
std::unique_ptr< SCT_BaseBoard > m_baseBoard
Definition SCT_Module.h:102
double m_stereoOuter
Definition SCT_Module.h:95
void getParameters()
std::unique_ptr< GeoTrf::Vector3D > m_env1RefPointVector
Definition SCT_Module.h:108
double m_stereoInner
Definition SCT_Module.h:94
double m_env1Width
Definition SCT_Module.h:82
double m_sensorGap
Definition SCT_Module.h:93
double m_env1Thickness
Definition SCT_Module.h:81
double m_length
Definition SCT_Module.h:79
double m_baseBoardOffsetZ
Definition SCT_Module.h:91
double thickness() const
Definition SCT_Module.h:44
const SCT_InnerSide * innerSide() const
Definition SCT_Module.h:68
double m_env2Width
Definition SCT_Module.h:85
double m_env2Thickness
Definition SCT_Module.h:84
std::unique_ptr< GeoTrf::Transform3D > m_innerSidePos
Definition SCT_Module.h:104
double m_env2Length
Definition SCT_Module.h:86
std::unique_ptr< GeoTrf::Translate3D > m_baseBoardPos
Definition SCT_Module.h:106
double m_env1Length
Definition SCT_Module.h:83
double m_safety
Definition SCT_Module.h:98
virtual GeoVPhysVol * build(SCT_Identifier id)
std::unique_ptr< SCT_InnerSide > m_innerSide
Definition SCT_Module.h:100
std::unique_ptr< SCT_OuterSide > m_outerSide
Definition SCT_Module.h:101
double m_width
Definition SCT_Module.h:78
double m_baseBoardOffsetY
Definition SCT_Module.h:90
int m_upperSide
Definition SCT_Module.h:97
std::unique_ptr< GeoTrf::Vector3D > m_env2RefPointVector
Definition SCT_Module.h:109
virtual const GeoLogVol * preBuild()
double m_activeWidth
Definition SCT_Module.h:88
std::unique_ptr< GeoTrf::Transform3D > m_outerSidePos
Definition SCT_Module.h:105
double m_thickness
Definition SCT_Module.h:77
SCT_Module(const std::string &name, InDetDD::SCT_DetectorManager *detectorManager, SCT_GeometryManager *geometryManager, SCT_MaterialManager *materials, GeoModelIO::ReadGeoModel *sqliteReader, std::shared_ptr< std::map< std::string, GeoFullPhysVol * > > mapFPV, std::shared_ptr< std::map< std::string, GeoAlignableTransform * > > mapAX)
double m_stereoAngle
Definition SCT_Module.h:96
SCT_UniqueComponentFactory(const std::string &name, InDetDD::SCT_DetectorManager *detectorManager, SCT_GeometryManager *geometryManager, SCT_MaterialManager *materials=nullptr, GeoModelIO::ReadGeoModel *sqliteReader=nullptr, std::shared_ptr< std::map< std::string, GeoFullPhysVol * > > mapFPV=nullptr, std::shared_ptr< std::map< std::string, GeoAlignableTransform * > > mapAX=nullptr)
std::shared_ptr< std::map< std::string, GeoFullPhysVol * > > m_mapFPV
std::shared_ptr< std::map< std::string, GeoAlignableTransform * > > m_mapAX
GeoModelIO::ReadGeoModel * m_sqliteReader
bool add(const std::string &hname, TKey *tobj)
Definition fastadd.cxx:55
int r
Definition globals.cxx:22
STL namespace.