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