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