]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PHOS/AliPHOSv0.cxx
to keep compatibility with Sun and HP CC!
[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
16 /* $Id$ */
17
18 //_________________________________________________________________________
19 // Implementation version v0 of PHOS Manager class 
20 // Layout EMC + PPSD has name GPS2  
21 //                  
22 //*-- Author: Yves Schutz (SUBATECH)
23
24
25 // --- ROOT system ---
26
27 #include "TBRIK.h"
28 #include "TNode.h"
29 #include "TRandom.h"
30
31 // --- Standard library ---
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <strstream.h>
37
38 // --- AliRoot header files ---
39
40 #include "AliPHOSv0.h"
41 #include "AliPHOSHit.h"
42 #include "AliPHOSDigit.h"
43 #include "AliPHOSReconstructioner.h"
44 #include "AliRun.h"
45 #include "AliConst.h"
46
47 ClassImp(AliPHOSv0)
48
49 //____________________________________________________________________________
50 AliPHOSv0::AliPHOSv0()
51 {
52   // ctor
53   fNTmpHits = 0 ; 
54   fTmpHits  = 0 ; 
55 }
56
57 //____________________________________________________________________________
58 AliPHOSv0::AliPHOSv0(const char *name, const char *title):
59   AliPHOS(name,title)
60 {
61   // ctor : title is used to identify the layout
62   //        GPS2 = 5 modules (EMC + PPSD)   
63   // We use 2 arrays of hits :
64   //
65   //   - fHits (the "normal" one), which retains the hits associated with
66   //     the current primary particle being tracked
67   //     (this array is reset after each primary has been tracked).
68   //
69   //   - fTmpHits, which retains all the hits of the current event. It 
70   //     is used for the digitization part.
71
72   fPinElectronicNoise = 0.010 ;
73   fDigitThreshold      = 1. ;   // 1 GeV 
74
75   // We do not want to save in TreeH the raw hits
76   // fHits   = new TClonesArray("AliPHOSHit",100) ;
77   // gAlice->AddHitList(fHits) ; 
78
79   // But save the cumulated hits instead (need to create the branch myself)
80   // It is put in the Digit Tree because the TreeH is filled after each primary
81   // and the TreeD at the end of the event (branch is set in FinishEvent() ).
82   
83   fTmpHits= new TClonesArray("AliPHOSHit",100) ;
84
85   fNTmpHits = fNhits = 0 ;
86
87   fDigits = new TClonesArray("AliPHOSDigit",100) ;
88
89
90   fIshunt     =  1 ; // All hits are associated with primary particles
91  
92   // gets an instance of the geometry parameters class  
93    
94   fGeom =  AliPHOSGeometry::GetInstance(title, "") ; 
95
96   if (fGeom->IsInitialized() ) 
97     cout << "AliPHOSv0 : PHOS geometry intialized for " << fGeom->GetName() << endl ;
98   else
99    cout << "AliPHOSv0 : PHOS geometry initialization failed !" << endl ;   
100 }
101
102 //____________________________________________________________________________
103 AliPHOSv0::AliPHOSv0(AliPHOSReconstructioner * Reconstructioner, const char *name, const char *title):
104   AliPHOS(name,title)
105 {
106   // ctor : title is used to identify the layout
107   //        GPS2 = 5 modules (EMC + PPSD)   
108   // We use 2 arrays of hits :
109   //
110   //   - fHits (the "normal" one), which retains the hits associated with
111   //     the current primary particle being tracked
112   //     (this array is reset after each primary has been tracked).
113   //
114   //   - fTmpHits, which retains all the hits of the current event. It 
115   //     is used for the digitization part.
116
117   fPinElectronicNoise = 0.010 ;
118
119   // We do not want to save in TreeH the raw hits
120   //fHits   = new TClonesArray("AliPHOSHit",100) ;
121
122   fDigits = new TClonesArray("AliPHOSDigit",100) ;
123   fTmpHits= new TClonesArray("AliPHOSHit",100) ;
124
125   fNTmpHits = fNhits = 0 ;
126
127   fIshunt     =  1 ; // All hits are associated with primary particles
128  
129   // gets an instance of the geometry parameters class  
130   fGeom =  AliPHOSGeometry::GetInstance(title, "") ; 
131
132   if (fGeom->IsInitialized() ) 
133     cout << "AliPHOSv0 : PHOS geometry intialized for " << fGeom->GetName() << endl ;
134   else
135    cout << "AliPHOSv0 : PHOS geometry initialization failed !" << endl ;   
136
137   // Defining the PHOS Reconstructioner
138  
139  fReconstructioner = Reconstructioner ;
140 }
141
142 //____________________________________________________________________________
143 AliPHOSv0::~AliPHOSv0()
144 {
145   // dtor
146
147   if ( fTmpHits) {
148     fTmpHits->Delete() ; 
149     delete fTmpHits ;
150     fTmpHits = 0 ; 
151   }
152
153   if ( fEmcRecPoints ) {
154     fEmcRecPoints->Delete() ; 
155     delete fEmcRecPoints ; 
156     fEmcRecPoints = 0 ; 
157   }
158
159   if ( fPpsdRecPoints ) { 
160     fPpsdRecPoints->Delete() ;
161     delete fPpsdRecPoints ;
162     fPpsdRecPoints = 0 ; 
163   }
164   
165   if ( fTrackSegments ) {
166     fTrackSegments->Delete() ; 
167     delete fTrackSegments ;
168     fTrackSegments = 0 ; 
169   }
170
171 }
172
173 //____________________________________________________________________________
174 void AliPHOSv0::AddHit(Int_t primary, Int_t Id, Float_t * hits)
175 {
176   // Add a hit to the hit list.
177   // A PHOS hit is the sum of all hits in a single crystal
178   //   or in a single PPSD gas cell
179
180   Int_t hitCounter ;
181   TClonesArray &ltmphits = *fTmpHits ;
182   AliPHOSHit *newHit ;
183   AliPHOSHit *curHit ;
184   //  AliPHOSHit *curHit2 ;
185   Bool_t deja = kFALSE ;
186
187   // In any case, fills the fTmpHit TClonesArray (with "accumulated hits")
188
189   newHit = new AliPHOSHit(primary, Id, hits) ;
190
191   // We do not want to save in TreeH the raw hits 
192   //  TClonesArray &lhits = *fHits;
193
194   for ( hitCounter = 0 ; hitCounter < fNTmpHits && !deja ; hitCounter++ ) {
195     curHit = (AliPHOSHit*) ltmphits[hitCounter] ;
196   if( *curHit == *newHit ) {
197     *curHit = *curHit + *newHit ;
198     deja = kTRUE ;
199     }
200   }
201          
202   if ( !deja ) {
203     new(ltmphits[fNTmpHits]) AliPHOSHit(*newHit) ;
204     fNTmpHits++ ;
205   }
206
207   // We do not want to save in TreeH the raw hits 
208   //   new(lhits[fNhits]) AliPHOSHit(*newHit) ;    
209   //   fNhits++ ;
210
211   // Please note that the fTmpHits array must survive up to the
212   // end of the events, so it does not appear e.g. in ResetHits() (
213   // which is called at the end of each primary).  
214
215   delete newHit;
216
217 }
218
219
220 //____________________________________________________________________________
221 void AliPHOSv0::BuildGeometry()
222 {
223   // Build the PHOS geometry for the ROOT display
224   //BEGIN_HTML
225   /*
226     <H2>
227      PHOS in ALICE displayed by root
228     </H2>
229     <UL>
230     <LI> All Views
231     <P>
232     <CENTER>
233     <IMG Align=BOTTOM ALT="All Views" SRC="../images/AliPHOSv0AllViews.gif"> 
234     </CENTER></P></LI>
235     <LI> Front View
236     <P>
237     <CENTER>
238     <IMG Align=BOTTOM ALT="Front View" SRC="../images/AliPHOSv0FrontView.gif"> 
239     </CENTER></P></LI>
240      <LI> 3D View 1
241     <P>
242     <CENTER>
243     <IMG Align=BOTTOM ALT="3D View 1" SRC="../images/AliPHOSv03DView1.gif"> 
244     </CENTER></P></LI>
245     <LI> 3D View 2
246     <P>
247     <CENTER>
248     <IMG Align=BOTTOM ALT="3D View 2" SRC="../images/AliPHOSv03DView2.gif"> 
249     </CENTER></P></LI>
250     </UL>
251   */
252   //END_HTML  
253
254   this->BuildGeometryforPHOS() ; 
255   if ( ( strcmp(fGeom->GetName(), "GPS2" ) == 0 ) ) 
256     this->BuildGeometryforPPSD() ;
257   else
258     cout << "AliPHOSv0::BuildGeometry : no charged particle identification system installed" << endl; 
259
260 }
261
262 //____________________________________________________________________________
263 void AliPHOSv0:: BuildGeometryforPHOS(void)
264 {
265  // Build the PHOS-EMC geometry for the ROOT display
266
267   const Int_t kColorPHOS = kRed ;
268   const Int_t kColorXTAL = kBlue ;
269
270   Double_t const kRADDEG = 180.0 / kPI ;
271  
272   new TBRIK( "OuterBox", "PHOS box", "void", fGeom->GetOuterBoxSize(0)/2, 
273                                              fGeom->GetOuterBoxSize(1)/2, 
274                                              fGeom->GetOuterBoxSize(2)/2 );
275
276   // Textolit Wall box, position inside PHOS 
277   
278   new TBRIK( "TextolitBox", "PHOS Textolit box ", "void", fGeom->GetTextolitBoxSize(0)/2, 
279                                                           fGeom->GetTextolitBoxSize(1)/2, 
280                                                           fGeom->GetTextolitBoxSize(2)/2);
281
282   // Polystyrene Foam Plate
283
284   new TBRIK( "UpperFoamPlate", "PHOS Upper foam plate", "void", fGeom->GetTextolitBoxSize(0)/2, 
285                                                                 fGeom->GetSecondUpperPlateThickness()/2, 
286                                                                 fGeom->GetTextolitBoxSize(2)/2 ) ; 
287
288   // Air Filled Box
289  
290   new TBRIK( "AirFilledBox", "PHOS air filled box", "void", fGeom->GetAirFilledBoxSize(0)/2, 
291                                                             fGeom->GetAirFilledBoxSize(1)/2, 
292                                                             fGeom->GetAirFilledBoxSize(2)/2 );
293
294   // Crystals Box
295
296   Float_t xtlX = fGeom->GetCrystalSize(0) ; 
297   Float_t xtlY = fGeom->GetCrystalSize(1) ; 
298   Float_t xtlZ = fGeom->GetCrystalSize(2) ; 
299
300   Float_t xl =  fGeom->GetNPhi() * ( xtlX + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 + fGeom->GetModuleBoxThickness() ;
301   Float_t yl =  ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 
302              + fGeom->GetModuleBoxThickness() / 2.0 ;
303   Float_t zl =  fGeom->GetNZ() * ( xtlZ + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 +  fGeom->GetModuleBoxThickness() ;
304   
305   new TBRIK( "CrystalsBox", "PHOS crystals box", "void", xl, yl, zl ) ;
306
307 // position PHOS into ALICE
308
309   Float_t r = fGeom->GetIPtoOuterCoverDistance() + fGeom->GetOuterBoxSize(1) / 2.0 ;
310   Int_t number = 988 ; 
311   Float_t pphi =  TMath::ATan( fGeom->GetOuterBoxSize(0)  / ( 2.0 * fGeom->GetIPtoOuterCoverDistance() ) ) ;
312   pphi *= kRADDEG ;
313   TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
314  
315   char * nodename = new char[20] ;  
316   char * rotname  = new char[20] ; 
317
318   for( Int_t i = 1; i <= fGeom->GetNModules(); i++ ) { 
319    Float_t angle = pphi * 2 * ( i - fGeom->GetNModules() / 2.0 - 0.5 ) ;
320    sprintf(rotname, "%s%d", "rot", number++) ;
321    new TRotMatrix(rotname, rotname, 90, angle, 90, 90 + angle, 0, 0);
322    top->cd();
323    sprintf(nodename,"%s%d", "Module", i) ;    
324    Float_t x =  r * TMath::Sin( angle / kRADDEG ) ;
325    Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
326    TNode * outerboxnode = new TNode(nodename, nodename, "OuterBox", x, y, 0, rotname ) ;
327    outerboxnode->SetLineColor(kColorPHOS) ;
328    fNodes->Add(outerboxnode) ;
329    outerboxnode->cd() ; 
330    // now inside the outer box the textolit box
331    y = ( fGeom->GetOuterBoxThickness(1) -  fGeom->GetUpperPlateThickness() ) / 2.  ;
332    sprintf(nodename,"%s%d", "TexBox", i) ;  
333    TNode * textolitboxnode = new TNode(nodename, nodename, "TextolitBox", 0, y, 0) ; 
334    textolitboxnode->SetLineColor(kColorPHOS) ;
335    fNodes->Add(textolitboxnode) ;
336    // upper foam plate inside outre box
337    outerboxnode->cd() ; 
338    sprintf(nodename, "%s%d", "UFPlate", i) ;
339    y =  ( fGeom->GetTextolitBoxSize(1) - fGeom->GetSecondUpperPlateThickness() ) / 2.0 ;
340    TNode * upperfoamplatenode = new TNode(nodename, nodename, "UpperFoamPlate", 0, y, 0) ; 
341    upperfoamplatenode->SetLineColor(kColorPHOS) ;
342    fNodes->Add(upperfoamplatenode) ;  
343    // air filled box inside textolit box (not drawn)
344    textolitboxnode->cd();
345    y = ( fGeom->GetTextolitBoxSize(1) - fGeom->GetAirFilledBoxSize(1) ) / 2.0 -  fGeom->GetSecondUpperPlateThickness() ;
346    sprintf(nodename, "%s%d", "AFBox", i) ;
347    TNode * airfilledboxnode = new TNode(nodename, nodename, "AirFilledBox", 0, y, 0) ; 
348    fNodes->Add(airfilledboxnode) ; 
349    // crystals box inside air filled box
350    airfilledboxnode->cd() ; 
351    y = fGeom->GetAirFilledBoxSize(1) / 2.0 - yl 
352        - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetModuleBoxThickness() 
353        -  fGeom->GetUpperPlateThickness() -  fGeom->GetSecondUpperPlateThickness() ) ; 
354    sprintf(nodename, "%s%d", "XTBox", i) ; 
355    TNode * crystalsboxnode = new TNode(nodename, nodename, "CrystalsBox", 0, y, 0) ;    
356    crystalsboxnode->SetLineColor(kColorXTAL) ; 
357    fNodes->Add(crystalsboxnode) ; 
358   }
359 }
360
361 //____________________________________________________________________________
362 void AliPHOSv0:: BuildGeometryforPPSD(void)
363 {
364  //  Build the PHOS-PPSD geometry for the ROOT display
365  //BEGIN_HTML
366   /*
367     <H2>
368      PPSD displayed by root
369     </H2>
370     <UL>
371     <LI> Zoom on PPSD: Front View
372     <P>
373     <CENTER>
374     <IMG Align=BOTTOM ALT="PPSD Front View" SRC="../images/AliPHOSv0PPSDFrontView.gif"> 
375     </CENTER></P></LI>
376     <LI> Zoom on PPSD: Perspective View
377     <P>
378     <CENTER>
379     <IMG Align=BOTTOM ALT="PPSD Prespective View" SRC="../images/AliPHOSv0PPSDPerspectiveView.gif"> 
380     </CENTER></P></LI>
381     </UL>
382   */
383   //END_HTML  
384   Double_t const kRADDEG = 180.0 / kPI ;
385
386   const Int_t kColorPHOS = kRed ;
387   const Int_t kColorPPSD = kGreen ;
388   const Int_t kColorGas  = kBlue ;  
389   const Int_t kColorAir  = kYellow ; 
390
391   // Box for a full PHOS module
392
393   new TBRIK( "PPSDBox", "PPSD box", "void",  fGeom->GetPPSDBoxSize(0)/2, 
394                                              fGeom->GetPPSDBoxSize(1)/2, 
395                                              fGeom->GetPPSDBoxSize(2)/2 );
396
397   // Box containing one micromegas module 
398
399   new TBRIK( "PPSDModule", "PPSD module", "void",  fGeom->GetPPSDModuleSize(0)/2, 
400                                                    fGeom->GetPPSDModuleSize(1)/2, 
401                                                    fGeom->GetPPSDModuleSize(2)/2 );
402  // top lid
403
404   new TBRIK ( "TopLid", "Micromegas top lid", "void",  fGeom->GetPPSDModuleSize(0)/2,
405                                                        fGeom->GetLidThickness()/2,
406                                                        fGeom->GetPPSDModuleSize(2)/2 ) ; 
407  // composite panel (top and bottom)
408
409   new TBRIK ( "TopPanel", "Composite top panel", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
410                                                             fGeom->GetCompositeThickness()/2,
411                                                           ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ;  
412   
413   new TBRIK ( "BottomPanel", "Composite bottom panel", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
414                                                                   fGeom->GetCompositeThickness()/2,
415                                                                 ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
416  // gas gap (conversion and avalanche)
417
418   new TBRIK ( "GasGap", "gas gap", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
419                                             ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() )/2,
420                                             ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
421
422  // anode and cathode 
423
424   new TBRIK ( "Anode", "Anode", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
425                                            fGeom->GetAnodeThickness()/2,
426                                          ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
427
428   new TBRIK ( "Cathode", "Cathode", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
429                                                fGeom->GetCathodeThickness()/2,
430                                              ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
431  // PC  
432
433   new TBRIK ( "PCBoard", "Printed Circuit", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
434                                                        fGeom->GetPCThickness()/2,
435                                                      ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
436  // Gap between Lead and top micromegas
437
438   new TBRIK ( "LeadToM", "Air Gap top", "void", fGeom->GetPPSDBoxSize(0)/2,
439                                                 fGeom->GetMicro1ToLeadGap()/2,
440                                                 fGeom->GetPPSDBoxSize(2)/2  ) ;  
441  
442 // Gap between Lead and bottom micromegas
443
444   new TBRIK ( "MToLead", "Air Gap bottom", "void", fGeom->GetPPSDBoxSize(0)/2,
445                                                    fGeom->GetLeadToMicro2Gap()/2,
446                                                    fGeom->GetPPSDBoxSize(2)/2  ) ; 
447  // Lead converter
448    
449   new TBRIK ( "Lead", "Lead converter", "void", fGeom->GetPPSDBoxSize(0)/2,
450                                                 fGeom->GetLeadConverterThickness()/2,
451                                                 fGeom->GetPPSDBoxSize(2)/2  ) ; 
452
453      // position PPSD into ALICE
454
455   char * nodename = new char[20] ;  
456   char * rotname  = new char[20] ; 
457
458   Float_t r = fGeom->GetIPtoTopLidDistance() + fGeom->GetPPSDBoxSize(1) / 2.0 ;
459   Int_t number = 988 ; 
460   TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
461  
462   for( Int_t i = 1; i <= fGeom->GetNModules(); i++ ) { // the number of PHOS modules
463     Float_t angle = fGeom->GetPHOSAngle(i) ;
464     sprintf(rotname, "%s%d", "rotg", number++) ;
465     new TRotMatrix(rotname, rotname, 90, angle, 90, 90 + angle, 0, 0);
466     top->cd();
467     sprintf(nodename, "%s%d", "Moduleg", i) ;    
468     Float_t x =  r * TMath::Sin( angle / kRADDEG ) ;
469     Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
470     TNode * ppsdboxnode = new TNode(nodename , nodename ,"PPSDBox", x, y, 0, rotname ) ;
471     ppsdboxnode->SetLineColor(kColorPPSD) ;
472     fNodes->Add(ppsdboxnode) ;
473     ppsdboxnode->cd() ;
474     // inside the PPSD box: 
475     //   1.   fNumberOfModulesPhi x fNumberOfModulesZ top micromegas
476     x = ( fGeom->GetPPSDBoxSize(0) - fGeom->GetPPSDModuleSize(0) ) / 2. ;  
477     {
478       for ( Int_t iphi = 1; iphi <= fGeom->GetNumberOfModulesPhi(); iphi++ ) { // the number of micromegas modules in phi per PHOS module
479         Float_t z = ( fGeom->GetPPSDBoxSize(2) - fGeom->GetPPSDModuleSize(2) ) / 2. ;
480         TNode * micro1node ; 
481         for ( Int_t iz = 1; iz <= fGeom->GetNumberOfModulesZ(); iz++ ) { // the number of micromegas modules in z per PHOS module
482           y = ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas1Thickness() ) / 2. ; 
483           sprintf(nodename, "%s%d%d%d", "Mic1", i, iphi, iz) ;
484           micro1node  = new TNode(nodename, nodename, "PPSDModule", x, y, z) ;
485           micro1node->SetLineColor(kColorPPSD) ;  
486           fNodes->Add(micro1node) ; 
487           // inside top micromegas
488           micro1node->cd() ; 
489           //      a. top lid
490           y = ( fGeom->GetMicromegas1Thickness() - fGeom->GetLidThickness() ) / 2. ; 
491           sprintf(nodename, "%s%d%d%d", "Lid", i, iphi, iz) ;
492           TNode * toplidnode = new TNode(nodename, nodename, "TopLid", 0, y, 0) ;
493           toplidnode->SetLineColor(kColorPPSD) ;  
494           fNodes->Add(toplidnode) ; 
495           //      b. composite panel
496           y = y - fGeom->GetLidThickness() / 2. - fGeom->GetCompositeThickness() / 2. ; 
497           sprintf(nodename, "%s%d%d%d", "CompU", i, iphi, iz) ;
498           TNode * compupnode = new TNode(nodename, nodename, "TopPanel", 0, y, 0) ;
499           compupnode->SetLineColor(kColorPPSD) ;  
500           fNodes->Add(compupnode) ; 
501           //      c. anode
502           y = y - fGeom->GetCompositeThickness() / 2. - fGeom->GetAnodeThickness()  / 2. ; 
503           sprintf(nodename, "%s%d%d%d", "Ano", i, iphi, iz) ;
504           TNode * anodenode = new TNode(nodename, nodename, "Anode", 0, y, 0) ;
505           anodenode->SetLineColor(kColorPHOS) ;  
506           fNodes->Add(anodenode) ; 
507           //      d.  gas 
508           y = y - fGeom->GetAnodeThickness() / 2. - ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() ) / 2. ; 
509           sprintf(nodename, "%s%d%d%d", "GGap", i, iphi, iz) ;
510           TNode * ggapnode = new TNode(nodename, nodename, "GasGap", 0, y, 0) ;
511           ggapnode->SetLineColor(kColorGas) ;  
512           fNodes->Add(ggapnode) ;          
513           //      f. cathode
514           y = y - ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() ) / 2. - fGeom->GetCathodeThickness()  / 2. ; 
515           sprintf(nodename, "%s%d%d%d", "Cathode", i, iphi, iz) ;
516           TNode * cathodenode = new TNode(nodename, nodename, "Cathode", 0, y, 0) ;
517           cathodenode->SetLineColor(kColorPHOS) ;  
518           fNodes->Add(cathodenode) ;        
519           //      g. printed circuit
520           y = y - fGeom->GetCathodeThickness() / 2. - fGeom->GetPCThickness()  / 2. ; 
521           sprintf(nodename, "%s%d%d%d", "PC", i, iphi, iz) ;
522           TNode * pcnode = new TNode(nodename, nodename, "PCBoard", 0, y, 0) ;
523           pcnode->SetLineColor(kColorPPSD) ;  
524           fNodes->Add(pcnode) ;        
525           //      h. composite panel
526           y = y - fGeom->GetPCThickness() / 2. - fGeom->GetCompositeThickness()  / 2. ; 
527           sprintf(nodename, "%s%d%d%d", "CompDown", i, iphi, iz) ;
528           TNode * compdownnode = new TNode(nodename, nodename, "BottomPanel", 0, y, 0) ;
529           compdownnode->SetLineColor(kColorPPSD) ;  
530           fNodes->Add(compdownnode) ;   
531           z = z - fGeom->GetPPSDModuleSize(2) ;
532           ppsdboxnode->cd() ;
533         } // end of Z module loop     
534         x = x -  fGeom->GetPPSDModuleSize(0) ; 
535         ppsdboxnode->cd() ;
536       } // end of phi module loop
537     }
538     //   2. air gap      
539     ppsdboxnode->cd() ;
540     y = ( fGeom->GetPPSDBoxSize(1) - 2 * fGeom->GetMicromegas1Thickness() - fGeom->GetMicro1ToLeadGap() ) / 2. ; 
541     sprintf(nodename, "%s%d", "GapUp", i) ;
542     TNode * gapupnode = new TNode(nodename, nodename, "LeadToM", 0, y, 0) ;
543     gapupnode->SetLineColor(kColorAir) ;  
544     fNodes->Add(gapupnode) ;        
545     //   3. lead converter
546     y = y - fGeom->GetMicro1ToLeadGap() / 2. - fGeom->GetLeadConverterThickness() / 2. ; 
547     sprintf(nodename, "%s%d", "LeadC", i) ;
548     TNode * leadcnode = new TNode(nodename, nodename, "Lead", 0, y, 0) ;
549     leadcnode->SetLineColor(kColorPPSD) ;  
550     fNodes->Add(leadcnode) ;        
551     //   4. air gap
552     y = y - fGeom->GetLeadConverterThickness() / 2. - fGeom->GetLeadToMicro2Gap()  / 2. ; 
553     sprintf(nodename, "%s%d", "GapDown", i) ;
554     TNode * gapdownnode = new TNode(nodename, nodename, "MToLead", 0, y, 0) ;
555     gapdownnode->SetLineColor(kColorAir) ;  
556     fNodes->Add(gapdownnode) ;        
557     //    5.  fNumberOfModulesPhi x fNumberOfModulesZ bottom micromegas
558     x = ( fGeom->GetPPSDBoxSize(0) - fGeom->GetPPSDModuleSize(0) ) / 2. - fGeom->GetPhiDisplacement() ;  
559     {
560       for ( Int_t iphi = 1; iphi <= fGeom->GetNumberOfModulesPhi(); iphi++ ) { 
561         Float_t z = ( fGeom->GetPPSDBoxSize(2) - fGeom->GetPPSDModuleSize(2) ) / 2.  - fGeom->GetZDisplacement() ;;
562         TNode * micro2node ; 
563         for ( Int_t iz = 1; iz <= fGeom->GetNumberOfModulesZ(); iz++ ) { 
564           y = - ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas2Thickness() ) / 2. ; 
565           sprintf(nodename, "%s%d%d%d", "Mic2", i, iphi, iz) ;
566           micro2node  = new TNode(nodename, nodename, "PPSDModule", x, y, z) ;
567           micro2node->SetLineColor(kColorPPSD) ;  
568           fNodes->Add(micro2node) ; 
569           // inside bottom micromegas
570           micro2node->cd() ; 
571           //      a. top lid
572           y = ( fGeom->GetMicromegas2Thickness() - fGeom->GetLidThickness() ) / 2. ; 
573           sprintf(nodename, "%s%d", "Lidb", i) ;
574           TNode * toplidbnode = new TNode(nodename, nodename, "TopLid", 0, y, 0) ;
575           toplidbnode->SetLineColor(kColorPPSD) ;  
576           fNodes->Add(toplidbnode) ; 
577           //      b. composite panel
578           y = y - fGeom->GetLidThickness() / 2. - fGeom->GetCompositeThickness() / 2. ; 
579           sprintf(nodename, "%s%d", "CompUb", i) ;
580           TNode * compupbnode = new TNode(nodename, nodename, "TopPanel", 0, y, 0) ;
581           compupbnode->SetLineColor(kColorPPSD) ;  
582           fNodes->Add(compupbnode) ; 
583           //      c. anode
584           y = y - fGeom->GetCompositeThickness() / 2. - fGeom->GetAnodeThickness()  / 2. ; 
585           sprintf(nodename, "%s%d", "Anob", i) ;
586           TNode * anodebnode = new TNode(nodename, nodename, "Anode", 0, y, 0) ;
587           anodebnode->SetLineColor(kColorPPSD) ;  
588           fNodes->Add(anodebnode) ; 
589           //      d. conversion gas
590           y = y - fGeom->GetAnodeThickness() / 2. - ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() )  / 2. ; 
591           sprintf(nodename, "%s%d", "GGapb", i) ;
592           TNode * ggapbnode = new TNode(nodename, nodename, "GasGap", 0, y, 0) ;
593           ggapbnode->SetLineColor(kColorGas) ;  
594           fNodes->Add(ggapbnode) ;           
595           //      f. cathode
596           y = y - ( fGeom->GetConversionGap() + fGeom->GetAvalancheGap() ) / 2. - fGeom->GetCathodeThickness()  / 2. ; 
597           sprintf(nodename, "%s%d", "Cathodeb", i) ;
598           TNode * cathodebnode = new TNode(nodename, nodename, "Cathode", 0, y, 0) ;
599           cathodebnode->SetLineColor(kColorPPSD) ;  
600           fNodes->Add(cathodebnode) ;        
601           //      g. printed circuit
602           y = y - fGeom->GetCathodeThickness() / 2. - fGeom->GetPCThickness()  / 2. ; 
603           sprintf(nodename, "%s%d", "PCb", i) ;
604           TNode * pcbnode = new TNode(nodename, nodename, "PCBoard", 0, y, 0) ;
605           pcbnode->SetLineColor(kColorPPSD) ;  
606           fNodes->Add(pcbnode) ;        
607           //      h. composite pane
608           y = y - fGeom->GetPCThickness() / 2. - fGeom->GetCompositeThickness()  / 2. ; 
609           sprintf(nodename, "%s%d", "CompDownb", i) ;
610           TNode * compdownbnode = new TNode(nodename, nodename, "BottomPanel", 0, y, 0) ;
611           compdownbnode->SetLineColor(kColorPPSD) ;  
612           fNodes->Add(compdownbnode) ;        
613           z = z - fGeom->GetPPSDModuleSize(2) ;
614           ppsdboxnode->cd() ;
615         } // end of Z module loop     
616         x = x -  fGeom->GetPPSDModuleSize(0) ; 
617         ppsdboxnode->cd() ;
618       } // end of phi module loop
619     }
620   } // PHOS modules
621  
622   delete[] rotname ;  
623   delete[] nodename ; 
624
625 }
626
627 //____________________________________________________________________________
628 void AliPHOSv0::CreateGeometry()
629 {
630   // Create the PHOS geometry for Geant
631
632   AliPHOSv0 *phostmp = (AliPHOSv0*)gAlice->GetModule("PHOS") ;
633
634   if ( phostmp == NULL ) {
635     
636     fprintf(stderr, "PHOS detector not found!\n") ;
637     return;
638     
639   }
640   // Get pointer to the array containing media indeces
641   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
642
643   Float_t bigbox[3] ; 
644   bigbox[0] =   fGeom->GetOuterBoxSize(0) / 2.0 ;
645   bigbox[1] = ( fGeom->GetOuterBoxSize(1) + fGeom->GetPPSDBoxSize(1) ) / 2.0 ;
646   bigbox[2] =   fGeom->GetOuterBoxSize(2) / 2.0 ;
647   
648   gMC->Gsvolu("PHOS", "BOX ", idtmed[798], bigbox, 3) ;
649   
650   this->CreateGeometryforPHOS() ; 
651   if ( strcmp( fGeom->GetName(), "GPS2") == 0  ) 
652     this->CreateGeometryforPPSD() ;
653   else
654     cout << "AliPHOSv0::CreateGeometry : no charged particle identification system installed" << endl; 
655   
656   // --- Position  PHOS mdules in ALICE setup ---
657   
658   Int_t idrotm[99] ;
659   Double_t const kRADDEG = 180.0 / kPI ;
660   
661   for( Int_t i = 1; i <= fGeom->GetNModules(); i++ ) {
662     
663     Float_t angle = fGeom->GetPHOSAngle(i) ;
664     AliMatrix(idrotm[i-1], 90.0, angle, 90.0, 90.0+angle, 0.0, 0.0) ;
665  
666     Float_t r = fGeom->GetIPtoOuterCoverDistance() + ( fGeom->GetOuterBoxSize(1) + fGeom->GetPPSDBoxSize(1) ) / 2.0 ;
667
668     Float_t xP1 = r * TMath::Sin( angle / kRADDEG ) ;
669     Float_t yP1 = -r * TMath::Cos( angle / kRADDEG ) ;
670
671     gMC->Gspos("PHOS", i, "ALIC", xP1, yP1, 0.0, idrotm[i-1], "ONLY") ;
672  
673   } // for GetNModules
674
675 }
676
677 //____________________________________________________________________________
678 void AliPHOSv0::CreateGeometryforPHOS()
679 {
680   // Create the PHOS-EMC geometry for GEANT
681     //BEGIN_HTML
682   /*
683     <H2>
684     Geant3 geometry tree of PHOS-EMC in ALICE
685     </H2>
686     <P><CENTER>
687     <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/EMCinAlice.gif"> 
688     </CENTER><P>
689   */
690   //END_HTML  
691   
692   // Get pointer to the array containing media indexes
693   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
694
695   // ---
696   // --- Define PHOS box volume, fPUFPill with thermo insulating foam ---
697   // --- Foam Thermo Insulating outer cover dimensions ---
698   // --- Put it in bigbox = PHOS
699
700   Float_t dphos[3] ; 
701   dphos[0] =  fGeom->GetOuterBoxSize(0) / 2.0 ;
702   dphos[1] =  fGeom->GetOuterBoxSize(1) / 2.0 ;
703   dphos[2] =  fGeom->GetOuterBoxSize(2) / 2.0 ;
704
705   gMC->Gsvolu("EMCA", "BOX ", idtmed[706], dphos, 3) ;
706
707   Float_t yO =  - fGeom->GetPPSDBoxSize(1)  / 2.0 ;
708
709   gMC->Gspos("EMCA", 1, "PHOS", 0.0, yO, 0.0, 0, "ONLY") ; 
710
711   // ---
712   // --- Define Textolit Wall box, position inside EMCA ---
713   // --- Textolit Wall box dimentions ---
714  
715  
716   Float_t dptxw[3];
717   dptxw[0] = fGeom->GetTextolitBoxSize(0) / 2.0 ;
718   dptxw[1] = fGeom->GetTextolitBoxSize(1) / 2.0 ;
719   dptxw[2] = fGeom->GetTextolitBoxSize(2) / 2.0 ;
720
721   gMC->Gsvolu("PTXW", "BOX ", idtmed[707], dptxw, 3);
722
723   yO =   (  fGeom->GetOuterBoxThickness(1) -   fGeom->GetUpperPlateThickness() ) / 2.  ;
724    
725   gMC->Gspos("PTXW", 1, "EMCA", 0.0, yO, 0.0, 0, "ONLY") ;
726
727   // --- 
728   // --- Define Upper Polystyrene Foam Plate, place inside PTXW ---
729   // --- immediately below Foam Thermo Insulation Upper plate ---
730
731   // --- Upper Polystyrene Foam plate thickness ---
732  
733   Float_t  dpufp[3] ;
734   dpufp[0] = fGeom->GetTextolitBoxSize(0) / 2.0 ; 
735   dpufp[1] = fGeom->GetSecondUpperPlateThickness() / 2. ;
736   dpufp[2] = fGeom->GetTextolitBoxSize(2) /2.0 ; 
737
738   gMC->Gsvolu("PUFP", "BOX ", idtmed[703], dpufp, 3) ;
739   
740   yO = ( fGeom->GetTextolitBoxSize(1) -  fGeom->GetSecondUpperPlateThickness() ) / 2.0 ;
741   
742   gMC->Gspos("PUFP", 1, "PTXW", 0.0, yO, 0.0, 0, "ONLY") ;
743   
744   // ---
745   // --- Define air-filled box, place inside PTXW ---
746   // --- Inner AIR volume dimensions ---
747  
748
749   Float_t  dpair[3] ;
750   dpair[0] = fGeom->GetAirFilledBoxSize(0) / 2.0 ;
751   dpair[1] = fGeom->GetAirFilledBoxSize(1) / 2.0 ;
752   dpair[2] = fGeom->GetAirFilledBoxSize(2) / 2.0 ;
753
754   gMC->Gsvolu("PAIR", "BOX ", idtmed[798], dpair, 3) ;
755   
756   yO = ( fGeom->GetTextolitBoxSize(1) -  fGeom->GetAirFilledBoxSize(1) ) / 2.0 -   fGeom->GetSecondUpperPlateThickness() ;
757   
758   gMC->Gspos("PAIR", 1, "PTXW", 0.0, yO, 0.0, 0, "ONLY") ;
759
760 // --- Dimensions of PbWO4 crystal ---
761
762   Float_t xtlX =  fGeom->GetCrystalSize(0) ; 
763   Float_t xtlY =  fGeom->GetCrystalSize(1) ; 
764   Float_t xtlZ =  fGeom->GetCrystalSize(2) ; 
765
766   Float_t dptcb[3] ;  
767   dptcb[0] =  fGeom->GetNPhi() * ( xtlX + 2 *  fGeom->GetGapBetweenCrystals() ) / 2.0 + fGeom->GetModuleBoxThickness() ;
768   dptcb[1] = ( xtlY +  fGeom->GetCrystalSupportHeight() +  fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 
769              + fGeom->GetModuleBoxThickness() / 2.0 ;
770   dptcb[2] = fGeom->GetNZ() * ( xtlZ + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 +  fGeom->GetModuleBoxThickness() ;
771   
772   gMC->Gsvolu("PTCB", "BOX ", idtmed[706], dptcb, 3) ;
773
774   yO =  fGeom->GetAirFilledBoxSize(1) / 2.0 - dptcb[1] 
775        - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetModuleBoxThickness() 
776        -  fGeom->GetUpperPlateThickness() -  fGeom->GetSecondUpperPlateThickness() ) ;
777   
778   gMC->Gspos("PTCB", 1, "PAIR", 0.0, yO, 0.0, 0, "ONLY") ;
779
780   // ---
781   // --- Define Crystal BLock filled with air, position it inside PTCB ---
782   Float_t dpcbl[3] ; 
783   
784   dpcbl[0] = fGeom->GetNPhi() * ( xtlX + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 ;
785   dpcbl[1] = ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 ;
786   dpcbl[2] = fGeom->GetNZ() * ( xtlZ + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 ;
787   
788   gMC->Gsvolu("PCBL", "BOX ", idtmed[798], dpcbl, 3) ;
789   
790   // --- Divide PCBL in X (phi) and Z directions --
791   gMC->Gsdvn("PROW", "PCBL", Int_t (fGeom->GetNPhi()), 1) ;
792   gMC->Gsdvn("PCEL", "PROW", Int_t (fGeom->GetNZ()), 3) ;
793
794   yO = -fGeom->GetModuleBoxThickness() / 2.0 ;
795   
796   gMC->Gspos("PCBL", 1, "PTCB", 0.0, yO, 0.0, 0, "ONLY") ;
797
798   // ---
799   // --- Define STeel (actually, it's titanium) Cover volume, place inside PCEL
800   Float_t  dpstc[3] ; 
801   
802   dpstc[0] = ( xtlX + 2 * fGeom->GetCrystalWrapThickness() ) / 2.0 ;
803   dpstc[1] = ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 ;
804   dpstc[2] = ( xtlZ + 2 * fGeom->GetCrystalWrapThickness()  + 2 *  fGeom->GetCrystalHolderThickness() ) / 2.0 ;
805   
806   gMC->Gsvolu("PSTC", "BOX ", idtmed[704], dpstc, 3) ;
807
808   gMC->Gspos("PSTC", 1, "PCEL", 0.0, 0.0, 0.0, 0, "ONLY") ;
809
810   // ---
811   // --- Define Tyvek volume, place inside PSTC ---
812   Float_t  dppap[3] ;
813
814   dppap[0] = xtlX / 2.0 + fGeom->GetCrystalWrapThickness() ;
815   dppap[1] = ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 ;
816   dppap[2] = xtlZ / 2.0 + fGeom->GetCrystalWrapThickness() ;
817   
818   gMC->Gsvolu("PPAP", "BOX ", idtmed[702], dppap, 3) ;
819   
820   yO = ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 
821               - ( xtlY +  fGeom->GetCrystalSupportHeight() +  fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 ;
822    
823   gMC->Gspos("PPAP", 1, "PSTC", 0.0, yO, 0.0, 0, "ONLY") ;
824
825   // ---
826   // --- Define PbWO4 crystal volume, place inside PPAP ---
827   Float_t  dpxtl[3] ; 
828
829   dpxtl[0] = xtlX / 2.0 ;
830   dpxtl[1] = xtlY / 2.0 ;
831   dpxtl[2] = xtlZ / 2.0 ;
832   
833   gMC->Gsvolu("PXTL", "BOX ", idtmed[699], dpxtl, 3) ;
834
835   yO = ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 - xtlY / 2.0 - fGeom->GetCrystalWrapThickness() ;
836   
837   gMC->Gspos("PXTL", 1, "PPAP", 0.0, yO, 0.0, 0, "ONLY") ;
838
839   // ---
840   // --- Define crystal support volume, place inside PPAP ---
841   Float_t dpsup[3] ; 
842
843   dpsup[0] = xtlX / 2.0 + fGeom->GetCrystalWrapThickness()  ;
844   dpsup[1] = fGeom->GetCrystalSupportHeight() / 2.0 ;
845   dpsup[2] = xtlZ / 2.0 +  fGeom->GetCrystalWrapThickness() ;
846
847   gMC->Gsvolu("PSUP", "BOX ", idtmed[798], dpsup, 3) ;
848
849   yO =  fGeom->GetCrystalSupportHeight() / 2.0 - ( xtlY +  fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 ;
850
851   gMC->Gspos("PSUP", 1, "PPAP", 0.0, yO, 0.0, 0, "ONLY") ;
852
853   // ---
854   // --- Define PIN-diode volume and position it inside crystal support ---
855   // --- right behind PbWO4 crystal
856
857   // --- PIN-diode dimensions ---
858
859  
860   Float_t dppin[3] ;
861   dppin[0] = fGeom->GetPinDiodeSize(0) / 2.0 ;
862   dppin[1] = fGeom->GetPinDiodeSize(1) / 2.0 ;
863   dppin[2] = fGeom->GetPinDiodeSize(2) / 2.0 ;
864  
865   gMC->Gsvolu("PPIN", "BOX ", idtmed[705], dppin, 3) ;
866  
867   yO = fGeom->GetCrystalSupportHeight() / 2.0 - fGeom->GetPinDiodeSize(1) / 2.0 ;
868  
869   gMC->Gspos("PPIN", 1, "PSUP", 0.0, yO, 0.0, 0, "ONLY") ;
870
871   // ---
872   // --- Define Upper Cooling Panel, place it on top of PTCB ---
873   Float_t dpucp[3] ;
874  // --- Upper Cooling Plate thickness ---
875  
876   dpucp[0] = dptcb[0] ;
877   dpucp[1] = fGeom->GetUpperCoolingPlateThickness() ;
878   dpucp[2] = dptcb[2] ;
879   
880   gMC->Gsvolu("PUCP", "BOX ", idtmed[701], dpucp,3) ;
881   
882   yO = (  fGeom->GetAirFilledBoxSize(1) -  fGeom->GetUpperCoolingPlateThickness() ) / 2. 
883        - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetModuleBoxThickness()
884            - fGeom->GetUpperPlateThickness() - fGeom->GetSecondUpperPlateThickness() - fGeom->GetUpperCoolingPlateThickness() ) ; 
885   
886   gMC->Gspos("PUCP", 1, "PAIR", 0.0, yO, 0.0, 0, "ONLY") ;
887
888   // ---
889   // --- Define Al Support Plate, position it inside PAIR ---
890   // --- right beneath PTCB ---
891  // --- Al Support Plate thickness ---
892  
893   Float_t dpasp[3] ;
894   dpasp[0] =  fGeom->GetAirFilledBoxSize(0) / 2.0 ;
895   dpasp[1] = fGeom->GetSupportPlateThickness() / 2.0 ;
896   dpasp[2] =  fGeom->GetAirFilledBoxSize(2) / 2.0 ;
897   
898   gMC->Gsvolu("PASP", "BOX ", idtmed[701], dpasp, 3) ;
899   
900   yO = (  fGeom->GetAirFilledBoxSize(1) - fGeom->GetSupportPlateThickness() ) / 2. 
901        -  ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance()
902            - fGeom->GetUpperPlateThickness() - fGeom->GetSecondUpperPlateThickness() + dpcbl[1] * 2 ) ;
903   
904   gMC->Gspos("PASP", 1, "PAIR", 0.0, yO, 0.0, 0, "ONLY") ;
905
906   // ---
907   // --- Define Thermo Insulating Plate, position it inside PAIR ---
908   // --- right beneath PASP ---
909   // --- Lower Thermo Insulating Plate thickness ---
910   
911   Float_t dptip[3] ;
912   dptip[0] = fGeom->GetAirFilledBoxSize(0) / 2.0 ;
913   dptip[1] = fGeom->GetLowerThermoPlateThickness() / 2.0 ;
914   dptip[2] = fGeom->GetAirFilledBoxSize(2) / 2.0 ;
915
916   gMC->Gsvolu("PTIP", "BOX ", idtmed[706], dptip, 3) ;
917
918   yO =  ( fGeom->GetAirFilledBoxSize(1) - fGeom->GetLowerThermoPlateThickness() ) / 2. 
919        -  ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetUpperPlateThickness() 
920             - fGeom->GetSecondUpperPlateThickness() + dpcbl[1] * 2 + fGeom->GetSupportPlateThickness() ) ;
921
922   gMC->Gspos("PTIP", 1, "PAIR", 0.0, yO, 0.0, 0, "ONLY") ;
923
924   // ---
925   // --- Define Textolit Plate, position it inside PAIR ---
926   // --- right beneath PTIP ---
927   // --- Lower Textolit Plate thickness ---
928  
929   Float_t dptxp[3] ;
930   dptxp[0] = fGeom->GetAirFilledBoxSize(0) / 2.0 ;
931   dptxp[1] = fGeom->GetLowerTextolitPlateThickness() / 2.0 ;
932   dptxp[2] = fGeom->GetAirFilledBoxSize(2) / 2.0 ;
933
934   gMC->Gsvolu("PTXP", "BOX ", idtmed[707], dptxp, 3) ;
935
936   yO =  ( fGeom->GetAirFilledBoxSize(1) - fGeom->GetLowerTextolitPlateThickness() ) / 2. 
937        -  ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetUpperPlateThickness() 
938             - fGeom->GetSecondUpperPlateThickness() + dpcbl[1] * 2 + fGeom->GetSupportPlateThickness() 
939             +  fGeom->GetLowerThermoPlateThickness() ) ;
940
941   gMC->Gspos("PTXP", 1, "PAIR", 0.0, yO, 0.0, 0, "ONLY") ;
942
943 }
944
945 //____________________________________________________________________________
946 void AliPHOSv0::CreateGeometryforPPSD()
947 {
948   // Create the PHOS-PPSD geometry for GEANT
949
950   //BEGIN_HTML
951   /*
952     <H2>
953     Geant3 geometry tree of PHOS-PPSD in ALICE
954     </H2>
955     <P><CENTER>
956     <IMG Align=BOTTOM ALT="PPSD geant tree" SRC="../images/PPSDinAlice.gif"> 
957     </CENTER><P>
958   */
959   //END_HTML  
960
961   // Get pointer to the array containing media indexes
962   Int_t *idtmed = fIdtmed->GetArray() - 699 ;
963   
964   // The box containing all ppsd's for one PHOS module filled with air 
965   Float_t ppsd[3] ; 
966   ppsd[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ;  
967   ppsd[1] = fGeom->GetPPSDBoxSize(1) / 2.0 ; 
968   ppsd[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
969
970   gMC->Gsvolu("PPSD", "BOX ", idtmed[798], ppsd, 3) ;
971
972   Float_t yO =  fGeom->GetOuterBoxSize(1) / 2.0 ;
973
974   gMC->Gspos("PPSD", 1, "PHOS", 0.0, yO, 0.0, 0, "ONLY") ; 
975
976   // Now we build a micromegas module
977   // The box containing the whole module filled with epoxy (FR4)
978
979   Float_t mppsd[3] ;  
980   mppsd[0] = fGeom->GetPPSDModuleSize(0) / 2.0 ;  
981   mppsd[1] = fGeom->GetPPSDModuleSize(1) / 2.0 ;  
982   mppsd[2] = fGeom->GetPPSDModuleSize(2) / 2.0 ;
983
984   gMC->Gsvolu("MPPS", "BOX ", idtmed[708], mppsd, 3) ;  
985  
986   // Inside mppsd :
987   // 1. The Top Lid made of epoxy (FR4) 
988
989   Float_t tlppsd[3] ; 
990   tlppsd[0] = fGeom->GetPPSDModuleSize(0) / 2.0 ; 
991   tlppsd[1] = fGeom->GetLidThickness() / 2.0 ;
992   tlppsd[2] = fGeom->GetPPSDModuleSize(2) / 2.0 ;
993
994   gMC->Gsvolu("TLPS", "BOX ", idtmed[708], tlppsd, 3) ; 
995
996   Float_t  y0 = ( fGeom->GetMicromegas1Thickness() - fGeom->GetLidThickness() ) / 2. ; 
997
998   gMC->Gspos("TLPS", 1, "MPPS", 0.0, y0, 0.0, 0, "ONLY") ; 
999  
1000   // 2. the upper panel made of composite material
1001
1002   Float_t upppsd[3] ; 
1003   upppsd[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
1004   upppsd[1] = fGeom->GetCompositeThickness() / 2.0 ;
1005   upppsd[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
1006  
1007   gMC->Gsvolu("UPPS", "BOX ", idtmed[709], upppsd, 3) ; 
1008   
1009   y0 = y0 - fGeom->GetLidThickness() / 2. - fGeom->GetCompositeThickness() / 2. ; 
1010
1011   gMC->Gspos("UPPS", 1, "MPPS", 0.0, y0, 0.0, 0, "ONLY") ; 
1012
1013   // 3. the anode made of Copper
1014   
1015   Float_t anppsd[3] ; 
1016   anppsd[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ; 
1017   anppsd[1] = fGeom->GetAnodeThickness() / 2.0 ; 
1018   anppsd[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0  ; 
1019
1020   gMC->Gsvolu("ANPS", "BOX ", idtmed[710], anppsd, 3) ; 
1021   
1022   y0 = y0 - fGeom->GetCompositeThickness() / 2. - fGeom->GetAnodeThickness()  / 2. ; 
1023   
1024   gMC->Gspos("ANPS", 1, "MPPS", 0.0, y0, 0.0, 0, "ONLY") ; 
1025
1026   // 4. the conversion gap + avalanche gap filled with gas
1027
1028   Float_t ggppsd[3] ; 
1029   ggppsd[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
1030   ggppsd[1] = ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() ) / 2.0 ; 
1031   ggppsd[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
1032
1033   gMC->Gsvolu("GGPS", "BOX ", idtmed[715], ggppsd, 3) ; 
1034   
1035   // --- Divide GGPP in X (phi) and Z directions --
1036   gMC->Gsdvn("GROW", "GGPS", fGeom->GetNumberOfPadsPhi(), 1) ;
1037   gMC->Gsdvn("GCEL", "GROW", fGeom->GetNumberOfPadsZ() , 3) ;
1038
1039   y0 = y0 - fGeom->GetAnodeThickness() / 2.  - ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() ) / 2. ; 
1040
1041   gMC->Gspos("GGPS", 1, "MPPS", 0.0, y0, 0.0, 0, "ONLY") ; 
1042
1043
1044   // 6. the cathode made of Copper
1045
1046   Float_t cappsd[3] ;
1047   cappsd[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
1048   cappsd[1] = fGeom->GetCathodeThickness() / 2.0 ; 
1049   cappsd[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0  ;
1050
1051   gMC->Gsvolu("CAPS", "BOX ", idtmed[710], cappsd, 3) ; 
1052
1053   y0 = y0 - ( fGeom->GetAvalancheGap() +  fGeom->GetAvalancheGap() ) / 2. - fGeom->GetCathodeThickness()  / 2. ; 
1054
1055   gMC->Gspos("CAPS", 1, "MPPS", 0.0, y0, 0.0, 0, "ONLY") ; 
1056
1057   // 7. the printed circuit made of G10       
1058
1059   Float_t pcppsd[3] ; 
1060   pcppsd[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2,.0 ; 
1061   pcppsd[1] = fGeom->GetPCThickness() / 2.0 ; 
1062   pcppsd[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
1063
1064   gMC->Gsvolu("PCPS", "BOX ", idtmed[711], cappsd, 3) ; 
1065
1066   y0 = y0 - fGeom->GetCathodeThickness() / 2. - fGeom->GetPCThickness()  / 2. ; 
1067
1068   gMC->Gspos("PCPS", 1, "MPPS", 0.0, y0, 0.0, 0, "ONLY") ; 
1069
1070   // 8. the lower panel made of composite material
1071                                                     
1072   Float_t lpppsd[3] ; 
1073   lpppsd[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ; 
1074   lpppsd[1] = fGeom->GetCompositeThickness() / 2.0 ; 
1075   lpppsd[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
1076
1077   gMC->Gsvolu("LPPS", "BOX ", idtmed[709], lpppsd, 3) ; 
1078  
1079   y0 = y0 - fGeom->GetPCThickness() / 2. - fGeom->GetCompositeThickness()  / 2. ; 
1080
1081   gMC->Gspos("LPPS", 1, "MPPS", 0.0, y0, 0.0, 0, "ONLY") ; 
1082
1083   // Position the  fNumberOfModulesPhi x fNumberOfModulesZ modules (mppsd) inside PPSD to cover a PHOS module
1084   // the top and bottom one's (which are assumed identical) :
1085
1086    Float_t yt = ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas1Thickness() ) / 2. ; 
1087    Float_t yb = - ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas2Thickness() ) / 2. ; 
1088
1089    Int_t copyNumbertop = 0 ; 
1090    Int_t copyNumberbot = fGeom->GetNumberOfModulesPhi() *  fGeom->GetNumberOfModulesZ() ; 
1091
1092    Float_t x  = ( fGeom->GetPPSDBoxSize(0) - fGeom->GetPPSDModuleSize(0) ) / 2. ;  
1093
1094    for ( Int_t iphi = 1; iphi <= fGeom->GetNumberOfModulesPhi(); iphi++ ) { // the number of micromegas modules in phi per PHOS module
1095       Float_t z = ( fGeom->GetPPSDBoxSize(2) - fGeom->GetPPSDModuleSize(2) ) / 2. ;
1096
1097       for ( Int_t iz = 1; iz <= fGeom->GetNumberOfModulesZ(); iz++ ) { // the number of micromegas modules in z per PHOS module
1098         gMC->Gspos("MPPS", ++copyNumbertop, "PPSD", x, yt, z, 0, "ONLY") ;
1099         gMC->Gspos("MPPS", ++copyNumberbot, "PPSD", x, yb, z, 0, "ONLY") ; 
1100         z = z - fGeom->GetPPSDModuleSize(2) ;
1101       } // end of Z module loop   
1102       x = x -  fGeom->GetPPSDModuleSize(0) ; 
1103     } // end of phi module loop
1104
1105    // The Lead converter between two air gaps
1106    // 1. Upper air gap
1107
1108    Float_t uappsd[3] ;
1109    uappsd[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ;
1110    uappsd[1] = fGeom->GetMicro1ToLeadGap() / 2.0 ; 
1111    uappsd[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
1112
1113   gMC->Gsvolu("UAPPSD", "BOX ", idtmed[798], uappsd, 3) ; 
1114
1115   y0 = ( fGeom->GetPPSDBoxSize(1) - 2 * fGeom->GetMicromegas1Thickness() - fGeom->GetMicro1ToLeadGap() ) / 2. ; 
1116
1117   gMC->Gspos("UAPPSD", 1, "PPSD", 0.0, y0, 0.0, 0, "ONLY") ; 
1118
1119    // 2. Lead converter
1120  
1121   Float_t lcppsd[3] ; 
1122   lcppsd[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ;
1123   lcppsd[1] = fGeom->GetLeadConverterThickness() / 2.0 ; 
1124   lcppsd[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
1125  
1126   gMC->Gsvolu("LCPPSD", "BOX ", idtmed[712], lcppsd, 3) ; 
1127   
1128   y0 = y0 - fGeom->GetMicro1ToLeadGap() / 2. - fGeom->GetLeadConverterThickness() / 2. ; 
1129
1130   gMC->Gspos("LCPPSD", 1, "PPSD", 0.0, y0, 0.0, 0, "ONLY") ; 
1131
1132   // 3. Lower air gap
1133
1134   Float_t lappsd[3] ; 
1135   lappsd[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ; 
1136   lappsd[1] = fGeom->GetLeadToMicro2Gap() / 2.0 ; 
1137   lappsd[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
1138
1139   gMC->Gsvolu("LAPPSD", "BOX ", idtmed[798], lappsd, 3) ; 
1140     
1141   y0 = y0 - fGeom->GetLeadConverterThickness() / 2. - fGeom->GetLeadToMicro2Gap()  / 2. ; 
1142   
1143   gMC->Gspos("LAPPSD", 1, "PPSD", 0.0, y0, 0.0, 0, "ONLY") ; 
1144    
1145 }
1146
1147 //___________________________________________________________________________
1148 Int_t AliPHOSv0::Digitize(Float_t Energy)
1149 {
1150   // Applies the energy calibration
1151   
1152   Float_t fB = 100000000. ;
1153   Float_t fA = 0. ;
1154   Int_t chan = Int_t(fA + Energy*fB ) ;
1155   return chan ;
1156 }
1157
1158 //___________________________________________________________________________
1159 void AliPHOSv0::FinishEvent()
1160 {
1161   // Makes the digits from the sum of summed hit in a single crystal or PPSD gas cell
1162   // Adds to the energy the electronic noise
1163   // Keeps digits with energy above fDigitThreshold
1164
1165   // Save the cumulated hits instead of raw hits (need to create the branch myself)
1166   // It is put in the Digit Tree because the TreeH is filled after each primary
1167   // and the TreeD at the end of the event.
1168   
1169   if ( ! (gAlice->IsLegoRun()) ) { // only when not in lego plot mode 
1170     if ( fTmpHits && gAlice->TreeD() ) {
1171       char branchname[10] ;
1172       sprintf(branchname, "%sCH", GetName()) ;
1173       gAlice->TreeD()->Branch(branchname, &fTmpHits, fBufferSize) ; 
1174     } else 
1175       cout << "AliPHOSv0::AliPHOSv0: Failed to create branch PHOSCH in TreeD " << endl ;  
1176   }
1177   
1178   Int_t i ;
1179   Int_t relid[4];
1180   Int_t j ; 
1181   TClonesArray &lDigits = *fDigits ;
1182   AliPHOSHit  * hit ;
1183   AliPHOSDigit * newdigit ;
1184   AliPHOSDigit * curdigit ;
1185   Bool_t deja = kFALSE ; 
1186   
1187   for ( i = 0 ; i < fNTmpHits ; i++ ) {
1188     hit = (AliPHOSHit*)fTmpHits->At(i) ;
1189     newdigit = new AliPHOSDigit( hit->GetPrimary(), hit->GetId(), Digitize( hit->GetEnergy() ) ) ;
1190     deja =kFALSE ;
1191     for ( j = 0 ; j < fNdigits ;  j++) { 
1192       curdigit = (AliPHOSDigit*) lDigits[j] ;
1193       if ( *curdigit == *newdigit) {
1194         *curdigit = *curdigit + *newdigit ; 
1195         deja = kTRUE ; 
1196       }
1197     }
1198     if ( !deja ) {
1199       new(lDigits[fNdigits]) AliPHOSDigit(* newdigit) ;
1200       fNdigits++ ;  
1201     }
1202  
1203     delete newdigit ;    
1204   } 
1205   
1206   // Noise induced by the PIN diode of the PbWO crystals
1207
1208   Float_t energyandnoise ;
1209   for ( i = 0 ; i < fNdigits ; i++ ) {
1210     newdigit =  (AliPHOSDigit * ) fDigits->At(i) ;
1211     fGeom->AbsToRelNumbering(newdigit->GetId(), relid) ;
1212
1213     if (relid[1]==0){   // Digits belong to EMC (PbW0_4 crystals)
1214       energyandnoise = newdigit->GetAmp() + Digitize(gRandom->Gaus(0., fPinElectronicNoise)) ;
1215
1216       if (energyandnoise < 0 ) 
1217         energyandnoise = 0 ;
1218
1219       if ( newdigit->GetAmp() < fDigitThreshold ) // if threshold not surpassed, remove digit from list
1220         fDigits->RemoveAt(i) ; 
1221     }
1222   }
1223   
1224   fDigits->Compress() ;  
1225
1226   fNdigits =  fDigits->GetEntries() ; 
1227   for (i = 0 ; i < fNdigits ; i++) { 
1228     newdigit = (AliPHOSDigit *) fDigits->At(i) ; 
1229     newdigit->SetIndexInList(i) ; 
1230   }
1231
1232 }
1233
1234 //____________________________________________________________________________
1235 void AliPHOSv0::Init(void)
1236 {
1237   // Just prints an information message
1238   
1239   Int_t i;
1240
1241   printf("\n");
1242   for(i=0;i<35;i++) printf("*");
1243   printf(" PHOS_INIT ");
1244   for(i=0;i<35;i++) printf("*");
1245   printf("\n");
1246
1247   // Here the PHOS initialisation code (if any!)
1248
1249   for(i=0;i<80;i++) printf("*");
1250   printf("\n");
1251   
1252 }
1253
1254 //___________________________________________________________________________
1255 void AliPHOSv0::MakeBranch(Option_t* opt)
1256 {  
1257   // Create new branche in the current Root Tree in the digit Tree
1258
1259   AliDetector::MakeBranch(opt) ;
1260   
1261   char branchname[10];
1262   sprintf(branchname,"%s",GetName());
1263   char *cdD = strstr(opt,"D");
1264   
1265   if (fDigits && gAlice->TreeD() && cdD) {
1266     gAlice->TreeD()->Branch(branchname, &fDigits, fBufferSize);
1267   }
1268 }
1269
1270 //____________________________________________________________________________
1271 RecPointsList * AliPHOSv0::PpsdRecPoints(Int_t evt) 
1272 {
1273   // returns the pointer to the PPSD RecPoints list
1274   // if the list is empty, get it from TreeR on the disk file
1275
1276   RecPointsList * rv = 0 ; 
1277
1278   if ( fPpsdRecPoints ) 
1279     rv = fPpsdRecPoints ; 
1280
1281   else {
1282     fPpsdRecPoints = new TClonesArray("AliPHOSPpsdRecPoint", 100) ; 
1283     gAlice->GetEvent(evt) ; 
1284     TTree * fReconstruct = gAlice->TreeR() ; 
1285     fReconstruct->SetBranchAddress( "PHOSPpsdRP", &fPpsdRecPoints) ;
1286     fReconstruct->GetEvent(0) ;
1287     rv =  fPpsdRecPoints ;
1288   }
1289   
1290   fPpsdRecPoints->Expand( fPpsdRecPoints->GetEntries() ) ; 
1291     
1292   return rv ; 
1293   
1294 }
1295
1296 //_____________________________________________________________________________
1297 void AliPHOSv0::Reconstruction(AliPHOSReconstructioner * Reconstructioner)
1298
1299   // 1. Reinitializes the existing RecPoint, TrackSegment, and RecParticles Lists and 
1300   // 2. Creates TreeR wit a branch for each list
1301   // 3. Steers the reconstruction processes
1302   // 4. Saves the 3 lists in TreeR
1303   // 5. Write the Tree to File
1304   
1305   fReconstructioner = Reconstructioner ;
1306   
1307   char branchname[10] ;
1308
1309   // 1.
1310
1311   gAlice->MakeTree("R") ; 
1312   Int_t splitlevel = 0 ; 
1313   
1314   if (fEmcRecPoints) { 
1315     fEmcRecPoints->Delete() ; 
1316     delete fEmcRecPoints ;
1317     fEmcRecPoints = 0 ; 
1318   }
1319
1320   //  fEmcRecPoints= new RecPointsList("AliPHOSEmcRecPoint", 100) ; if TClonesArray
1321   fEmcRecPoints= new RecPointsList(100) ; 
1322
1323   if ( fEmcRecPoints && gAlice->TreeR() ) {
1324     sprintf(branchname,"%sEmcRP",GetName()) ;
1325     
1326     // gAlice->TreeR()->Branch(branchname, &fEmcRecPoints, fBufferSize); if TClonesArray
1327     gAlice->TreeR()->Branch(branchname, "TObjArray", &fEmcRecPoints, fBufferSize, splitlevel) ; 
1328   }
1329
1330   if (fPpsdRecPoints) { 
1331     fPpsdRecPoints->Delete() ; 
1332     delete fPpsdRecPoints ; 
1333     fPpsdRecPoints = 0 ; 
1334   }
1335
1336   //  fPpsdRecPoints = new RecPointsList("AliPHOSPpsdRecPoint", 100) ; if TClonesArray
1337   fPpsdRecPoints = new RecPointsList(100) ;
1338
1339   if ( fPpsdRecPoints && gAlice->TreeR() ) {
1340     sprintf(branchname,"%sPpsdRP",GetName()) ;
1341      
1342      // gAlice->TreeR()->Branch(branchname, &fPpsdRecPoints, fBufferSize); if TClonesArray
1343     gAlice->TreeR()->Branch(branchname, "TObjArray", &fPpsdRecPoints, fBufferSize, splitlevel) ;
1344   }
1345
1346   if (fTrackSegments) { 
1347    fTrackSegments->Delete() ; 
1348     delete fTrackSegments ; 
1349     fTrackSegments = 0 ; 
1350   }
1351
1352   fTrackSegments = new TrackSegmentsList("AliPHOSTrackSegment", 100) ;
1353   if ( fTrackSegments && gAlice->TreeR() ) { 
1354     sprintf(branchname,"%sTS",GetName()) ;
1355     gAlice->TreeR()->Branch(branchname, &fTrackSegments, fBufferSize) ;
1356   }
1357
1358   if (fRecParticles) {  
1359     fRecParticles->Delete() ; 
1360     delete fRecParticles ; 
1361     fRecParticles = 0 ; 
1362   }
1363   fRecParticles = new RecParticlesList("AliPHOSRecParticle", 100) ;
1364   if ( fRecParticles && gAlice->TreeR() ) { 
1365      sprintf(branchname,"%sRP",GetName()) ;
1366      gAlice->TreeR()->Branch(branchname, &fRecParticles, fBufferSize) ;
1367   }
1368   
1369   // 3.
1370
1371   fReconstructioner->Make(fDigits, fEmcRecPoints, fPpsdRecPoints, fTrackSegments, fRecParticles);
1372
1373   // 4. Expand or Shrink the arrays to the proper size
1374   
1375   Int_t size ;
1376   
1377   size = fEmcRecPoints->GetEntries() ;
1378   fEmcRecPoints->Expand(size) ;
1379  
1380   size = fPpsdRecPoints->GetEntries() ;
1381   fPpsdRecPoints->Expand(size) ;
1382
1383   size = fTrackSegments->GetEntries() ;
1384   fTrackSegments->Expand(size) ;
1385
1386   size = fRecParticles->GetEntries() ;
1387   fRecParticles->Expand(size) ;
1388
1389   gAlice->TreeR()->Fill() ;
1390  
1391   // 5.
1392
1393   gAlice->TreeR()->Write() ;
1394    
1395 }
1396
1397 //____________________________________________________________________________
1398 void AliPHOSv0::ResetDigits()
1399 {
1400   // May sound strange, but cumulative hits are store in digits Tree
1401
1402   if(  fTmpHits ) {
1403     fTmpHits->Delete();
1404     fNTmpHits = 0 ;
1405   }
1406 }
1407   
1408 //____________________________________________________________________________
1409 void AliPHOSv0::StepManager(void)
1410 {
1411   // Accumulates hits as long as the track stays in a single crystal or PPSD gas Cell
1412
1413   Int_t          relid[4] ;      // (box, layer, row, column) indices
1414   Float_t        xyze[4] ;       // position wrt MRS and energy deposited
1415   TLorentzVector pos ;
1416   Int_t copy ;
1417
1418   Int_t primary =  gAlice->GetPrimary( gAlice->CurrentTrack() ); 
1419   TString name = fGeom->GetName() ; 
1420   if ( name == "GPS2" ) { // the CPV is a PPSD
1421     if( gMC->CurrentVolID(copy) == gMC->VolId("GCEL") ) // We are inside a gas cell 
1422     {
1423       gMC->TrackPosition(pos) ;
1424       xyze[0] = pos[0] ;
1425       xyze[1] = pos[1] ;
1426       xyze[2] = pos[2] ;
1427       xyze[3] = gMC->Edep() ; 
1428
1429       if ( xyze[3] != 0 ) { // there is deposited energy 
1430         gMC->CurrentVolOffID(5, relid[0]) ;  // get the PHOS Module number
1431         gMC->CurrentVolOffID(3, relid[1]) ;  // get the Micromegas Module number 
1432       // 1-> Geom->GetNumberOfModulesPhi() *  fGeom->GetNumberOfModulesZ() upper                         
1433       //  >  fGeom->GetNumberOfModulesPhi()  *  fGeom->GetNumberOfModulesZ() lower
1434         gMC->CurrentVolOffID(1, relid[2]) ;  // get the row number of the cell
1435         gMC->CurrentVolID(relid[3]) ;        // get the column number 
1436
1437         // get the absolute Id number
1438
1439         Int_t absid ; 
1440         fGeom->RelToAbsNumbering(relid, absid) ; 
1441
1442         // add current hit to the hit list      
1443         AddHit(primary, absid, xyze);
1444
1445       } // there is deposited energy 
1446      } // We are inside the gas of the CPV  
1447    } // GPS2 configuration
1448   
1449    if(gMC->CurrentVolID(copy) == gMC->VolId("PXTL") )  //  We are inside a PBWO crystal
1450      {
1451        gMC->TrackPosition(pos) ;
1452        xyze[0] = pos[0] ;
1453        xyze[1] = pos[1] ;
1454        xyze[2] = pos[2] ;
1455        xyze[3] = gMC->Edep() ;
1456
1457        if ( xyze[3] != 0 ) {
1458           gMC->CurrentVolOffID(10, relid[0]) ; // get the PHOS module number ;
1459           relid[1] = 0   ;                    // means PBW04
1460           gMC->CurrentVolOffID(4, relid[2]) ; // get the row number inside the module
1461           gMC->CurrentVolOffID(3, relid[3]) ; // get the cell number inside the module
1462
1463       // get the absolute Id number
1464
1465           Int_t absid ; 
1466           fGeom->RelToAbsNumbering(relid, absid) ; 
1467  
1468       // add current hit to the hit list
1469
1470           AddHit(primary, absid, xyze);
1471     
1472        } // there is deposited energy
1473     } // we are inside a PHOS Xtal
1474 }
1475