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