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