Project
Loading...
Searching...
No Matches
Geometry.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include <TGeoManager.h>
13#include <TGeoPhysicalNode.h>
14#include <TMath.h>
15#include <TVirtualMC.h>
16#include <fairlogger/Logger.h>
17
19#include "MathUtils/Utils.h" // math_utils::bit2Mask
20#include "TRDBase/Geometry.h"
21#include "TRDBase/PadPlane.h"
22
23using namespace o2::trd;
24using namespace o2::trd::constants;
25
26//_____________________________________________________________________________
27
28const o2::detectors::DetID Geometry::sDetID(o2::detectors::DetID::TRD);
29
30//_____________________________________________________________________________
31Geometry::Geometry() : GeometryBase(), o2::detectors::DetMatrixCacheIndirect(sDetID)
32{
33 createPadPlaneArray();
34}
35
36//_____________________________________________________________________________
37bool Geometry::rotateBack(int det, const float* const loc, float* glb) const
38{
39 //
40 // Rotates a chambers to transform the corresponding local frame
41 // coordinates <loc> into the coordinates of the ALICE restframe <glb>.
42 //
43
44 int sector = getSector(det);
45 float phi = 2.0 * TMath::Pi() / (float)NSECTOR * ((float)sector + 0.5);
46
47 glb[0] = loc[0] * TMath::Cos(phi) - loc[1] * TMath::Sin(phi);
48 glb[1] = loc[0] * TMath::Sin(phi) + loc[1] * TMath::Cos(phi);
49 glb[2] = loc[2];
50
51 return true;
52}
53
54//_____________________________________________________________________________
56{
57 //
58 // Creates the array of PadPlane objects
59 //
60
61 for (int ilayer = 0; ilayer < NLAYER; ilayer++) {
62 for (int istack = 0; istack < NSTACK; istack++) {
63 createPadPlane(ilayer, istack);
64 }
65 }
66}
67
68//_____________________________________________________________________________
69void Geometry::createPadPlane(int ilayer, int istack)
70{
71 //
72 // Creates an PadPlane object
73 //
74 int ipp = getDetectorSec(ilayer, istack);
75 auto& padPlane = mPadPlanes[ipp];
76
77 padPlane.setLayer(ilayer);
78 padPlane.setStack(istack);
79
80 padPlane.setRowSpacing(0.0);
81 padPlane.setColSpacing(0.0);
82
83 padPlane.setLengthRim(1.0);
84 padPlane.setWidthRim(0.5);
85
86 padPlane.setNcols(144);
87
88 padPlane.setAnodeWireOffset(0.25);
89
90 //
91 // The pad plane parameter
92 //
93 const float kTiltAngle = 2.0;
94 switch (ilayer) {
95 case 0:
96 if (istack == 2) {
97 // L0C0 type
98 padPlane.setNrows(12);
99 padPlane.setLength(108.0);
100 padPlane.setLengthOPad(8.0);
101 padPlane.setLengthIPad(9.0);
102 } else {
103 // L0C1 type
104 padPlane.setNrows(16);
105 padPlane.setLength(122.0);
106 padPlane.setLengthOPad(7.5);
107 padPlane.setLengthIPad(7.5);
108 }
109 padPlane.setWidth(92.2);
110 padPlane.setWidthOPad(0.515);
111 padPlane.setWidthIPad(0.635);
112 padPlane.setTiltingAngle(-kTiltAngle);
113 break;
114 case 1:
115 if (istack == 2) {
116 // L1C0 type
117 padPlane.setNrows(12);
118 padPlane.setLength(108.0);
119 padPlane.setLengthOPad(8.0);
120 padPlane.setLengthIPad(9.0);
121 } else {
122 // L1C1 type
123 padPlane.setNrows(16);
124 padPlane.setLength(122.0);
125 padPlane.setLengthOPad(7.5);
126 padPlane.setLengthIPad(7.5);
127 }
128 padPlane.setWidth(96.6);
129 padPlane.setWidthOPad(0.585);
130 padPlane.setWidthIPad(0.665);
131 padPlane.setTiltingAngle(kTiltAngle);
132 break;
133 case 2:
134 if (istack == 2) {
135 // L2C0 type
136 padPlane.setNrows(12);
137 padPlane.setLength(108.0);
138 padPlane.setLengthOPad(8.0);
139 padPlane.setLengthIPad(9.0);
140 } else {
141 // L2C1 type
142 padPlane.setNrows(16);
143 padPlane.setLength(129.0);
144 padPlane.setLengthOPad(7.5);
145 padPlane.setLengthIPad(8.0);
146 }
147 padPlane.setWidth(101.1);
148 padPlane.setWidthOPad(0.705);
149 padPlane.setWidthIPad(0.695);
150 padPlane.setTiltingAngle(-kTiltAngle);
151 break;
152 case 3:
153 if (istack == 2) {
154 // L3C0 type
155 padPlane.setNrows(12);
156 padPlane.setLength(108.0);
157 padPlane.setLengthOPad(8.0);
158 padPlane.setLengthIPad(9.0);
159 } else {
160 // L3C1 type
161 padPlane.setNrows(16);
162 padPlane.setLength(136.0);
163 padPlane.setLengthOPad(7.5);
164 padPlane.setLengthIPad(8.5);
165 }
166 padPlane.setWidth(105.5);
167 padPlane.setWidthOPad(0.775);
168 padPlane.setWidthIPad(0.725);
169 padPlane.setTiltingAngle(kTiltAngle);
170 break;
171 case 4:
172 if (istack == 2) {
173 // L4C0 type
174 padPlane.setNrows(12);
175 padPlane.setLength(108.0);
176 padPlane.setLengthOPad(8.0);
177 } else {
178 // L4C1 type
179 padPlane.setNrows(16);
180 padPlane.setLength(143.0);
181 padPlane.setLengthOPad(7.5);
182 }
183 padPlane.setWidth(109.9);
184 padPlane.setWidthOPad(0.845);
185 padPlane.setLengthIPad(9.0);
186 padPlane.setWidthIPad(0.755);
187 padPlane.setTiltingAngle(-kTiltAngle);
188 break;
189 case 5:
190 if (istack == 2) {
191 // L5C0 type
192 padPlane.setNrows(12);
193 padPlane.setLength(108.0);
194 padPlane.setLengthOPad(8.0);
195 } else {
196 // L5C1 type
197 padPlane.setNrows(16);
198 padPlane.setLength(145.0);
199 padPlane.setLengthOPad(8.5);
200 }
201 padPlane.setWidth(114.4);
202 padPlane.setWidthOPad(0.965);
203 padPlane.setLengthIPad(9.0);
204 padPlane.setWidthIPad(0.785);
205 padPlane.setTiltingAngle(kTiltAngle);
206 break;
207 };
208
209 //
210 // The positions of the borders of the pads
211 //
212 // Row direction
213 //
214 float row = CLENGTH[ilayer][istack] / 2.0 - RPADW - padPlane.getLengthRim();
215 for (int ir = 0; ir < padPlane.getNrows(); ir++) {
216 padPlane.setPadRow(ir, row);
217 row -= padPlane.getRowSpacing();
218 if (ir == 0) {
219 row -= padPlane.getLengthOPad();
220 } else {
221 row -= padPlane.getLengthIPad();
222 }
223 }
224 //
225 // Column direction
226 //
227 float col = -CWIDTH[ilayer] / 2.0 - CROW + padPlane.getWidthRim();
228 for (int ic = 0; ic < padPlane.getNcols(); ic++) {
229 padPlane.setPadCol(ic, col);
230 col += padPlane.getColSpacing();
231 if (ic == 0) {
232 col += padPlane.getWidthOPad();
233 } else {
234 col += padPlane.getWidthIPad();
235 }
236 }
237 // Calculate the offset to translate from the local ROC system into
238 // the local supermodule system, which is used for clusters
239 float rowTmp = CLENGTH[ilayer][0] + CLENGTH[ilayer][1] + CLENGTH[ilayer][2] / 2.0;
240 for (int jstack = 0; jstack < istack; jstack++) {
241 rowTmp -= CLENGTH[ilayer][jstack];
242 }
243 padPlane.setPadRowSMOffset(rowTmp - CLENGTH[ilayer][istack] / 2.0);
244}
245
246void Geometry::createVolume(const char* name, const char* shape, int nmed, double* upar, int np)
247{
248 TVirtualMC::GetMC()->Gsvolu(name, shape, nmed, upar, np);
249
250 // add to sensitive volumes for TRD if matching criterion
251 // these are coded with J+K in the second character (according to AliTRDv1.cxx of AliROOT)
252 if (name[1] == 'J' || name[1] == 'K') {
253 mSensitiveVolumeNames.emplace_back(name);
254 }
255}
256
257//_____________________________________________________________________________
258void Geometry::createGeometry(std::vector<int> const& idtmed)
259{
260 //
261 // Create the TRD geometry
262
263 if (!gGeoManager) {
264 // RSTODO: in future there will be a method to load matrices from the CDB
265 LOG(fatal) << "Geometry is not loaded";
266 }
267
268 createVolumes(idtmed);
269}
270
271void Geometry::createVolumes(std::vector<int> const& idtmed)
272{
273 //
274 // Create the TRD geometry volumes
275 //
276 //
277 // Names of the TRD volumina (xx = detector number):
278 //
279 // Volume (Air) wrapping the readout chamber components
280 // UTxx includes: UAxx, UDxx, UFxx, UUxx
281 //
282 // Lower part of the readout chambers (drift volume + radiator)
283 // UAxx Aluminum frames (Al)
284 //
285 // Upper part of the readout chambers (readout plane + fee)
286 // UDxx Wacosit frames of amp. region (Wacosit)
287 // UFxx Aluminum frame of back panel (Al)
288 //
289 // Services on chambers (cooling, cables, MCMs, DCS boards, ...)
290 // UUxx Volume containing the services (Air)
291 //
292 // Material layers inside sensitive area:
293 // Name Description Mat. Thick. Dens. Radl. X/X_0
294 //
295 // URMYxx Mylar layers (x2) Mylar 0.0015 1.39 28.5464 0.005%
296 // URCBxx Carbon layer (x2) Carbon 0.0055 1.75 24.2824 0.023%
297 // URGLxx Glue on the carbon layers (x2) Araldite 0.0065 1.12 37.0664 0.018%
298 // URRHxx Rohacell layer (x2) Rohacell 0.8 0.075 536.005 0.149%
299 // URFBxx Fiber mat layer PP 3.186 0.068 649.727 0.490%
300 //
301 // UJxx Drift region Xe/CO2 3.0 0.00495 1792.37 0.167%
302 // UKxx Amplification region Xe/CO2 0.7 0.00495 1792.37 0.039%
303 // UWxx Wire planes (x2) Copper 0.00011 8.96 1.43503 0.008%
304 //
305 // UPPDxx Copper of pad plane Copper 0.0025 8.96 1.43503 0.174%
306 // UPPPxx PCB of pad plane G10 0.0356 2.0 14.9013 0.239%
307 // UPGLxx Glue on pad planes Araldite 0.0923 1.12 37.0664 0.249%
308 // + add. glue (ca. 600g) Araldite 0.0505 1.12 37.0663 0.107%
309 // UPCBxx Carbon fiber mats (x2) Carbon 0.019 1.75 24.2824 0.078%
310 // UPHCxx Honeycomb structure Aramide 2.0299 0.032 1198.84 0.169%
311 // UPPCxx PCB of readout board G10 0.0486 2.0 14.9013 0.326%
312 // UPRDxx Copper of readout board Copper 0.0057 8.96 1.43503 0.404%
313 // UPELxx Electronics + cables Copper 0.0029 8.96 1.43503 0.202%
314 //
315
316 const int kNparTrd = 4;
317 const int kNparCha = 3;
318
319 double xpos;
320 double ypos;
321 double zpos;
322
323 double parTrd[kNparTrd];
324 double parCha[kNparCha];
325
326 const int kTag = 100;
327 char cTagV[kTag];
328 char cTagM[kTag];
329
330 // There are three TRD volumes for the supermodules in order to accomodate
331 // the different arrangements in front of PHOS
332 // UTR1: Default supermodule
333 // UTR2: Supermodule in front of PHOS with double carbon cover
334 // UTR3: As UTR2, but w/o middle stack
335 // UTR4: Sector 17 with missing chamber L4S4
336 //
337 // The mother volume for one sector (Air), full length in z-direction
338 // Provides material for side plates of super module
339 parTrd[0] = SWIDTH1 / 2.0;
340 parTrd[1] = SWIDTH2 / 2.0;
341 parTrd[2] = SLENGTH / 2.0;
342 parTrd[3] = SHEIGHT / 2.0;
343 createVolume("UTR1", "TRD1", idtmed[2], parTrd, kNparTrd);
344 createVolume("UTR2", "TRD1", idtmed[2], parTrd, kNparTrd);
345 createVolume("UTR3", "TRD1", idtmed[2], parTrd, kNparTrd);
346 createVolume("UTR4", "TRD1", idtmed[2], parTrd, kNparTrd);
347 // The outer aluminum plates of the super module (Al)
348 parTrd[0] = SWIDTH1 / 2.0;
349 parTrd[1] = SWIDTH2 / 2.0;
350 parTrd[2] = SLENGTH / 2.0;
351 parTrd[3] = SHEIGHT / 2.0;
352 createVolume("UTS1", "TRD1", idtmed[1], parTrd, kNparTrd);
353 createVolume("UTS2", "TRD1", idtmed[1], parTrd, kNparTrd);
354 createVolume("UTS3", "TRD1", idtmed[1], parTrd, kNparTrd);
355 createVolume("UTS4", "TRD1", idtmed[1], parTrd, kNparTrd);
356 // The inner part of the TRD mother volume for one sector (Air),
357 // full length in z-direction
358 parTrd[0] = SWIDTH1 / 2.0 - SMPLTT;
359 parTrd[1] = SWIDTH2 / 2.0 - SMPLTT;
360 parTrd[2] = SLENGTH / 2.0;
361 parTrd[3] = SHEIGHT / 2.0 - SMPLTT;
362 createVolume("UTI1", "TRD1", idtmed[2], parTrd, kNparTrd);
363 createVolume("UTI2", "TRD1", idtmed[2], parTrd, kNparTrd);
364 createVolume("UTI3", "TRD1", idtmed[2], parTrd, kNparTrd);
365 createVolume("UTI4", "TRD1", idtmed[2], parTrd, kNparTrd);
366
367 // The inner part of the TRD mother volume for services in front
368 // of the supermodules (Air),
369 parTrd[0] = SWIDTH1 / 2.0;
370 parTrd[1] = SWIDTH2 / 2.0;
371 parTrd[2] = FLENGTH / 2.0;
372 parTrd[3] = SHEIGHT / 2.0;
373 createVolume("UTF1", "TRD1", idtmed[2], parTrd, kNparTrd);
374 createVolume("UTF2", "TRD1", idtmed[2], parTrd, kNparTrd);
375
376 // The chamber shape is fixed by the layer (its width) and by the chamber length, and the
377 // length is the same for every stack but the middle one -- so twelve chambers describe all
378 // thirty. Stacks 0 and 2 are built as the representatives of the two length classes; the
379 // per-chamber identity lives in the UTxx assembly of assembleChamber(), which is what the
380 // alignable volume and the hit lookup are keyed on.
381 for (int istack : {0, 2}) {
382 for (int ilayer = 0; ilayer < NLAYER; ilayer++) {
383 int iShape = shapeClass(ilayer, istack);
384
385 // Half-sizes of this chamber and of the three air volumes the material layers sit in.
386 // The Geant3 convention of passing -1 and letting TGeo copy the dimension from the
387 // mother at CheckGeometry() time is not used here: every such placement makes TGeo
388 // clone a fresh TGeoVolume, so the dimensions are written out instead.
389 // double, not float: the originals compute the whole expression in double and only the
390 // store into parCha[] rounds, so a float intermediate here would shift a dimension by
391 // one ulp and, through Geant4's stepping, move a handful of hits.
392 const double halfWidth = CWIDTH[ilayer] / 2.0;
393 const double halfLength = CLENGTH[ilayer][istack] / 2.0 - HSPACE / 2.0;
394 const double radX = halfWidth - CALT - CCLST - CGLT; // inside of the radiator (UC)
395 const double radY = halfLength - CCLFT - CGLT;
396 const double ampX = halfWidth + CROW - CCUTB; // inside of the amplification frame (UE)
397 const double ampY = halfLength - CCUTA;
398 const double robX = halfWidth + CROW - CAUT; // inside of the back-panel frame (UG)
399 const double robY = halfLength - CAUT;
400
401 // The lower part of the readout chambers (drift volume + radiator)
402 // The aluminum frames
403 snprintf(cTagV, kTag, "UA%02d", iShape);
404 parCha[0] = CWIDTH[ilayer] / 2.0;
405 parCha[1] = CLENGTH[ilayer][istack] / 2.0 - HSPACE / 2.0;
406 parCha[2] = CRAH / 2.0 + CDRH / 2.0;
407 createVolume(cTagV, "BOX ", idtmed[1], parCha, kNparCha);
408 // The additional aluminum on the frames
409 // This part has not the correct shape but is just supposed to
410 // represent the missing material. The correct form of the L-shaped
411 // profile would not fit into the alignable volume.
412 snprintf(cTagV, kTag, "UZ%02d", iShape);
413 parCha[0] = CALWMOD / 2.0;
414 parCha[1] = CLENGTH[ilayer][istack] / 2.0 - HSPACE / 2.0;
415 parCha[2] = CALHMOD / 2.0;
416 createVolume(cTagV, "BOX ", idtmed[1], parCha, kNparCha);
417 // The additional Wacosit on the frames
418 snprintf(cTagV, kTag, "UP%02d", iShape);
419 parCha[0] = CWSW / 2.0;
420 parCha[1] = CLENGTH[ilayer][istack] / 2.0 - HSPACE / 2.0;
421 parCha[2] = CWSH / 2.0;
422 createVolume(cTagV, "BOX ", idtmed[7], parCha, kNparCha);
423 // The Wacosit frames
424 snprintf(cTagV, kTag, "UB%02d", iShape);
425 parCha[0] = CWIDTH[ilayer] / 2.0 - CALT;
426 parCha[1] = halfLength;
427 parCha[2] = CRAH / 2.0 + CDRH / 2.0;
428 createVolume(cTagV, "BOX ", idtmed[7], parCha, kNparCha);
429 // The glue around the radiator
430 snprintf(cTagV, kTag, "UX%02d", iShape);
431 parCha[0] = CWIDTH[ilayer] / 2.0 - CALT - CCLST;
432 parCha[1] = CLENGTH[ilayer][istack] / 2.0 - HSPACE / 2.0 - CCLFT;
433 parCha[2] = CRAH / 2.0;
434 createVolume(cTagV, "BOX ", idtmed[11], parCha, kNparCha);
435 // The inner part of radiator (air)
436 snprintf(cTagV, kTag, "UC%02d", iShape);
437 parCha[0] = CWIDTH[ilayer] / 2.0 - CALT - CCLST - CGLT;
438 parCha[1] = CLENGTH[ilayer][istack] / 2.0 - HSPACE / 2.0 - CCLFT - CGLT;
439 parCha[2] = CRAH / 2.0;
440 createVolume(cTagV, "BOX ", idtmed[2], parCha, kNparCha);
441
442 // The upper part of the readout chambers (amplification volume)
443 // The Wacosit frames
444 snprintf(cTagV, kTag, "UD%02d", iShape);
445 parCha[0] = CWIDTH[ilayer] / 2.0 + CROW;
446 parCha[1] = CLENGTH[ilayer][istack] / 2.0 - HSPACE / 2.0;
447 parCha[2] = CAMH / 2.0;
448 createVolume(cTagV, "BOX ", idtmed[7], parCha, kNparCha);
449 // The inner part of the Wacosit frame (air)
450 snprintf(cTagV, kTag, "UE%02d", iShape);
451 parCha[0] = CWIDTH[ilayer] / 2.0 + CROW - CCUTB;
452 parCha[1] = CLENGTH[ilayer][istack] / 2.0 - HSPACE / 2.0 - CCUTA;
453 parCha[2] = CAMH / 2.0;
454 createVolume(cTagV, "BOX ", idtmed[2], parCha, kNparCha);
455
456 // The back panel, including pad plane and readout boards
457 // The aluminum frames
458 snprintf(cTagV, kTag, "UF%02d", iShape);
459 parCha[0] = CWIDTH[ilayer] / 2.0 + CROW;
460 parCha[1] = CLENGTH[ilayer][istack] / 2.0 - HSPACE / 2.0;
461 parCha[2] = CROH / 2.0;
462 createVolume(cTagV, "BOX ", idtmed[1], parCha, kNparCha);
463 // The inner part of the aluminum frames
464 snprintf(cTagV, kTag, "UG%02d", iShape);
465 parCha[0] = CWIDTH[ilayer] / 2.0 + CROW - CAUT;
466 parCha[1] = CLENGTH[ilayer][istack] / 2.0 - HSPACE / 2.0 - CAUT;
467 parCha[2] = CROH / 2.0;
468 createVolume(cTagV, "BOX ", idtmed[2], parCha, kNparCha);
469
470 //
471 // The material layers inside the chambers
472 //
473
474 // Mylar layer (radiator)
475 parCha[0] = radX;
476 parCha[1] = radY;
477 parCha[2] = RMYTHICK / 2.0;
478 snprintf(cTagV, kTag, "URMY%02d", iShape);
479 createVolume(cTagV, "BOX ", idtmed[27], parCha, kNparCha);
480 // Carbon layer (radiator)
481 parCha[0] = radX;
482 parCha[1] = radY;
483 parCha[2] = RCBTHICK / 2.0;
484 snprintf(cTagV, kTag, "URCB%02d", iShape);
485 createVolume(cTagV, "BOX ", idtmed[26], parCha, kNparCha);
486 // Araldite layer (radiator)
487 parCha[0] = radX;
488 parCha[1] = radY;
489 parCha[2] = RGLTHICK / 2.0;
490 snprintf(cTagV, kTag, "URGL%02d", iShape);
491 createVolume(cTagV, "BOX ", idtmed[11], parCha, kNparCha);
492 // Rohacell layer (radiator)
493 parCha[0] = radX;
494 parCha[1] = radY;
495 parCha[2] = RRHTHICK / 2.0;
496 snprintf(cTagV, kTag, "URRH%02d", iShape);
497 createVolume(cTagV, "BOX ", idtmed[15], parCha, kNparCha);
498 // Fiber layer (radiator)
499 parCha[0] = radX;
500 parCha[1] = radY;
501 parCha[2] = RFBTHICK / 2.0;
502 snprintf(cTagV, kTag, "URFB%02d", iShape);
503 createVolume(cTagV, "BOX ", idtmed[28], parCha, kNparCha);
504
505 // Xe/Isobutane layer (drift volume)
506 parCha[0] = CWIDTH[ilayer] / 2.0 - CALT - CCLST;
507 parCha[1] = CLENGTH[ilayer][istack] / 2.0 - HSPACE / 2.0 - CCLFT;
508 parCha[2] = DRTHICK / 2.0;
509 snprintf(cTagV, kTag, "UJ%02d", iShape);
510 createVolume(cTagV, "BOX ", idtmed[9], parCha, kNparCha);
511
512 // Xe/Isobutane layer (amplification volume)
513 parCha[0] = ampX;
514 parCha[1] = ampY;
515 parCha[2] = AMTHICK / 2.0;
516 snprintf(cTagV, kTag, "UK%02d", iShape);
517 createVolume(cTagV, "BOX ", idtmed[9], parCha, kNparCha);
518 // Cu layer (wire plane)
519 parCha[0] = ampX;
520 parCha[1] = ampY;
521 parCha[2] = WRTHICK / 2.0;
522 snprintf(cTagV, kTag, "UW%02d", iShape);
523 createVolume(cTagV, "BOX ", idtmed[3], parCha, kNparCha);
524
525 // Cu layer (pad plane)
526 parCha[0] = robX;
527 parCha[1] = robY;
528 parCha[2] = PPDTHICK / 2.0;
529 snprintf(cTagV, kTag, "UPPD%02d", iShape);
530 createVolume(cTagV, "BOX ", idtmed[5], parCha, kNparCha);
531 // G10 layer (pad plane)
532 parCha[0] = robX;
533 parCha[1] = robY;
534 parCha[2] = PPPTHICK / 2.0;
535 snprintf(cTagV, kTag, "UPPP%02d", iShape);
536 createVolume(cTagV, "BOX ", idtmed[13], parCha, kNparCha);
537 // Araldite layer (glue)
538 parCha[0] = robX;
539 parCha[1] = robY;
540 parCha[2] = PGLTHICK / 2.0;
541 snprintf(cTagV, kTag, "UPGL%02d", iShape);
542 createVolume(cTagV, "BOX ", idtmed[11], parCha, kNparCha);
543 // Carbon layer (carbon fiber mats)
544 parCha[0] = robX;
545 parCha[1] = robY;
546 parCha[2] = PCBTHICK / 2.0;
547 snprintf(cTagV, kTag, "UPCB%02d", iShape);
548 createVolume(cTagV, "BOX ", idtmed[26], parCha, kNparCha);
549 // Aramide layer (honeycomb)
550 parCha[0] = robX;
551 parCha[1] = robY;
552 parCha[2] = PHCTHICK / 2.0;
553 snprintf(cTagV, kTag, "UPHC%02d", iShape);
554 createVolume(cTagV, "BOX ", idtmed[10], parCha, kNparCha);
555 // G10 layer (PCB readout board)
556 parCha[0] = robX;
557 parCha[1] = robY;
558 parCha[2] = PPCTHICK / 2;
559 snprintf(cTagV, kTag, "UPPC%02d", iShape);
560 createVolume(cTagV, "BOX ", idtmed[13], parCha, kNparCha);
561 // Cu layer (traces in readout board)
562 parCha[0] = robX;
563 parCha[1] = robY;
564 parCha[2] = PRBTHICK / 2.0;
565 snprintf(cTagV, kTag, "UPRB%02d", iShape);
566 createVolume(cTagV, "BOX ", idtmed[6], parCha, kNparCha);
567 // Cu layer (other material on in readout board, incl. screws)
568 parCha[0] = robX;
569 parCha[1] = robY;
570 parCha[2] = PELTHICK / 2.0;
571 snprintf(cTagV, kTag, "UPEL%02d", iShape);
572 createVolume(cTagV, "BOX ", idtmed[4], parCha, kNparCha);
573
574 //
575 // Position the layers in the chambers
576 //
577 xpos = 0.0;
578 ypos = 0.0;
579
580 // Lower part
581 // Mylar layers (radiator)
582 zpos = RMYTHICK / 2.0 - CRAH / 2.0;
583 snprintf(cTagV, kTag, "URMY%02d", iShape);
584 snprintf(cTagM, kTag, "UC%02d", iShape);
585 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
586 zpos = -RMYTHICK / 2.0 + CRAH / 2.0;
587 snprintf(cTagV, kTag, "URMY%02d", iShape);
588 snprintf(cTagM, kTag, "UC%02d", iShape);
589 TVirtualMC::GetMC()->Gspos(cTagV, 2, cTagM, xpos, ypos, zpos, 0, "ONLY");
590 // Carbon layers (radiator)
591 zpos = RCBTHICK / 2.0 + RMYTHICK - CRAH / 2.0;
592 snprintf(cTagV, kTag, "URCB%02d", iShape);
593 snprintf(cTagM, kTag, "UC%02d", iShape);
594 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
595 zpos = -RCBTHICK / 2.0 - RMYTHICK + CRAH / 2.0;
596 snprintf(cTagV, kTag, "URCB%02d", iShape);
597 snprintf(cTagM, kTag, "UC%02d", iShape);
598 TVirtualMC::GetMC()->Gspos(cTagV, 2, cTagM, xpos, ypos, zpos, 0, "ONLY");
599 // Carbon layers (radiator)
600 zpos = RGLTHICK / 2.0 + RCBTHICK + RMYTHICK - CRAH / 2.0;
601 snprintf(cTagV, kTag, "URGL%02d", iShape);
602 snprintf(cTagM, kTag, "UC%02d", iShape);
603 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
604 zpos = -RGLTHICK / 2.0 - RCBTHICK - RMYTHICK + CRAH / 2.0;
605 snprintf(cTagV, kTag, "URGL%02d", iShape);
606 snprintf(cTagM, kTag, "UC%02d", iShape);
607 TVirtualMC::GetMC()->Gspos(cTagV, 2, cTagM, xpos, ypos, zpos, 0, "ONLY");
608 // Rohacell layers (radiator)
609 zpos = RRHTHICK / 2.0 + RGLTHICK + RCBTHICK + RMYTHICK - CRAH / 2.0;
610 snprintf(cTagV, kTag, "URRH%02d", iShape);
611 snprintf(cTagM, kTag, "UC%02d", iShape);
612 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
613 zpos = -RRHTHICK / 2.0 - RGLTHICK - RCBTHICK - RMYTHICK + CRAH / 2.0;
614 snprintf(cTagV, kTag, "URRH%02d", iShape);
615 snprintf(cTagM, kTag, "UC%02d", iShape);
616 TVirtualMC::GetMC()->Gspos(cTagV, 2, cTagM, xpos, ypos, zpos, 0, "ONLY");
617 // Fiber layers (radiator)
618 zpos = 0.0;
619 snprintf(cTagV, kTag, "URFB%02d", iShape);
620 snprintf(cTagM, kTag, "UC%02d", iShape);
621 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
622
623 // Xe/Isobutane layer (drift volume)
624 zpos = DRZPOS;
625 snprintf(cTagV, kTag, "UJ%02d", iShape);
626 snprintf(cTagM, kTag, "UB%02d", iShape);
627 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
628
629 // Upper part
630 // Xe/Isobutane layer (amplification volume)
631 zpos = AMZPOS;
632 snprintf(cTagV, kTag, "UK%02d", iShape);
633 snprintf(cTagM, kTag, "UE%02d", iShape);
634 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
635 // Cu layer (wire planes inside amplification volume)
636 zpos = WRZPOSA;
637 snprintf(cTagV, kTag, "UW%02d", iShape);
638 snprintf(cTagM, kTag, "UK%02d", iShape);
639 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
640 zpos = WRZPOSB;
641 snprintf(cTagV, kTag, "UW%02d", iShape);
642 snprintf(cTagM, kTag, "UK%02d", iShape);
643 TVirtualMC::GetMC()->Gspos(cTagV, 2, cTagM, xpos, ypos, zpos, 0, "ONLY");
644
645 // Back panel + pad plane + readout part
646 // Cu layer (pad plane)
647 zpos = PPDTHICK / 2.0 - CROH / 2.0;
648 snprintf(cTagV, kTag, "UPPD%02d", iShape);
649 snprintf(cTagM, kTag, "UG%02d", iShape);
650 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
651 // G10 layer (pad plane)
652 zpos = PPPTHICK / 2.0 + PPDTHICK - CROH / 2.0;
653 snprintf(cTagV, kTag, "UPPP%02d", iShape);
654 snprintf(cTagM, kTag, "UG%02d", iShape);
655 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
656 // Araldite layer (glue)
657 zpos = PGLTHICK / 2.0 + PPPTHICK + PPDTHICK - CROH / 2.0;
658 snprintf(cTagV, kTag, "UPGL%02d", iShape);
659 snprintf(cTagM, kTag, "UG%02d", iShape);
660 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
661 // Carbon layers (carbon fiber mats)
662 zpos = PCBTHICK / 2.0 + PGLTHICK + PPPTHICK + PPDTHICK - CROH / 2.0;
663 snprintf(cTagV, kTag, "UPCB%02d", iShape);
664 snprintf(cTagM, kTag, "UG%02d", iShape);
665 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
666 zpos = -PCBTHICK / 2.0 - PPCTHICK - PRBTHICK - PELTHICK + CROH / 2.0;
667 snprintf(cTagV, kTag, "UPCB%02d", iShape);
668 snprintf(cTagM, kTag, "UG%02d", iShape);
669 TVirtualMC::GetMC()->Gspos(cTagV, 2, cTagM, xpos, ypos, zpos, 0, "ONLY");
670 // Aramide layer (honeycomb)
671 zpos = PHCTHICK / 2.0 + PCBTHICK + PGLTHICK + PPPTHICK + PPDTHICK - CROH / 2.0;
672 snprintf(cTagV, kTag, "UPHC%02d", iShape);
673 snprintf(cTagM, kTag, "UG%02d", iShape);
674 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
675 // G10 layer (PCB readout board)
676 zpos = -PPCTHICK / 2.0 - PRBTHICK - PELTHICK + CROH / 2.0;
677 snprintf(cTagV, kTag, "UPPC%02d", iShape);
678 snprintf(cTagM, kTag, "UG%02d", iShape);
679 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
680 // Cu layer (traces in readout board)
681 zpos = -PRBTHICK / 2.0 - PELTHICK + CROH / 2.0;
682 snprintf(cTagV, kTag, "UPRB%02d", iShape);
683 snprintf(cTagM, kTag, "UG%02d", iShape);
684 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
685 // Cu layer (other materials on readout board, incl. screws)
686 zpos = -PELTHICK / 2.0 + CROH / 2.0;
687 snprintf(cTagV, kTag, "UPEL%02d", iShape);
688 snprintf(cTagM, kTag, "UG%02d", iShape);
689 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
690
691 // Position the inner volumes of the chambers in the frames
692 xpos = 0.0;
693 ypos = 0.0;
694
695 // The inner part of the radiator (air)
696 zpos = 0.0;
697 snprintf(cTagV, kTag, "UC%02d", iShape);
698 snprintf(cTagM, kTag, "UX%02d", iShape);
699 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
700 // The glue around the radiator
701 zpos = CRAH / 2.0 - CDRH / 2.0 - CRAH / 2.0;
702 snprintf(cTagV, kTag, "UX%02d", iShape);
703 snprintf(cTagM, kTag, "UB%02d", iShape);
704 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
705 // The lower Wacosit frame inside the aluminum frame
706 zpos = 0.0;
707 snprintf(cTagV, kTag, "UB%02d", iShape);
708 snprintf(cTagM, kTag, "UA%02d", iShape);
709 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
710
711 // The inside of the upper Wacosit frame
712 zpos = 0.0;
713 snprintf(cTagV, kTag, "UE%02d", iShape);
714 snprintf(cTagM, kTag, "UD%02d", iShape);
715 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
716
717 // The inside of the upper aluminum frame
718 zpos = 0.0;
719 snprintf(cTagV, kTag, "UG%02d", iShape);
720 snprintf(cTagM, kTag, "UF%02d", iShape);
721 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
722 }
723 }
724
725 // Create the volumes of the super module frame
726 createFrame(idtmed);
727
728 // Create the volumes of the services
729 createServices(idtmed);
730
731 for (int istack = 0; istack < NSTACK; istack++) {
732 for (int ilayer = 0; ilayer < NLAYER; ilayer++) {
733 assembleChamber(ilayer, istack);
734 }
735 }
736
737 xpos = 0.0;
738 ypos = 0.0;
739 zpos = 0.0;
740 TVirtualMC::GetMC()->Gspos("UTI1", 1, "UTS1", xpos, ypos, zpos, 0, "ONLY");
741 TVirtualMC::GetMC()->Gspos("UTI2", 1, "UTS2", xpos, ypos, zpos, 0, "ONLY");
742 TVirtualMC::GetMC()->Gspos("UTI3", 1, "UTS3", xpos, ypos, zpos, 0, "ONLY");
743 TVirtualMC::GetMC()->Gspos("UTI4", 1, "UTS4", xpos, ypos, zpos, 0, "ONLY");
744
745 xpos = 0.0;
746 ypos = 0.0;
747 zpos = 0.0;
748 TVirtualMC::GetMC()->Gspos("UTS1", 1, "UTR1", xpos, ypos, zpos, 0, "ONLY");
749 TVirtualMC::GetMC()->Gspos("UTS2", 1, "UTR2", xpos, ypos, zpos, 0, "ONLY");
750 TVirtualMC::GetMC()->Gspos("UTS3", 1, "UTR3", xpos, ypos, zpos, 0, "ONLY");
751 TVirtualMC::GetMC()->Gspos("UTS4", 1, "UTR4", xpos, ypos, zpos, 0, "ONLY");
752
753 // Put the TRD volumes into the space frame mother volumes
754 // if enabled via status flag
755 xpos = 0.0;
756 ypos = 0.0;
757 zpos = 0.0;
758 for (int isector = 0; isector < NSECTOR; isector++) {
759 if (getSMstatus(isector)) {
760 snprintf(cTagV, kTag, "BTRD%d", isector);
761 switch (isector) {
762 case 17:
763 // Missing L4S4 chamber
764 TVirtualMC::GetMC()->Gspos("UTR4", 1, cTagV, xpos, ypos, zpos, 0, "ONLY");
765 break;
766 case 13:
767 case 14:
768 case 15:
769 // Double carbon, w/o middle stack
770 TVirtualMC::GetMC()->Gspos("UTR3", 1, cTagV, xpos, ypos, zpos, 0, "ONLY");
771 break;
772 case 11:
773 case 12:
774 // Double carbon, all stacks
775 TVirtualMC::GetMC()->Gspos("UTR2", 1, cTagV, xpos, ypos, zpos, 0, "ONLY");
776 break;
777 default:
778 // Standard supermodule
779 TVirtualMC::GetMC()->Gspos("UTR1", 1, cTagV, xpos, ypos, zpos, 0, "ONLY");
780 };
781 }
782 }
783
784 // Put the TRD volumes into the space frame mother volumes
785 // if enabled via status flag
786 xpos = 0.0;
787 ypos = 0.5 * SLENGTH + 0.5 * FLENGTH;
788 zpos = 0.0;
789 for (int isector = 0; isector < NSECTOR; isector++) {
790 if (getSMstatus(isector)) {
791 snprintf(cTagV, kTag, "BTRD%d", isector);
792 TVirtualMC::GetMC()->Gspos("UTF1", 1, cTagV, xpos, ypos, zpos, 0, "ONLY");
793 TVirtualMC::GetMC()->Gspos("UTF2", 1, cTagV, xpos, -ypos, zpos, 0, "ONLY");
794 }
795 }
796
797 // Resolve runtime shapes (which is done as part of TGeoManager::CheckGeometry) NOW.
798 // This is otherwise done when saying gGeoManager->CloseGeometry().
799 // However, we need to make sure all the TGeoVolumes are correctly available even before this
800 // stage because FairMCApplication initializes the sensisitive volumes before closing the geometry.
801 // The true origin of the "problem" comes from the fact, that the TRD construction above uses
802 // Geant3-like construction routines that allow giving negative parameters, indicating dimensions to be
803 // fixed later. This prevents immediate construction of the TGeoVolume.
804 gGeoManager->CheckGeometry();
805}
806
807//_____________________________________________________________________________
808void Geometry::createFrame(std::vector<int> const& idtmed)
809{
810 //
811 // Create the geometry of the frame of the supermodule
812 //
813 // Names of the TRD services volumina
814 //
815 // USRL Support rails for the chambers (Al)
816 // USxx Support cross bars between the chambers (Al)
817 // USHx Horizontal connection between the cross bars (Al)
818 // USLx Long corner ledges (Al)
819 //
820
821 int ilayer = 0;
822
823 double xpos = 0.0;
824 double ypos = 0.0;
825 double zpos = 0.0;
826
827 const int kTag = 100;
828 char cTagV[kTag];
829 char cTagM[kTag];
830
831 const int kNparTRD = 4;
832 double parTRD[kNparTRD];
833 const int kNparBOX = 3;
834 double parBOX[kNparBOX];
835 const int kNparTRP = 11;
836 double parTRP[kNparTRP];
837
838 // The rotation matrices
839 const int kNmatrix = 7;
840 int matrix[kNmatrix];
841 TVirtualMC::GetMC()->Matrix(matrix[0], 100.0, 0.0, 90.0, 90.0, 10.0, 0.0);
842 TVirtualMC::GetMC()->Matrix(matrix[1], 80.0, 0.0, 90.0, 90.0, 10.0, 180.0);
843 TVirtualMC::GetMC()->Matrix(matrix[2], 90.0, 0.0, 0.0, 0.0, 90.0, 90.0);
844 TVirtualMC::GetMC()->Matrix(matrix[3], 90.0, 180.0, 0.0, 180.0, 90.0, 90.0);
845 TVirtualMC::GetMC()->Matrix(matrix[4], 170.0, 0.0, 80.0, 0.0, 90.0, 90.0);
846 TVirtualMC::GetMC()->Matrix(matrix[5], 170.0, 180.0, 80.0, 180.0, 90.0, 90.0);
847 TVirtualMC::GetMC()->Matrix(matrix[6], 180.0, 180.0, 90.0, 180.0, 90.0, 90.0);
848
849 //
850 // The carbon inserts in the top/bottom aluminum plates
851 //
852
853 const int kNparCrb = 3;
854 double parCrb[kNparCrb];
855 parCrb[0] = 0.0;
856 parCrb[1] = 0.0;
857 parCrb[2] = 0.0;
858 createVolume("USCR", "BOX ", idtmed[26], parCrb, 0);
859 // Bottom 1 (all sectors)
860 parCrb[0] = 77.49 / 2.0;
861 parCrb[1] = 104.60 / 2.0;
862 parCrb[2] = SMPLTT / 2.0;
863 xpos = 0.0;
864 ypos = 0.0;
865 zpos = SMPLTT / 2.0 - SHEIGHT / 2.0;
866 TVirtualMC::GetMC()->Gsposp("USCR", 1, "UTS1", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
867 TVirtualMC::GetMC()->Gsposp("USCR", 2, "UTS2", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
868 TVirtualMC::GetMC()->Gsposp("USCR", 3, "UTS3", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
869 TVirtualMC::GetMC()->Gsposp("USCR", 4, "UTS4", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
870 // Bottom 2 (all sectors)
871 parCrb[0] = 77.49 / 2.0;
872 parCrb[1] = 55.80 / 2.0;
873 parCrb[2] = SMPLTT / 2.0;
874 xpos = 0.0;
875 ypos = 85.6;
876 zpos = SMPLTT / 2.0 - SHEIGHT / 2.0;
877 TVirtualMC::GetMC()->Gsposp("USCR", 5, "UTS1", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
878 TVirtualMC::GetMC()->Gsposp("USCR", 6, "UTS2", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
879 TVirtualMC::GetMC()->Gsposp("USCR", 7, "UTS3", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
880 TVirtualMC::GetMC()->Gsposp("USCR", 8, "UTS4", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
881 TVirtualMC::GetMC()->Gsposp("USCR", 9, "UTS1", xpos, -ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
882 TVirtualMC::GetMC()->Gsposp("USCR", 10, "UTS2", xpos, -ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
883 TVirtualMC::GetMC()->Gsposp("USCR", 11, "UTS3", xpos, -ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
884 TVirtualMC::GetMC()->Gsposp("USCR", 12, "UTS4", xpos, -ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
885 // Bottom 3 (all sectors)
886 parCrb[0] = 77.49 / 2.0;
887 parCrb[1] = 56.00 / 2.0;
888 parCrb[2] = SMPLTT / 2.0;
889 xpos = 0.0;
890 ypos = 148.5;
891 zpos = SMPLTT / 2.0 - SHEIGHT / 2.0;
892 TVirtualMC::GetMC()->Gsposp("USCR", 13, "UTS1", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
893 TVirtualMC::GetMC()->Gsposp("USCR", 14, "UTS2", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
894 TVirtualMC::GetMC()->Gsposp("USCR", 15, "UTS3", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
895 TVirtualMC::GetMC()->Gsposp("USCR", 16, "UTS4", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
896 TVirtualMC::GetMC()->Gsposp("USCR", 17, "UTS1", xpos, -ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
897 TVirtualMC::GetMC()->Gsposp("USCR", 18, "UTS2", xpos, -ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
898 TVirtualMC::GetMC()->Gsposp("USCR", 19, "UTS3", xpos, -ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
899 TVirtualMC::GetMC()->Gsposp("USCR", 20, "UTS4", xpos, -ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
900 // Bottom 4 (all sectors)
901 parCrb[0] = 77.49 / 2.0;
902 parCrb[1] = 118.00 / 2.0;
903 parCrb[2] = SMPLTT / 2.0;
904 xpos = 0.0;
905 ypos = 240.5;
906 zpos = SMPLTT / 2.0 - SHEIGHT / 2.0;
907 TVirtualMC::GetMC()->Gsposp("USCR", 21, "UTS1", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
908 TVirtualMC::GetMC()->Gsposp("USCR", 22, "UTS2", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
909 TVirtualMC::GetMC()->Gsposp("USCR", 23, "UTS3", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
910 TVirtualMC::GetMC()->Gsposp("USCR", 24, "UTS4", xpos, ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
911 TVirtualMC::GetMC()->Gsposp("USCR", 25, "UTS1", xpos, -ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
912 TVirtualMC::GetMC()->Gsposp("USCR", 26, "UTS2", xpos, -ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
913 TVirtualMC::GetMC()->Gsposp("USCR", 27, "UTS3", xpos, -ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
914 TVirtualMC::GetMC()->Gsposp("USCR", 28, "UTS4", xpos, -ypos, zpos, 0, "ONLY", parCrb, kNparCrb);
915 // Top 1 (only in front of PHOS)
916 parCrb[0] = 111.48 / 2.0;
917 parCrb[1] = 105.00 / 2.0;
918 parCrb[2] = SMPLTT / 2.0;
919 xpos = 0.0;
920 ypos = 0.0;
921 zpos = SMPLTT / 2.0 - SHEIGHT / 2.0;
922 TVirtualMC::GetMC()->Gsposp("USCR", 29, "UTS2", xpos, ypos, -zpos, 0, "ONLY", parCrb, kNparCrb);
923 TVirtualMC::GetMC()->Gsposp("USCR", 30, "UTS3", xpos, ypos, -zpos, 0, "ONLY", parCrb, kNparCrb);
924 // Top 2 (only in front of PHOS)
925 parCrb[0] = 111.48 / 2.0;
926 parCrb[1] = 56.00 / 2.0;
927 parCrb[2] = SMPLTT / 2.0;
928 xpos = 0.0;
929 ypos = 85.5;
930 zpos = SMPLTT / 2.0 - SHEIGHT / 2.0;
931 TVirtualMC::GetMC()->Gsposp("USCR", 31, "UTS2", xpos, ypos, -zpos, 0, "ONLY", parCrb, kNparCrb);
932 TVirtualMC::GetMC()->Gsposp("USCR", 32, "UTS3", xpos, ypos, -zpos, 0, "ONLY", parCrb, kNparCrb);
933 TVirtualMC::GetMC()->Gsposp("USCR", 33, "UTS2", xpos, -ypos, -zpos, 0, "ONLY", parCrb, kNparCrb);
934 TVirtualMC::GetMC()->Gsposp("USCR", 34, "UTS3", xpos, -ypos, -zpos, 0, "ONLY", parCrb, kNparCrb);
935
936 //
937 // The chamber support rails
938 //
939
940 const double kSRLhgt = 2.00;
941 const double kSRLwidA = 2.3;
942 const double kSRLwidB = 1.947;
943 const double kSRLdst = 1.135;
944 const int kNparSRL = 11;
945 double parSRL[kNparSRL];
946 // Trapezoidal shape
947 parSRL[0] = SLENGTH / 2.0;
948 parSRL[1] = 0.0;
949 parSRL[2] = 0.0;
950 parSRL[3] = kSRLhgt / 2.0;
951 parSRL[4] = kSRLwidB / 2.0;
952 parSRL[5] = kSRLwidA / 2.0;
953 parSRL[6] = 5.0;
954 parSRL[7] = kSRLhgt / 2.0;
955 parSRL[8] = kSRLwidB / 2.0;
956 parSRL[9] = kSRLwidA / 2.0;
957 parSRL[10] = 5.0;
958 createVolume("USRL", "TRAP", idtmed[1], parSRL, kNparSRL);
959
960 xpos = 0.0;
961 ypos = 0.0;
962 zpos = 0.0;
963 for (ilayer = 1; ilayer < NLAYER; ilayer++) {
964 xpos = CWIDTH[ilayer] / 2.0 + kSRLwidA / 2.0 + kSRLdst;
965 ypos = 0.0;
966 zpos = VROCSM + SMPLTT - CALZPOS - SHEIGHT / 2.0 + CRAH + CDRH - CALH - kSRLhgt / 2.0 +
967 ilayer * (CH + VSPACE);
968 TVirtualMC::GetMC()->Gspos("USRL", ilayer + 1, "UTI1", xpos, ypos, zpos, matrix[2], "ONLY");
969 TVirtualMC::GetMC()->Gspos("USRL", ilayer + 1 + NLAYER, "UTI1", -xpos, ypos, zpos, matrix[3], "ONLY");
970 TVirtualMC::GetMC()->Gspos("USRL", ilayer + 1 + 2 * NLAYER, "UTI2", xpos, ypos, zpos, matrix[2], "ONLY");
971 TVirtualMC::GetMC()->Gspos("USRL", ilayer + 1 + 3 * NLAYER, "UTI2", -xpos, ypos, zpos, matrix[3], "ONLY");
972 TVirtualMC::GetMC()->Gspos("USRL", ilayer + 1 + 4 * NLAYER, "UTI3", xpos, ypos, zpos, matrix[2], "ONLY");
973 TVirtualMC::GetMC()->Gspos("USRL", ilayer + 1 + 5 * NLAYER, "UTI3", -xpos, ypos, zpos, matrix[3], "ONLY");
974 TVirtualMC::GetMC()->Gspos("USRL", ilayer + 1 + 6 * NLAYER, "UTI4", xpos, ypos, zpos, matrix[2], "ONLY");
975 TVirtualMC::GetMC()->Gspos("USRL", ilayer + 1 + 7 * NLAYER, "UTI4", -xpos, ypos, zpos, matrix[3], "ONLY");
976 }
977
978 //
979 // The cross bars between the chambers
980 //
981
982 const double kSCBwid = 1.0;
983 const double kSCBthk = 2.0;
984 const double kSCHhgt = 0.3;
985
986 const int kNparSCB = 3;
987 double parSCB[kNparSCB];
988 parSCB[1] = kSCBwid / 2.0;
989 parSCB[2] = CH / 2.0 + VSPACE / 2.0 - kSCHhgt;
990
991 const int kNparSCI = 3;
992 double parSCI[kNparSCI];
993 parSCI[1] = -1;
994
995 xpos = 0.0;
996 ypos = 0.0;
997 zpos = 0.0;
998 for (ilayer = 0; ilayer < NLAYER; ilayer++) {
999 // The aluminum of the cross bars
1000 parSCB[0] = CWIDTH[ilayer] / 2.0 + kSRLdst / 2.0;
1001 snprintf(cTagV, kTag, "USF%01d", ilayer);
1002 createVolume(cTagV, "BOX ", idtmed[1], parSCB, kNparSCB);
1003
1004 // The empty regions in the cross bars
1005 double thkSCB = kSCBthk;
1006 if (ilayer < 2) {
1007 thkSCB *= 1.5;
1008 }
1009 parSCI[2] = parSCB[2] - thkSCB;
1010 parSCI[0] = parSCB[0] / 4.0 - kSCBthk;
1011 snprintf(cTagV, kTag, "USI%01d", ilayer);
1012 createVolume(cTagV, "BOX ", idtmed[2], parSCI, kNparSCI);
1013
1014 snprintf(cTagV, kTag, "USI%01d", ilayer);
1015 snprintf(cTagM, kTag, "USF%01d", ilayer);
1016 ypos = 0.0;
1017 zpos = 0.0;
1018 xpos = parSCI[0] + thkSCB / 2.0;
1019 TVirtualMC::GetMC()->Gspos(cTagV, 1, cTagM, xpos, ypos, zpos, 0, "ONLY");
1020 xpos = -parSCI[0] - thkSCB / 2.0;
1021 TVirtualMC::GetMC()->Gspos(cTagV, 2, cTagM, xpos, ypos, zpos, 0, "ONLY");
1022 xpos = 3.0 * parSCI[0] + 1.5 * thkSCB;
1023 TVirtualMC::GetMC()->Gspos(cTagV, 3, cTagM, xpos, ypos, zpos, 0, "ONLY");
1024 xpos = -3.0 * parSCI[0] - 1.5 * thkSCB;
1025 TVirtualMC::GetMC()->Gspos(cTagV, 4, cTagM, xpos, ypos, zpos, 0, "ONLY");
1026
1027 snprintf(cTagV, kTag, "USF%01d", ilayer);
1028 xpos = 0.0;
1029 zpos = VROCSM + SMPLTT + parSCB[2] - SHEIGHT / 2.0 + ilayer * (CH + VSPACE);
1030
1031 ypos = CLENGTH[ilayer][2] / 2.0 + CLENGTH[ilayer][1];
1032 TVirtualMC::GetMC()->Gspos(cTagV, 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1033 TVirtualMC::GetMC()->Gspos(cTagV, 3, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1034 TVirtualMC::GetMC()->Gspos(cTagV, 5, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1035 TVirtualMC::GetMC()->Gspos(cTagV, 7, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1036
1037 ypos = -CLENGTH[ilayer][2] / 2.0 - CLENGTH[ilayer][1];
1038 TVirtualMC::GetMC()->Gspos(cTagV, 2, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1039 TVirtualMC::GetMC()->Gspos(cTagV, 4, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1040 TVirtualMC::GetMC()->Gspos(cTagV, 6, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1041 TVirtualMC::GetMC()->Gspos(cTagV, 8, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1042 }
1043
1044 //
1045 // The horizontal connections between the cross bars
1046 //
1047
1048 const int kNparSCH = 3;
1049 double parSCH[kNparSCH];
1050
1051 for (ilayer = 1; ilayer < NLAYER - 1; ilayer++) {
1052 parSCH[0] = CWIDTH[ilayer] / 2.0;
1053 parSCH[1] = (CLENGTH[ilayer + 1][2] / 2.0 + CLENGTH[ilayer + 1][1] - CLENGTH[ilayer][2] / 2.0 -
1054 CLENGTH[ilayer][1]) /
1055 2.0;
1056 parSCH[2] = kSCHhgt / 2.0;
1057
1058 snprintf(cTagV, kTag, "USH%01d", ilayer);
1059 createVolume(cTagV, "BOX ", idtmed[1], parSCH, kNparSCH);
1060 xpos = 0.0;
1061 ypos = CLENGTH[ilayer][2] / 2.0 + CLENGTH[ilayer][1] + parSCH[1];
1062 zpos = VROCSM + SMPLTT - kSCHhgt / 2.0 - SHEIGHT / 2.0 + (ilayer + 1) * (CH + VSPACE);
1063 TVirtualMC::GetMC()->Gspos(cTagV, 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1064 TVirtualMC::GetMC()->Gspos(cTagV, 3, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1065 TVirtualMC::GetMC()->Gspos(cTagV, 5, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1066 TVirtualMC::GetMC()->Gspos(cTagV, 7, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1067 ypos = -ypos;
1068 TVirtualMC::GetMC()->Gspos(cTagV, 2, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1069 TVirtualMC::GetMC()->Gspos(cTagV, 4, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1070 TVirtualMC::GetMC()->Gspos(cTagV, 6, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1071 TVirtualMC::GetMC()->Gspos(cTagV, 8, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1072 }
1073
1074 //
1075 // The asymmetric flat frame in the middle
1076 //
1077
1078 // The envelope volume (aluminum)
1079 parTRD[0] = 87.60 / 2.0;
1080 parTRD[1] = 114.00 / 2.0;
1081 parTRD[2] = 1.20 / 2.0;
1082 parTRD[3] = 71.30 / 2.0;
1083 createVolume("USDB", "TRD1", idtmed[1], parTRD, kNparTRD);
1084 // Empty spaces (air)
1085 parTRP[0] = 1.20 / 2.0;
1086 parTRP[1] = 0.0;
1087 parTRP[2] = 0.0;
1088 parTRP[3] = 27.00 / 2.0;
1089 parTRP[4] = 50.60 / 2.0;
1090 parTRP[5] = 5.00 / 2.0;
1091 parTRP[6] = 3.5;
1092 parTRP[7] = 27.00 / 2.0;
1093 parTRP[8] = 50.60 / 2.0;
1094 parTRP[9] = 5.00 / 2.0;
1095 parTRP[10] = 3.5;
1096 createVolume("USD1", "TRAP", idtmed[2], parTRP, kNparTRP);
1097 xpos = 18.0;
1098 ypos = 0.0;
1099 zpos = 27.00 / 2.0 - 71.3 / 2.0;
1100 TVirtualMC::GetMC()->Gspos("USD1", 1, "USDB", xpos, ypos, zpos, matrix[2], "ONLY");
1101 // Empty spaces (air)
1102 parTRP[0] = 1.20 / 2.0;
1103 parTRP[1] = 0.0;
1104 parTRP[2] = 0.0;
1105 parTRP[3] = 33.00 / 2.0;
1106 parTRP[4] = 5.00 / 2.0;
1107 parTRP[5] = 62.10 / 2.0;
1108 parTRP[6] = 3.5;
1109 parTRP[7] = 33.00 / 2.0;
1110 parTRP[8] = 5.00 / 2.0;
1111 parTRP[9] = 62.10 / 2.0;
1112 parTRP[10] = 3.5;
1113 createVolume("USD2", "TRAP", idtmed[2], parTRP, kNparTRP);
1114 xpos = 21.0;
1115 ypos = 0.0;
1116 zpos = 71.3 / 2.0 - 33.0 / 2.0;
1117 TVirtualMC::GetMC()->Gspos("USD2", 1, "USDB", xpos, ypos, zpos, matrix[2], "ONLY");
1118 // Empty spaces (air)
1119 parBOX[0] = 22.50 / 2.0;
1120 parBOX[1] = 1.20 / 2.0;
1121 parBOX[2] = 70.50 / 2.0;
1122 createVolume("USD3", "BOX ", idtmed[2], parBOX, kNparBOX);
1123 xpos = -25.75;
1124 ypos = 0.0;
1125 zpos = 0.4;
1126 TVirtualMC::GetMC()->Gspos("USD3", 1, "USDB", xpos, ypos, zpos, 0, "ONLY");
1127 // Empty spaces (air)
1128 parTRP[0] = 1.20 / 2.0;
1129 parTRP[1] = 0.0;
1130 parTRP[2] = 0.0;
1131 parTRP[3] = 25.50 / 2.0;
1132 parTRP[4] = 5.00 / 2.0;
1133 parTRP[5] = 65.00 / 2.0;
1134 parTRP[6] = -1.0;
1135 parTRP[7] = 25.50 / 2.0;
1136 parTRP[8] = 5.00 / 2.0;
1137 parTRP[9] = 65.00 / 2.0;
1138 parTRP[10] = -1.0;
1139 createVolume("USD4", "TRAP", idtmed[2], parTRP, kNparTRP);
1140 xpos = 2.0;
1141 ypos = 0.0;
1142 zpos = -1.6;
1143 TVirtualMC::GetMC()->Gspos("USD4", 1, "USDB", xpos, ypos, zpos, matrix[6], "ONLY");
1144 // Empty spaces (air)
1145 parTRP[0] = 1.20 / 2.0;
1146 parTRP[1] = 0.0;
1147 parTRP[2] = 0.0;
1148 parTRP[3] = 23.50 / 2.0;
1149 parTRP[4] = 63.50 / 2.0;
1150 parTRP[5] = 5.00 / 2.0;
1151 parTRP[6] = 16.0;
1152 parTRP[7] = 23.50 / 2.0;
1153 parTRP[8] = 63.50 / 2.0;
1154 parTRP[9] = 5.00 / 2.0;
1155 parTRP[10] = 16.0;
1156 createVolume("USD5", "TRAP", idtmed[2], parTRP, kNparTRP);
1157 xpos = 36.5;
1158 ypos = 0.0;
1159 zpos = -1.5;
1160 TVirtualMC::GetMC()->Gspos("USD5", 1, "USDB", xpos, ypos, zpos, matrix[5], "ONLY");
1161 // Empty spaces (air)
1162 parTRP[0] = 1.20 / 2.0;
1163 parTRP[1] = 0.0;
1164 parTRP[2] = 0.0;
1165 parTRP[3] = 70.50 / 2.0;
1166 parTRP[4] = 4.50 / 2.0;
1167 parTRP[5] = 16.50 / 2.0;
1168 parTRP[6] = -5.0;
1169 parTRP[7] = 70.50 / 2.0;
1170 parTRP[8] = 4.50 / 2.0;
1171 parTRP[9] = 16.50 / 2.0;
1172 parTRP[10] = -5.0;
1173 createVolume("USD6", "TRAP", idtmed[2], parTRP, kNparTRP);
1174 xpos = -43.7;
1175 ypos = 0.0;
1176 zpos = 0.4;
1177 TVirtualMC::GetMC()->Gspos("USD6", 1, "USDB", xpos, ypos, zpos, matrix[2], "ONLY");
1178 xpos = 0.0;
1179 ypos = CLENGTH[5][2] / 2.0;
1180 zpos = 0.04;
1181 TVirtualMC::GetMC()->Gspos("USDB", 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1182 TVirtualMC::GetMC()->Gspos("USDB", 2, "UTI1", xpos, -ypos, zpos, 0, "ONLY");
1183 TVirtualMC::GetMC()->Gspos("USDB", 3, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1184 TVirtualMC::GetMC()->Gspos("USDB", 4, "UTI2", xpos, -ypos, zpos, 0, "ONLY");
1185 TVirtualMC::GetMC()->Gspos("USDB", 5, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1186 TVirtualMC::GetMC()->Gspos("USDB", 6, "UTI3", xpos, -ypos, zpos, 0, "ONLY");
1187 TVirtualMC::GetMC()->Gspos("USDB", 7, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1188 TVirtualMC::GetMC()->Gspos("USDB", 8, "UTI4", xpos, -ypos, zpos, 0, "ONLY");
1189 // Upper bar (aluminum)
1190 parBOX[0] = 95.00 / 2.0;
1191 parBOX[1] = 1.20 / 2.0;
1192 parBOX[2] = 3.00 / 2.0;
1193 createVolume("USD7", "BOX ", idtmed[1], parBOX, kNparBOX);
1194 xpos = 0.0;
1195 ypos = CLENGTH[5][2] / 2.0;
1196 zpos = SHEIGHT / 2.0 - SMPLTT - 3.00 / 2.0;
1197 TVirtualMC::GetMC()->Gspos("USD7", 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1198 TVirtualMC::GetMC()->Gspos("USD7", 2, "UTI1", xpos, -ypos, zpos, 0, "ONLY");
1199 TVirtualMC::GetMC()->Gspos("USD7", 3, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1200 TVirtualMC::GetMC()->Gspos("USD7", 4, "UTI2", xpos, -ypos, zpos, 0, "ONLY");
1201 TVirtualMC::GetMC()->Gspos("USD7", 5, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1202 TVirtualMC::GetMC()->Gspos("USD7", 6, "UTI3", xpos, -ypos, zpos, 0, "ONLY");
1203 TVirtualMC::GetMC()->Gspos("USD7", 7, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1204 TVirtualMC::GetMC()->Gspos("USD7", 8, "UTI4", xpos, -ypos, zpos, 0, "ONLY");
1205 // Lower bar (aluminum)
1206 parBOX[0] = 90.22 / 2.0;
1207 parBOX[1] = 1.20 / 2.0;
1208 parBOX[2] = 1.74 / 2.0;
1209 createVolume("USD8", "BOX ", idtmed[1], parBOX, kNparBOX);
1210 xpos = 0.0;
1211 ypos = CLENGTH[5][2] / 2.0 - 0.1;
1212 zpos = -SHEIGHT / 2.0 + SMPLTT + 2.27;
1213 TVirtualMC::GetMC()->Gspos("USD8", 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1214 TVirtualMC::GetMC()->Gspos("USD8", 2, "UTI1", xpos, -ypos, zpos, 0, "ONLY");
1215 TVirtualMC::GetMC()->Gspos("USD8", 3, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1216 TVirtualMC::GetMC()->Gspos("USD8", 4, "UTI2", xpos, -ypos, zpos, 0, "ONLY");
1217 TVirtualMC::GetMC()->Gspos("USD8", 5, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1218 TVirtualMC::GetMC()->Gspos("USD8", 6, "UTI3", xpos, -ypos, zpos, 0, "ONLY");
1219 TVirtualMC::GetMC()->Gspos("USD8", 7, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1220 TVirtualMC::GetMC()->Gspos("USD8", 8, "UTI4", xpos, -ypos, zpos, 0, "ONLY");
1221 // Lower bar (aluminum)
1222 parBOX[0] = 82.60 / 2.0;
1223 parBOX[1] = 1.20 / 2.0;
1224 parBOX[2] = 1.40 / 2.0;
1225 createVolume("USD9", "BOX ", idtmed[1], parBOX, kNparBOX);
1226 xpos = 0.0;
1227 ypos = CLENGTH[5][2] / 2.0;
1228 zpos = -SHEIGHT / 2.0 + SMPLTT + 1.40 / 2.0;
1229 TVirtualMC::GetMC()->Gspos("USD9", 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1230 TVirtualMC::GetMC()->Gspos("USD9", 2, "UTI1", xpos, -ypos, zpos, 0, "ONLY");
1231 TVirtualMC::GetMC()->Gspos("USD9", 3, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1232 TVirtualMC::GetMC()->Gspos("USD9", 4, "UTI2", xpos, -ypos, zpos, 0, "ONLY");
1233 TVirtualMC::GetMC()->Gspos("USD9", 5, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1234 TVirtualMC::GetMC()->Gspos("USD9", 6, "UTI3", xpos, -ypos, zpos, 0, "ONLY");
1235 TVirtualMC::GetMC()->Gspos("USD9", 7, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1236 TVirtualMC::GetMC()->Gspos("USD9", 8, "UTI4", xpos, -ypos, zpos, 0, "ONLY");
1237 // Front sheet (aluminum)
1238 parTRP[0] = 0.10 / 2.0;
1239 parTRP[1] = 0.0;
1240 parTRP[2] = 0.0;
1241 parTRP[3] = 74.50 / 2.0;
1242 parTRP[4] = 31.70 / 2.0;
1243 parTRP[5] = 44.00 / 2.0;
1244 parTRP[6] = -5.0;
1245 parTRP[7] = 74.50 / 2.0;
1246 parTRP[8] = 31.70 / 2.0;
1247 parTRP[9] = 44.00 / 2.0;
1248 parTRP[10] = -5.0;
1249 createVolume("USDF", "TRAP", idtmed[2], parTRP, kNparTRP);
1250 xpos = -32.0;
1251 ypos = CLENGTH[5][2] / 2.0 + 1.20 / 2.0 + 0.10 / 2.0;
1252 zpos = 0.0;
1253 TVirtualMC::GetMC()->Gspos("USDF", 1, "UTI1", xpos, ypos, zpos, matrix[2], "ONLY");
1254 TVirtualMC::GetMC()->Gspos("USDF", 2, "UTI1", xpos, -ypos, zpos, matrix[2], "ONLY");
1255 TVirtualMC::GetMC()->Gspos("USDF", 3, "UTI2", xpos, ypos, zpos, matrix[2], "ONLY");
1256 TVirtualMC::GetMC()->Gspos("USDF", 4, "UTI2", xpos, -ypos, zpos, matrix[2], "ONLY");
1257 TVirtualMC::GetMC()->Gspos("USDF", 5, "UTI3", xpos, ypos, zpos, matrix[2], "ONLY");
1258 TVirtualMC::GetMC()->Gspos("USDF", 6, "UTI3", xpos, -ypos, zpos, matrix[2], "ONLY");
1259 TVirtualMC::GetMC()->Gspos("USDF", 7, "UTI4", xpos, ypos, zpos, matrix[2], "ONLY");
1260 TVirtualMC::GetMC()->Gspos("USDF", 8, "UTI4", xpos, -ypos, zpos, matrix[2], "ONLY");
1261
1262 //
1263 // The flat frame in front of the chambers
1264 //
1265
1266 // The envelope volume (aluminum)
1267 parTRD[0] = 90.00 / 2.0 - 0.1;
1268 parTRD[1] = 114.00 / 2.0 - 0.1;
1269 parTRD[2] = 1.50 / 2.0;
1270 parTRD[3] = 70.30 / 2.0;
1271 createVolume("USCB", "TRD1", idtmed[1], parTRD, kNparTRD);
1272 // Empty spaces (air)
1273 parTRD[0] = 87.00 / 2.0;
1274 parTRD[1] = 10.00 / 2.0;
1275 parTRD[2] = 1.50 / 2.0;
1276 parTRD[3] = 26.35 / 2.0;
1277 createVolume("USC1", "TRD1", idtmed[2], parTRD, kNparTRD);
1278 xpos = 0.0;
1279 ypos = 0.0;
1280 zpos = 26.35 / 2.0 - 70.3 / 2.0;
1281 TVirtualMC::GetMC()->Gspos("USC1", 1, "USCB", xpos, ypos, zpos, 0, "ONLY");
1282 // Empty spaces (air)
1283 parTRD[0] = 10.00 / 2.0;
1284 parTRD[1] = 111.00 / 2.0;
1285 parTRD[2] = 1.50 / 2.0;
1286 parTRD[3] = 35.05 / 2.0;
1287 createVolume("USC2", "TRD1", idtmed[2], parTRD, kNparTRD);
1288 xpos = 0.0;
1289 ypos = 0.0;
1290 zpos = 70.3 / 2.0 - 35.05 / 2.0;
1291 TVirtualMC::GetMC()->Gspos("USC2", 1, "USCB", xpos, ypos, zpos, 0, "ONLY");
1292 // Empty spaces (air)
1293 parTRP[0] = 1.50 / 2.0;
1294 parTRP[1] = 0.0;
1295 parTRP[2] = 0.0;
1296 parTRP[3] = 37.60 / 2.0;
1297 parTRP[4] = 63.90 / 2.0;
1298 parTRP[5] = 8.86 / 2.0;
1299 parTRP[6] = 16.0;
1300 parTRP[7] = 37.60 / 2.0;
1301 parTRP[8] = 63.90 / 2.0;
1302 parTRP[9] = 8.86 / 2.0;
1303 parTRP[10] = 16.0;
1304 createVolume("USC3", "TRAP", idtmed[2], parTRP, kNparTRP);
1305 xpos = -30.5;
1306 ypos = 0.0;
1307 zpos = -2.0;
1308 TVirtualMC::GetMC()->Gspos("USC3", 1, "USCB", xpos, ypos, zpos, matrix[4], "ONLY");
1309 TVirtualMC::GetMC()->Gspos("USC3", 2, "USCB", -xpos, ypos, zpos, matrix[5], "ONLY");
1310 xpos = 0.0;
1311 ypos = CLENGTH[5][2] / 2.0 + CLENGTH[5][1] + CLENGTH[5][0];
1312 zpos = 0.0;
1313 TVirtualMC::GetMC()->Gspos("USCB", 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1314 TVirtualMC::GetMC()->Gspos("USCB", 2, "UTI1", xpos, -ypos, zpos, 0, "ONLY");
1315 TVirtualMC::GetMC()->Gspos("USCB", 3, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1316 TVirtualMC::GetMC()->Gspos("USCB", 4, "UTI2", xpos, -ypos, zpos, 0, "ONLY");
1317 TVirtualMC::GetMC()->Gspos("USCB", 5, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1318 TVirtualMC::GetMC()->Gspos("USCB", 6, "UTI3", xpos, -ypos, zpos, 0, "ONLY");
1319 TVirtualMC::GetMC()->Gspos("USCB", 7, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1320 TVirtualMC::GetMC()->Gspos("USCB", 8, "UTI4", xpos, -ypos, zpos, 0, "ONLY");
1321 // Upper bar (aluminum)
1322 parBOX[0] = 95.00 / 2.0;
1323 parBOX[1] = 1.50 / 2.0;
1324 parBOX[2] = 3.00 / 2.0;
1325 createVolume("USC4", "BOX ", idtmed[1], parBOX, kNparBOX);
1326 xpos = 0.0;
1327 ypos = CLENGTH[5][2] / 2.0 + CLENGTH[5][1] + CLENGTH[5][0];
1328 zpos = SHEIGHT / 2.0 - SMPLTT - 3.00 / 2.0;
1329 TVirtualMC::GetMC()->Gspos("USC4", 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1330 TVirtualMC::GetMC()->Gspos("USC4", 2, "UTI1", xpos, -ypos, zpos, 0, "ONLY");
1331 TVirtualMC::GetMC()->Gspos("USC4", 3, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1332 TVirtualMC::GetMC()->Gspos("USC4", 4, "UTI2", xpos, -ypos, zpos, 0, "ONLY");
1333 TVirtualMC::GetMC()->Gspos("USC4", 5, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1334 TVirtualMC::GetMC()->Gspos("USC4", 6, "UTI3", xpos, -ypos, zpos, 0, "ONLY");
1335 TVirtualMC::GetMC()->Gspos("USC4", 7, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1336 TVirtualMC::GetMC()->Gspos("USC4", 8, "UTI4", xpos, -ypos, zpos, 0, "ONLY");
1337 // Lower bar (aluminum)
1338 parBOX[0] = 90.22 / 2.0;
1339 parBOX[1] = 1.50 / 2.0;
1340 parBOX[2] = 2.00 / 2.0;
1341 createVolume("USC5", "BOX ", idtmed[1], parBOX, kNparBOX);
1342 xpos = 0.0;
1343 ypos = CLENGTH[5][2] / 2.0 + CLENGTH[5][1] + CLENGTH[5][0];
1344 zpos = -SHEIGHT / 2.0 + SMPLTT + 2.60;
1345 TVirtualMC::GetMC()->Gspos("USC5", 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1346 TVirtualMC::GetMC()->Gspos("USC5", 2, "UTI1", xpos, -ypos, zpos, 0, "ONLY");
1347 TVirtualMC::GetMC()->Gspos("USC5", 3, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1348 TVirtualMC::GetMC()->Gspos("USC5", 4, "UTI2", xpos, -ypos, zpos, 0, "ONLY");
1349 TVirtualMC::GetMC()->Gspos("USC5", 5, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1350 TVirtualMC::GetMC()->Gspos("USC5", 6, "UTI3", xpos, -ypos, zpos, 0, "ONLY");
1351 TVirtualMC::GetMC()->Gspos("USC5", 7, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1352 TVirtualMC::GetMC()->Gspos("USC5", 8, "UTI4", xpos, -ypos, zpos, 0, "ONLY");
1353 // Lower bar (aluminum)
1354 parBOX[0] = 82.60 / 2.0;
1355 parBOX[1] = 1.50 / 2.0;
1356 parBOX[2] = 1.60 / 2.0;
1357 createVolume("USC6", "BOX ", idtmed[1], parBOX, kNparBOX);
1358 xpos = 0.0;
1359 ypos = CLENGTH[5][2] / 2.0 + CLENGTH[5][1] + CLENGTH[5][0];
1360 zpos = -SHEIGHT / 2.0 + SMPLTT + 1.60 / 2.0;
1361 TVirtualMC::GetMC()->Gspos("USC6", 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1362 TVirtualMC::GetMC()->Gspos("USC6", 2, "UTI1", xpos, -ypos, zpos, 0, "ONLY");
1363 TVirtualMC::GetMC()->Gspos("USC6", 3, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1364 TVirtualMC::GetMC()->Gspos("USC6", 4, "UTI2", xpos, -ypos, zpos, 0, "ONLY");
1365 TVirtualMC::GetMC()->Gspos("USC6", 5, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1366 TVirtualMC::GetMC()->Gspos("USC6", 6, "UTI3", xpos, -ypos, zpos, 0, "ONLY");
1367 TVirtualMC::GetMC()->Gspos("USC6", 7, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1368 TVirtualMC::GetMC()->Gspos("USC6", 8, "UTI4", xpos, -ypos, zpos, 0, "ONLY");
1369
1370 //
1371 // The long corner ledges
1372 //
1373
1374 const int kNparSCL = 3;
1375 double parSCL[kNparSCL];
1376 const int kNparSCLb = 11;
1377 double parSCLb[kNparSCLb];
1378
1379 // Upper ledges
1380 // Thickness of the corner ledges
1381 const double kSCLthkUa = 0.6;
1382 const double kSCLthkUb = 0.6;
1383 // Width of the corner ledges
1384 const double kSCLwidUa = 3.2;
1385 const double kSCLwidUb = 4.8;
1386 // Position of the corner ledges
1387 const double kSCLposxUa = 0.7;
1388 const double kSCLposxUb = 3.3;
1389 const double kSCLposzUa = 1.65;
1390 const double kSCLposzUb = 0.3;
1391 // Vertical
1392 parSCL[0] = kSCLthkUa / 2.0;
1393 parSCL[1] = SLENGTH / 2.0;
1394 parSCL[2] = kSCLwidUa / 2.0;
1395 createVolume("USL1", "BOX ", idtmed[1], parSCL, kNparSCL);
1396 xpos = SWIDTH2 / 2.0 - SMPLTT - kSCLposxUa;
1397 ypos = 0.0;
1398 zpos = SHEIGHT / 2.0 - SMPLTT - kSCLposzUa;
1399 TVirtualMC::GetMC()->Gspos("USL1", 1, "UTI1", xpos, ypos, zpos, matrix[0], "ONLY");
1400 TVirtualMC::GetMC()->Gspos("USL1", 3, "UTI4", xpos, ypos, zpos, matrix[0], "ONLY");
1401 xpos = -xpos;
1402 TVirtualMC::GetMC()->Gspos("USL1", 2, "UTI1", xpos, ypos, zpos, matrix[1], "ONLY");
1403 TVirtualMC::GetMC()->Gspos("USL1", 4, "UTI4", xpos, ypos, zpos, matrix[1], "ONLY");
1404 // Horizontal
1405 parSCL[0] = kSCLwidUb / 2.0;
1406 parSCL[1] = SLENGTH / 2.0;
1407 parSCL[2] = kSCLthkUb / 2.0;
1408 createVolume("USL2", "BOX ", idtmed[1], parSCL, kNparSCL);
1409 xpos = SWIDTH2 / 2.0 - SMPLTT - kSCLposxUb;
1410 ypos = 0.0;
1411 zpos = SHEIGHT / 2.0 - SMPLTT - kSCLposzUb;
1412 TVirtualMC::GetMC()->Gspos("USL2", 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1413 TVirtualMC::GetMC()->Gspos("USL2", 3, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1414 TVirtualMC::GetMC()->Gspos("USL2", 5, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1415 TVirtualMC::GetMC()->Gspos("USL2", 7, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1416 xpos = -xpos;
1417 TVirtualMC::GetMC()->Gspos("USL2", 2, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1418 TVirtualMC::GetMC()->Gspos("USL2", 4, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1419 TVirtualMC::GetMC()->Gspos("USL2", 6, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1420 TVirtualMC::GetMC()->Gspos("USL2", 8, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1421
1422 // Lower ledges
1423 // Thickness of the corner ledges
1424 const double kSCLthkLa = 2.464;
1425 const double kSCLthkLb = 1.0;
1426 // Width of the corner ledges
1427 const double kSCLwidLa = 8.3;
1428 const double kSCLwidLb = 4.0;
1429 // Position of the corner ledges
1430 const double kSCLposxLa = (3.0 * kSCLthkLb - kSCLthkLa) / 4.0 + 0.05;
1431 const double kSCLposxLb = kSCLthkLb + kSCLwidLb / 2.0 + 0.05;
1432 const double kSCLposzLa = kSCLwidLa / 2.0;
1433 const double kSCLposzLb = kSCLthkLb / 2.0;
1434 // Vertical
1435 // Trapezoidal shape
1436 parSCLb[0] = SLENGTH / 2.0;
1437 parSCLb[1] = 0.0;
1438 parSCLb[2] = 0.0;
1439 parSCLb[3] = kSCLwidLa / 2.0;
1440 parSCLb[4] = kSCLthkLb / 2.0;
1441 parSCLb[5] = kSCLthkLa / 2.0;
1442 parSCLb[6] = 5.0;
1443 parSCLb[7] = kSCLwidLa / 2.0;
1444 parSCLb[8] = kSCLthkLb / 2.0;
1445 parSCLb[9] = kSCLthkLa / 2.0;
1446 parSCLb[10] = 5.0;
1447 createVolume("USL3", "TRAP", idtmed[1], parSCLb, kNparSCLb);
1448 xpos = SWIDTH1 / 2.0 - SMPLTT - kSCLposxLa;
1449 ypos = 0.0;
1450 zpos = -SHEIGHT / 2.0 + SMPLTT + kSCLposzLa;
1451 TVirtualMC::GetMC()->Gspos("USL3", 1, "UTI1", xpos, ypos, zpos, matrix[2], "ONLY");
1452 TVirtualMC::GetMC()->Gspos("USL3", 3, "UTI2", xpos, ypos, zpos, matrix[2], "ONLY");
1453 TVirtualMC::GetMC()->Gspos("USL3", 5, "UTI3", xpos, ypos, zpos, matrix[2], "ONLY");
1454 TVirtualMC::GetMC()->Gspos("USL3", 7, "UTI4", xpos, ypos, zpos, matrix[2], "ONLY");
1455 xpos = -xpos;
1456 TVirtualMC::GetMC()->Gspos("USL3", 2, "UTI1", xpos, ypos, zpos, matrix[3], "ONLY");
1457 TVirtualMC::GetMC()->Gspos("USL3", 4, "UTI2", xpos, ypos, zpos, matrix[3], "ONLY");
1458 TVirtualMC::GetMC()->Gspos("USL3", 6, "UTI3", xpos, ypos, zpos, matrix[3], "ONLY");
1459 TVirtualMC::GetMC()->Gspos("USL3", 8, "UTI4", xpos, ypos, zpos, matrix[3], "ONLY");
1460 // Horizontal part
1461 parSCL[0] = kSCLwidLb / 2.0;
1462 parSCL[1] = SLENGTH / 2.0;
1463 parSCL[2] = kSCLthkLb / 2.0;
1464 createVolume("USL4", "BOX ", idtmed[1], parSCL, kNparSCL);
1465 xpos = SWIDTH1 / 2.0 - SMPLTT - kSCLposxLb;
1466 ypos = 0.0;
1467 zpos = -SHEIGHT / 2.0 + SMPLTT + kSCLposzLb;
1468 TVirtualMC::GetMC()->Gspos("USL4", 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1469 TVirtualMC::GetMC()->Gspos("USL4", 3, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1470 TVirtualMC::GetMC()->Gspos("USL4", 5, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1471 TVirtualMC::GetMC()->Gspos("USL4", 7, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1472 xpos = -xpos;
1473 TVirtualMC::GetMC()->Gspos("USL4", 2, "UTI1", xpos, ypos, zpos, 0, "ONLY");
1474 TVirtualMC::GetMC()->Gspos("USL4", 4, "UTI2", xpos, ypos, zpos, 0, "ONLY");
1475 TVirtualMC::GetMC()->Gspos("USL4", 6, "UTI3", xpos, ypos, zpos, 0, "ONLY");
1476 TVirtualMC::GetMC()->Gspos("USL4", 8, "UTI4", xpos, ypos, zpos, 0, "ONLY");
1477
1478 //
1479 // Aluminum plates in the front part of the super modules
1480 //
1481
1482 const int kNparTrd = 4;
1483 double parTrd[kNparTrd];
1484 parTrd[0] = SWIDTH1 / 2.0 - 2.5;
1485 parTrd[1] = SWIDTH2 / 2.0 - 2.5;
1486 parTrd[2] = SMPLTT / 2.0;
1487 parTrd[3] = SHEIGHT / 2.0 - 1.0;
1488 createVolume("UTA1", "TRD1", idtmed[1], parTrd, kNparTrd);
1489 xpos = 0.0;
1490 ypos = SMPLTT / 2.0 - FLENGTH / 2.0;
1491 zpos = -0.5;
1492 TVirtualMC::GetMC()->Gspos("UTA1", 1, "UTF1", xpos, ypos, zpos, 0, "ONLY");
1493 TVirtualMC::GetMC()->Gspos("UTA1", 2, "UTF2", xpos, -ypos, zpos, 0, "ONLY");
1494
1495 const int kNparPlt = 3;
1496 double parPlt[kNparPlt];
1497 parPlt[0] = 0.0;
1498 parPlt[1] = 0.0;
1499 parPlt[2] = 0.0;
1500 createVolume("UTA2", "BOX ", idtmed[1], parPlt, 0);
1501 xpos = 0.0;
1502 ypos = 0.0;
1503 zpos = SHEIGHT / 2.0 - SMPLTT / 2.0;
1504 parPlt[0] = SWIDTH2 / 2.0 - 0.2;
1505 parPlt[1] = FLENGTH / 2.0;
1506 parPlt[2] = SMPLTT / 2.0;
1507 TVirtualMC::GetMC()->Gsposp("UTA2", 1, "UTF2", xpos, ypos, zpos, 0, "ONLY", parPlt, kNparPlt);
1508 xpos = (SWIDTH1 + SWIDTH2) / 4.0 - SMPLTT / 2.0 - 0.0016;
1509 ypos = 0.0;
1510 zpos = 0.0;
1511 parPlt[0] = SMPLTT / 2.0;
1512 parPlt[1] = FLENGTH / 2.0;
1513 parPlt[2] = SHEIGHT / 2.0;
1514 TVirtualMC::GetMC()->Gsposp("UTA2", 2, "UTF2", xpos, ypos, zpos, matrix[0], "ONLY", parPlt, kNparPlt);
1515 TVirtualMC::GetMC()->Gsposp("UTA2", 3, "UTF2", -xpos, ypos, zpos, matrix[1], "ONLY", parPlt, kNparPlt);
1516
1517 // Additional aluminum bar
1518 parBOX[0] = 80.0 / 2.0;
1519 parBOX[1] = 1.0 / 2.0;
1520 parBOX[2] = 10.0 / 2.0;
1521 createVolume("UTA3", "BOX ", idtmed[1], parBOX, kNparBOX);
1522 xpos = 0.0;
1523 ypos = 1.0 / 2.0 + SMPLTT - FLENGTH / 2.0;
1524 zpos = SHEIGHT / 2.0 - 1.5 - 10.0 / 2.0;
1525 TVirtualMC::GetMC()->Gspos("UTA3", 1, "UTF1", xpos, ypos, zpos, 0, "ONLY");
1526 TVirtualMC::GetMC()->Gspos("UTA3", 2, "UTF2", xpos, -ypos, zpos, 0, "ONLY");
1527}
1528
1529//_____________________________________________________________________________
1530void Geometry::createServices(std::vector<int> const& idtmed)
1531{
1532 //
1533 // Create the geometry of the services
1534 //
1535 // Names of the TRD services volumina
1536 //
1537 // UTC1 Cooling arterias (Al)
1538 // UTC2 Cooling arterias (Water)
1539 // UUxx Volumes for the services at the chambers (Air)
1540 // UMCM Readout MCMs (G10/Cu/Si)
1541 // UDCS DCSs boards (G10/Cu)
1542 // UTP1 Power bars (Cu)
1543 // UTCP Cooling pipes (Fe)
1544 // UTCH Cooling pipes (Water)
1545 // UTPL Power lines (Cu)
1546 // UTGD Gas distribution box (V2A)
1547 //
1548
1549 int ilayer = 0;
1550 int istack = 0;
1551
1552 double xpos = 0.0;
1553 double ypos = 0.0;
1554 double zpos = 0.0;
1555
1556 const int kTag = 100;
1557 char cTagV[kTag];
1558 char cTagM[kTag];
1559
1560 const int kNparBox = 3;
1561 double parBox[kNparBox];
1562
1563 const int kNparTube = 3;
1564 double parTube[kNparTube];
1565
1566 // Services inside the baby frame
1567 const double kBBMdz = 223.0;
1568 const double kBBSdz = 8.5;
1569
1570 // Services inside the back frame
1571 const double kBFMdz = 118.0;
1572 const double kBFSdz = 8.5;
1573
1574 // The rotation matrices
1575 const int kNmatrix = 10;
1576 int matrix[kNmatrix];
1577 TVirtualMC::GetMC()->Matrix(matrix[0], 100.0, 0.0, 90.0, 90.0, 10.0, 0.0); // rotation around y-axis
1578 TVirtualMC::GetMC()->Matrix(matrix[1], 80.0, 0.0, 90.0, 90.0, 10.0, 180.0); // rotation around y-axis
1579 TVirtualMC::GetMC()->Matrix(matrix[2], 0.0, 0.0, 90.0, 90.0, 90.0, 0.0);
1580 TVirtualMC::GetMC()->Matrix(matrix[3], 180.0, 0.0, 90.0, 90.0, 90.0, 180.0);
1581 TVirtualMC::GetMC()->Matrix(matrix[4], 90.0, 0.0, 0.0, 0.0, 90.0, 90.0);
1582 TVirtualMC::GetMC()->Matrix(matrix[5], 100.0, 0.0, 90.0, 270.0, 10.0, 0.0);
1583 TVirtualMC::GetMC()->Matrix(matrix[6], 80.0, 0.0, 90.0, 270.0, 10.0, 180.0);
1584 TVirtualMC::GetMC()->Matrix(matrix[7], 90.0, 10.0, 90.0, 100.0, 0.0, 0.0); // rotation around z-axis
1585 TVirtualMC::GetMC()->Matrix(matrix[8], 90.0, 350.0, 90.0, 80.0, 0.0, 0.0); // rotation around z-axis
1586 TVirtualMC::GetMC()->Matrix(matrix[9], 90.0, 90.0, 90.0, 180.0, 0.0, 0.0); // rotation around z-axis
1587
1588 //
1589 // The cooling arterias
1590 //
1591
1592 // Width of the cooling arterias
1593 const double kCOLwid = 0.8;
1594 // Height of the cooling arterias
1595 const double kCOLhgt = 6.5;
1596 // Positioning of the cooling
1597 const double kCOLposx = 1.0;
1598 const double kCOLposz = -1.2;
1599 // Thickness of the walls of the cooling arterias
1600 const double kCOLthk = 0.1;
1601 const int kNparCOL = 3;
1602 double parCOL[kNparCOL];
1603 parCOL[0] = 0.0;
1604 parCOL[1] = 0.0;
1605 parCOL[2] = 0.0;
1606 createVolume("UTC1", "BOX ", idtmed[8], parCOL, 0);
1607 createVolume("UTC3", "BOX ", idtmed[8], parCOL, 0);
1608 parCOL[0] = kCOLwid / 2.0 - kCOLthk;
1609 parCOL[1] = -1.0;
1610 parCOL[2] = kCOLhgt / 2.0 - kCOLthk;
1611 createVolume("UTC2", "BOX ", idtmed[14], parCOL, kNparCOL);
1612 createVolume("UTC4", "BOX ", idtmed[14], parCOL, kNparCOL);
1613
1614 xpos = 0.0;
1615 ypos = 0.0;
1616 zpos = 0.0;
1617 TVirtualMC::GetMC()->Gspos("UTC2", 1, "UTC1", xpos, ypos, zpos, 0, "ONLY");
1618 TVirtualMC::GetMC()->Gspos("UTC4", 1, "UTC3", xpos, ypos, zpos, 0, "ONLY");
1619
1620 for (ilayer = 1; ilayer < NLAYER; ilayer++) {
1621 // Along the chambers
1622 xpos = CWIDTH[ilayer] / 2.0 + kCOLwid / 2.0 + kCOLposx;
1623 ypos = 0.0;
1624 zpos =
1625 VROCSM + SMPLTT - CALZPOS + kCOLhgt / 2.0 - SHEIGHT / 2.0 + kCOLposz + ilayer * (CH + VSPACE);
1626 parCOL[0] = kCOLwid / 2.0;
1627 parCOL[1] = SLENGTH / 2.0;
1628 parCOL[2] = kCOLhgt / 2.0;
1629 TVirtualMC::GetMC()->Gsposp("UTC1", ilayer, "UTI1", xpos, ypos, zpos, matrix[0], "ONLY", parCOL, kNparCOL);
1630 TVirtualMC::GetMC()->Gsposp("UTC1", ilayer + NLAYER, "UTI1", -xpos, ypos, zpos, matrix[1], "ONLY", parCOL,
1631 kNparCOL);
1632 TVirtualMC::GetMC()->Gsposp("UTC1", ilayer + 6 * NLAYER, "UTI2", xpos, ypos, zpos, matrix[0], "ONLY", parCOL,
1633 kNparCOL);
1634 TVirtualMC::GetMC()->Gsposp("UTC1", ilayer + 7 * NLAYER, "UTI2", -xpos, ypos, zpos, matrix[1], "ONLY", parCOL,
1635 kNparCOL);
1636 TVirtualMC::GetMC()->Gsposp("UTC1", ilayer + 8 * NLAYER, "UTI3", xpos, ypos, zpos, matrix[0], "ONLY", parCOL,
1637 kNparCOL);
1638 TVirtualMC::GetMC()->Gsposp("UTC1", ilayer + 9 * NLAYER, "UTI3", -xpos, ypos, zpos, matrix[1], "ONLY", parCOL,
1639 kNparCOL);
1640 TVirtualMC::GetMC()->Gsposp("UTC1", ilayer + 10 * NLAYER, "UTI4", xpos, ypos, zpos, matrix[0], "ONLY", parCOL,
1641 kNparCOL);
1642 TVirtualMC::GetMC()->Gsposp("UTC1", ilayer + 11 * NLAYER, "UTI4", -xpos, ypos, zpos, matrix[1], "ONLY", parCOL,
1643 kNparCOL);
1644
1645 // Front of supermodules
1646 xpos = CWIDTH[ilayer] / 2.0 + kCOLwid / 2.0 + kCOLposx;
1647 ypos = 0.0;
1648 zpos =
1649 VROCSM + SMPLTT - CALZPOS + kCOLhgt / 2.0 - SHEIGHT / 2.0 + kCOLposz + ilayer * (CH + VSPACE);
1650 parCOL[0] = kCOLwid / 2.0;
1651 parCOL[1] = FLENGTH / 2.0;
1652 parCOL[2] = kCOLhgt / 2.0;
1653 TVirtualMC::GetMC()->Gsposp("UTC3", ilayer + 2 * NLAYER, "UTF1", xpos, ypos, zpos, matrix[0], "ONLY", parCOL,
1654 kNparCOL);
1655 TVirtualMC::GetMC()->Gsposp("UTC3", ilayer + 3 * NLAYER, "UTF1", -xpos, ypos, zpos, matrix[1], "ONLY", parCOL,
1656 kNparCOL);
1657 TVirtualMC::GetMC()->Gsposp("UTC3", ilayer + 4 * NLAYER, "UTF2", xpos, ypos, zpos, matrix[0], "ONLY", parCOL,
1658 kNparCOL);
1659 TVirtualMC::GetMC()->Gsposp("UTC3", ilayer + 5 * NLAYER, "UTF2", -xpos, ypos, zpos, matrix[1], "ONLY", parCOL,
1660 kNparCOL);
1661 }
1662
1663 for (ilayer = 1; ilayer < NLAYER; ilayer++) {
1664 // In baby frame
1665 xpos = CWIDTH[ilayer] / 2.0 + kCOLwid / 2.0 + kCOLposx - 2.5;
1666 ypos = kBBSdz / 2.0 - kBBMdz / 2.0;
1667 zpos =
1668 VROCSM + SMPLTT - CALZPOS + kCOLhgt / 2.0 - SHEIGHT / 2.0 + kCOLposz + ilayer * (CH + VSPACE);
1669 parCOL[0] = kCOLwid / 2.0;
1670 parCOL[1] = kBBSdz / 2.0;
1671 parCOL[2] = kCOLhgt / 2.0;
1672 TVirtualMC::GetMC()->Gsposp("UTC3", ilayer + 6 * NLAYER, "BBTRD", xpos, ypos, zpos, matrix[0], "ONLY", parCOL,
1673 kNparCOL);
1674 TVirtualMC::GetMC()->Gsposp("UTC3", ilayer + 7 * NLAYER, "BBTRD", -xpos, ypos, zpos, matrix[1], "ONLY", parCOL,
1675 kNparCOL);
1676 }
1677
1678 for (ilayer = 1; ilayer < NLAYER; ilayer++) {
1679 // In back frame
1680 xpos = CWIDTH[ilayer] / 2.0 + kCOLwid / 2.0 + kCOLposx - 0.3;
1681 ypos = -kBFSdz / 2.0 + kBFMdz / 2.0;
1682 zpos =
1683 VROCSM + SMPLTT - CALZPOS + kCOLhgt / 2.0 - SHEIGHT / 2.0 + kCOLposz + ilayer * (CH + VSPACE);
1684 parCOL[0] = kCOLwid / 2.0;
1685 parCOL[1] = kBFSdz / 2.0;
1686 parCOL[2] = kCOLhgt / 2.0;
1687 TVirtualMC::GetMC()->Gsposp("UTC3", ilayer + 6 * NLAYER, "BFTRD", xpos, ypos, zpos, matrix[0], "ONLY", parCOL,
1688 kNparCOL);
1689 TVirtualMC::GetMC()->Gsposp("UTC3", ilayer + 7 * NLAYER, "BFTRD", -xpos, ypos, zpos, matrix[1], "ONLY", parCOL,
1690 kNparCOL);
1691 }
1692
1693 // The upper most layer
1694 // Along the chambers
1695 xpos = CWIDTH[5] / 2.0 - kCOLhgt / 2.0 - 1.3;
1696 ypos = 0.0;
1697 zpos = SHEIGHT / 2.0 - SMPLTT - 0.4 - kCOLwid / 2.0;
1698 parCOL[0] = kCOLwid / 2.0;
1699 parCOL[1] = SLENGTH / 2.0;
1700 parCOL[2] = kCOLhgt / 2.0;
1701 TVirtualMC::GetMC()->Gsposp("UTC1", 6, "UTI1", xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1702 TVirtualMC::GetMC()->Gsposp("UTC1", 6 + NLAYER, "UTI1", -xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1703 TVirtualMC::GetMC()->Gsposp("UTC1", 6 + 6 * NLAYER, "UTI2", xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1704 TVirtualMC::GetMC()->Gsposp("UTC1", 6 + 7 * NLAYER, "UTI2", -xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1705 TVirtualMC::GetMC()->Gsposp("UTC1", 6 + 8 * NLAYER, "UTI3", xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1706 TVirtualMC::GetMC()->Gsposp("UTC1", 6 + 9 * NLAYER, "UTI3", -xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1707 TVirtualMC::GetMC()->Gsposp("UTC1", 6 + 10 * NLAYER, "UTI4", xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1708 TVirtualMC::GetMC()->Gsposp("UTC1", 6 + 11 * NLAYER, "UTI4", -xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1709 // Front of supermodules
1710 xpos = CWIDTH[5] / 2.0 - kCOLhgt / 2.0 - 1.3;
1711 ypos = 0.0;
1712 zpos = SHEIGHT / 2.0 - SMPLTT - 0.4 - kCOLwid / 2.0;
1713 parCOL[0] = kCOLwid / 2.0;
1714 parCOL[1] = FLENGTH / 2.0;
1715 parCOL[2] = kCOLhgt / 2.0;
1716 TVirtualMC::GetMC()->Gsposp("UTC3", 6 + 2 * NLAYER, "UTF1", xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1717 TVirtualMC::GetMC()->Gsposp("UTC3", 6 + 3 * NLAYER, "UTF1", -xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1718 TVirtualMC::GetMC()->Gsposp("UTC3", 6 + 4 * NLAYER, "UTF2", xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1719 TVirtualMC::GetMC()->Gsposp("UTC3", 6 + 5 * NLAYER, "UTF2", -xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1720 // In baby frame
1721 xpos = CWIDTH[5] / 2.0 - kCOLhgt / 2.0 - 3.1;
1722 ypos = kBBSdz / 2.0 - kBBMdz / 2.0;
1723 zpos = SHEIGHT / 2.0 - SMPLTT - 0.4 - kCOLwid / 2.0;
1724 parCOL[0] = kCOLwid / 2.0;
1725 parCOL[1] = kBBSdz / 2.0;
1726 parCOL[2] = kCOLhgt / 2.0;
1727 TVirtualMC::GetMC()->Gsposp("UTC3", 6 + 6 * NLAYER, "BBTRD", xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1728 TVirtualMC::GetMC()->Gsposp("UTC3", 6 + 7 * NLAYER, "BBTRD", -xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1729 // In back frame
1730 xpos = CWIDTH[5] / 2.0 - kCOLhgt / 2.0 - 1.3;
1731 ypos = -kBFSdz / 2.0 + kBFMdz / 2.0;
1732 zpos = SHEIGHT / 2.0 - SMPLTT - 0.4 - kCOLwid / 2.0;
1733 parCOL[0] = kCOLwid / 2.0;
1734 parCOL[1] = kBFSdz / 2.0;
1735 parCOL[2] = kCOLhgt / 2.0;
1736 TVirtualMC::GetMC()->Gsposp("UTC3", 6 + 6 * NLAYER, "BFTRD", xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1737 TVirtualMC::GetMC()->Gsposp("UTC3", 6 + 7 * NLAYER, "BFTRD", -xpos, ypos, zpos, matrix[3], "ONLY", parCOL, kNparCOL);
1738
1739 //
1740 // The power bus bars
1741 //
1742
1743 const double kPWRwid = 0.6;
1744 // Increase the height of the power bus bars to take into
1745 // account the material of additional cables, etc.
1746 const double kPWRhgtA = 5.0 + 0.2;
1747 const double kPWRhgtB = 5.0;
1748 const double kPWRposx = 2.0;
1749 const double kPWRposz = 0.1;
1750 const int kNparPWR = 3;
1751 double parPWR[kNparPWR];
1752 parPWR[0] = 0.0;
1753 parPWR[1] = 0.0;
1754 parPWR[2] = 0.0;
1755 createVolume("UTP1", "BOX ", idtmed[25], parPWR, 0);
1756 createVolume("UTP3", "BOX ", idtmed[25], parPWR, 0);
1757
1758 for (ilayer = 1; ilayer < NLAYER; ilayer++) {
1759 // Along the chambers
1760 xpos = CWIDTH[ilayer] / 2.0 + kPWRwid / 2.0 + kPWRposx;
1761 ypos = 0.0;
1762 zpos =
1763 VROCSM + SMPLTT - CALZPOS + kPWRhgtA / 2.0 - SHEIGHT / 2.0 + kPWRposz + ilayer * (CH + VSPACE);
1764 parPWR[0] = kPWRwid / 2.0;
1765 parPWR[1] = SLENGTH / 2.0;
1766 parPWR[2] = kPWRhgtA / 2.0;
1767 TVirtualMC::GetMC()->Gsposp("UTP1", ilayer, "UTI1", xpos, ypos, zpos, matrix[0], "ONLY", parPWR, kNparPWR);
1768 TVirtualMC::GetMC()->Gsposp("UTP1", ilayer + NLAYER, "UTI1", -xpos, ypos, zpos, matrix[1], "ONLY", parPWR,
1769 kNparPWR);
1770 TVirtualMC::GetMC()->Gsposp("UTP1", ilayer + 6 * NLAYER, "UTI2", xpos, ypos, zpos, matrix[0], "ONLY", parPWR,
1771 kNparPWR);
1772 TVirtualMC::GetMC()->Gsposp("UTP1", ilayer + 7 * NLAYER, "UTI2", -xpos, ypos, zpos, matrix[1], "ONLY", parPWR,
1773 kNparPWR);
1774 TVirtualMC::GetMC()->Gsposp("UTP1", ilayer + 8 * NLAYER, "UTI3", xpos, ypos, zpos, matrix[0], "ONLY", parPWR,
1775 kNparPWR);
1776 TVirtualMC::GetMC()->Gsposp("UTP1", ilayer + 9 * NLAYER, "UTI3", -xpos, ypos, zpos, matrix[1], "ONLY", parPWR,
1777 kNparPWR);
1778 TVirtualMC::GetMC()->Gsposp("UTP1", ilayer + 10 * NLAYER, "UTI4", xpos, ypos, zpos, matrix[0], "ONLY", parPWR,
1779 kNparPWR);
1780 TVirtualMC::GetMC()->Gsposp("UTP1", ilayer + 11 * NLAYER, "UTI4", -xpos, ypos, zpos, matrix[1], "ONLY", parPWR,
1781 kNparPWR);
1782
1783 // Front of supermodule
1784 xpos = CWIDTH[ilayer] / 2.0 + kPWRwid / 2.0 + kPWRposx;
1785 ypos = 0.0;
1786 zpos =
1787 VROCSM + SMPLTT - CALZPOS + kPWRhgtA / 2.0 - SHEIGHT / 2.0 + kPWRposz + ilayer * (CH + VSPACE);
1788 parPWR[0] = kPWRwid / 2.0;
1789 parPWR[1] = FLENGTH / 2.0;
1790 parPWR[2] = kPWRhgtA / 2.0;
1791 TVirtualMC::GetMC()->Gsposp("UTP3", ilayer + 2 * NLAYER, "UTF1", xpos, ypos, zpos, matrix[0], "ONLY", parPWR,
1792 kNparPWR);
1793 TVirtualMC::GetMC()->Gsposp("UTP3", ilayer + 3 * NLAYER, "UTF1", -xpos, ypos, zpos, matrix[1], "ONLY", parPWR,
1794 kNparPWR);
1795 TVirtualMC::GetMC()->Gsposp("UTP3", ilayer + 4 * NLAYER, "UTF2", xpos, ypos, zpos, matrix[0], "ONLY", parPWR,
1796 kNparPWR);
1797 TVirtualMC::GetMC()->Gsposp("UTP3", ilayer + 5 * NLAYER, "UTF2", -xpos, ypos, zpos, matrix[1], "ONLY", parPWR,
1798 kNparPWR);
1799 }
1800
1801 for (ilayer = 1; ilayer < NLAYER; ilayer++) {
1802 // In baby frame
1803 xpos = CWIDTH[ilayer] / 2.0 + kPWRwid / 2.0 + kPWRposx - 2.5;
1804 ypos = kBBSdz / 2.0 - kBBMdz / 2.0;
1805 zpos =
1806 VROCSM + SMPLTT - CALZPOS + kPWRhgtB / 2.0 - SHEIGHT / 2.0 + kPWRposz + ilayer * (CH + VSPACE);
1807 parPWR[0] = kPWRwid / 2.0;
1808 parPWR[1] = kBBSdz / 2.0;
1809 parPWR[2] = kPWRhgtB / 2.0;
1810 TVirtualMC::GetMC()->Gsposp("UTP3", ilayer + 6 * NLAYER, "BBTRD", xpos, ypos, zpos, matrix[0], "ONLY", parPWR,
1811 kNparPWR);
1812 TVirtualMC::GetMC()->Gsposp("UTP3", ilayer + 7 * NLAYER, "BBTRD", -xpos, ypos, zpos, matrix[1], "ONLY", parPWR,
1813 kNparPWR);
1814 }
1815
1816 for (ilayer = 1; ilayer < NLAYER; ilayer++) {
1817 // In back frame
1818 xpos = CWIDTH[ilayer] / 2.0 + kPWRwid / 2.0 + kPWRposx - 0.3;
1819 ypos = -kBFSdz / 2.0 + kBFMdz / 2.0;
1820 zpos =
1821 VROCSM + SMPLTT - CALZPOS + kPWRhgtB / 2.0 - SHEIGHT / 2.0 + kPWRposz + ilayer * (CH + VSPACE);
1822 parPWR[0] = kPWRwid / 2.0;
1823 parPWR[1] = kBFSdz / 2.0;
1824 parPWR[2] = kPWRhgtB / 2.0;
1825 TVirtualMC::GetMC()->Gsposp("UTP3", ilayer + 8 * NLAYER, "BFTRD", xpos, ypos, zpos, matrix[0], "ONLY", parPWR,
1826 kNparPWR);
1827 TVirtualMC::GetMC()->Gsposp("UTP3", ilayer + 9 * NLAYER, "BFTRD", -xpos, ypos, zpos, matrix[1], "ONLY", parPWR,
1828 kNparPWR);
1829 }
1830
1831 // The upper most layer
1832 // Along the chambers
1833 xpos = CWIDTH[5] / 2.0 + kPWRhgtB / 2.0 - 1.3;
1834 ypos = 0.0;
1835 zpos = SHEIGHT / 2.0 - SMPLTT - 0.6 - kPWRwid / 2.0;
1836 parPWR[0] = kPWRwid / 2.0;
1837 parPWR[1] = SLENGTH / 2.0;
1838 parPWR[2] = kPWRhgtB / 2.0;
1839 TVirtualMC::GetMC()->Gsposp("UTP1", 6, "UTI1", xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1840 TVirtualMC::GetMC()->Gsposp("UTP1", 6 + NLAYER, "UTI1", -xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1841 TVirtualMC::GetMC()->Gsposp("UTP1", 6 + 6 * NLAYER, "UTI2", xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1842 TVirtualMC::GetMC()->Gsposp("UTP1", 6 + 7 * NLAYER, "UTI2", -xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1843 TVirtualMC::GetMC()->Gsposp("UTP1", 6 + 8 * NLAYER, "UTI3", xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1844 TVirtualMC::GetMC()->Gsposp("UTP1", 6 + 9 * NLAYER, "UTI3", -xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1845 TVirtualMC::GetMC()->Gsposp("UTP1", 6 + 10 * NLAYER, "UTI4", xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1846 TVirtualMC::GetMC()->Gsposp("UTP1", 6 + 11 * NLAYER, "UTI4", -xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1847 // Front of supermodules
1848 xpos = CWIDTH[5] / 2.0 + kPWRhgtB / 2.0 - 1.3;
1849 ypos = 0.0;
1850 zpos = SHEIGHT / 2.0 - SMPLTT - 0.6 - kPWRwid / 2.0;
1851 parPWR[0] = kPWRwid / 2.0;
1852 parPWR[1] = FLENGTH / 2.0;
1853 parPWR[2] = kPWRhgtB / 2.0;
1854 TVirtualMC::GetMC()->Gsposp("UTP3", 6 + 2 * NLAYER, "UTF1", xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1855 TVirtualMC::GetMC()->Gsposp("UTP3", 6 + 3 * NLAYER, "UTF1", -xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1856 TVirtualMC::GetMC()->Gsposp("UTP3", 6 + 4 * NLAYER, "UTF2", xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1857 TVirtualMC::GetMC()->Gsposp("UTP3", 6 + 5 * NLAYER, "UTF2", -xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1858 // In baby frame
1859 xpos = CWIDTH[5] / 2.0 + kPWRhgtB / 2.0 - 3.0;
1860 ypos = kBBSdz / 2.0 - kBBMdz / 2.0;
1861 zpos = SHEIGHT / 2.0 - SMPLTT - 0.6 - kPWRwid / 2.0;
1862 parPWR[0] = kPWRwid / 2.0;
1863 parPWR[1] = kBBSdz / 2.0;
1864 parPWR[2] = kPWRhgtB / 2.0;
1865 TVirtualMC::GetMC()->Gsposp("UTP3", 6 + 6 * NLAYER, "BBTRD", xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1866 TVirtualMC::GetMC()->Gsposp("UTP3", 6 + 7 * NLAYER, "BBTRD", -xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1867 // In back frame
1868 xpos = CWIDTH[5] / 2.0 + kPWRhgtB / 2.0 - 1.3;
1869 ypos = -kBFSdz / 2.0 + kBFMdz / 2.0;
1870 zpos = SHEIGHT / 2.0 - SMPLTT - 0.6 - kPWRwid / 2.0;
1871 parPWR[0] = kPWRwid / 2.0;
1872 parPWR[1] = kBFSdz / 2.0;
1873 parPWR[2] = kPWRhgtB / 2.0;
1874 TVirtualMC::GetMC()->Gsposp("UTP3", 6 + 8 * NLAYER, "BFTRD", xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1875 TVirtualMC::GetMC()->Gsposp("UTP3", 6 + 9 * NLAYER, "BFTRD", -xpos, ypos, zpos, matrix[3], "ONLY", parPWR, kNparPWR);
1876
1877 //
1878 // The gas tubes connecting the chambers in the super modules with holes
1879 // Material: Stainless steel
1880 //
1881
1882 // PHOS holes
1883 parTube[0] = 0.0;
1884 parTube[1] = 2.2 / 2.0;
1885 parTube[2] = CLENGTH[5][2] / 2.0 - HSPACE / 2.0;
1886 createVolume("UTG1", "TUBE", idtmed[8], parTube, kNparTube);
1887 parTube[0] = 0.0;
1888 parTube[1] = 2.1 / 2.0;
1889 parTube[2] = CLENGTH[5][2] / 2.0 - HSPACE / 2.0;
1890 createVolume("UTG2", "TUBE", idtmed[9], parTube, kNparTube);
1891 xpos = 0.0;
1892 ypos = 0.0;
1893 zpos = 0.0;
1894 TVirtualMC::GetMC()->Gspos("UTG2", 1, "UTG1", xpos, ypos, zpos, 0, "ONLY");
1895 for (ilayer = 0; ilayer < NLAYER; ilayer++) {
1896 xpos = CWIDTH[ilayer] / 2.0 + kCOLwid / 2.0 - 1.5;
1897 ypos = 0.0;
1898 zpos = VROCSM + SMPLTT + kCOLhgt / 2.0 - SHEIGHT / 2.0 + 5.0 + ilayer * (CH + VSPACE);
1899 TVirtualMC::GetMC()->Gspos("UTG1", 1 + ilayer, "UTI3", xpos, ypos, zpos, matrix[4], "ONLY");
1900 TVirtualMC::GetMC()->Gspos("UTG1", 7 + ilayer, "UTI3", -xpos, ypos, zpos, matrix[4], "ONLY");
1901 }
1902 // Missing L4S4 chamber in sector 17
1903 parTube[0] = 0.0;
1904 parTube[1] = 2.2 / 2.0;
1905 parTube[2] = CLENGTH[4][4] / 2.0 - HSPACE / 2.0;
1906 createVolume("UTG3", "TUBE", idtmed[8], parTube, kNparTube);
1907 parTube[0] = 0.0;
1908 parTube[1] = 2.1 / 2.0;
1909 parTube[2] = CLENGTH[4][4] / 2.0 - HSPACE / 2.0;
1910 createVolume("UTG4", "TUBE", idtmed[9], parTube, kNparTube);
1911 xpos = 0.0;
1912 ypos = 0.0;
1913 zpos = 0.0;
1914 TVirtualMC::GetMC()->Gspos("UTG4", 1, "UTG3", xpos, ypos, zpos, 0, "ONLY");
1915 xpos = CWIDTH[4] / 2.0 + kCOLwid / 2.0 - 1.5;
1916 ypos = -CLENGTH[4][0] / 2.0 - CLENGTH[4][1] - CLENGTH[4][2] / 2.0;
1917 zpos = VROCSM + SMPLTT + kCOLhgt / 2.0 - SHEIGHT / 2.0 + 5.0 + 4 * (CH + VSPACE);
1918 TVirtualMC::GetMC()->Gspos("UTG3", 1, "UTI4", xpos, ypos, zpos, matrix[4], "ONLY");
1919 // The mirrored tube is the steel pipe UTG3, not its Xe core UTG4 -- compare the PHOS-hole
1920 // loop above, which places UTG1 on both sides.
1921 TVirtualMC::GetMC()->Gspos("UTG3", 2, "UTI4", -xpos, ypos, zpos, matrix[4], "ONLY");
1922
1923 //
1924 // The volumes for the services at the chambers
1925 //
1926
1927 const int kNparServ = 3;
1928 double parServ[kNparServ];
1929
1930 for (int istack : {0, 2}) {
1931 for (ilayer = 0; ilayer < NLAYER; ilayer++) {
1932 int iDet = getDetectorSec(ilayer, istack);
1933
1934 snprintf(cTagV, kTag, "UU%02d", shapeClass(ilayer, istack));
1935 parServ[0] = CWIDTH[ilayer] / 2.0;
1936 parServ[1] = CLENGTH[ilayer][istack] / 2.0 - HSPACE / 2.0;
1937 parServ[2] = CSVH / 2.0;
1938 createVolume(cTagV, "BOX", idtmed[2], parServ, kNparServ);
1939 }
1940 }
1941
1942 //
1943 // The cooling pipes inside the service volumes
1944 //
1945
1946 // The cooling pipes and the water inside them. Their only free parameter is the chamber
1947 // width, which depends on the layer alone, so six volumes cover all 456 rows of a
1948 // supermodule.
1949 for (ilayer = 0; ilayer < NLAYER; ilayer++) {
1950 snprintf(cTagV, kTag, "UCP%01d", ilayer);
1951 parTube[0] = 0.0;
1952 parTube[1] = 0.3 / 2.0; // Thickness of the cooling pipes
1953 parTube[2] = CWIDTH[ilayer] / 2.0;
1954 createVolume(cTagV, "TUBE", idtmed[24], parTube, kNparTube);
1955 snprintf(cTagM, kTag, "UCW%01d", ilayer);
1956 parTube[0] = 0.0;
1957 parTube[1] = 0.2 / 2.0; // The cooling water
1958 parTube[2] = CWIDTH[ilayer] / 2.0;
1959 createVolume(cTagM, "TUBE", idtmed[14], parTube, kNparTube);
1960 TVirtualMC::GetMC()->Gspos(cTagM, 1, cTagV, 0.0, 0.0, 0.0, 0, "ONLY");
1961 }
1962
1963 // Position the cooling pipes in the mother volume
1964 for (int istack : {0, 2}) {
1965 for (ilayer = 0; ilayer < NLAYER; ilayer++) {
1966 int iDet = getDetectorSec(ilayer, istack);
1967 int iCopy = getDetector(ilayer, istack, 0) * 100;
1968 int nMCMrow = getRowMax(ilayer, istack, 0);
1969 double ySize = (getChamberLength(ilayer, istack) - 2.0 * RPADW) / ((double)nMCMrow);
1970 snprintf(cTagV, kTag, "UU%02d", shapeClass(ilayer, istack));
1971 snprintf(cTagM, kTag, "UCP%01d", ilayer);
1972 for (int iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
1973 xpos = 0.0;
1974 ypos = (0.5 + iMCMrow) * ySize - CLENGTH[ilayer][istack] / 2.0 + HSPACE / 2.0;
1975 zpos = 0.0 + 0.742 / 2.0;
1976 TVirtualMC::GetMC()->Gspos(cTagM, iCopy + iMCMrow, cTagV, xpos, ypos, zpos, matrix[2], "ONLY");
1977 }
1978 }
1979 }
1980
1981 //
1982 // The power lines
1983 //
1984
1985 // The copper power lines, again one per layer rather than one per row
1986 for (ilayer = 0; ilayer < NLAYER; ilayer++) {
1987 snprintf(cTagV, kTag, "UPL%01d", ilayer);
1988 parTube[0] = 0.0;
1989 parTube[1] = 0.2 / 2.0; // Thickness of the power lines
1990 parTube[2] = CWIDTH[ilayer] / 2.0;
1991 createVolume(cTagV, "TUBE", idtmed[5], parTube, kNparTube);
1992 }
1993
1994 // Position the power lines in the mother volume
1995 for (int istack : {0, 2}) {
1996 for (ilayer = 0; ilayer < NLAYER; ilayer++) {
1997 int iDet = getDetectorSec(ilayer, istack);
1998 int iCopy = getDetector(ilayer, istack, 0) * 100;
1999 int nMCMrow = getRowMax(ilayer, istack, 0);
2000 double ySize = (getChamberLength(ilayer, istack) - 2.0 * RPADW) / ((double)nMCMrow);
2001 snprintf(cTagV, kTag, "UU%02d", shapeClass(ilayer, istack));
2002 snprintf(cTagM, kTag, "UPL%01d", ilayer);
2003 for (int iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
2004 xpos = 0.0;
2005 ypos = (0.5 + iMCMrow) * ySize - 1.0 - CLENGTH[ilayer][istack] / 2.0 + HSPACE / 2.0;
2006 zpos = -0.4 + 0.742 / 2.0;
2007 TVirtualMC::GetMC()->Gspos(cTagM, iCopy + iMCMrow, cTagV, xpos, ypos, zpos, matrix[2], "ONLY");
2008 }
2009 }
2010 }
2011
2012 //
2013 // The MCMs
2014 //
2015
2016 const double kMCMx = 3.0;
2017 const double kMCMy = 3.0;
2018 const double kMCMz = 0.3;
2019
2020 const double kMCMpcTh = 0.1;
2021 const double kMCMcuTh = 0.0025;
2022 const double kMCMsiTh = 0.03;
2023 const double kMCMcoTh = 0.04;
2024
2025 // The mother volume for the MCMs (air)
2026 const int kNparMCM = 3;
2027 double parMCM[kNparMCM];
2028 parMCM[0] = kMCMx / 2.0;
2029 parMCM[1] = kMCMy / 2.0;
2030 parMCM[2] = kMCMz / 2.0;
2031 createVolume("UMCM", "BOX", idtmed[2], parMCM, kNparMCM);
2032
2033 // The MCM carrier G10 layer
2034 parMCM[0] = kMCMx / 2.0;
2035 parMCM[1] = kMCMy / 2.0;
2036 parMCM[2] = kMCMpcTh / 2.0;
2037 createVolume("UMC1", "BOX", idtmed[19], parMCM, kNparMCM);
2038 // The MCM carrier Cu layer
2039 parMCM[0] = kMCMx / 2.0;
2040 parMCM[1] = kMCMy / 2.0;
2041 parMCM[2] = kMCMcuTh / 2.0;
2042 createVolume("UMC2", "BOX", idtmed[18], parMCM, kNparMCM);
2043 // The silicon of the chips
2044 parMCM[0] = kMCMx / 2.0;
2045 parMCM[1] = kMCMy / 2.0;
2046 parMCM[2] = kMCMsiTh / 2.0;
2047 createVolume("UMC3", "BOX", idtmed[20], parMCM, kNparMCM);
2048 // The aluminum of the cooling plates
2049 parMCM[0] = kMCMx / 2.0;
2050 parMCM[1] = kMCMy / 2.0;
2051 parMCM[2] = kMCMcoTh / 2.0;
2052 createVolume("UMC4", "BOX", idtmed[24], parMCM, kNparMCM);
2053
2054 // The two short cooling pipe stubs that sit on top of every MCM. Their dimensions do not
2055 // depend on layer or stack, so one volume is built here and placed ~7300 times per
2056 // supermodule. Gsposp would instead create a new TGeoVolume on every single call.
2057 parTube[0] = 0.0;
2058 parTube[1] = 0.3 / 2.0; // Thickness of the cooling pipes
2059 parTube[2] = kMCMx / 2.0;
2060 createVolume("UTCQ", "TUBE", idtmed[24], parTube, kNparTube);
2061 parTube[0] = 0.0;
2062 parTube[1] = 0.2 / 2.0; // The cooling water inside them
2063 parTube[2] = kMCMx / 2.0;
2064 createVolume("UTCR", "TUBE", idtmed[14], parTube, kNparTube);
2065 TVirtualMC::GetMC()->Gspos("UTCR", 1, "UTCQ", 0.0, 0.0, 0.0, 0, "ONLY");
2066
2067 // Put the MCM material inside the MCM mother volume
2068 xpos = 0.0;
2069 ypos = 0.0;
2070 zpos = -kMCMz / 2.0 + kMCMpcTh / 2.0;
2071 TVirtualMC::GetMC()->Gspos("UMC1", 1, "UMCM", xpos, ypos, zpos, 0, "ONLY");
2072 zpos += kMCMpcTh / 2.0 + kMCMcuTh / 2.0;
2073 TVirtualMC::GetMC()->Gspos("UMC2", 1, "UMCM", xpos, ypos, zpos, 0, "ONLY");
2074 zpos += kMCMcuTh / 2.0 + kMCMsiTh / 2.0;
2075 TVirtualMC::GetMC()->Gspos("UMC3", 1, "UMCM", xpos, ypos, zpos, 0, "ONLY");
2076 zpos += kMCMsiTh / 2.0 + kMCMcoTh / 2.0;
2077 TVirtualMC::GetMC()->Gspos("UMC4", 1, "UMCM", xpos, ypos, zpos, 0, "ONLY");
2078
2079 // Position the MCMs in the mother volume
2080 for (int istack : {0, 2}) {
2081 for (ilayer = 0; ilayer < NLAYER; ilayer++) {
2082 int iDet = getDetectorSec(ilayer, istack);
2083 int iCopy = getDetector(ilayer, istack, 0) * 1000;
2084 int nMCMrow = getRowMax(ilayer, istack, 0);
2085 double ySize = (getChamberLength(ilayer, istack) - 2.0 * RPADW) / ((double)nMCMrow);
2086 int nMCMcol = 8;
2087 double xSize = (getChamberWidth(ilayer) - 2.0 * CPADW) / ((double)nMCMcol + 6); // Introduce 6 gaps
2088 int iMCM[8] = {1, 2, 3, 5, 8, 9, 10, 12}; // 0..7 MCM + 6 gap structure
2089 snprintf(cTagV, kTag, "UU%02d", shapeClass(ilayer, istack));
2090 for (int iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
2091 for (int iMCMcol = 0; iMCMcol < nMCMcol; iMCMcol++) {
2092 xpos = (0.5 + iMCM[iMCMcol]) * xSize + 1.0 - CWIDTH[ilayer] / 2.0;
2093 ypos = (0.5 + iMCMrow) * ySize + 1.0 - CLENGTH[ilayer][istack] / 2.0 + HSPACE / 2.0;
2094 zpos = -0.4 + 0.742 / 2.0;
2095 TVirtualMC::GetMC()->Gspos("UMCM", iCopy + iMCMrow * 10 + iMCMcol, cTagV, xpos, ypos, zpos, 0, "ONLY");
2096 // Add two additional smaller cooling pipes on top of the MCMs
2097 // to mimic the meandering structure
2098 xpos = (0.5 + iMCM[iMCMcol]) * xSize + 1.0 - CWIDTH[ilayer] / 2.0;
2099 ypos = (0.5 + iMCMrow) * ySize - CLENGTH[ilayer][istack] / 2.0 + HSPACE / 2.0;
2100 zpos = 0.0 + 0.742 / 2.0;
2101 TVirtualMC::GetMC()->Gspos("UTCQ", iCopy + iMCMrow * 10 + iMCMcol + 50, cTagV, xpos, ypos + 1.0, zpos,
2102 matrix[2], "ONLY");
2103 TVirtualMC::GetMC()->Gspos("UTCQ", iCopy + iMCMrow * 10 + iMCMcol + 500, cTagV, xpos, ypos + 2.0, zpos,
2104 matrix[2], "ONLY");
2105 }
2106 }
2107 }
2108 }
2109
2110 //
2111 // The DCS boards
2112 //
2113
2114 const double kDCSx = 9.0;
2115 const double kDCSy = 14.5;
2116 const double kDCSz = 0.3;
2117
2118 const double kDCSpcTh = 0.15;
2119 const double kDCScuTh = 0.01;
2120 const double kDCScoTh = 0.04;
2121
2122 // The mother volume for the DCSs (air)
2123 const int kNparDCS = 3;
2124 double parDCS[kNparDCS];
2125 parDCS[0] = kDCSx / 2.0;
2126 parDCS[1] = kDCSy / 2.0;
2127 parDCS[2] = kDCSz / 2.0;
2128 createVolume("UDCS", "BOX", idtmed[2], parDCS, kNparDCS);
2129
2130 // The DCS carrier G10 layer
2131 parDCS[0] = kDCSx / 2.0;
2132 parDCS[1] = kDCSy / 2.0;
2133 parDCS[2] = kDCSpcTh / 2.0;
2134 createVolume("UDC1", "BOX", idtmed[19], parDCS, kNparDCS);
2135 // The DCS carrier Cu layer
2136 parDCS[0] = kDCSx / 2.0;
2137 parDCS[1] = kDCSy / 2.0;
2138 parDCS[2] = kDCScuTh / 2.0;
2139 createVolume("UDC2", "BOX", idtmed[18], parDCS, kNparDCS);
2140 // The aluminum of the cooling plates
2141 parDCS[0] = 5.0 / 2.0;
2142 parDCS[1] = 5.0 / 2.0;
2143 parDCS[2] = kDCScoTh / 2.0;
2144 createVolume("UDC3", "BOX", idtmed[24], parDCS, kNparDCS);
2145
2146 // Put the DCS material inside the DCS mother volume
2147 xpos = 0.0;
2148 ypos = 0.0;
2149 zpos = -kDCSz / 2.0 + kDCSpcTh / 2.0;
2150 TVirtualMC::GetMC()->Gspos("UDC1", 1, "UDCS", xpos, ypos, zpos, 0, "ONLY");
2151 zpos += kDCSpcTh / 2.0 + kDCScuTh / 2.0;
2152 TVirtualMC::GetMC()->Gspos("UDC2", 1, "UDCS", xpos, ypos, zpos, 0, "ONLY");
2153 zpos += kDCScuTh / 2.0 + kDCScoTh / 2.0;
2154 TVirtualMC::GetMC()->Gspos("UDC3", 1, "UDCS", xpos, ypos, zpos, 0, "ONLY");
2155
2156 // Put the DCS board in the chamber services mother volume
2157 for (int istack : {0, 2}) {
2158 for (ilayer = 0; ilayer < NLAYER; ilayer++) {
2159 int iDet = getDetectorSec(ilayer, istack);
2160 int iCopy = iDet + 1;
2161 xpos = CWIDTH[ilayer] / 2.0 -
2162 1.9 * (getChamberLength(ilayer, istack) - 2.0 * RPADW) / ((double)getRowMax(ilayer, istack, 0));
2163 ypos = 0.05 * CLENGTH[ilayer][istack];
2164 zpos = kDCSz / 2.0 - CSVH / 2.0;
2165 snprintf(cTagV, kTag, "UU%02d", shapeClass(ilayer, istack));
2166 TVirtualMC::GetMC()->Gspos("UDCS", iCopy, cTagV, xpos, ypos, zpos, 0, "ONLY");
2167 }
2168 }
2169
2170 //
2171 // The ORI boards
2172 //
2173
2174 const double kORIx = 4.2;
2175 const double kORIy = 13.5;
2176 const double kORIz = 0.3;
2177
2178 const double kORIpcTh = 0.15;
2179 const double kORIcuTh = 0.01;
2180 const double kORIcoTh = 0.04;
2181
2182 // The mother volume for the ORIs (air)
2183 const int kNparORI = 3;
2184 double parORI[kNparORI];
2185 parORI[0] = kORIx / 2.0;
2186 parORI[1] = kORIy / 2.0;
2187 parORI[2] = kORIz / 2.0;
2188 createVolume("UORI", "BOX", idtmed[2], parORI, kNparORI);
2189
2190 // The ORI carrier G10 layer
2191 parORI[0] = kORIx / 2.0;
2192 parORI[1] = kORIy / 2.0;
2193 parORI[2] = kORIpcTh / 2.0;
2194 createVolume("UOR1", "BOX", idtmed[19], parORI, kNparORI);
2195 // The ORI carrier Cu layer
2196 parORI[0] = kORIx / 2.0;
2197 parORI[1] = kORIy / 2.0;
2198 parORI[2] = kORIcuTh / 2.0;
2199 createVolume("UOR2", "BOX", idtmed[18], parORI, kNparORI);
2200 // The aluminum of the cooling plates
2201 parORI[0] = kORIx / 2.0;
2202 parORI[1] = kORIy / 2.0;
2203 parORI[2] = kORIcoTh / 2.0;
2204 createVolume("UOR3", "BOX", idtmed[24], parORI, kNparORI);
2205
2206 // Put the ORI material inside the ORI mother volume
2207 xpos = 0.0;
2208 ypos = 0.0;
2209 zpos = -kORIz / 2.0 + kORIpcTh / 2.0;
2210 TVirtualMC::GetMC()->Gspos("UOR1", 1, "UORI", xpos, ypos, zpos, 0, "ONLY");
2211 zpos += kORIpcTh / 2.0 + kORIcuTh / 2.0;
2212 TVirtualMC::GetMC()->Gspos("UOR2", 1, "UORI", xpos, ypos, zpos, 0, "ONLY");
2213 zpos += kORIcuTh / 2.0 + kORIcoTh / 2.0;
2214 TVirtualMC::GetMC()->Gspos("UOR3", 1, "UORI", xpos, ypos, zpos, 0, "ONLY");
2215
2216 // Put the ORI board in the chamber services mother volume
2217 for (int istack : {0, 2}) {
2218 for (ilayer = 0; ilayer < NLAYER; ilayer++) {
2219 int iDet = getDetectorSec(ilayer, istack);
2220 int iCopy = iDet + 1;
2221 xpos = CWIDTH[ilayer] / 2.0 -
2222 1.92 * (getChamberLength(ilayer, istack) - 2.0 * RPADW) / ((double)getRowMax(ilayer, istack, 0));
2223 ypos = -16.0;
2224 zpos = kORIz / 2.0 - CSVH / 2.0;
2225 snprintf(cTagV, kTag, "UU%02d", shapeClass(ilayer, istack));
2226 TVirtualMC::GetMC()->Gspos("UORI", iCopy, cTagV, xpos, ypos, zpos, 0, "ONLY");
2227 xpos = -CWIDTH[ilayer] / 2.0 +
2228 3.8 * (getChamberLength(ilayer, istack) - 2.0 * RPADW) / ((double)getRowMax(ilayer, istack, 0));
2229 ypos = -16.0;
2230 zpos = kORIz / 2.0 - CSVH / 2.0;
2231 snprintf(cTagV, kTag, "UU%02d", shapeClass(ilayer, istack));
2232 TVirtualMC::GetMC()->Gspos("UORI", iCopy + MAXCHAMBER, cTagV, xpos, ypos, zpos, 0, "ONLY");
2233 }
2234 }
2235
2236 //
2237 // Services in front of the super module
2238 //
2239
2240 // Gas in-/outlet pipes (INOX) with the Xe inside them, one per layer. These used to reuse
2241 // the names UTG3/UTG4 of the sector-17 tubes above, which only worked because the two
2242 // registrations happened to land in different TGeo volume lists.
2243 for (ilayer = 0; ilayer < NLAYER - 1; ilayer++) {
2244 snprintf(cTagV, kTag, "UGI%01d", ilayer);
2245 parTube[0] = 0.0;
2246 parTube[1] = 1.5 / 2.0;
2247 parTube[2] = CWIDTH[ilayer] / 2.0 - 2.5;
2248 createVolume(cTagV, "TUBE", idtmed[8], parTube, kNparTube);
2249 snprintf(cTagM, kTag, "UGX%01d", ilayer);
2250 parTube[0] = 0.0;
2251 parTube[1] = 1.2 / 2.0;
2252 parTube[2] = CWIDTH[ilayer] / 2.0 - 2.5;
2253 createVolume(cTagM, "TUBE", idtmed[9], parTube, kNparTube);
2254 TVirtualMC::GetMC()->Gspos(cTagM, 1, cTagV, 0.0, 0.0, 0.0, 0, "ONLY");
2255 }
2256 for (ilayer = 0; ilayer < NLAYER - 1; ilayer++) {
2257 xpos = 0.0;
2258 ypos = CLENGTH[ilayer][2] / 2.0 + CLENGTH[ilayer][1] + CLENGTH[ilayer][0];
2259 zpos = 9.0 - SHEIGHT / 2.0 + ilayer * (CH + VSPACE);
2260 snprintf(cTagV, kTag, "UGI%01d", ilayer);
2261 TVirtualMC::GetMC()->Gspos(cTagV, ilayer + 1, "UTI1", xpos, ypos, zpos, matrix[2], "ONLY");
2262 TVirtualMC::GetMC()->Gspos(cTagV, ilayer + 1 + 1 * NLAYER, "UTI1", xpos, -ypos, zpos, matrix[2], "ONLY");
2263 TVirtualMC::GetMC()->Gspos(cTagV, ilayer + 1 + 2 * NLAYER, "UTI2", xpos, ypos, zpos, matrix[2], "ONLY");
2264 TVirtualMC::GetMC()->Gspos(cTagV, ilayer + 1 + 3 * NLAYER, "UTI2", xpos, -ypos, zpos, matrix[2], "ONLY");
2265 TVirtualMC::GetMC()->Gspos(cTagV, ilayer + 1 + 4 * NLAYER, "UTI3", xpos, ypos, zpos, matrix[2], "ONLY");
2266 TVirtualMC::GetMC()->Gspos(cTagV, ilayer + 1 + 5 * NLAYER, "UTI3", xpos, -ypos, zpos, matrix[2], "ONLY");
2267 TVirtualMC::GetMC()->Gspos(cTagV, ilayer + 1 + 6 * NLAYER, "UTI4", xpos, ypos, zpos, matrix[2], "ONLY");
2268 TVirtualMC::GetMC()->Gspos(cTagV, ilayer + 1 + 7 * NLAYER, "UTI4", xpos, -ypos, zpos, matrix[2], "ONLY");
2269 }
2270
2271 // Gas distribution box
2272 parBox[0] = 14.50 / 2.0;
2273 parBox[1] = 4.52 / 2.0;
2274 parBox[2] = 5.00 / 2.0;
2275 createVolume("UTGD", "BOX ", idtmed[8], parBox, kNparBox);
2276 parBox[0] = 14.50 / 2.0;
2277 parBox[1] = 4.00 / 2.0;
2278 parBox[2] = 4.40 / 2.0;
2279 createVolume("UTGI", "BOX ", idtmed[9], parBox, kNparBox);
2280 parTube[0] = 0.0;
2281 parTube[1] = 4.0 / 2.0;
2282 parTube[2] = 8.0 / 2.0;
2283 createVolume("UTGT", "TUBE", idtmed[8], parTube, kNparTube);
2284 parTube[0] = 0.0;
2285 parTube[1] = 3.4 / 2.0;
2286 parTube[2] = 8.0 / 2.0;
2287 createVolume("UTGG", "TUBE", idtmed[9], parTube, kNparTube);
2288 xpos = 0.0;
2289 ypos = 0.0;
2290 zpos = 0.0;
2291 TVirtualMC::GetMC()->Gspos("UTGI", 1, "UTGD", xpos, ypos, zpos, 0, "ONLY");
2292 TVirtualMC::GetMC()->Gspos("UTGG", 1, "UTGT", xpos, ypos, zpos, 0, "ONLY");
2293 xpos = 0.0;
2294 ypos = 0.0;
2295 zpos = 0.0;
2296 TVirtualMC::GetMC()->Gspos("UTGD", 1, "UTF1", xpos, ypos, zpos, 0, "ONLY");
2297 xpos = -3.0;
2298 ypos = 0.0;
2299 zpos = 6.5;
2300 TVirtualMC::GetMC()->Gspos("UTGT", 1, "UTF1", xpos, ypos, zpos, 0, "ONLY");
2301 xpos = -11.25;
2302 ypos = 0.0;
2303 zpos = 0.5;
2304 TVirtualMC::GetMC()->Gspos("UTGT", 3, "UTF1", xpos, ypos, zpos, matrix[2], "ONLY");
2305 xpos = 11.25;
2306 ypos = 0.0;
2307 zpos = 0.5;
2308 TVirtualMC::GetMC()->Gspos("UTGT", 5, "UTF1", xpos, ypos, zpos, matrix[2], "ONLY");
2309
2310 // Cooling manifolds
2311 parBox[0] = 5.0 / 2.0;
2312 parBox[1] = 23.0 / 2.0;
2313 parBox[2] = 70.0 / 2.0;
2314 createVolume("UTCM", "BOX ", idtmed[2], parBox, kNparBox);
2315 parBox[0] = 5.0 / 2.0;
2316 parBox[1] = 5.0 / 2.0;
2317 parBox[2] = 70.0 / 2.0;
2318 createVolume("UTCA", "BOX ", idtmed[8], parBox, kNparBox);
2319 parBox[0] = 5.0 / 2.0 - 0.3;
2320 parBox[1] = 5.0 / 2.0 - 0.3;
2321 parBox[2] = 70.0 / 2.0 - 0.3;
2322 createVolume("UTCW", "BOX ", idtmed[14], parBox, kNparBox);
2323 xpos = 0.0;
2324 ypos = 0.0;
2325 zpos = 0.0;
2326 TVirtualMC::GetMC()->Gspos("UTCW", 1, "UTCA", xpos, ypos, zpos, 0, "ONLY");
2327 xpos = 0.0;
2328 ypos = 5.0 / 2.0 - 23.0 / 2.0;
2329 zpos = 0.0;
2330 TVirtualMC::GetMC()->Gspos("UTCA", 1, "UTCM", xpos, ypos, zpos, 0, "ONLY");
2331 parTube[0] = 0.0;
2332 parTube[1] = 3.0 / 2.0;
2333 parTube[2] = 18.0 / 2.0;
2334 createVolume("UTCO", "TUBE", idtmed[8], parTube, kNparTube);
2335 parTube[0] = 0.0;
2336 parTube[1] = 3.0 / 2.0 - 0.3;
2337 parTube[2] = 18.0 / 2.0;
2338 createVolume("UTCL", "TUBE", idtmed[14], parTube, kNparTube);
2339 xpos = 0.0;
2340 ypos = 0.0;
2341 zpos = 0.0;
2342 TVirtualMC::GetMC()->Gspos("UTCL", 1, "UTCO", xpos, ypos, zpos, 0, "ONLY");
2343 xpos = 0.0;
2344 ypos = 2.5;
2345 zpos = -70.0 / 2.0 + 7.0;
2346 TVirtualMC::GetMC()->Gspos("UTCO", 1, "UTCM", xpos, ypos, zpos, matrix[4], "ONLY");
2347 zpos += 7.0;
2348 TVirtualMC::GetMC()->Gspos("UTCO", 2, "UTCM", xpos, ypos, zpos, matrix[4], "ONLY");
2349 zpos += 7.0;
2350 TVirtualMC::GetMC()->Gspos("UTCO", 3, "UTCM", xpos, ypos, zpos, matrix[4], "ONLY");
2351 zpos += 7.0;
2352 TVirtualMC::GetMC()->Gspos("UTCO", 4, "UTCM", xpos, ypos, zpos, matrix[4], "ONLY");
2353 zpos += 7.0;
2354 TVirtualMC::GetMC()->Gspos("UTCO", 5, "UTCM", xpos, ypos, zpos, matrix[4], "ONLY");
2355 zpos += 7.0;
2356 TVirtualMC::GetMC()->Gspos("UTCO", 6, "UTCM", xpos, ypos, zpos, matrix[4], "ONLY");
2357 zpos += 7.0;
2358 TVirtualMC::GetMC()->Gspos("UTCO", 7, "UTCM", xpos, ypos, zpos, matrix[4], "ONLY");
2359 zpos += 7.0;
2360 TVirtualMC::GetMC()->Gspos("UTCO", 8, "UTCM", xpos, ypos, zpos, matrix[4], "ONLY");
2361
2362 xpos = 40.0;
2363 ypos = FLENGTH / 2.0 - 23.0 / 2.0;
2364 zpos = 0.0;
2365 TVirtualMC::GetMC()->Gspos("UTCM", 1, "UTF1", xpos, ypos, zpos, matrix[0], "ONLY");
2366 TVirtualMC::GetMC()->Gspos("UTCM", 2, "UTF1", -xpos, ypos, zpos, matrix[1], "ONLY");
2367 TVirtualMC::GetMC()->Gspos("UTCM", 3, "UTF2", xpos, -ypos, zpos, matrix[5], "ONLY");
2368 TVirtualMC::GetMC()->Gspos("UTCM", 4, "UTF2", -xpos, -ypos, zpos, matrix[6], "ONLY");
2369
2370 // Power connection boards (Cu)
2371 parBox[0] = 0.5 / 2.0;
2372 parBox[1] = 15.0 / 2.0;
2373 parBox[2] = 7.0 / 2.0;
2374 createVolume("UTPC", "BOX ", idtmed[25], parBox, kNparBox);
2375 for (ilayer = 0; ilayer < NLAYER - 1; ilayer++) {
2376 xpos = CWIDTH[ilayer] / 2.0 + kPWRwid / 2.0;
2377 ypos = 0.0;
2378 zpos = VROCSM + SMPLTT + kPWRhgtA / 2.0 - SHEIGHT / 2.0 + kPWRposz + (ilayer + 1) * (CH + VSPACE);
2379 TVirtualMC::GetMC()->Gspos("UTPC", ilayer, "UTF1", xpos, ypos, zpos, matrix[0], "ONLY");
2380 TVirtualMC::GetMC()->Gspos("UTPC", ilayer + NLAYER, "UTF1", -xpos, ypos, zpos, matrix[1], "ONLY");
2381 }
2382 xpos = CWIDTH[5] / 2.0 + kPWRhgtA / 2.0 - 2.0;
2383 ypos = 0.0;
2384 zpos = SHEIGHT / 2.0 - SMPLTT - 2.0;
2385 TVirtualMC::GetMC()->Gspos("UTPC", 5, "UTF1", xpos, ypos, zpos, matrix[3], "ONLY");
2386 TVirtualMC::GetMC()->Gspos("UTPC", 5 + NLAYER, "UTF1", -xpos, ypos, zpos, matrix[3], "ONLY");
2387
2388 // Power connection panel (Al)
2389 parBox[0] = 60.0 / 2.0;
2390 parBox[1] = 10.0 / 2.0;
2391 parBox[2] = 3.0 / 2.0;
2392 createVolume("UTPP", "BOX ", idtmed[1], parBox, kNparBox);
2393 xpos = 0.0;
2394 ypos = 0.0;
2395 zpos = 18.0;
2396 TVirtualMC::GetMC()->Gspos("UTPP", 1, "UTF1", xpos, ypos, zpos, 0, "ONLY");
2397
2398 //
2399 // Electronics boxes
2400 //
2401
2402 // Casing (INOX)
2403 parBox[0] = 60.0 / 2.0;
2404 parBox[1] = 10.0 / 2.0;
2405 parBox[2] = 6.0 / 2.0;
2406 createVolume("UTE1", "BOX ", idtmed[8], parBox, kNparBox);
2407 // Interior (air)
2408 parBox[0] = parBox[0] - 0.5;
2409 parBox[1] = parBox[1] - 0.5;
2410 parBox[2] = parBox[2] - 0.5;
2411 createVolume("UTE2", "BOX ", idtmed[2], parBox, kNparBox);
2412 xpos = 0.0;
2413 ypos = 0.0;
2414 zpos = 0.0;
2415 TVirtualMC::GetMC()->Gspos("UTE2", 1, "UTE1", xpos, ypos, zpos, 0, "ONLY");
2416 xpos = 0.0;
2417 ypos = SLENGTH / 2.0 - 10.0 / 2.0 - 3.0;
2418 zpos = -SHEIGHT / 2.0 + 6.0 / 2.0 + 1.0;
2419 TVirtualMC::GetMC()->Gspos("UTE1", 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
2420 TVirtualMC::GetMC()->Gspos("UTE1", 2, "UTI2", xpos, ypos, zpos, 0, "ONLY");
2421 TVirtualMC::GetMC()->Gspos("UTE1", 3, "UTI3", xpos, ypos, zpos, 0, "ONLY");
2422 TVirtualMC::GetMC()->Gspos("UTE1", 4, "UTI4", xpos, ypos, zpos, 0, "ONLY");
2423
2424 // Casing (INOX)
2425 parBox[0] = 50.0 / 2.0;
2426 parBox[1] = 15.0 / 2.0;
2427 parBox[2] = 20.0 / 2.0;
2428 createVolume("UTE3", "BOX ", idtmed[8], parBox, kNparBox);
2429 // Interior (air)
2430 parBox[0] = parBox[0] - 0.5;
2431 parBox[1] = parBox[1] - 0.5;
2432 parBox[2] = parBox[2] - 0.5;
2433 createVolume("UTE4", "BOX ", idtmed[2], parBox, kNparBox);
2434 xpos = 0.0;
2435 ypos = 0.0;
2436 zpos = 0.0;
2437 TVirtualMC::GetMC()->Gspos("UTE4", 1, "UTE3", xpos, ypos, zpos, 0, "ONLY");
2438 xpos = 0.0;
2439 ypos = -SLENGTH / 2.0 + 15.0 / 2.0 + 3.0;
2440 zpos = -SHEIGHT / 2.0 + 20.0 / 2.0 + 1.0;
2441 TVirtualMC::GetMC()->Gspos("UTE3", 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
2442 TVirtualMC::GetMC()->Gspos("UTE3", 2, "UTI2", xpos, ypos, zpos, 0, "ONLY");
2443 TVirtualMC::GetMC()->Gspos("UTE3", 3, "UTI3", xpos, ypos, zpos, 0, "ONLY");
2444 TVirtualMC::GetMC()->Gspos("UTE3", 4, "UTI4", xpos, ypos, zpos, 0, "ONLY");
2445
2446 // Casing (INOX)
2447 parBox[0] = 20.0 / 2.0;
2448 parBox[1] = 7.0 / 2.0;
2449 parBox[2] = 20.0 / 2.0;
2450 createVolume("UTE5", "BOX ", idtmed[8], parBox, kNparBox);
2451 // Interior (air)
2452 parBox[0] = parBox[0] - 0.5;
2453 parBox[1] = parBox[1] - 0.5;
2454 parBox[2] = parBox[2] - 0.5;
2455 createVolume("UTE6", "BOX ", idtmed[2], parBox, kNparBox);
2456 xpos = 0.0;
2457 ypos = 0.0;
2458 zpos = 0.0;
2459 TVirtualMC::GetMC()->Gspos("UTE6", 1, "UTE5", xpos, ypos, zpos, 0, "ONLY");
2460 xpos = 20.0;
2461 ypos = -SLENGTH / 2.0 + 7.0 / 2.0 + 3.0;
2462 zpos = 0.0;
2463 TVirtualMC::GetMC()->Gspos("UTE5", 1, "UTI1", xpos, ypos, zpos, 0, "ONLY");
2464 TVirtualMC::GetMC()->Gspos("UTE5", 2, "UTI2", xpos, ypos, zpos, 0, "ONLY");
2465 TVirtualMC::GetMC()->Gspos("UTE5", 3, "UTI3", xpos, ypos, zpos, 0, "ONLY");
2466 TVirtualMC::GetMC()->Gspos("UTE5", 4, "UTI4", xpos, ypos, zpos, 0, "ONLY");
2467 xpos = -xpos;
2468 TVirtualMC::GetMC()->Gspos("UTE5", 5, "UTI1", xpos, ypos, zpos, 0, "ONLY");
2469 TVirtualMC::GetMC()->Gspos("UTE5", 6, "UTI2", xpos, ypos, zpos, 0, "ONLY");
2470 TVirtualMC::GetMC()->Gspos("UTE5", 7, "UTI3", xpos, ypos, zpos, 0, "ONLY");
2471 TVirtualMC::GetMC()->Gspos("UTE5", 8, "UTI4", xpos, ypos, zpos, 0, "ONLY");
2472}
2473
2474//_____________________________________________________________________________
2475void Geometry::assembleChamber(int ilayer, int istack)
2476{
2477 //
2478 // Group volumes UA, UD, UF, UU into an assembly that defines the
2479 // alignable volume of a single readout chamber
2480 //
2481
2482 const int kTag = 100;
2483 char cTagV[kTag];
2484 char cTagM[kTag];
2485
2486 double xpos = 0.0;
2487 double ypos = 0.0;
2488 double zpos = 0.0;
2489
2490 int idet = getDetectorSec(ilayer, istack);
2491 // The parts below are shared between the stacks of equal chamber length; only the
2492 // assembly keeps the per-chamber name, because it is the alignable volume.
2493 int ishape = shapeClass(ilayer, istack);
2494
2495 // Create the assembly for a given ROC
2496 snprintf(cTagM, kTag, "UT%02d", idet);
2497 TGeoVolume* roc = new TGeoVolumeAssembly(cTagM);
2498
2499 // Add the lower part of the chamber (aluminum frame),
2500 // including radiator and drift region
2501 xpos = 0.0;
2502 ypos = 0.0;
2503 zpos = CRAH / 2.0 + CDRH / 2.0 - CHSV / 2.0;
2504 snprintf(cTagV, kTag, "UA%02d", ishape);
2505 TGeoVolume* rocA = gGeoManager->GetVolume(cTagV);
2506 roc->AddNode(rocA, 1, new TGeoTranslation(xpos, ypos, zpos));
2507
2508 // Add the additional aluminum ledges
2509 xpos = CWIDTH[ilayer] / 2.0 + CALWMOD / 2.0;
2510 ypos = 0.0;
2511 zpos = CRAH + CDRH - CALZPOS - CALHMOD / 2.0 - CHSV / 2.0;
2512 snprintf(cTagV, kTag, "UZ%02d", ishape);
2513 TGeoVolume* rocZ = gGeoManager->GetVolume(cTagV);
2514 roc->AddNode(rocZ, 1, new TGeoTranslation(xpos, ypos, zpos));
2515 roc->AddNode(rocZ, 2, new TGeoTranslation(-xpos, ypos, zpos));
2516
2517 // Add the additional wacosit ledges
2518 xpos = CWIDTH[ilayer] / 2.0 + CWSW / 2.0;
2519 ypos = 0.0;
2520 zpos = CRAH + CDRH - CWSH / 2.0 - CHSV / 2.0;
2521 snprintf(cTagV, kTag, "UP%02d", ishape);
2522 TGeoVolume* rocP = gGeoManager->GetVolume(cTagV);
2523 roc->AddNode(rocP, 1, new TGeoTranslation(xpos, ypos, zpos));
2524 roc->AddNode(rocP, 2, new TGeoTranslation(-xpos, ypos, zpos));
2525
2526 // Add the middle part of the chamber (G10 frame),
2527 // including amplification region
2528 xpos = 0.0;
2529 ypos = 0.0;
2530 zpos = CAMH / 2.0 + CRAH + CDRH - CHSV / 2.0;
2531 snprintf(cTagV, kTag, "UD%02d", ishape);
2532 TGeoVolume* rocD = gGeoManager->GetVolume(cTagV);
2533 roc->AddNode(rocD, 1, new TGeoTranslation(xpos, ypos, zpos));
2534
2535 // Add the upper part of the chamber (aluminum frame),
2536 // including back panel and FEE
2537 xpos = 0.0;
2538 ypos = 0.0;
2539 zpos = CROH / 2.0 + CAMH + CRAH + CDRH - CHSV / 2.0;
2540 snprintf(cTagV, kTag, "UF%02d", ishape);
2541 TGeoVolume* rocF = gGeoManager->GetVolume(cTagV);
2542 roc->AddNode(rocF, 1, new TGeoTranslation(xpos, ypos, zpos));
2543
2544 // Add the volume with services on top of the back panel
2545 xpos = 0.0;
2546 ypos = 0.0;
2547 zpos = CSVH / 2.0 + CROH + CAMH + CRAH + CDRH - CHSV / 2.0;
2548 snprintf(cTagV, kTag, "UU%02d", ishape);
2549 TGeoVolume* rocU = gGeoManager->GetVolume(cTagV);
2550 roc->AddNode(rocU, 1, new TGeoTranslation(xpos, ypos, zpos));
2551
2552 // Place the ROC assembly into the super modules
2553 xpos = 0.0;
2554 ypos = 0.0;
2555 ypos = CLENGTH[ilayer][0] + CLENGTH[ilayer][1] + CLENGTH[ilayer][2] / 2.0;
2556 for (int ic = 0; ic < istack; ic++) {
2557 ypos -= CLENGTH[ilayer][ic];
2558 }
2559 ypos -= CLENGTH[ilayer][istack] / 2.0;
2560 zpos = VROCSM + SMPLTT + CHSV / 2.0 - SHEIGHT / 2.0 + ilayer * (CH + VSPACE);
2561 TGeoVolume* sm1 = gGeoManager->GetVolume("UTI1");
2562 TGeoVolume* sm2 = gGeoManager->GetVolume("UTI2");
2563 TGeoVolume* sm3 = gGeoManager->GetVolume("UTI3");
2564 TGeoVolume* sm4 = gGeoManager->GetVolume("UTI4");
2565 sm1->AddNode(roc, 1, new TGeoTranslation(xpos, ypos, zpos));
2566 sm2->AddNode(roc, 1, new TGeoTranslation(xpos, ypos, zpos));
2567 if (istack != 2) {
2568 // w/o middle stack
2569 sm3->AddNode(roc, 1, new TGeoTranslation(xpos, ypos, zpos));
2570 }
2571 if (!((ilayer == 4) && (istack == 4))) {
2572 // Sector 17 w/o L4S4 chamber
2573 sm4->AddNode(roc, 1, new TGeoTranslation(xpos, ypos, zpos));
2574 }
2575}
2576
2578{
2579 if (mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L)) {
2580 useT2LCache();
2581 }
2582 if (mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)) {
2583 useL2GCache();
2584 }
2585 if (mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2G)) {
2586 useT2GCache();
2587 }
2588 if (mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2GRot)) {
2590 }
2591
2592 std::string volPath;
2593 // keep in mind that changing this path can affect behaviour in Detector.cxx
2594 // see: https://github.com/AliceO2Group/AliceO2/pull/3890
2595 const std::string vpStr{"ALIC_1/barrel_1/B077_1/BSEGMO"};
2596 const std::string vpApp1{"_1/BTRD"};
2597 const std::string vpApp2{"_1"};
2598 const std::string vpApp3a{"/UTR1_1/UTS1_1/UTI1_1"};
2599 const std::string vpApp3b{"/UTR2_1/UTS2_1/UTI2_1"};
2600 const std::string vpApp3c{"/UTR3_1/UTS3_1/UTI3_1"};
2601 const std::string vpApp3d{"/UTR4_1/UTS4_1/UTI4_1"};
2602
2603 for (int ilayer = 0; ilayer < NLAYER; ilayer++) {
2604 for (int isector = 0; isector < NSECTOR; isector++) {
2605 for (int istack = 0; istack < NSTACK; istack++) {
2606 Int_t lid = getDetector(ilayer, istack, isector);
2607 // Check for disabled supermodules
2608 volPath = vpStr;
2609 volPath += std::to_string(isector);
2610 volPath += vpApp1;
2611 volPath += std::to_string(isector);
2612 volPath += vpApp2;
2613 switch (isector) {
2614 case 17:
2615 if ((istack == 4) && (ilayer == 4)) {
2616 continue;
2617 }
2618 volPath += vpApp3d;
2619 break;
2620 case 13:
2621 case 14:
2622 case 15:
2623 // Check for holes in from of PHOS
2624 if (istack == 2) {
2625 continue;
2626 }
2627 volPath += vpApp3c;
2628 break;
2629 case 11:
2630 case 12:
2631 volPath += vpApp3b;
2632 break;
2633 default:
2634 volPath += vpApp3a;
2635 };
2636 if (!gGeoManager->CheckPath(volPath.c_str())) {
2637 continue;
2638 }
2639 const auto m = o2::base::GeometryManager::getMatrix(o2::detectors::DetID::TRD, lid);
2640 TGeoHMatrix rotMatrix;
2641 rotMatrix.RotateX(-90);
2642 rotMatrix.RotateY(-90);
2643 rotMatrix.MultiplyLeft(m);
2644 const TGeoHMatrix& t2l = rotMatrix.Inverse();
2645 if (mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G)) {
2646 setMatrixL2G(Mat3D(t2l), lid);
2647 }
2648
2649 Double_t sectorAngle = 20.0 * (isector % 18) + 10.0;
2650 TGeoHMatrix rotSector;
2651 rotSector.RotateZ(sectorAngle);
2652 if (mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2G)) {
2653 setMatrixT2G(Mat3D(rotSector), lid);
2654 }
2655 if (mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2GRot)) {
2656 setMatrixT2GRot(Rot2D(sectorAngle), lid);
2657 }
2658 if (mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L)) {
2659 const TGeoMatrix& inv = rotSector.Inverse();
2660 rotMatrix.MultiplyLeft(&inv);
2661 setMatrixT2L(Mat3D(rotMatrix.Inverse()), lid);
2662 }
2663 }
2664 }
2665 }
2666}
2667
2668//_____________________________________________________________________________
2670{
2671 //
2672 // define alignable volumes of the TRD
2673 //
2674 if (!gGeoManager) {
2675 LOG(fatal) << "Geometry is not loaded";
2676 }
2677
2678 std::string volPath;
2679 std::string vpStr{"ALIC_1/barrel_1/B077_1/BSEGMO"};
2680 const std::string vpApp1{"_1/BTRD"};
2681 const std::string vpApp2{"_1"};
2682 const std::string vpApp3a{"/UTR1_1/UTS1_1/UTI1_1"};
2683 const std::string vpApp3b{"/UTR2_1/UTS2_1/UTI2_1"};
2684 const std::string vpApp3c{"/UTR3_1/UTS3_1/UTI3_1"};
2685 const std::string vpApp3d{"/UTR4_1/UTS4_1/UTI4_1"};
2686 std::string symName;
2687
2688 // in opposite to AliGeomManager, we use consecutive numbering of modules through whole TRD
2689
2690 // The super modules
2691 // The symbolic names are: TRD/sm00 ... TRD/sm17
2692 for (int isector = 0; isector < NSECTOR; isector++) {
2693 volPath = vpStr;
2694 volPath += std::to_string(isector);
2695 volPath += vpApp1;
2696 volPath += std::to_string(isector);
2697 volPath += vpApp2;
2698 symName = Form("TRD/sm%02d", isector);
2699 gGeoManager->SetAlignableEntry(symName.c_str(), volPath.c_str());
2700 }
2701
2702 // The readout chambers
2703 // The symbolic names are: TRD/sm00/st0/pl0 ... TRD/sm17/st4/pl5
2704
2705 for (int isector = 0; isector < NSECTOR; isector++) {
2706 if (!getSMstatus(isector)) {
2707 continue;
2708 }
2709 for (int ilayer = 0; ilayer < NLAYER; ilayer++) {
2710 for (int istack = 0; istack < NSTACK; istack++) {
2711 Int_t lid = getDetector(ilayer, istack, isector);
2712 int idet = getDetectorSec(ilayer, istack);
2713
2714 // Check for disabled supermodules
2715 volPath = vpStr;
2716 volPath += std::to_string(isector);
2717 volPath += vpApp1;
2718 volPath += std::to_string(isector);
2719 volPath += vpApp2;
2720 switch (isector) {
2721 case 17:
2722 if ((istack == 4) && (ilayer == 4)) {
2723 continue;
2724 }
2725 volPath += vpApp3d;
2726 break;
2727 case 13:
2728 case 14:
2729 case 15:
2730 // Check for holes in from of PHOS
2731 if (istack == 2) {
2732 continue;
2733 }
2734 volPath += vpApp3c;
2735 break;
2736 case 11:
2737 case 12:
2738 volPath += vpApp3b;
2739 break;
2740 default:
2741 volPath += vpApp3a;
2742 };
2743 volPath += Form("/UT%02d_1", idet);
2744
2745 symName = Form("TRD/sm%02d/st%d/pl%d", isector, istack, ilayer);
2746 int modID = o2::base::GeometryManager::getSensID(o2::detectors::DetID::TRD, lid);
2747
2748 TGeoPNEntry* alignableEntry = gGeoManager->SetAlignableEntry(symName.c_str(), volPath.c_str(), modID);
2749
2750 // Add the tracking to local matrix
2751 if (alignableEntry) {
2752 TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
2753 Double_t sectorAngle = 20.0 * (isector % 18) + 10.0;
2754 TGeoHMatrix* t2lMatrix = new TGeoHMatrix();
2755 t2lMatrix->RotateZ(sectorAngle);
2756 const TGeoHMatrix& globmatrixi = globMatrix->Inverse();
2757 t2lMatrix->MultiplyLeft(&globmatrixi);
2758 alignableEntry->SetMatrix(t2lMatrix);
2759 } else {
2760 LOG(error) << "Alignable entry is not valid: ModID:" << modID << " Sector:" << isector << " Lr:" << ilayer
2761 << " Stack: " << istack << " name: " << symName.c_str() << " vol: " << volPath.c_str();
2762 }
2763 }
2764 }
2765 }
2766}
2767
2768//_____________________________________________________________________________
2770{
2771
2772 if (!gGeoManager) {
2773 LOG(error) << "Geometry is not loaded yet";
2774 return false;
2775 }
2776
2777 if (isBuilt()) {
2778 LOG(warning) << "Already built";
2779 return true; // already initialized
2780 }
2781
2782 setSize(NCHAMBER, MAXCHAMBER); //Only NCHAMBER=521 of MAXCHAMBER matrices are filled
2783 fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L) | o2::math_utils::bit2Mask(o2::math_utils::TransformType::L2G) |
2784 o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2G) | o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2GRot));
2785 return true;
2786}
2787
2788//_____________________________________________________________________________
2790{
2791 //
2792 // Checks whether the given detector is part of the current geometry
2793 //
2794
2795 if (!isMatrixAvailable(det)) {
2796 return false;
2797 } else {
2798 return true;
2799 }
2800}
General auxilliary methods.
Definition of the GeometryManager class.
uint32_t roc
Definition RawData.h:3
uint32_t col
Definition RawData.h:4
static int getSensID(o2::detectors::DetID detid, int sensid)
static TGeoHMatrix * getMatrix(const char *symname)
Static class with identifiers, bitmasks and names for ALICE detectors.
Definition DetID.h:60
void setMatrixT2L(const Mat3D &matrix, int sensID)
o2::math_utils::Rotation2Df_t Rot2D
void setMatrixT2GRot(const Rot2D &matrix, int sensID)
o2::math_utils::Transform3D Mat3D
void setMatrixL2G(const Mat3D &matrix, int sensID)
void setMatrixT2G(const Mat3D &matrix, int sensID)
bool isMatrixAvailable(int sensID) const
PadPlane mPadPlanes[constants::NLAYER *constants::NSTACK]
bool rotateBack(int det, const float *const loc, float *glb) const
Definition Geometry.cxx:37
void createPadPlaneArray()
Definition Geometry.cxx:55
void addAlignableVolumes() const
bool createClusterMatrixArray()
void fillMatrixCache(int mask) override
void createGeometry(std::vector< int > const &idtmed)
Definition Geometry.cxx:258
bool chamberInGeometry(int det) const
void setLayer(int l)
Definition PadPlane.h:42
const GLfloat * m
Definition glcorearb.h:4066
GLuint const GLchar * name
Definition glcorearb.h:781
GLint GLuint mask
Definition glcorearb.h:291
std::string detectors(const std::vector< std::string > &det, unsigned mask)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)