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