Clean up to correct for the mess introduced by my eratic branching !
[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 //_________________________________________________________________________
17 // Manager class for PHOS version SUBATECH
18 //*-- Author : Y. Schutz SUBATECH 
19 //////////////////////////////////////////////////////////////////////////////
20
21 // --- ROOT system ---
22
23 #include "TBRIK.h"
24 #include "TNode.h"
25
26 // --- Standard library ---
27
28 #include <cstdio>
29 #include <cstring>
30 #include <cstdlib>
31 #include <strstream>
32 #include <cassert>
33
34 // --- AliRoot header files ---
35
36 #include "AliPHOSv0.h"
37 #include "AliPHOSHit.h"
38 #include "AliPHOSDigit.h"
39 #include "AliPHOSReconstructioner.h"
40 #include "AliRun.h"
41 #include "AliConst.h"
42
43 ClassImp(AliPHOSv0)
44
45 //____________________________________________________________________________
46 AliPHOSv0::AliPHOSv0()
47 {
48   fNTmpHits = 0 ; 
49   fTmpHits  = 0 ; 
50 }
51
52 //____________________________________________________________________________
53 AliPHOSv0::AliPHOSv0(const char *name, const char *title):
54   AliPHOS(name,title)
55 {
56   
57   // We use 2 arrays of hits :
58   //
59   //   - fHits (the "normal" one), which retains the hits associated with
60   //     the current primary particle being tracked
61   //     (this array is reset after each primary has been tracked).
62   //
63   //   - fTmpHits, which retains all the hits of the current event. It 
64   //     is used for the digitization part.
65
66   fHits   = new TClonesArray("AliPHOSHit",100) ;
67   fDigits = new TClonesArray("AliPHOSDigit",100) ;
68   fTmpHits= new TClonesArray("AliPHOSHit",100) ;
69
70   fNTmpHits = fNhits = 0 ;
71
72   fIshunt     =  1 ; // All hits are associated with primary particles
73  
74   // gets an instance of the geometry parameters class  
75   fGeom =  AliPHOSGeometry::GetInstance(title, "") ; 
76
77   if (fGeom->IsInitialized() ) 
78     cout << "AliPHOSv0 : PHOS geometry intialized for " << fGeom->GetName() << endl ;
79   else
80    cout << "AliPHOSv0 : PHOS geometry initialization failed !" << endl ;   
81 }
82 //____________________________________________________________________________
83 AliPHOSv0::AliPHOSv0(AliPHOSReconstructioner & Reconstructioner, const char *name, const char *title):
84   AliPHOS(name,title)
85 {
86   
87   // We use 2 arrays of hits :
88   //
89   //   - fHits (the "normal" one), which retains the hits associated with
90   //     the current primary particle being tracked
91   //     (this array is reset after each primary has been tracked).
92   //
93   //   - fTmpHits, which retains all the hits of the current event. It 
94   //     is used for the digitization part.
95
96   fHits   = new TClonesArray("AliPHOSHit",100) ;
97   fDigits = new TClonesArray("AliPHOSDigit",100) ;
98   fTmpHits= new TClonesArray("AliPHOSHit",100) ;
99
100   fNTmpHits = fNhits = 0 ;
101
102   fIshunt     =  1 ; // All hits are associated with primary particles
103  
104   // gets an instance of the geometry parameters class  
105   fGeom =  AliPHOSGeometry::GetInstance(title, "") ; 
106
107   if (fGeom->IsInitialized() ) 
108     cout << "AliPHOSv0 : PHOS geometry intialized for " << fGeom->GetName() << endl ;
109   else
110    cout << "AliPHOSv0 : PHOS geometry initialization failed !" << endl ;   
111
112   // Defining the PHOS Reconstructioner
113  
114  fReconstructioner = &Reconstructioner ;
115 }
116
117 //____________________________________________________________________________
118 AliPHOSv0::~AliPHOSv0()
119 {
120   fTmpHits->Delete() ; 
121   delete fTmpHits ;
122   fTmpHits = 0 ; 
123
124   fEmcClusters->Delete() ; 
125   delete fEmcClusters ; 
126   fEmcClusters = 0 ; 
127
128   fPpsdClusters->Delete() ;
129   delete fPpsdClusters ;
130   fPpsdClusters = 0 ; 
131
132   fTrackSegments->Delete() ; 
133   delete fTrackSegments ;
134   fTrackSegments = 0 ; 
135 }
136
137 //____________________________________________________________________________
138 void AliPHOSv0::AddHit(Int_t track, Int_t Id, Float_t * hits)
139 {
140   Int_t hitCounter ;
141   TClonesArray &ltmphits = *fTmpHits;
142   AliPHOSHit *newHit ;
143   AliPHOSHit *curHit;
144   bool already = false ;
145
146   // In any case, fills the fTmpHit TClonesArray (with "accumulated hits")
147
148   newHit = new AliPHOSHit(fIshunt, track, Id, hits) ;
149
150   for ( hitCounter = 0 ; hitCounter < fNTmpHits && !already ; hitCounter++ ) {
151     curHit = (AliPHOSHit*) ltmphits[hitCounter] ;
152     if( *curHit == *newHit ) {
153       *curHit = *curHit + *newHit ;
154       already = true ;
155     }
156   }
157        
158   if ( !already ) {
159     new(ltmphits[fNTmpHits]) AliPHOSHit(*newHit) ;
160     fNTmpHits++ ;
161   }
162
163   // Please note that the fTmpHits array must survive up to the
164   // end of the events, so it does not appear e.g. in ResetHits() (
165   // which is called at the end of each primary).  
166
167   //  if (IsTreeSelected('H')) {
168     // And, if we really want raw hits tree, have the fHits array filled also
169   //    TClonesArray &lhits = *fHits;
170   //    new(lhits[fNhits]) AliPHOSHit(*newHit) ;
171   //    fNhits++ ;
172   //  }
173
174    delete newHit;
175
176 }
177
178
179 //____________________________________________________________________________
180 void AliPHOSv0::BuildGeometry()
181 {
182
183   this->BuildGeometryforPHOS() ; 
184   if ( ( strcmp(fGeom->GetName(), "GPS2" ) == 0 ) ) 
185     this->BuildGeometryforPPSD() ;
186   else
187     cout << "AliPHOSv0::BuildGeometry : no charged particle identification system installed" << endl; 
188
189 }
190
191 //____________________________________________________________________________
192 void AliPHOSv0:: BuildGeometryforPHOS(void)
193 {
194  // Build the PHOS geometry for the ROOT display
195
196   const Int_t kColorPHOS = kRed ;
197   const Int_t kColorXTAL = kBlue ;
198
199   Double_t const RADDEG = 180.0 / kPI ;
200  
201   new TBRIK( "OuterBox", "PHOS box", "void", fGeom->GetOuterBoxSize(0)/2, 
202                                              fGeom->GetOuterBoxSize(1)/2, 
203                                              fGeom->GetOuterBoxSize(2)/2 );
204
205   // Textolit Wall box, position inside PHOS 
206   
207   new TBRIK( "TextolitBox", "PHOS Textolit box ", "void", fGeom->GetTextolitBoxSize(0)/2, 
208                                                           fGeom->GetTextolitBoxSize(1)/2, 
209                                                           fGeom->GetTextolitBoxSize(2)/2);
210
211   // Polystyrene Foam Plate
212
213   new TBRIK( "UpperFoamPlate", "PHOS Upper foam plate", "void", fGeom->GetTextolitBoxSize(0)/2, 
214                                                                 fGeom->GetSecondUpperPlateThickness()/2, 
215                                                                 fGeom->GetTextolitBoxSize(2)/2 ) ; 
216
217   // Air Filled Box
218  
219   new TBRIK( "AirFilledBox", "PHOS air filled box", "void", fGeom->GetAirFilledBoxSize(0)/2, 
220                                                             fGeom->GetAirFilledBoxSize(1)/2, 
221                                                             fGeom->GetAirFilledBoxSize(2)/2 );
222
223   // Crystals Box
224
225   Float_t XTL_X = fGeom->GetCrystalSize(0) ; 
226   Float_t XTL_Y = fGeom->GetCrystalSize(1) ; 
227   Float_t XTL_Z = fGeom->GetCrystalSize(2) ; 
228
229   Float_t XL =  fGeom->GetNPhi() * ( XTL_X + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 + fGeom->GetModuleBoxThickness() ;
230   Float_t YL =  ( XTL_Y + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 
231              + fGeom->GetModuleBoxThickness() / 2.0 ;
232   Float_t ZL =  fGeom->GetNZ() * ( XTL_Z + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 +  fGeom->GetModuleBoxThickness() ;
233   
234   new TBRIK( "CrystalsBox", "PHOS crystals box", "void", XL, YL, ZL ) ;
235
236 // position PHOS into ALICE
237
238   Float_t R = fGeom->GetIPtoOuterCoverDistance() + fGeom->GetOuterBoxSize(1) / 2.0 ;
239   Int_t number = 988 ; 
240   Float_t pphi =  TMath::ATan( fGeom->GetOuterBoxSize(0)  / ( 2.0 * fGeom->GetIPtoOuterCoverDistance() ) ) ;
241   pphi *= RADDEG ;
242   TNode * Top = gAlice->GetGeometry()->GetNode("alice") ;
243  
244   char * nodename = new char[20] ;  
245   char * rotname  = new char[20] ; 
246
247   for( Int_t i = 1; i <= fGeom->GetNModules(); i++ ) { 
248    Float_t angle = pphi * 2 * ( i - fGeom->GetNModules() / 2.0 - 0.5 ) ;
249    sprintf(rotname, "%s%d", "rot", number++) ;
250    new TRotMatrix(rotname, rotname, 90, angle, 90, 90 + angle, 0, 0);
251    Top->cd();
252    sprintf(nodename,"%s%d", "Module", i) ;    
253    Float_t X =  R * TMath::Sin( angle / RADDEG ) ;
254    Float_t Y = -R * TMath::Cos( angle / RADDEG ) ;
255    TNode * OuterBoxNode = new TNode(nodename, nodename, "OuterBox", X, Y, 0, rotname ) ;
256    OuterBoxNode->SetLineColor(kColorPHOS) ;
257    fNodes->Add(OuterBoxNode) ;
258    OuterBoxNode->cd() ; 
259    // now inside the outer box the textolit box
260    Y = ( fGeom->GetOuterBoxThickness(1) -  fGeom->GetUpperPlateThickness() ) / 2.  ;
261    sprintf(nodename,"%s%d", "TexBox", i) ;  
262    TNode * TextolitBoxNode = new TNode(nodename, nodename, "TextolitBox", 0, Y, 0) ; 
263    TextolitBoxNode->SetLineColor(kColorPHOS) ;
264    fNodes->Add(TextolitBoxNode) ;
265    // upper foam plate inside outre box
266    OuterBoxNode->cd() ; 
267    sprintf(nodename, "%s%d", "UFPlate", i) ;
268    Y =  ( fGeom->GetTextolitBoxSize(1) - fGeom->GetSecondUpperPlateThickness() ) / 2.0 ;
269    TNode * UpperFoamPlateNode = new TNode(nodename, nodename, "UpperFoamPlate", 0, Y, 0) ; 
270    UpperFoamPlateNode->SetLineColor(kColorPHOS) ;
271    fNodes->Add(UpperFoamPlateNode) ;  
272    // air filled box inside textolit box (not drawn)
273    TextolitBoxNode->cd();
274    Y = ( fGeom->GetTextolitBoxSize(1) - fGeom->GetAirFilledBoxSize(1) ) / 2.0 -  fGeom->GetSecondUpperPlateThickness() ;
275    sprintf(nodename, "%s%d", "AFBox", i) ;
276    TNode * AirFilledBoxNode = new TNode(nodename, nodename, "AirFilledBox", 0, Y, 0) ; 
277    fNodes->Add(AirFilledBoxNode) ; 
278    // crystals box inside air filled box
279    AirFilledBoxNode->cd() ; 
280    Y = fGeom->GetAirFilledBoxSize(1) / 2.0 - YL 
281        - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetModuleBoxThickness() 
282        -  fGeom->GetUpperPlateThickness() -  fGeom->GetSecondUpperPlateThickness() ) ; 
283    sprintf(nodename, "%s%d", "XTBox", i) ; 
284    TNode * CrystalsBoxNode = new TNode(nodename, nodename, "CrystalsBox", 0, Y, 0) ;    
285    CrystalsBoxNode->SetLineColor(kColorXTAL) ; 
286    fNodes->Add(CrystalsBoxNode) ; 
287   }
288 }
289
290 //____________________________________________________________________________
291 void AliPHOSv0:: BuildGeometryforPPSD(void)
292 {
293  //  Build the PPSD geometry for the ROOT display
294
295   Double_t const RADDEG = 180.0 / kPI ;
296
297   const Int_t kColorPHOS = kRed ;
298   const Int_t kColorPPSD = kGreen ;
299   const Int_t kColorGas  = kBlue ;  
300   const Int_t kColorAir  = kYellow ; 
301
302   // Box for a full PHOS module
303
304   new TBRIK( "PPSDBox", "PPSD box", "void",  fGeom->GetPPSDBoxSize(0)/2, 
305                                              fGeom->GetPPSDBoxSize(1)/2, 
306                                              fGeom->GetPPSDBoxSize(2)/2 );
307
308   // Box containing one micromegas module 
309
310   new TBRIK( "PPSDModule", "PPSD module", "void",  fGeom->GetPPSDModuleSize(0)/2, 
311                                                    fGeom->GetPPSDModuleSize(1)/2, 
312                                                    fGeom->GetPPSDModuleSize(2)/2 );
313  // top lid
314
315   new TBRIK ( "TopLid", "Micromegas top lid", "void",  fGeom->GetPPSDModuleSize(0)/2,
316                                                        fGeom->GetLidThickness()/2,
317                                                        fGeom->GetPPSDModuleSize(2)/2 ) ; 
318  // composite panel (top and bottom)
319
320   new TBRIK ( "TopPanel", "Composite top panel", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
321                                                             fGeom->GetCompositeThickness()/2,
322                                                           ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ;  
323   
324   new TBRIK ( "BottomPanel", "Composite bottom panel", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
325                                                                   fGeom->GetCompositeThickness()/2,
326                                                                 ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
327  // gas gap (conversion and avalanche)
328
329   new TBRIK ( "GasGap", "gas gap", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
330                                             ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() )/2,
331                                             ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
332
333  // anode and cathode 
334
335   new TBRIK ( "Anode", "Anode", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
336                                            fGeom->GetAnodeThickness()/2,
337                                          ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
338
339   new TBRIK ( "Cathode", "Cathode", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
340                                                fGeom->GetCathodeThickness()/2,
341                                              ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
342  // PC  
343
344   new TBRIK ( "PCBoard", "Printed Circuit", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
345                                                        fGeom->GetPCThickness()/2,
346                                                      ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
347  // Gap between Lead and top micromegas
348
349   new TBRIK ( "LeadToM", "Air Gap top", "void", fGeom->GetPPSDBoxSize(0)/2,
350                                                 fGeom->GetMicro1ToLeadGap()/2,
351                                                 fGeom->GetPPSDBoxSize(2)/2  ) ;  
352  
353 // Gap between Lead and bottom micromegas
354
355   new TBRIK ( "MToLead", "Air Gap bottom", "void", fGeom->GetPPSDBoxSize(0)/2,
356                                                    fGeom->GetLeadToMicro2Gap()/2,
357                                                    fGeom->GetPPSDBoxSize(2)/2  ) ; 
358  // Lead converter
359    
360   new TBRIK ( "Lead", "Lead converter", "void", fGeom->GetPPSDBoxSize(0)/2,
361                                                 fGeom->GetLeadConverterThickness()/2,
362                                                 fGeom->GetPPSDBoxSize(2)/2  ) ; 
363
364      // position PPSD into ALICE
365
366   char * nodename = new char[20] ;  
367   char * rotname  = new char[20] ; 
368
369   Float_t R = fGeom->GetIPtoTopLidDistance() + fGeom->GetPPSDBoxSize(1) / 2.0 ;
370   Int_t number = 988 ; 
371   TNode * Top = gAlice->GetGeometry()->GetNode("alice") ;
372  
373   for( Int_t i = 1; i <= fGeom->GetNModules(); i++ ) { // the number of PHOS modules
374     Float_t angle = fGeom->GetPHOSAngle(i) ;
375     sprintf(rotname, "%s%d", "rotg", number++) ;
376     new TRotMatrix(rotname, rotname, 90, angle, 90, 90 + angle, 0, 0);
377     Top->cd();
378     sprintf(nodename, "%s%d", "Moduleg", i) ;    
379     Float_t X =  R * TMath::Sin( angle / RADDEG ) ;
380     Float_t Y = -R * TMath::Cos( angle / RADDEG ) ;
381     TNode * PPSDBoxNode = new TNode(nodename , nodename ,"PPSDBox", X, Y, 0, rotname ) ;
382     PPSDBoxNode->SetLineColor(kColorPPSD) ;
383     fNodes->Add(PPSDBoxNode) ;
384     PPSDBoxNode->cd() ;
385     // inside the PPSD box: 
386     //   1.   fNumberOfModulesPhi x fNumberOfModulesZ top micromegas
387     X = ( fGeom->GetPPSDBoxSize(0) - fGeom->GetPPSDModuleSize(0) ) / 2. ;  
388     for ( Int_t iphi = 1; iphi <= fGeom->GetNumberOfModulesPhi(); iphi++ ) { // the number of micromegas modules in phi per PHOS module
389       Float_t Z = ( fGeom->GetPPSDBoxSize(2) - fGeom->GetPPSDModuleSize(2) ) / 2. ;
390       TNode * Micro1Node ; 
391       for ( Int_t iz = 1; iz <= fGeom->GetNumberOfModulesZ(); iz++ ) { // the number of micromegas modules in z per PHOS module
392         Y = ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas1Thickness() ) / 2. ; 
393         sprintf(nodename, "%s%d%d%d", "Mic1", i, iphi, iz) ;
394         Micro1Node  = new TNode(nodename, nodename, "PPSDModule", X, Y, Z) ;
395         Micro1Node->SetLineColor(kColorPPSD) ;  
396         fNodes->Add(Micro1Node) ; 
397         // inside top micromegas
398         Micro1Node->cd() ; 
399         //      a. top lid
400         Y = ( fGeom->GetMicromegas1Thickness() - fGeom->GetLidThickness() ) / 2. ; 
401         sprintf(nodename, "%s%d%d%d", "Lid", i, iphi, iz) ;
402         TNode * TopLidNode = new TNode(nodename, nodename, "TopLid", 0, Y, 0) ;
403         TopLidNode->SetLineColor(kColorPPSD) ;  
404         fNodes->Add(TopLidNode) ; 
405         //      b. composite panel
406         Y = Y - fGeom->GetLidThickness() / 2. - fGeom->GetCompositeThickness() / 2. ; 
407         sprintf(nodename, "%s%d%d%d", "CompU", i, iphi, iz) ;
408         TNode * CompUpNode = new TNode(nodename, nodename, "TopPanel", 0, Y, 0) ;
409         CompUpNode->SetLineColor(kColorPPSD) ;  
410         fNodes->Add(CompUpNode) ; 
411         //      c. anode
412         Y = Y - fGeom->GetCompositeThickness() / 2. - fGeom->GetAnodeThickness()  / 2. ; 
413         sprintf(nodename, "%s%d%d%d", "Ano", i, iphi, iz) ;
414         TNode * AnodeNode = new TNode(nodename, nodename, "Anode", 0, Y, 0) ;
415         AnodeNode->SetLineColor(kColorPHOS) ;  
416         fNodes->Add(AnodeNode) ; 
417         //      d.  gas 
418         Y = Y - fGeom->GetAnodeThickness() / 2. - ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() ) / 2. ; 
419         sprintf(nodename, "%s%d%d%d", "GGap", i, iphi, iz) ;
420         TNode * GGapNode = new TNode(nodename, nodename, "GasGap", 0, Y, 0) ;
421         GGapNode->SetLineColor(kColorGas) ;  
422         fNodes->Add(GGapNode) ;          
423           //      f. cathode
424         Y = Y - ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() ) / 2. - fGeom->GetCathodeThickness()  / 2. ; 
425         sprintf(nodename, "%s%d%d%d", "Cathode", i, iphi, iz) ;
426         TNode * CathodeNode = new TNode(nodename, nodename, "Cathode", 0, Y, 0) ;
427         CathodeNode->SetLineColor(kColorPHOS) ;  
428         fNodes->Add(CathodeNode) ;        
429         //      g. printed circuit
430         Y = Y - fGeom->GetCathodeThickness() / 2. - fGeom->GetPCThickness()  / 2. ; 
431         sprintf(nodename, "%s%d%d%d", "PC", i, iphi, iz) ;
432         TNode * PCNode = new TNode(nodename, nodename, "PCBoard", 0, Y, 0) ;
433         PCNode->SetLineColor(kColorPPSD) ;  
434         fNodes->Add(PCNode) ;        
435         //      h. composite panel
436         Y = Y - fGeom->GetPCThickness() / 2. - fGeom->GetCompositeThickness()  / 2. ; 
437         sprintf(nodename, "%s%d%d%d", "CompDown", i, iphi, iz) ;
438         TNode * CompDownNode = new TNode(nodename, nodename, "BottomPanel", 0, Y, 0) ;
439         CompDownNode->SetLineColor(kColorPPSD) ;  
440         fNodes->Add(CompDownNode) ;   
441         Z = Z - fGeom->GetPPSDModuleSize(2) ;
442         PPSDBoxNode->cd() ;
443       } // end of Z module loop     
444       X = X -  fGeom->GetPPSDModuleSize(0) ; 
445       PPSDBoxNode->cd() ;
446     } // end of phi module loop
447     //   2. air gap      
448     PPSDBoxNode->cd() ;
449     Y = ( fGeom->GetPPSDBoxSize(1) - 2 * fGeom->GetMicromegas1Thickness() - fGeom->GetMicro1ToLeadGap() ) / 2. ; 
450     sprintf(nodename, "%s%d", "GapUp", i) ;
451     TNode * GapUpNode = new TNode(nodename, nodename, "LeadToM", 0, Y, 0) ;
452     GapUpNode->SetLineColor(kColorAir) ;  
453     fNodes->Add(GapUpNode) ;        
454     //   3. lead converter
455     Y = Y - fGeom->GetMicro1ToLeadGap() / 2. - fGeom->GetLeadConverterThickness() / 2. ; 
456     sprintf(nodename, "%s%d", "LeadC", i) ;
457     TNode * LeadCNode = new TNode(nodename, nodename, "Lead", 0, Y, 0) ;
458     LeadCNode->SetLineColor(kColorPPSD) ;  
459     fNodes->Add(LeadCNode) ;        
460     //   4. air gap
461     Y = Y - fGeom->GetLeadConverterThickness() / 2. - fGeom->GetLeadToMicro2Gap()  / 2. ; 
462     sprintf(nodename, "%s%d", "GapDown", i) ;
463     TNode * GapDownNode = new TNode(nodename, nodename, "MToLead", 0, Y, 0) ;
464     GapDownNode->SetLineColor(kColorAir) ;  
465     fNodes->Add(GapDownNode) ;        
466     //    5.  fNumberOfModulesPhi x fNumberOfModulesZ bottom micromegas
467     X = ( fGeom->GetPPSDBoxSize(0) - fGeom->GetPPSDModuleSize(0) ) / 2. - fGeom->GetPhiDisplacement() ;  
468     for ( Int_t iphi = 1; iphi <= fGeom->GetNumberOfModulesPhi(); iphi++ ) { 
469       Float_t Z = ( fGeom->GetPPSDBoxSize(2) - fGeom->GetPPSDModuleSize(2) ) / 2.  - fGeom->GetZDisplacement() ;;
470       TNode * Micro2Node ; 
471       for ( Int_t iz = 1; iz <= fGeom->GetNumberOfModulesZ(); iz++ ) { 
472         Y = - ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas2Thickness() ) / 2. ; 
473         sprintf(nodename, "%s%d%d%d", "Mic2", i, iphi, iz) ;
474         Micro2Node  = new TNode(nodename, nodename, "PPSDModule", X, Y, Z) ;
475         Micro2Node->SetLineColor(kColorPPSD) ;  
476         fNodes->Add(Micro2Node) ; 
477         // inside bottom micromegas
478         Micro2Node->cd() ; 
479           //      a. top lid
480           Y = ( fGeom->GetMicromegas2Thickness() - fGeom->GetLidThickness() ) / 2. ; 
481           sprintf(nodename, "%s%d", "Lidb", i) ;
482           TNode * TopLidbNode = new TNode(nodename, nodename, "TopLid", 0, Y, 0) ;
483           TopLidbNode->SetLineColor(kColorPPSD) ;  
484           fNodes->Add(TopLidbNode) ; 
485           //      b. composite panel
486           Y = Y - fGeom->GetLidThickness() / 2. - fGeom->GetCompositeThickness() / 2. ; 
487           sprintf(nodename, "%s%d", "CompUb", i) ;
488           TNode * CompUpbNode = new TNode(nodename, nodename, "TopPanel", 0, Y, 0) ;
489           CompUpbNode->SetLineColor(kColorPPSD) ;  
490           fNodes->Add(CompUpbNode) ; 
491           //      c. anode
492           Y = Y - fGeom->GetCompositeThickness() / 2. - fGeom->GetAnodeThickness()  / 2. ; 
493           sprintf(nodename, "%s%d", "Anob", i) ;
494           TNode * AnodebNode = new TNode(nodename, nodename, "Anode", 0, Y, 0) ;
495           AnodebNode->SetLineColor(kColorPPSD) ;  
496           fNodes->Add(AnodebNode) ; 
497           //      d. conversion gas
498           Y = Y - fGeom->GetAnodeThickness() / 2. - ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() )  / 2. ; 
499           sprintf(nodename, "%s%d", "GGapb", i) ;
500           TNode * GGapbNode = new TNode(nodename, nodename, "GasGap", 0, Y, 0) ;
501           GGapbNode->SetLineColor(kColorGas) ;  
502           fNodes->Add(GGapbNode) ;           
503           //      f. cathode
504           Y = Y - ( fGeom->GetConversionGap() + fGeom->GetAvalancheGap() ) / 2. - fGeom->GetCathodeThickness()  / 2. ; 
505           sprintf(nodename, "%s%d", "Cathodeb", i) ;
506           TNode * CathodebNode = new TNode(nodename, nodename, "Cathode", 0, Y, 0) ;
507           CathodebNode->SetLineColor(kColorPPSD) ;  
508           fNodes->Add(CathodebNode) ;        
509           //      g. printed circuit
510           Y = Y - fGeom->GetCathodeThickness() / 2. - fGeom->GetPCThickness()  / 2. ; 
511           sprintf(nodename, "%s%d", "PCb", i) ;
512           TNode * PCbNode = new TNode(nodename, nodename, "PCBoard", 0, Y, 0) ;
513           PCbNode->SetLineColor(kColorPPSD) ;  
514           fNodes->Add(PCbNode) ;        
515           //      h. composite pane
516           Y = Y - fGeom->GetPCThickness() / 2. - fGeom->GetCompositeThickness()  / 2. ; 
517           sprintf(nodename, "%s%d", "CompDownb", i) ;
518           TNode * CompDownbNode = new TNode(nodename, nodename, "BottomPanel", 0, Y, 0) ;
519           CompDownbNode->SetLineColor(kColorPPSD) ;  
520           fNodes->Add(CompDownbNode) ;        
521           Z = Z - fGeom->GetPPSDModuleSize(2) ;
522           PPSDBoxNode->cd() ;
523         } // end of Z module loop     
524         X = X -  fGeom->GetPPSDModuleSize(0) ; 
525         PPSDBoxNode->cd() ;
526        } // end of phi module loop
527      } // PHOS modules
528  delete rotname ; 
529  delete nodename ; 
530 }
531
532 //____________________________________________________________________________
533 void AliPHOSv0::CreateGeometry()
534 {
535
536   AliPHOSv0 *PHOS_tmp = (AliPHOSv0*)gAlice->GetModule("PHOS") ;
537
538   if ( PHOS_tmp == NULL ) {
539     
540     fprintf(stderr, "PHOS detector not found!\n") ;
541     return;
542     
543   }
544
545   // Get pointer to the array containing media indeces
546   Int_t *IDTMED = fIdtmed->GetArray() - 699 ;
547
548   Float_t BigBox[3] ; 
549   BigBox[0] =   fGeom->GetOuterBoxSize(0) / 2.0 ;
550   BigBox[1] = ( fGeom->GetOuterBoxSize(1) + fGeom->GetPPSDBoxSize(1) ) / 2.0 ;
551   BigBox[2] =   fGeom->GetOuterBoxSize(2) / 2.0 ;
552   
553   gMC->Gsvolu("PHOS", "BOX ", IDTMED[798], BigBox, 3) ;
554   
555   this->CreateGeometryforPHOS() ; 
556   if ( strcmp( fGeom->GetName(), "GPS2") == 0  ) 
557     this->CreateGeometryforPPSD() ;
558   else
559     cout << "AliPHOSv0::CreateGeometry : no charged particle identification system installed" << endl; 
560   
561   // --- Position  PHOS mdules in ALICE setup ---
562   
563   Int_t IDROTM[99] ;
564   Double_t const RADDEG = 180.0 / kPI ;
565   
566   for( Int_t i = 1; i <= fGeom->GetNModules(); i++ ) {
567     
568     Float_t angle = fGeom->GetPHOSAngle(i) ;
569     AliMatrix(IDROTM[i-1], 90.0, angle, 90.0, 90.0+angle, 0.0, 0.0) ;
570  
571     Float_t R = fGeom->GetIPtoOuterCoverDistance() + ( fGeom->GetOuterBoxSize(1) + fGeom->GetPPSDBoxSize(1) ) / 2.0 ;
572
573     Float_t XP1 = R * TMath::Sin( angle / RADDEG ) ;
574     Float_t YP1 = -R * TMath::Cos( angle / RADDEG ) ;
575
576     gMC->Gspos("PHOS", i, "ALIC", XP1, YP1, 0.0, IDROTM[i-1], "ONLY") ;
577  
578   } // for GetNModules
579
580 }
581
582 //____________________________________________________________________________
583 void AliPHOSv0::CreateGeometryforPHOS()
584 {
585   // Get pointer to the array containing media indeces
586   Int_t *IDTMED = fIdtmed->GetArray() - 699 ;
587
588   // ---
589   // --- Define PHOS box volume, fPUFPill with thermo insulating foam ---
590   // --- Foam Thermo Insulating outer cover dimensions ---
591   // --- Put it in BigBox = PHOS
592
593   Float_t DPHOS[3] ; 
594   DPHOS[0] =  fGeom->GetOuterBoxSize(0) / 2.0 ;
595   DPHOS[1] =  fGeom->GetOuterBoxSize(1) / 2.0 ;
596   DPHOS[2] =  fGeom->GetOuterBoxSize(2) / 2.0 ;
597
598   gMC->Gsvolu("EMCA", "BOX ", IDTMED[706], DPHOS, 3) ;
599
600   Float_t YO =  - fGeom->GetPPSDBoxSize(1)  / 2.0 ;
601
602   gMC->Gspos("EMCA", 1, "PHOS", 0.0, YO, 0.0, 0, "ONLY") ; 
603
604   // ---
605   // --- Define Textolit Wall box, position inside EMCA ---
606   // --- Textolit Wall box dimentions ---
607  
608  
609   Float_t DPTXW[3];
610   DPTXW[0] = fGeom->GetTextolitBoxSize(0) / 2.0 ;
611   DPTXW[1] = fGeom->GetTextolitBoxSize(1) / 2.0 ;
612   DPTXW[2] = fGeom->GetTextolitBoxSize(2) / 2.0 ;
613
614   gMC->Gsvolu("PTXW", "BOX ", IDTMED[707], DPTXW, 3);
615
616   YO =   (  fGeom->GetOuterBoxThickness(1) -   fGeom->GetUpperPlateThickness() ) / 2.  ;
617    
618   gMC->Gspos("PTXW", 1, "EMCA", 0.0, YO, 0.0, 0, "ONLY") ;
619
620   // --- 
621   // --- Define Upper Polystyrene Foam Plate, place inside PTXW ---
622   // --- immediately below Foam Thermo Insulation Upper plate ---
623
624   // --- Upper Polystyrene Foam plate thickness ---
625  
626   Float_t  DPUFP[3] ;
627   DPUFP[0] = fGeom->GetTextolitBoxSize(0) / 2.0 ; 
628   DPUFP[1] = fGeom->GetSecondUpperPlateThickness() / 2. ;
629   DPUFP[2] = fGeom->GetTextolitBoxSize(2) /2.0 ; 
630
631   gMC->Gsvolu("PUFP", "BOX ", IDTMED[703], DPUFP, 3) ;
632   
633   YO = ( fGeom->GetTextolitBoxSize(1) -  fGeom->GetSecondUpperPlateThickness() ) / 2.0 ;
634   
635   gMC->Gspos("PUFP", 1, "PTXW", 0.0, YO, 0.0, 0, "ONLY") ;
636   
637   // ---
638   // --- Define air-filled box, place inside PTXW ---
639   // --- Inner AIR volume dimensions ---
640  
641
642   Float_t  DPAIR[3] ;
643   DPAIR[0] = fGeom->GetAirFilledBoxSize(0) / 2.0 ;
644   DPAIR[1] = fGeom->GetAirFilledBoxSize(1) / 2.0 ;
645   DPAIR[2] = fGeom->GetAirFilledBoxSize(2) / 2.0 ;
646
647   gMC->Gsvolu("PAIR", "BOX ", IDTMED[798], DPAIR, 3) ;
648   
649   YO = ( fGeom->GetTextolitBoxSize(1) -  fGeom->GetAirFilledBoxSize(1) ) / 2.0 -   fGeom->GetSecondUpperPlateThickness() ;
650   
651   gMC->Gspos("PAIR", 1, "PTXW", 0.0, YO, 0.0, 0, "ONLY") ;
652
653 // --- Dimensions of PbWO4 crystal ---
654
655   Float_t XTL_X =  fGeom->GetCrystalSize(0) ; 
656   Float_t XTL_Y =  fGeom->GetCrystalSize(1) ; 
657   Float_t XTL_Z =  fGeom->GetCrystalSize(2) ; 
658
659   Float_t DPTCB[3] ;  
660   DPTCB[0] =  fGeom->GetNPhi() * ( XTL_X + 2 *  fGeom->GetGapBetweenCrystals() ) / 2.0 + fGeom->GetModuleBoxThickness() ;
661   DPTCB[1] = ( XTL_Y +  fGeom->GetCrystalSupportHeight() +  fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 
662              + fGeom->GetModuleBoxThickness() / 2.0 ;
663   DPTCB[2] = fGeom->GetNZ() * ( XTL_Z + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 +  fGeom->GetModuleBoxThickness() ;
664   
665   gMC->Gsvolu("PTCB", "BOX ", IDTMED[706], DPTCB, 3) ;
666
667   YO =  fGeom->GetAirFilledBoxSize(1) / 2.0 - DPTCB[1] 
668        - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetModuleBoxThickness() 
669        -  fGeom->GetUpperPlateThickness() -  fGeom->GetSecondUpperPlateThickness() ) ;
670   
671   gMC->Gspos("PTCB", 1, "PAIR", 0.0, YO, 0.0, 0, "ONLY") ;
672
673   // ---
674   // --- Define Crystal BLock filled with air, position it inside PTCB ---
675   Float_t DPCBL[3] ; 
676   
677   DPCBL[0] = fGeom->GetNPhi() * ( XTL_X + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 ;
678   DPCBL[1] = ( XTL_Y + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 ;
679   DPCBL[2] = fGeom->GetNZ() * ( XTL_Z + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 ;
680   
681   gMC->Gsvolu("PCBL", "BOX ", IDTMED[798], DPCBL, 3) ;
682   
683   // --- Divide PCBL in X (phi) and Z directions --
684   gMC->Gsdvn("PROW", "PCBL", Int_t (fGeom->GetNPhi()), 1) ;
685   gMC->Gsdvn("PCEL", "PROW", Int_t (fGeom->GetNZ()), 3) ;
686
687   YO = -fGeom->GetModuleBoxThickness() / 2.0 ;
688   
689   gMC->Gspos("PCBL", 1, "PTCB", 0.0, YO, 0.0, 0, "ONLY") ;
690
691   // ---
692   // --- Define STeel (actually, it's titanium) Cover volume, place inside PCEL
693   Float_t  DPSTC[3] ; 
694   
695   DPSTC[0] = ( XTL_X + 2 * fGeom->GetCrystalWrapThickness() ) / 2.0 ;
696   DPSTC[1] = ( XTL_Y + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 ;
697   DPSTC[2] = ( XTL_Z + 2 * fGeom->GetCrystalWrapThickness()  + 2 *  fGeom->GetCrystalHolderThickness() ) / 2.0 ;
698   
699   gMC->Gsvolu("PSTC", "BOX ", IDTMED[704], DPSTC, 3) ;
700
701   gMC->Gspos("PSTC", 1, "PCEL", 0.0, 0.0, 0.0, 0, "ONLY") ;
702
703   // ---
704   // --- Define Tyvek volume, place inside PSTC ---
705   Float_t  DPPAP[3] ;
706
707   DPPAP[0] = XTL_X / 2.0 + fGeom->GetCrystalWrapThickness() ;
708   DPPAP[1] = ( XTL_Y + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 ;
709   DPPAP[2] = XTL_Z / 2.0 + fGeom->GetCrystalWrapThickness() ;
710   
711   gMC->Gsvolu("PPAP", "BOX ", IDTMED[702], DPPAP, 3) ;
712   
713   YO = ( XTL_Y + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 
714               - ( XTL_Y +  fGeom->GetCrystalSupportHeight() +  fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 ;
715    
716   gMC->Gspos("PPAP", 1, "PSTC", 0.0, YO, 0.0, 0, "ONLY") ;
717
718   // ---
719   // --- Define PbWO4 crystal volume, place inside PPAP ---
720   Float_t  DPXTL[3] ; 
721
722   DPXTL[0] = XTL_X / 2.0 ;
723   DPXTL[1] = XTL_Y / 2.0 ;
724   DPXTL[2] = XTL_Z / 2.0 ;
725   
726   gMC->Gsvolu("PXTL", "BOX ", IDTMED[699], DPXTL, 3) ;
727
728   YO = ( XTL_Y + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 - XTL_Y / 2.0 - fGeom->GetCrystalWrapThickness() ;
729   
730   gMC->Gspos("PXTL", 1, "PPAP", 0.0, YO, 0.0, 0, "ONLY") ;
731
732   // ---
733   // --- Define crystal support volume, place inside PPAP ---
734   Float_t DPSUP[3] ; 
735
736   DPSUP[0] = XTL_X / 2.0 + fGeom->GetCrystalWrapThickness()  ;
737   DPSUP[1] = fGeom->GetCrystalSupportHeight() / 2.0 ;
738   DPSUP[2] = XTL_Z / 2.0 +  fGeom->GetCrystalWrapThickness() ;
739
740   gMC->Gsvolu("PSUP", "BOX ", IDTMED[798], DPSUP, 3) ;
741
742   YO =  fGeom->GetCrystalSupportHeight() / 2.0 - ( XTL_Y +  fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 ;
743
744   gMC->Gspos("PSUP", 1, "PPAP", 0.0, YO, 0.0, 0, "ONLY") ;
745
746   // ---
747   // --- Define PIN-diode volume and position it inside crystal support ---
748   // --- right behind PbWO4 crystal
749
750   // --- PIN-diode dimensions ---
751
752  
753   Float_t DPPIN[3] ;
754   DPPIN[0] = fGeom->GetPinDiodeSize(0) / 2.0 ;
755   DPPIN[1] = fGeom->GetPinDiodeSize(1) / 2.0 ;
756   DPPIN[2] = fGeom->GetPinDiodeSize(2) / 2.0 ;
757  
758   gMC->Gsvolu("PPIN", "BOX ", IDTMED[705], DPPIN, 3) ;
759  
760   YO = fGeom->GetCrystalSupportHeight() / 2.0 - fGeom->GetPinDiodeSize(1) / 2.0 ;
761  
762   gMC->Gspos("PPIN", 1, "PSUP", 0.0, YO, 0.0, 0, "ONLY") ;
763
764   // ---
765   // --- Define Upper Cooling Panel, place it on top of PTCB ---
766   Float_t DPUCP[3] ;
767  // --- Upper Cooling Plate thickness ---
768  
769   DPUCP[0] = DPTCB[0] ;
770   DPUCP[1] = fGeom->GetUpperCoolingPlateThickness() ;
771   DPUCP[2] = DPTCB[2] ;
772   
773   gMC->Gsvolu("PUCP", "BOX ", IDTMED[701], DPUCP,3) ;
774   
775   YO = (  fGeom->GetAirFilledBoxSize(1) -  fGeom->GetUpperCoolingPlateThickness() ) / 2. 
776        - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetModuleBoxThickness()
777            - fGeom->GetUpperPlateThickness() - fGeom->GetSecondUpperPlateThickness() - fGeom->GetUpperCoolingPlateThickness() ) ; 
778   
779   gMC->Gspos("PUCP", 1, "PAIR", 0.0, YO, 0.0, 0, "ONLY") ;
780
781   // ---
782   // --- Define Al Support Plate, position it inside PAIR ---
783   // --- right beneath PTCB ---
784  // --- Al Support Plate thickness ---
785  
786   Float_t DPASP[3] ;
787   DPASP[0] =  fGeom->GetAirFilledBoxSize(0) / 2.0 ;
788   DPASP[1] = fGeom->GetSupportPlateThickness() / 2.0 ;
789   DPASP[2] =  fGeom->GetAirFilledBoxSize(2) / 2.0 ;
790   
791   gMC->Gsvolu("PASP", "BOX ", IDTMED[701], DPASP, 3) ;
792   
793   YO = (  fGeom->GetAirFilledBoxSize(1) - fGeom->GetSupportPlateThickness() ) / 2. 
794        -  ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance()
795            - fGeom->GetUpperPlateThickness() - fGeom->GetSecondUpperPlateThickness() + DPCBL[1] * 2 ) ;
796   
797   gMC->Gspos("PASP", 1, "PAIR", 0.0, YO, 0.0, 0, "ONLY") ;
798
799   // ---
800   // --- Define Thermo Insulating Plate, position it inside PAIR ---
801   // --- right beneath PASP ---
802   // --- Lower Thermo Insulating Plate thickness ---
803   
804   Float_t DPTIP[3] ;
805   DPTIP[0] = fGeom->GetAirFilledBoxSize(0) / 2.0 ;
806   DPTIP[1] = fGeom->GetLowerThermoPlateThickness() / 2.0 ;
807   DPTIP[2] = fGeom->GetAirFilledBoxSize(2) / 2.0 ;
808
809   gMC->Gsvolu("PTIP", "BOX ", IDTMED[706], DPTIP, 3) ;
810
811   YO =  ( fGeom->GetAirFilledBoxSize(1) - fGeom->GetLowerThermoPlateThickness() ) / 2. 
812        -  ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetUpperPlateThickness() 
813             - fGeom->GetSecondUpperPlateThickness() + DPCBL[1] * 2 + fGeom->GetSupportPlateThickness() ) ;
814
815   gMC->Gspos("PTIP", 1, "PAIR", 0.0, YO, 0.0, 0, "ONLY") ;
816
817   // ---
818   // --- Define Textolit Plate, position it inside PAIR ---
819   // --- right beneath PTIP ---
820   // --- Lower Textolit Plate thickness ---
821  
822   Float_t DPTXP[3] ;
823   DPTXP[0] = fGeom->GetAirFilledBoxSize(0) / 2.0 ;
824   DPTXP[1] = fGeom->GetLowerTextolitPlateThickness() / 2.0 ;
825   DPTXP[2] = fGeom->GetAirFilledBoxSize(2) / 2.0 ;
826
827   gMC->Gsvolu("PTXP", "BOX ", IDTMED[707], DPTXP, 3) ;
828
829   YO =  ( fGeom->GetAirFilledBoxSize(1) - fGeom->GetLowerTextolitPlateThickness() ) / 2. 
830        -  ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetUpperPlateThickness() 
831             - fGeom->GetSecondUpperPlateThickness() + DPCBL[1] * 2 + fGeom->GetSupportPlateThickness() 
832             +  fGeom->GetLowerThermoPlateThickness() ) ;
833
834   gMC->Gspos("PTXP", 1, "PAIR", 0.0, YO, 0.0, 0, "ONLY") ;
835
836 }
837
838 //____________________________________________________________________________
839 void AliPHOSv0::CreateGeometryforPPSD()
840 {
841   // Get pointer to the array containing media indeces
842   Int_t *IDTMED = fIdtmed->GetArray() - 699 ;
843   
844   // The box containing all PPSD's for one PHOS module filled with air 
845   Float_t PPSD[3] ; 
846   PPSD[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ;  
847   PPSD[1] = fGeom->GetPPSDBoxSize(1) / 2.0 ; 
848   PPSD[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
849
850   gMC->Gsvolu("PPSD", "BOX ", IDTMED[798], PPSD, 3) ;
851
852   Float_t YO =  fGeom->GetOuterBoxSize(1) / 2.0 ;
853
854   gMC->Gspos("PPSD", 1, "PHOS", 0.0, YO, 0.0, 0, "ONLY") ; 
855
856   // Now we build a micromegas module
857   // The box containing the whole module filled with epoxy (FR4)
858
859   Float_t MPPSD[3] ;  
860   MPPSD[0] = fGeom->GetPPSDModuleSize(0) / 2.0 ;  
861   MPPSD[1] = fGeom->GetPPSDModuleSize(1) / 2.0 ;  
862   MPPSD[2] = fGeom->GetPPSDModuleSize(2) / 2.0 ;
863
864   gMC->Gsvolu("MPPS", "BOX ", IDTMED[708], MPPSD, 3) ;  
865  
866   // Inside MPPSD :
867   // 1. The Top Lid made of epoxy (FR4) 
868
869   Float_t TLPPSD[3] ; 
870   TLPPSD[0] = fGeom->GetPPSDModuleSize(0) / 2.0 ; 
871   TLPPSD[1] = fGeom->GetLidThickness() / 2.0 ;
872   TLPPSD[2] = fGeom->GetPPSDModuleSize(2) / 2.0 ;
873
874   gMC->Gsvolu("TLPS", "BOX ", IDTMED[708], TLPPSD, 3) ; 
875
876   Float_t  Y0 = ( fGeom->GetMicromegas1Thickness() - fGeom->GetLidThickness() ) / 2. ; 
877
878   gMC->Gspos("TLPS", 1, "MPPS", 0.0, Y0, 0.0, 0, "ONLY") ; 
879  
880   // 2. the upper panel made of composite material
881
882   Float_t UPPPSD[3] ; 
883   UPPPSD[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
884   UPPPSD[1] = fGeom->GetCompositeThickness() / 2.0 ;
885   UPPPSD[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
886  
887   gMC->Gsvolu("UPPS", "BOX ", IDTMED[709], UPPPSD, 3) ; 
888   
889   Y0 = Y0 - fGeom->GetLidThickness() / 2. - fGeom->GetCompositeThickness() / 2. ; 
890
891   gMC->Gspos("UPPS", 1, "MPPS", 0.0, Y0, 0.0, 0, "ONLY") ; 
892
893   // 3. the anode made of Copper
894   
895   Float_t ANPPSD[3] ; 
896   ANPPSD[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ; 
897   ANPPSD[1] = fGeom->GetAnodeThickness() / 2.0 ; 
898   ANPPSD[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0  ; 
899
900   gMC->Gsvolu("ANPS", "BOX ", IDTMED[710], ANPPSD, 3) ; 
901   
902   Y0 = Y0 - fGeom->GetCompositeThickness() / 2. - fGeom->GetAnodeThickness()  / 2. ; 
903   
904   gMC->Gspos("ANPS", 1, "MPPS", 0.0, Y0, 0.0, 0, "ONLY") ; 
905
906   // 4. the conversion gap + avalanche gap filled with gas
907
908   Float_t GGPPSD[3] ; 
909   GGPPSD[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
910   GGPPSD[1] = ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() ) / 2.0 ; 
911   GGPPSD[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
912
913   gMC->Gsvolu("GGPS", "BOX ", IDTMED[715], GGPPSD, 3) ; 
914   
915   // --- Divide GGPP in X (phi) and Z directions --
916   gMC->Gsdvn("GROW", "GGPS", fGeom->GetNumberOfPadsPhi(), 1) ;
917   gMC->Gsdvn("GCEL", "GROW", fGeom->GetNumberOfPadsZ() , 3) ;
918
919   Y0 = Y0 - fGeom->GetAnodeThickness() / 2.  - ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() ) / 2. ; 
920
921   gMC->Gspos("GGPS", 1, "MPPS", 0.0, Y0, 0.0, 0, "ONLY") ; 
922
923
924   // 6. the cathode made of Copper
925
926   Float_t CAPPSD[3] ;
927   CAPPSD[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
928   CAPPSD[1] = fGeom->GetCathodeThickness() / 2.0 ; 
929   CAPPSD[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0  ;
930
931   gMC->Gsvolu("CAPS", "BOX ", IDTMED[710], CAPPSD, 3) ; 
932
933   Y0 = Y0 - ( fGeom->GetAvalancheGap() +  fGeom->GetAvalancheGap() ) / 2. - fGeom->GetCathodeThickness()  / 2. ; 
934
935   gMC->Gspos("CAPS", 1, "MPPS", 0.0, Y0, 0.0, 0, "ONLY") ; 
936
937   // 7. the printed circuit made of G10       
938
939   Float_t PCPPSD[3] ; 
940   PCPPSD[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2,.0 ; 
941   PCPPSD[1] = fGeom->GetPCThickness() / 2.0 ; 
942   PCPPSD[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
943
944   gMC->Gsvolu("PCPS", "BOX ", IDTMED[711], CAPPSD, 3) ; 
945
946   Y0 = Y0 - fGeom->GetCathodeThickness() / 2. - fGeom->GetPCThickness()  / 2. ; 
947
948   gMC->Gspos("PCPS", 1, "MPPS", 0.0, Y0, 0.0, 0, "ONLY") ; 
949
950   // 8. the lower panel made of composite material
951                                                     
952   Float_t LPPPSD[3] ; 
953   LPPPSD[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ; 
954   LPPPSD[1] = fGeom->GetCompositeThickness() / 2.0 ; 
955   LPPPSD[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
956
957   gMC->Gsvolu("LPPS", "BOX ", IDTMED[709], LPPPSD, 3) ; 
958  
959   Y0 = Y0 - fGeom->GetPCThickness() / 2. - fGeom->GetCompositeThickness()  / 2. ; 
960
961   gMC->Gspos("LPPS", 1, "MPPS", 0.0, Y0, 0.0, 0, "ONLY") ; 
962
963   // Position the  fNumberOfModulesPhi x fNumberOfModulesZ modules (MPPSD) inside PPSD to cover a PHOS module
964   // the top and bottom one's (which are assumed identical) :
965
966    Float_t Yt = ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas1Thickness() ) / 2. ; 
967    Float_t Yb = - ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas2Thickness() ) / 2. ; 
968
969    Int_t CopyNumbertop = 0 ; 
970    Int_t CopyNumberbot = fGeom->GetNumberOfModulesPhi() *  fGeom->GetNumberOfModulesZ() ; 
971
972    Float_t X  = ( fGeom->GetPPSDBoxSize(0) - fGeom->GetPPSDModuleSize(0) ) / 2. ;  
973
974    for ( Int_t iphi = 1; iphi <= fGeom->GetNumberOfModulesPhi(); iphi++ ) { // the number of micromegas modules in phi per PHOS module
975       Float_t Z = ( fGeom->GetPPSDBoxSize(2) - fGeom->GetPPSDModuleSize(2) ) / 2. ;
976
977       for ( Int_t iz = 1; iz <= fGeom->GetNumberOfModulesZ(); iz++ ) { // the number of micromegas modules in z per PHOS module
978         gMC->Gspos("MPPS", ++CopyNumbertop, "PPSD", X, Yt, Z, 0, "ONLY") ;
979         gMC->Gspos("MPPS", ++CopyNumberbot, "PPSD", X, Yb, Z, 0, "ONLY") ; 
980         Z = Z - fGeom->GetPPSDModuleSize(2) ;
981       } // end of Z module loop   
982       X = X -  fGeom->GetPPSDModuleSize(0) ; 
983     } // end of phi module loop
984
985    // The Lead converter between two air gaps
986    // 1. Upper air gap
987
988    Float_t UAPPSD[3] ;
989    UAPPSD[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ;
990    UAPPSD[1] = fGeom->GetMicro1ToLeadGap() / 2.0 ; 
991    UAPPSD[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
992
993   gMC->Gsvolu("UAPPSD", "BOX ", IDTMED[798], UAPPSD, 3) ; 
994
995   Y0 = ( fGeom->GetPPSDBoxSize(1) - 2 * fGeom->GetMicromegas1Thickness() - fGeom->GetMicro1ToLeadGap() ) / 2. ; 
996
997   gMC->Gspos("UAPPSD", 1, "PPSD", 0.0, Y0, 0.0, 0, "ONLY") ; 
998
999    // 2. Lead converter
1000  
1001   Float_t LCPPSD[3] ; 
1002   LCPPSD[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ;
1003   LCPPSD[1] = fGeom->GetLeadConverterThickness() / 2.0 ; 
1004   LCPPSD[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
1005  
1006   gMC->Gsvolu("LCPPSD", "BOX ", IDTMED[712], LCPPSD, 3) ; 
1007   
1008   Y0 = Y0 - fGeom->GetMicro1ToLeadGap() / 2. - fGeom->GetLeadConverterThickness() / 2. ; 
1009
1010   gMC->Gspos("LCPPSD", 1, "PPSD", 0.0, Y0, 0.0, 0, "ONLY") ; 
1011
1012   // 3. Lower air gap
1013
1014   Float_t LAPPSD[3] ; 
1015   LAPPSD[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ; 
1016   LAPPSD[1] = fGeom->GetLeadToMicro2Gap() / 2.0 ; 
1017   LAPPSD[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
1018
1019   gMC->Gsvolu("LAPPSD", "BOX ", IDTMED[798], LAPPSD, 3) ; 
1020     
1021   Y0 = Y0 - fGeom->GetLeadConverterThickness() / 2. - fGeom->GetLeadToMicro2Gap()  / 2. ; 
1022   
1023   gMC->Gspos("LAPPSD", 1, "PPSD", 0.0, Y0, 0.0, 0, "ONLY") ; 
1024    
1025 }
1026
1027 //___________________________________________________________________________
1028 Int_t AliPHOSv0::Digitize(Float_t Energy){
1029   Float_t fB = 100000000. ;
1030   Float_t fA = 0. ;
1031   Int_t chan = Int_t(fA + Energy*fB ) ;
1032   return chan ;
1033 }
1034 //___________________________________________________________________________
1035 void AliPHOSv0::FinishEvent()
1036 {
1037   cout << "//_____________________________________________________" << endl ;
1038   cout << "<I> AliPHOSv0::FinishEvent() -- Starting digitalization" << endl ;
1039   Int_t i ;
1040   TClonesArray &lDigits = *fDigits ;
1041   AliPHOSHit  * Hit ;
1042   AliPHOSDigit * Digit ;
1043
1044   for ( i = 0 ; i < fNTmpHits ; i++ ) {
1045     Hit = (AliPHOSHit*)fTmpHits->At(i) ;
1046     Digit = new AliPHOSDigit(Hit->GetId(),Digitize(Hit->GetEnergy())) ;
1047     new(lDigits[fNdigits]) AliPHOSDigit(* Digit) ;
1048     fNdigits++;  delete Digit ;    
1049   }
1050
1051   // Reset the array of all the "accumulated hits" of this event.
1052   fNTmpHits = 0 ;
1053   fTmpHits->Delete();
1054 }
1055
1056 //____________________________________________________________________________
1057 void AliPHOSv0::Init(void)
1058 {
1059  
1060   Int_t i;
1061
1062   printf("\n");
1063   for(i=0;i<35;i++) printf("*");
1064   printf(" PHOS_INIT ");
1065   for(i=0;i<35;i++) printf("*");
1066   printf("\n");
1067
1068   // Here the PHOS initialisation code (if any!)
1069
1070   for(i=0;i<80;i++) printf("*");
1071   printf("\n");
1072   
1073 }
1074
1075 //___________________________________________________________________________
1076 void AliPHOSv0::MakeBranch(Option_t* opt)
1077 {  
1078   //
1079   // Create a new branch in the current Root Tree
1080   // The branch of fHits is automatically split
1081   //
1082   AliDetector::MakeBranch(opt) ;
1083   
1084   char branchname[10];
1085   sprintf(branchname,"%s",GetName());
1086   char *D = strstr(opt,"D");
1087   
1088   if (fDigits && gAlice->TreeD() && D) {
1089     gAlice->TreeD()->Branch(branchname,&fDigits, fBufferSize);
1090     printf("* AliPHOS::MakeBranch * Making Branch %s for digits\n",branchname);
1091   }
1092 }
1093
1094 //_____________________________________________________________________________
1095 void AliPHOSv0::Reconstruction(AliPHOSReconstructioner & Reconstructioner)
1096
1097   // reinitializes the existing RecPoint Lists and steers the reconstruction processes
1098
1099   fReconstructioner = &Reconstructioner ;
1100   cout << "Hola1" << endl;
1101   if (fEmcClusters) { 
1102     fEmcClusters->Delete() ; 
1103     delete fEmcClusters ;
1104     fEmcClusters = 0 ; 
1105
1106   }
1107   fEmcClusters= new RecPointsList("AliPHOSEmcRecPoint", 100) ;
1108  
1109   cout << "Hola2" << endl;
1110   if (fPpsdClusters) { 
1111     fPpsdClusters->Delete() ; 
1112     delete fPpsdClusters ; 
1113     fPpsdClusters = 0 ; 
1114   }
1115   fPpsdClusters = new RecPointsList("AliPHOSPpsdRecPoint", 100) ;
1116
1117
1118   cout << "Hola3" << endl;
1119   if (fTrackSegments) { 
1120    fTrackSegments->Print(""); 
1121    fTrackSegments->Delete() ; 
1122     delete fTrackSegments ; 
1123     fTrackSegments = 0 ; 
1124   }
1125   fTrackSegments = new TObjArray(100) ;
1126
1127   cout << "Hola4" << endl;
1128   fReconstructioner->Make(fDigits, fEmcClusters, fPpsdClusters, fTrackSegments);
1129   cout << "Hola5" << endl;
1130 }
1131
1132 //____________________________________________________________________________
1133 void AliPHOSv0::StepManager(void)
1134 {
1135   Int_t          RelId[4] ;      // (box, layer, row, column) indices
1136   Float_t        xyze[4] ;       // position wrt MRS and energy deposited
1137   TLorentzVector pos ;
1138   Int_t copy;
1139
1140   TString name = fGeom->GetName() ; 
1141
1142   if ( name == "GPS2" ) { // the CPV is a PPSD
1143     if( gMC->CurrentVolID(copy) == gMC->VolId("GCEL") )
1144     //     if( strcmp ( gMC->CurrentVolName(), "GCEL" ) == 0 )  // We are inside a gas cell 
1145     {
1146       gMC->TrackPosition(pos) ;
1147       xyze[0] = pos[0] ;
1148       xyze[1] = pos[1] ;
1149       xyze[2] = pos[2] ;
1150       xyze[3] = gMC->Edep() ; 
1151
1152       if ( xyze[3] != 0 ) { // there is deposited energy 
1153         gMC->CurrentVolOffID(5, RelId[0]) ;  // get the PHOS Module number
1154         gMC->CurrentVolOffID(3, RelId[1]) ;  // get the Micromegas Module number 
1155       // 1-> Geom->GetNumberOfModulesPhi() *  fGeom->GetNumberOfModulesZ() upper                         
1156       //  >  fGeom->GetNumberOfModulesPhi()  *  fGeom->GetNumberOfModulesZ() lower
1157         gMC->CurrentVolOffID(1, RelId[2]) ;  // get the row number of the cell
1158         gMC->CurrentVolID(RelId[3]) ;        // get the column number 
1159
1160         // get the absolute Id number
1161
1162         Int_t AbsId ; 
1163         fGeom->RelToAbsNumbering(RelId,AbsId) ; 
1164
1165         // add current hit to the hit list      
1166         AddHit(gAlice->CurrentTrack(), AbsId, xyze);
1167
1168       } // there is deposited energy 
1169      } // We are inside the gas of the CPV  
1170    } // GPS2 configuration
1171   
1172    if(gMC->CurrentVolID(copy) == gMC->VolId("PXTL") ) 
1173   //      if( strcmp ( gMC->CurrentVolName(), "PXTL" ) == 0 ) { //  We are inside a PWO crystal
1174      {
1175        gMC->TrackPosition(pos) ;
1176        xyze[0] = pos[0] ;
1177        xyze[1] = pos[1] ;
1178        xyze[2] = pos[2] ;
1179        xyze[3] = gMC->Edep() ;
1180
1181        if ( xyze[3] != 0 ) {
1182           gMC->CurrentVolOffID(10, RelId[0]) ; // get the PHOS module number ;
1183           RelId[1] = 0   ;                    // means PW04
1184           gMC->CurrentVolOffID(4, RelId[2]) ; // get the row number inside the module
1185           gMC->CurrentVolOffID(3, RelId[3]) ; // get the cell number inside the module
1186
1187       // get the absolute Id number
1188
1189           Int_t AbsId ; 
1190           fGeom->RelToAbsNumbering(RelId,AbsId) ; 
1191  
1192       // add current hit to the hit list
1193
1194           AddHit(gAlice->CurrentTrack(), AbsId, xyze);
1195     
1196        } // there is deposited energy
1197     } // we are inside a PHOS Xtal
1198 }
1199