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