Removal of the last gAlice deps. In case of raw-data reconstruction and missing gAlic...
[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   // Parameter of the BTRD mother volumes 
58   const Float_t  AliTRDgeometry::fgkSheight   =  77.9; 
59   const Float_t  AliTRDgeometry::fgkSwidth1   =  94.881; 
60   const Float_t  AliTRDgeometry::fgkSwidth2   = 122.353;
61   const Float_t  AliTRDgeometry::fgkSlength   = 751.0;
62
63   // The super module side plates
64   const Float_t  AliTRDgeometry::fgkSMpltT    =   0.2;
65
66   // Height of different chamber parts
67   // Radiator
68   const Float_t  AliTRDgeometry::fgkCraH      =   4.8; 
69   // Drift region
70   const Float_t  AliTRDgeometry::fgkCdrH      =   3.0;
71   // Amplification region
72   const Float_t  AliTRDgeometry::fgkCamH      =   0.7;
73   // Readout
74   const Float_t  AliTRDgeometry::fgkCroH      =   2.316;
75   // Total height
76   const Float_t  AliTRDgeometry::fgkCH        = AliTRDgeometry::fgkCraH
77                                               + AliTRDgeometry::fgkCdrH
78                                               + AliTRDgeometry::fgkCamH
79                                               + AliTRDgeometry::fgkCroH;  
80
81   // Vertical spacing of the chambers
82   const Float_t  AliTRDgeometry::fgkVspace    =   1.784;
83   // Horizontal spacing of the chambers
84   const Float_t  AliTRDgeometry::fgkHspace    =   2.0;
85   // Radial distance of the first ROC to the outer plates of the SM
86   const Float_t  AliTRDgeometry::fgkVrocsm    =   1.2;
87
88   // Thicknesses of different parts of the chamber frame
89   // Lower aluminum frame
90   const Float_t  AliTRDgeometry::fgkCalT      =   0.4;
91   // Lower Wacosit frame sides
92   const Float_t  AliTRDgeometry::fgkCclsT     =   0.21;
93   // Lower Wacosit frame front
94   const Float_t  AliTRDgeometry::fgkCclfT     =   1.0;
95   // Thickness of glue around radiator
96   const Float_t  AliTRDgeometry::fgkCglT      =   0.25;
97   // Upper Wacosit frame
98   const Float_t  AliTRDgeometry::fgkCcuT      =   0.9;
99   // Al frame of back panel
100   const Float_t  AliTRDgeometry::fgkCauT      =   1.5;
101   // Additional Al of the lower chamber frame
102   const Float_t  AliTRDgeometry::fgkCalW      =   1.11;
103
104   // Additional width of the readout chamber frames
105   const Float_t  AliTRDgeometry::fgkCroW      =   0.9;
106
107   // Difference of outer chamber width and pad plane width
108   const Float_t  AliTRDgeometry::fgkCpadW     =   0.0;
109   const Float_t  AliTRDgeometry::fgkRpadW     =   1.0;
110
111   //
112   // Thickness of the the material layers
113   //
114   const Float_t  AliTRDgeometry::fgkMyThick   = 0.005;
115   const Float_t  AliTRDgeometry::fgkRaThick   = 0.3233;  
116   const Float_t  AliTRDgeometry::fgkDrThick   = AliTRDgeometry::fgkCdrH;    
117   const Float_t  AliTRDgeometry::fgkAmThick   = AliTRDgeometry::fgkCamH;
118   const Float_t  AliTRDgeometry::fgkXeThick   = AliTRDgeometry::fgkDrThick
119                                               + AliTRDgeometry::fgkAmThick;
120   const Float_t  AliTRDgeometry::fgkWrThick   = 0.0002;
121   const Float_t  AliTRDgeometry::fgkCuThick   = 0.0072; 
122   const Float_t  AliTRDgeometry::fgkGlThick   = 0.05;
123   const Float_t  AliTRDgeometry::fgkSuThick   = 0.0919; 
124   const Float_t  AliTRDgeometry::fgkRcThick   = 0.0058;
125   const Float_t  AliTRDgeometry::fgkRpThick   = 0.0632;
126   const Float_t  AliTRDgeometry::fgkRoThick   = 0.0028;
127
128   //
129   // Position of the material layers
130   //
131   const Float_t  AliTRDgeometry::fgkRaZpos    =  0.0;
132   const Float_t  AliTRDgeometry::fgkDrZpos    =  2.4;
133   const Float_t  AliTRDgeometry::fgkAmZpos    =  0.0;
134   const Float_t  AliTRDgeometry::fgkWrZpos    =  0.0;
135   const Float_t  AliTRDgeometry::fgkCuZpos    = -0.9995;
136   const Float_t  AliTRDgeometry::fgkGlZpos    = -0.5; 
137   const Float_t  AliTRDgeometry::fgkSuZpos    =  0.0;
138   const Float_t  AliTRDgeometry::fgkRcZpos    =  1.04;
139   const Float_t  AliTRDgeometry::fgkRpZpos    =  1.0;
140   const Float_t  AliTRDgeometry::fgkRoZpos    =  1.05;
141
142   const Int_t    AliTRDgeometry::fgkMCMmax    = 16;   
143   const Int_t    AliTRDgeometry::fgkMCMrow    = 4;   
144   const Int_t    AliTRDgeometry::fgkROBmaxC0  = 6; 
145   const Int_t    AliTRDgeometry::fgkROBmaxC1  = 8; 
146   const Int_t    AliTRDgeometry::fgkADCmax    = 21;   
147   const Int_t    AliTRDgeometry::fgkTBmax     = 60;   
148   const Int_t    AliTRDgeometry::fgkPadmax    = 18;   
149   const Int_t    AliTRDgeometry::fgkColmax    = 144;
150   const Int_t    AliTRDgeometry::fgkRowmaxC0  = 12;
151   const Int_t    AliTRDgeometry::fgkRowmaxC1  = 16;
152
153   const Double_t AliTRDgeometry::fgkTime0Base = 300.65;
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) {
219     Init();
220   }
221
222   return *this;
223
224 }
225
226 //_____________________________________________________________________________
227 void AliTRDgeometry::Init()
228 {
229   //
230   // Initializes the geometry parameter
231   //
232
233   Int_t icham;
234   Int_t iplan;
235   Int_t isect;
236
237   // The outer width of the chambers
238   fCwidth[0] =  90.4;
239   fCwidth[1] =  94.8;
240   fCwidth[2] =  99.3;
241   fCwidth[3] = 103.7;
242   fCwidth[4] = 108.1;
243   fCwidth[5] = 112.6;
244
245   // The outer lengths of the chambers
246   // Includes the spacings between the chambers!
247   Float_t length[kNplan][kNcham]   = { { 124.0, 124.0, 110.0, 124.0, 124.0 }
248                                      , { 124.0, 124.0, 110.0, 124.0, 124.0 }
249                                      , { 131.0, 131.0, 110.0, 131.0, 131.0 }
250                                      , { 138.0, 138.0, 110.0, 138.0, 138.0 }
251                                      , { 145.0, 145.0, 110.0, 145.0, 145.0 }
252                                      , { 147.0, 147.0, 110.0, 147.0, 147.0 } };
253
254   for (icham = 0; icham < kNcham; icham++) {
255     for (iplan = 0; iplan < kNplan; iplan++) {
256       fClength[iplan][icham] = length[iplan][icham];
257     }
258   }
259
260   // The rotation matrix elements
261   Float_t phi = 0.0;
262   for (isect = 0; isect < fgkNsect; isect++) {
263     phi = 2.0 * TMath::Pi() /  (Float_t) fgkNsect * ((Float_t) isect + 0.5);
264     fRotA11[isect] = TMath::Cos(phi);
265     fRotA12[isect] = TMath::Sin(phi);
266     fRotA21[isect] = TMath::Sin(phi);
267     fRotA22[isect] = TMath::Cos(phi);
268     phi = -1.0 * phi;
269     fRotB11[isect] = TMath::Cos(phi);
270     fRotB12[isect] = TMath::Sin(phi);
271     fRotB21[isect] = TMath::Sin(phi);
272     fRotB22[isect] = TMath::Cos(phi);
273   }
274
275   for (isect = 0; isect < fgkNsect; isect++) {
276     SetSMstatus(isect,1);
277   }
278  
279 }
280
281 //_____________________________________________________________________________
282 void AliTRDgeometry::CreateGeometry(Int_t *idtmed)
283 {
284   //
285   // Create the TRD geometry without hole
286   //
287   //
288   // Names of the TRD volumina (xx = detector number):
289   //
290   //      Volume (Air) wrapping the readout chamber components
291   //        UTxx    includes: UAxx, UDxx, UFxx, UUxx
292   //
293   //      Volume (Air) wrapping the services (fee + cooling)
294   //        UUxx    the services volume has been reduced by 7.42 mm
295   //                in order to allow shifts in radial direction
296   //
297   //      Lower part of the readout chambers (drift volume + radiator)
298   //
299   //        UAxx    Aluminum frames                 (Al)
300   //        UBxx    Wacosit frames                  (C)
301   //        UXxx    Glue around radiator            (Epoxy)
302   //        UCxx    Inner volumes                   (Air)
303   //        UZxx    Additional aluminum ledges      (Al)
304   //
305   //      Upper part of the readout chambers (readout plane + fee)
306   //
307   //        UDxx    Wacosit frames of amp. region   (C)
308   //        UExx    Inner volumes of the frame      (Air)
309   //        UFxx    Aluminum frame of back panel    (Al)
310   //        UGxx    Inner volumes of the back panel (Air)
311   //
312   //      Inner material layers
313   //
314   //        UHxx    Radiator                        (Rohacell)
315   //        UJxx    Drift volume                    (Xe/CO2)
316   //        UKxx    Amplification volume            (Xe/CO2)
317   //        UWxx    Wire plane                      (Cu)
318   //        ULxx    Pad plane                       (Cu)
319   //        UYxx    Glue layer                      (Epoxy)
320   //        UMxx    Support structure               (Rohacell)
321   //        UNxx    ROB base material               (C)
322   //        UOxx    ROB copper                      (Cu)
323   //        UVxx    ROB other materials             (Cu)
324   //
325
326   const Int_t kNparTrd = 4;
327   const Int_t kNparCha = 3;
328
329   Float_t xpos;
330   Float_t ypos;
331   Float_t zpos;
332
333   Float_t parTrd[kNparTrd];
334   Float_t parCha[kNparCha];
335
336   Char_t  cTagV[6];
337   Char_t  cTagM[5];
338
339   // The TRD mother volume for one sector (Air), full length in z-direction
340   // Provides material for side plates of super module
341   parTrd[0] = fgkSwidth1/2.0;
342   parTrd[1] = fgkSwidth2/2.0;
343   parTrd[2] = fgkSlength/2.0;
344   parTrd[3] = fgkSheight/2.0;
345   gMC->Gsvolu("UTR1","TRD1",idtmed[1302-1],parTrd,kNparTrd);
346
347   // The outer aluminum plates of the super module (Al)
348   parTrd[0] = fgkSwidth1/2.0;
349   parTrd[1] = fgkSwidth2/2.0;
350   parTrd[2] = fgkSlength/2.0;
351   parTrd[3] = fgkSheight/2.0;
352   gMC->Gsvolu("UTS1","TRD1",idtmed[1301-1],parTrd,kNparTrd);
353
354   // The inner part of the TRD mother volume for one sector (Air), 
355   // full length in z-direction
356   parTrd[0] = fgkSwidth1/2.0 - fgkSMpltT;
357   parTrd[1] = fgkSwidth2/2.0 - fgkSMpltT;
358   parTrd[2] = fgkSlength/2.0;
359   parTrd[3] = fgkSheight/2.0 - fgkSMpltT;
360   gMC->Gsvolu("UTI1","TRD1",idtmed[1302-1],parTrd,kNparTrd);
361
362   for (Int_t icham = 0; icham < kNcham; icham++) {
363     for (Int_t iplan = 0; iplan < kNplan; iplan++) {  
364
365       Int_t iDet = GetDetectorSec(iplan,icham);
366
367       // The lower part of the readout chambers (drift volume + radiator) 
368       // The aluminum frames 
369       sprintf(cTagV,"UA%02d",iDet);
370       parCha[0] = fCwidth[iplan]/2.0;
371       parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
372       parCha[2] = fgkCraH/2.0 + fgkCdrH/2.0;
373       fChamberUAboxd[iDet][0] = parCha[0];
374       fChamberUAboxd[iDet][1] = parCha[1];
375       fChamberUAboxd[iDet][2] = parCha[2];
376       gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parCha,kNparCha);
377       // The additional aluminum on the frames
378       // This part has not the correct postion but is just supposed to
379       // represent the missing material. The correct from of the L-shaped
380       // profile would not fit into the alignable volume. 
381       sprintf(cTagV,"UZ%02d",iDet);
382       parCha[0] = fgkCroW/2.0;
383       parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
384       parCha[2] = fgkCalW/2.0;
385       fChamberUAboxd[iDet][0] = fChamberUAboxd[iDet][0] + fgkCroW;
386       gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parCha,kNparCha);
387       // The Wacosit frames 
388       sprintf(cTagV,"UB%02d",iDet);
389       parCha[0] = fCwidth[iplan]/2.0 - fgkCalT; 
390       parCha[1] = -1.0;
391       parCha[2] = -1.0;
392       gMC->Gsvolu(cTagV,"BOX ",idtmed[1307-1],parCha,kNparCha);
393       // The glue around the radiator
394       sprintf(cTagV,"UX%02d",iDet);
395       parCha[0] = fCwidth[iplan]/2.0 - fgkCalT - fgkCclsT; 
396       parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0 - fgkCclfT;
397       parCha[2] = fgkCraH/2.0;
398       gMC->Gsvolu(cTagV,"BOX ",idtmed[1311-1],parCha,kNparCha);
399       // The inner part of radiator (air)
400       sprintf(cTagV,"UC%02d",iDet);
401       parCha[0] = fCwidth[iplan]/2.0 - fgkCalT - fgkCclsT - fgkCglT; 
402       parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0 - fgkCclfT - fgkCglT;
403       parCha[2] = -1.0;
404       gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
405
406       // The upper part of the readout chambers (amplification volume)
407       // The Wacosit 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 Wacosit 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
423       // The support structure (pad plane, back panel, readout boards)
424       // The aluminum frames
425       sprintf(cTagV,"UF%02d",iDet);
426       parCha[0] = fCwidth[iplan]/2.0 + fgkCroW;
427       parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
428       parCha[2] = fgkCroH/2.0;
429       fChamberUFboxd[iDet][0] = parCha[0];
430       fChamberUFboxd[iDet][1] = parCha[1];
431       fChamberUFboxd[iDet][2] = parCha[2];
432       gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parCha,kNparCha);
433       // The inner part of the aluminum frames
434       sprintf(cTagV,"UG%02d",iDet);
435       parCha[0] = fCwidth[iplan]/2.0 + fgkCroW - fgkCauT; 
436       parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0 - fgkCauT;
437       parCha[2] = -1.0;
438       gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
439
440       // The material layers inside the chambers
441       // Rohacell layer (radiator)
442       parCha[0] = -1.0;
443       parCha[1] = -1.0;
444       parCha[2] = fgkRaThick/2.0;
445       sprintf(cTagV,"UH%02d",iDet);
446       gMC->Gsvolu(cTagV,"BOX ",idtmed[1315-1],parCha,kNparCha);
447       // Xe/Isobutane layer (drift volume) 
448       parCha[0] = fCwidth[iplan]/2.0 - fgkCalT - fgkCclsT;
449       parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0 - fgkCclfT;
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[0] = -1.0;
455       parCha[1] = -1.0;
456       parCha[2] = fgkAmThick/2.0;
457       sprintf(cTagV,"UK%02d",iDet);
458       gMC->Gsvolu(cTagV,"BOX ",idtmed[1309-1],parCha,kNparCha);  
459       // Cu layer (wire plane)
460       parCha[0] = -1.0;
461       parCha[1] = -1.0;
462       parCha[2] = fgkWrThick/2.0;
463       sprintf(cTagV,"UW%02d",iDet);
464       gMC->Gsvolu(cTagV,"BOX ",idtmed[1303-1],parCha,kNparCha);
465       // Cu layer (pad plane)
466       parCha[0] = -1.0;
467       parCha[1] = -1.0;
468       parCha[2] = fgkCuThick/2.0;
469       sprintf(cTagV,"UL%02d",iDet);
470       gMC->Gsvolu(cTagV,"BOX ",idtmed[1305-1],parCha,kNparCha);
471       // Epoxy layer (glue)
472       parCha[0] = -1.0;
473       parCha[1] = -1.0;
474       parCha[2] = fgkGlThick/2.0;
475       sprintf(cTagV,"UY%02d",iDet);
476       gMC->Gsvolu(cTagV,"BOX ",idtmed[1311-1],parCha,kNparCha);
477       // G10 layer (support structure / honeycomb)
478       parCha[0] = -1.0;
479       parCha[1] = -1.0;
480       parCha[2] = fgkSuThick/2.0;
481       sprintf(cTagV,"UM%02d",iDet);
482       gMC->Gsvolu(cTagV,"BOX ",idtmed[1310-1],parCha,kNparCha);
483       // G10 layer (PCB readout board)
484       parCha[0] = -1.0;
485       parCha[1] = -1.0;
486       parCha[2] = fgkRpThick/2;
487       sprintf(cTagV,"UN%02d",iDet);
488       gMC->Gsvolu(cTagV,"BOX ",idtmed[1313-1],parCha,kNparCha);
489       // Cu layer (traces in readout board)
490       parCha[0] = -1.0;
491       parCha[1] = -1.0;
492       parCha[2] = fgkRcThick/2.0;
493       sprintf(cTagV,"UO%02d",iDet);
494       gMC->Gsvolu(cTagV,"BOX ",idtmed[1306-1],parCha,kNparCha);
495       // Cu layer (other material on in readout board)
496       parCha[0] = -1.0;
497       parCha[1] = -1.0;
498       parCha[2] = fgkRoThick/2.0;
499       sprintf(cTagV,"UV%02d",iDet);
500       gMC->Gsvolu(cTagV,"BOX ",idtmed[1304-1],parCha,kNparCha);
501
502       // Position the layers in the chambers
503       xpos = 0.0;
504       ypos = 0.0;
505       // Lower part
506       // Rohacell layer (radiator)
507       zpos = fgkRaZpos;
508       sprintf(cTagV,"UH%02d",iDet);
509       sprintf(cTagM,"UC%02d",iDet);
510       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
511       // Xe/Isobutane layer (drift volume) 
512       zpos = fgkDrZpos;
513       sprintf(cTagV,"UJ%02d",iDet);
514       sprintf(cTagM,"UB%02d",iDet);
515       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
516       // Upper part
517       // Xe/Isobutane layer (amplification volume)
518       zpos = fgkAmZpos;
519       sprintf(cTagV,"UK%02d",iDet);
520       sprintf(cTagM,"UE%02d",iDet);
521       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
522       // Cu layer (wire plane inside amplification volume)
523       zpos = fgkWrZpos; 
524       sprintf(cTagV,"UW%02d",iDet);
525       sprintf(cTagM,"UK%02d",iDet);
526       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
527       // Readout part + support plane
528       // Cu layer (pad plane)
529       zpos = fgkCuZpos; 
530       sprintf(cTagV,"UL%02d",iDet);
531       sprintf(cTagM,"UG%02d",iDet);
532       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
533       // Epoxy layer (glue)
534       zpos = fgkGlZpos; 
535       sprintf(cTagV,"UY%02d",iDet);
536       sprintf(cTagM,"UG%02d",iDet);
537       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
538       // G10 layer (support structure)
539       zpos = fgkSuZpos;
540       sprintf(cTagV,"UM%02d",iDet);
541       sprintf(cTagM,"UG%02d",iDet);
542       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
543       // G10 layer (PCB readout board)
544       zpos = fgkRpZpos;
545       sprintf(cTagV,"UN%02d",iDet);
546       sprintf(cTagM,"UG%02d",iDet);
547       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
548       // Cu layer (traces in readout board)
549       zpos = fgkRcZpos;
550       sprintf(cTagV,"UO%02d",iDet);
551       sprintf(cTagM,"UG%02d",iDet);
552       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
553       // Cu layer (other materials on readout board)
554       zpos = fgkRoZpos;
555       sprintf(cTagV,"UV%02d",iDet);
556       sprintf(cTagM,"UG%02d",iDet);
557       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
558
559       // Position the inner volumes of the chambers in the frames
560       xpos = 0.0;
561       ypos = 0.0;
562       // The inner part of the radiator
563       zpos = 0.0;
564       sprintf(cTagV,"UC%02d",iDet);
565       sprintf(cTagM,"UX%02d",iDet);
566       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
567       // The glue around the radiator
568       zpos = fgkCraH/2.0 - fgkCdrH/2.0 - fgkCraH/2.0;
569       sprintf(cTagV,"UX%02d",iDet);
570       sprintf(cTagM,"UB%02d",iDet);
571       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
572       // The lower Wacosit frame inside the aluminum frame
573       zpos = 0.0;
574       sprintf(cTagV,"UB%02d",iDet);
575       sprintf(cTagM,"UA%02d",iDet);
576       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
577       // The inside of the upper Wacosit frame
578       zpos = 0.0;
579       sprintf(cTagV,"UE%02d",iDet);
580       sprintf(cTagM,"UD%02d",iDet);
581       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
582       // The inside of the upper aluminum frame
583       zpos = 0.0;
584       sprintf(cTagV,"UG%02d",iDet);
585       sprintf(cTagM,"UF%02d",iDet);
586       gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");      
587
588       // Position the frames of the chambers in the TRD mother volume
589       xpos  = 0.0;
590       ypos  = fClength[iplan][0] + fClength[iplan][1] + fClength[iplan][2]/2.0;
591       for (Int_t ic = 0; ic < icham; ic++) {
592         ypos -= fClength[iplan][ic];        
593       }
594       ypos -= fClength[iplan][icham]/2.0;
595       zpos  = fgkVrocsm + fgkSMpltT + fgkCraH/2.0 + fgkCdrH/2.0 - fgkSheight/2.0 
596             + iplan * (fgkCH + fgkVspace);
597       // The lower aluminum frame, radiator + drift region
598       sprintf(cTagV,"UA%02d",iDet);      
599       fChamberUAorig[iDet][0] = xpos;
600       fChamberUAorig[iDet][1] = ypos;
601       fChamberUAorig[iDet][2] = zpos;
602       // The upper G10 frame, amplification region
603       sprintf(cTagV,"UD%02d",iDet);
604       zpos += fgkCamH/2.0 + fgkCraH/2.0 + fgkCdrH/2.0;      
605       fChamberUDorig[iDet][0] = xpos;
606       fChamberUDorig[iDet][1] = ypos;
607       fChamberUDorig[iDet][2] = zpos;
608       // The upper aluminum frame
609       sprintf(cTagV,"UF%02d",iDet);
610       zpos += fgkCroH/2.0 + fgkCamH/2.0;      
611       fChamberUForig[iDet][0] = xpos;
612       fChamberUForig[iDet][1] = ypos;
613       fChamberUForig[iDet][2] = zpos;
614
615     }
616   }
617
618   // Create the volumes of the super module frame
619   CreateFrame(idtmed);
620
621   // Create the volumes of the services
622   CreateServices(idtmed);
623   
624   for (Int_t icham = 0; icham < kNcham; icham++) {
625     for (Int_t iplan = 0; iplan < kNplan; iplan++) {  
626       GroupChamber(iplan,icham,idtmed);
627     }
628   }
629   
630   xpos = 0.0;
631   ypos = 0.0;
632   zpos = 0.0;
633   gMC->Gspos("UTI1",1,"UTS1",xpos,ypos,zpos,0,"ONLY");
634
635   xpos = 0.0;
636   ypos = 0.0;
637   zpos = 0.0;
638   gMC->Gspos("UTS1",1,"UTR1",xpos,ypos,zpos,0,"ONLY");
639
640   // Put the TRD volumes into the space frame mother volumes
641   // if enabled via status flag
642   xpos = 0.0;
643   ypos = 0.0;
644   zpos = 0.0;
645   for (Int_t isect = 0; isect < kNsect; isect++) {
646     if (fSMstatus[isect]) {
647       sprintf(cTagV,"BTRD%d",isect);
648       gMC->Gspos("UTR1",1,cTagV,xpos,ypos,zpos,0,"ONLY");
649     }
650   }
651
652 }
653
654 //_____________________________________________________________________________
655 void AliTRDgeometry::CreateFrame(Int_t *idtmed)
656 {
657   //
658   // Create the geometry of the frame of the supermodule
659   //
660   // Names of the TRD services volumina
661   //
662   //        USRL    Support rails for the chambers (Al)
663   //        USxx    Support cross bars between the chambers (Al)
664   //        USHx    Horizontal connection between the cross bars (Al)
665   //        USLx    Long corner ledges (Al)
666   //
667
668   Int_t   iplan = 0;
669
670   Float_t xpos  = 0.0;
671   Float_t ypos  = 0.0;
672   Float_t zpos  = 0.0;
673
674   Char_t  cTagV[5];
675   Char_t  cTagM[5];
676
677   // The rotation matrices
678   const Int_t kNmatrix = 4;
679   Int_t   matrix[kNmatrix];
680   gMC->Matrix(matrix[0], 100.0,   0.0,  90.0,  90.0,  10.0,   0.0);
681   gMC->Matrix(matrix[1],  80.0,   0.0,  90.0,  90.0,  10.0, 180.0);
682   gMC->Matrix(matrix[2],  90.0,   0.0,   0.0,   0.0,  90.0,  90.0);
683   gMC->Matrix(matrix[3],  90.0, 180.0,   0.0, 180.0,  90.0,  90.0);
684
685   //
686   // The chamber support rails
687   //
688
689   const Float_t kSRLwid  = 2.00;
690   const Float_t kSRLhgt  = 2.3;
691   const Float_t kSRLdst  = 1.0;
692   const Int_t   kNparSRL = 3;
693   Float_t parSRL[kNparSRL];
694   parSRL[0] = kSRLwid   /2.0;
695   parSRL[1] = fgkSlength/2.0;
696   parSRL[2] = kSRLhgt   /2.0;
697   gMC->Gsvolu("USRL","BOX ",idtmed[1301-1],parSRL,kNparSRL);
698
699   xpos  = 0.0;
700   ypos  = 0.0;
701   zpos  = 0.0;
702   for (iplan = 0; iplan < kNplan; iplan++) {
703     xpos  = fCwidth[iplan]/2.0 + kSRLwid/2.0 + kSRLdst;
704     ypos  = 0.0;
705     zpos  = fgkVrocsm + fgkSMpltT + fgkCraH + fgkCdrH + fgkCamH 
706           - fgkSheight/2.0  
707           + iplan * (fgkCH + fgkVspace);
708     gMC->Gspos("USRL",iplan+1         ,"UTI1", xpos,ypos,zpos,0,"ONLY");
709     gMC->Gspos("USRL",iplan+1+  kNplan,"UTI1",-xpos,ypos,zpos,0,"ONLY");
710   }
711
712   //
713   // The cross bars between the chambers
714   //
715
716   const Float_t kSCBwid  = 1.0;
717   const Float_t kSCBthk  = 2.0;
718   const Float_t kSCHhgt  = 0.3;
719
720   const Int_t   kNparSCB = 3;
721   Float_t parSCB[kNparSCB];
722   parSCB[1] = kSCBwid/2.0;
723   parSCB[2] = fgkCH  /2.0 + fgkVspace/2.0 - kSCHhgt;
724
725   const Int_t   kNparSCI = 3;
726   Float_t parSCI[kNparSCI];
727   parSCI[1] = -1;
728
729   xpos  = 0.0;
730   ypos  = 0.0;
731   zpos  = 0.0;
732   for (iplan = 0; iplan < kNplan; iplan++) {
733
734     // The aluminum of the cross bars
735     parSCB[0] = fCwidth[iplan]/2.0 + kSRLdst/2.0;
736     sprintf(cTagV,"USF%01d",iplan);
737     gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
738
739     // The empty regions in the cross bars
740     Float_t thkSCB = kSCBthk;
741     if (iplan < 2) {
742       thkSCB *= 1.5;
743     }
744     parSCI[2] = parSCB[2] - thkSCB;
745     parSCI[0] = parSCB[0]/4.0 - kSCBthk;
746     sprintf(cTagV,"USI%01d",iplan);
747     gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parSCI,kNparSCI);
748
749     sprintf(cTagV,"USI%01d",iplan);
750     sprintf(cTagM,"USF%01d",iplan);
751     ypos  = 0.0;
752     zpos  = 0.0;
753     xpos  =   parSCI[0] + thkSCB/2.0;
754     gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
755     xpos  = - parSCI[0] - thkSCB/2.0;
756     gMC->Gspos(cTagV,2,cTagM,xpos,ypos,zpos,0,"ONLY");
757     xpos  =   3.0 * parSCI[0] + 1.5 * thkSCB;
758     gMC->Gspos(cTagV,3,cTagM,xpos,ypos,zpos,0,"ONLY");
759     xpos  = - 3.0 * parSCI[0] - 1.5 * thkSCB;
760     gMC->Gspos(cTagV,4,cTagM,xpos,ypos,zpos,0,"ONLY");
761
762     sprintf(cTagV,"USF%01d",iplan);
763     xpos  = 0.0;
764     zpos  = fgkVrocsm + fgkSMpltT + parSCB[2] - fgkSheight/2.0 
765           + iplan * (fgkCH + fgkVspace);
766
767     ypos  =   fgkSlength/2.0 - kSCBwid/2.0;
768     gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
769
770     ypos  =   fClength[iplan][2]/2.0 + fClength[iplan][1];
771     gMC->Gspos(cTagV,2,"UTI1", xpos,ypos,zpos,0,"ONLY");
772
773     ypos  =   fClength[iplan][2]/2.0;
774     gMC->Gspos(cTagV,3,"UTI1", xpos,ypos,zpos,0,"ONLY");
775
776     ypos  = - fClength[iplan][2]/2.0;
777     gMC->Gspos(cTagV,4,"UTI1", xpos,ypos,zpos,0,"ONLY");
778
779     ypos  = - fClength[iplan][2]/2.0 - fClength[iplan][1];
780     gMC->Gspos(cTagV,5,"UTI1", xpos,ypos,zpos,0,"ONLY");
781
782     ypos  = - fgkSlength/2.0 + kSCBwid/2.0;
783     gMC->Gspos(cTagV,6,"UTI1", xpos,ypos,zpos,0,"ONLY");
784
785   }
786
787   //
788   // The horizontal connections between the cross bars
789   //
790
791   const Int_t   kNparSCH = 3;
792   Float_t parSCH[kNparSCH];
793
794   for (iplan = 1; iplan < kNplan-1; iplan++) {
795
796     parSCH[0] = fCwidth[iplan]/2.0;
797     parSCH[1] = (fClength[iplan+1][2]/2.0 + fClength[iplan+1][1]
798                - fClength[iplan  ][2]/2.0 - fClength[iplan  ][1])/2.0;
799     parSCH[2] = kSCHhgt/2.0;
800
801     sprintf(cTagV,"USH%01d",iplan);
802     gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCH,kNparSCH);
803     xpos  = 0.0;
804     ypos  = fClength[iplan][2]/2.0 + fClength[iplan][1] + parSCH[1];
805     zpos  = fgkVrocsm + fgkSMpltT - kSCHhgt/2.0 - fgkSheight/2.0 
806           + (iplan+1) * (fgkCH + fgkVspace);
807     gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
808     ypos  = -ypos;
809     gMC->Gspos(cTagV,2,"UTI1", xpos,ypos,zpos,0,"ONLY");
810
811   }
812
813   //
814   // The long corner ledges
815   //
816
817   const Int_t   kNparSCL  =  3;
818   Float_t parSCL[kNparSCL];
819   const Int_t   kNparSCLb = 11;
820   Float_t parSCLb[kNparSCLb];
821
822   // Upper ledges 
823   // Thickness of the corner ledges
824   const Float_t kSCLthkUa  =  0.6; 
825   const Float_t kSCLthkUb  =  0.6; 
826   // Width of the corner ledges
827   const Float_t kSCLwidUa  =  3.2;
828   const Float_t kSCLwidUb  =  4.8;
829   // Position of the corner ledges
830   const Float_t kSCLposxUa = 0.7;
831   const Float_t kSCLposxUb = 3.3;
832   const Float_t kSCLposzUa = 1.6;
833   const Float_t kSCLposzUb = 0.3;
834   // Vertical
835   parSCL[0]  = kSCLthkUa /2.0;
836   parSCL[1]  = fgkSlength/2.0;
837   parSCL[2]  = kSCLwidUa /2.0;
838   gMC->Gsvolu("USL1","BOX ",idtmed[1301-1],parSCL,kNparSCL);
839   xpos  =   fgkSwidth2/2.0 - fgkSMpltT - kSCLposxUa;
840   ypos  =   0.0;
841   zpos  =   fgkSheight/2.0 - fgkSMpltT - kSCLposzUa;
842   gMC->Gspos("USL1",1,"UTI1", xpos,ypos,zpos,matrix[0],"ONLY");
843   xpos  = -xpos;
844   gMC->Gspos("USL1",2,"UTI1", xpos,ypos,zpos,matrix[1],"ONLY");
845   // Horizontal
846   parSCL[0]  = kSCLwidUb /2.0;
847   parSCL[1]  = fgkSlength/2.0;
848   parSCL[2]  = kSCLthkUb /2.0;
849   gMC->Gsvolu("USL2","BOX ",idtmed[1301-1],parSCL,kNparSCL);
850   xpos  =   fgkSwidth2/2.0 - fgkSMpltT - kSCLposxUb;
851   ypos  =   0.0;
852   zpos  =   fgkSheight/2.0 - fgkSMpltT - kSCLposzUb; 
853   gMC->Gspos("USL2",1,"UTI1", xpos,ypos,zpos,        0,"ONLY");
854   xpos  = -xpos;
855   gMC->Gspos("USL2",2,"UTI1", xpos,ypos,zpos,        0,"ONLY");
856
857   // Lower ledges 
858   // Thickness of the corner ledges
859   const Float_t kSCLthkLa  =  2.464; 
860   const Float_t kSCLthkLb  =  1.0; 
861   // Width of the corner ledges
862   const Float_t kSCLwidLa  =  8.5;
863   const Float_t kSCLwidLb  =  3.3;
864   // Position of the corner ledges
865   const Float_t kSCLposxLa =  0.0;
866   const Float_t kSCLposxLb =  2.6;
867   const Float_t kSCLposzLa = -4.25;
868   const Float_t kSCLposzLb = -0.5;
869   // Vertical
870   // Trapezoidal shape
871   parSCLb[ 0] = fgkSlength/2.0;
872   parSCLb[ 1] = 0.0;
873   parSCLb[ 2] = 0.0;
874   parSCLb[ 3] = kSCLwidLa /2.0;
875   parSCLb[ 4] = kSCLthkLb /2.0;
876   parSCLb[ 5] = kSCLthkLa /2.0;
877   parSCLb[ 6] = 5.0;
878   parSCLb[ 7] = kSCLwidLa /2.0;
879   parSCLb[ 8] = kSCLthkLb /2.0;
880   parSCLb[ 9] = kSCLthkLa /2.0;
881   parSCLb[10] = 5.0;
882   gMC->Gsvolu("USL3","TRAP",idtmed[1301-1],parSCLb,kNparSCLb);
883   xpos  =   fgkSwidth1/2.0 - fgkSMpltT - kSCLposxLa;
884   ypos  =   0.0;
885   zpos  = - fgkSheight/2.0 + fgkSMpltT - kSCLposzLa;
886   gMC->Gspos("USL3",1,"UTI1", xpos,ypos,zpos,matrix[2],"ONLY");
887   xpos  = -xpos;
888   gMC->Gspos("USL3",2,"UTI1", xpos,ypos,zpos,matrix[3],"ONLY");
889   // Horizontal
890   parSCL[0]  = kSCLwidLb /2.0;
891   parSCL[1]  = fgkSlength/2.0;
892   parSCL[2]  = kSCLthkLb /2.0;
893   gMC->Gsvolu("USL4","BOX ",idtmed[1301-1],parSCL,kNparSCL);
894   xpos  =   fgkSwidth1/2.0 - fgkSMpltT - kSCLposxLb;
895   ypos  =   0.0;
896   zpos  = - fgkSheight/2.0 + fgkSMpltT - kSCLposzLb;
897   gMC->Gspos("USL4",1,"UTI1", xpos,ypos,zpos,        0,"ONLY");
898   xpos  = -xpos;
899   gMC->Gspos("USL4",2,"UTI1", xpos,ypos,zpos,        0,"ONLY");
900
901 }
902
903 //_____________________________________________________________________________
904 void AliTRDgeometry::CreateServices(Int_t *idtmed)
905 {
906   //
907   // Create the geometry of the services
908   //
909   // Names of the TRD services volumina
910   //
911   //        UTCL    Cooling arterias (Al)
912   //        UTCW    Cooling arterias (Water)
913   //        UUxx    Volumes for the services at the chambers (Air)
914   //        UTPW    Power bars       (Cu)
915   //        UTCP    Cooling pipes    (Fe)
916   //        UTCH    Cooling pipes    (Water)
917   //        UTPL    Power lines      (Cu)
918   //        UMCM    Readout MCMs     (G10/Cu/Si)
919   //
920
921   Int_t   iplan = 0;
922   Int_t   icham = 0;
923
924   Float_t xpos  = 0.0;
925   Float_t ypos  = 0.0;
926   Float_t zpos  = 0.0;
927
928   Char_t  cTagV[5];
929
930   // The rotation matrices
931   const Int_t kNmatrix = 4;
932   Int_t   matrix[kNmatrix];
933   gMC->Matrix(matrix[0], 100.0,   0.0,  90.0,  90.0,  10.0,   0.0);
934   gMC->Matrix(matrix[1],  80.0,   0.0,  90.0,  90.0,  10.0, 180.0);
935   gMC->Matrix(matrix[2],   0.0,   0.0,  90.0,  90.0,  90.0,   0.0);
936   gMC->Matrix(matrix[3], 180.0,   0.0,  90.0,  90.0,  90.0, 180.0);
937
938   AliTRDCommonParam *commonParam = AliTRDCommonParam::Instance();
939   if (!commonParam) {
940     AliError("Could not get common parameters\n");
941     return;
942   }
943     
944   //
945   // The cooling arterias
946   //
947
948   // Width of the cooling arterias
949   const Float_t kCOLwid  =  0.8; 
950   // Height of the cooling arterias
951   const Float_t kCOLhgt  =  6.5;
952   // Positioning of the cooling 
953   const Float_t kCOLposx =  1.8;
954   const Float_t kCOLposz = -0.1;
955   // Thickness of the walls of the cooling arterias
956   const Float_t kCOLthk  =  0.1;
957   const Int_t   kNparCOL =  3;
958   Float_t parCOL[kNparCOL];
959   parCOL[0]  = kCOLwid   /2.0;
960   parCOL[1]  = fgkSlength/2.0;
961   parCOL[2]  = kCOLhgt   /2.0;
962   gMC->Gsvolu("UTCL","BOX ",idtmed[1308-1],parCOL,kNparCOL);
963   parCOL[0] -= kCOLthk;
964   parCOL[1]  = fgkSlength/2.0;
965   parCOL[2] -= kCOLthk;
966   gMC->Gsvolu("UTCW","BOX ",idtmed[1314-1],parCOL,kNparCOL);
967
968   xpos  = 0.0;
969   ypos  = 0.0;
970   zpos  = 0.0;
971   gMC->Gspos("UTCW",1,"UTCL", xpos,ypos,zpos,0,"ONLY");
972
973   for (iplan = 1; iplan < kNplan; iplan++) { 
974
975     xpos  = fCwidth[iplan]/2.0 + kCOLwid/2.0 + kCOLposx;
976     ypos  = 0.0;
977     zpos  = fgkVrocsm + fgkSMpltT + kCOLhgt/2.0 - fgkSheight/2.0 + kCOLposz 
978           + iplan * (fgkCH + fgkVspace);
979     gMC->Gspos("UTCL",iplan       ,"UTI1", xpos,ypos,zpos,matrix[0],"ONLY");
980     gMC->Gspos("UTCL",iplan+kNplan,"UTI1",-xpos,ypos,zpos,matrix[1],"ONLY");
981
982   }
983
984   // The upper most layer (reaching into TOF acceptance)
985   xpos  = fCwidth[5]/2.0 - kCOLhgt/2.0 - 1.3;
986   ypos  = 0.0;
987   zpos  = fgkSheight/2.0 - fgkSMpltT - 0.4 - kCOLwid/2.0; 
988   gMC->Gspos("UTCL",6       ,"UTI1", xpos,ypos,zpos,matrix[3],"ONLY");
989   gMC->Gspos("UTCL",6+kNplan,"UTI1",-xpos,ypos,zpos,matrix[3],"ONLY");
990
991   //
992   // The power bars
993   //
994
995   const Float_t kPWRwid  =  0.6;
996   const Float_t kPWRhgt  =  5.0;
997   const Float_t kPWRposx =  1.4;
998   const Float_t kPWRposz =  1.9;
999   const Int_t   kNparPWR =  3;
1000   Float_t parPWR[kNparPWR];
1001   parPWR[0] = kPWRwid   /2.0;
1002   parPWR[1] = fgkSlength/2.0;
1003   parPWR[2] = kPWRhgt   /2.0;
1004   gMC->Gsvolu("UTPW","BOX ",idtmed[1325-1],parPWR,kNparPWR);
1005   
1006   for (iplan = 1; iplan < kNplan; iplan++) { 
1007     
1008     xpos  = fCwidth[iplan]/2.0 + kPWRwid/2.0 + kPWRposx;
1009     ypos  = 0.0;
1010     zpos  = fgkVrocsm + fgkSMpltT + kPWRhgt/2.0 - fgkSheight/2.0 + kPWRposz 
1011           + iplan * (fgkCH + fgkVspace);
1012     gMC->Gspos("UTPW",iplan       ,"UTI1", xpos,ypos,zpos,matrix[0],"ONLY");
1013     gMC->Gspos("UTPW",iplan+kNplan,"UTI1",-xpos,ypos,zpos,matrix[1],"ONLY");
1014
1015   }
1016
1017   // The upper most layer (reaching into TOF acceptance)
1018   xpos  = fCwidth[5]/2.0 + kPWRhgt/2.0 - 1.3;
1019   ypos  = 0.0;
1020   zpos  = fgkSheight/2.0 - fgkSMpltT - 0.6 - kPWRwid/2.0; 
1021   gMC->Gspos("UTPW",6       ,"UTI1", xpos,ypos,zpos,matrix[3],"ONLY");
1022   gMC->Gspos("UTPW",6+kNplan,"UTI1",-xpos,ypos,zpos,matrix[3],"ONLY");
1023
1024   //
1025   // The volumes for the services at the chambers
1026   //
1027
1028   const Int_t kNparServ = 3;
1029   Float_t parServ[kNparServ];
1030
1031   for (icham = 0; icham < kNcham; icham++) {
1032     for (iplan = 0; iplan < kNplan; iplan++) {
1033
1034       Int_t iDet = GetDetectorSec(iplan,icham);
1035
1036       sprintf(cTagV,"UU%02d",iDet);
1037       parServ[0] = fCwidth[iplan]        /2.0;
1038       parServ[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
1039       parServ[2] = fgkVspace             /2.0 - 0.742/2.0; 
1040       fChamberUUboxd[iDet][0] = parServ[0];
1041       fChamberUUboxd[iDet][1] = parServ[1];
1042       fChamberUUboxd[iDet][2] = parServ[2];
1043       gMC->Gsvolu(cTagV,"BOX",idtmed[1302-1],parServ,kNparServ);
1044
1045       xpos  = 0.0;
1046       ypos  = fClength[iplan][0] + fClength[iplan][1] + fClength[iplan][2]/2.0;
1047       for (Int_t ic = 0; ic < icham; ic++) {
1048         ypos -= fClength[iplan][ic];        
1049       }
1050       ypos -= fClength[iplan][icham]/2.0;
1051       zpos  = fgkVrocsm + fgkSMpltT + fgkCH + fgkVspace/2.0 - fgkSheight/2.0 
1052             + iplan * (fgkCH + fgkVspace);
1053       zpos -= 0.742/2.0;
1054       fChamberUUorig[iDet][0] = xpos;
1055       fChamberUUorig[iDet][1] = ypos;
1056       fChamberUUorig[iDet][2] = zpos;
1057
1058     }
1059   }
1060
1061   //
1062   // The cooling pipes inside the service volumes
1063   //
1064
1065   const Int_t kNparTube = 3;
1066   Float_t parTube[kNparTube];
1067   // The cooling pipes
1068   parTube[0] = 0.0;
1069   parTube[1] = 0.0;
1070   parTube[2] = 0.0;
1071   gMC->Gsvolu("UTCP","TUBE",idtmed[1324-1],parTube,0);
1072   // The cooling water
1073   parTube[0] =  0.0;
1074   parTube[1] =  0.2/2.0;
1075   parTube[2] = -1.;
1076   gMC->Gsvolu("UTCH","TUBE",idtmed[1314-1],parTube,kNparTube);
1077   // Water inside the cooling pipe
1078   xpos = 0.0;
1079   ypos = 0.0;
1080   zpos = 0.0;
1081   gMC->Gspos("UTCH",1,"UTCP",xpos,ypos,zpos,0,"ONLY");
1082
1083   // Position the cooling pipes in the mother volume
1084   const Int_t kNpar = 3;
1085   Float_t par[kNpar];
1086   for (icham = 0; icham < kNcham;   icham++) {
1087     for (iplan = 0; iplan < kNplan; iplan++) {
1088       Int_t   iDet    = GetDetectorSec(iplan,icham);
1089       Int_t   iCopy   = GetDetector(iplan,icham,0) * 100;
1090       Int_t   nMCMrow = commonParam->GetRowMax(iplan,icham,0);
1091       Float_t ySize   = (GetChamberLength(iplan,icham) - 2.0*fgkRpadW) 
1092                       / ((Float_t) nMCMrow);
1093       sprintf(cTagV,"UU%02d",iDet);
1094       for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
1095         xpos   = 0.0;
1096         ypos   = (0.5 + iMCMrow) * ySize - 1.9 
1097                - fClength[iplan][icham]/2.0 + fgkHspace/2.0;
1098         zpos   = 0.0 + 0.742/2.0;                 
1099         par[0] = 0.0;
1100         par[1] = 0.3/2.0; // Thickness of the cooling pipes
1101         par[2] = fCwidth[iplan]/2.0;
1102         gMC->Gsposp("UTCP",iCopy+iMCMrow,cTagV,xpos,ypos,zpos
1103                           ,matrix[2],"ONLY",par,kNpar);
1104       }
1105     }
1106   }
1107
1108   //
1109   // The power lines
1110   //
1111
1112   // The copper power lines
1113   parTube[0] = 0.0;
1114   parTube[1] = 0.0;
1115   parTube[2] = 0.0;
1116   gMC->Gsvolu("UTPL","TUBE",idtmed[1305-1],parTube,0);
1117
1118   // Position the power lines in the mother volume
1119   for (icham = 0; icham < kNcham;   icham++) {
1120     for (iplan = 0; iplan < kNplan; iplan++) {
1121       Int_t   iDet    = GetDetectorSec(iplan,icham);
1122       Int_t   iCopy   = GetDetector(iplan,icham,0) * 100;
1123       Int_t   nMCMrow = commonParam->GetRowMax(iplan,icham,0);
1124       Float_t ySize   = (GetChamberLength(iplan,icham) - 2.0*fgkRpadW) 
1125                       / ((Float_t) nMCMrow);
1126       sprintf(cTagV,"UU%02d",iDet);
1127       for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
1128         xpos   = 0.0;
1129         ypos   = (0.5 + iMCMrow) * ySize - 1.0 
1130                - fClength[iplan][icham]/2.0 + fgkHspace/2.0;
1131         zpos   = -0.4 + 0.742/2.0;
1132         par[0] = 0.0;
1133         par[1] = 0.2/2.0; // Thickness of the power lines
1134         par[2] = fCwidth[iplan]/2.0;
1135         gMC->Gsposp("UTPL",iCopy+iMCMrow,cTagV,xpos,ypos,zpos
1136                           ,matrix[2],"ONLY",par,kNpar);
1137       }
1138     }
1139   }
1140
1141   //
1142   // The MCMs
1143   //
1144
1145   const Float_t kMCMx    = 3.0;
1146   const Float_t kMCMy    = 3.0;
1147   const Float_t kMCMz    = 0.3;
1148
1149   const Float_t kMCMpcTh = 0.1;
1150   const Float_t kMCMcuTh = 0.0215;
1151   const Float_t kMCMsiTh = 0.003;
1152   const Float_t kMCMcoTh = 0.1549;
1153
1154   // The mother volume for the MCMs (air)
1155   const Int_t kNparMCM = 3;
1156   Float_t parMCM[kNparMCM];
1157   parMCM[0] = kMCMx   /2.0;
1158   parMCM[1] = kMCMy   /2.0;
1159   parMCM[2] = kMCMz   /2.0;
1160   gMC->Gsvolu("UMCM","BOX",idtmed[1302-1],parMCM,kNparMCM);
1161
1162   // The MCM carrier G10 layer
1163   parMCM[0] = kMCMx   /2.0;
1164   parMCM[1] = kMCMy   /2.0;
1165   parMCM[2] = kMCMpcTh/2.0;
1166   gMC->Gsvolu("UMC1","BOX",idtmed[1319-1],parMCM,kNparMCM);
1167   // The MCM carrier Cu layer
1168   parMCM[0] = kMCMx   /2.0;
1169   parMCM[1] = kMCMy   /2.0;
1170   parMCM[2] = kMCMcuTh/2.0;
1171   gMC->Gsvolu("UMC2","BOX",idtmed[1318-1],parMCM,kNparMCM);
1172   // The silicon of the chips
1173   parMCM[0] = kMCMx   /2.0;
1174   parMCM[1] = kMCMy   /2.0;
1175   parMCM[2] = kMCMsiTh/2.0;
1176   gMC->Gsvolu("UMC3","BOX",idtmed[1320-1],parMCM,kNparMCM);
1177   // The aluminum of the cooling plates
1178   parMCM[0] = kMCMx   /2.0;
1179   parMCM[1] = kMCMy   /2.0;
1180   parMCM[2] = kMCMcoTh/2.0;
1181   gMC->Gsvolu("UMC4","BOX",idtmed[1324-1],parMCM,kNparMCM);
1182
1183   // Put the MCM material inside the MCM mother volume
1184   xpos  =  0.0;
1185   ypos  =  0.0;
1186   zpos  = -kMCMz   /2.0 + kMCMpcTh/2.0;
1187   gMC->Gspos("UMC1",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
1188   zpos +=  kMCMpcTh/2.0 + kMCMcuTh/2.0;
1189   gMC->Gspos("UMC2",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
1190   zpos +=  kMCMcuTh/2.0 + kMCMsiTh/2.0;
1191   gMC->Gspos("UMC3",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
1192   zpos +=  kMCMsiTh/2.0 + kMCMcoTh/2.0;
1193   gMC->Gspos("UMC4",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
1194
1195   // Position the MCMs in the mother volume
1196   for (icham = 0; icham < kNcham;   icham++) {
1197     for (iplan = 0; iplan < kNplan; iplan++) {
1198       Int_t   iDet    = GetDetectorSec(iplan,icham);
1199       Int_t   iCopy   = GetDetector(iplan,icham,0) * 1000;
1200       Int_t   nMCMrow = commonParam->GetRowMax(iplan,icham,0);
1201       Float_t ySize   = (GetChamberLength(iplan,icham) - 2.0*fgkRpadW) 
1202                       / ((Float_t) nMCMrow);
1203       Int_t   nMCMcol = 8;
1204       Float_t xSize   = (GetChamberWidth(iplan)        - 2.0*fgkCpadW)
1205                       / ((Float_t) nMCMcol);
1206       sprintf(cTagV,"UU%02d",iDet);
1207       for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
1208         for (Int_t iMCMcol = 0; iMCMcol < nMCMcol; iMCMcol++) {
1209           xpos   = (0.5 + iMCMcol) * xSize + 1.0 
1210                  - fCwidth[iplan]/2.0;
1211           ypos   = (0.5 + iMCMrow) * ySize + 1.0 
1212                  - fClength[iplan][icham]/2.0 + fgkHspace/2.0;
1213           zpos   = -0.4 + 0.742/2.0;
1214           par[0] = 0.0;
1215           par[1] = 0.2/2.0; // Thickness of the power lines
1216           par[2] = fCwidth[iplan]/2.0;
1217           gMC->Gspos("UMCM",iCopy+iMCMrow*10+iMCMcol,cTagV
1218                            ,xpos,ypos,zpos,0,"ONLY");
1219         }
1220       }
1221
1222     }
1223   }
1224
1225 }
1226
1227 //_____________________________________________________________________________
1228 void AliTRDgeometry::GroupChamber(Int_t iplan, Int_t icham, Int_t *idtmed)
1229 {
1230   //
1231   // Group volumes UA, UD, UF, UU in a single chamber (Air)
1232   // UA, UD, UF, UU are boxes
1233   // UT will be a box
1234   //
1235
1236   const Int_t kNparCha = 3;
1237
1238   Int_t iDet = GetDetectorSec(iplan,icham);
1239
1240   Float_t xyzMin[3];
1241   Float_t xyzMax[3];
1242   Float_t xyzOrig[3];
1243   Float_t xyzBoxd[3];
1244
1245   Char_t  cTagV[5];
1246   Char_t  cTagM[5];
1247
1248   for (Int_t i = 0; i < 3; i++) {
1249     xyzMin[i] = +9999.0; 
1250     xyzMax[i] = -9999.0;
1251   }
1252
1253   for (Int_t i = 0; i < 3; i++) {
1254
1255     xyzMin[i] = TMath::Min(xyzMin[i],fChamberUAorig[iDet][i]-fChamberUAboxd[iDet][i]);
1256     xyzMax[i] = TMath::Max(xyzMax[i],fChamberUAorig[iDet][i]+fChamberUAboxd[iDet][i]);
1257
1258     xyzMin[i] = TMath::Min(xyzMin[i],fChamberUDorig[iDet][i]-fChamberUDboxd[iDet][i]);
1259     xyzMax[i] = TMath::Max(xyzMax[i],fChamberUDorig[iDet][i]+fChamberUDboxd[iDet][i]);
1260
1261     xyzMin[i] = TMath::Min(xyzMin[i],fChamberUForig[iDet][i]-fChamberUFboxd[iDet][i]);
1262     xyzMax[i] = TMath::Max(xyzMax[i],fChamberUForig[iDet][i]+fChamberUFboxd[iDet][i]);
1263
1264     xyzMin[i] = TMath::Min(xyzMin[i],fChamberUUorig[iDet][i]-fChamberUUboxd[iDet][i]);
1265     xyzMax[i] = TMath::Max(xyzMax[i],fChamberUUorig[iDet][i]+fChamberUUboxd[iDet][i]);
1266
1267     xyzOrig[i] = 0.5*(xyzMax[i]+xyzMin[i]);
1268     xyzBoxd[i] = 0.5*(xyzMax[i]-xyzMin[i]);
1269
1270   }
1271   
1272   sprintf(cTagM,"UT%02d",iDet);
1273   gMC->Gsvolu(cTagM,"BOX ",idtmed[1302-1],xyzBoxd,kNparCha);
1274
1275   sprintf(cTagV,"UA%02d",iDet);
1276   gMC->Gspos(cTagV,1,cTagM
1277             ,fChamberUAorig[iDet][0]-xyzOrig[0]
1278             ,fChamberUAorig[iDet][1]-xyzOrig[1]
1279             ,fChamberUAorig[iDet][2]-xyzOrig[2]
1280             ,0,"ONLY");
1281
1282   sprintf(cTagV,"UZ%02d",iDet);
1283   gMC->Gspos(cTagV,1,cTagM
1284             ,fChamberUAorig[iDet][0]-xyzOrig[0] + fChamberUAboxd[iDet][0] - fgkCroW/2.0
1285             ,fChamberUAorig[iDet][1]-xyzOrig[1]
1286             ,fChamberUAorig[iDet][2]-xyzOrig[2] + fgkCraH/2.0 + fgkCdrH/2.0 - fgkCalW/2.0
1287             ,0,"ONLY");
1288   gMC->Gspos(cTagV,2,cTagM
1289             ,fChamberUAorig[iDet][0]-xyzOrig[0] - fChamberUAboxd[iDet][0] + fgkCroW/2.0
1290             ,fChamberUAorig[iDet][1]-xyzOrig[1]
1291             ,fChamberUAorig[iDet][2]-xyzOrig[2] + fgkCraH/2.0 + fgkCdrH/2.0 - fgkCalW/2.0
1292             ,0,"ONLY");
1293
1294   sprintf(cTagV,"UD%02d",iDet);
1295   gMC->Gspos(cTagV,1,cTagM
1296             ,fChamberUDorig[iDet][0]-xyzOrig[0]
1297             ,fChamberUDorig[iDet][1]-xyzOrig[1]
1298             ,fChamberUDorig[iDet][2]-xyzOrig[2]
1299             ,0,"ONLY");
1300
1301   sprintf(cTagV,"UF%02d",iDet);
1302   gMC->Gspos(cTagV,1,cTagM
1303             ,fChamberUForig[iDet][0]-xyzOrig[0]
1304             ,fChamberUForig[iDet][1]-xyzOrig[1]
1305             ,fChamberUForig[iDet][2]-xyzOrig[2]
1306             ,0,"ONLY");
1307   
1308   sprintf(cTagV,"UU%02d",iDet);
1309   gMC->Gspos(cTagV,1,cTagM
1310             ,fChamberUUorig[iDet][0]-xyzOrig[0]
1311             ,fChamberUUorig[iDet][1]-xyzOrig[1]
1312             ,fChamberUUorig[iDet][2]-xyzOrig[2]
1313             ,0,"ONLY");
1314
1315   sprintf(cTagV,"UT%02d",iDet);
1316   gMC->Gspos(cTagV,1,"UTI1"
1317             ,xyzOrig[0]
1318             ,xyzOrig[1]
1319             ,xyzOrig[2]
1320             ,0,"ONLY");
1321
1322 }
1323
1324 //_____________________________________________________________________________
1325 Bool_t AliTRDgeometry::Rotate(Int_t d, Double_t *pos, Double_t *rot) const
1326 {
1327   //
1328   // Rotates all chambers in the position of sector 0 and transforms
1329   // the coordinates in the ALICE restframe <pos> into the 
1330   // corresponding local frame <rot>.
1331   //
1332
1333   Int_t sector = GetSector(d);
1334
1335   rot[0] =  pos[0] * fRotA11[sector] + pos[1] * fRotA12[sector];
1336   rot[1] = -pos[0] * fRotA21[sector] + pos[1] * fRotA22[sector];
1337   rot[2] =  pos[2];
1338
1339   return kTRUE;
1340
1341 }
1342
1343 //_____________________________________________________________________________
1344 Bool_t AliTRDgeometry::RotateBack(Int_t d, Double_t *rot, Double_t *pos) const
1345 {
1346   //
1347   // Rotates a chambers from the position of sector 0 into its
1348   // original position and transforms the corresponding local frame 
1349   // coordinates <rot> into the coordinates of the ALICE restframe <pos>.
1350   //
1351
1352   Int_t sector = GetSector(d);
1353
1354   pos[0] =  rot[0] * fRotB11[sector] + rot[1] * fRotB12[sector];
1355   pos[1] = -rot[0] * fRotB21[sector] + rot[1] * fRotB22[sector];
1356   pos[2] =  rot[2];
1357
1358   return kTRUE;
1359
1360 }
1361
1362 //_____________________________________________________________________________
1363 Int_t AliTRDgeometry::GetDetectorSec(Int_t p, Int_t c)
1364 {
1365   //
1366   // Convert plane / chamber into detector number for one single sector
1367   //
1368
1369   return (p + c * fgkNplan);
1370
1371 }
1372
1373 //_____________________________________________________________________________
1374 Int_t AliTRDgeometry::GetDetector(Int_t p, Int_t c, Int_t s)
1375 {
1376   //
1377   // Convert plane / chamber / sector into detector number
1378   //
1379
1380   return (p + c * fgkNplan + s * fgkNplan * fgkNcham);
1381
1382 }
1383
1384 //_____________________________________________________________________________
1385 Int_t AliTRDgeometry::GetPlane(Int_t d) const
1386 {
1387   //
1388   // Reconstruct the plane number from the detector number
1389   //
1390
1391   return ((Int_t) (d % fgkNplan));
1392
1393 }
1394
1395 //_____________________________________________________________________________
1396 Int_t AliTRDgeometry::GetChamber(Int_t d) const
1397 {
1398   //
1399   // Reconstruct the chamber number from the detector number
1400   //
1401
1402   return ((Int_t) (d % (fgkNplan * fgkNcham)) / fgkNplan);
1403
1404 }
1405
1406 //_____________________________________________________________________________
1407 Int_t AliTRDgeometry::GetSector(Int_t d) const
1408 {
1409   //
1410   // Reconstruct the sector number from the detector number
1411   //
1412
1413   return ((Int_t) (d / (fgkNplan * fgkNcham)));
1414
1415 }
1416
1417 //_____________________________________________________________________________
1418 Int_t AliTRDgeometry::GetPadRowFromMCM(Int_t irob, Int_t imcm) const
1419 {
1420
1421   // return on which row this mcm sits 
1422
1423   return fgkMCMrow*(irob/2) + imcm/fgkMCMrow;
1424
1425 ;
1426 }
1427
1428 //_____________________________________________________________________________
1429 Int_t AliTRDgeometry::GetPadColFromADC(Int_t irob, Int_t imcm, Int_t iadc) const
1430 {
1431   //
1432   // return which pad is connected to this adc channel.
1433   //
1434   // ADC channels 2 to 19 are connected directly to a pad via PASA.
1435   // ADC channels 0, 1 and 20 are not connected to the PASA on this MCM.
1436   // So the mapping (for MCM 0 on ROB 0 at least) is
1437   //
1438   // ADC channel  :   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
1439   // Pad          :   x  x 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0  x
1440   // Func. returns:  19 18 17 16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0 -1
1441   //
1442   // Here we assume that 21 ADC channels are transmitted. Maybe it will only be
1443   // 18 later on!!!
1444   //
1445   // This function maps also correctly the channels that cross from MCM to MCM
1446   // (ADC channels 0, 1, 20).
1447   //
1448
1449   return (17-(iadc-2)) + (imcm%fgkMCMrow)*fgkPadmax + GetRobSide(irob)*fgkColmax/2;
1450
1451 }
1452
1453 //_____________________________________________________________________________
1454 Int_t AliTRDgeometry::GetMCMfromPad(Int_t irow, Int_t icol) const
1455 {
1456
1457   // return on which mcm this pad is
1458
1459   if ( irow < 0 || icol < 0 || irow > fgkRowmaxC1 || icol > fgkColmax ) return -1;
1460
1461   return (icol%(fgkColmax/2))/fgkPadmax + fgkMCMrow*(irow%fgkMCMrow);
1462
1463 }
1464
1465 //_____________________________________________________________________________
1466 Int_t AliTRDgeometry::GetROBfromPad(Int_t irow, Int_t icol) const
1467 {
1468
1469   // return on which rob this pad is
1470
1471   return (irow/fgkMCMrow)*2 + GetColSide(icol);
1472
1473 }
1474
1475 //_____________________________________________________________________________
1476 Int_t AliTRDgeometry::GetRobSide(Int_t irob) const
1477 {
1478
1479   // return on which side this rob sits (A side = 0, B side = 1)
1480
1481   if ( irob < 0 || irob >= fgkROBmaxC1 ) return -1;
1482
1483   return irob%2;
1484
1485 }
1486
1487 //_____________________________________________________________________________
1488 Int_t AliTRDgeometry::GetColSide(Int_t icol) const
1489 {
1490
1491   // return on which side this column sits (A side = 0, B side = 1)
1492
1493   if ( icol < 0 || icol >= fgkColmax ) return -1;
1494
1495   return icol/(fgkColmax/2);
1496
1497 }
1498
1499 //_____________________________________________________________________________
1500 AliTRDgeometry *AliTRDgeometry::GetGeometry(AliRunLoader *runLoader)
1501 {
1502   //
1503   // Load the geometry from the galice file
1504   //
1505
1506   if (!runLoader) {
1507     runLoader = AliRunLoader::GetRunLoader();
1508   }
1509   if (!runLoader) {
1510     AliErrorGeneral("AliTRDgeometry::GetGeometry","No run loader");
1511     return NULL;
1512   }
1513
1514   TDirectory *saveDir = gDirectory;
1515   runLoader->CdGAFile();
1516
1517   // Try from the galice.root file
1518   AliTRDgeometry *geom = (AliTRDgeometry *) gDirectory->Get("TRDgeometry");
1519
1520   if (!geom) {
1521     // If it is not in the file, try to get it from the run loader 
1522     if (runLoader->GetAliRun()) {
1523       AliTRD *trd = (AliTRD *) runLoader->GetAliRun()->GetDetector("TRD");
1524       if (trd) geom = trd->GetGeometry();
1525     }
1526   }
1527   if (!geom) {
1528     AliErrorGeneral("AliTRDgeometry::GetGeometry","Geometry not found");
1529     return NULL;
1530   }
1531
1532   saveDir->cd();
1533   return geom;
1534
1535 }
1536
1537 //_____________________________________________________________________________
1538 Bool_t AliTRDgeometry::ReadGeoMatrices()
1539 {
1540   //
1541   // Read the geo matrices from the current gGeoManager for each TRD detector
1542   //
1543   // This fill three arrays of TGeoHMatrix, ordered by detector numbers 
1544   // for fast access:
1545   //   fMatrixArray:           Used for transformation local <-> global ???
1546   //   fMatrixCorrectionArray: Used for transformation local <-> tracking system
1547   //   fMatrixGeo:             Alignable objects
1548   //
1549
1550   if (!gGeoManager) {
1551     return kFALSE;
1552   }
1553
1554   fMatrixArray           = new TObjArray(kNdet); 
1555   fMatrixCorrectionArray = new TObjArray(kNdet);
1556   fMatrixGeo             = new TObjArray(kNdet);
1557
1558   for (Int_t iLayer = AliAlignObj::kTRD1; iLayer <= AliAlignObj::kTRD6; iLayer++) {
1559     for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
1560
1561       // Find the path to the different alignable objects (ROCs)
1562       UShort_t     volid   = AliAlignObj::LayerToVolUID(iLayer,iModule);
1563       const char  *symname = AliAlignObj::SymName(volid);
1564       TGeoPNEntry *pne     = gGeoManager->GetAlignableEntry(symname);
1565       const char  *path    = symname;
1566       if (pne) {
1567         path = pne->GetTitle();
1568       }
1569       if (!gGeoManager->cd(path)) {
1570         return kFALSE;
1571       }
1572
1573       // Get the geo matrix of the current alignable object
1574       // and add it to the corresponding list
1575       TGeoHMatrix *matrix   = gGeoManager->GetCurrentMatrix();
1576       Int_t        iplane   = iLayer - AliAlignObj::kTRD1;
1577       Int_t        isector  = iModule / Ncham();
1578       Int_t        ichamber = iModule % Ncham();
1579       Int_t        idet     = GetDetector(iplane,ichamber,isector);
1580       fMatrixGeo->AddAt(new TGeoHMatrix(* matrix),idet);
1581
1582       // Construct the geo matrix for the local <-> global transformation
1583       // and add it to the corresponding list.
1584       // In addition to the original geo matrix also a rotation of the
1585       // kind z-x-y to x-y--z is applied.
1586       TGeoRotation rotMatrixA;
1587       rotMatrixA.RotateY(90); 
1588       rotMatrixA.RotateX(90);
1589       TGeoHMatrix matrixGlobal(rotMatrixA.Inverse());
1590       matrixGlobal.MultiplyLeft(matrix);
1591       fMatrixArray->AddAt(new TGeoHMatrix(matrixGlobal),idet);
1592
1593       // Construct the geo matrix for the cluster transformation
1594       // and add it to the corresponding list.
1595       // In addition to the original geo matrix also a rotation of the
1596       // kind x-y--z to z-x-y and a rotation by the sector angle is applied.
1597       Double_t sectorAngle = 20.0 * (isector % 18) + 10.0;
1598       TGeoHMatrix rotMatrixB(rotMatrixA.Inverse());
1599       rotMatrixB.MultiplyLeft(matrix);
1600       TGeoHMatrix rotSector;
1601       rotSector.RotateZ(sectorAngle);
1602       rotMatrixB.MultiplyLeft(&rotSector);      
1603       fMatrixCorrectionArray->AddAt(new TGeoHMatrix(rotMatrixB),idet);
1604
1605     }    
1606   }
1607
1608   return kTRUE;
1609
1610 }
1611