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