]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PHOS/PHOSsim/AliPHOSv0.cxx
CMake: Deleting wrong CMakeLists
[u/mrichter/AliRoot.git] / PHOS / PHOSsim / 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  fCreateCPV(kFALSE), 
113  fCreateHalfMod(kFALSE) 
114 {
115   // ctor : title is used to identify the layout
116   //Check possible configurations  
117   
118   for(Int_t mod=0; mod<6; mod++){
119     fActiveModule[mod]=kFALSE ;
120     fActiveCPV[mod]=kFALSE ;
121   }
122   //Default geometries
123   //for period 2009-2013
124   if(strstr(title,"Run1")!=0){
125     fCreateCPV=kFALSE ;
126     fCreateHalfMod=kFALSE;
127     fActiveModule[1]=kTRUE ;
128     fActiveModule[2]=kTRUE ;
129     fActiveModule[3]=kTRUE ;
130     //NO CPV in Run1   
131   }
132   else{
133     //for period 2015-2018
134     if(strstr(title,"Run2")!=0){
135       fCreateCPV=kTRUE ;
136       fCreateHalfMod=kTRUE;
137       fActiveModule[1]=kTRUE ;
138       fActiveModule[2]=kTRUE ;
139       fActiveModule[3]=kTRUE ;
140       fActiveModule[4]=kTRUE ;
141       fActiveCPV[3]=kTRUE ;
142     }
143     else{
144      //custom geometry can be set in form
145      //Modxxx_CPVyyy, where xxx- list of PHOS modules in geometry, yyy -list of modules with CPVallFront
146      Bool_t isOK=kFALSE ;
147      TString a(title); 
148      Int_t modPos=a.Index("Mod",0,TString::kIgnoreCase) ;
149      Int_t cpvPos=a.Index("CPV",0,TString::kIgnoreCase) ;
150      Int_t size = a.Sizeof() ;
151      Int_t modEnd=(cpvPos>modPos)?cpvPos:size ;
152      Int_t cpvEnd=(cpvPos>modPos)?size:modPos ;
153      for(Int_t mod=1; mod<6; mod++){
154        Int_t imod=a.Index(Form("%d",mod),modPos);
155        if(imod>modPos && imod<modEnd){
156          fActiveModule[mod]=kTRUE ;
157          isOK=kTRUE ;
158          if(mod==4)
159            fCreateHalfMod=kTRUE;
160        }
161        Int_t icpv=a.Index(Form("%d",mod),cpvPos);
162        if(icpv>cpvPos && icpv<cpvEnd){
163          fActiveCPV[mod]=kTRUE ;
164          fCreateCPV=kTRUE ;
165        }
166      }
167      if(!isOK){
168        AliFatal(Form("Unknown PHOS configuration: %s. Possible: 'Run1' for 2009-2013, 'Run2' for 2015-2018', 'Modxxx_CPVyyy' for castom",title)) ; 
169      }
170     }
171   }
172    
173   GetGeometry() ; 
174
175   
176 }
177
178 //____________________________________________________________________________
179 void AliPHOSv0::CreateGeometry()
180 {
181   // Create the PHOS geometry for Geant
182
183   AliPHOSv0 *phostmp = dynamic_cast<AliPHOSv0*>(gAlice->GetModule("PHOS")) ;
184
185   if ( phostmp == NULL ) {
186     
187     fprintf(stderr, "PHOS detector not found!\n") ;
188     return;
189     
190   }
191
192   AliPHOSGeometry * geom = GetGeometry() ; 
193
194   // Get pointer to the array containing media indeces
195   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
196
197   // Create a PHOS module.
198   
199   TVirtualMC::GetMC()->Gsvolu("PHOS", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;        
200   if(fCreateHalfMod){
201     TVirtualMC::GetMC()->Gsvolu("PHOH", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;        
202   }
203   if(fCreateCPV){
204     TVirtualMC::GetMC()->Gsvolu("PHOC", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;             
205   }
206   
207   this->CreateGeometryforEMC() ; 
208   //Should we create 4-th module
209
210   if (fCreateCPV) 
211     this->CreateGeometryforCPV() ;
212   
213   this->CreateGeometryforSupport() ; 
214   
215   // --- Position  PHOS mdules in ALICE setup ---
216   Int_t idrotm[99] ;
217   Int_t iXYZ,iAngle;
218   char im[5] ;
219   for (Int_t iModule = 0; iModule < 5 ; iModule++ ) {
220     snprintf(im,5,"%d",iModule+1) ;
221     if(!fActiveModule[iModule+1])
222       continue ;
223     Float_t angle[3][2];
224     for (iXYZ=0; iXYZ<3; iXYZ++)
225       for (iAngle=0; iAngle<2; iAngle++)
226         angle[iXYZ][iAngle] = geom->GetModuleAngle(iModule,iXYZ, iAngle);
227     AliMatrix(idrotm[iModule],
228               angle[0][0],angle[0][1],
229               angle[1][0],angle[1][1],
230               angle[2][0],angle[2][1]) ;
231     
232     Float_t pos[3];
233     for (iXYZ=0; iXYZ<3; iXYZ++)
234       pos[iXYZ] = geom->GetModuleCenter(iModule,iXYZ);
235     if(iModule==3){ //special 1/2 module
236        TVirtualMC::GetMC()->Gspos("PHOH", iModule+1, "ALIC", pos[0], pos[1], pos[2],
237                idrotm[iModule], "ONLY") ;
238     }
239     else{
240       if(fActiveCPV[iModule+1]){ //use module with CPV
241         TVirtualMC::GetMC()->Gspos("PHOC", iModule+1, "ALIC", pos[0], pos[1], pos[2],
242                idrotm[iModule], "ONLY") ;
243       }
244       else{ //module wihtout CPV
245         TVirtualMC::GetMC()->Gspos("PHOS", iModule+1, "ALIC", pos[0], pos[1], pos[2],
246                idrotm[iModule], "ONLY") ;
247       }
248    }
249   }
250 }
251
252 //____________________________________________________________________________
253 void AliPHOSv0::CreateGeometryforEMC()
254 {
255   // Create the PHOS-EMC geometry for GEANT
256   // Author: Dmitri Peressounko August 2001
257   // The used coordinate system: 
258   //   1. in Module: X along longer side, Y out of beam, Z along shorter side (along beam)
259   //   2. In Strip the same: X along longer side, Y out of beam, Z along shorter side (along beam)
260
261
262     //BEGIN_HTML
263   /*
264     <H2>
265     Geant3 geometry tree of PHOS-EMC in ALICE
266     </H2>
267     <P><CENTER>
268     <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/EMCinAlice.gif"> 
269     </CENTER><P>
270   */
271   //END_HTML  
272   
273   // Get pointer to the array containing media indexes
274   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
275
276   AliPHOSGeometry * geom = GetGeometry() ; 
277   AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
278   Float_t par[4];
279   Int_t  ipar;
280   
281   // ======= Define the strip ===============
282
283   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetStripHalfSize() + ipar);
284   TVirtualMC::GetMC()->Gsvolu("PSTR", "BOX ", idtmed[716], par, 3) ;  //Made of steel
285
286   // --- define steel volume (cell of the strip unit)
287   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetAirCellHalfSize() + ipar);
288   TVirtualMC::GetMC()->Gsvolu("PCEL", "BOX ", idtmed[798], par, 3);
289
290   // --- define wrapped crystal and put it into steel cell
291
292   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetWrappedHalfSize() + ipar);
293   TVirtualMC::GetMC()->Gsvolu("PWRA", "BOX ", idtmed[702], par, 3);
294   const Float_t * pin    = emcg->GetAPDHalfSize() ; 
295   const Float_t * preamp = emcg->GetPreampHalfSize() ;
296   Float_t y = (emcg->GetAirGapLed()-2*pin[1]-2*preamp[1])/2;
297   TVirtualMC::GetMC()->Gspos("PWRA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
298     
299   // --- Define crystal and put it into wrapped crystall ---
300   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetCrystalHalfSize() + ipar);
301   TVirtualMC::GetMC()->Gsvolu("PXTL", "BOX ", idtmed[699], par, 3) ;
302   TVirtualMC::GetMC()->Gspos("PXTL", 1, "PWRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
303   
304   // --- define APD/PIN preamp and put it into AirCell
305  
306   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetAPDHalfSize() + ipar);
307   TVirtualMC::GetMC()->Gsvolu("PPIN", "BOX ", idtmed[705], par, 3) ;
308   const Float_t * crystal = emcg->GetCrystalHalfSize() ;
309   y = crystal[1] + emcg->GetAirGapLed() /2 - preamp[1]; 
310   TVirtualMC::GetMC()->Gspos("PPIN", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
311   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetPreampHalfSize() + ipar);
312   TVirtualMC::GetMC()->Gsvolu("PREA", "BOX ", idtmed[711], par, 3) ;   // Here I assumed preamp as a printed Circuit
313   y = crystal[1] + emcg->GetAirGapLed() /2 + pin[1]  ;    // May it should be changed
314   TVirtualMC::GetMC()->Gspos("PREA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ; // to ceramics?
315   
316   
317   // --- Fill strip with wrapped cristals in steel cells
318   
319   const Float_t* splate = emcg->GetSupportPlateHalfSize();  
320   y = -splate[1] ;
321   const Float_t* acel = emcg->GetAirCellHalfSize() ;
322   
323   for(Int_t lev = 2, icel = 1; 
324       icel <= emcg->GetNCellsXInStrip()*emcg->GetNCellsZInStrip(); 
325       icel += 2, lev += 2) {
326     Float_t x = (2*(lev / 2) - 1 - emcg->GetNCellsXInStrip())* acel[0] ;
327     Float_t z = acel[2];
328     TVirtualMC::GetMC()->Gspos("PCEL", icel, "PSTR", x, y, +z, 0, "ONLY") ;
329     TVirtualMC::GetMC()->Gspos("PCEL", icel + 1, "PSTR", x, y, -z, 0, "ONLY") ;
330   }
331
332   // --- define the support plate, hole in it and position it in strip ----
333   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetSupportPlateHalfSize() + ipar);
334   TVirtualMC::GetMC()->Gsvolu("PSUP", "BOX ", idtmed[701], par, 3) ;
335   
336   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetSupportPlateInHalfSize() + ipar);
337   TVirtualMC::GetMC()->Gsvolu("PSHO", "BOX ", idtmed[798], par, 3) ;
338   Float_t z = emcg->GetSupportPlateThickness()/2 ;
339   TVirtualMC::GetMC()->Gspos("PSHO", 1, "PSUP", 0.0, 0.0, z, 0, "ONLY") ;
340
341   y = acel[1] ;
342   TVirtualMC::GetMC()->Gspos("PSUP", 1, "PSTR", 0.0, y, 0.0, 0, "ONLY") ;
343
344   
345   // ========== Fill module with strips and put them into inner thermoinsulation=============
346   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetInnerThermoHalfSize() + ipar);
347   TVirtualMC::GetMC()->Gsvolu("PTII", "BOX ", idtmed[706], par, 3) ;     
348   
349   if(fCreateHalfMod)
350     TVirtualMC::GetMC()->Gsvolu("PTIH", "BOX ", idtmed[706], par, 3) ;     
351     
352   
353   const Float_t * inthermo = emcg->GetInnerThermoHalfSize() ;
354   const Float_t * strip    = emcg->GetStripHalfSize() ;
355   y = inthermo[1] - strip[1] ;
356   Int_t irow;
357   Int_t nr = 1 ;
358   Int_t icol ;
359   
360   for(irow = 0; irow < emcg->GetNStripX(); irow ++){
361     Float_t x = (2*irow + 1 - emcg->GetNStripX())* strip[0] ;
362     for(icol = 0; icol < emcg->GetNStripZ(); icol ++){
363       z = (2*icol + 1 - emcg->GetNStripZ()) * strip[2] ;
364       TVirtualMC::GetMC()->Gspos("PSTR", nr, "PTII", x, y, z, 0, "ONLY") ;
365       nr++ ;
366     }
367   }
368   if(fCreateHalfMod){
369     nr = 1 ;
370     for(irow = 0; irow < emcg->GetNStripX(); irow ++){
371       Float_t x = (2*irow + 1 - emcg->GetNStripX())* strip[0] ;
372       for(icol = 0; icol < emcg->GetNStripZ(); icol ++){
373         z = (2*icol + 1 - emcg->GetNStripZ()) * strip[2] ;
374         if(irow>=emcg->GetNStripX()/2)
375           TVirtualMC::GetMC()->Gspos("PSTR", nr, "PTIH", x, y, z, 0, "ONLY") ;
376         nr++ ;
377       }
378     }
379   }
380   
381   // ------- define the air gap between thermoinsulation and cooler
382   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetAirGapHalfSize() + ipar);
383   TVirtualMC::GetMC()->Gsvolu("PAGA", "BOX ", idtmed[798], par, 3) ;   
384   if(fCreateHalfMod)
385     TVirtualMC::GetMC()->Gsvolu("PAGH", "BOX ", idtmed[798], par, 3) ;   
386   const Float_t * agap = emcg->GetAirGapHalfSize() ;
387   y = agap[1] - inthermo[1]  ;
388   
389   TVirtualMC::GetMC()->Gspos("PTII", 1, "PAGA", 0.0, y, 0.0, 0, "ONLY") ;
390   if(fCreateHalfMod)
391     TVirtualMC::GetMC()->Gspos("PTIH", 1, "PAGH", 0.0, y, 0.0, 0, "ONLY") ;
392
393
394   // ------- define the Al passive cooler 
395   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetCoolerHalfSize() + ipar);
396   TVirtualMC::GetMC()->Gsvolu("PCOR", "BOX ", idtmed[701], par, 3) ;   
397   if(fCreateHalfMod)
398     TVirtualMC::GetMC()->Gsvolu("PCOH", "BOX ", idtmed[701], par, 3) ;   
399
400   const Float_t * cooler = emcg->GetCoolerHalfSize() ;
401   y = cooler[1] - agap[1]  ;
402   
403   TVirtualMC::GetMC()->Gspos("PAGA", 1, "PCOR", 0.0, y, 0.0, 0, "ONLY") ;
404   if(fCreateHalfMod)
405     TVirtualMC::GetMC()->Gspos("PAGH", 1, "PCOH", 0.0, y, 0.0, 0, "ONLY") ;
406   
407   // ------- define the outer thermoinsulating cover
408   for (ipar=0; ipar<4; ipar++) par[ipar] = *(emcg->GetOuterThermoParams() + ipar);
409   TVirtualMC::GetMC()->Gsvolu("PTIO", "TRD1", idtmed[706], par, 4) ;        
410   if(fCreateHalfMod)
411     TVirtualMC::GetMC()->Gsvolu("PIOH", "TRD1", idtmed[706], par, 4) ;        
412   const Float_t * outparams = emcg->GetOuterThermoParams() ; 
413   
414   Int_t idrotm[99] ;
415   AliMatrix(idrotm[1], 90.0, 0.0, 0.0, 0.0, 90.0, 270.0) ;
416   // Frame in outer thermoinsulation and so on: z out of beam, y along beam, x across beam
417   
418   z = outparams[3] - cooler[1] ;
419   TVirtualMC::GetMC()->Gspos("PCOR", 1, "PTIO", 0., 0.0, z, idrotm[1], "ONLY") ;
420   if(fCreateHalfMod)
421     TVirtualMC::GetMC()->Gspos("PCOH", 1, "PIOH", 0., 0.0, z, idrotm[1], "ONLY") ;
422   
423   // -------- Define the outer Aluminium cover -----
424   for (ipar=0; ipar<4; ipar++) par[ipar] = *(emcg->GetAlCoverParams() + ipar);
425   TVirtualMC::GetMC()->Gsvolu("PCOL", "TRD1", idtmed[701], par, 4) ;        
426   if(fCreateHalfMod)
427     TVirtualMC::GetMC()->Gsvolu("PCLH", "TRD1", idtmed[701], par, 4) ;        
428
429   const Float_t * covparams = emcg->GetAlCoverParams() ; 
430   z = covparams[3] - outparams[3] ;  
431   TVirtualMC::GetMC()->Gspos("PTIO", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
432   if(fCreateHalfMod)
433     TVirtualMC::GetMC()->Gspos("PIOH", 1, "PCLH", 0., 0.0, z, 0, "ONLY") ;
434
435   // --------- Define front fiberglass cover -----------
436   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFiberGlassHalfSize() + ipar);
437   TVirtualMC::GetMC()->Gsvolu("PFGC", "BOX ", idtmed[717], par, 3) ;  
438   z = - outparams[3] ;
439   TVirtualMC::GetMC()->Gspos("PFGC", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
440   if(fCreateHalfMod)
441     TVirtualMC::GetMC()->Gspos("PFGC", 1, "PCLH", 0., 0.0, z, 0, "ONLY") ;
442
443   //=============This is all with cold section==============
444   
445
446   //------ Warm Section --------------
447   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetWarmAlCoverHalfSize() + ipar);
448   TVirtualMC::GetMC()->Gsvolu("PWAR", "BOX ", idtmed[701], par, 3) ; 
449   const Float_t * warmcov = emcg->GetWarmAlCoverHalfSize() ;
450   
451   // --- Define the outer thermoinsulation ---
452   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetWarmThermoHalfSize() + ipar);
453   TVirtualMC::GetMC()->Gsvolu("PWTI", "BOX ", idtmed[706], par, 3) ; 
454   const Float_t * warmthermo = emcg->GetWarmThermoHalfSize() ;
455   z = -warmcov[2] + warmthermo[2] ;
456   
457   TVirtualMC::GetMC()->Gspos("PWTI", 1, "PWAR", 0., 0.0, z, 0, "ONLY") ;     
458   
459   // --- Define cables area and put in it T-supports ---- 
460   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTCables1HalfSize() + ipar);
461   TVirtualMC::GetMC()->Gsvolu("PCA1", "BOX ", idtmed[718], par, 3) ; 
462   const Float_t * cbox = emcg->GetTCables1HalfSize() ;
463   
464   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTSupport1HalfSize() + ipar);
465   TVirtualMC::GetMC()->Gsvolu("PBE1", "BOX ", idtmed[701], par, 3) ;
466   const Float_t * beams = emcg->GetTSupport1HalfSize() ;
467   Int_t isup ;
468   for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
469     Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
470     TVirtualMC::GetMC()->Gspos("PBE1", isup, "PCA1", x, 0.0, 0.0, 0, "ONLY") ;
471   }
472   
473   z = -warmthermo[2] + cbox[2];
474   TVirtualMC::GetMC()->Gspos("PCA1", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;     
475   
476   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTCables2HalfSize() + ipar);
477   TVirtualMC::GetMC()->Gsvolu("PCA2", "BOX ", idtmed[718], par, 3) ; 
478   const Float_t * cbox2 = emcg->GetTCables2HalfSize() ;
479   
480   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTSupport2HalfSize() + ipar);
481   TVirtualMC::GetMC()->Gsvolu("PBE2", "BOX ", idtmed[701], par, 3) ;
482   for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
483     Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
484     TVirtualMC::GetMC()->Gspos("PBE2", isup, "PCA2", x, 0.0, 0.0, 0, "ONLY") ;
485   }
486   
487   z = -warmthermo[2] + 2*cbox[2] + cbox2[2];
488   TVirtualMC::GetMC()->Gspos("PCA2", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;     
489   
490   // --- Define frame ---
491   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFrameXHalfSize() + ipar);
492   TVirtualMC::GetMC()->Gsvolu("PFRX", "BOX ", idtmed[716], par, 3) ; 
493   const Float_t * posit1 = emcg->GetFrameXPosition() ;
494   TVirtualMC::GetMC()->Gspos("PFRX", 1, "PWTI", posit1[0],  posit1[1], posit1[2], 0, "ONLY") ;
495   TVirtualMC::GetMC()->Gspos("PFRX", 2, "PWTI", posit1[0], -posit1[1], posit1[2], 0, "ONLY") ;
496   
497   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFrameZHalfSize() + ipar);
498   TVirtualMC::GetMC()->Gsvolu("PFRZ", "BOX ", idtmed[716], par, 3) ; 
499   const Float_t * posit2 = emcg->GetFrameZPosition() ;
500   TVirtualMC::GetMC()->Gspos("PFRZ", 1, "PWTI",  posit2[0], posit2[1], posit2[2], 0, "ONLY") ;
501   TVirtualMC::GetMC()->Gspos("PFRZ", 2, "PWTI", -posit2[0], posit2[1], posit2[2], 0, "ONLY") ;
502
503  // --- Define Fiber Glass support ---
504   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGupXHalfSize() + ipar);
505   TVirtualMC::GetMC()->Gsvolu("PFG1", "BOX ", idtmed[717], par, 3) ; 
506   const Float_t * posit3 = emcg->GetFGupXPosition() ;
507   TVirtualMC::GetMC()->Gspos("PFG1", 1, "PWTI", posit3[0],  posit3[1], posit3[2], 0, "ONLY") ;
508   TVirtualMC::GetMC()->Gspos("PFG1", 2, "PWTI", posit3[0], -posit3[1], posit3[2], 0, "ONLY") ;
509   
510   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGupZHalfSize() + ipar);
511   TVirtualMC::GetMC()->Gsvolu("PFG2", "BOX ", idtmed[717], par, 3) ; 
512   const Float_t * posit4 = emcg->GetFGupZPosition();
513   TVirtualMC::GetMC()->Gspos("PFG2", 1, "PWTI",  posit4[0], posit4[1], posit4[2], 0, "ONLY") ;
514   TVirtualMC::GetMC()->Gspos("PFG2", 2, "PWTI", -posit4[0], posit4[1], posit4[2], 0, "ONLY") ;
515   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGlowXHalfSize() + ipar);
516   TVirtualMC::GetMC()->Gsvolu("PFG3", "BOX ", idtmed[717], par, 3) ; 
517   const Float_t * posit5 = emcg->GetFGlowXPosition() ;
518   TVirtualMC::GetMC()->Gspos("PFG3", 1, "PWTI", posit5[0],  posit5[1], posit5[2], 0, "ONLY") ;
519   TVirtualMC::GetMC()->Gspos("PFG3", 2, "PWTI", posit5[0], -posit5[1], posit5[2], 0, "ONLY") ;
520     
521   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGlowZHalfSize() + ipar);
522   TVirtualMC::GetMC()->Gsvolu("PFG4", "BOX ", idtmed[717], par, 3) ; 
523   const Float_t * posit6 = emcg->GetFGlowZPosition() ;
524   TVirtualMC::GetMC()->Gspos("PFG4", 1, "PWTI",  posit6[0], posit6[1], posit6[2], 0, "ONLY") ;
525   TVirtualMC::GetMC()->Gspos("PFG4", 2, "PWTI", -posit6[0], posit6[1], posit6[2], 0, "ONLY") ;
526
527   // --- Define Air Gap for FEE electronics -----   
528   for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFEEAirHalfSize() + ipar);
529   TVirtualMC::GetMC()->Gsvolu("PAFE", "BOX ", idtmed[798], par, 3) ; 
530   const Float_t * posit7 = emcg->GetFEEAirPosition() ;
531   TVirtualMC::GetMC()->Gspos("PAFE", 1, "PWTI",  posit7[0], posit7[1], posit7[2], 0, "ONLY") ;
532   
533   // Define the EMC module volume and combine Cool and Warm sections  
534   for (ipar=0; ipar<4; ipar++) par[ipar] = *(emcg->GetEMCParams() + ipar);
535   TVirtualMC::GetMC()->Gsvolu("PEMC", "TRD1", idtmed[798], par, 4) ;        
536   if(fCreateHalfMod)
537     TVirtualMC::GetMC()->Gsvolu("PEMH", "TRD1", idtmed[798], par, 4) ;        
538   z =  - warmcov[2] ;
539   TVirtualMC::GetMC()->Gspos("PCOL", 1, "PEMC",  0., 0., z, 0, "ONLY") ;
540   if(fCreateHalfMod)
541     TVirtualMC::GetMC()->Gspos("PCLH", 1, "PEMH",  0., 0., z, 0, "ONLY") ;
542   z = covparams[3] ;
543   TVirtualMC::GetMC()->Gspos("PWAR", 1, "PEMC",  0., 0., z, 0, "ONLY") ;
544   if(fCreateHalfMod)
545     TVirtualMC::GetMC()->Gspos("PWAR", 1, "PEMH",  0., 0., z, 0, "ONLY") ;
546   
547   
548   // Put created EMC geometry into PHOS volume
549   
550   z = geom->GetCPVBoxSize(1) / 2. ;
551   //normal PHOS module
552   TVirtualMC::GetMC()->Gspos("PEMC", 1, "PHOS", 0., 0., z, 0, "ONLY") ; 
553   if(fCreateCPV) //Module with CPV 
554     TVirtualMC::GetMC()->Gspos("PEMC", 1, "PHOC", 0., 0., z, 0, "ONLY") ;   
555   if(fCreateHalfMod) //half of PHOS module
556     TVirtualMC::GetMC()->Gspos("PEMH", 1, "PHOH", 0., 0., z, 0, "ONLY") ; 
557   
558 }
559
560 //____________________________________________________________________________
561 void AliPHOSv0::CreateGeometryforCPV()
562 {
563   
564 printf("Create CPV geometry \n") ;  
565   
566   // Create the PHOS-CPV geometry for GEANT
567   // Author: Yuri Kharlov 11 September 2000
568   //BEGIN_HTML
569   /*
570     <H2>
571     Geant3 geometry of PHOS-CPV in ALICE
572     </H2>
573     <table width=700>
574
575     <tr>
576          <td>CPV perspective view</td>
577          <td>CPV front view      </td>
578     </tr>
579
580     <tr>
581          <td> <img height=300 width=290 src="../images/CPVallPersp.gif"> </td>
582          <td> <img height=300 width=290 src="../images/CPVallFront.gif"> </td>
583     </tr>
584
585     <tr>
586          <td>One CPV module, perspective view                            </td>
587          <td>One CPV module, front view (extended in vertical direction) </td>
588     </tr>
589
590     <tr>
591          <td><img height=300 width=290 src="../images/CPVmodulePers.gif"></td>
592          <td><img height=300 width=290 src="../images/CPVmoduleSide.gif"></td>
593     </tr>
594
595     </table>
596
597     <H2>
598     Geant3 geometry tree of PHOS-CPV in ALICE
599     </H2>
600     <center>
601     <img height=300 width=290 src="../images/CPVtree.gif">
602     </center>
603   */
604   //END_HTML  
605
606   Float_t par[3], x,y,z;
607
608   // Get pointer to the array containing media indexes
609   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
610
611   AliPHOSGeometry * geom = GetGeometry() ; 
612
613   // The box containing all CPV for one PHOS module filled with air 
614   par[0] = geom->GetCPVBoxSize(0) / 2.0 ;  
615   par[1] = geom->GetCPVBoxSize(1) / 2.0 ; 
616   par[2] = geom->GetCPVBoxSize(2) / 2.0 ;
617   TVirtualMC::GetMC()->Gsvolu("PCPV", "BOX ", idtmed[798], par, 3) ;
618
619   const Float_t * emcParams = geom->GetEMCAGeometry()->GetEMCParams() ;
620   z = - emcParams[3] ;
621   Int_t rotm ;
622   AliMatrix(rotm, 90.,0., 0., 0., 90., 90.) ;
623
624   TVirtualMC::GetMC()->Gspos("PCPV", 1, "PHOC", 0.0, 0.0, z, rotm, "ONLY") ; 
625   
626   // Gassiplex board
627   
628   par[0] = geom->GetGassiplexChipSize(0)/2.;
629   par[1] = geom->GetGassiplexChipSize(1)/2.;
630   par[2] = geom->GetGassiplexChipSize(2)/2.;
631   TVirtualMC::GetMC()->Gsvolu("PCPC","BOX ",idtmed[707],par,3);
632   
633   // Cu+Ni foil covers Gassiplex board
634
635   par[1] = geom->GetCPVCuNiFoilThickness()/2;
636   TVirtualMC::GetMC()->Gsvolu("PCPD","BOX ",idtmed[710],par,3);
637   y      = -(geom->GetGassiplexChipSize(1)/2 - par[1]);
638   TVirtualMC::GetMC()->Gspos("PCPD",1,"PCPC",0,y,0,0,"ONLY");
639
640   // Position of the chip inside CPV
641
642   Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
643   Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ()   + 1);
644   Int_t   copy  = 0;
645   y = geom->GetCPVFrameSize(1)/2           - geom->GetFTPosition(0) +
646     geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
647   for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
648     x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
649     for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
650       copy++;
651       z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
652       TVirtualMC::GetMC()->Gspos("PCPC",copy,"PCPV",x,y,z,0,"ONLY");
653     }
654   }
655
656   // Foiled textolite (1 mm of textolite + 50 mkm of Cu + 6 mkm of Ni)
657   
658   par[0] = geom->GetCPVActiveSize(0)        / 2;
659   par[1] = geom->GetCPVTextoliteThickness() / 2;
660   par[2] = geom->GetCPVActiveSize(1)        / 2;
661   TVirtualMC::GetMC()->Gsvolu("PCPF","BOX ",idtmed[707],par,3);
662
663   // Argon gas volume
664
665   par[1] = (geom->GetFTPosition(2) - geom->GetFTPosition(1) - geom->GetCPVTextoliteThickness()) / 2;
666   TVirtualMC::GetMC()->Gsvolu("PCPG","BOX ",idtmed[715],par,3);
667
668   for (Int_t i=0; i<4; i++) {
669     y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(i) + geom->GetCPVTextoliteThickness()/2;
670     TVirtualMC::GetMC()->Gspos("PCPF",i+1,"PCPV",0,y,0,0,"ONLY");
671     if(i==1){
672       y-= (geom->GetFTPosition(2) - geom->GetFTPosition(1)) / 2;
673       TVirtualMC::GetMC()->Gspos("PCPG",1,"PCPV ",0,y,0,0,"ONLY");
674     }
675   }
676
677   // Dummy sensitive plane in the middle of argone gas volume
678
679   par[1]=0.001;
680   TVirtualMC::GetMC()->Gsvolu("PCPQ","BOX ",idtmed[715],par,3);
681   TVirtualMC::GetMC()->Gspos ("PCPQ",1,"PCPG",0,0,0,0,"ONLY");
682
683   // Cu+Ni foil covers textolite
684
685   par[1] = geom->GetCPVCuNiFoilThickness() / 2;
686   TVirtualMC::GetMC()->Gsvolu("PCP1","BOX ",idtmed[710],par,3);
687   y = geom->GetCPVTextoliteThickness()/2 - par[1];
688   TVirtualMC::GetMC()->Gspos ("PCP1",1,"PCPF",0,y,0,0,"ONLY");
689
690   // Aluminum frame around CPV
691
692   par[0] = geom->GetCPVFrameSize(0)/2;
693   par[1] = geom->GetCPVFrameSize(1)/2;
694   par[2] = geom->GetCPVBoxSize(2)  /2;
695   TVirtualMC::GetMC()->Gsvolu("PCF1","BOX ",idtmed[701],par,3);
696
697   par[0] = geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0);
698   par[1] = geom->GetCPVFrameSize(1)/2;
699   par[2] = geom->GetCPVFrameSize(2)/2;
700   TVirtualMC::GetMC()->Gsvolu("PCF2","BOX ",idtmed[701],par,3);
701
702   for (Int_t j=0; j<=1; j++) {
703     x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
704     TVirtualMC::GetMC()->Gspos("PCF1",j+1,"PCPV", x,0,0,0,"ONLY");
705     z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
706     TVirtualMC::GetMC()->Gspos("PCF2",j+1,"PCPV",0, 0,z,0,"ONLY");
707   }
708
709 }
710
711
712 //____________________________________________________________________________
713 void AliPHOSv0::CreateGeometryforSupport()
714 {
715   // Create the PHOS' support geometry for GEANT
716     //BEGIN_HTML
717   /*
718     <H2>
719     Geant3 geometry of the PHOS's support
720     </H2>
721     <P><CENTER>
722     <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/PHOS_support.gif"> 
723     </CENTER><P>
724   */
725   //END_HTML  
726   
727   Float_t par[5], x0,y0,z0 ; 
728   Int_t   i,j,copy;
729
730   // Get pointer to the array containing media indexes
731   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
732
733   AliPHOSGeometry * geom = GetGeometry() ; 
734
735   // --- Dummy box containing two rails on which PHOS support moves
736   // --- Put these rails to the bottom of the L3 magnet
737
738   par[0] =  geom->GetRailRoadSize(0) / 2.0 ;
739   par[1] =  geom->GetRailRoadSize(1) / 2.0 ;
740   par[2] =  geom->GetRailRoadSize(2) / 2.0 ;
741   TVirtualMC::GetMC()->Gsvolu("PRRD", "BOX ", idtmed[798], par, 3) ;
742
743   y0     = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) / 2.0) ;
744   TVirtualMC::GetMC()->Gspos("PRRD", 1, "ALIC", 0.0, y0, 0.0, 0, "ONLY") ; 
745
746   // --- Dummy box containing one rail
747
748   par[0] =  geom->GetRailOuterSize(0) / 2.0 ;
749   par[1] =  geom->GetRailOuterSize(1) / 2.0 ;
750   par[2] =  geom->GetRailOuterSize(2) / 2.0 ;
751   TVirtualMC::GetMC()->Gsvolu("PRAI", "BOX ", idtmed[798], par, 3) ;
752
753   for (i=0; i<2; i++) {
754     x0     = (2*i-1) * geom->GetDistanceBetwRails()  / 2.0 ;
755     TVirtualMC::GetMC()->Gspos("PRAI", i, "PRRD", x0, 0.0, 0.0, 0, "ONLY") ; 
756   }
757
758   // --- Upper and bottom steel parts of the rail
759
760   par[0] =  geom->GetRailPart1(0) / 2.0 ;
761   par[1] =  geom->GetRailPart1(1) / 2.0 ;
762   par[2] =  geom->GetRailPart1(2) / 2.0 ;
763   TVirtualMC::GetMC()->Gsvolu("PRP1", "BOX ", idtmed[716], par, 3) ;
764
765   y0     = - (geom->GetRailOuterSize(1) - geom->GetRailPart1(1))  / 2.0 ;
766   TVirtualMC::GetMC()->Gspos("PRP1", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
767   y0     =   (geom->GetRailOuterSize(1) - geom->GetRailPart1(1))  / 2.0 - geom->GetRailPart3(1);
768   TVirtualMC::GetMC()->Gspos("PRP1", 2, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
769
770   // --- The middle vertical steel parts of the rail
771
772   par[0] =  geom->GetRailPart2(0) / 2.0 ;
773   par[1] =  geom->GetRailPart2(1) / 2.0 ;
774   par[2] =  geom->GetRailPart2(2) / 2.0 ;
775   TVirtualMC::GetMC()->Gsvolu("PRP2", "BOX ", idtmed[716], par, 3) ;
776
777   y0     =   - geom->GetRailPart3(1) / 2.0 ;
778   TVirtualMC::GetMC()->Gspos("PRP2", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ; 
779
780   // --- The most upper steel parts of the rail
781
782   par[0] =  geom->GetRailPart3(0) / 2.0 ;
783   par[1] =  geom->GetRailPart3(1) / 2.0 ;
784   par[2] =  geom->GetRailPart3(2) / 2.0 ;
785   TVirtualMC::GetMC()->Gsvolu("PRP3", "BOX ", idtmed[716], par, 3) ;
786
787   y0     =   (geom->GetRailOuterSize(1) - geom->GetRailPart3(1))  / 2.0 ;
788   TVirtualMC::GetMC()->Gspos("PRP3", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ; 
789
790   // --- The wall of the cradle
791   // --- The wall is empty: steel thin walls and air inside
792
793   par[1] =  TMath::Sqrt(TMath::Power((geom->GetIPtoCPVDistance() + geom->GetOuterBoxSize(3)),2) +
794                         TMath::Power((geom->GetOuterBoxSize(1)/2),2))+10. ;
795   par[0] =  par[1] - geom->GetCradleWall(1) ;
796   par[2] =  geom->GetCradleWall(2) / 2.0 ;
797   par[3] =  geom->GetCradleWall(3) ;
798   par[4] =  geom->GetCradleWall(4) ;
799   TVirtualMC::GetMC()->Gsvolu("PCRA", "TUBS", idtmed[716], par, 5) ;
800
801   par[0] +=  geom->GetCradleWallThickness() ;
802   par[1] -=  geom->GetCradleWallThickness() ;
803   par[2] -=  geom->GetCradleWallThickness() ;
804   TVirtualMC::GetMC()->Gsvolu("PCRE", "TUBS", idtmed[798], par, 5) ;
805   TVirtualMC::GetMC()->Gspos ("PCRE", 1, "PCRA", 0.0, 0.0, 0.0, 0, "ONLY") ; 
806
807   for (i=0; i<2; i++) {
808     z0 = (2*i-1) * (geom->GetOuterBoxSize(2) + geom->GetCradleWall(2) )/ 2.0  ;
809         TVirtualMC::GetMC()->Gspos("PCRA", i, "ALIC", 0.0, 0.0, z0, 0, "ONLY") ; 
810   }
811
812   // --- The "wheels" of the cradle
813   
814   par[0] = geom->GetCradleWheel(0) / 2;
815   par[1] = geom->GetCradleWheel(1) / 2;
816   par[2] = geom->GetCradleWheel(2) / 2;
817   TVirtualMC::GetMC()->Gsvolu("PWHE", "BOX ", idtmed[716], par, 3) ;
818
819   y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) -
820          geom->GetCradleWheel(1)/2) ;
821   for (i=0; i<2; i++) {
822     z0 = (2*i-1) * ((geom->GetOuterBoxSize(2) + geom->GetCradleWheel(2))/ 2.0 +
823                     geom->GetCradleWall(2));
824     for (j=0; j<2; j++) {
825       copy = 2*i + j;
826       x0 = (2*j-1) * geom->GetDistanceBetwRails()  / 2.0 ;
827       TVirtualMC::GetMC()->Gspos("PWHE", copy, "ALIC", x0, y0, z0, 0, "ONLY") ; 
828     }
829   }
830
831 }
832
833 //_____________________________________________________________________________
834 void AliPHOSv0::AddAlignableVolumes() const
835 {
836   //
837   // Create entries for alignable volumes associating the symbolic volume
838   // name with the corresponding volume path. Needs to be syncronized with
839   // eventual changes in the geometry
840   // Alignable volumes are:
841   // 1) PHOS modules as a whole
842   // 2) Cradle
843   // 3) Cradle wheels
844   // 4) Strip units (group of 2x8 crystals)
845
846   TString volpath, symname;
847
848   // Alignable modules
849   // Volume path /ALIC_1/PHOS_<i> => symbolic name /PHOS/Module<i>, <i>=1,2,3,4,5
850   
851   AliGeomManager::ELayerID idPHOS1 = AliGeomManager::kPHOS1;
852   AliGeomManager::ELayerID idPHOS2 = AliGeomManager::kPHOS2;
853   Int_t modUID, modnum = 0;
854   TString physModulePath="/ALIC_1/PHOS_";
855   TString physModulePath2="/ALIC_1/PHOH_";
856   TString physModulePath3="/ALIC_1/PHOC_";
857   TString symbModuleName="PHOS/Module";
858   Int_t nModules = GetGeometry()->GetNModules();
859   
860   for(Int_t iModule=1; iModule<=nModules; iModule++){
861     if(!fActiveModule[iModule])
862       continue ;
863     modUID = AliGeomManager::LayerToVolUID(idPHOS1,iModule-1);
864      if(iModule==4)
865       volpath = physModulePath2;
866     else
867       if(fActiveCPV[iModule])
868         volpath = physModulePath3;
869       else
870         volpath = physModulePath;       
871     volpath += iModule;
872     //    volpath += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1";
873  
874    // Check the volume path if not all 5 modules exist
875     if (!gGeoManager->CheckPath(volpath.Data())) {                                                                                         
876       AliError(Form("Volume path %s not valid!",volpath.Data()));                                                                          
877       continue;                                                                                                                            
878     }                                                                                                                                      
879  
880     symname = symbModuleName;
881     symname += iModule;
882     if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
883       continue ;
884 //      AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
885
886     // Creates the Tracking to Local transformation matrix for PHOS modules
887     TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
888
889     Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
890     TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
891
892     TGeoHMatrix *matTtoL = new TGeoHMatrix;
893     matTtoL->RotateZ(-90.+angle);
894     matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
895     alignableEntry->SetMatrix(matTtoL);
896   }
897
898   //Aligning of CPV should be done for volume PCPV_1
899   symbModuleName="PHOS/Module";
900   modnum=0;
901   for(Int_t iModule=1; iModule<=nModules; iModule++){
902     if(!fActiveCPV[iModule])
903       continue ;
904     modUID = AliGeomManager::LayerToVolUID(idPHOS2,iModule-1);
905     volpath = physModulePath3;
906     volpath += iModule;
907     volpath += "/PCPV_1";
908     // Check the volume path
909     if (!gGeoManager->CheckPath(volpath.Data())) {
910       AliError(Form("Volume path %s not valid!",volpath.Data()));
911       continue;
912     }
913
914     symname = symbModuleName;
915     symname += iModule;
916     symname += "/CPV";
917     if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
918       AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
919           
920     // Creates the TGeo Local to Tracking transformation matrix ...
921     TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
922
923     Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
924     TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
925
926     TGeoHMatrix *matTtoL = new TGeoHMatrix;
927     matTtoL->RotateZ(-90.+angle);
928     matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
929     alignableEntry->SetMatrix(matTtoL);
930     
931   }
932  
933
934   // Alignable cradle walls
935   // Volume path /ALIC_1/PCRA_<i> => symbolic name /PHOS/Cradle<i>, <i>=0,1
936
937   TString physCradlePath="/ALIC_1/PCRA_";
938   TString symbCradleName="PHOS/Cradle";
939   Int_t nCradles = 2;
940
941   for(Int_t iCradle=0; iCradle<nCradles; iCradle++){
942     volpath = physCradlePath;
943     volpath += iCradle;
944     symname = symbCradleName;
945     symname += iCradle;
946     gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
947   }
948
949   // Alignable wheels
950   // Volume path /ALIC_1/PWHE_<i> => symbolic name /PHOS/Wheel<i>, i=0,1,2,3
951
952   TString physWheelPath="/ALIC_1/PWHE_";
953   TString symbWheelName="PHOS/Wheel";
954   Int_t nWheels = 4;
955
956   for(Int_t iWheel=0; iWheel<nWheels; iWheel++){
957     volpath = physWheelPath;
958     volpath += iWheel;
959     symname = symbWheelName;
960     symname += iWheel;
961     gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
962   }
963
964   
965 /*  
966   //Physical strip path is a combination of: physModulePath + module number + 
967   //physStripPath + strip number == ALIC_1/PHOS_N/..../PSTR_M
968   const Int_t nStripsX = GetGeometry()->GetEMCAGeometry()->GetNStripX();
969   const Int_t nStripsZ = GetGeometry()->GetEMCAGeometry()->GetNStripZ();
970   TString partialPhysStripName(100);
971   TString fullPhysStripName(100);
972   TString partialSymbStripName(100);
973   TString fullSymbStripName(100);
974
975   for(Int_t module = 1; module <= nModules; ++module){
976
977     snprintf(im,5,"%d",module) ;
978     if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
979       continue ;
980
981     volpath = physModulePath;
982     volpath += module;
983     // Check the volume path if not all 5 modules exist
984     if (!gGeoManager->CheckPath(volpath.Data())) {
985       AliError(Form("Volume path %s does not exist",volpath.Data())) ;
986       continue;
987     }
988
989     partialPhysStripName  = physModulePath;
990     partialPhysStripName += module;
991     if(module!=4)
992       partialPhysStripName += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1/PSTR_";
993     else
994       partialPhysStripName += "/PEMH_1/PCLH_1/PIOH_1/PCOH_1/PAGH_1/PTIH_1/PSTR_";
995
996     partialSymbStripName  = symbModuleName;
997     partialSymbStripName += module;
998     partialSymbStripName += "/Strip_";
999
1000     for(Int_t i = 0, ind1D = 1; i < nStripsX; ++i){//ind1D starts from 1 (PSTR_1...PSTR_224...)
1001       for(Int_t j = 0; j < nStripsZ; ++j, ++ind1D){
1002          fullPhysStripName = partialPhysStripName;
1003          fullPhysStripName += ind1D;
1004          
1005          fullSymbStripName  = partialSymbStripName;
1006          fullSymbStripName += i;//ind1D;
1007          fullSymbStripName += '_';
1008          fullSymbStripName += j;
1009
1010          gGeoManager->SetAlignableEntry(fullSymbStripName.Data(), fullPhysStripName.Data());
1011
1012          // Creates the TGeo Local to Tracking transformation matrix ...
1013          TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntry(fullSymbStripName.Data()) ;
1014          const char *path = alignableEntry->GetTitle();
1015          if (!gGeoManager->cd(path))
1016            AliFatal(Form("Volume path %s not valid!",path));
1017          TGeoHMatrix matLtoT = *gGeoManager->GetCurrentMatrix() ;
1018          Double_t refl[3]={-1.,-1.,-1.} ;
1019          matLtoT.SetScale(refl) ;
1020          TGeoHMatrix *matTtoL = new TGeoHMatrix(matLtoT.Inverse());
1021  
1022          char phosPath[50] ;
1023          snprintf(phosPath,50,"/ALIC_1/PHOS_%d",module) ;
1024          if (!gGeoManager->cd(phosPath)){
1025             AliFatal("Geo manager can not find path \n");
1026          }
1027          TGeoHMatrix *mPHOS = gGeoManager->GetCurrentMatrix();
1028          if (mPHOS) 
1029            matTtoL->Multiply(mPHOS);
1030          else{
1031            AliFatal("Geo matrixes are not loaded \n") ;
1032          }
1033          //Switch y<->z
1034          Double_t rot[9]={1.,0.,0.,  0.,1.,0., 0.,0.,1.} ;
1035          matTtoL->SetRotation(rot) ;
1036          alignableEntry->SetMatrix(matTtoL);
1037 */
1038 /*
1039   //Check poisition of corner cell of the strip
1040   AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
1041   Int_t relid[4] ; 
1042   relid[0] = module ;
1043   relid[1] = 0 ;
1044   Int_t iStrip=ind1D ;
1045   Int_t icell=1 ;
1046   Int_t raw = geom->GetEMCAGeometry()->GetNCellsXInStrip()*((iStrip-1)/geom->GetEMCAGeometry()->GetNStripZ()) +
1047                 1 + (icell-1)/geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
1048   Int_t col = geom->GetEMCAGeometry()->GetNCellsZInStrip()*(1+(iStrip-1)%geom->GetEMCAGeometry()->GetNStripZ()) - 
1049                 (icell-1)%geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
1050   if(col==0) col=geom->GetNZ() ;
1051   relid[2] = raw ;
1052   relid[3] = col ;
1053   Float_t xG,zG ; 
1054   geom->RelPosInModule(relid, xG, zG) ;
1055 printf("============\n") ;
1056 printf("Geometry: x=%f, z=%f \n",xG,zG) ;
1057   Int_t absid ; 
1058   geom->RelToAbsNumbering(relid,absid) ;
1059   Double_t pos[3]= {-2.2*3.5,0.0,1.1}; //Position incide the strip (Y coordinalte is not important)
1060   Double_t posC[3]={0.0,0.0,0.}; //Global position
1061  
1062   matTtoL->MasterToLocal(pos,posC);
1063 printf("Matrix:   x=%f, z=%f, y=%f \n",posC[0],posC[2],posC[1]) ;
1064 */
1065 //      }
1066 //    }
1067 //  }
1068 }
1069
1070 //____________________________________________________________________________
1071 Float_t AliPHOSv0::ZMin(void) const
1072 {
1073   // Overall dimension of the PHOS (min)
1074
1075   AliPHOSGeometry * geom = GetGeometry() ; 
1076
1077   return -geom->GetOuterBoxSize(2)/2.;
1078 }
1079
1080 //____________________________________________________________________________
1081 Float_t AliPHOSv0::ZMax(void) const
1082 {
1083   // Overall dimension of the PHOS (max)
1084
1085   AliPHOSGeometry * geom = GetGeometry() ; 
1086
1087   return  geom->GetOuterBoxSize(2)/2.;
1088 }
1089
1090 //____________________________________________________________________________
1091 void AliPHOSv0::Init(void)
1092 {
1093   // Just prints an information message
1094   
1095   Int_t i;
1096
1097   if(AliLog::GetGlobalDebugLevel()>0) {
1098     TString st ; 
1099     for(i=0;i<35;i++) 
1100       st += "*";
1101     Info("Init", "%s", st.Data()) ;  
1102     // Here the PHOS initialisation code (if any!)
1103     
1104     AliPHOSGeometry * geom = GetGeometry() ; 
1105
1106     if (geom!=0)  
1107       Info("Init", "AliPHOS%s: PHOS geometry intialized for %s", Version().Data(), geom->GetName()) ;
1108     else
1109       Info("Init", "AliPHOS%s: PHOS geometry initialization failed !", Version().Data()) ;       
1110
1111     Info("Init", "%s", st.Data()) ;  
1112   }
1113 }