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