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
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, float* 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 float xpos;
320 float ypos;
321 float zpos;
322
323 float parTrd[kNparTrd];
324 float 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 float xpos = 0.0;
824 float ypos = 0.0;
825 float zpos = 0.0;
826
827 const int kTag = 100;
828 char cTagV[kTag];
829 char cTagM[kTag];
830
831 const int kNparTRD = 4;
832 float parTRD[kNparTRD];
833 const int kNparBOX = 3;
834 float parBOX[kNparBOX];
835 const int kNparTRP = 11;
836 float 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 float 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 float kSRLhgt = 2.00;
941 const float kSRLwidA = 2.3;
942 const float kSRLwidB = 1.947;
943 const float kSRLdst = 1.135;
944 const int kNparSRL = 11;
945 float 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 float kSCBwid = 1.0;
983 const float kSCBthk = 2.0;
984 const float kSCHhgt = 0.3;
985
986 const int kNparSCB = 3;
987 float 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 float 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 float 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 float 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 float parSCL[kNparSCL];
1376 const int kNparSCLb = 11;
1377 float parSCLb[kNparSCLb];
1378
1379 // Upper ledges
1380 // Thickness of the corner ledges
1381 const float kSCLthkUa = 0.6;
1382 const float kSCLthkUb = 0.6;
1383 // Width of the corner ledges
1384 const float kSCLwidUa = 3.2;
1385 const float kSCLwidUb = 4.8;
1386 // Position of the corner ledges
1387 const float kSCLposxUa = 0.7;
1388 const float kSCLposxUb = 3.3;
1389 const float kSCLposzUa = 1.65;
1390 const float 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 float kSCLthkLa = 2.464;
1425 const float kSCLthkLb = 1.0;
1426 // Width of the corner ledges
1427 const float kSCLwidLa = 8.3;
1428 const float kSCLwidLb = 4.0;
1429 // Position of the corner ledges
1430 const float kSCLposxLa = (3.0 * kSCLthkLb - kSCLthkLa) / 4.0 + 0.05;
1431 const float kSCLposxLb = kSCLthkLb + kSCLwidLb / 2.0 + 0.05;
1432 const float kSCLposzLa = kSCLwidLa / 2.0;
1433 const float 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 float 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 float 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 float xpos = 0.0;
1553 float ypos = 0.0;
1554 float zpos = 0.0;
1555
1556 const int kTag = 100;
1557 char cTagV[kTag];
1558 char cTagM[kTag];
1559
1560 const int kNparBox = 3;
1561 float parBox[kNparBox];
1562
1563 const int kNparTube = 3;
1564 float parTube[kNparTube];
1565
1566 // Services inside the baby frame
1567 const float kBBMdz = 223.0;
1568 const float kBBSdz = 8.5;
1569
1570 // Services inside the back frame
1571 const float kBFMdz = 118.0;
1572 const float 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 float kCOLwid = 0.8;
1594 // Height of the cooling arterias
1595 const float kCOLhgt = 6.5;
1596 // Positioning of the cooling
1597 const float kCOLposx = 1.0;
1598 const float kCOLposz = -1.2;
1599 // Thickness of the walls of the cooling arterias
1600 const float kCOLthk = 0.1;
1601 const int kNparCOL = 3;
1602 float 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 float 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 float kPWRhgtA = 5.0 + 0.2;
1747 const float kPWRhgtB = 5.0;
1748 const float kPWRposx = 2.0;
1749 const float kPWRposz = 0.1;
1750 const int kNparPWR = 3;
1751 float 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 float 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 float ySize = (getChamberLength(ilayer, istack) - 2.0 * RPADW) / ((float)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 float ySize = (getChamberLength(ilayer, istack) - 2.0 * RPADW) / ((float)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 float kMCMx = 3.0;
2017 const float kMCMy = 3.0;
2018 const float kMCMz = 0.3;
2019
2020 const float kMCMpcTh = 0.1;
2021 const float kMCMcuTh = 0.0025;
2022 const float kMCMsiTh = 0.03;
2023 const float kMCMcoTh = 0.04;
2024
2025 // The mother volume for the MCMs (air)
2026 const int kNparMCM = 3;
2027 float 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 float ySize = (getChamberLength(ilayer, istack) - 2.0 * RPADW) / ((float)nMCMrow);
2086 int nMCMcol = 8;
2087 float xSize = (getChamberWidth(ilayer) - 2.0 * CPADW) / ((float)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 float kDCSx = 9.0;
2115 const float kDCSy = 14.5;
2116 const float kDCSz = 0.3;
2117
2118 const float kDCSpcTh = 0.15;
2119 const float kDCScuTh = 0.01;
2120 const float kDCScoTh = 0.04;
2121
2122 // The mother volume for the DCSs (air)
2123 const int kNparDCS = 3;
2124 float 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) / ((float)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 float kORIx = 4.2;
2175 const float kORIy = 13.5;
2176 const float kORIz = 0.3;
2177
2178 const float kORIpcTh = 0.15;
2179 const float kORIcuTh = 0.01;
2180 const float kORIcoTh = 0.04;
2181
2182 // The mother volume for the ORIs (air)
2183 const int kNparORI = 3;
2184 float 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) / ((float)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) / ((float)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 }
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);
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:58
static constexpr ID TRD
Definition DetID.h:65
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
static constexpr float PGLTHICK
Thickness of the glue layer.
static constexpr float PRBTHICK
Thickness of the PCB copper layers.
static constexpr float AMZPOS
Position of the amplification region.
static constexpr float PELTHICK
Thickness of all other electronics components (caps, etc.)
static constexpr float DRZPOS
Position of the drift region.
static constexpr float AMTHICK
Thickness of the amplification region.
static constexpr float CALHMOD
Height of additional aluminum ledge on lower frame.
static constexpr float CWSW
Width of additional wacosit ledge on lower frame.
static constexpr float CWIDTH[constants::NLAYER]
static constexpr float PPDTHICK
Thickness of copper of the pad plane.
static constexpr float CAUT
Al frame of back panel.
static constexpr float DRTHICK
Thickness of the drift region.
static constexpr float CGLT
Thichness of the glue around the radiator.
static constexpr float CSVH
Height of the services on top of the chambers.
static constexpr float RRHTHICK
Thickness of the rohacell layers in the radiator.
static constexpr float CWSH
Height of additional wacosit ledge on lower frame.
static constexpr float CLENGTH[constants::NLAYER][constants::NSTACK]
static constexpr float CHSV
Total height of the chambers (with services)
static constexpr float SWIDTH1
Lower width of the supermodule.
static constexpr float RFBTHICK
Thickness of the fiber layers in the radiator.
static constexpr float SLENGTH
Length of the supermodule.
static constexpr float WRTHICK
Thickness of the wire planes.
static constexpr float PHCTHICK
Thickness of the honeycomb support structure.
static constexpr float CROW
Additional width of the readout chamber frames.
static constexpr float CCLFT
Thickness of the lower Wacosit frame front.
static constexpr float CROH
Height of the readout of the chambers.
static constexpr float PCBTHICK
Thickness of the carbon layers.
static constexpr float CALZPOS
Position of the additional aluminum ledges.
static constexpr float RCBTHICK
Thickness of the carbon layers in the radiator.
static constexpr float CCLST
Thickness of the lower Wacosit frame sides.
static constexpr float WRZPOSB
Position of the wire planes.
static constexpr float RGLTHICK
Thickness of the glue layers in the radiator.
static constexpr float VROCSM
Radial distance of the first ROC to the outer plates of the SM.
PadPlane mPadPlanes[constants::NLAYER *constants::NSTACK]
static constexpr float FLENGTH
static constexpr float CRAH
Height of the radiator part of the chambers.
static constexpr float PPPTHICK
Thickness of PCB board of the pad plane.
static constexpr float CALH
Height of additional aluminum ledge on lower frame.
static constexpr float VSPACE
Vertical spacing of the chambers.
static constexpr float SHEIGHT
Height of the supermodule.
static constexpr float CDRH
Height of the drift region of the chambers.
static constexpr float CCUTB
Thickness of the upper Wacosit frame around amp. region.
static constexpr float SMPLTT
Thickness of the super module side plates.
static constexpr float HSPACE
Horizontal spacing of the chambers.
static constexpr float CH
Total height of the chambers (w/o services)
static constexpr float CALWMOD
Width of additional aluminum ledge on lower frame.
static constexpr float RMYTHICK
Thickness of the mylar layers in the radiator.
static constexpr float SWIDTH2
Upper width of the supermodule.
static constexpr float CPADW
static constexpr float PPCTHICK
Thickness of the PCB readout boards.
static constexpr float RPADW
>Difference of outer chamber width and pad plane width
static constexpr float WRZPOSA
Position of the wire planes.
static constexpr float CAMH
Height of the amplification region of the chambers.
static constexpr float CCUTA
Upper Wacosit frame around amplification region.
static constexpr float CALT
Thicknesses of different parts of the chamber frame Lower aluminum frame.
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)
constexpr int NLAYER
the number of layers
Definition Constants.h:27
constexpr int NSECTOR
the number of sectors
Definition Constants.h:25
constexpr int NSTACK
the number of stacks per sector
Definition Constants.h:26
constexpr int MAXCHAMBER
the maximum number of installed chambers
Definition Constants.h:30
constexpr int NCHAMBER
the number of chambers actually installed
Definition Constants.h:32
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
static constexpr int L2G
Definition Cartesian.h:55
static constexpr int T2L
Definition Cartesian.h:56
static constexpr int T2GRot
Definition Cartesian.h:58
static constexpr int T2G
Definition Cartesian.h:57
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)