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