58dc89f66a5d507e83f5979da10ca17a84ade813
[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   
383   Int_t idrotm[99] ;
384   Int_t iXYZ,iAngle;
385   for (Int_t iModule = 0; iModule < geom->GetNModules(); iModule++ ) {
386     
387     Float_t angle[3][2];
388     for (iXYZ=0; iXYZ<3; iXYZ++)
389       for (iAngle=0; iAngle<2; iAngle++)
390         angle[iXYZ][iAngle] = geom->GetModuleAngle(iModule,iXYZ, iAngle);
391     AliMatrix(idrotm[iModule],
392               angle[0][0],angle[0][1],
393               angle[1][0],angle[1][1],
394               angle[2][0],angle[2][1]) ;
395     
396     Float_t pos[3];
397     for (iXYZ=0; iXYZ<3; iXYZ++)
398       pos[iXYZ] = geom->GetModuleCenter(iModule,iXYZ);
399     gMC->Gspos("PHOS", iModule+1, "ALIC", pos[0], pos[1], pos[2],
400                idrotm[iModule], "ONLY") ;
401   }
402
403 }
404
405 //____________________________________________________________________________
406 void AliPHOSv0::CreateGeometryforEMC()
407 {
408   // Create the PHOS-EMC geometry for GEANT
409   // Author: Dmitri Peressounko August 2001
410   // The used coordinate system: 
411   //   1. in Module: X along longer side, Y out of beam, Z along shorter side (along beam)
412   //   2. In Strip the same: X along longer side, Y out of beam, Z along shorter side (along beam)
413
414
415     //BEGIN_HTML
416   /*
417     <H2>
418     Geant3 geometry tree of PHOS-EMC in ALICE
419     </H2>
420     <P><CENTER>
421     <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/EMCinAlice.gif"> 
422     </CENTER><P>
423   */
424   //END_HTML  
425   
426   // Get pointer to the array containing media indexes
427   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
428
429   AliPHOSGeometry * geom = GetGeometry() ; 
430   AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
431
432   // ======= Define the strip ===============
433
434   gMC->Gsvolu("PSTR", "BOX ", idtmed[716], emcg->GetStripHalfSize(), 3) ;  //Made of steel
435    
436       // --- define steel volume (cell of the strip unit)
437 //       gMC->Gsvolu("PCEL", "BOX ", idtmed[798], emcg->GetSteelCellHalfSize(), 3);
438       gMC->Gsvolu("PCEL", "BOX ", idtmed[798], emcg->GetAirCellHalfSize(), 3);
439
440       // --- define wrapped crystal and put it into steel cell
441
442       gMC->Gsvolu("PWRA", "BOX ", idtmed[702], emcg->GetWrappedHalfSize(), 3);
443       Float_t * pin = emcg->GetAPDHalfSize() ; 
444       Float_t * preamp = emcg->GetPreampHalfSize() ;
445       Float_t y = (emcg->GetAirGapLed()-2*pin[1]-2*preamp[1])/2;
446       gMC->Gspos("PWRA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
447     
448       // --- Define crystal and put it into wrapped crystall ---
449       gMC->Gsvolu("PXTL", "BOX ", idtmed[699], emcg->GetCrystalHalfSize(), 3) ;
450       gMC->Gspos("PXTL", 1, "PWRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
451       
452       // --- define APD/PIN preamp and put it into AirCell
453  
454       gMC->Gsvolu("PPIN", "BOX ", idtmed[705], emcg->GetAPDHalfSize(), 3) ;
455       Float_t * crystal = emcg->GetCrystalHalfSize() ;
456       y = crystal[1] + emcg->GetAirGapLed() /2 - preamp[1]; 
457       gMC->Gspos("PPIN", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
458
459       gMC->Gsvolu("PREA", "BOX ", idtmed[711], emcg->GetPreampHalfSize(), 3) ;   // Here I assumed preamp
460                                                                                  // as a printed Circuit
461       y = crystal[1] + emcg->GetAirGapLed() /2 + pin[1]  ;                  // May it should be changed
462       gMC->Gspos("PREA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;                    // to ceramics?
463    
464
465       // --- Fill strip with wrapped cristals in steel cells
466
467       Float_t* splate = emcg->GetSupportPlateHalfSize();  
468       y = -splate[1] ;
469 //       Float_t* acel = emcg->GetSteelCellHalfSize() ;
470       Float_t* acel = emcg->GetAirCellHalfSize() ;
471
472       for(Int_t lev = 2, icel = 1; icel <= emcg->GetNCellsXInStrip()*emcg->GetNCellsZInStrip(); icel += 2, lev += 2){
473          Float_t x = (2*(lev / 2) - 1 - emcg->GetNCellsXInStrip())* acel[0] ;
474          Float_t z = acel[2];
475          gMC->Gspos("PCEL", icel, "PSTR", x, y, +z, 0, "ONLY") ;
476          gMC->Gspos("PCEL", icel + 1, "PSTR", x, y, -z, 0, "ONLY") ;
477       }
478
479       // --- define the support plate, hole in it and position it in strip ----
480       gMC->Gsvolu("PSUP", "BOX ", idtmed[701], emcg->GetSupportPlateHalfSize(), 3) ;
481
482       gMC->Gsvolu("PSHO", "BOX ", idtmed[798], emcg->GetSupportPlateInHalfSize(), 3) ;
483       Float_t z = emcg->GetSupportPlateThickness()/2 ;
484       gMC->Gspos("PSHO", 1, "PSUP", 0.0, 0.0, z, 0, "ONLY") ;
485
486       y = acel[1] ;
487       gMC->Gspos("PSUP", 1, "PSTR", 0.0, y, 0.0, 0, "ONLY") ;
488
489
490     // ========== Fill module with strips and put them into inner thermoinsulation=============
491       gMC->Gsvolu("PTII", "BOX ", idtmed[706], emcg->GetInnerThermoHalfSize(), 3) ;     
492
493       Float_t * inthermo = emcg->GetInnerThermoHalfSize() ;
494       Float_t * strip = emcg->GetStripHalfSize() ;
495       y = inthermo[1] - strip[1] ;
496       Int_t irow;
497       Int_t nr = 1 ;
498       Int_t icol ;
499
500       for(irow = 0; irow < emcg->GetNStripX(); irow ++){
501         Float_t x = (2*irow + 1 - emcg->GetNStripX())* strip[0] ;
502         for(icol = 0; icol < emcg->GetNStripZ(); icol ++){
503           z = (2*icol + 1 - emcg->GetNStripZ()) * strip[2] ;
504           gMC->Gspos("PSTR", nr, "PTII", x, y, z, 0, "ONLY") ;
505           nr++ ;
506         }
507       }
508           
509
510    // ------- define the air gap between thermoinsulation and cooler
511       gMC->Gsvolu("PAGA", "BOX ", idtmed[798], emcg->GetAirGapHalfSize(), 3) ;   
512       Float_t * agap = emcg->GetAirGapHalfSize() ;
513       y = agap[1] - inthermo[1]  ;
514       
515       gMC->Gspos("PTII", 1, "PAGA", 0.0, y, 0.0, 0, "ONLY") ;
516
517
518
519    // ------- define the Al passive cooler 
520       gMC->Gsvolu("PCOR", "BOX ", idtmed[701], emcg->GetCoolerHalfSize(), 3) ;   
521       Float_t * cooler = emcg->GetCoolerHalfSize() ;
522       y = cooler[1] - agap[1]  ;
523       
524       gMC->Gspos("PAGA", 1, "PCOR", 0.0, y, 0.0, 0, "ONLY") ;
525
526    // ------- define the outer thermoinsulating cover
527       gMC->Gsvolu("PTIO", "TRD1", idtmed[706], emcg->GetOuterThermoParams(), 4) ;        
528       Float_t * outparams = emcg->GetOuterThermoParams() ; 
529
530       Int_t idrotm[99] ;
531       AliMatrix(idrotm[1], 90.0, 0.0, 0.0, 0.0, 90.0, 270.0) ;
532       // Frame in outer thermoinsulation and so on: z out of beam, y along beam, x across beam
533  
534       z = outparams[3] - cooler[1] ;
535       gMC->Gspos("PCOR", 1, "PTIO", 0., 0.0, z, idrotm[1], "ONLY") ;
536        
537   // -------- Define the outer Aluminium cover -----
538       gMC->Gsvolu("PCOL", "TRD1", idtmed[701], emcg->GetAlCoverParams(), 4) ;        
539       Float_t * covparams = emcg->GetAlCoverParams() ; 
540       z = covparams[3] - outparams[3] ;
541       gMC->Gspos("PTIO", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
542
543  // --------- Define front fiberglass cover -----------
544       gMC->Gsvolu("PFGC", "BOX ", idtmed[717], emcg->GetFiberGlassHalfSize(), 3) ;  
545       z = - outparams[3] ;
546       gMC->Gspos("PFGC", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
547
548  //=============This is all with cold section==============
549
550
551       //------ Warm Section --------------
552       gMC->Gsvolu("PWAR", "BOX ", idtmed[701], emcg->GetWarmAlCoverHalfSize(), 3) ; 
553       Float_t * warmcov = emcg->GetWarmAlCoverHalfSize() ;
554
555       // --- Define the outer thermoinsulation ---
556       gMC->Gsvolu("PWTI", "BOX ", idtmed[706], emcg->GetWarmThermoHalfSize(), 3) ; 
557       Float_t * warmthermo = emcg->GetWarmThermoHalfSize() ;
558       z = -warmcov[2] + warmthermo[2] ;
559
560       gMC->Gspos("PWTI", 1, "PWAR", 0., 0.0, z, 0, "ONLY") ;     
561
562       // --- Define cables area and put in it T-supports ---- 
563       gMC->Gsvolu("PCA1", "BOX ", idtmed[718], emcg->GetTCables1HalfSize(), 3) ; 
564       Float_t * cbox = emcg->GetTCables1HalfSize() ;
565
566       gMC->Gsvolu("PBE1", "BOX ", idtmed[701], emcg->GetTSupport1HalfSize(), 3) ;
567       Float_t * beams = emcg->GetTSupport1HalfSize() ;
568       Int_t isup ;
569       for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
570         Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
571         gMC->Gspos("PBE1", isup, "PCA1", x, 0.0, 0.0, 0, "ONLY") ;
572       }
573
574       z = -warmthermo[2] + cbox[2] ;
575       gMC->Gspos("PCA1", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;     
576
577       gMC->Gsvolu("PCA2", "BOX ", idtmed[718], emcg->GetTCables2HalfSize(), 3) ; 
578       Float_t * cbox2 = emcg->GetTCables2HalfSize() ;
579
580       gMC->Gsvolu("PBE2", "BOX ", idtmed[701], emcg->GetTSupport2HalfSize(), 3) ;
581       for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
582         Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
583         gMC->Gspos("PBE2", isup, "PCA2", x, 0.0, 0.0, 0, "ONLY") ;
584       }
585
586       z = -warmthermo[2] + 2*cbox[2] + cbox2[2];
587       gMC->Gspos("PCA2", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;     
588
589
590   // --- Define frame ---
591       gMC->Gsvolu("PFRX", "BOX ", idtmed[716], emcg->GetFrameXHalfSize(), 3) ; 
592       Float_t * posit = emcg->GetFrameXPosition() ;
593       gMC->Gspos("PFRX", 1, "PWTI", posit[0],  posit[1], posit[2], 0, "ONLY") ;
594       gMC->Gspos("PFRX", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
595
596       gMC->Gsvolu("PFRZ", "BOX ", idtmed[716], emcg->GetFrameZHalfSize(), 3) ; 
597       posit = emcg->GetFrameZPosition() ;
598       gMC->Gspos("PFRZ", 1, "PWTI", posit[0], posit[1],  posit[2], 0, "ONLY") ;
599       gMC->Gspos("PFRZ", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
600
601  // --- Define Fiber Glass support ---
602       gMC->Gsvolu("PFG1", "BOX ", idtmed[717], emcg->GetFGupXHalfSize(), 3) ; 
603       posit = emcg->GetFGupXPosition() ;
604       gMC->Gspos("PFG1", 1, "PWTI", posit[0],  posit[1], posit[2], 0, "ONLY") ;
605       gMC->Gspos("PFG1", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
606
607       gMC->Gsvolu("PFG2", "BOX ", idtmed[717], emcg->GetFGupZHalfSize(), 3) ; 
608       posit = emcg->GetFGupZPosition() ;
609       gMC->Gspos("PFG2", 1, "PWTI",  posit[0], posit[1], posit[2], 0, "ONLY") ;
610       gMC->Gspos("PFG2", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
611
612       gMC->Gsvolu("PFG3", "BOX ", idtmed[717], emcg->GetFGlowXHalfSize(), 3) ; 
613       posit = emcg->GetFGlowXPosition() ;
614       gMC->Gspos("PFG3", 1, "PWTI", posit[0],  posit[1], posit[2], 0, "ONLY") ;
615       gMC->Gspos("PFG3", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
616
617       gMC->Gsvolu("PFG4", "BOX ", idtmed[717], emcg->GetFGlowZHalfSize(), 3) ; 
618       posit = emcg->GetFGlowZPosition() ;
619       gMC->Gspos("PFG4", 1, "PWTI",  posit[0], posit[1], posit[2], 0, "ONLY") ;
620       gMC->Gspos("PFG4", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
621
622       // --- Define Air Gap for FEE electronics ----- 
623
624       gMC->Gsvolu("PAFE", "BOX ", idtmed[798], emcg->GetFEEAirHalfSize(), 3) ; 
625       posit = emcg->GetFEEAirPosition() ;
626       gMC->Gspos("PAFE", 1, "PWTI",  posit[0], posit[1], posit[2], 0, "ONLY") ;
627
628       // Define the EMC module volume and combine Cool and Warm sections
629
630       gMC->Gsvolu("PEMC", "TRD1", idtmed[798], emcg->GetEMCParams(), 4) ;        
631
632       z =  - warmcov[2] ;
633       gMC->Gspos("PCOL", 1, "PEMC",  0., 0., z, 0, "ONLY") ;
634       z = covparams[3] ;
635       gMC->Gspos("PWAR", 1, "PEMC",  0., 0., z, 0, "ONLY") ;
636
637
638       // Put created EMC geometry into PHOS volume
639       
640       z = geom->GetCPVBoxSize(1) / 2. ;
641       gMC->Gspos("PEMC", 1, "PHOS", 0., 0., z, 0, "ONLY") ; 
642             
643 }
644
645 //____________________________________________________________________________
646 void AliPHOSv0::CreateGeometryforCPV()
647 {
648   // Create the PHOS-CPV geometry for GEANT
649   // Author: Yuri Kharlov 11 September 2000
650   //BEGIN_HTML
651   /*
652     <H2>
653     Geant3 geometry of PHOS-CPV in ALICE
654     </H2>
655     <table width=700>
656
657     <tr>
658          <td>CPV perspective view</td>
659          <td>CPV front view      </td>
660     </tr>
661
662     <tr>
663          <td> <img height=300 width=290 src="../images/CPVallPersp.gif"> </td>
664          <td> <img height=300 width=290 src="../images/CPVallFront.gif"> </td>
665     </tr>
666
667     <tr>
668          <td>One CPV module, perspective view                            </td>
669          <td>One CPV module, front view (extended in vertical direction) </td>
670     </tr>
671
672     <tr>
673          <td><img height=300 width=290 src="../images/CPVmodulePers.gif"></td>
674          <td><img height=300 width=290 src="../images/CPVmoduleSide.gif"></td>
675     </tr>
676
677     </table>
678
679     <H2>
680     Geant3 geometry tree of PHOS-CPV in ALICE
681     </H2>
682     <center>
683     <img height=300 width=290 src="../images/CPVtree.gif">
684     </center>
685   */
686   //END_HTML  
687
688   Float_t par[3], x,y,z;
689
690   // Get pointer to the array containing media indexes
691   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
692
693   AliPHOSGeometry * geom = GetGeometry() ; 
694
695   // The box containing all CPV for one PHOS module filled with air 
696   par[0] = geom->GetCPVBoxSize(0) / 2.0 ;  
697   par[1] = geom->GetCPVBoxSize(1) / 2.0 ; 
698   par[2] = geom->GetCPVBoxSize(2) / 2.0 ;
699   gMC->Gsvolu("PCPV", "BOX ", idtmed[798], par, 3) ;
700
701   Float_t * emcParams = geom->GetEMCAGeometry()->GetEMCParams() ;
702   z = - emcParams[3] ;
703   Int_t rotm ;
704   AliMatrix(rotm, 90.,0., 0., 0., 90., 90.) ;
705
706   gMC->Gspos("PCPV", 1, "PHOS", 0.0, 0.0, z, rotm, "ONLY") ; 
707   
708   // Gassiplex board
709   
710   par[0] = geom->GetGassiplexChipSize(0)/2.;
711   par[1] = geom->GetGassiplexChipSize(1)/2.;
712   par[2] = geom->GetGassiplexChipSize(2)/2.;
713   gMC->Gsvolu("PCPC","BOX ",idtmed[707],par,3);
714   
715   // Cu+Ni foil covers Gassiplex board
716
717   par[1] = geom->GetCPVCuNiFoilThickness()/2;
718   gMC->Gsvolu("PCPD","BOX ",idtmed[710],par,3);
719   y      = -(geom->GetGassiplexChipSize(1)/2 - par[1]);
720   gMC->Gspos("PCPD",1,"PCPC",0,y,0,0,"ONLY");
721
722   // Position of the chip inside CPV
723
724   Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
725   Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ()   + 1);
726   Int_t   copy  = 0;
727   y = geom->GetCPVFrameSize(1)/2           - geom->GetFTPosition(0) +
728     geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
729   for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
730     x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
731     for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
732       copy++;
733       z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
734       gMC->Gspos("PCPC",copy,"PCPV",x,y,z,0,"ONLY");
735     }
736   }
737
738   // Foiled textolite (1 mm of textolite + 50 mkm of Cu + 6 mkm of Ni)
739   
740   par[0] = geom->GetCPVActiveSize(0)        / 2;
741   par[1] = geom->GetCPVTextoliteThickness() / 2;
742   par[2] = geom->GetCPVActiveSize(1)        / 2;
743   gMC->Gsvolu("PCPF","BOX ",idtmed[707],par,3);
744
745   // Argon gas volume
746
747   par[1] = (geom->GetFTPosition(2) - geom->GetFTPosition(1) - geom->GetCPVTextoliteThickness()) / 2;
748   gMC->Gsvolu("PCPG","BOX ",idtmed[715],par,3);
749
750   for (Int_t i=0; i<4; i++) {
751     y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(i) + geom->GetCPVTextoliteThickness()/2;
752     gMC->Gspos("PCPF",i+1,"PCPV",0,y,0,0,"ONLY");
753     if(i==1){
754       y-= (geom->GetFTPosition(2) - geom->GetFTPosition(1)) / 2;
755       gMC->Gspos("PCPG",1,"PCPV ",0,y,0,0,"ONLY");
756     }
757   }
758
759   // Dummy sensitive plane in the middle of argone gas volume
760
761   par[1]=0.001;
762   gMC->Gsvolu("PCPQ","BOX ",idtmed[715],par,3);
763   gMC->Gspos ("PCPQ",1,"PCPG",0,0,0,0,"ONLY");
764
765   // Cu+Ni foil covers textolite
766
767   par[1] = geom->GetCPVCuNiFoilThickness() / 2;
768   gMC->Gsvolu("PCP1","BOX ",idtmed[710],par,3);
769   y = geom->GetCPVTextoliteThickness()/2 - par[1];
770   gMC->Gspos ("PCP1",1,"PCPF",0,y,0,0,"ONLY");
771
772   // Aluminum frame around CPV
773
774   par[0] = geom->GetCPVFrameSize(0)/2;
775   par[1] = geom->GetCPVFrameSize(1)/2;
776   par[2] = geom->GetCPVBoxSize(2)  /2;
777   gMC->Gsvolu("PCF1","BOX ",idtmed[701],par,3);
778
779   par[0] = geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0);
780   par[1] = geom->GetCPVFrameSize(1)/2;
781   par[2] = geom->GetCPVFrameSize(2)/2;
782   gMC->Gsvolu("PCF2","BOX ",idtmed[701],par,3);
783
784   for (Int_t j=0; j<=1; j++) {
785     x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
786     gMC->Gspos("PCF1",j+1,"PCPV", x,0,0,0,"ONLY");
787     z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
788     gMC->Gspos("PCF2",j+1,"PCPV",0, 0,z,0,"ONLY");
789   }
790
791 }
792
793
794 //____________________________________________________________________________
795 void AliPHOSv0::CreateGeometryforSupport()
796 {
797   // Create the PHOS' support geometry for GEANT
798     //BEGIN_HTML
799   /*
800     <H2>
801     Geant3 geometry of the PHOS's support
802     </H2>
803     <P><CENTER>
804     <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/PHOS_support.gif"> 
805     </CENTER><P>
806   */
807   //END_HTML  
808   
809   Float_t par[5], x0,y0,z0 ; 
810   Int_t   i,j,copy;
811
812   // Get pointer to the array containing media indexes
813   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
814
815   AliPHOSGeometry * geom = GetGeometry() ; 
816
817   // --- Dummy box containing two rails on which PHOS support moves
818   // --- Put these rails to the bottom of the L3 magnet
819
820   par[0] =  geom->GetRailRoadSize(0) / 2.0 ;
821   par[1] =  geom->GetRailRoadSize(1) / 2.0 ;
822   par[2] =  geom->GetRailRoadSize(2) / 2.0 ;
823   gMC->Gsvolu("PRRD", "BOX ", idtmed[798], par, 3) ;
824
825   y0     = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) / 2.0) ;
826   gMC->Gspos("PRRD", 1, "ALIC", 0.0, y0, 0.0, 0, "ONLY") ; 
827
828   // --- Dummy box containing one rail
829
830   par[0] =  geom->GetRailOuterSize(0) / 2.0 ;
831   par[1] =  geom->GetRailOuterSize(1) / 2.0 ;
832   par[2] =  geom->GetRailOuterSize(2) / 2.0 ;
833   gMC->Gsvolu("PRAI", "BOX ", idtmed[798], par, 3) ;
834
835   for (i=0; i<2; i++) {
836     x0     = (2*i-1) * geom->GetDistanceBetwRails()  / 2.0 ;
837     gMC->Gspos("PRAI", i, "PRRD", x0, 0.0, 0.0, 0, "ONLY") ; 
838   }
839
840   // --- Upper and bottom steel parts of the rail
841
842   par[0] =  geom->GetRailPart1(0) / 2.0 ;
843   par[1] =  geom->GetRailPart1(1) / 2.0 ;
844   par[2] =  geom->GetRailPart1(2) / 2.0 ;
845   gMC->Gsvolu("PRP1", "BOX ", idtmed[716], par, 3) ;
846
847   y0     = - (geom->GetRailOuterSize(1) - geom->GetRailPart1(1))  / 2.0 ;
848   gMC->Gspos("PRP1", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
849   y0     =   (geom->GetRailOuterSize(1) - geom->GetRailPart1(1))  / 2.0 - geom->GetRailPart3(1);
850   gMC->Gspos("PRP1", 2, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
851
852   // --- The middle vertical steel parts of the rail
853
854   par[0] =  geom->GetRailPart2(0) / 2.0 ;
855   par[1] =  geom->GetRailPart2(1) / 2.0 ;
856   par[2] =  geom->GetRailPart2(2) / 2.0 ;
857   gMC->Gsvolu("PRP2", "BOX ", idtmed[716], par, 3) ;
858
859   y0     =   - geom->GetRailPart3(1) / 2.0 ;
860   gMC->Gspos("PRP2", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ; 
861
862   // --- The most upper steel parts of the rail
863
864   par[0] =  geom->GetRailPart3(0) / 2.0 ;
865   par[1] =  geom->GetRailPart3(1) / 2.0 ;
866   par[2] =  geom->GetRailPart3(2) / 2.0 ;
867   gMC->Gsvolu("PRP3", "BOX ", idtmed[716], par, 3) ;
868
869   y0     =   (geom->GetRailOuterSize(1) - geom->GetRailPart3(1))  / 2.0 ;
870   gMC->Gspos("PRP3", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ; 
871
872   // --- The wall of the cradle
873   // --- The wall is empty: steel thin walls and air inside
874
875   par[1] =  TMath::Sqrt(TMath::Power((geom->GetIPtoCPVDistance() + geom->GetOuterBoxSize(3)),2) +
876                         TMath::Power((geom->GetOuterBoxSize(1)/2),2))+10. ;
877   par[0] =  par[1] - geom->GetCradleWall(1) ;
878   par[2] =  geom->GetCradleWall(2) / 2.0 ;
879   par[3] =  geom->GetCradleWall(3) ;
880   par[4] =  geom->GetCradleWall(4) ;
881   gMC->Gsvolu("PCRA", "TUBS", idtmed[716], par, 5) ;
882
883   par[0] +=  geom->GetCradleWallThickness() ;
884   par[1] -=  geom->GetCradleWallThickness() ;
885   par[2] -=  geom->GetCradleWallThickness() ;
886   gMC->Gsvolu("PCRE", "TUBS", idtmed[798], par, 5) ;
887   gMC->Gspos ("PCRE", 1, "PCRA", 0.0, 0.0, 0.0, 0, "ONLY") ; 
888
889   for (i=0; i<2; i++) {
890     z0 = (2*i-1) * (geom->GetOuterBoxSize(2) + geom->GetCradleWall(2) )/ 2.0  ;
891         gMC->Gspos("PCRA", i, "ALIC", 0.0, 0.0, z0, 0, "ONLY") ; 
892   }
893
894   // --- The "wheels" of the cradle
895   
896   par[0] = geom->GetCradleWheel(0) / 2;
897   par[1] = geom->GetCradleWheel(1) / 2;
898   par[2] = geom->GetCradleWheel(2) / 2;
899   gMC->Gsvolu("PWHE", "BOX ", idtmed[716], par, 3) ;
900
901   y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) -
902          geom->GetCradleWheel(1)/2) ;
903   for (i=0; i<2; i++) {
904     z0 = (2*i-1) * ((geom->GetOuterBoxSize(2) + geom->GetCradleWheel(2))/ 2.0 +
905                     geom->GetCradleWall(2));
906     for (j=0; j<2; j++) {
907       copy = 2*i + j;
908       x0 = (2*j-1) * geom->GetDistanceBetwRails()  / 2.0 ;
909       gMC->Gspos("PWHE", copy, "ALIC", x0, y0, z0, 0, "ONLY") ; 
910     }
911   }
912
913 }
914
915 //_____________________________________________________________________________
916 void AliPHOSv0::AddAlignableVolumes() const
917 {
918   //
919   // Create entries for alignable volumes associating the symbolic volume
920   // name with the corresponding volume path. Needs to be syncronized with
921   // eventual changes in the geometry
922   // Alignable volumes are:
923   // 1) PHOS modules as a whole
924   // 2) Cradle
925   // 3) Cradle wheels
926   // 4) Strip units (group of 2x8 crystals)
927
928   TString volpath, symname;
929
930   // Alignable modules
931   // Volume path /ALIC_1/PHOS_<i> => symbolic name /PHOS/Module<i>, <i>=1,2,3,4,5
932   
933   AliGeomManager::ELayerID idPHOS1 = AliGeomManager::kPHOS1;
934   AliGeomManager::ELayerID idPHOS2 = AliGeomManager::kPHOS2;
935   Int_t modUID, modnum = 0;
936   TString physModulePath="/ALIC_1/PHOS_";
937   TString symbModuleName="PHOS/Module";
938   Int_t nModules = GetGeometry()->GetNModules();
939   
940   for(Int_t iModule=1; iModule<=nModules; iModule++){
941     modUID = AliGeomManager::LayerToVolUID(idPHOS1,modnum++);
942     volpath = physModulePath;
943     volpath += iModule;
944     //    volpath += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1";
945
946     symname = symbModuleName;
947     symname += iModule;
948     if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
949       AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
950
951     // Creates the Tracking to Local transformation matrix for PHOS modules
952     TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
953
954     Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
955     TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
956
957     TGeoHMatrix *matTtoL = new TGeoHMatrix;
958     matTtoL->RotateZ(-90.+angle);
959     matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
960     alignableEntry->SetMatrix(matTtoL);
961   }
962
963   //Aligning of CPV should be done for volume PCPV_1
964   symbModuleName="PHOS/Module";
965   modnum=0;
966   for(Int_t iModule=1; iModule<=nModules; iModule++){
967     modUID = AliGeomManager::LayerToVolUID(idPHOS2,modnum++);
968     volpath = physModulePath;
969     volpath += iModule;
970     volpath += "/PCPV_1";
971     // Check the volume path
972     if (!gGeoManager->CheckPath(volpath.Data())) {
973       AliError(Form("Volume path %s not valid!",volpath.Data()));
974       continue;
975     }
976
977     symname = symbModuleName;
978     symname += iModule;
979     symname += "/CPV";
980     if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
981       AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
982           
983     // Creates the TGeo Local to Tracking transformation matrix ...
984     TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
985
986     Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
987     TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
988
989     TGeoHMatrix *matTtoL = new TGeoHMatrix;
990     matTtoL->RotateZ(-90.+angle);
991     matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
992     alignableEntry->SetMatrix(matTtoL);
993     
994   }
995  
996
997   // Alignable cradle walls
998   // Volume path /ALIC_1/PCRA_<i> => symbolic name /PHOS/Cradle<i>, <i>=0,1
999
1000   TString physCradlePath="/ALIC_1/PCRA_";
1001   TString symbCradleName="PHOS/Cradle";
1002   Int_t nCradles = 2;
1003
1004   for(Int_t iCradle=0; iCradle<nCradles; iCradle++){
1005     volpath = physCradlePath;
1006     volpath += iCradle;
1007     symname = symbCradleName;
1008     symname += iCradle;
1009     gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
1010   }
1011
1012   // Alignable wheels
1013   // Volume path /ALIC_1/PWHE_<i> => symbolic name /PHOS/Wheel<i>, i=0,1,2,3
1014
1015   TString physWheelPath="/ALIC_1/PWHE_";
1016   TString symbWheelName="PHOS/Wheel";
1017   Int_t nWheels = 4;
1018
1019   for(Int_t iWheel=0; iWheel<nWheels; iWheel++){
1020     volpath = physWheelPath;
1021     volpath += iWheel;
1022     symname = symbWheelName;
1023     symname += iWheel;
1024     gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
1025   }
1026
1027   //Physical strip path is a combination of: physModulePath + module number + 
1028   //physStripPath + strip number == ALIC_1/PHOS_N/..../PSTR_M
1029   const Int_t nStripsX = GetGeometry()->GetEMCAGeometry()->GetNStripX();
1030   const Int_t nStripsZ = GetGeometry()->GetEMCAGeometry()->GetNStripZ();
1031   TString partialPhysStripName(100);
1032   TString fullPhysStripName(100);
1033   TString partialSymbStripName(100);
1034   TString fullSymbStripName(100);
1035
1036   for(Int_t module = 1; module <= nModules; ++module){
1037     partialPhysStripName  = physModulePath;
1038     partialPhysStripName += module;
1039     partialPhysStripName += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1/PSTR_";
1040
1041     partialSymbStripName  = symbModuleName;
1042     partialSymbStripName += module;
1043     partialSymbStripName += "/Strip_";
1044
1045     for(Int_t i = 0, ind1D = 1; i < nStripsX; ++i){//ind1D starts from 1 (PSTR_1...PSTR_224...)
1046       for(Int_t j = 0; j < nStripsZ; ++j, ++ind1D){
1047          fullPhysStripName = partialPhysStripName;
1048          fullPhysStripName += ind1D;
1049          
1050          fullSymbStripName  = partialSymbStripName;
1051          fullSymbStripName += i;//ind1D;
1052          fullSymbStripName += '_';
1053          fullSymbStripName += j;
1054
1055          gGeoManager->SetAlignableEntry(fullSymbStripName.Data(), fullPhysStripName.Data());
1056
1057          // Creates the TGeo Local to Tracking transformation matrix ...
1058          TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntry(fullSymbStripName.Data()) ;
1059          const char *path = alignableEntry->GetTitle();
1060          if (!gGeoManager->cd(path))
1061            AliFatal(Form("Volume path %s not valid!",path));
1062          TGeoHMatrix matLtoT = *gGeoManager->GetCurrentMatrix() ;
1063          Double_t refl[3]={-1.,-1.,-1.} ;
1064          matLtoT.SetScale(refl) ;
1065          TGeoHMatrix *matTtoL = new TGeoHMatrix(matLtoT.Inverse());
1066  
1067          char phosPath[50] ;
1068          sprintf(phosPath,"/ALIC_1/PHOS_%d",module) ;
1069          if (!gGeoManager->cd(phosPath)){
1070             AliFatal("Geo manager can not find path \n");
1071          }
1072          TGeoHMatrix *mPHOS = gGeoManager->GetCurrentMatrix();
1073          if (mPHOS) 
1074            matTtoL->Multiply(mPHOS);
1075          else{
1076            AliFatal("Geo matrixes are not loaded \n") ;
1077          }
1078          //Switch y<->z
1079          Double_t rot[9]={1.,0.,0.,  0.,1.,0., 0.,0.,1.} ;
1080          matTtoL->SetRotation(rot) ;
1081          alignableEntry->SetMatrix(matTtoL);
1082
1083 /*
1084   //Check poisition of corner cell of the strip
1085   AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
1086   Int_t relid[4] ; 
1087   relid[0] = module ;
1088   relid[1] = 0 ;
1089   Int_t iStrip=ind1D ;
1090   Int_t icell=1 ;
1091   Int_t raw = geom->GetEMCAGeometry()->GetNCellsXInStrip()*((iStrip-1)/geom->GetEMCAGeometry()->GetNStripZ()) +
1092                 1 + (icell-1)/geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
1093   Int_t col = geom->GetEMCAGeometry()->GetNCellsZInStrip()*(1+(iStrip-1)%geom->GetEMCAGeometry()->GetNStripZ()) - 
1094                 (icell-1)%geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
1095   if(col==0) col=geom->GetNZ() ;
1096   relid[2] = raw ;
1097   relid[3] = col ;
1098   Float_t xG,zG ; 
1099   geom->RelPosInModule(relid, xG, zG) ;
1100 printf("============\n") ;
1101 printf("Geometry: x=%f, z=%f \n",xG,zG) ;
1102   Int_t absid ; 
1103   geom->RelToAbsNumbering(relid,absid) ;
1104   Double_t pos[3]= {-2.2*3.5,0.0,1.1}; //Position incide the strip (Y coordinalte is not important)
1105   Double_t posC[3]={0.0,0.0,0.}; //Global position
1106  
1107   matTtoL->MasterToLocal(pos,posC);
1108 printf("Matrix:   x=%f, z=%f, y=%f \n",posC[0],posC[2],posC[1]) ;
1109 */
1110       }
1111     }
1112   }
1113 }
1114
1115 //____________________________________________________________________________
1116 Float_t AliPHOSv0::ZMin(void) const
1117 {
1118   // Overall dimension of the PHOS (min)
1119
1120   AliPHOSGeometry * geom = GetGeometry() ; 
1121
1122   return -geom->GetOuterBoxSize(2)/2.;
1123 }
1124
1125 //____________________________________________________________________________
1126 Float_t AliPHOSv0::ZMax(void) const
1127 {
1128   // Overall dimension of the PHOS (max)
1129
1130   AliPHOSGeometry * geom = GetGeometry() ; 
1131
1132   return  geom->GetOuterBoxSize(2)/2.;
1133 }
1134
1135 //____________________________________________________________________________
1136 void AliPHOSv0::Init(void)
1137 {
1138   // Just prints an information message
1139   
1140   Int_t i;
1141
1142   if(AliLog::GetGlobalDebugLevel()>0) {
1143     TString st ; 
1144     for(i=0;i<35;i++) 
1145       st += "*";
1146     Info("Init", "%s", st.Data()) ;  
1147     // Here the PHOS initialisation code (if any!)
1148     
1149     AliPHOSGeometry * geom = GetGeometry() ; 
1150
1151     if (geom!=0)  
1152       Info("Init", "AliPHOS%s: PHOS geometry intialized for %s", Version().Data(), geom->GetName()) ;
1153     else
1154       Info("Init", "AliPHOS%s: PHOS geometry initialization failed !", Version().Data()) ;       
1155
1156     Info("Init", "%s", st.Data()) ;  
1157   }
1158 }