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