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