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