a16e99aae7008fa3bf2cc4765a49d04c0608a32f
[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 /*
17 $Log$
18 Revision 1.1.4.1  2000/05/08 14:45:55  cblume
19 Bug fix in RotateBack(). Geometry update
20
21 Revision 1.1  2000/02/28 19:00:44  cblume
22 Add new TRD classes
23
24 */
25
26 ///////////////////////////////////////////////////////////////////////////////
27 //                                                                           //
28 //  TRD geometry class                                                       //
29 //                                                                           //
30 ///////////////////////////////////////////////////////////////////////////////
31
32 #include "AliTRDgeometry.h"
33 #include "AliTRDrecPoint.h"
34
35 ClassImp(AliTRDgeometry)
36
37 //_____________________________________________________________________________
38 AliTRDgeometry::AliTRDgeometry():AliGeometry()
39 {
40   //
41   // AliTRDgeometry default constructor
42   //
43
44   Init();
45
46 }
47
48 //_____________________________________________________________________________
49 AliTRDgeometry::~AliTRDgeometry()
50 {
51
52 }
53
54 //_____________________________________________________________________________
55 void AliTRDgeometry::Init()
56 {
57   //
58   // Initializes the geometry parameter
59   //
60
61   Int_t iplan;
62
63   // The width of the chambers
64   fCwidth[0]    =  99.6;
65   fCwidth[1]    = 104.1;
66   fCwidth[2]    = 108.5;
67   fCwidth[3]    = 112.9;
68   fCwidth[4]    = 117.4;
69   fCwidth[5]    = 121.8;
70
71   // The default pad dimensions
72   fRowPadSize  = 4.5;
73   fColPadSize  = 1.0;
74   fTimeBinSize = 0.1;
75
76   // The maximum number of pads
77   // and the position of pad 0,0,0 
78   // 
79   // chambers seen from the top:
80   //     +----------------------------+
81   //     |                            |
82   //     |                            |     ^
83   //     |                            | rphi|
84   //     |                            |     |
85   //     |0                           |     | 
86   //     +----------------------------+     +------>
87   //                                             z 
88   // chambers seen from the side:           ^
89   //     +----------------------------+ time|
90   //     |                            |     |
91   //     |0                           |     |
92   //     +----------------------------+     +------>
93   //                                             z
94   //                                             
95
96   // The pad column (rphi-direction)  
97   for (iplan = 0; iplan < kNplan; iplan++) {
98     fColMax[iplan] = 1 + TMath::Nint((fCwidth[iplan] - 2. * kCcthick) 
99                                                      / fColPadSize - 0.5);
100     fCol0[iplan]   = -fCwidth[iplan]/2. + kCcthick;
101   }
102
103   // The time bucket
104   fTimeMax = 1 + TMath::Nint(kDrThick / fTimeBinSize - 0.5);
105   for (iplan = 0; iplan < kNplan; iplan++) {
106     fTime0[iplan]  = kRmin + kCcframe/2. + kDrZpos - 0.5 * kDrThick
107                            + iplan * (kCheight + kCspace);
108   } 
109
110 }
111
112 //_____________________________________________________________________________
113 void AliTRDgeometry::CreateGeometry(Int_t *idtmed)
114 {
115   //
116   // Create the TRD geometry
117   //
118   // Author: Christoph Blume (C.Blume@gsi.de) 20/07/99
119   //
120   // The volumes:
121   //    TRD1-3     (Air)   --- The TRD mother volumes for one sector. 
122   //                           To be placed into the spaceframe.
123   //
124   //    UAFI(/M/O) (Al)    --- The aluminum frame of the inner(/middle/outer) chambers (readout)
125   //    UCFI(/M/O) (C)     --- The carbon frame of the inner(/middle/outer) chambers 
126   //                           (driftchamber + radiator)
127   //    UAII(/M/O) (Air)   --- The inner part of the readout of the inner(/middle/outer) chambers
128   //    UFII(/M/O) (Air)   --- The inner part of the chamner and radiator of the 
129   //                           inner(/middle/outer) chambers
130   //
131   // The material layers in one chamber:
132   //    UL01       (G10)   --- The gas seal of the radiator
133   //    UL02       (CO2)   --- The gas in the radiator
134   //    UL03       (PE)    --- The foil stack
135   //    UL04       (Mylar) --- Entrance window to the driftvolume and HV-cathode
136   //    UL05       (Xe)    --- The driftvolume
137   //    UL06       (Xe)    --- The amplification region
138   //    
139   //    UL07       (Cu)    --- The pad plane
140   //    UL08       (G10)   --- The Nomex honeycomb support structure
141   //    UL09       (Cu)    --- FEE and signal lines
142   //    UL10       (PE)    --- The cooling devices
143   //    UL11       (Water) --- The cooling water
144
145   const Int_t npar_cha = 3;
146
147   Float_t par_dum[3];
148   Float_t par_cha[npar_cha];
149
150   Float_t xpos, ypos, zpos;
151
152   // The aluminum frames - readout + electronics (Al)
153   // The inner chambers
154   gMC->Gsvolu("UAFI","BOX ",idtmed[1301-1],par_dum,0);
155   // The middle chambers
156   gMC->Gsvolu("UAFM","BOX ",idtmed[1301-1],par_dum,0);
157   // The outer chambers
158   gMC->Gsvolu("UAFO","BOX ",idtmed[1301-1],par_dum,0);
159
160   // The inner part of the aluminum frames (Air)
161   // The inner chambers
162   gMC->Gsvolu("UAII","BOX ",idtmed[1302-1],par_dum,0);
163   // The middle chambers
164   gMC->Gsvolu("UAIM","BOX ",idtmed[1302-1],par_dum,0);
165   // The outer chambers
166   gMC->Gsvolu("UAIO","BOX ",idtmed[1302-1],par_dum,0);
167
168   // The carbon frames - radiator + driftchamber (C)
169   // The inner chambers
170   gMC->Gsvolu("UCFI","BOX ",idtmed[1307-1],par_dum,0);
171   // The middle chambers
172   gMC->Gsvolu("UCFM","BOX ",idtmed[1307-1],par_dum,0);
173   // The outer chambers
174   gMC->Gsvolu("UCFO","BOX ",idtmed[1307-1],par_dum,0);
175
176   // The inner part of the carbon frames (Air)
177   // The inner chambers
178   gMC->Gsvolu("UCII","BOX ",idtmed[1302-1],par_dum,0);
179   // The middle chambers
180   gMC->Gsvolu("UCIM","BOX ",idtmed[1302-1],par_dum,0);
181   // The outer chambers
182   gMC->Gsvolu("UCIO","BOX ",idtmed[1302-1],par_dum,0);
183
184   // The material layers inside the chambers
185   par_cha[0] = -1.;
186   par_cha[1] = -1.;
187   // G10 layer (radiator seal)
188   par_cha[2] = kSeThick/2;
189   gMC->Gsvolu("UL01","BOX ",idtmed[1313-1],par_cha,npar_cha);
190   // CO2 layer (radiator)
191   par_cha[2] = kRaThick/2;
192   gMC->Gsvolu("UL02","BOX ",idtmed[1312-1],par_cha,npar_cha);
193   // PE layer (radiator)
194   par_cha[2] = kPeThick/2;
195   gMC->Gsvolu("UL03","BOX ",idtmed[1303-1],par_cha,npar_cha);
196   // Mylar layer (entrance window + HV cathode) 
197   par_cha[2] = kMyThick/2;
198   gMC->Gsvolu("UL04","BOX ",idtmed[1308-1],par_cha,npar_cha);
199   // Xe/Isobutane layer (drift volume, sensitive) 
200   par_cha[2] = kDrThick/2.;
201   gMC->Gsvolu("UL05","BOX ",idtmed[1309-1],par_cha,npar_cha);
202   // Xe/Isobutane layer (amplification volume, not sensitive)
203   par_cha[2] = kAmThick/2.;
204   gMC->Gsvolu("UL06","BOX ",idtmed[1309-1],par_cha,npar_cha);
205   
206   // Cu layer (pad plane)
207   par_cha[2] = kCuThick/2;
208   gMC->Gsvolu("UL07","BOX ",idtmed[1305-1],par_cha,npar_cha);
209   // G10 layer (support structure)
210   par_cha[2] = kSuThick/2;
211   gMC->Gsvolu("UL08","BOX ",idtmed[1313-1],par_cha,npar_cha);
212   // Cu layer (FEE + signal lines)
213   par_cha[2] = kFeThick/2;
214   gMC->Gsvolu("UL09","BOX ",idtmed[1305-1],par_cha,npar_cha);
215   // PE layer (cooling devices)
216   par_cha[2] = kCoThick/2;
217   gMC->Gsvolu("UL10","BOX ",idtmed[1303-1],par_cha,npar_cha);
218   // Water layer (cooling)
219   par_cha[2] = kWaThick/2;
220   gMC->Gsvolu("UL11","BOX ",idtmed[1314-1],par_cha,npar_cha);
221
222   // Position the layers in the chambers
223   xpos = 0;
224   ypos = 0;
225
226   // G10 layer (radiator seal)
227   zpos = kSeZpos;
228   gMC->Gspos("UL01",1,"UCII",xpos,ypos,zpos,0,"ONLY");
229   gMC->Gspos("UL01",2,"UCIM",xpos,ypos,zpos,0,"ONLY");
230   gMC->Gspos("UL01",3,"UCIO",xpos,ypos,zpos,0,"ONLY");
231   // CO2 layer (radiator)
232   zpos = kRaZpos;
233   gMC->Gspos("UL02",1,"UCII",xpos,ypos,zpos,0,"ONLY");
234   gMC->Gspos("UL02",2,"UCIM",xpos,ypos,zpos,0,"ONLY");
235   gMC->Gspos("UL02",3,"UCIO",xpos,ypos,zpos,0,"ONLY");
236   // PE layer (radiator)
237   zpos = 0;
238   gMC->Gspos("UL03",1,"UL02",xpos,ypos,zpos,0,"ONLY");
239   // Mylar layer (entrance window + HV cathode)   
240   zpos = kMyZpos;
241   gMC->Gspos("UL04",1,"UCII",xpos,ypos,zpos,0,"ONLY");
242   gMC->Gspos("UL04",2,"UCIM",xpos,ypos,zpos,0,"ONLY");
243   gMC->Gspos("UL04",3,"UCIO",xpos,ypos,zpos,0,"ONLY");
244   // Xe/Isobutane layer (drift volume) 
245   zpos = kDrZpos;
246   gMC->Gspos("UL05",1,"UCII",xpos,ypos,zpos,0,"ONLY");
247   gMC->Gspos("UL05",2,"UCIM",xpos,ypos,zpos,0,"ONLY");
248   gMC->Gspos("UL05",3,"UCIO",xpos,ypos,zpos,0,"ONLY");
249   // Xe/Isobutane layer (amplification volume)
250   zpos = kAmZpos;
251   gMC->Gspos("UL06",1,"UCII",xpos,ypos,zpos,0,"ONLY");
252   gMC->Gspos("UL06",2,"UCIM",xpos,ypos,zpos,0,"ONLY");
253   gMC->Gspos("UL06",3,"UCIO",xpos,ypos,zpos,0,"ONLY");
254
255   // Cu layer (pad plane)
256   zpos = kCuZpos;
257   gMC->Gspos("UL07",1,"UAII",xpos,ypos,zpos,0,"ONLY");
258   gMC->Gspos("UL07",2,"UAIM",xpos,ypos,zpos,0,"ONLY");
259   gMC->Gspos("UL07",3,"UAIO",xpos,ypos,zpos,0,"ONLY");
260   // G10 layer (support structure)
261   zpos = kSuZpos;
262   gMC->Gspos("UL08",1,"UAII",xpos,ypos,zpos,0,"ONLY");
263   gMC->Gspos("UL08",2,"UAIM",xpos,ypos,zpos,0,"ONLY");
264   gMC->Gspos("UL08",3,"UAIO",xpos,ypos,zpos,0,"ONLY");
265   // Cu layer (FEE + signal lines)
266   zpos = kFeZpos; 
267   gMC->Gspos("UL09",1,"UAII",xpos,ypos,zpos,0,"ONLY");
268   gMC->Gspos("UL09",2,"UAIM",xpos,ypos,zpos,0,"ONLY");
269   gMC->Gspos("UL09",3,"UAIO",xpos,ypos,zpos,0,"ONLY");
270   // PE layer (cooling devices)
271   zpos = kCoZpos;
272   gMC->Gspos("UL10",1,"UAII",xpos,ypos,zpos,0,"ONLY");
273   gMC->Gspos("UL10",2,"UAIM",xpos,ypos,zpos,0,"ONLY");
274   gMC->Gspos("UL10",3,"UAIO",xpos,ypos,zpos,0,"ONLY");
275   // Water layer (cooling)
276   zpos = kWaZpos;
277   gMC->Gspos("UL11",1,"UAII",xpos,ypos,zpos,0,"ONLY");
278   gMC->Gspos("UL11",1,"UAIM",xpos,ypos,zpos,0,"ONLY");
279   gMC->Gspos("UL11",1,"UAIO",xpos,ypos,zpos,0,"ONLY");
280
281 }
282
283 //_____________________________________________________________________________
284 Bool_t AliTRDgeometry::Local2Global(Int_t idet, Float_t *local, Float_t *global)
285 {
286   //
287   // Converts local pad-coordinates (row,col,time) into 
288   // global ALICE reference frame coordinates (x,y,z)
289   //
290
291   Int_t        icham     = GetChamber(idet);    // Chamber info (0-4)
292   Int_t        isect     = GetSector(idet);     // Sector info  (0-17)
293   Int_t        iplan     = GetPlane(idet);      // Plane info   (0-5)
294
295   return Local2Global(iplan,icham,isect,local,global);
296
297 }
298  
299 //_____________________________________________________________________________
300 Bool_t AliTRDgeometry::Local2Global(Int_t iplan, Int_t icham, Int_t isect
301                                   , Float_t *local, Float_t *global)
302 {
303   //
304   // Converts local pad-coordinates (row,col,time) into 
305   // global ALICE reference frame coordinates (x,y,z)
306   //
307
308   Int_t        idet      = GetDetector(iplan,icham,isect); // Detector number
309
310   Float_t      padRow    = local[0];                       // Pad Row position
311   Float_t      padCol    = local[1];                       // Pad Column position
312   Float_t      timeSlice = local[2];                       // Time "position"
313
314   Float_t      row0      = GetRow0(iplan,icham,isect);
315   Float_t      col0      = GetCol0(iplan);
316   Float_t      time0     = GetTime0(iplan);
317
318   Float_t      rot[3];
319
320   // calculate (x,y,z) position in rotated chamber
321   rot[0] = time0 + timeSlice * fTimeBinSize;
322   rot[1] = col0  + padCol    * fColPadSize;
323   rot[2] = row0  + padRow    * fRowPadSize;
324
325   // Rotate back to original position
326   return RotateBack(idet,rot,global);
327
328 }
329
330 //_____________________________________________________________________________
331 Bool_t AliTRDgeometry::Rotate(Int_t d, Float_t *pos, Float_t *rot)
332 {
333   //
334   // Rotates all chambers in the position of sector 0 and transforms
335   // the coordinates in the ALICE restframe <pos> into the 
336   // corresponding local frame <rot>.
337   //
338
339   Int_t   sector = GetSector(d);
340
341   Float_t phi    = -2.0 * kPI /  (Float_t) kNsect * ((Float_t) sector + 0.5);
342
343   rot[0] =  pos[0] * TMath::Cos(phi) + pos[1] * TMath::Sin(phi);
344   rot[1] = -pos[0] * TMath::Sin(phi) + pos[1] * TMath::Cos(phi);
345   rot[2] =  pos[2];
346
347   return kTRUE;
348
349 }
350
351 //_____________________________________________________________________________
352 Bool_t AliTRDgeometry::RotateBack(Int_t d, Float_t *rot, Float_t *pos)
353 {
354   //
355   // Rotates a chambers from the position of sector 0 into its
356   // original position and transforms the corresponding local frame 
357   // coordinates <rot> into the coordinates of the ALICE restframe <pos>.
358   //
359
360   Int_t   sector = GetSector(d);
361
362   Float_t phi    =  2.0 * kPI /  (Float_t) kNsect * ((Float_t) sector + 0.5);
363
364   pos[0] =  rot[0] * TMath::Cos(phi) + rot[1] * TMath::Sin(phi);
365   pos[1] = -rot[0] * TMath::Sin(phi) + rot[1] * TMath::Cos(phi);
366   pos[2] =  rot[2];
367
368   return kTRUE;
369
370 }
371
372 //_____________________________________________________________________________
373 Int_t AliTRDgeometry::GetDetector(Int_t p, Int_t c, Int_t s)
374 {
375   //
376   // Convert plane / chamber / sector into detector number
377   //
378
379   return (p + c * kNplan + s * kNplan * kNcham);
380
381 }
382
383 //_____________________________________________________________________________
384 Int_t AliTRDgeometry::GetPlane(Int_t d)
385 {
386   //
387   // Reconstruct the plane number from the detector number
388   //
389
390   return ((Int_t) (d % kNplan));
391
392 }
393
394 //_____________________________________________________________________________
395 Int_t AliTRDgeometry::GetChamber(Int_t d)
396 {
397   //
398   // Reconstruct the chamber number from the detector number
399   //
400
401   return ((Int_t) (d % (kNplan * kNcham)) / kNplan);
402
403 }
404
405 //_____________________________________________________________________________
406 Int_t AliTRDgeometry::GetSector(Int_t d)
407 {
408   //
409   // Reconstruct the sector number from the detector number
410   //
411
412   return ((Int_t) (d / (kNplan * kNcham)));
413
414 }
415
416 //_____________________________________________________________________________
417 void AliTRDgeometry::GetGlobal(const AliRecPoint *p, TVector3 &pos, TMatrix &mat)
418 {
419   // 
420   // Returns the global coordinate and error matrix of a AliTRDrecPoint
421   //
422
423   GetGlobal(p,pos);
424
425 }
426
427 //_____________________________________________________________________________
428 void AliTRDgeometry::GetGlobal(const AliRecPoint *p, TVector3 &pos)
429 {
430   // 
431   // Returns the global coordinate and error matrix of a AliTRDrecPoint
432   //
433
434   Int_t detector = ((AliTRDrecPoint *) p)->GetDetector();
435
436   Float_t global[3];
437   Float_t local[3];
438   local[0] = ((AliTRDrecPoint *) p)->GetLocalRow();
439   local[1] = ((AliTRDrecPoint *) p)->GetLocalCol();
440   local[2] = ((AliTRDrecPoint *) p)->GetLocalTime();
441
442   if (Local2Global(detector,local,global)) {
443     pos.SetX(global[0]);
444     pos.SetY(global[1]);
445     pos.SetZ(global[2]);
446   }
447   else {
448     pos.SetX(0.0);
449     pos.SetY(0.0);
450     pos.SetZ(0.0);
451   }
452
453 }