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