]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PHOS/AliPHOSGeometry.cxx
New AliSTARThit
[u/mrichter/AliRoot.git] / PHOS / AliPHOSGeometry.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 // Geometry class  for PHOS : singleton  
20 // The EMC modules are parametrized so that any configuration can be easily implemented 
21 // The title is used to identify the type of CPV used. So far only PPSD implemented
22 //                  
23 //*-- Author: Yves Schutz (SUBATECH)
24
25 // --- ROOT system ---
26
27 #include "TVector3.h"
28 #include "TRotation.h" 
29
30 // --- Standard library ---
31
32 #include <iostream.h>
33
34 // --- AliRoot header files ---
35
36 #include "AliPHOSGeometry.h"
37 #include "AliPHOSPpsdRecPoint.h"
38 #include "AliConst.h"
39
40 ClassImp(AliPHOSGeometry)
41
42   AliPHOSGeometry * AliPHOSGeometry::fGeom = 0 ;
43
44 //____________________________________________________________________________
45 AliPHOSGeometry::~AliPHOSGeometry(void)
46 {
47   // dtor
48
49   fRotMatrixArray->Delete() ; 
50   delete fRotMatrixArray ; 
51 }
52
53 //____________________________________________________________________________
54 Bool_t AliPHOSGeometry::AbsToRelNumbering(const Int_t AbsId, Int_t * relid)
55 {
56   // Converts the absolute numbering into the following array/
57   //  relid[0] = PHOS Module number 1:fNModules 
58   //  relid[1] = 0 if PbW04
59   //           = PPSD Module number 1:fNumberOfModulesPhi*fNumberOfModulesZ*2 (2->up and bottom level)
60   //  relid[2] = Row number inside a PHOS or PPSD module
61   //  relid[3] = Column number inside a PHOS or PPSD module
62
63   Bool_t rv  = kTRUE ; 
64   Float_t id = AbsId ;
65
66   Int_t phosmodulenumber = (Int_t)TMath:: Ceil( id / ( GetNPhi() * GetNZ() ) ) ; 
67   
68   if ( phosmodulenumber >  GetNModules() ) { // its a PPSD pad
69
70     id -=  GetNPhi() * GetNZ() *  GetNModules() ; 
71     Float_t tempo = 2 *  GetNumberOfModulesPhi() * GetNumberOfModulesZ() *  GetNumberOfPadsPhi() * GetNumberOfPadsZ() ; 
72     relid[0] = (Int_t)TMath::Ceil( id / tempo ) ; 
73     id -= ( relid[0] - 1 ) * tempo ;
74     relid[1] = (Int_t)TMath::Ceil( id / ( GetNumberOfPadsPhi() * GetNumberOfPadsZ() ) ) ; 
75     id -= ( relid[1] - 1 ) * GetNumberOfPadsPhi() * GetNumberOfPadsZ() ;
76     relid[2] = (Int_t)TMath::Ceil( id / GetNumberOfPadsPhi() ) ;
77     relid[3] = (Int_t) ( id - ( relid[2] - 1 )  * GetNumberOfPadsPhi() ) ; 
78   } 
79   else { // its a PW04 crystal
80
81     relid[0] = phosmodulenumber ;
82     relid[1] = 0 ;
83     id -= ( phosmodulenumber - 1 ) *  GetNPhi() * GetNZ() ; 
84     relid[2] = (Int_t)TMath::Ceil( id / GetNPhi() ) ;
85     relid[3] = (Int_t)( id - ( relid[2] - 1 ) * GetNPhi() ) ; 
86   } 
87   return rv ; 
88 }
89 //____________________________________________________________________________  
90 void AliPHOSGeometry::EmcModuleCoverage(const Int_t mod, Double_t & tm, Double_t & tM, Double_t & pm, Double_t & pM, Option_t * opt) 
91 {
92   // calculates the angular coverage in theta and phi of a EMC module
93
94  Double_t conv ; 
95   if ( opt == kRadian ) 
96     conv = 1. ; 
97   else if ( opt == kDegre )
98     conv = 180. / TMath::Pi() ; 
99   else {
100     cout << "<I>  AliPHOSGeometry::EmcXtalCoverage : " << opt << " unknown option; result in radian " << endl ; 
101     conv = 1. ;
102       }
103
104   Float_t phi =  GetPHOSAngle(mod) *  (TMath::Pi() / 180.)  ;  
105   Float_t y0  =  GetIPtoOuterCoverDistance() + GetUpperPlateThickness()
106                   + GetSecondUpperPlateThickness() + GetUpperCoolingPlateThickness()  ;  
107   
108   Double_t angle = TMath::ATan( GetCrystalSize(0)*GetNPhi() / (2 * y0) ) ;
109   phi = phi + 1.5 * TMath::Pi() ; // to follow the convention of the particle generator(PHOS is between 230 and 310 deg.)
110   Double_t max  = phi - angle ;
111   Double_t min   = phi + angle ;
112   pM = TMath::Max(max, min) * conv ;
113   pm = TMath::Min(max, min) * conv ; 
114   
115   angle =  TMath::ATan( GetCrystalSize(2)*GetNZ() / (2 * y0) ) ;
116   max  = TMath::Pi() / 2.  + angle ; // to follow the convention of the particle generator(PHOS is at 90 deg.)
117   min  = TMath::Pi() / 2.  - angle ;
118   tM = TMath::Max(max, min) * conv ;
119   tm = TMath::Min(max, min) * conv ; 
120  
121 }
122
123 //____________________________________________________________________________  
124 void AliPHOSGeometry::EmcXtalCoverage(Double_t & theta, Double_t & phi, Option_t * opt) 
125 {
126   // calculates the angular coverage in theta and phi of a single crystal in a EMC module
127
128   Double_t conv ; 
129   if ( opt == kRadian ) 
130     conv = 1. ; 
131   else if ( opt == kDegre )
132     conv = 180. / TMath::Pi() ; 
133   else {
134     cout << "<I>  AliPHOSGeometry::EmcXtalCoverage : " << opt << " unknown option; result in radian " << endl ; 
135     conv = 1. ;
136       }
137
138   Float_t y0   =  GetIPtoOuterCoverDistance() + GetUpperPlateThickness()
139     + GetSecondUpperPlateThickness() + GetUpperCoolingPlateThickness()  ;  
140   theta = 2 * TMath::ATan( GetCrystalSize(2) / (2 * y0) ) * conv ;
141   phi   = 2 * TMath::ATan( GetCrystalSize(0) / (2 * y0) ) * conv ;
142 }
143  
144
145 //____________________________________________________________________________
146 void AliPHOSGeometry::ImpactOnEmc(const Double_t theta, const Double_t phi, Int_t & ModuleNumber, Double_t & z, Double_t & x) 
147 {
148   // calculates the impact coordinates of a neutral particle  
149   // emitted in direction theta and phi in ALICE
150
151   // searches for the PHOS EMC module
152   ModuleNumber = 0 ; 
153   Double_t tm, tM, pm, pM ; 
154   Int_t index = 1 ; 
155   while ( ModuleNumber == 0 && index <= GetNModules() ) { 
156     EmcModuleCoverage(index, tm, tM, pm, pM) ; 
157     if ( (theta >= tm && theta <= tM) && (phi >= pm && phi <= pM ) ) 
158       ModuleNumber = index ; 
159     index++ ;    
160   }
161   if ( ModuleNumber != 0 ) {
162     Float_t phi0 =  GetPHOSAngle(ModuleNumber) *  (TMath::Pi() / 180.) + 1.5 * TMath::Pi()  ;  
163     Float_t y0  =  GetIPtoOuterCoverDistance() + GetUpperPlateThickness()
164       + GetSecondUpperPlateThickness() + GetUpperCoolingPlateThickness()  ;   
165     Double_t angle = phi - phi0; 
166     x = y0 * TMath::Tan(angle) ; 
167     angle = theta - TMath::Pi() / 2 ; 
168     z = y0 * TMath::Tan(angle) ; 
169   }
170 }
171
172 //____________________________________________________________________________
173 void AliPHOSGeometry::GetGlobal(const AliRecPoint* RecPoint, TVector3 & gpos, TMatrix & gmat)
174 {
175   // Calculates the ALICE global coordinates of a RecPoint and the error matrix
176  
177   AliPHOSRecPoint * tmpPHOS = (AliPHOSRecPoint *) RecPoint ;  
178   TVector3 localposition ;
179
180   tmpPHOS->GetLocalPosition(gpos) ;
181
182
183   if ( tmpPHOS->IsEmc() ) // it is a EMC crystal 
184     {  gpos.SetY( -(GetIPtoOuterCoverDistance() + GetUpperPlateThickness() +
185                     GetSecondUpperPlateThickness() + GetUpperCoolingPlateThickness()) ) ;  
186
187     }
188   else
189     { // it is a PPSD pad
190       AliPHOSPpsdRecPoint * tmpPpsd = (AliPHOSPpsdRecPoint *) RecPoint ;
191       if (tmpPpsd->GetUp() ) // it is an upper module
192         {
193           gpos.SetY(-( GetIPtoOuterCoverDistance() - GetMicromegas2Thickness() - 
194                        GetLeadToMicro2Gap() - GetLeadConverterThickness() -  
195                        GetMicro1ToLeadGap() - GetMicromegas1Thickness() / 2.0 )  ) ; 
196         } 
197       else // it is a lower module
198         gpos.SetY(-( GetIPtoOuterCoverDistance() - GetMicromegas2Thickness() / 2.0) ) ; 
199     }  
200
201   Float_t phi           = GetPHOSAngle( tmpPHOS->GetPHOSMod()) ; 
202   Double_t const kRADDEG = 180.0 / kPI ;
203   Float_t rphi          = phi / kRADDEG ; 
204   
205   TRotation rot ;
206   rot.RotateZ(-rphi) ; // a rotation around Z by angle  
207   
208   TRotation dummy = rot.Invert() ;  // to transform from original frame to rotate frame
209   gpos.Transform(rot) ; // rotate the baby 
210
211 }
212
213 //____________________________________________________________________________
214 void AliPHOSGeometry::GetGlobal(const AliRecPoint* RecPoint, TVector3 & gpos)
215 {
216   // Calculates the ALICE global coordinates of a RecPoint 
217
218   AliPHOSRecPoint * tmpPHOS = (AliPHOSRecPoint *) RecPoint ;  
219   TVector3 localposition ;
220   tmpPHOS->GetLocalPosition(gpos) ;
221
222
223   if ( tmpPHOS->IsEmc() ) // it is a EMC crystal 
224     {  gpos.SetY( -(GetIPtoOuterCoverDistance() + GetUpperPlateThickness() +
225                     GetSecondUpperPlateThickness() + GetUpperCoolingPlateThickness()) ) ;  
226     }
227   else
228     { // it is a PPSD pad
229       AliPHOSPpsdRecPoint * tmpPpsd = (AliPHOSPpsdRecPoint *) RecPoint ;
230       if (tmpPpsd->GetUp() ) // it is an upper module
231         {
232           gpos.SetY(-( GetIPtoOuterCoverDistance() - GetMicromegas2Thickness() - 
233                        GetLeadToMicro2Gap() - GetLeadConverterThickness() -  
234                        GetMicro1ToLeadGap() - GetMicromegas1Thickness() / 2.0 )  ) ; 
235         } 
236       else // it is a lower module
237         gpos.SetY(-( GetIPtoOuterCoverDistance() - GetMicromegas2Thickness() / 2.0) ) ; 
238     }  
239
240   Float_t phi           = GetPHOSAngle( tmpPHOS->GetPHOSMod()) ; 
241   Double_t const kRADDEG = 180.0 / kPI ;
242   Float_t rphi          = phi / kRADDEG ; 
243   
244   TRotation rot ;
245   rot.RotateZ(-rphi) ; // a rotation around Z by angle  
246   
247   TRotation dummy = rot.Invert() ;  // to transform from original frame to rotate frame
248   gpos.Transform(rot) ; // rotate the baby 
249 }
250
251 //____________________________________________________________________________
252 void AliPHOSGeometry::Init(void)
253 {
254   // Initializes the PHOS parameters
255   
256   fRotMatrixArray = new TObjArray(fNModules) ; 
257
258   cout << "PHOS geometry setup: parameters for option " << fName << " " << fTitle << endl ;
259   if ( ((strcmp( fName, "default" )) == 0)  || ((strcmp( fName, "GPS2" )) == 0) ) {
260     fInit     = kTRUE ; 
261     this->InitPHOS() ; 
262     this->InitPPSD() ;
263     this->SetPHOSAngles() ; 
264   }
265  else {
266    fInit = kFALSE ; 
267    cout << "PHOS Geometry setup: option not defined " << fName << endl ; 
268  }
269 }
270
271 //____________________________________________________________________________
272 void AliPHOSGeometry::InitPHOS(void)
273 {
274   // Initializes the EMC parameters
275
276   fNPhi     = 64 ; 
277   fNZ       = 64 ; 
278   fNModules =  5 ; 
279   
280   fPHOSAngle[0] = 0.0 ; // Module position angles are set in CreateGeometry()
281   fPHOSAngle[1] = 0.0 ;
282   fPHOSAngle[2] = 0.0 ;
283   fPHOSAngle[3] = 0.0 ;
284  
285   fXtlSize[0] =  2.2 ;
286   fXtlSize[1] = 18.0 ;
287   fXtlSize[2] =  2.2 ;
288
289   // all these numbers coming next are subject to changes
290
291   fOuterBoxThickness[0] = 2.8 ;
292   fOuterBoxThickness[1] = 5.0 ;      
293   fOuterBoxThickness[2] = 5.0 ;
294   
295   fUpperPlateThickness  = 4.0 ;
296   
297   fSecondUpperPlateThickness = 5.0 ; 
298   
299   fCrystalSupportHeight   = 6.95 ; 
300   fCrystalWrapThickness   = 0.01 ;
301   fCrystalHolderThickness = 0.005 ;
302   fModuleBoxThickness     = 2.0 ; 
303   fIPtoOuterCoverDistance = 447.0 ;      
304   fIPtoCrystalSurface     = 460.0 ;  
305   
306   fPinDiodeSize[0] = 1.71 ;   //Values given by Odd Harald feb 2000  
307   fPinDiodeSize[1] = 0.0280 ; // 0.0280 is the depth of active layer in the silicon     
308   fPinDiodeSize[2] = 1.61 ;    
309   
310   fUpperCoolingPlateThickness   = 0.06 ; 
311   fSupportPlateThickness        = 10.0 ;
312   fLowerThermoPlateThickness    =  3.0 ; 
313   fLowerTextolitPlateThickness  =  1.0 ;
314   fGapBetweenCrystals           = 0.03 ;
315   
316   fTextolitBoxThickness[0] = 1.5 ;  
317   fTextolitBoxThickness[1] = 0.0 ;   
318   fTextolitBoxThickness[2] = 3.0 ; 
319   
320   fAirThickness[0] =  1.56   ;
321   fAirThickness[1] = 20.5175 ;  
322   fAirThickness[2] =  2.48   ;  
323   
324   Float_t xtalModulePhiSize =  fNPhi * ( fXtlSize[0] + 2 * fGapBetweenCrystals ) ; 
325   Float_t xtalModuleZSize   =  fNZ * ( fXtlSize[2] + 2 * fGapBetweenCrystals ) ;
326   
327   // The next dimensions are calculated from the above parameters
328   
329   fOuterBoxSize[0] =  xtalModulePhiSize + 2 * ( fAirThickness[0] + fModuleBoxThickness
330                                                 + fTextolitBoxThickness[0] + fOuterBoxThickness[0] ) ; 
331   fOuterBoxSize[1] = ( fXtlSize[1] + fCrystalSupportHeight + fCrystalWrapThickness + fCrystalHolderThickness )
332     + 2 * (fAirThickness[1] +  fModuleBoxThickness + fTextolitBoxThickness[1] + fOuterBoxThickness[1] ) ;
333   fOuterBoxSize[2] =  xtalModuleZSize +  2 * ( fAirThickness[2] + fModuleBoxThickness 
334                                                + fTextolitBoxThickness[2] + fOuterBoxThickness[2] ) ; 
335   
336   fTextolitBoxSize[0]  = fOuterBoxSize[0] - 2 * fOuterBoxThickness[0] ;
337   fTextolitBoxSize[1]  = fOuterBoxSize[1] -  fOuterBoxThickness[1] - fUpperPlateThickness ;
338   fTextolitBoxSize[2]  = fOuterBoxSize[2] - 2 * fOuterBoxThickness[2] ;
339   
340   fAirFilledBoxSize[0] =  fTextolitBoxSize[0] - 2 * fTextolitBoxThickness[0] ; 
341   fAirFilledBoxSize[1] =  fTextolitBoxSize[1] - fSecondUpperPlateThickness ; 
342   fAirFilledBoxSize[2] =  fTextolitBoxSize[2] - 2 * fTextolitBoxThickness[2] ; 
343   
344 }
345
346 //____________________________________________________________________________
347 void AliPHOSGeometry::InitPPSD(void)
348 {
349   // Initializes the PPSD parameters
350     
351   fAnodeThickness           = 0.0009 ; 
352   fAvalancheGap             = 0.01 ; 
353   fCathodeThickness         = 0.0009 ;
354   fCompositeThickness       = 0.3 ; 
355   fConversionGap            = 0.6 ; 
356   fLeadConverterThickness   = 0.56 ; 
357   fLeadToMicro2Gap          = 0.1 ; 
358   fLidThickness             = 0.2 ; 
359   fMicro1ToLeadGap          = 0.1 ; 
360   fMicromegasWallThickness  = 0.6 ; 
361   fNumberOfModulesPhi       = 4 ; 
362   fNumberOfModulesZ         = 4 ; 
363   fNumberOfPadsPhi          = 24 ; 
364   fNumberOfPadsZ            = 24 ;   
365   fPCThickness              = 0.1 ; 
366   fPhiDisplacement          = 0.8 ;  
367   fZDisplacement            = 0.8 ;  
368
369   fMicromegas1Thickness   = fLidThickness + 2 * fCompositeThickness + fCathodeThickness + fPCThickness 
370                               + fAnodeThickness + fConversionGap + fAvalancheGap ; 
371   fMicromegas2Thickness   = fMicromegas1Thickness ; 
372
373
374   fPPSDModuleSize[0] = 38.0 ; 
375   fPPSDModuleSize[1] = fMicromegas1Thickness ; 
376   fPPSDModuleSize[2] = 38.0 ; 
377  
378   fPPSDBoxSize[0] = fNumberOfModulesPhi * fPPSDModuleSize[0] + 2 * fPhiDisplacement ;  
379   fPPSDBoxSize[1] = fMicromegas2Thickness + fMicromegas2Thickness + fLeadConverterThickness + fMicro1ToLeadGap + fLeadToMicro2Gap ;    
380   fPPSDBoxSize[2] = fNumberOfModulesZ *  fPPSDModuleSize[2] + 2 * fZDisplacement ;
381
382   fIPtoTopLidDistance     = fIPtoOuterCoverDistance -  fPPSDBoxSize[1] - 1. ;  
383   
384 }
385
386 //____________________________________________________________________________
387 AliPHOSGeometry *  AliPHOSGeometry::GetInstance() 
388
389   // Returns the pointer of the unique instance
390   
391   return (AliPHOSGeometry *) fGeom ; 
392 }
393
394 //____________________________________________________________________________
395 AliPHOSGeometry *  AliPHOSGeometry::GetInstance(const Text_t* name, const Text_t* title) 
396 {
397   // Returns the pointer of the unique instance
398
399   AliPHOSGeometry * rv = 0  ; 
400   if ( fGeom == 0 ) {
401     fGeom = new AliPHOSGeometry(name, title) ; 
402     rv = (AliPHOSGeometry * ) fGeom ; 
403   }
404   else {
405     if ( strcmp(fGeom->GetName(), name) != 0 ) {
406       cout << "AliPHOSGeometry <E> : current geometry is " << fGeom->GetName() << endl
407            << "                      you cannot call     " << name << endl ; 
408     }
409     else
410       rv = (AliPHOSGeometry *) fGeom ; 
411   } 
412   return rv ; 
413 }
414
415 //____________________________________________________________________________
416 Bool_t AliPHOSGeometry::RelToAbsNumbering(const Int_t * relid, Int_t &  AbsId)
417 {
418   // Converts the relative numbering into the absolute numbering
419   //  AbsId = 1:fNModules * fNPhi * fNZ  -> PbWO4
420   //  AbsId = 1:fNModules * 2 * (fNumberOfModulesPhi * fNumberOfModulesZ) * fNumberOfPadsPhi * fNumberOfPadsZ -> PPSD
421
422   Bool_t rv = kTRUE ; 
423  
424   if ( relid[1] > 0 ) { // its a PPSD pad
425
426     AbsId =    GetNPhi() * GetNZ() *  GetNModules()                          // the offset to separate emcal crystals from PPSD pads
427       + ( relid[0] - 1 ) * GetNumberOfModulesPhi() * GetNumberOfModulesZ()   // the pads offset of PHOS modules 
428                          * GetNumberOfPadsPhi() * GetNumberOfPadsZ() * 2
429       + ( relid[1] - 1 ) * GetNumberOfPadsPhi() * GetNumberOfPadsZ()         // the pads offset of PPSD modules 
430       + ( relid[2] - 1 ) * GetNumberOfPadsPhi()                              // the pads offset of a PPSD row
431       + relid[3] ;                                                           // the column number
432   } 
433   else {
434     if ( relid[1] == 0 ) { // its a Phos crystal
435       AbsId =  ( relid[0] - 1 ) *  GetNPhi() * GetNZ() // the offset of PHOS modules
436         + ( relid[2] - 1 ) * GetNPhi()                 // the offset of a xtal row
437         + relid[3] ;                                   // the column number
438     }
439   }
440
441   return rv ; 
442 }
443
444 //____________________________________________________________________________
445
446 void AliPHOSGeometry::RelPosInAlice(const Int_t id, TVector3 & pos ) 
447 {
448   // Converts the absolute numbering into the global ALICE coordinates
449   
450    if (id > 0) { 
451
452   Int_t relid[4] ;
453  
454   AbsToRelNumbering(id , relid) ;
455
456   Int_t phosmodule = relid[0] ; 
457
458   Float_t y0 = 0 ; 
459
460   if ( relid[1] == 0 ) // it is a PbW04 crystal 
461   {  y0 =  -(GetIPtoOuterCoverDistance() + GetUpperPlateThickness()
462       + GetSecondUpperPlateThickness() + GetUpperCoolingPlateThickness())  ;  
463   }
464   if ( relid[1] > 0 ) { // its a PPSD pad
465     if ( relid[1] >  GetNumberOfModulesPhi() *  GetNumberOfModulesZ() ) // its an bottom module
466      {
467        y0 = -( GetIPtoOuterCoverDistance() - GetMicromegas2Thickness() / 2.0)  ;
468      } 
469     else // its an upper module
470       y0 = -( GetIPtoOuterCoverDistance() - GetMicromegas2Thickness() - GetLeadToMicro2Gap()
471         -  GetLeadConverterThickness() -  GetMicro1ToLeadGap() - GetMicromegas1Thickness() / 2.0) ; 
472   }
473
474   Float_t x, z ; 
475   RelPosInModule(relid, x, z) ; 
476
477   pos.SetX(x) ;
478   pos.SetZ(z) ;
479   pos.SetY( TMath::Sqrt(x*x + z*z + y0*y0) ) ; 
480
481
482
483    Float_t phi           = GetPHOSAngle( phosmodule) ; 
484    Double_t const kRADDEG = 180.0 / kPI ;
485    Float_t rphi          = phi / kRADDEG ; 
486
487    TRotation rot ;
488    rot.RotateZ(-rphi) ; // a rotation around Z by angle  
489   
490    TRotation dummy = rot.Invert() ;  // to transform from original frame to rotate frame
491   
492    pos.Transform(rot) ; // rotate the baby 
493   }
494   else {
495  pos.SetX(0.);
496  pos.SetY(0.);
497  pos.SetZ(0.);
498        }
499
500
501 //____________________________________________________________________________
502 void AliPHOSGeometry::RelPosInModule(const Int_t * relid, Float_t & x, Float_t & z) 
503 {
504   // Converts the relative numbering into the local PHOS-module (x, z) coordinates
505   
506   Int_t ppsdmodule  ; 
507   Int_t row        = relid[2] ; //offset along z axiz
508   Int_t column     = relid[3] ; //offset along x axiz
509
510   Float_t padsizeZ = GetPPSDModuleSize(2)/ GetNumberOfPadsZ();
511   Float_t padsizeX = GetPPSDModuleSize(0)/ GetNumberOfPadsPhi();
512
513   if ( relid[1] == 0 ) { // its a PbW04 crystal 
514     x = -( GetNPhi()/2. - row   + 0.5 ) *  GetCrystalSize(0) ; // position ox Xtal with respect
515     z = ( GetNZ() /2. - column + 0.5 ) *  GetCrystalSize(2) ; // of center of PHOS module  
516    }  
517    else  {    
518     if ( relid[1] >  GetNumberOfModulesPhi() *  GetNumberOfModulesZ() )
519        ppsdmodule =  relid[1]-GetNumberOfModulesPhi() *  GetNumberOfModulesZ(); 
520     else ppsdmodule =  relid[1] ;
521     Int_t modrow = 1+(Int_t)TMath::Ceil( (Float_t)ppsdmodule / GetNumberOfModulesPhi()-1. ) ; 
522     Int_t modcol = ppsdmodule -  ( modrow - 1 ) * GetNumberOfModulesPhi() ;     
523     Float_t x0 = (  GetNumberOfModulesPhi() / 2.  - modrow  + 0.5 ) * GetPPSDModuleSize(0) ;
524     Float_t z0 = (  GetNumberOfModulesZ() / 2.  - modcol  + 0.5 ) * GetPPSDModuleSize(2)  ;     
525     x = - ( GetNumberOfPadsPhi()/2. - row - 0.5 ) * padsizeX + x0 ; // position of pad  with respect
526     z = ( GetNumberOfPadsZ()/2.   - column - 0.5 ) * padsizeZ - z0 ; // of center of PHOS module  
527          }
528 }
529
530 //____________________________________________________________________________
531 void AliPHOSGeometry::SetPHOSAngles() 
532
533   // Calculates the position in ALICE of the PHOS modules
534   
535   Double_t const kRADDEG = 180.0 / kPI ;
536   Float_t pphi =  TMath::ATan( fOuterBoxSize[0]  / ( 2.0 * fIPtoOuterCoverDistance ) ) ;
537   pphi *= kRADDEG ;
538   
539   for( Int_t i = 1; i <= fNModules ; i++ ) {
540     Float_t angle = pphi * 2 * ( i - fNModules / 2.0 - 0.5 ) ;
541     fPHOSAngle[i-1] = -  angle ;
542   } 
543 }
544
545 //____________________________________________________________________________
546 void AliPHOSGeometry::SetLeadConverterThickness(Float_t e) 
547 {
548   // should ultimately disappear 
549   
550   cout << " AliPHOSGeometry WARNING : You have changed LeadConverterThickness from " 
551        << fLeadConverterThickness << " to " << e << endl ;
552
553   fLeadConverterThickness = e ; 
554 }