bug fix in the vertex selection
[u/mrichter/AliRoot.git] / PHOS / AliPHOSv0.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 /* $Id$ */
16
17 /* History of cvs commits:
18  *
19  * $Log$
20  * Revision 1.94  2007/10/18 08:40:02  kharlov
21  * Misalignment-related bug fixed
22  *
23  * Revision 1.93  2007/10/06 22:24:40  kharlov
24  * Bug in strip unit geometry is corrected
25  *
26  * Revision 1.92  2007/07/04 16:38:19  policheh
27  * Tracking2LocalCS matrices corrected for CPV.
28  *
29  * Revision 1.91  2007/07/02 14:50:49  policheh
30  * Tracking2LocalCS matrices corrected.
31  *
32  * Revision 1.90  2007/05/24 13:04:05  policheh
33  * AddAlignableVolumes: local to tracking CS transformation matrices creates for each
34  * PHOS supermodule
35  *
36  * Revision 1.89  2007/04/24 14:34:39  hristov
37  * Additional protection: do not search for alignable object if the CPV is not in the geometry
38  *
39  * Revision 1.88  2007/04/19 15:28:30  kharlov
40  * Modify strip unit geometry according to the final drawings (Timur)
41  *
42  * Revision 1.87  2007/04/01 07:37:10  kharlov
43  * TGeo RS to Local RS transf matr added
44  *
45  * Revision 1.86  2007/03/06 06:55:46  kharlov
46  * DP:Misalignment of CPV added
47  *
48  * Revision 1.85  2007/03/01 11:37:37  kharlov
49  * Strip units changed from 8x1 to 8x2 (T.Pocheptsov)
50  *
51  * Revision 1.84  2006/12/20 16:56:43  kharlov
52  * Optional geometry without CPV
53  *
54  * Revision 1.83  2006/11/14 17:11:15  hristov
55  * Removing inheritances from TAttLine, TAttMarker and AliRndm in AliModule. The copy constructor and assignment operators are moved to the private part of the class and not implemented. The corresponding changes are propagated to the detectors
56  *
57  * Revision 1.82  2006/09/27 19:55:57  kharlov
58  * Alignment object with symbolic volume names are introduced
59  *
60  * Revision 1.81  2006/03/04 20:25:56  kharlov
61  * Set geom parameters from CDB
62  *
63  * Revision 1.80  2005/06/17 07:39:07  hristov
64  * Removing GetDebug and SetDebug from AliRun and AliModule. Using AliLog for the messages
65  *
66  * Revision 1.79  2005/05/28 14:19:05  schutz
67  * Compilation warnings fixed by T.P.
68  *
69  */
70
71 //_________________________________________________________________________
72 // Implementation version v0 of PHOS Manager class 
73 // An object of this class does not produce hits nor digits
74 // It is the one to use if you do not want to produce outputs in TREEH or TREED
75 //                  
76 //*-- Author: Yves Schutz (SUBATECH) & Dmitri Peressounko (RRC KI & SUBATECH)
77
78
79 // --- ROOT system ---
80
81 #include <TFolder.h>
82 #include <TGeometry.h>
83 #include <TROOT.h>
84 #include <TRandom.h>
85 #include <TTree.h>
86 #include <TVirtualMC.h>
87 #include <TGeoPhysicalNode.h>
88 #include <TGeoManager.h>
89 #include <TGeoMatrix.h>
90 #include <TVector3.h>
91
92 // --- Standard library ---
93
94 #include <string.h>
95 #include <stdlib.h>
96
97 // --- AliRoot header files ---
98
99 #include "AliConst.h"
100 #include "AliPHOSGeometry.h"
101 #include "AliPHOSLoader.h"
102 #include "AliPHOSv0.h"
103 #include "AliRun.h"
104 #include "AliLog.h"
105 #include "AliGeomManager.h"
106
107 ClassImp(AliPHOSv0)
108
109 //____________________________________________________________________________
110 AliPHOSv0::AliPHOSv0(const char *name, const char *title):
111   AliPHOS(name,title)
112 {
113   // ctor : title is used to identify the layout
114   GetGeometry() ; 
115 }
116
117 //____________________________________________________________________________
118 void AliPHOSv0::CreateGeometry()
119 {
120   // Create the PHOS geometry for Geant
121
122   AliPHOSv0 *phostmp = dynamic_cast<AliPHOSv0*>(gAlice->GetModule("PHOS")) ;
123
124   if ( phostmp == NULL ) {
125     
126     fprintf(stderr, "PHOS detector not found!\n") ;
127     return;
128     
129   }
130
131   AliPHOSGeometry * geom = GetGeometry() ; 
132
133   // Get pointer to the array containing media indeces
134   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
135
136   // Create a PHOS module.
137   
138   gMC->Gsvolu("PHOS", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;        
139   
140   this->CreateGeometryforEMC() ; 
141
142   if (strstr(fTitle.Data(),"noCPV") == 0) 
143     this->CreateGeometryforCPV() ;
144   
145   this->CreateGeometryforSupport() ; 
146   
147   // --- Position  PHOS mdules in ALICE setup ---
148   Int_t idrotm[99] ;
149   Int_t iXYZ,iAngle;
150   char im[5] ;
151   Bool_t anyModuleCreated=0 ;
152   for (Int_t iModule = 0; iModule < 5 ; iModule++ ) {
153     sprintf(im,"%d",iModule+1) ;
154     if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
155       continue ;
156     anyModuleCreated=1 ;
157     Float_t angle[3][2];
158     for (iXYZ=0; iXYZ<3; iXYZ++)
159       for (iAngle=0; iAngle<2; iAngle++)
160         angle[iXYZ][iAngle] = geom->GetModuleAngle(iModule,iXYZ, iAngle);
161     AliMatrix(idrotm[iModule],
162               angle[0][0],angle[0][1],
163               angle[1][0],angle[1][1],
164               angle[2][0],angle[2][1]) ;
165     
166     Float_t pos[3];
167     for (iXYZ=0; iXYZ<3; iXYZ++)
168       pos[iXYZ] = geom->GetModuleCenter(iModule,iXYZ);
169     gMC->Gspos("PHOS", iModule+1, "ALIC", pos[0], pos[1], pos[2],
170                idrotm[iModule], "ONLY") ;
171   }
172   if(!anyModuleCreated)
173     AliError("No one PHOS module was created") ;
174 }
175
176 //____________________________________________________________________________
177 void AliPHOSv0::CreateGeometryforEMC()
178 {
179   // Create the PHOS-EMC geometry for GEANT
180   // Author: Dmitri Peressounko August 2001
181   // The used coordinate system: 
182   //   1. in Module: X along longer side, Y out of beam, Z along shorter side (along beam)
183   //   2. In Strip the same: X along longer side, Y out of beam, Z along shorter side (along beam)
184
185
186     //BEGIN_HTML
187   /*
188     <H2>
189     Geant3 geometry tree of PHOS-EMC in ALICE
190     </H2>
191     <P><CENTER>
192     <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/EMCinAlice.gif"> 
193     </CENTER><P>
194   */
195   //END_HTML  
196   
197   // Get pointer to the array containing media indexes
198   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
199
200   AliPHOSGeometry * geom = GetGeometry() ; 
201   AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
202   Float_t par[4];
203   Int_t  ipar;
204
205   // ======= Define the strip ===============
206
207   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetStripHalfSize() + ipar);
208   gMC->Gsvolu("PSTR", "BOX ", idtmed[716], par, 3) ;  //Made of steel
209    
210   // --- define steel volume (cell of the strip unit)
211   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetAirCellHalfSize() + ipar);
212   gMC->Gsvolu("PCEL", "BOX ", idtmed[798], par, 3);
213
214   // --- define wrapped crystal and put it into steel cell
215
216   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetWrappedHalfSize() + ipar);
217   gMC->Gsvolu("PWRA", "BOX ", idtmed[702], par, 3);
218   const Float_t * pin    = emcg->GetAPDHalfSize() ; 
219   const Float_t * preamp = emcg->GetPreampHalfSize() ;
220   Float_t y = (emcg->GetAirGapLed()-2*pin[1]-2*preamp[1])/2;
221   gMC->Gspos("PWRA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
222     
223   // --- Define crystal and put it into wrapped crystall ---
224   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetCrystalHalfSize() + ipar);
225   gMC->Gsvolu("PXTL", "BOX ", idtmed[699], par, 3) ;
226   gMC->Gspos("PXTL", 1, "PWRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
227       
228   // --- define APD/PIN preamp and put it into AirCell
229  
230   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetAPDHalfSize() + ipar);
231   gMC->Gsvolu("PPIN", "BOX ", idtmed[705], par, 3) ;
232   const Float_t * crystal = emcg->GetCrystalHalfSize() ;
233   y = crystal[1] + emcg->GetAirGapLed() /2 - preamp[1]; 
234   gMC->Gspos("PPIN", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
235   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetPreampHalfSize() + ipar);
236   gMC->Gsvolu("PREA", "BOX ", idtmed[711], par, 3) ;   // Here I assumed preamp as a printed Circuit
237   y = crystal[1] + emcg->GetAirGapLed() /2 + pin[1]  ;    // May it should be changed
238   gMC->Gspos("PREA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ; // to ceramics?
239   
240   
241   // --- Fill strip with wrapped cristals in steel cells
242   
243   const Float_t* splate = emcg->GetSupportPlateHalfSize();  
244   y = -splate[1] ;
245   const Float_t* acel = emcg->GetAirCellHalfSize() ;
246   
247   for(Int_t lev = 2, icel = 1; 
248       icel <= emcg->GetNCellsXInStrip()*emcg->GetNCellsZInStrip(); 
249       icel += 2, lev += 2) {
250     Float_t x = (2*(lev / 2) - 1 - emcg->GetNCellsXInStrip())* acel[0] ;
251     Float_t z = acel[2];
252     gMC->Gspos("PCEL", icel, "PSTR", x, y, +z, 0, "ONLY") ;
253     gMC->Gspos("PCEL", icel + 1, "PSTR", x, y, -z, 0, "ONLY") ;
254   }
255
256   // --- define the support plate, hole in it and position it in strip ----
257   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetSupportPlateHalfSize() + ipar);
258   gMC->Gsvolu("PSUP", "BOX ", idtmed[701], par, 3) ;
259   
260   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetSupportPlateInHalfSize() + ipar);
261   gMC->Gsvolu("PSHO", "BOX ", idtmed[798], par, 3) ;
262   Float_t z = emcg->GetSupportPlateThickness()/2 ;
263   gMC->Gspos("PSHO", 1, "PSUP", 0.0, 0.0, z, 0, "ONLY") ;
264
265   y = acel[1] ;
266   gMC->Gspos("PSUP", 1, "PSTR", 0.0, y, 0.0, 0, "ONLY") ;
267
268   
269   // ========== Fill module with strips and put them into inner thermoinsulation=============
270   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetInnerThermoHalfSize() + ipar);
271   gMC->Gsvolu("PTII", "BOX ", idtmed[706], par, 3) ;     
272   
273   const Float_t * inthermo = emcg->GetInnerThermoHalfSize() ;
274   const Float_t * strip    = emcg->GetStripHalfSize() ;
275   y = inthermo[1] - strip[1] ;
276   Int_t irow;
277   Int_t nr = 1 ;
278   Int_t icol ;
279   
280   for(irow = 0; irow < emcg->GetNStripX(); irow ++){
281     Float_t x = (2*irow + 1 - emcg->GetNStripX())* strip[0] ;
282     for(icol = 0; icol < emcg->GetNStripZ(); icol ++){
283       z = (2*icol + 1 - emcg->GetNStripZ()) * strip[2] ;
284       gMC->Gspos("PSTR", nr, "PTII", x, y, z, 0, "ONLY") ;
285       nr++ ;
286     }
287   }
288   
289   
290   // ------- define the air gap between thermoinsulation and cooler
291   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetAirGapHalfSize() + ipar);
292   gMC->Gsvolu("PAGA", "BOX ", idtmed[798], par, 3) ;   
293   const Float_t * agap = emcg->GetAirGapHalfSize() ;
294   y = agap[1] - inthermo[1]  ;
295   
296   gMC->Gspos("PTII", 1, "PAGA", 0.0, y, 0.0, 0, "ONLY") ;
297
298
299   // ------- define the Al passive cooler 
300   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetCoolerHalfSize() + ipar);
301   gMC->Gsvolu("PCOR", "BOX ", idtmed[701], par, 3) ;   
302   const Float_t * cooler = emcg->GetCoolerHalfSize() ;
303   y = cooler[1] - agap[1]  ;
304   
305   gMC->Gspos("PAGA", 1, "PCOR", 0.0, y, 0.0, 0, "ONLY") ;
306   
307   // ------- define the outer thermoinsulating cover
308   for (ipar=0; ipar<4; ipar++) par[ipar] = *(emcg->GetOuterThermoParams() + ipar);
309   gMC->Gsvolu("PTIO", "TRD1", idtmed[706], par, 4) ;        
310   const Float_t * outparams = emcg->GetOuterThermoParams() ; 
311   
312   Int_t idrotm[99] ;
313   AliMatrix(idrotm[1], 90.0, 0.0, 0.0, 0.0, 90.0, 270.0) ;
314   // Frame in outer thermoinsulation and so on: z out of beam, y along beam, x across beam
315   
316   z = outparams[3] - cooler[1] ;
317   gMC->Gspos("PCOR", 1, "PTIO", 0., 0.0, z, idrotm[1], "ONLY") ;
318   
319   // -------- Define the outer Aluminium cover -----
320   for (ipar=0; ipar<4; ipar++) par[ipar] = *(emcg->GetAlCoverParams() + ipar);
321   gMC->Gsvolu("PCOL", "TRD1", idtmed[701], par, 4) ;        
322   const Float_t * covparams = emcg->GetAlCoverParams() ; 
323   z = covparams[3] - outparams[3] ;
324   gMC->Gspos("PTIO", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
325
326   // --------- Define front fiberglass cover -----------
327   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFiberGlassHalfSize() + ipar);
328   gMC->Gsvolu("PFGC", "BOX ", idtmed[717], par, 3) ;  
329   z = - outparams[3] ;
330   gMC->Gspos("PFGC", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
331
332   //=============This is all with cold section==============
333   
334
335   //------ Warm Section --------------
336   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetWarmAlCoverHalfSize() + ipar);
337   gMC->Gsvolu("PWAR", "BOX ", idtmed[701], par, 3) ; 
338   const Float_t * warmcov = emcg->GetWarmAlCoverHalfSize() ;
339   
340   // --- Define the outer thermoinsulation ---
341   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetWarmThermoHalfSize() + ipar);
342   gMC->Gsvolu("PWTI", "BOX ", idtmed[706], par, 3) ; 
343   const Float_t * warmthermo = emcg->GetWarmThermoHalfSize() ;
344   z = -warmcov[2] + warmthermo[2] ;
345   
346   gMC->Gspos("PWTI", 1, "PWAR", 0., 0.0, z, 0, "ONLY") ;     
347   
348   // --- Define cables area and put in it T-supports ---- 
349   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTCables1HalfSize() + ipar);
350   gMC->Gsvolu("PCA1", "BOX ", idtmed[718], par, 3) ; 
351   const Float_t * cbox = emcg->GetTCables1HalfSize() ;
352   
353   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTSupport1HalfSize() + ipar);
354   gMC->Gsvolu("PBE1", "BOX ", idtmed[701], par, 3) ;
355   const Float_t * beams = emcg->GetTSupport1HalfSize() ;
356   Int_t isup ;
357   for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
358     Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
359     gMC->Gspos("PBE1", isup, "PCA1", x, 0.0, 0.0, 0, "ONLY") ;
360   }
361   
362   z = -warmthermo[2] + cbox[2];
363   gMC->Gspos("PCA1", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;     
364   
365   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTCables2HalfSize() + ipar);
366   gMC->Gsvolu("PCA2", "BOX ", idtmed[718], par, 3) ; 
367   const Float_t * cbox2 = emcg->GetTCables2HalfSize() ;
368   
369   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTSupport2HalfSize() + ipar);
370   gMC->Gsvolu("PBE2", "BOX ", idtmed[701], par, 3) ;
371   for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
372     Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
373     gMC->Gspos("PBE2", isup, "PCA2", x, 0.0, 0.0, 0, "ONLY") ;
374   }
375   
376   z = -warmthermo[2] + 2*cbox[2] + cbox2[2];
377   gMC->Gspos("PCA2", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;     
378   
379   
380   // --- Define frame ---
381   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFrameXHalfSize() + ipar);
382   gMC->Gsvolu("PFRX", "BOX ", idtmed[716], par, 3) ; 
383   const Float_t * posit1 = emcg->GetFrameXPosition() ;
384   gMC->Gspos("PFRX", 1, "PWTI", posit1[0],  posit1[1], posit1[2], 0, "ONLY") ;
385   gMC->Gspos("PFRX", 2, "PWTI", posit1[0], -posit1[1], posit1[2], 0, "ONLY") ;
386   
387   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFrameZHalfSize() + ipar);
388   gMC->Gsvolu("PFRZ", "BOX ", idtmed[716], par, 3) ; 
389   const Float_t * posit2 = emcg->GetFrameZPosition() ;
390   gMC->Gspos("PFRZ", 1, "PWTI",  posit2[0], posit2[1], posit2[2], 0, "ONLY") ;
391   gMC->Gspos("PFRZ", 2, "PWTI", -posit2[0], posit2[1], posit2[2], 0, "ONLY") ;
392
393  // --- Define Fiber Glass support ---
394   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGupXHalfSize() + ipar);
395   gMC->Gsvolu("PFG1", "BOX ", idtmed[717], par, 3) ; 
396   const Float_t * posit3 = emcg->GetFGupXPosition() ;
397   gMC->Gspos("PFG1", 1, "PWTI", posit3[0],  posit3[1], posit3[2], 0, "ONLY") ;
398   gMC->Gspos("PFG1", 2, "PWTI", posit3[0], -posit3[1], posit3[2], 0, "ONLY") ;
399
400   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGupZHalfSize() + ipar);
401   gMC->Gsvolu("PFG2", "BOX ", idtmed[717], par, 3) ; 
402   const Float_t * posit4 = emcg->GetFGupZPosition();
403   gMC->Gspos("PFG2", 1, "PWTI",  posit4[0], posit4[1], posit4[2], 0, "ONLY") ;
404   gMC->Gspos("PFG2", 2, "PWTI", -posit4[0], posit4[1], posit4[2], 0, "ONLY") ;
405
406   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGlowXHalfSize() + ipar);
407   gMC->Gsvolu("PFG3", "BOX ", idtmed[717], par, 3) ; 
408   const Float_t * posit5 = emcg->GetFGlowXPosition() ;
409   gMC->Gspos("PFG3", 1, "PWTI", posit5[0],  posit5[1], posit5[2], 0, "ONLY") ;
410   gMC->Gspos("PFG3", 2, "PWTI", posit5[0], -posit5[1], posit5[2], 0, "ONLY") ;
411
412   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGlowZHalfSize() + ipar);
413   gMC->Gsvolu("PFG4", "BOX ", idtmed[717], par, 3) ; 
414   const Float_t * posit6 = emcg->GetFGlowZPosition() ;
415   gMC->Gspos("PFG4", 1, "PWTI",  posit6[0], posit6[1], posit6[2], 0, "ONLY") ;
416   gMC->Gspos("PFG4", 2, "PWTI", -posit6[0], posit6[1], posit6[2], 0, "ONLY") ;
417
418   // --- Define Air Gap for FEE electronics ----- 
419   
420   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFEEAirHalfSize() + ipar);
421   gMC->Gsvolu("PAFE", "BOX ", idtmed[798], par, 3) ; 
422   const Float_t * posit7 = emcg->GetFEEAirPosition() ;
423   gMC->Gspos("PAFE", 1, "PWTI",  posit7[0], posit7[1], posit7[2], 0, "ONLY") ;
424   
425   // Define the EMC module volume and combine Cool and Warm sections
426   
427   for (ipar=0; ipar<4; ipar++) par[ipar] = *(emcg->GetEMCParams() + ipar);
428   gMC->Gsvolu("PEMC", "TRD1", idtmed[798], par, 4) ;        
429   z =  - warmcov[2] ;
430   gMC->Gspos("PCOL", 1, "PEMC",  0., 0., z, 0, "ONLY") ;
431   z = covparams[3] ;
432   gMC->Gspos("PWAR", 1, "PEMC",  0., 0., z, 0, "ONLY") ;
433   
434   
435   // Put created EMC geometry into PHOS volume
436   
437   z = geom->GetCPVBoxSize(1) / 2. ;
438   gMC->Gspos("PEMC", 1, "PHOS", 0., 0., z, 0, "ONLY") ; 
439   
440 }
441
442 //____________________________________________________________________________
443 void AliPHOSv0::CreateGeometryforCPV()
444 {
445   // Create the PHOS-CPV geometry for GEANT
446   // Author: Yuri Kharlov 11 September 2000
447   //BEGIN_HTML
448   /*
449     <H2>
450     Geant3 geometry of PHOS-CPV in ALICE
451     </H2>
452     <table width=700>
453
454     <tr>
455          <td>CPV perspective view</td>
456          <td>CPV front view      </td>
457     </tr>
458
459     <tr>
460          <td> <img height=300 width=290 src="../images/CPVallPersp.gif"> </td>
461          <td> <img height=300 width=290 src="../images/CPVallFront.gif"> </td>
462     </tr>
463
464     <tr>
465          <td>One CPV module, perspective view                            </td>
466          <td>One CPV module, front view (extended in vertical direction) </td>
467     </tr>
468
469     <tr>
470          <td><img height=300 width=290 src="../images/CPVmodulePers.gif"></td>
471          <td><img height=300 width=290 src="../images/CPVmoduleSide.gif"></td>
472     </tr>
473
474     </table>
475
476     <H2>
477     Geant3 geometry tree of PHOS-CPV in ALICE
478     </H2>
479     <center>
480     <img height=300 width=290 src="../images/CPVtree.gif">
481     </center>
482   */
483   //END_HTML  
484
485   Float_t par[3], x,y,z;
486
487   // Get pointer to the array containing media indexes
488   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
489
490   AliPHOSGeometry * geom = GetGeometry() ; 
491
492   // The box containing all CPV for one PHOS module filled with air 
493   par[0] = geom->GetCPVBoxSize(0) / 2.0 ;  
494   par[1] = geom->GetCPVBoxSize(1) / 2.0 ; 
495   par[2] = geom->GetCPVBoxSize(2) / 2.0 ;
496   gMC->Gsvolu("PCPV", "BOX ", idtmed[798], par, 3) ;
497
498   const Float_t * emcParams = geom->GetEMCAGeometry()->GetEMCParams() ;
499   z = - emcParams[3] ;
500   Int_t rotm ;
501   AliMatrix(rotm, 90.,0., 0., 0., 90., 90.) ;
502
503   gMC->Gspos("PCPV", 1, "PHOS", 0.0, 0.0, z, rotm, "ONLY") ; 
504   
505   // Gassiplex board
506   
507   par[0] = geom->GetGassiplexChipSize(0)/2.;
508   par[1] = geom->GetGassiplexChipSize(1)/2.;
509   par[2] = geom->GetGassiplexChipSize(2)/2.;
510   gMC->Gsvolu("PCPC","BOX ",idtmed[707],par,3);
511   
512   // Cu+Ni foil covers Gassiplex board
513
514   par[1] = geom->GetCPVCuNiFoilThickness()/2;
515   gMC->Gsvolu("PCPD","BOX ",idtmed[710],par,3);
516   y      = -(geom->GetGassiplexChipSize(1)/2 - par[1]);
517   gMC->Gspos("PCPD",1,"PCPC",0,y,0,0,"ONLY");
518
519   // Position of the chip inside CPV
520
521   Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
522   Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ()   + 1);
523   Int_t   copy  = 0;
524   y = geom->GetCPVFrameSize(1)/2           - geom->GetFTPosition(0) +
525     geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
526   for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
527     x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
528     for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
529       copy++;
530       z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
531       gMC->Gspos("PCPC",copy,"PCPV",x,y,z,0,"ONLY");
532     }
533   }
534
535   // Foiled textolite (1 mm of textolite + 50 mkm of Cu + 6 mkm of Ni)
536   
537   par[0] = geom->GetCPVActiveSize(0)        / 2;
538   par[1] = geom->GetCPVTextoliteThickness() / 2;
539   par[2] = geom->GetCPVActiveSize(1)        / 2;
540   gMC->Gsvolu("PCPF","BOX ",idtmed[707],par,3);
541
542   // Argon gas volume
543
544   par[1] = (geom->GetFTPosition(2) - geom->GetFTPosition(1) - geom->GetCPVTextoliteThickness()) / 2;
545   gMC->Gsvolu("PCPG","BOX ",idtmed[715],par,3);
546
547   for (Int_t i=0; i<4; i++) {
548     y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(i) + geom->GetCPVTextoliteThickness()/2;
549     gMC->Gspos("PCPF",i+1,"PCPV",0,y,0,0,"ONLY");
550     if(i==1){
551       y-= (geom->GetFTPosition(2) - geom->GetFTPosition(1)) / 2;
552       gMC->Gspos("PCPG",1,"PCPV ",0,y,0,0,"ONLY");
553     }
554   }
555
556   // Dummy sensitive plane in the middle of argone gas volume
557
558   par[1]=0.001;
559   gMC->Gsvolu("PCPQ","BOX ",idtmed[715],par,3);
560   gMC->Gspos ("PCPQ",1,"PCPG",0,0,0,0,"ONLY");
561
562   // Cu+Ni foil covers textolite
563
564   par[1] = geom->GetCPVCuNiFoilThickness() / 2;
565   gMC->Gsvolu("PCP1","BOX ",idtmed[710],par,3);
566   y = geom->GetCPVTextoliteThickness()/2 - par[1];
567   gMC->Gspos ("PCP1",1,"PCPF",0,y,0,0,"ONLY");
568
569   // Aluminum frame around CPV
570
571   par[0] = geom->GetCPVFrameSize(0)/2;
572   par[1] = geom->GetCPVFrameSize(1)/2;
573   par[2] = geom->GetCPVBoxSize(2)  /2;
574   gMC->Gsvolu("PCF1","BOX ",idtmed[701],par,3);
575
576   par[0] = geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0);
577   par[1] = geom->GetCPVFrameSize(1)/2;
578   par[2] = geom->GetCPVFrameSize(2)/2;
579   gMC->Gsvolu("PCF2","BOX ",idtmed[701],par,3);
580
581   for (Int_t j=0; j<=1; j++) {
582     x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
583     gMC->Gspos("PCF1",j+1,"PCPV", x,0,0,0,"ONLY");
584     z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
585     gMC->Gspos("PCF2",j+1,"PCPV",0, 0,z,0,"ONLY");
586   }
587
588 }
589
590
591 //____________________________________________________________________________
592 void AliPHOSv0::CreateGeometryforSupport()
593 {
594   // Create the PHOS' support geometry for GEANT
595     //BEGIN_HTML
596   /*
597     <H2>
598     Geant3 geometry of the PHOS's support
599     </H2>
600     <P><CENTER>
601     <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/PHOS_support.gif"> 
602     </CENTER><P>
603   */
604   //END_HTML  
605   
606   Float_t par[5], x0,y0,z0 ; 
607   Int_t   i,j,copy;
608
609   // Get pointer to the array containing media indexes
610   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
611
612   AliPHOSGeometry * geom = GetGeometry() ; 
613
614   // --- Dummy box containing two rails on which PHOS support moves
615   // --- Put these rails to the bottom of the L3 magnet
616
617   par[0] =  geom->GetRailRoadSize(0) / 2.0 ;
618   par[1] =  geom->GetRailRoadSize(1) / 2.0 ;
619   par[2] =  geom->GetRailRoadSize(2) / 2.0 ;
620   gMC->Gsvolu("PRRD", "BOX ", idtmed[798], par, 3) ;
621
622   y0     = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) / 2.0) ;
623   gMC->Gspos("PRRD", 1, "ALIC", 0.0, y0, 0.0, 0, "ONLY") ; 
624
625   // --- Dummy box containing one rail
626
627   par[0] =  geom->GetRailOuterSize(0) / 2.0 ;
628   par[1] =  geom->GetRailOuterSize(1) / 2.0 ;
629   par[2] =  geom->GetRailOuterSize(2) / 2.0 ;
630   gMC->Gsvolu("PRAI", "BOX ", idtmed[798], par, 3) ;
631
632   for (i=0; i<2; i++) {
633     x0     = (2*i-1) * geom->GetDistanceBetwRails()  / 2.0 ;
634     gMC->Gspos("PRAI", i, "PRRD", x0, 0.0, 0.0, 0, "ONLY") ; 
635   }
636
637   // --- Upper and bottom steel parts of the rail
638
639   par[0] =  geom->GetRailPart1(0) / 2.0 ;
640   par[1] =  geom->GetRailPart1(1) / 2.0 ;
641   par[2] =  geom->GetRailPart1(2) / 2.0 ;
642   gMC->Gsvolu("PRP1", "BOX ", idtmed[716], par, 3) ;
643
644   y0     = - (geom->GetRailOuterSize(1) - geom->GetRailPart1(1))  / 2.0 ;
645   gMC->Gspos("PRP1", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
646   y0     =   (geom->GetRailOuterSize(1) - geom->GetRailPart1(1))  / 2.0 - geom->GetRailPart3(1);
647   gMC->Gspos("PRP1", 2, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
648
649   // --- The middle vertical steel parts of the rail
650
651   par[0] =  geom->GetRailPart2(0) / 2.0 ;
652   par[1] =  geom->GetRailPart2(1) / 2.0 ;
653   par[2] =  geom->GetRailPart2(2) / 2.0 ;
654   gMC->Gsvolu("PRP2", "BOX ", idtmed[716], par, 3) ;
655
656   y0     =   - geom->GetRailPart3(1) / 2.0 ;
657   gMC->Gspos("PRP2", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ; 
658
659   // --- The most upper steel parts of the rail
660
661   par[0] =  geom->GetRailPart3(0) / 2.0 ;
662   par[1] =  geom->GetRailPart3(1) / 2.0 ;
663   par[2] =  geom->GetRailPart3(2) / 2.0 ;
664   gMC->Gsvolu("PRP3", "BOX ", idtmed[716], par, 3) ;
665
666   y0     =   (geom->GetRailOuterSize(1) - geom->GetRailPart3(1))  / 2.0 ;
667   gMC->Gspos("PRP3", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ; 
668
669   // --- The wall of the cradle
670   // --- The wall is empty: steel thin walls and air inside
671
672   par[1] =  TMath::Sqrt(TMath::Power((geom->GetIPtoCPVDistance() + geom->GetOuterBoxSize(3)),2) +
673                         TMath::Power((geom->GetOuterBoxSize(1)/2),2))+10. ;
674   par[0] =  par[1] - geom->GetCradleWall(1) ;
675   par[2] =  geom->GetCradleWall(2) / 2.0 ;
676   par[3] =  geom->GetCradleWall(3) ;
677   par[4] =  geom->GetCradleWall(4) ;
678   gMC->Gsvolu("PCRA", "TUBS", idtmed[716], par, 5) ;
679
680   par[0] +=  geom->GetCradleWallThickness() ;
681   par[1] -=  geom->GetCradleWallThickness() ;
682   par[2] -=  geom->GetCradleWallThickness() ;
683   gMC->Gsvolu("PCRE", "TUBS", idtmed[798], par, 5) ;
684   gMC->Gspos ("PCRE", 1, "PCRA", 0.0, 0.0, 0.0, 0, "ONLY") ; 
685
686   for (i=0; i<2; i++) {
687     z0 = (2*i-1) * (geom->GetOuterBoxSize(2) + geom->GetCradleWall(2) )/ 2.0  ;
688         gMC->Gspos("PCRA", i, "ALIC", 0.0, 0.0, z0, 0, "ONLY") ; 
689   }
690
691   // --- The "wheels" of the cradle
692   
693   par[0] = geom->GetCradleWheel(0) / 2;
694   par[1] = geom->GetCradleWheel(1) / 2;
695   par[2] = geom->GetCradleWheel(2) / 2;
696   gMC->Gsvolu("PWHE", "BOX ", idtmed[716], par, 3) ;
697
698   y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) -
699          geom->GetCradleWheel(1)/2) ;
700   for (i=0; i<2; i++) {
701     z0 = (2*i-1) * ((geom->GetOuterBoxSize(2) + geom->GetCradleWheel(2))/ 2.0 +
702                     geom->GetCradleWall(2));
703     for (j=0; j<2; j++) {
704       copy = 2*i + j;
705       x0 = (2*j-1) * geom->GetDistanceBetwRails()  / 2.0 ;
706       gMC->Gspos("PWHE", copy, "ALIC", x0, y0, z0, 0, "ONLY") ; 
707     }
708   }
709
710 }
711
712 //_____________________________________________________________________________
713 void AliPHOSv0::AddAlignableVolumes() const
714 {
715   //
716   // Create entries for alignable volumes associating the symbolic volume
717   // name with the corresponding volume path. Needs to be syncronized with
718   // eventual changes in the geometry
719   // Alignable volumes are:
720   // 1) PHOS modules as a whole
721   // 2) Cradle
722   // 3) Cradle wheels
723   // 4) Strip units (group of 2x8 crystals)
724
725   TString volpath, symname;
726
727   // Alignable modules
728   // Volume path /ALIC_1/PHOS_<i> => symbolic name /PHOS/Module<i>, <i>=1,2,3,4,5
729   
730   AliGeomManager::ELayerID idPHOS1 = AliGeomManager::kPHOS1;
731   AliGeomManager::ELayerID idPHOS2 = AliGeomManager::kPHOS2;
732   Int_t modUID, modnum = 0;
733   TString physModulePath="/ALIC_1/PHOS_";
734   TString symbModuleName="PHOS/Module";
735   Int_t nModules = GetGeometry()->GetNModules();
736   
737   char im[5] ;
738   for(Int_t iModule=1; iModule<=nModules; iModule++){
739     sprintf(im,"%d",iModule) ;
740     modUID = AliGeomManager::LayerToVolUID(idPHOS1,modnum++);
741     if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
742       continue ;
743     volpath = physModulePath;
744     volpath += iModule;
745     //    volpath += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1";
746  
747    // Check the volume path if not all 5 modules exist
748     if (!gGeoManager->CheckPath(volpath.Data())) {                                                                                         
749       AliError(Form("Volume path %s not valid!",volpath.Data()));                                                                          
750       continue;                                                                                                                            
751     }                                                                                                                                      
752  
753     symname = symbModuleName;
754     symname += iModule;
755     if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
756       continue ;
757 //      AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
758
759     // Creates the Tracking to Local transformation matrix for PHOS modules
760     TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
761
762     Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
763     TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
764
765     TGeoHMatrix *matTtoL = new TGeoHMatrix;
766     matTtoL->RotateZ(-90.+angle);
767     matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
768     alignableEntry->SetMatrix(matTtoL);
769   }
770
771   //Aligning of CPV should be done for volume PCPV_1
772   symbModuleName="PHOS/Module";
773   modnum=0;
774   for(Int_t iModule=1; iModule<=nModules; iModule++){
775     if(strstr(GetTitle(),"noCPV"))
776       continue ;
777     sprintf(im,"%d",iModule) ;
778     modUID = AliGeomManager::LayerToVolUID(idPHOS2,modnum++);
779     if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0)
780       continue ;
781     volpath = physModulePath;
782     volpath += iModule;
783     volpath += "/PCPV_1";
784     // Check the volume path
785     if (!gGeoManager->CheckPath(volpath.Data())) {
786       AliError(Form("Volume path %s not valid!",volpath.Data()));
787       continue;
788     }
789
790     symname = symbModuleName;
791     symname += iModule;
792     symname += "/CPV";
793     if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
794       AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
795           
796     // Creates the TGeo Local to Tracking transformation matrix ...
797     TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
798
799     Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
800     TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
801
802     TGeoHMatrix *matTtoL = new TGeoHMatrix;
803     matTtoL->RotateZ(-90.+angle);
804     matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
805     alignableEntry->SetMatrix(matTtoL);
806     
807   }
808  
809
810   // Alignable cradle walls
811   // Volume path /ALIC_1/PCRA_<i> => symbolic name /PHOS/Cradle<i>, <i>=0,1
812
813   TString physCradlePath="/ALIC_1/PCRA_";
814   TString symbCradleName="PHOS/Cradle";
815   Int_t nCradles = 2;
816
817   for(Int_t iCradle=0; iCradle<nCradles; iCradle++){
818     volpath = physCradlePath;
819     volpath += iCradle;
820     symname = symbCradleName;
821     symname += iCradle;
822     gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
823   }
824
825   // Alignable wheels
826   // Volume path /ALIC_1/PWHE_<i> => symbolic name /PHOS/Wheel<i>, i=0,1,2,3
827
828   TString physWheelPath="/ALIC_1/PWHE_";
829   TString symbWheelName="PHOS/Wheel";
830   Int_t nWheels = 4;
831
832   for(Int_t iWheel=0; iWheel<nWheels; iWheel++){
833     volpath = physWheelPath;
834     volpath += iWheel;
835     symname = symbWheelName;
836     symname += iWheel;
837     gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
838   }
839
840   //Physical strip path is a combination of: physModulePath + module number + 
841   //physStripPath + strip number == ALIC_1/PHOS_N/..../PSTR_M
842   const Int_t nStripsX = GetGeometry()->GetEMCAGeometry()->GetNStripX();
843   const Int_t nStripsZ = GetGeometry()->GetEMCAGeometry()->GetNStripZ();
844   TString partialPhysStripName(100);
845   TString fullPhysStripName(100);
846   TString partialSymbStripName(100);
847   TString fullSymbStripName(100);
848
849   for(Int_t module = 1; module <= nModules; ++module){
850
851     sprintf(im,"%d",module) ;
852     if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
853       continue ;
854
855     volpath = physModulePath;
856     volpath += module;
857     // Check the volume path if not all 5 modules exist
858     if (!gGeoManager->CheckPath(volpath.Data())) {
859       AliError(Form("Volume path %s does not exist",volpath.Data())) ;
860       continue;
861     }
862
863     partialPhysStripName  = physModulePath;
864     partialPhysStripName += module;
865     partialPhysStripName += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1/PSTR_";
866
867     partialSymbStripName  = symbModuleName;
868     partialSymbStripName += module;
869     partialSymbStripName += "/Strip_";
870
871     for(Int_t i = 0, ind1D = 1; i < nStripsX; ++i){//ind1D starts from 1 (PSTR_1...PSTR_224...)
872       for(Int_t j = 0; j < nStripsZ; ++j, ++ind1D){
873          fullPhysStripName = partialPhysStripName;
874          fullPhysStripName += ind1D;
875          
876          fullSymbStripName  = partialSymbStripName;
877          fullSymbStripName += i;//ind1D;
878          fullSymbStripName += '_';
879          fullSymbStripName += j;
880
881          gGeoManager->SetAlignableEntry(fullSymbStripName.Data(), fullPhysStripName.Data());
882
883          // Creates the TGeo Local to Tracking transformation matrix ...
884          TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntry(fullSymbStripName.Data()) ;
885          const char *path = alignableEntry->GetTitle();
886          if (!gGeoManager->cd(path))
887            AliFatal(Form("Volume path %s not valid!",path));
888          TGeoHMatrix matLtoT = *gGeoManager->GetCurrentMatrix() ;
889          Double_t refl[3]={-1.,-1.,-1.} ;
890          matLtoT.SetScale(refl) ;
891          TGeoHMatrix *matTtoL = new TGeoHMatrix(matLtoT.Inverse());
892  
893          char phosPath[50] ;
894          sprintf(phosPath,"/ALIC_1/PHOS_%d",module) ;
895          if (!gGeoManager->cd(phosPath)){
896             AliFatal("Geo manager can not find path \n");
897          }
898          TGeoHMatrix *mPHOS = gGeoManager->GetCurrentMatrix();
899          if (mPHOS) 
900            matTtoL->Multiply(mPHOS);
901          else{
902            AliFatal("Geo matrixes are not loaded \n") ;
903          }
904          //Switch y<->z
905          Double_t rot[9]={1.,0.,0.,  0.,1.,0., 0.,0.,1.} ;
906          matTtoL->SetRotation(rot) ;
907          alignableEntry->SetMatrix(matTtoL);
908
909 /*
910   //Check poisition of corner cell of the strip
911   AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
912   Int_t relid[4] ; 
913   relid[0] = module ;
914   relid[1] = 0 ;
915   Int_t iStrip=ind1D ;
916   Int_t icell=1 ;
917   Int_t raw = geom->GetEMCAGeometry()->GetNCellsXInStrip()*((iStrip-1)/geom->GetEMCAGeometry()->GetNStripZ()) +
918                 1 + (icell-1)/geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
919   Int_t col = geom->GetEMCAGeometry()->GetNCellsZInStrip()*(1+(iStrip-1)%geom->GetEMCAGeometry()->GetNStripZ()) - 
920                 (icell-1)%geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
921   if(col==0) col=geom->GetNZ() ;
922   relid[2] = raw ;
923   relid[3] = col ;
924   Float_t xG,zG ; 
925   geom->RelPosInModule(relid, xG, zG) ;
926 printf("============\n") ;
927 printf("Geometry: x=%f, z=%f \n",xG,zG) ;
928   Int_t absid ; 
929   geom->RelToAbsNumbering(relid,absid) ;
930   Double_t pos[3]= {-2.2*3.5,0.0,1.1}; //Position incide the strip (Y coordinalte is not important)
931   Double_t posC[3]={0.0,0.0,0.}; //Global position
932  
933   matTtoL->MasterToLocal(pos,posC);
934 printf("Matrix:   x=%f, z=%f, y=%f \n",posC[0],posC[2],posC[1]) ;
935 */
936       }
937     }
938   }
939 }
940
941 //____________________________________________________________________________
942 Float_t AliPHOSv0::ZMin(void) const
943 {
944   // Overall dimension of the PHOS (min)
945
946   AliPHOSGeometry * geom = GetGeometry() ; 
947
948   return -geom->GetOuterBoxSize(2)/2.;
949 }
950
951 //____________________________________________________________________________
952 Float_t AliPHOSv0::ZMax(void) const
953 {
954   // Overall dimension of the PHOS (max)
955
956   AliPHOSGeometry * geom = GetGeometry() ; 
957
958   return  geom->GetOuterBoxSize(2)/2.;
959 }
960
961 //____________________________________________________________________________
962 void AliPHOSv0::Init(void)
963 {
964   // Just prints an information message
965   
966   Int_t i;
967
968   if(AliLog::GetGlobalDebugLevel()>0) {
969     TString st ; 
970     for(i=0;i<35;i++) 
971       st += "*";
972     Info("Init", "%s", st.Data()) ;  
973     // Here the PHOS initialisation code (if any!)
974     
975     AliPHOSGeometry * geom = GetGeometry() ; 
976
977     if (geom!=0)  
978       Info("Init", "AliPHOS%s: PHOS geometry intialized for %s", Version().Data(), geom->GetName()) ;
979     else
980       Info("Init", "AliPHOS%s: PHOS geometry initialization failed !", Version().Data()) ;       
981
982     Info("Init", "%s", st.Data()) ;  
983   }
984 }