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