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