]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDgeometry.cxx
Even more effc++
[u/mrichter/AliRoot.git] / TRD / AliTRDgeometry.cxx
CommitLineData
f7336fa3 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
afc51ac2 16/* $Id$ */
f7336fa3 17
18///////////////////////////////////////////////////////////////////////////////
19// //
20// TRD geometry class //
21// //
22///////////////////////////////////////////////////////////////////////////////
23
793ff80c 24
b4a9cd27 25#include <TGeoManager.h>
26#include <TGeoPhysicalNode.h>
27#include <TGeoMatrix.h>
28
2745a409 29#include "AliLog.h"
bdbb05bb 30#include "AliRunLoader.h"
b4a9cd27 31#include "AliAlignObj.h"
32#include "AliAlignObjAngles.h"
ecb36af7 33#include "AliRun.h"
030b4415 34
ecb36af7 35#include "AliTRD.h"
3551db50 36#include "AliTRDcalibDB.h"
37#include "AliTRDCommonParam.h"
2745a409 38#include "AliTRDgeometry.h"
39#include "AliTRDpadPlane.h"
ecb36af7 40
f7336fa3 41ClassImp(AliTRDgeometry)
42
793ff80c 43//_____________________________________________________________________________
44
45 //
46 // The geometry constants
47 //
48 const Int_t AliTRDgeometry::fgkNsect = kNsect;
49 const Int_t AliTRDgeometry::fgkNplan = kNplan;
50 const Int_t AliTRDgeometry::fgkNcham = kNcham;
51 const Int_t AliTRDgeometry::fgkNdet = kNdet;
52
53 //
54 // Dimensions of the detector
55 //
0a770ac9 56
57 // Inner and outer radius of the mother volumes
793ff80c 58 const Float_t AliTRDgeometry::fgkRmin = 294.0;
59 const Float_t AliTRDgeometry::fgkRmax = 368.0;
60
0a770ac9 61 // Upper and lower length of the mother volumes
793ff80c 62 const Float_t AliTRDgeometry::fgkZmax1 = 378.35;
63 const Float_t AliTRDgeometry::fgkZmax2 = 302.0;
64
0a770ac9 65 // Parameter of the BTR mother volumes
a797f961 66 const Float_t AliTRDgeometry::fgkSheight = 77.9;
67 const Float_t AliTRDgeometry::fgkSwidth1 = 94.881;
68 const Float_t AliTRDgeometry::fgkSwidth2 = 122.353;
793ff80c 69 const Float_t AliTRDgeometry::fgkSlenTR1 = 751.0;
70 const Float_t AliTRDgeometry::fgkSlenTR2 = 313.5;
71 const Float_t AliTRDgeometry::fgkSlenTR3 = 159.5;
72
73ae7b59 73 // The super module side plates
287c5d50 74 const Float_t AliTRDgeometry::fgkSMpltT = 0.2;
a797f961 75 //const Float_t AliTRDgeometry::fgkSMgapT = 0.5;
73ae7b59 76
0a770ac9 77 // Height of different chamber parts
78 // Radiator
79 const Float_t AliTRDgeometry::fgkCraH = 4.8;
80 // Drift region
81 const Float_t AliTRDgeometry::fgkCdrH = 3.0;
82 // Amplification region
83 const Float_t AliTRDgeometry::fgkCamH = 0.7;
84 // Readout
73ae7b59 85 const Float_t AliTRDgeometry::fgkCroH = 2.316;
0a770ac9 86 // Total height
87 const Float_t AliTRDgeometry::fgkCH = AliTRDgeometry::fgkCraH
88 + AliTRDgeometry::fgkCdrH
89 + AliTRDgeometry::fgkCamH
90 + AliTRDgeometry::fgkCroH;
91
92 // Vertical spacing of the chambers
73ae7b59 93 const Float_t AliTRDgeometry::fgkVspace = 1.784;
0a770ac9 94
95 // Horizontal spacing of the chambers
96 const Float_t AliTRDgeometry::fgkHspace = 2.0;
97
a797f961 98 // Radial distance of the first ROC to the outer plates of the SM
99 const Float_t AliTRDgeometry::fgkVrocsm = 1.2;
100
0a770ac9 101 // Thicknesses of different parts of the chamber frame
102 // Lower aluminum frame
103 const Float_t AliTRDgeometry::fgkCalT = 0.3;
104 // Lower G10 frame sides
105 const Float_t AliTRDgeometry::fgkCclsT = 0.3;
106 // Lower G10 frame front
107 const Float_t AliTRDgeometry::fgkCclfT = 1.0;
108 // Upper G10 frame
109 const Float_t AliTRDgeometry::fgkCcuT = 0.9;
110 // Upper Al frame
111 const Float_t AliTRDgeometry::fgkCauT = 1.5;
112
113 // Additional width of the readout chamber frames
114 const Float_t AliTRDgeometry::fgkCroW = 0.9;
115
116 // Difference of outer chamber width and pad plane width
73ae7b59 117 //const Float_t AliTRDgeometry::fgkCpadW = 1.0;
118 const Float_t AliTRDgeometry::fgkCpadW = 0.0;
de6df1b1 119 const Float_t AliTRDgeometry::fgkRpadW = 1.0;
793ff80c 120
121 //
122 // Thickness of the the material layers
123 //
db30bf0f 124 const Float_t AliTRDgeometry::fgkRaThick = 0.3646;
793ff80c 125 const Float_t AliTRDgeometry::fgkMyThick = 0.005;
0a770ac9 126 const Float_t AliTRDgeometry::fgkDrThick = AliTRDgeometry::fgkCdrH;
127 const Float_t AliTRDgeometry::fgkAmThick = AliTRDgeometry::fgkCamH;
128 const Float_t AliTRDgeometry::fgkXeThick = AliTRDgeometry::fgkDrThick
129 + AliTRDgeometry::fgkAmThick;
a797f961 130 const Float_t AliTRDgeometry::fgkCuThick = 0.0072;
793ff80c 131 const Float_t AliTRDgeometry::fgkSuThick = 0.06;
132 const Float_t AliTRDgeometry::fgkFeThick = 0.0044;
133 const Float_t AliTRDgeometry::fgkCoThick = 0.02;
db30bf0f 134 const Float_t AliTRDgeometry::fgkWaThick = 0.02;
a797f961 135 const Float_t AliTRDgeometry::fgkRcThick = 0.0058;
136 const Float_t AliTRDgeometry::fgkRpThick = 0.0632;
793ff80c 137
138 //
139 // Position of the material layers
140 //
0a770ac9 141 const Float_t AliTRDgeometry::fgkRaZpos = -1.50;
142 const Float_t AliTRDgeometry::fgkMyZpos = 0.895;
143 const Float_t AliTRDgeometry::fgkDrZpos = 2.4;
144 const Float_t AliTRDgeometry::fgkAmZpos = 0.0;
145 const Float_t AliTRDgeometry::fgkCuZpos = -0.9995;
793ff80c 146 const Float_t AliTRDgeometry::fgkSuZpos = 0.0000;
0a770ac9 147 const Float_t AliTRDgeometry::fgkFeZpos = 0.0322;
148 const Float_t AliTRDgeometry::fgkCoZpos = 0.97;
149 const Float_t AliTRDgeometry::fgkWaZpos = 0.99;
a797f961 150 const Float_t AliTRDgeometry::fgkRcZpos = 1.04;
151 const Float_t AliTRDgeometry::fgkRpZpos = 1.0;
3551db50 152
153 const Double_t AliTRDgeometry::fgkTime0Base = Rmin() + CraHght() + CdrHght() + CamHght()/2.;
154 const Float_t AliTRDgeometry::fgkTime0[6] = { fgkTime0Base + 0 * (Cheight() + Cspace()),
155 fgkTime0Base + 1 * (Cheight() + Cspace()),
156 fgkTime0Base + 2 * (Cheight() + Cspace()),
157 fgkTime0Base + 3 * (Cheight() + Cspace()),
158 fgkTime0Base + 4 * (Cheight() + Cspace()),
159 fgkTime0Base + 5 * (Cheight() + Cspace()) };
793ff80c 160
f7336fa3 161//_____________________________________________________________________________
2745a409 162AliTRDgeometry::AliTRDgeometry()
163 :AliGeometry()
164 ,fMatrixArray(0)
165 ,fMatrixCorrectionArray(0)
166 ,fMatrixGeo(0)
167
f7336fa3 168{
169 //
170 // AliTRDgeometry default constructor
171 //
bd0f8685 172
2745a409 173 Init();
174
175}
176
177//_____________________________________________________________________________
178AliTRDgeometry::AliTRDgeometry(const AliTRDgeometry &g)
179 :AliGeometry(g)
030b4415 180 ,fMatrixArray(g.fMatrixArray)
181 ,fMatrixCorrectionArray(g.fMatrixCorrectionArray)
182 ,fMatrixGeo(g.fMatrixGeo)
2745a409 183{
184 //
185 // AliTRDgeometry copy constructor
186 //
bd0f8685 187
f7336fa3 188 Init();
bd0f8685 189
f7336fa3 190}
191
192//_____________________________________________________________________________
193AliTRDgeometry::~AliTRDgeometry()
194{
8230f242 195 //
196 // AliTRDgeometry destructor
197 //
bd0f8685 198
030b4415 199 if (fMatrixArray) {
200 delete fMatrixArray;
201 fMatrixArray = 0;
202 }
203
204 if (fMatrixCorrectionArray) {
205 delete fMatrixCorrectionArray;
206 fMatrixCorrectionArray = 0;
207 }
bd0f8685 208
f7336fa3 209}
210
2745a409 211//_____________________________________________________________________________
212AliTRDgeometry &AliTRDgeometry::operator=(const AliTRDgeometry &g)
213{
214 //
215 // Assignment operator
216 //
217
218 if (this != &g) Init();
030b4415 219
2745a409 220 return *this;
221
222}
223
f7336fa3 224//_____________________________________________________________________________
225void AliTRDgeometry::Init()
226{
227 //
228 // Initializes the geometry parameter
229 //
f7336fa3 230 // The maximum number of pads
231 // and the position of pad 0,0,0
232 //
233 // chambers seen from the top:
234 // +----------------------------+
235 // | |
793ff80c 236 // | | ^
237 // | | rphi|
238 // | | |
239 // |0 | |
240 // +----------------------------+ +------>
f7336fa3 241 // z
793ff80c 242 // chambers seen from the side: ^
243 // +----------------------------+ drift|
244 // |0 | |
245 // | | |
246 // +----------------------------+ +------>
f7336fa3 247 // z
248 //
a2b90f83 249 // IMPORTANT: time bin 0 is now the first one in the drift region
250 // closest to the readout !!!
793ff80c 251 //
f7336fa3 252
0a770ac9 253 Int_t icham;
254 Int_t iplan;
255 Int_t isect;
256
257 // The outer width of the chambers
287c5d50 258 fCwidth[0] = 90.4;
e0d47c25 259 fCwidth[1] = 94.8;
260 fCwidth[2] = 99.3;
261 fCwidth[3] = 103.7;
262 fCwidth[4] = 108.1;
263 fCwidth[5] = 112.6;
0a770ac9 264
265 // The outer lengths of the chambers
73ae7b59 266 // Includes the spacings between the chambers!
8737e16f 267 Float_t length[kNplan][kNcham] = { { 124.0, 124.0, 110.0, 124.0, 124.0 }
e0d47c25 268 , { 124.0, 124.0, 110.0, 124.0, 124.0 }
8737e16f 269 , { 131.0, 131.0, 110.0, 131.0, 131.0 }
270 , { 138.0, 138.0, 110.0, 138.0, 138.0 }
271 , { 145.0, 145.0, 110.0, 145.0, 145.0 }
e0d47c25 272 , { 147.0, 147.0, 110.0, 147.0, 147.0 } };
0a770ac9 273
274 for (icham = 0; icham < kNcham; icham++) {
275 for (iplan = 0; iplan < kNplan; iplan++) {
030b4415 276 fClength[iplan][icham] = length[iplan][icham];
0a770ac9 277 }
278 }
279
793ff80c 280 // The rotation matrix elements
030b4415 281 Float_t phi = 0.0;
793ff80c 282 for (isect = 0; isect < fgkNsect; isect++) {
5443e65e 283 phi = -2.0 * TMath::Pi() / (Float_t) fgkNsect * ((Float_t) isect + 0.5);
793ff80c 284 fRotA11[isect] = TMath::Cos(phi);
285 fRotA12[isect] = TMath::Sin(phi);
286 fRotA21[isect] = TMath::Sin(phi);
287 fRotA22[isect] = TMath::Cos(phi);
288 phi = -1.0 * phi;
289 fRotB11[isect] = TMath::Cos(phi);
290 fRotB12[isect] = TMath::Sin(phi);
291 fRotB21[isect] = TMath::Sin(phi);
292 fRotB22[isect] = TMath::Cos(phi);
293 }
bd0f8685 294
295 for (isect = 0; isect < fgkNsect; isect++) {
296 SetSMstatus(isect,1);
297 }
793ff80c 298
299}
300
f7336fa3 301//_____________________________________________________________________________
bd0f8685 302void AliTRDgeometry::CreateGeometry(Int_t *idtmed)
303{
304 //
305 // Create the TRD geometry without hole
306 //
307 //
308 // Names of the TRD volumina (xx = detector number):
309 //
310 // Volume (Air) wrapping the readout chamber components
311 // UTxx includes: UAxx, UDxx, UFxx, UUxx
312 // Obs:
313 // UUxx the services volume has been reduced by 7.42 mm
314 // in order to allow shifts in radial direction
315 //
316 // Lower part of the readout chambers (gas volume + radiator)
317 //
318 // UAxx Aluminum frames (Al)
319 // UBxx G10 frames (C)
320 // UCxx Inner volumes (Air)
321 //
322 // Upper part of the readout chambers (readout plane + fee)
323 //
324 // UDxx G10 frames (C)
325 // UExx Inner volumes of the G10 (Air)
326 // UFxx Aluminum frames (Al)
327 // UGxx Inner volumes of the Al (Air)
328 //
329 // Inner material layers
330 //
331 // UHxx Radiator (Rohacell)
332 // UIxx Entrance window (Mylar)
333 // UJxx Drift volume (Xe/CO2)
334 // UKxx Amplification volume (Xe/CO2)
335 // ULxx Pad plane (Cu)
336 // UMxx Support structure (Rohacell)
a797f961 337 // UNxx ROB base material (C)
338 // UOxx ROB copper (Cu)
bd0f8685 339 //
340
341 const Int_t kNparTrd = 4;
342 const Int_t kNparCha = 3;
343
030b4415 344 Float_t xpos;
345 Float_t ypos;
346 Float_t zpos;
bd0f8685 347
348 Float_t parTrd[kNparTrd];
349 Float_t parCha[kNparCha];
350
351 Char_t cTagV[6];
352 Char_t cTagM[5];
353
354 // The TRD mother volume for one sector (Air), full length in z-direction
355 // Provides material for side plates of super module
030b4415 356 parTrd[0] = fgkSwidth1/2.0;
357 parTrd[1] = fgkSwidth2/2.0;
358 parTrd[2] = fgkSlenTR1/2.0;
359 parTrd[3] = fgkSheight/2.0;
bd0f8685 360 gMC->Gsvolu("UTR1","TRD1",idtmed[1302-1],parTrd,kNparTrd);
361
362 //
a797f961 363 // The outer aluminum plates of the super module (Al)
030b4415 364 parTrd[0] = fgkSwidth1/2.0;
365 parTrd[1] = fgkSwidth2/2.0;
366 parTrd[2] = fgkSlenTR1/2.0;
367 parTrd[3] = fgkSheight/2.0;
bd0f8685 368 gMC->Gsvolu("UTS1","TRD1",idtmed[1301-1],parTrd,kNparTrd);
369
370 // The inner part of the TRD mother volume for one sector (Air),
371 // full length in z-direction
030b4415 372 parTrd[0] = fgkSwidth1/2.0 - fgkSMpltT;
373 parTrd[1] = fgkSwidth2/2.0 - fgkSMpltT;
374 parTrd[2] = fgkSlenTR1/2.0;
375 parTrd[3] = fgkSheight/2.0 - fgkSMpltT;
bd0f8685 376 gMC->Gsvolu("UTI1","TRD1",idtmed[1302-1],parTrd,kNparTrd);
377
378 for (Int_t icham = 0; icham < kNcham; icham++) {
379 for (Int_t iplan = 0; iplan < kNplan; iplan++) {
380
381 Int_t iDet = GetDetectorSec(iplan,icham);
382
383 // The lower part of the readout chambers (gas volume + radiator)
384 // The aluminum frames
385 sprintf(cTagV,"UA%02d",iDet);
030b4415 386 parCha[0] = fCwidth[iplan]/2.0;
387 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
388 parCha[2] = fgkCraH/2.0 + fgkCdrH/2.0;
bd0f8685 389 fChamberUAboxd[iDet][0] = parCha[0];
390 fChamberUAboxd[iDet][1] = parCha[1];
391 fChamberUAboxd[iDet][2] = parCha[2];
392 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parCha,kNparCha);
393 // The G10 frames
394 sprintf(cTagV,"UB%02d",iDet);
030b4415 395 parCha[0] = fCwidth[iplan]/2.0 - fgkCalT;
396 parCha[1] = -1.0;
397 parCha[2] = -1.0;
bd0f8685 398 gMC->Gsvolu(cTagV,"BOX ",idtmed[1307-1],parCha,kNparCha);
399 // The inner part (air)
400 sprintf(cTagV,"UC%02d",iDet);
030b4415 401 parCha[0] = fCwidth[iplan]/2.0 - fgkCalT - fgkCclsT;
402 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0- fgkCclfT;
403 parCha[2] = -1.0;
bd0f8685 404 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
405
406 // The upper part of the readout chambers (readout plane)
407 // The G10 frames
408 sprintf(cTagV,"UD%02d",iDet);
030b4415 409 parCha[0] = fCwidth[iplan]/2.0 + fgkCroW;
410 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
411 parCha[2] = fgkCamH/2.0;
bd0f8685 412 fChamberUDboxd[iDet][0] = parCha[0];
413 fChamberUDboxd[iDet][1] = parCha[1];
414 fChamberUDboxd[iDet][2] = parCha[2];
415 gMC->Gsvolu(cTagV,"BOX ",idtmed[1307-1],parCha,kNparCha);
416 // The inner part of the G10 frame (air)
417 sprintf(cTagV,"UE%02d",iDet);
030b4415 418 parCha[0] = fCwidth[iplan]/2.0 + fgkCroW - fgkCcuT;
419 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0- fgkCcuT;
bd0f8685 420 parCha[2] = -1.;
421 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
422 // The aluminum frames
423 sprintf(cTagV,"UF%02d",iDet);
030b4415 424 parCha[0] = fCwidth[iplan]/2.0 + fgkCroW;
425 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
426 parCha[2] = fgkCroH/2.0;
bd0f8685 427 fChamberUFboxd[iDet][0] = parCha[0];
428 fChamberUFboxd[iDet][1] = parCha[1];
429 fChamberUFboxd[iDet][2] = parCha[2];
430 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parCha,kNparCha);
431 // The inner part of the aluminum frames
432 sprintf(cTagV,"UG%02d",iDet);
030b4415 433 parCha[0] = fCwidth[iplan]/2.0 + fgkCroW - fgkCauT;
434 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0- fgkCauT;
435 parCha[2] = -1.0;
bd0f8685 436 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
437
438 // The material layers inside the chambers
030b4415 439 parCha[0] = -1.0;
440 parCha[1] = -1.0;
bd0f8685 441 // Rohacell layer (radiator)
030b4415 442 parCha[2] = fgkRaThick/2.0;
bd0f8685 443 sprintf(cTagV,"UH%02d",iDet);
444 gMC->Gsvolu(cTagV,"BOX ",idtmed[1315-1],parCha,kNparCha);
445 // Mylar layer (entrance window + HV cathode)
030b4415 446 parCha[2] = fgkMyThick/2.0;
bd0f8685 447 sprintf(cTagV,"UI%02d",iDet);
448 gMC->Gsvolu(cTagV,"BOX ",idtmed[1308-1],parCha,kNparCha);
449 // Xe/Isobutane layer (drift volume)
030b4415 450 parCha[2] = fgkDrThick/2.0;
bd0f8685 451 sprintf(cTagV,"UJ%02d",iDet);
452 gMC->Gsvolu(cTagV,"BOX ",idtmed[1309-1],parCha,kNparCha);
453 // Xe/Isobutane layer (amplification volume)
030b4415 454 parCha[2] = fgkAmThick/2.0;
bd0f8685 455 sprintf(cTagV,"UK%02d",iDet);
456 gMC->Gsvolu(cTagV,"BOX ",idtmed[1309-1],parCha,kNparCha);
457 // Cu layer (pad plane)
030b4415 458 parCha[2] = fgkCuThick/2.0;
bd0f8685 459 sprintf(cTagV,"UL%02d",iDet);
460 gMC->Gsvolu(cTagV,"BOX ",idtmed[1305-1],parCha,kNparCha);
461 // G10 layer (support structure / honeycomb)
030b4415 462 parCha[2] = fgkSuThick/2.0;
bd0f8685 463 sprintf(cTagV,"UM%02d",iDet);
464 gMC->Gsvolu(cTagV,"BOX ",idtmed[1313-1],parCha,kNparCha);
a797f961 465 // G10 layer (readout board)
466 parCha[2] = fgkRpThick/2;
467 sprintf(cTagV,"UN%02d",iDet);
468 gMC->Gsvolu(cTagV,"BOX ",idtmed[1313-1],parCha,kNparCha);
469 // Cu layer (readout board)
030b4415 470 parCha[2] = fgkRcThick/2.0;
a797f961 471 sprintf(cTagV,"UO%02d",iDet);
472 gMC->Gsvolu(cTagV,"BOX ",idtmed[1306-1],parCha,kNparCha);
bd0f8685 473
474 // Position the layers in the chambers
030b4415 475 xpos = 0.0;
476 ypos = 0.0;
bd0f8685 477 // Lower part
478 // Rohacell layer (radiator)
479 zpos = fgkRaZpos;
480 sprintf(cTagV,"UH%02d",iDet);
481 sprintf(cTagM,"UC%02d",iDet);
482 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
483 // Mylar layer (entrance window + HV cathode)
484 zpos = fgkMyZpos;
485 sprintf(cTagV,"UI%02d",iDet);
486 sprintf(cTagM,"UC%02d",iDet);
487 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
488 // Xe/Isobutane layer (drift volume)
489 zpos = fgkDrZpos;
490 sprintf(cTagV,"UJ%02d",iDet);
491 sprintf(cTagM,"UC%02d",iDet);
492 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
493 // Upper part
494 // Xe/Isobutane layer (amplification volume)
495 zpos = fgkAmZpos;
496 sprintf(cTagV,"UK%02d",iDet);
497 sprintf(cTagM,"UE%02d",iDet);
498 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
499 // Readout part
500 // Cu layer (pad plane)
501 zpos = fgkCuZpos;
502 sprintf(cTagV,"UL%02d",iDet);
503 sprintf(cTagM,"UG%02d",iDet);
504 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
505 // G10 layer (support structure)
506 zpos = fgkSuZpos;
507 sprintf(cTagV,"UM%02d",iDet);
508 sprintf(cTagM,"UG%02d",iDet);
509 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
a797f961 510 // G10 layer (readout board)
511 zpos = fgkRpZpos;
512 sprintf(cTagV,"UN%02d",iDet);
513 sprintf(cTagM,"UG%02d",iDet);
514 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
515 // Cu layer (readout board)
516 zpos = fgkRcZpos;
517 sprintf(cTagV,"UO%02d",iDet);
518 sprintf(cTagM,"UG%02d",iDet);
519 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
bd0f8685 520
521 // Position the inner volumes of the chambers in the frames
030b4415 522 xpos = 0.0;
523 ypos = 0.0;
524 zpos = 0.0;
bd0f8685 525 // The inside of the lower G10 frame
526 sprintf(cTagV,"UC%02d",iDet);
527 sprintf(cTagM,"UB%02d",iDet);
528 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
529 // The lower G10 frame inside the aluminum frame
530 sprintf(cTagV,"UB%02d",iDet);
531 sprintf(cTagM,"UA%02d",iDet);
532 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
533 // The inside of the upper G10 frame
534 sprintf(cTagV,"UE%02d",iDet);
535 sprintf(cTagM,"UD%02d",iDet);
536 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
537 // The inside of the upper aluminum frame
538 sprintf(cTagV,"UG%02d",iDet);
539 sprintf(cTagM,"UF%02d",iDet);
540 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
541
542 // Position the frames of the chambers in the TRD mother volume
030b4415 543 xpos = 0.0;
544 ypos = - fClength[iplan][0] - fClength[iplan][1] - fClength[iplan][2]/2.0;
bd0f8685 545 for (Int_t ic = 0; ic < icham; ic++) {
546 ypos += fClength[iplan][ic];
547 }
030b4415 548 ypos += fClength[iplan][icham]/2.0;
549 zpos = fgkVrocsm + fgkCraH/2.0 + fgkCdrH/2.0 - fgkSheight/2.0
a797f961 550 + iplan * (fgkCH + fgkVspace);
bd0f8685 551 // The lower aluminum frame, radiator + drift region
552 sprintf(cTagV,"UA%02d",iDet);
553 fChamberUAorig[iDet][0] = xpos;
554 fChamberUAorig[iDet][1] = ypos;
555 fChamberUAorig[iDet][2] = zpos;
556 // The upper G10 frame, amplification region
557 sprintf(cTagV,"UD%02d",iDet);
030b4415 558 zpos += fgkCamH/2.0 + fgkCraH/2.0 + fgkCdrH/2.0;
bd0f8685 559 fChamberUDorig[iDet][0] = xpos;
560 fChamberUDorig[iDet][1] = ypos;
561 fChamberUDorig[iDet][2] = zpos;
562 // The upper aluminum frame
563 sprintf(cTagV,"UF%02d",iDet);
030b4415 564 zpos += fgkCroH/2.0 + fgkCamH/2.0;
bd0f8685 565 fChamberUForig[iDet][0] = xpos;
566 fChamberUForig[iDet][1] = ypos;
567 fChamberUForig[iDet][2] = zpos;
568
569 }
570 }
571
572 // Create the volumes of the super module frame
573 CreateFrame(idtmed);
574
575 // Create the volumes of the services
576 CreateServices(idtmed);
577
578 for (Int_t icham = 0; icham < kNcham; icham++) {
579 for (Int_t iplan = 0; iplan < kNplan; iplan++) {
580 GroupChamber(iplan,icham,idtmed);
581 }
582 }
583
030b4415 584 xpos = 0.0;
585 ypos = 0.0;
586 zpos = 0.0;
bd0f8685 587 gMC->Gspos("UTI1",1,"UTS1",xpos,ypos,zpos,0,"ONLY");
588
030b4415 589 xpos = 0.0;
590 ypos = 0.0;
591 zpos = 0.0;
bd0f8685 592 gMC->Gspos("UTS1",1,"UTR1",xpos,ypos,zpos,0,"ONLY");
593
594 // Put the TRD volumes into the space frame mother volumes
595 // if enabled via status flag
030b4415 596 xpos = 0.0;
597 ypos = 0.0;
598 zpos = 0.0;
bd0f8685 599 for (Int_t isect = 0; isect < kNsect; isect++) {
600 if (fSMstatus[isect]) {
601 sprintf(cTagV,"BTRD%d",isect);
602 gMC->Gspos("UTR1",1,cTagV,xpos,ypos,zpos,0,"ONLY");
603 }
604 }
605
606}
607
608//_____________________________________________________________________________
609void AliTRDgeometry::CreateFrame(Int_t *idtmed)
610{
611 //
612 // Create the geometry of the frame of the supermodule
613 //
614 // Names of the TRD services volumina
615 //
616 // USRL Support rails for the chambers (Al)
617 // USxx Support cross bars between the chambers (Al)
618 //
619
620 Int_t iplan = 0;
621
622 Float_t xpos = 0.0;
623 Float_t ypos = 0.0;
624 Float_t zpos = 0.0;
625
626 Char_t cTagV[5];
627
628 //
629 // The chamber support rails
630 //
631
030b4415 632 const Float_t kSRLwid = 2.00;
bd0f8685 633 const Float_t kSRLhgt = 2.3;
634 const Float_t kSRLdst = 0.6;
635 const Int_t kNparSRL = 3;
636 Float_t parSRL[kNparSRL];
030b4415 637 parSRL[0] = kSRLwid/2.0;
bd0f8685 638 parSRL[1] = fgkSlenTR1/2.;
030b4415 639 parSRL[2] = kSRLhgt/2.0;
bd0f8685 640 gMC->Gsvolu("USRL","BOX ",idtmed[1301-1],parSRL,kNparSRL);
641
642 xpos = 0.0;
643 ypos = 0.0;
644 zpos = 0.0;
645 for (iplan = 0; iplan < kNplan; iplan++) {
030b4415 646 xpos = fCwidth[iplan]/2.0 + kSRLwid/2.0 + kSRLdst;
bd0f8685 647 ypos = 0.0;
030b4415 648 zpos = fgkVrocsm + fgkCraH + fgkCdrH - fgkSheight/2.0 - kSRLhgt/2.0
bd0f8685 649 + iplan * (fgkCH + fgkVspace);
650 gMC->Gspos("USRL",iplan+1 ,"UTI1", xpos,ypos,zpos,0,"ONLY");
651 gMC->Gspos("USRL",iplan+1+ kNplan,"UTI1",-xpos,ypos,zpos,0,"ONLY");
bd0f8685 652 }
653
654 //
655 // The cross bars between the chambers
656 //
657
658 const Float_t kSCBwid = 1.0;
659 const Int_t kNparSCB = 3;
660 Float_t parSCB[kNparSCB];
030b4415 661 parSCB[1] = kSCBwid/2.0;
662 parSCB[2] = fgkCH/2.0;
bd0f8685 663
664 xpos = 0.0;
665 ypos = 0.0;
666 zpos = 0.0;
667 for (iplan = 0; iplan < kNplan; iplan++) {
668
030b4415 669 parSCB[0] = fCwidth[iplan]/2.0 + kSRLdst/2.0;
bd0f8685 670
671 sprintf(cTagV,"US0%01d",iplan);
672 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
673 xpos = 0.0;
030b4415 674 ypos = fgkSlenTR1/2.0 - kSCBwid/2.0;
675 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
bd0f8685 676 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
677
678 sprintf(cTagV,"US1%01d",iplan);
679 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
680 xpos = 0.0;
030b4415 681 ypos = fClength[iplan][2]/2.0 + fClength[iplan][1];
682 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
bd0f8685 683 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
684
685 sprintf(cTagV,"US2%01d",iplan);
686 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
687 xpos = 0.0;
030b4415 688 ypos = fClength[iplan][2]/2.0;
689 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
bd0f8685 690 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
691
692 sprintf(cTagV,"US3%01d",iplan);
693 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
694 xpos = 0.0;
030b4415 695 ypos = - fClength[iplan][2]/2.0;
696 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
bd0f8685 697 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
698
699 sprintf(cTagV,"US4%01d",iplan);
700 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
701 xpos = 0.0;
030b4415 702 ypos = - fClength[iplan][2]/2.0 - fClength[iplan][1];
703 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
bd0f8685 704 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
705
706 sprintf(cTagV,"US5%01d",iplan);
707 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
708 xpos = 0.0;
030b4415 709 ypos = - fgkSlenTR1/2.0 + kSCBwid/2.0;
710 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
bd0f8685 711 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
712
713 }
714
715}
716
717//_____________________________________________________________________________
718void AliTRDgeometry::CreateServices(Int_t *idtmed)
719{
720 //
721 // Create the geometry of the services
722 //
723 // Names of the TRD services volumina
724 //
725 // UTCL Cooling arterias (Al)
726 // UTCW Cooling arterias (Water)
727 // UUxx Volumes for the services at the chambers (Air)
728 // UTPW Power bars (Cu)
729 // UTCP Cooling pipes (Al)
730 // UTCH Cooling pipes (Water)
731 // UTPL Power lines (Cu)
732 // UMCM Readout MCMs (G10/Cu/Si)
733 //
734
735 Int_t iplan = 0;
736 Int_t icham = 0;
737
738 Float_t xpos = 0.0;
739 Float_t ypos = 0.0;
740 Float_t zpos = 0.0;
741
742 Char_t cTagV[5];
743
744 // The rotation matrices
745 const Int_t kNmatrix = 3;
746 Int_t matrix[kNmatrix];
030b4415 747 gMC->Matrix(matrix[0], 100.0, 0.0, 90.0, 90.0, 10.0, 0.0);
748 gMC->Matrix(matrix[1], 80.0, 0.0, 90.0, 90.0, 10.0, 180.0);
749 gMC->Matrix(matrix[2], 0.0, 0.0, 90.0, 90.0, 90.0, 0.0);
bd0f8685 750
030b4415 751 AliTRDCommonParam *commonParam = AliTRDCommonParam::Instance();
2745a409 752 if (!commonParam) {
753 AliError("Could not get common parameters\n");
bd0f8685 754 return;
755 }
756
757 //
758 // The cooling arterias
759 //
760
761 // Width of the cooling arterias
762 const Float_t kCOLwid = 0.5;
763 // Height of the cooling arterias
764 const Float_t kCOLhgt = 5.5;
765 // Positioning of the cooling
766 const Float_t kCOLposx = 1.6;
767 const Float_t kCOLposz = -0.2;
768 // Thickness of the walls of the cooling arterias
769 const Float_t kCOLthk = 0.1;
030b4415 770 const Int_t kNparCOL = 3;
bd0f8685 771 Float_t parCOL[kNparCOL];
030b4415 772 parCOL[0] = kCOLwid/2.0;
773 parCOL[1] = fgkSlenTR1/2.0;
774 parCOL[2] = kCOLhgt/2.0;
bd0f8685 775 gMC->Gsvolu("UTCL","BOX ",idtmed[1324-1],parCOL,kNparCOL);
776 parCOL[0] -= kCOLthk;
030b4415 777 parCOL[1] = fgkSlenTR1/2.0;
bd0f8685 778 parCOL[2] -= kCOLthk;
779 gMC->Gsvolu("UTCW","BOX ",idtmed[1314-1],parCOL,kNparCOL);
780
781 xpos = 0.0;
782 ypos = 0.0;
783 zpos = 0.0;
784 gMC->Gspos("UTCW",1,"UTCL", xpos,ypos,zpos,0,"ONLY");
785
a797f961 786 for (iplan = 0; iplan < kNplan; iplan++) {
030b4415 787 xpos = fCwidth[iplan]/2.0 + kCOLwid/2.0 + kCOLposx;
bd0f8685 788 ypos = 0.0;
030b4415 789 zpos = fgkVrocsm + kCOLhgt/2.0 - fgkSheight/2.0 + kCOLposz
a797f961 790 + iplan * (fgkCH + fgkVspace);
030b4415 791 // To avoid overlaps !
792 if (iplan == 0) zpos += 0.25;
bd0f8685 793 gMC->Gspos("UTCL",iplan+1 ,"UTI1", xpos,ypos,zpos,matrix[0],"ONLY");
794 gMC->Gspos("UTCL",iplan+1+ kNplan,"UTI1",-xpos,ypos,zpos,matrix[1],"ONLY");
bd0f8685 795 }
796
797 //
798 // The power bars
799 //
800
801 const Float_t kPWRwid = 0.6;
802 const Float_t kPWRhgt = 4.5;
803 const Float_t kPWRposx = 1.05;
804 const Float_t kPWRposz = 0.9;
030b4415 805 const Int_t kNparPWR = 3;
bd0f8685 806 Float_t parPWR[kNparPWR];
030b4415 807 parPWR[0] = kPWRwid/2.0;
808 parPWR[1] = fgkSlenTR1/2.0;
809 parPWR[2] = kPWRhgt/2.0;
bd0f8685 810 gMC->Gsvolu("UTPW","BOX ",idtmed[1325-1],parPWR,kNparPWR);
811
a797f961 812 for (iplan = 0; iplan < kNplan; iplan++) {
bd0f8685 813
030b4415 814 xpos = fCwidth[iplan]/2.0 + kPWRwid/2.0 + kPWRposx;
bd0f8685 815 ypos = 0.0;
030b4415 816 zpos = fgkVrocsm + kPWRhgt/2.0 - fgkSheight/2.0 + kPWRposz
a797f961 817 + iplan * (fgkCH + fgkVspace);
bd0f8685 818 gMC->Gspos("UTPW",iplan+1 ,"UTI1", xpos,ypos,zpos,matrix[0],"ONLY");
819 gMC->Gspos("UTPW",iplan+1+ kNplan,"UTI1",-xpos,ypos,zpos,matrix[1],"ONLY");
820
821 }
822
823 //
824 // The volumes for the services at the chambers
825 //
826
827 const Int_t kNparServ = 3;
828 Float_t parServ[kNparServ];
829
830 for (icham = 0; icham < kNcham; icham++) {
831 for (iplan = 0; iplan < kNplan; iplan++) {
bd0f8685 832
833 Int_t iDet = GetDetectorSec(iplan,icham);
834
835 sprintf(cTagV,"UU%02d",iDet);
030b4415 836 parServ[0] = fCwidth[iplan]/2.0;
837 parServ[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
838 // ???? !!!!!!!!!!!!!!
839 parServ[2] = fgkVspace/2.0 - 0.742/2.0;
bd0f8685 840 fChamberUUboxd[iDet][0] = parServ[0];
841 fChamberUUboxd[iDet][1] = parServ[1];
842 fChamberUUboxd[iDet][2] = parServ[2];
bd0f8685 843 gMC->Gsvolu(cTagV,"BOX",idtmed[1302-1],parServ,kNparServ);
a797f961 844
bd0f8685 845 xpos = 0.;
030b4415 846 ypos = - fClength[iplan][0] - fClength[iplan][1] - fClength[iplan][2]/2.0;
bd0f8685 847 for (Int_t ic = 0; ic < icham; ic++) {
848 ypos += fClength[iplan][ic];
849 }
030b4415 850 ypos += fClength[iplan][icham]/2.0;
851 zpos = fgkVrocsm + fgkCH + fgkVspace/2.0 - fgkSheight/2.0
a797f961 852 + iplan * (fgkCH + fgkVspace);
030b4415 853 zpos -= 0.742/2.0;
bd0f8685 854 fChamberUUorig[iDet][0] = xpos;
855 fChamberUUorig[iDet][1] = ypos;
856 fChamberUUorig[iDet][2] = zpos;
857
858 }
859 }
860
861 //
862 // The cooling pipes inside the service volumes
863 //
864
865 const Int_t kNparTube = 3;
866 Float_t parTube[kNparTube];
867 // The aluminum pipe for the cooling
868 parTube[0] = 0.0;
869 parTube[1] = 0.0;
870 parTube[2] = 0.0;
871 gMC->Gsvolu("UTCP","TUBE",idtmed[1324-1],parTube,0);
872 // The cooling water
873 parTube[0] = 0.0;
030b4415 874 parTube[1] = 0.2/2.0;
bd0f8685 875 parTube[2] = -1.;
876 gMC->Gsvolu("UTCH","TUBE",idtmed[1314-1],parTube,kNparTube);
877 // Water inside the cooling pipe
878 xpos = 0.0;
879 ypos = 0.0;
880 zpos = 0.0;
881 gMC->Gspos("UTCH",1,"UTCP",xpos,ypos,zpos,0,"ONLY");
882
883 // Position the cooling pipes in the mother volume
884 const Int_t kNpar = 3;
885 Float_t par[kNpar];
886 for (icham = 0; icham < kNcham; icham++) {
887 for (iplan = 0; iplan < kNplan; iplan++) {
bd0f8685 888 Int_t iDet = GetDetectorSec(iplan,icham);
889 Int_t iCopy = GetDetector(iplan,icham,0) * 100;
890 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
030b4415 891 Float_t ySize = (GetChamberLength(iplan,icham) - 2.0*fgkRpadW)
bd0f8685 892 / ((Float_t) nMCMrow);
893 sprintf(cTagV,"UU%02d",iDet);
894 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
895 xpos = 0.0;
896 ypos = (0.5 + iMCMrow) * ySize - 1.9
030b4415 897 - fClength[iplan][icham]/2.0 + fgkHspace/2.0;
898 zpos = 0.0 + 0.742/2.0;
bd0f8685 899 par[0] = 0.0;
030b4415 900 par[1] = 0.3/2.0; // Thickness of the cooling pipes
901 par[2] = fCwidth[iplan]/2.0;
bd0f8685 902 gMC->Gsposp("UTCP",iCopy+iMCMrow,cTagV,xpos,ypos,zpos
903 ,matrix[2],"ONLY",par,kNpar);
904 }
905 }
906 }
907
908 //
909 // The power lines
910 //
911
912 // The copper power lines
913 parTube[0] = 0.0;
914 parTube[1] = 0.0;
915 parTube[2] = 0.0;
916 gMC->Gsvolu("UTPL","TUBE",idtmed[1305-1],parTube,0);
917
918 // Position the power lines in the mother volume
919 for (icham = 0; icham < kNcham; icham++) {
920 for (iplan = 0; iplan < kNplan; iplan++) {
bd0f8685 921 Int_t iDet = GetDetectorSec(iplan,icham);
922 Int_t iCopy = GetDetector(iplan,icham,0) * 100;
923 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
030b4415 924 Float_t ySize = (GetChamberLength(iplan,icham) - 2.0*fgkRpadW)
bd0f8685 925 / ((Float_t) nMCMrow);
926 sprintf(cTagV,"UU%02d",iDet);
927 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
928 xpos = 0.0;
929 ypos = (0.5 + iMCMrow) * ySize - 1.0
030b4415 930 - fClength[iplan][icham]/2.0 + fgkHspace/2.0;
931 zpos = -0.4 + 0.742/2.0;
bd0f8685 932 par[0] = 0.0;
030b4415 933 par[1] = 0.2/2.0; // Thickness of the power lines
934 par[2] = fCwidth[iplan]/2.0;
bd0f8685 935 gMC->Gsposp("UTPL",iCopy+iMCMrow,cTagV,xpos,ypos,zpos
936 ,matrix[2],"ONLY",par,kNpar);
937 }
938 }
939 }
940
941 //
942 // The MCMs
943 //
944
945 // The mother volume for the MCMs (air)
946 const Int_t kNparMCM = 3;
947 Float_t parMCM[kNparMCM];
030b4415 948 parMCM[0] = 3.0/2.0;
949 parMCM[1] = 3.0/2.0;
950 parMCM[2] = 0.14/2.0;
bd0f8685 951 gMC->Gsvolu("UMCM","BOX",idtmed[1302-1],parMCM,kNparMCM);
952
953 // The MCM carrier G10 layer
030b4415 954 parMCM[0] = 3.0/2.0;
955 parMCM[1] = 3.0/2.0;
956 parMCM[2] = 0.1/2.0;
bd0f8685 957 gMC->Gsvolu("UMC1","BOX",idtmed[1319-1],parMCM,kNparMCM);
958 // The MCM carrier Cu layer
030b4415 959 parMCM[0] = 3.0/2.0;
960 parMCM[1] = 3.0/2.0;
961 parMCM[2] = 0.0162/2.0;
bd0f8685 962 gMC->Gsvolu("UMC2","BOX",idtmed[1318-1],parMCM,kNparMCM);
963 // The silicon of the chips
030b4415 964 parMCM[0] = 3.0/2.0;
965 parMCM[1] = 3.0/2.0;
966 parMCM[2] = 0.003/2.0;
bd0f8685 967 gMC->Gsvolu("UMC3","BOX",idtmed[1320-1],parMCM,kNparMCM);
968
969 // Put the MCM material inside the MCM mother volume
970 xpos = 0.0;
971 ypos = 0.0;
030b4415 972 zpos = -0.07 + 0.1/2.0;
bd0f8685 973 gMC->Gspos("UMC1",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
030b4415 974 zpos += 0.1/2.0 + 0.0162/2.0;
bd0f8685 975 gMC->Gspos("UMC2",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
030b4415 976 zpos += 0.00162/2 + 0.003/2.0;
bd0f8685 977 gMC->Gspos("UMC3",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
978
979 // Position the MCMs in the mother volume
980 for (icham = 0; icham < kNcham; icham++) {
981 for (iplan = 0; iplan < kNplan; iplan++) {
982 // Take out upper plane until TRD mothervolume is adjusted
983 //for (iplan = 0; iplan < kNplan-1; iplan++) {
984 Int_t iDet = GetDetectorSec(iplan,icham);
985 Int_t iCopy = GetDetector(iplan,icham,0) * 1000;
986 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
030b4415 987 Float_t ySize = (GetChamberLength(iplan,icham) - 2.0*fgkRpadW)
bd0f8685 988 / ((Float_t) nMCMrow);
989 Int_t nMCMcol = 8;
030b4415 990 Float_t xSize = (GetChamberWidth(iplan) - 2.0* fgkCpadW)
bd0f8685 991 / ((Float_t) nMCMcol);
992 sprintf(cTagV,"UU%02d",iDet);
993 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
994 for (Int_t iMCMcol = 0; iMCMcol < nMCMcol; iMCMcol++) {
995 xpos = (0.5 + iMCMcol) * xSize + 1.0
030b4415 996 - fCwidth[iplan]/2.0;
bd0f8685 997 ypos = (0.5 + iMCMrow) * ySize + 1.0
030b4415 998 - fClength[iplan][icham]/2.0 + fgkHspace/2.0;
999 zpos = -0.4 + 0.742/2.0;
bd0f8685 1000 par[0] = 0.0;
030b4415 1001 par[1] = 0.2/2.0; // Thickness of the power lines
1002 par[2] = fCwidth[iplan]/2.0;
bd0f8685 1003 gMC->Gspos("UMCM",iCopy+iMCMrow*10+iMCMcol,cTagV
1004 ,xpos,ypos,zpos,0,"ONLY");
1005 }
1006 }
1007
1008 }
1009 }
1010
1011}
1012
1013//_____________________________________________________________________________
1014void AliTRDgeometry::GroupChamber(Int_t iplan, Int_t icham, Int_t *idtmed)
f7336fa3 1015{
1016 //
bd0f8685 1017 // Group volumes UA, UD, UF, UU in a single chamber (Air)
1018 // UA, UD, UF, UU are boxes
1019 // UT will be a box
0a770ac9 1020 //
bd0f8685 1021
1022 const Int_t kNparCha = 3;
1023
1024 Int_t iDet = GetDetectorSec(iplan,icham);
1025
1026 Float_t xyzMin[3];
1027 Float_t xyzMax[3];
1028 Float_t xyzOrig[3];
1029 Float_t xyzBoxd[3];
1030
1031 Char_t cTagV[5];
1032 Char_t cTagM[5];
1033
1034 for (Int_t i = 0; i < 3; i++) {
030b4415 1035 xyzMin[i] = +9999.0;
1036 xyzMax[i] = -9999.0;
bd0f8685 1037 }
1038
1039 for (Int_t i = 0; i < 3; i++) {
1040
1041 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUAorig[iDet][i]-fChamberUAboxd[iDet][i]);
1042 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUAorig[iDet][i]+fChamberUAboxd[iDet][i]);
1043
1044 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUDorig[iDet][i]-fChamberUDboxd[iDet][i]);
1045 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUDorig[iDet][i]+fChamberUDboxd[iDet][i]);
1046
1047 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUForig[iDet][i]-fChamberUFboxd[iDet][i]);
1048 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUForig[iDet][i]+fChamberUFboxd[iDet][i]);
1049
a797f961 1050 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUUorig[iDet][i]-fChamberUUboxd[iDet][i]);
1051 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUUorig[iDet][i]+fChamberUUboxd[iDet][i]);
bd0f8685 1052
1053 xyzOrig[i] = 0.5*(xyzMax[i]+xyzMin[i]);
1054 xyzBoxd[i] = 0.5*(xyzMax[i]-xyzMin[i]);
1055
1056 }
1057
1058 sprintf(cTagM,"UT%02d",iDet);
bd0f8685 1059 gMC->Gsvolu(cTagM,"BOX ",idtmed[1302-1],xyzBoxd,kNparCha);
1060
1061 sprintf(cTagV,"UA%02d",iDet);
1062 gMC->Gspos(cTagV,1,cTagM,
1063 fChamberUAorig[iDet][0]-xyzOrig[0],
1064 fChamberUAorig[iDet][1]-xyzOrig[1],
1065 fChamberUAorig[iDet][2]-xyzOrig[2],
1066 0,"ONLY");
1067
1068 sprintf(cTagV,"UD%02d",iDet);
1069 gMC->Gspos(cTagV,1,cTagM,
1070 fChamberUDorig[iDet][0]-xyzOrig[0],
1071 fChamberUDorig[iDet][1]-xyzOrig[1],
1072 fChamberUDorig[iDet][2]-xyzOrig[2],
1073 0,"ONLY");
1074
1075 sprintf(cTagV,"UF%02d",iDet);
1076 gMC->Gspos(cTagV,1,cTagM,
1077 fChamberUForig[iDet][0]-xyzOrig[0],
1078 fChamberUForig[iDet][1]-xyzOrig[1],
1079 fChamberUForig[iDet][2]-xyzOrig[2],
1080 0,"ONLY");
1081
a797f961 1082 sprintf(cTagV,"UU%02d",iDet);
1083 gMC->Gspos(cTagV,1,cTagM,
1084 fChamberUUorig[iDet][0]-xyzOrig[0],
1085 fChamberUUorig[iDet][1]-xyzOrig[1],
1086 fChamberUUorig[iDet][2]-xyzOrig[2],
1087 0,"ONLY");
bd0f8685 1088
1089 sprintf(cTagV,"UT%02d",iDet);
1090 gMC->Gspos(cTagV,1,"UTI1",xyzOrig[0],xyzOrig[1],xyzOrig[2],0,"ONLY");
f7336fa3 1091
1092}
1093
1094//_____________________________________________________________________________
a5cadd36 1095Bool_t AliTRDgeometry::Local2Global(Int_t idet, Double_t *local
dde59437 1096 , Double_t *global) const
f7336fa3 1097{
1098 //
1099 // Converts local pad-coordinates (row,col,time) into
1100 // global ALICE reference frame coordinates (x,y,z)
1101 //
1102
793ff80c 1103 Int_t icham = GetChamber(idet); // Chamber info (0-4)
1104 Int_t isect = GetSector(idet); // Sector info (0-17)
1105 Int_t iplan = GetPlane(idet); // Plane info (0-5)
f7336fa3 1106
dde59437 1107 return Local2Global(iplan,icham,isect,local,global);
f7336fa3 1108
1109}
1110
1111//_____________________________________________________________________________
1112Bool_t AliTRDgeometry::Local2Global(Int_t iplan, Int_t icham, Int_t isect
dde59437 1113 , Double_t *local, Double_t *global) const
f7336fa3 1114{
1115 //
1116 // Converts local pad-coordinates (row,col,time) into
1117 // global ALICE reference frame coordinates (x,y,z)
1118 //
1119
3551db50 1120 AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
2745a409 1121 if (!commonParam) {
1122 AliError("Could not get common parameters\n");
3551db50 1123 return kFALSE;
2745a409 1124 }
5443e65e 1125
3551db50 1126 AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
2745a409 1127 if (!calibration) {
1128 AliError("Could not get calibration data\n");
3551db50 1129 return kFALSE;
2745a409 1130 }
3551db50 1131
1132 AliTRDpadPlane *padPlane = commonParam->GetPadPlane(iplan,icham);
f7336fa3 1133
a5cadd36 1134 // calculate (x,y,z) position in rotated chamber
1135 Int_t row = ((Int_t) local[0]);
1136 Int_t col = ((Int_t) local[1]);
1137 Float_t timeSlice = local[2] + 0.5;
3551db50 1138 Float_t time0 = GetTime0(iplan);
f7336fa3 1139
7754cd1f 1140 Int_t idet = GetDetector(iplan, icham, isect);
1141
a5cadd36 1142 Double_t rot[3];
7754cd1f 1143 rot[0] = time0 - (timeSlice - calibration->GetT0(idet, col, row))
030b4415 1144 * calibration->GetVdrift(idet, col, row)
1145 / calibration->GetSamplingFrequency();
a5cadd36 1146 rot[1] = padPlane->GetColPos(col) - 0.5 * padPlane->GetColSize(col);
1147 rot[2] = padPlane->GetRowPos(row) - 0.5 * padPlane->GetRowSize(row);
f7336fa3 1148
1149 // Rotate back to original position
1150 return RotateBack(idet,rot,global);
1151
1152}
1153
3d7b6a24 1154//_____________________________________________________________________________
a5cadd36 1155Bool_t AliTRDgeometry::Global2Local(Int_t mode, Double_t *local, Double_t *global
bd0f8685 1156 , Int_t* index) const
3d7b6a24 1157{
1158 //
1159 // Converts local pad-coordinates (row,col,time) into
1160 // global ALICE reference frame coordinates (x,y,z)
1161 //
e0d47c25 1162 // index[0] = plane number
1163 // index[1] = chamber number
1164 // index[2] = sector number
3d7b6a24 1165 //
030b4415 1166 // mode = 0 - local coordinate in y, z, x - rotated global
3d7b6a24 1167 //
e0d47c25 1168
bd0f8685 1169 Int_t idet = GetDetector(index[0],index[1],index[2]); // Detector number
b4a9cd27 1170 RotateBack(idet,global,local);
3d7b6a24 1171
030b4415 1172 if (mode == 0) {
1173 return kTRUE;
1174 }
1175
1176 return kFALSE;
3d7b6a24 1177
1178}
1179
a5cadd36 1180//_____________________________________________________________________________
3551db50 1181Bool_t AliTRDgeometry::Global2Detector(Double_t global[3], Int_t index[3])
3d7b6a24 1182{
1183 //
b4a9cd27 1184 // Find detector for given global point - Ideal geometry
1185 //
1186 //
e0d47c25 1187 // input = global position
1188 // output = index
1189 // index[0] = plane number
1190 // index[1] = chamber number
1191 // index[2] = sector number
3d7b6a24 1192 //
bd0f8685 1193
3d7b6a24 1194 //
b4a9cd27 1195 // Find sector
1196 //
1197 Float_t fi = TMath::ATan2(global[1],global[0]);
bd0f8685 1198 if (fi < 0) {
030b4415 1199 fi += 2.0 * TMath::Pi();
bd0f8685 1200 }
030b4415 1201 index[2] = fgkNsect - 1 - TMath::Nint((fi - GetAlpha()/2.0) / GetAlpha());
bd0f8685 1202
3d7b6a24 1203 //
b4a9cd27 1204 // Find plane
3d7b6a24 1205 //
1206 Float_t locx = global[0] * fRotA11[index[2]] + global[1] * fRotA12[index[2]];
1207 index[0] = 0;
3551db50 1208 Float_t max = locx - GetTime0(0);
030b4415 1209 for (Int_t iplane = 1; iplane < fgkNplan; iplane++) {
3551db50 1210 Float_t dist = TMath::Abs(locx - GetTime0(iplane));
030b4415 1211 if (dist < max) {
3d7b6a24 1212 index[0] = iplane;
030b4415 1213 max = dist;
3d7b6a24 1214 }
1215 }
bd0f8685 1216
b4a9cd27 1217 //
1218 // Find chamber
1219 //
030b4415 1220 if (TMath::Abs(global[2]) < 0.5*GetChamberLength(index[0],2)) {
1221 index[1] = 2;
bd0f8685 1222 }
030b4415 1223 else {
b4a9cd27 1224 Double_t localZ = global[2];
030b4415 1225 if (global[2] > 0.0) {
1226 localZ -= 0.5*(GetChamberLength(index[0],2)+GetChamberLength(index[0],1));
1227 index[1] = (TMath::Abs(localZ) < 0.5*GetChamberLength(index[0],3)) ? 1 : 0;
b4a9cd27 1228 }
030b4415 1229 else {
1230 localZ += 0.5*(GetChamberLength(index[0],2)+GetChamberLength(index[0],3));
1231 index[1] = (TMath::Abs(localZ) < 0.5*GetChamberLength(index[0],1)) ? 3 : 4;
b4a9cd27 1232 }
1233 }
bd0f8685 1234
3d7b6a24 1235 return kTRUE;
3d7b6a24 1236
bd0f8685 1237}
3d7b6a24 1238
f7336fa3 1239//_____________________________________________________________________________
a5cadd36 1240Bool_t AliTRDgeometry::Rotate(Int_t d, Double_t *pos, Double_t *rot) const
f7336fa3 1241{
1242 //
1243 // Rotates all chambers in the position of sector 0 and transforms
1244 // the coordinates in the ALICE restframe <pos> into the
1245 // corresponding local frame <rot>.
1246 //
1247
793ff80c 1248 Int_t sector = GetSector(d);
f7336fa3 1249
793ff80c 1250 rot[0] = pos[0] * fRotA11[sector] + pos[1] * fRotA12[sector];
1251 rot[1] = -pos[0] * fRotA21[sector] + pos[1] * fRotA22[sector];
f7336fa3 1252 rot[2] = pos[2];
1253
1254 return kTRUE;
1255
1256}
1257
1258//_____________________________________________________________________________
a5cadd36 1259Bool_t AliTRDgeometry::RotateBack(Int_t d, Double_t *rot, Double_t *pos) const
f7336fa3 1260{
1261 //
1262 // Rotates a chambers from the position of sector 0 into its
1263 // original position and transforms the corresponding local frame
1264 // coordinates <rot> into the coordinates of the ALICE restframe <pos>.
1265 //
1266
793ff80c 1267 Int_t sector = GetSector(d);
f7336fa3 1268
793ff80c 1269 pos[0] = rot[0] * fRotB11[sector] + rot[1] * fRotB12[sector];
1270 pos[1] = -rot[0] * fRotB21[sector] + rot[1] * fRotB22[sector];
6f1e466d 1271 pos[2] = rot[2];
f7336fa3 1272
1273 return kTRUE;
1274
1275}
1276
1277//_____________________________________________________________________________
3551db50 1278Int_t AliTRDgeometry::GetDetectorSec(Int_t p, Int_t c)
0a770ac9 1279{
1280 //
1281 // Convert plane / chamber into detector number for one single sector
1282 //
1283
1284 return (p + c * fgkNplan);
1285
1286}
1287
1288//_____________________________________________________________________________
3551db50 1289Int_t AliTRDgeometry::GetDetector(Int_t p, Int_t c, Int_t s)
f7336fa3 1290{
1291 //
1292 // Convert plane / chamber / sector into detector number
1293 //
1294
793ff80c 1295 return (p + c * fgkNplan + s * fgkNplan * fgkNcham);
f7336fa3 1296
1297}
1298
1299//_____________________________________________________________________________
afc51ac2 1300Int_t AliTRDgeometry::GetPlane(Int_t d) const
f7336fa3 1301{
1302 //
1303 // Reconstruct the plane number from the detector number
1304 //
1305
793ff80c 1306 return ((Int_t) (d % fgkNplan));
f7336fa3 1307
1308}
1309
1310//_____________________________________________________________________________
afc51ac2 1311Int_t AliTRDgeometry::GetChamber(Int_t d) const
f7336fa3 1312{
1313 //
1314 // Reconstruct the chamber number from the detector number
1315 //
1316
793ff80c 1317 return ((Int_t) (d % (fgkNplan * fgkNcham)) / fgkNplan);
f7336fa3 1318
1319}
1320
1321//_____________________________________________________________________________
afc51ac2 1322Int_t AliTRDgeometry::GetSector(Int_t d) const
f7336fa3 1323{
1324 //
1325 // Reconstruct the sector number from the detector number
1326 //
1327
793ff80c 1328 return ((Int_t) (d / (fgkNplan * fgkNcham)));
f7336fa3 1329
1330}
1331
bdbb05bb 1332//_____________________________________________________________________________
030b4415 1333AliTRDgeometry* AliTRDgeometry::GetGeometry(AliRunLoader *runLoader)
bdbb05bb 1334{
1335 //
030b4415 1336 // Load the geometry from the galice file
bdbb05bb 1337 //
1338
1339 if (!runLoader) runLoader = AliRunLoader::GetRunLoader();
1340 if (!runLoader) {
030b4415 1341 AliErrorGeneral("AliTRDgeometry::GetGeometry","No run loader");
bdbb05bb 1342 return NULL;
1343 }
1344
030b4415 1345 TDirectory *saveDir = gDirectory;
bdbb05bb 1346 runLoader->CdGAFile();
1347
ecb36af7 1348 // Try from the galice.root file
030b4415 1349 AliTRDgeometry *geom = (AliTRDgeometry *) gDirectory->Get("TRDgeometry");
ecb36af7 1350
1351 if (!geom) {
1352 // It is not in the file, try to get it from gAlice,
1353 // which corresponds to the run loader
030b4415 1354 AliTRD *trd = (AliTRD *) runLoader->GetAliRun()->GetDetector("TRD");
ecb36af7 1355 geom = trd->GetGeometry();
1356 }
2745a409 1357 if (!geom) {
030b4415 1358 AliErrorGeneral("AliTRDgeometry::GetGeometry","Geometry not found");
2745a409 1359 return NULL;
1360 }
bdbb05bb 1361
1362 saveDir->cd();
1363 return geom;
b4a9cd27 1364
bd0f8685 1365}
b4a9cd27 1366
1367//_____________________________________________________________________________
bd0f8685 1368Bool_t AliTRDgeometry::ReadGeoMatrices()
1369{
b4a9cd27 1370 //
1371 // Read geo matrices from current gGeoManager for each TRD sector
1372 //
1373
030b4415 1374 if (!gGeoManager) {
1375 return kFALSE;
1376 }
1377 fMatrixArray = new TObjArray(kNdet);
b4a9cd27 1378 fMatrixCorrectionArray = new TObjArray(kNdet);
030b4415 1379 fMatrixGeo = new TObjArray(kNdet);
b4a9cd27 1380 AliAlignObjAngles o;
bd0f8685 1381
b4a9cd27 1382 for (Int_t iLayer = AliAlignObj::kTRD1; iLayer <= AliAlignObj::kTRD6; iLayer++) {
1383 for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
030b4415 1384
1385 UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,iModule);
1386 const char *path = AliAlignObj::GetVolPath(volid);
b4a9cd27 1387 if (!gGeoManager->cd(path)) return kFALSE;
030b4415 1388 TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
1389 Int_t iLayerTRD = iLayer - AliAlignObj::kTRD1;
1390 Int_t isector = Nsect() - 1 - (iModule/Ncham());
1391 Int_t ichamber = Ncham() - 1 - (iModule%Ncham());
1392 Int_t lid = GetDetector(iLayerTRD,ichamber,isector);
bd0f8685 1393
b4a9cd27 1394 //
2745a409 1395 // Local geo system z-x-y to x-y--z
b4a9cd27 1396 //
1397 fMatrixGeo->AddAt(new TGeoHMatrix(*m),lid);
1398
1399 TGeoRotation mchange;
030b4415 1400 mchange.RotateY(90);
1401 mchange.RotateX(90);
bd0f8685 1402
b4a9cd27 1403 TGeoHMatrix gMatrix(mchange.Inverse());
1404 gMatrix.MultiplyLeft(m);
1405 fMatrixArray->AddAt(new TGeoHMatrix(gMatrix),lid);
bd0f8685 1406
b4a9cd27 1407 //
1408 // Cluster transformation matrix
1409 //
1410 TGeoHMatrix rotMatrix(mchange.Inverse());
1411 rotMatrix.MultiplyLeft(m);
030b4415 1412 Double_t sectorAngle = 20.0 * (isector % 18) + 10.0;
b4a9cd27 1413 TGeoHMatrix rotSector;
1414 rotSector.RotateZ(sectorAngle);
1415 rotMatrix.MultiplyLeft(&rotSector);
bd0f8685 1416
b4a9cd27 1417 fMatrixCorrectionArray->AddAt(new TGeoHMatrix(rotMatrix),lid);
bd0f8685 1418
b4a9cd27 1419 }
1420 }
bd0f8685 1421
b4a9cd27 1422 return kTRUE;
b4a9cd27 1423
bd0f8685 1424}
b4a9cd27 1425