Logics of high gain adding to digits has changed
[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.83  2006/11/14 17:11:15  hristov
21  * 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
22  *
23  * Revision 1.82  2006/09/27 19:55:57  kharlov
24  * Alignment object with symbolic volume names are introduced
25  *
26  * Revision 1.81  2006/03/04 20:25:56  kharlov
27  * Set geom parameters from CDB
28  *
29  * Revision 1.80  2005/06/17 07:39:07  hristov
30  * Removing GetDebug and SetDebug from AliRun and AliModule. Using AliLog for the messages
31  *
32  * Revision 1.79  2005/05/28 14:19:05  schutz
33  * Compilation warnings fixed by T.P.
34  *
35  */
36
37 //_________________________________________________________________________
38 // Implementation version v0 of PHOS Manager class 
39 // An object of this class does not produce hits nor digits
40 // It is the one to use if you do not want to produce outputs in TREEH or TREED
41 //                  
42 //*-- Author: Yves Schutz (SUBATECH) & Dmitri Peressounko (RRC KI & SUBATECH)
43
44
45 // --- ROOT system ---
46
47 #include <TBRIK.h>
48 #include <TFolder.h>
49 #include <TGeometry.h>
50 #include <TNode.h>
51 #include <TROOT.h>
52 #include <TRandom.h>
53 #include <TTRD1.h>
54 #include <TTree.h>
55 #include <TVirtualMC.h>
56 #include <TGeoManager.h>
57
58 // --- Standard library ---
59
60 #include <string.h>
61 #include <stdlib.h>
62
63 // --- AliRoot header files ---
64
65 #include "AliConst.h"
66 #include "AliPHOSGeometry.h"
67 #include "AliPHOSLoader.h"
68 #include "AliPHOSv0.h"
69 #include "AliRun.h"
70 #include "AliLog.h"
71
72 ClassImp(AliPHOSv0)
73
74 //____________________________________________________________________________
75 AliPHOSv0::AliPHOSv0(const char *name, const char *title):
76   AliPHOS(name,title)
77 {
78   // ctor : title is used to identify the layout
79   GetGeometry() ; 
80 }
81
82 //____________________________________________________________________________
83 void AliPHOSv0::BuildGeometry()
84 {
85   // Build the PHOS geometry for the ROOT display
86   //BEGIN_HTML
87   /*
88     <H2>
89      PHOS in ALICE displayed by root
90     </H2>
91     <UL>
92     <LI> All Views
93     <P>
94     <CENTER>
95     <IMG Align=BOTTOM ALT="All Views" SRC="../images/AliPHOSv0AllViews.gif"> 
96     </CENTER></P></LI>
97     <LI> Front View
98     <P>
99     <CENTER>
100     <IMG Align=BOTTOM ALT="Front View" SRC="../images/AliPHOSv0FrontView.gif"> 
101     </CENTER></P></LI>
102      <LI> 3D View 1
103     <P>
104     <CENTER>
105     <IMG Align=BOTTOM ALT="3D View 1" SRC="../images/AliPHOSv03DView1.gif"> 
106     </CENTER></P></LI>
107     <LI> 3D View 2
108     <P>
109     <CENTER>
110     <IMG Align=BOTTOM ALT="3D View 2" SRC="../images/AliPHOSv03DView2.gif"> 
111     </CENTER></P></LI>
112     </UL>
113   */
114   //END_HTML  
115   
116   this->BuildGeometryforEMC() ; 
117   this->BuildGeometryforCPV() ;
118   
119 }
120
121 //____________________________________________________________________________
122 void AliPHOSv0:: BuildGeometryforEMC(void)
123 {
124   // Build the PHOS-EMC geometry for the ROOT display
125   
126   const Int_t kColorPHOS = kRed ;
127   const Int_t kColorXTAL = kBlue ;
128   
129   Double_t const kRADDEG = 180.0 / TMath::Pi() ;
130   
131   AliPHOSGeometry * geom = GetGeometry() ; 
132   AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
133   Float_t * boxparams = emcg->GetEMCParams() ;
134
135   new TTRD1("OuterBox", "PHOS box", "void",boxparams[0],boxparams[1],boxparams[2], boxparams[3] );
136   
137   
138   // Crystals Box
139   
140   Float_t * cribox = emcg->GetInnerThermoHalfSize() ;  
141   new TBRIK( "CrystalsBox", "PHOS crystals box", "void", cribox[0], cribox[2], cribox[1] ) ;
142   
143   // position PHOS into ALICE
144   
145   Float_t r = geom->GetIPtoOuterCoverDistance() + boxparams[3] ;
146   Int_t number = 988 ; 
147   TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
148   
149   char * nodename = new char[20] ;  
150   char * rotname  = new char[20] ; 
151
152   new TRotMatrix("cribox", "cribox", 90, 0, 90, 90, 0, 0);  
153
154   for( Int_t i = 1; i <= geom->GetNModules(); i++ ) { 
155
156     Float_t angle = geom->GetPHOSAngle(i) ;
157     sprintf(rotname, "%s%d", "rot", number++) ;
158     new TRotMatrix(rotname, rotname, 90, angle, 0,  0,  90,  270 + angle);
159
160     top->cd();
161     sprintf(nodename,"%s%d", "Module", i) ;    
162     Float_t x =  r * TMath::Sin( angle / kRADDEG ) ;
163     Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
164     TNode * outerboxnode = new TNode(nodename, nodename, "OuterBox", x, y, 0, rotname ) ;
165     outerboxnode->SetLineColor(kColorPHOS) ;
166     fNodes->Add(outerboxnode) ;
167     outerboxnode->cd() ; 
168
169     Float_t z = -boxparams[3] - geom->GetIPtoOuterCoverDistance() + 
170                  cribox[1] +  geom->GetIPtoCrystalSurface() ;
171     TNode * crystalsboxnode = new TNode(nodename, nodename, "CrystalsBox", 0, 0, z) ;    
172     crystalsboxnode->SetLineColor(kColorXTAL) ; 
173     fNodes->Add(crystalsboxnode) ; 
174   }
175
176   delete[] rotname ;  
177   delete[] nodename ;
178 }
179
180
181 //____________________________________________________________________________
182 void AliPHOSv0:: BuildGeometryforCPV(void)
183 {
184   //  Build the PHOS-CPV geometry for the ROOT display
185   //  Author: Yuri Kharlov 11 September 2000
186   //
187   //BEGIN_HTML
188   /*
189     <H2>
190     CPV displayed by root
191     </H2>
192     <table width=700>
193
194     <tr>
195          <td>CPV perspective view</td>
196          <td>CPV front view      </td>
197     </tr>
198
199     <tr>
200          <td> <img height=300 width=290 src="../images/CPVRootPersp.gif"> </td>
201          <td> <img height=300 width=290 src="../images/CPVRootFront.gif"> </td>
202     </tr>
203
204     </table>
205
206   */
207   //END_HTML  
208
209   const Double_t kRADDEG         = 180.0 / TMath::Pi() ;
210   const Int_t    kColorCPV       = kGreen ;
211   const Int_t    kColorFrame     = kYellow ;
212   const Int_t    kColorGassiplex = kRed;
213   const Int_t    kColorPCB       = kCyan;
214
215   AliPHOSGeometry * geom = GetGeometry() ; 
216
217   // Box for a full PHOS module
218
219   new TBRIK ("CPVBox", "CPV box", "void",                   geom->GetCPVBoxSize(0)/2,
220                                                             geom->GetCPVBoxSize(1)/2,
221                                                             geom->GetCPVBoxSize(2)/2 );
222   new TBRIK ("CPVFrameLR", "CPV frame Left-Right", "void",  geom->GetCPVFrameSize(0)/2,
223                                                             geom->GetCPVFrameSize(1)/2,
224                                                             geom->GetCPVBoxSize(2)/2 );
225   new TBRIK ("CPVFrameUD", "CPV frame Up-Down",    "void",  geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0),
226                                                             geom->GetCPVFrameSize(1)/2,
227                                                             geom->GetCPVFrameSize(2)/2);
228   new TBRIK ("CPVPCB",    "CPV PCB",               "void",  geom->GetCPVActiveSize(0)/2,
229                                                             geom->GetCPVTextoliteThickness()/2,
230                                                             geom->GetCPVActiveSize(1)/2);
231   new TBRIK ("CPVGassiplex", "CPV Gassiplex PCB",  "void",  geom->GetGassiplexChipSize(0)/2,
232                                                             geom->GetGassiplexChipSize(1)/2,
233                                                             geom->GetGassiplexChipSize(2)/2);
234
235   // position CPV into ALICE
236
237   char * nodename = new char[25] ;
238   char * rotname  = new char[25] ;
239   
240   Float_t r = geom->GetIPtoCPVDistance() + geom->GetCPVBoxSize(1) / 2.0 ;
241   Int_t number = 988 ; 
242   TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
243
244   Int_t lastModule = 0 ;
245   lastModule = geom->GetNModules();
246   
247   for( Int_t i = 1; i <= lastModule; i++ ) { // the number of PHOS modules
248     
249     // One CPV module
250     
251     Float_t angle = geom->GetPHOSAngle(i) ;
252     sprintf(rotname, "%s%d", "rotg", number+i) ;
253     new TRotMatrix(rotname, rotname, 90, angle, 90, 90 + angle, 0, 0);
254     top->cd();
255     sprintf(nodename, "%s%d", "CPVModule", i) ;    
256     Float_t x =  r * TMath::Sin( angle / kRADDEG ) ;
257     Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
258     Float_t z;
259     TNode * cpvBoxNode = new TNode(nodename , nodename ,"CPVBox", x, y, 0, rotname ) ;
260     cpvBoxNode->SetLineColor(kColorCPV) ;
261     fNodes->Add(cpvBoxNode) ;
262     cpvBoxNode->cd() ;
263
264     // inside each CPV box:
265
266     // Frame around CPV
267     Int_t j;
268     for (j=0; j<=1; j++) {
269       sprintf(nodename, "CPVModule%d Frame%d", i, j+1) ;
270       x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
271       TNode * cpvFrameNode = new TNode(nodename , nodename ,"CPVFrameLR", x, 0, 0) ;
272       cpvFrameNode->SetLineColor(kColorFrame) ;
273       fNodes->Add(cpvFrameNode) ;
274
275       sprintf(nodename, "CPVModule%d Frame%d", i, j+3) ;
276       z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
277       cpvFrameNode = new TNode(nodename , nodename ,"CPVFrameUD", 0, 0, z) ;
278       cpvFrameNode->SetLineColor(kColorFrame) ;
279       fNodes->Add(cpvFrameNode) ;
280     }
281
282     // 4 printed circuit boards
283     for (j=0; j<4; j++) {
284       sprintf(nodename, "CPVModule%d PCB%d", i, j+1) ;
285       y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(j) + geom->GetCPVTextoliteThickness()/2;
286       TNode * cpvPCBNode = new TNode(nodename , nodename ,"CPVPCB", 0, y, 0) ;
287       cpvPCBNode->SetLineColor(kColorPCB) ;
288       fNodes->Add(cpvPCBNode) ;
289     }
290
291     // Gassiplex chips
292     Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
293     Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ()   + 1);
294     y = geom->GetCPVFrameSize(1)/2           - geom->GetFTPosition(0) +
295         geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
296     for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
297       x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
298       for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
299         z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
300         sprintf(nodename, "CPVModule%d Chip(%dx%d)", i, ix+1,iz+1) ;
301         TNode * cpvGassiplexNode = new TNode(nodename , nodename ,"CPVGassiplex", x, y, z) ;
302         cpvGassiplexNode->SetLineColor(kColorGassiplex) ;
303         fNodes->Add(cpvGassiplexNode) ;
304       }
305     }
306
307   } // PHOS modules
308  
309   delete[] rotname ;  
310   delete[] nodename ; 
311 }
312
313 //____________________________________________________________________________
314 void AliPHOSv0::CreateGeometry()
315 {
316   // Create the PHOS geometry for Geant
317
318   AliPHOSv0 *phostmp = dynamic_cast<AliPHOSv0*>(gAlice->GetModule("PHOS")) ;
319
320   if ( phostmp == NULL ) {
321     
322     fprintf(stderr, "PHOS detector not found!\n") ;
323     return;
324     
325   }
326
327   AliPHOSGeometry * geom = GetGeometry() ; 
328
329   // Get pointer to the array containing media indeces
330   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
331
332   // Create a PHOS module.
333   
334   gMC->Gsvolu("PHOS", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;        
335   
336   this->CreateGeometryforEMC() ; 
337
338   if (strstr(fTitle.Data(),"noCPV") == 0) 
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 }