1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 //_________________________________________________________________________
19 // Implementation version v0 of PHOS Manager class
20 // Layout EMC + PPSD has name GPS2
22 //*-- Author: Yves Schutz (SUBATECH)
25 // --- ROOT system ---
31 // --- Standard library ---
39 // --- AliRoot header files ---
41 #include "AliPHOSv0.h"
42 #include "AliPHOSHit.h"
43 #include "AliPHOSDigit.h"
44 #include "AliPHOSReconstructioner.h"
50 //____________________________________________________________________________
51 AliPHOSv0::AliPHOSv0()
58 //____________________________________________________________________________
59 AliPHOSv0::AliPHOSv0(const char *name, const char *title):
62 // ctor : title is used to identify the layout
63 // GPS2 = 5 modules (EMC + PPSD)
64 // We use 2 arrays of hits :
66 // - fHits (the "normal" one), which retains the hits associated with
67 // the current primary particle being tracked
68 // (this array is reset after each primary has been tracked).
70 // - fTmpHits, which retains all the hits of the current event. It
71 // is used for the digitization part.
73 fPinElectronicNoise = 0.010 ;
74 fDigitThreshold = 1. ; // 1 GeV
76 fHits = new TClonesArray("AliPHOSHit",100) ;
77 gAlice->AddHitList(fHits) ;
79 fTmpHits= new TClonesArray("AliPHOSHit",100) ;
81 fNTmpHits = fNhits = 0 ;
83 fDigits = new TClonesArray("AliPHOSDigit",100) ;
86 fIshunt = 1 ; // All hits are associated with primary particles
88 // gets an instance of the geometry parameters class
90 fGeom = AliPHOSGeometry::GetInstance(title, "") ;
92 if (fGeom->IsInitialized() )
93 cout << "AliPHOSv0 : PHOS geometry intialized for " << fGeom->GetName() << endl ;
95 cout << "AliPHOSv0 : PHOS geometry initialization failed !" << endl ;
97 //____________________________________________________________________________
98 AliPHOSv0::AliPHOSv0(AliPHOSReconstructioner * Reconstructioner, const char *name, const char *title):
101 // ctor : title is used to identify the layout
102 // GPS2 = 5 modules (EMC + PPSD)
103 // We use 2 arrays of hits :
105 // - fHits (the "normal" one), which retains the hits associated with
106 // the current primary particle being tracked
107 // (this array is reset after each primary has been tracked).
109 // - fTmpHits, which retains all the hits of the current event. It
110 // is used for the digitization part.
112 fPinElectronicNoise = 0.010 ;
113 fHits = new TClonesArray("AliPHOSHit",100) ;
114 fDigits = new TClonesArray("AliPHOSDigit",100) ;
115 fTmpHits= new TClonesArray("AliPHOSHit",100) ;
117 fNTmpHits = fNhits = 0 ;
119 fIshunt = 1 ; // All hits are associated with primary particles
121 // gets an instance of the geometry parameters class
122 fGeom = AliPHOSGeometry::GetInstance(title, "") ;
124 if (fGeom->IsInitialized() )
125 cout << "AliPHOSv0 : PHOS geometry intialized for " << fGeom->GetName() << endl ;
127 cout << "AliPHOSv0 : PHOS geometry initialization failed !" << endl ;
129 // Defining the PHOS Reconstructioner
131 fReconstructioner = Reconstructioner ;
134 //____________________________________________________________________________
135 AliPHOSv0::~AliPHOSv0()
143 fEmcClusters->Delete() ;
144 delete fEmcClusters ;
147 fPpsdClusters->Delete() ;
148 delete fPpsdClusters ;
151 fTrackSegments->Delete() ;
152 delete fTrackSegments ;
156 //____________________________________________________________________________
157 void AliPHOSv0::AddHit(Int_t primary, Int_t Id, Float_t * hits)
159 // Add a hit to the hit list.
160 // A PHOS hit is the sum of all hits in a single crystal
161 // or in a single PPSD gas cell
164 TClonesArray <mphits = *fTmpHits ;
167 Bool_t deja = kFALSE ;
169 // In any case, fills the fTmpHit TClonesArray (with "accumulated hits")
171 newHit = new AliPHOSHit(primary, Id, hits) ;
173 for ( hitCounter = 0 ; hitCounter < fNTmpHits && !deja ; hitCounter++ ) {
174 curHit = (AliPHOSHit*) ltmphits[hitCounter] ;
175 if( *curHit == *newHit ) {
176 *curHit = *curHit + *newHit ;
182 new(ltmphits[fNTmpHits]) AliPHOSHit(*newHit) ;
186 // Please note that the fTmpHits array must survive up to the
187 // end of the events, so it does not appear e.g. in ResetHits() (
188 // which is called at the end of each primary).
190 // if (IsTreeSelected('H')) {
191 // And, if we really want raw hits tree, have the fHits array filled also
192 // TClonesArray &lhits = *fHits;
193 // new(lhits[fNhits]) AliPHOSHit(*newHit) ;
202 //____________________________________________________________________________
203 void AliPHOSv0::BuildGeometry()
205 // Build the PHOS geometry for the ROOT display
209 PHOS in ALICE displayed by root
215 <IMG Align=BOTTOM ALT="All Views" SRC="../images/AliPHOSv0AllViews.gif">
220 <IMG Align=BOTTOM ALT="Front View" SRC="../images/AliPHOSv0FrontView.gif">
225 <IMG Align=BOTTOM ALT="3D View 1" SRC="../images/AliPHOSv03DView1.gif">
230 <IMG Align=BOTTOM ALT="3D View 2" SRC="../images/AliPHOSv03DView2.gif">
236 this->BuildGeometryforPHOS() ;
237 if ( ( strcmp(fGeom->GetName(), "GPS2" ) == 0 ) )
238 this->BuildGeometryforPPSD() ;
240 cout << "AliPHOSv0::BuildGeometry : no charged particle identification system installed" << endl;
244 //____________________________________________________________________________
245 void AliPHOSv0:: BuildGeometryforPHOS(void)
247 // Build the PHOS-EMC geometry for the ROOT display
249 const Int_t kColorPHOS = kRed ;
250 const Int_t kColorXTAL = kBlue ;
252 Double_t const kRADDEG = 180.0 / kPI ;
254 new TBRIK( "OuterBox", "PHOS box", "void", fGeom->GetOuterBoxSize(0)/2,
255 fGeom->GetOuterBoxSize(1)/2,
256 fGeom->GetOuterBoxSize(2)/2 );
258 // Textolit Wall box, position inside PHOS
260 new TBRIK( "TextolitBox", "PHOS Textolit box ", "void", fGeom->GetTextolitBoxSize(0)/2,
261 fGeom->GetTextolitBoxSize(1)/2,
262 fGeom->GetTextolitBoxSize(2)/2);
264 // Polystyrene Foam Plate
266 new TBRIK( "UpperFoamPlate", "PHOS Upper foam plate", "void", fGeom->GetTextolitBoxSize(0)/2,
267 fGeom->GetSecondUpperPlateThickness()/2,
268 fGeom->GetTextolitBoxSize(2)/2 ) ;
272 new TBRIK( "AirFilledBox", "PHOS air filled box", "void", fGeom->GetAirFilledBoxSize(0)/2,
273 fGeom->GetAirFilledBoxSize(1)/2,
274 fGeom->GetAirFilledBoxSize(2)/2 );
278 Float_t xtlX = fGeom->GetCrystalSize(0) ;
279 Float_t xtlY = fGeom->GetCrystalSize(1) ;
280 Float_t xtlZ = fGeom->GetCrystalSize(2) ;
282 Float_t xl = fGeom->GetNPhi() * ( xtlX + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 + fGeom->GetModuleBoxThickness() ;
283 Float_t yl = ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0
284 + fGeom->GetModuleBoxThickness() / 2.0 ;
285 Float_t zl = fGeom->GetNZ() * ( xtlZ + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 + fGeom->GetModuleBoxThickness() ;
287 new TBRIK( "CrystalsBox", "PHOS crystals box", "void", xl, yl, zl ) ;
289 // position PHOS into ALICE
291 Float_t r = fGeom->GetIPtoOuterCoverDistance() + fGeom->GetOuterBoxSize(1) / 2.0 ;
293 Float_t pphi = TMath::ATan( fGeom->GetOuterBoxSize(0) / ( 2.0 * fGeom->GetIPtoOuterCoverDistance() ) ) ;
295 TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
297 char * nodename = new char[20] ;
298 char * rotname = new char[20] ;
300 for( Int_t i = 1; i <= fGeom->GetNModules(); i++ ) {
301 Float_t angle = pphi * 2 * ( i - fGeom->GetNModules() / 2.0 - 0.5 ) ;
302 sprintf(rotname, "%s%d", "rot", number++) ;
303 new TRotMatrix(rotname, rotname, 90, angle, 90, 90 + angle, 0, 0);
305 sprintf(nodename,"%s%d", "Module", i) ;
306 Float_t x = r * TMath::Sin( angle / kRADDEG ) ;
307 Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
308 TNode * outerboxnode = new TNode(nodename, nodename, "OuterBox", x, y, 0, rotname ) ;
309 outerboxnode->SetLineColor(kColorPHOS) ;
310 fNodes->Add(outerboxnode) ;
312 // now inside the outer box the textolit box
313 y = ( fGeom->GetOuterBoxThickness(1) - fGeom->GetUpperPlateThickness() ) / 2. ;
314 sprintf(nodename,"%s%d", "TexBox", i) ;
315 TNode * textolitboxnode = new TNode(nodename, nodename, "TextolitBox", 0, y, 0) ;
316 textolitboxnode->SetLineColor(kColorPHOS) ;
317 fNodes->Add(textolitboxnode) ;
318 // upper foam plate inside outre box
320 sprintf(nodename, "%s%d", "UFPlate", i) ;
321 y = ( fGeom->GetTextolitBoxSize(1) - fGeom->GetSecondUpperPlateThickness() ) / 2.0 ;
322 TNode * upperfoamplatenode = new TNode(nodename, nodename, "UpperFoamPlate", 0, y, 0) ;
323 upperfoamplatenode->SetLineColor(kColorPHOS) ;
324 fNodes->Add(upperfoamplatenode) ;
325 // air filled box inside textolit box (not drawn)
326 textolitboxnode->cd();
327 y = ( fGeom->GetTextolitBoxSize(1) - fGeom->GetAirFilledBoxSize(1) ) / 2.0 - fGeom->GetSecondUpperPlateThickness() ;
328 sprintf(nodename, "%s%d", "AFBox", i) ;
329 TNode * airfilledboxnode = new TNode(nodename, nodename, "AirFilledBox", 0, y, 0) ;
330 fNodes->Add(airfilledboxnode) ;
331 // crystals box inside air filled box
332 airfilledboxnode->cd() ;
333 y = fGeom->GetAirFilledBoxSize(1) / 2.0 - yl
334 - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetModuleBoxThickness()
335 - fGeom->GetUpperPlateThickness() - fGeom->GetSecondUpperPlateThickness() ) ;
336 sprintf(nodename, "%s%d", "XTBox", i) ;
337 TNode * crystalsboxnode = new TNode(nodename, nodename, "CrystalsBox", 0, y, 0) ;
338 crystalsboxnode->SetLineColor(kColorXTAL) ;
339 fNodes->Add(crystalsboxnode) ;
343 //____________________________________________________________________________
344 void AliPHOSv0:: BuildGeometryforPPSD(void)
346 // Build the PHOS-PPSD geometry for the ROOT display
350 PPSD displayed by root
353 <LI> Zoom on PPSD: Front View
356 <IMG Align=BOTTOM ALT="PPSD Front View" SRC="../images/AliPHOSv0PPSDFrontView.gif">
358 <LI> Zoom on PPSD: Perspective View
361 <IMG Align=BOTTOM ALT="PPSD Prespective View" SRC="../images/AliPHOSv0PPSDPerspectiveView.gif">
366 Double_t const kRADDEG = 180.0 / kPI ;
368 const Int_t kColorPHOS = kRed ;
369 const Int_t kColorPPSD = kGreen ;
370 const Int_t kColorGas = kBlue ;
371 const Int_t kColorAir = kYellow ;
373 // Box for a full PHOS module
375 new TBRIK( "PPSDBox", "PPSD box", "void", fGeom->GetPPSDBoxSize(0)/2,
376 fGeom->GetPPSDBoxSize(1)/2,
377 fGeom->GetPPSDBoxSize(2)/2 );
379 // Box containing one micromegas module
381 new TBRIK( "PPSDModule", "PPSD module", "void", fGeom->GetPPSDModuleSize(0)/2,
382 fGeom->GetPPSDModuleSize(1)/2,
383 fGeom->GetPPSDModuleSize(2)/2 );
386 new TBRIK ( "TopLid", "Micromegas top lid", "void", fGeom->GetPPSDModuleSize(0)/2,
387 fGeom->GetLidThickness()/2,
388 fGeom->GetPPSDModuleSize(2)/2 ) ;
389 // composite panel (top and bottom)
391 new TBRIK ( "TopPanel", "Composite top panel", "void", ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
392 fGeom->GetCompositeThickness()/2,
393 ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ;
395 new TBRIK ( "BottomPanel", "Composite bottom panel", "void", ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
396 fGeom->GetCompositeThickness()/2,
397 ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ;
398 // gas gap (conversion and avalanche)
400 new TBRIK ( "GasGap", "gas gap", "void", ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
401 ( fGeom->GetConversionGap() + fGeom->GetAvalancheGap() )/2,
402 ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ;
406 new TBRIK ( "Anode", "Anode", "void", ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
407 fGeom->GetAnodeThickness()/2,
408 ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ;
410 new TBRIK ( "Cathode", "Cathode", "void", ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
411 fGeom->GetCathodeThickness()/2,
412 ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ;
415 new TBRIK ( "PCBoard", "Printed Circuit", "void", ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
416 fGeom->GetPCThickness()/2,
417 ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ;
418 // Gap between Lead and top micromegas
420 new TBRIK ( "LeadToM", "Air Gap top", "void", fGeom->GetPPSDBoxSize(0)/2,
421 fGeom->GetMicro1ToLeadGap()/2,
422 fGeom->GetPPSDBoxSize(2)/2 ) ;
424 // Gap between Lead and bottom micromegas
426 new TBRIK ( "MToLead", "Air Gap bottom", "void", fGeom->GetPPSDBoxSize(0)/2,
427 fGeom->GetLeadToMicro2Gap()/2,
428 fGeom->GetPPSDBoxSize(2)/2 ) ;
431 new TBRIK ( "Lead", "Lead converter", "void", fGeom->GetPPSDBoxSize(0)/2,
432 fGeom->GetLeadConverterThickness()/2,
433 fGeom->GetPPSDBoxSize(2)/2 ) ;
435 // position PPSD into ALICE
437 char * nodename = new char[20] ;
438 char * rotname = new char[20] ;
440 Float_t r = fGeom->GetIPtoTopLidDistance() + fGeom->GetPPSDBoxSize(1) / 2.0 ;
442 TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
444 for( Int_t i = 1; i <= fGeom->GetNModules(); i++ ) { // the number of PHOS modules
445 Float_t angle = fGeom->GetPHOSAngle(i) ;
446 sprintf(rotname, "%s%d", "rotg", number++) ;
447 new TRotMatrix(rotname, rotname, 90, angle, 90, 90 + angle, 0, 0);
449 sprintf(nodename, "%s%d", "Moduleg", i) ;
450 Float_t x = r * TMath::Sin( angle / kRADDEG ) ;
451 Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
452 TNode * ppsdboxnode = new TNode(nodename , nodename ,"PPSDBox", x, y, 0, rotname ) ;
453 ppsdboxnode->SetLineColor(kColorPPSD) ;
454 fNodes->Add(ppsdboxnode) ;
456 // inside the PPSD box:
457 // 1. fNumberOfModulesPhi x fNumberOfModulesZ top micromegas
458 x = ( fGeom->GetPPSDBoxSize(0) - fGeom->GetPPSDModuleSize(0) ) / 2. ;
459 for ( Int_t iphi = 1; iphi <= fGeom->GetNumberOfModulesPhi(); iphi++ ) { // the number of micromegas modules in phi per PHOS module
460 Float_t z = ( fGeom->GetPPSDBoxSize(2) - fGeom->GetPPSDModuleSize(2) ) / 2. ;
462 for ( Int_t iz = 1; iz <= fGeom->GetNumberOfModulesZ(); iz++ ) { // the number of micromegas modules in z per PHOS module
463 y = ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas1Thickness() ) / 2. ;
464 sprintf(nodename, "%s%d%d%d", "Mic1", i, iphi, iz) ;
465 micro1node = new TNode(nodename, nodename, "PPSDModule", x, y, z) ;
466 micro1node->SetLineColor(kColorPPSD) ;
467 fNodes->Add(micro1node) ;
468 // inside top micromegas
471 y = ( fGeom->GetMicromegas1Thickness() - fGeom->GetLidThickness() ) / 2. ;
472 sprintf(nodename, "%s%d%d%d", "Lid", i, iphi, iz) ;
473 TNode * toplidnode = new TNode(nodename, nodename, "TopLid", 0, y, 0) ;
474 toplidnode->SetLineColor(kColorPPSD) ;
475 fNodes->Add(toplidnode) ;
476 // b. composite panel
477 y = y - fGeom->GetLidThickness() / 2. - fGeom->GetCompositeThickness() / 2. ;
478 sprintf(nodename, "%s%d%d%d", "CompU", i, iphi, iz) ;
479 TNode * compupnode = new TNode(nodename, nodename, "TopPanel", 0, y, 0) ;
480 compupnode->SetLineColor(kColorPPSD) ;
481 fNodes->Add(compupnode) ;
483 y = y - fGeom->GetCompositeThickness() / 2. - fGeom->GetAnodeThickness() / 2. ;
484 sprintf(nodename, "%s%d%d%d", "Ano", i, iphi, iz) ;
485 TNode * anodenode = new TNode(nodename, nodename, "Anode", 0, y, 0) ;
486 anodenode->SetLineColor(kColorPHOS) ;
487 fNodes->Add(anodenode) ;
489 y = y - fGeom->GetAnodeThickness() / 2. - ( fGeom->GetConversionGap() + fGeom->GetAvalancheGap() ) / 2. ;
490 sprintf(nodename, "%s%d%d%d", "GGap", i, iphi, iz) ;
491 TNode * ggapnode = new TNode(nodename, nodename, "GasGap", 0, y, 0) ;
492 ggapnode->SetLineColor(kColorGas) ;
493 fNodes->Add(ggapnode) ;
495 y = y - ( fGeom->GetConversionGap() + fGeom->GetAvalancheGap() ) / 2. - fGeom->GetCathodeThickness() / 2. ;
496 sprintf(nodename, "%s%d%d%d", "Cathode", i, iphi, iz) ;
497 TNode * cathodenode = new TNode(nodename, nodename, "Cathode", 0, y, 0) ;
498 cathodenode->SetLineColor(kColorPHOS) ;
499 fNodes->Add(cathodenode) ;
500 // g. printed circuit
501 y = y - fGeom->GetCathodeThickness() / 2. - fGeom->GetPCThickness() / 2. ;
502 sprintf(nodename, "%s%d%d%d", "PC", i, iphi, iz) ;
503 TNode * pcnode = new TNode(nodename, nodename, "PCBoard", 0, y, 0) ;
504 pcnode->SetLineColor(kColorPPSD) ;
505 fNodes->Add(pcnode) ;
506 // h. composite panel
507 y = y - fGeom->GetPCThickness() / 2. - fGeom->GetCompositeThickness() / 2. ;
508 sprintf(nodename, "%s%d%d%d", "CompDown", i, iphi, iz) ;
509 TNode * compdownnode = new TNode(nodename, nodename, "BottomPanel", 0, y, 0) ;
510 compdownnode->SetLineColor(kColorPPSD) ;
511 fNodes->Add(compdownnode) ;
512 z = z - fGeom->GetPPSDModuleSize(2) ;
514 } // end of Z module loop
515 x = x - fGeom->GetPPSDModuleSize(0) ;
517 } // end of phi module loop
520 y = ( fGeom->GetPPSDBoxSize(1) - 2 * fGeom->GetMicromegas1Thickness() - fGeom->GetMicro1ToLeadGap() ) / 2. ;
521 sprintf(nodename, "%s%d", "GapUp", i) ;
522 TNode * gapupnode = new TNode(nodename, nodename, "LeadToM", 0, y, 0) ;
523 gapupnode->SetLineColor(kColorAir) ;
524 fNodes->Add(gapupnode) ;
526 y = y - fGeom->GetMicro1ToLeadGap() / 2. - fGeom->GetLeadConverterThickness() / 2. ;
527 sprintf(nodename, "%s%d", "LeadC", i) ;
528 TNode * leadcnode = new TNode(nodename, nodename, "Lead", 0, y, 0) ;
529 leadcnode->SetLineColor(kColorPPSD) ;
530 fNodes->Add(leadcnode) ;
532 y = y - fGeom->GetLeadConverterThickness() / 2. - fGeom->GetLeadToMicro2Gap() / 2. ;
533 sprintf(nodename, "%s%d", "GapDown", i) ;
534 TNode * gapdownnode = new TNode(nodename, nodename, "MToLead", 0, y, 0) ;
535 gapdownnode->SetLineColor(kColorAir) ;
536 fNodes->Add(gapdownnode) ;
537 // 5. fNumberOfModulesPhi x fNumberOfModulesZ bottom micromegas
538 x = ( fGeom->GetPPSDBoxSize(0) - fGeom->GetPPSDModuleSize(0) ) / 2. - fGeom->GetPhiDisplacement() ;
539 for ( Int_t iphi = 1; iphi <= fGeom->GetNumberOfModulesPhi(); iphi++ ) {
540 Float_t z = ( fGeom->GetPPSDBoxSize(2) - fGeom->GetPPSDModuleSize(2) ) / 2. - fGeom->GetZDisplacement() ;;
542 for ( Int_t iz = 1; iz <= fGeom->GetNumberOfModulesZ(); iz++ ) {
543 y = - ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas2Thickness() ) / 2. ;
544 sprintf(nodename, "%s%d%d%d", "Mic2", i, iphi, iz) ;
545 micro2node = new TNode(nodename, nodename, "PPSDModule", x, y, z) ;
546 micro2node->SetLineColor(kColorPPSD) ;
547 fNodes->Add(micro2node) ;
548 // inside bottom micromegas
551 y = ( fGeom->GetMicromegas2Thickness() - fGeom->GetLidThickness() ) / 2. ;
552 sprintf(nodename, "%s%d", "Lidb", i) ;
553 TNode * toplidbnode = new TNode(nodename, nodename, "TopLid", 0, y, 0) ;
554 toplidbnode->SetLineColor(kColorPPSD) ;
555 fNodes->Add(toplidbnode) ;
556 // b. composite panel
557 y = y - fGeom->GetLidThickness() / 2. - fGeom->GetCompositeThickness() / 2. ;
558 sprintf(nodename, "%s%d", "CompUb", i) ;
559 TNode * compupbnode = new TNode(nodename, nodename, "TopPanel", 0, y, 0) ;
560 compupbnode->SetLineColor(kColorPPSD) ;
561 fNodes->Add(compupbnode) ;
563 y = y - fGeom->GetCompositeThickness() / 2. - fGeom->GetAnodeThickness() / 2. ;
564 sprintf(nodename, "%s%d", "Anob", i) ;
565 TNode * anodebnode = new TNode(nodename, nodename, "Anode", 0, y, 0) ;
566 anodebnode->SetLineColor(kColorPPSD) ;
567 fNodes->Add(anodebnode) ;
569 y = y - fGeom->GetAnodeThickness() / 2. - ( fGeom->GetConversionGap() + fGeom->GetAvalancheGap() ) / 2. ;
570 sprintf(nodename, "%s%d", "GGapb", i) ;
571 TNode * ggapbnode = new TNode(nodename, nodename, "GasGap", 0, y, 0) ;
572 ggapbnode->SetLineColor(kColorGas) ;
573 fNodes->Add(ggapbnode) ;
575 y = y - ( fGeom->GetConversionGap() + fGeom->GetAvalancheGap() ) / 2. - fGeom->GetCathodeThickness() / 2. ;
576 sprintf(nodename, "%s%d", "Cathodeb", i) ;
577 TNode * cathodebnode = new TNode(nodename, nodename, "Cathode", 0, y, 0) ;
578 cathodebnode->SetLineColor(kColorPPSD) ;
579 fNodes->Add(cathodebnode) ;
580 // g. printed circuit
581 y = y - fGeom->GetCathodeThickness() / 2. - fGeom->GetPCThickness() / 2. ;
582 sprintf(nodename, "%s%d", "PCb", i) ;
583 TNode * pcbnode = new TNode(nodename, nodename, "PCBoard", 0, y, 0) ;
584 pcbnode->SetLineColor(kColorPPSD) ;
585 fNodes->Add(pcbnode) ;
587 y = y - fGeom->GetPCThickness() / 2. - fGeom->GetCompositeThickness() / 2. ;
588 sprintf(nodename, "%s%d", "CompDownb", i) ;
589 TNode * compdownbnode = new TNode(nodename, nodename, "BottomPanel", 0, y, 0) ;
590 compdownbnode->SetLineColor(kColorPPSD) ;
591 fNodes->Add(compdownbnode) ;
592 z = z - fGeom->GetPPSDModuleSize(2) ;
594 } // end of Z module loop
595 x = x - fGeom->GetPPSDModuleSize(0) ;
597 } // end of phi module loop
603 //____________________________________________________________________________
604 void AliPHOSv0::CreateGeometry()
606 // Create the PHOS geometry for Geant
608 AliPHOSv0 *phostmp = (AliPHOSv0*)gAlice->GetModule("PHOS") ;
610 if ( phostmp == NULL ) {
612 fprintf(stderr, "PHOS detector not found!\n") ;
616 // Get pointer to the array containing media indeces
617 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
620 bigbox[0] = fGeom->GetOuterBoxSize(0) / 2.0 ;
621 bigbox[1] = ( fGeom->GetOuterBoxSize(1) + fGeom->GetPPSDBoxSize(1) ) / 2.0 ;
622 bigbox[2] = fGeom->GetOuterBoxSize(2) / 2.0 ;
624 gMC->Gsvolu("PHOS", "BOX ", idtmed[798], bigbox, 3) ;
626 this->CreateGeometryforPHOS() ;
627 if ( strcmp( fGeom->GetName(), "GPS2") == 0 )
628 this->CreateGeometryforPPSD() ;
630 cout << "AliPHOSv0::CreateGeometry : no charged particle identification system installed" << endl;
632 // --- Position PHOS mdules in ALICE setup ---
635 Double_t const kRADDEG = 180.0 / kPI ;
637 for( Int_t i = 1; i <= fGeom->GetNModules(); i++ ) {
639 Float_t angle = fGeom->GetPHOSAngle(i) ;
640 AliMatrix(idrotm[i-1], 90.0, angle, 90.0, 90.0+angle, 0.0, 0.0) ;
642 Float_t r = fGeom->GetIPtoOuterCoverDistance() + ( fGeom->GetOuterBoxSize(1) + fGeom->GetPPSDBoxSize(1) ) / 2.0 ;
644 Float_t xP1 = r * TMath::Sin( angle / kRADDEG ) ;
645 Float_t yP1 = -r * TMath::Cos( angle / kRADDEG ) ;
647 gMC->Gspos("PHOS", i, "ALIC", xP1, yP1, 0.0, idrotm[i-1], "ONLY") ;
653 //____________________________________________________________________________
654 void AliPHOSv0::CreateGeometryforPHOS()
656 // Create the PHOS-EMC geometry for GEANT
660 Geant3 geometry tree of PHOS-EMC in ALICE
663 <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/EMCinAlice.gif">
668 // Get pointer to the array containing media indexes
669 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
672 // --- Define PHOS box volume, fPUFPill with thermo insulating foam ---
673 // --- Foam Thermo Insulating outer cover dimensions ---
674 // --- Put it in bigbox = PHOS
677 dphos[0] = fGeom->GetOuterBoxSize(0) / 2.0 ;
678 dphos[1] = fGeom->GetOuterBoxSize(1) / 2.0 ;
679 dphos[2] = fGeom->GetOuterBoxSize(2) / 2.0 ;
681 gMC->Gsvolu("EMCA", "BOX ", idtmed[706], dphos, 3) ;
683 Float_t yO = - fGeom->GetPPSDBoxSize(1) / 2.0 ;
685 gMC->Gspos("EMCA", 1, "PHOS", 0.0, yO, 0.0, 0, "ONLY") ;
688 // --- Define Textolit Wall box, position inside EMCA ---
689 // --- Textolit Wall box dimentions ---
693 dptxw[0] = fGeom->GetTextolitBoxSize(0) / 2.0 ;
694 dptxw[1] = fGeom->GetTextolitBoxSize(1) / 2.0 ;
695 dptxw[2] = fGeom->GetTextolitBoxSize(2) / 2.0 ;
697 gMC->Gsvolu("PTXW", "BOX ", idtmed[707], dptxw, 3);
699 yO = ( fGeom->GetOuterBoxThickness(1) - fGeom->GetUpperPlateThickness() ) / 2. ;
701 gMC->Gspos("PTXW", 1, "EMCA", 0.0, yO, 0.0, 0, "ONLY") ;
704 // --- Define Upper Polystyrene Foam Plate, place inside PTXW ---
705 // --- immediately below Foam Thermo Insulation Upper plate ---
707 // --- Upper Polystyrene Foam plate thickness ---
710 dpufp[0] = fGeom->GetTextolitBoxSize(0) / 2.0 ;
711 dpufp[1] = fGeom->GetSecondUpperPlateThickness() / 2. ;
712 dpufp[2] = fGeom->GetTextolitBoxSize(2) /2.0 ;
714 gMC->Gsvolu("PUFP", "BOX ", idtmed[703], dpufp, 3) ;
716 yO = ( fGeom->GetTextolitBoxSize(1) - fGeom->GetSecondUpperPlateThickness() ) / 2.0 ;
718 gMC->Gspos("PUFP", 1, "PTXW", 0.0, yO, 0.0, 0, "ONLY") ;
721 // --- Define air-filled box, place inside PTXW ---
722 // --- Inner AIR volume dimensions ---
726 dpair[0] = fGeom->GetAirFilledBoxSize(0) / 2.0 ;
727 dpair[1] = fGeom->GetAirFilledBoxSize(1) / 2.0 ;
728 dpair[2] = fGeom->GetAirFilledBoxSize(2) / 2.0 ;
730 gMC->Gsvolu("PAIR", "BOX ", idtmed[798], dpair, 3) ;
732 yO = ( fGeom->GetTextolitBoxSize(1) - fGeom->GetAirFilledBoxSize(1) ) / 2.0 - fGeom->GetSecondUpperPlateThickness() ;
734 gMC->Gspos("PAIR", 1, "PTXW", 0.0, yO, 0.0, 0, "ONLY") ;
736 // --- Dimensions of PbWO4 crystal ---
738 Float_t xtlX = fGeom->GetCrystalSize(0) ;
739 Float_t xtlY = fGeom->GetCrystalSize(1) ;
740 Float_t xtlZ = fGeom->GetCrystalSize(2) ;
743 dptcb[0] = fGeom->GetNPhi() * ( xtlX + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 + fGeom->GetModuleBoxThickness() ;
744 dptcb[1] = ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0
745 + fGeom->GetModuleBoxThickness() / 2.0 ;
746 dptcb[2] = fGeom->GetNZ() * ( xtlZ + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 + fGeom->GetModuleBoxThickness() ;
748 gMC->Gsvolu("PTCB", "BOX ", idtmed[706], dptcb, 3) ;
750 yO = fGeom->GetAirFilledBoxSize(1) / 2.0 - dptcb[1]
751 - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetModuleBoxThickness()
752 - fGeom->GetUpperPlateThickness() - fGeom->GetSecondUpperPlateThickness() ) ;
754 gMC->Gspos("PTCB", 1, "PAIR", 0.0, yO, 0.0, 0, "ONLY") ;
757 // --- Define Crystal BLock filled with air, position it inside PTCB ---
760 dpcbl[0] = fGeom->GetNPhi() * ( xtlX + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 ;
761 dpcbl[1] = ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 ;
762 dpcbl[2] = fGeom->GetNZ() * ( xtlZ + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 ;
764 gMC->Gsvolu("PCBL", "BOX ", idtmed[798], dpcbl, 3) ;
766 // --- Divide PCBL in X (phi) and Z directions --
767 gMC->Gsdvn("PROW", "PCBL", Int_t (fGeom->GetNPhi()), 1) ;
768 gMC->Gsdvn("PCEL", "PROW", Int_t (fGeom->GetNZ()), 3) ;
770 yO = -fGeom->GetModuleBoxThickness() / 2.0 ;
772 gMC->Gspos("PCBL", 1, "PTCB", 0.0, yO, 0.0, 0, "ONLY") ;
775 // --- Define STeel (actually, it's titanium) Cover volume, place inside PCEL
778 dpstc[0] = ( xtlX + 2 * fGeom->GetCrystalWrapThickness() ) / 2.0 ;
779 dpstc[1] = ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 ;
780 dpstc[2] = ( xtlZ + 2 * fGeom->GetCrystalWrapThickness() + 2 * fGeom->GetCrystalHolderThickness() ) / 2.0 ;
782 gMC->Gsvolu("PSTC", "BOX ", idtmed[704], dpstc, 3) ;
784 gMC->Gspos("PSTC", 1, "PCEL", 0.0, 0.0, 0.0, 0, "ONLY") ;
787 // --- Define Tyvek volume, place inside PSTC ---
790 dppap[0] = xtlX / 2.0 + fGeom->GetCrystalWrapThickness() ;
791 dppap[1] = ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 ;
792 dppap[2] = xtlZ / 2.0 + fGeom->GetCrystalWrapThickness() ;
794 gMC->Gsvolu("PPAP", "BOX ", idtmed[702], dppap, 3) ;
796 yO = ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0
797 - ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 ;
799 gMC->Gspos("PPAP", 1, "PSTC", 0.0, yO, 0.0, 0, "ONLY") ;
802 // --- Define PbWO4 crystal volume, place inside PPAP ---
805 dpxtl[0] = xtlX / 2.0 ;
806 dpxtl[1] = xtlY / 2.0 ;
807 dpxtl[2] = xtlZ / 2.0 ;
809 gMC->Gsvolu("PXTL", "BOX ", idtmed[699], dpxtl, 3) ;
811 yO = ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 - xtlY / 2.0 - fGeom->GetCrystalWrapThickness() ;
813 gMC->Gspos("PXTL", 1, "PPAP", 0.0, yO, 0.0, 0, "ONLY") ;
816 // --- Define crystal support volume, place inside PPAP ---
819 dpsup[0] = xtlX / 2.0 + fGeom->GetCrystalWrapThickness() ;
820 dpsup[1] = fGeom->GetCrystalSupportHeight() / 2.0 ;
821 dpsup[2] = xtlZ / 2.0 + fGeom->GetCrystalWrapThickness() ;
823 gMC->Gsvolu("PSUP", "BOX ", idtmed[798], dpsup, 3) ;
825 yO = fGeom->GetCrystalSupportHeight() / 2.0 - ( xtlY + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 ;
827 gMC->Gspos("PSUP", 1, "PPAP", 0.0, yO, 0.0, 0, "ONLY") ;
830 // --- Define PIN-diode volume and position it inside crystal support ---
831 // --- right behind PbWO4 crystal
833 // --- PIN-diode dimensions ---
837 dppin[0] = fGeom->GetPinDiodeSize(0) / 2.0 ;
838 dppin[1] = fGeom->GetPinDiodeSize(1) / 2.0 ;
839 dppin[2] = fGeom->GetPinDiodeSize(2) / 2.0 ;
841 gMC->Gsvolu("PPIN", "BOX ", idtmed[705], dppin, 3) ;
843 yO = fGeom->GetCrystalSupportHeight() / 2.0 - fGeom->GetPinDiodeSize(1) / 2.0 ;
845 gMC->Gspos("PPIN", 1, "PSUP", 0.0, yO, 0.0, 0, "ONLY") ;
848 // --- Define Upper Cooling Panel, place it on top of PTCB ---
850 // --- Upper Cooling Plate thickness ---
852 dpucp[0] = dptcb[0] ;
853 dpucp[1] = fGeom->GetUpperCoolingPlateThickness() ;
854 dpucp[2] = dptcb[2] ;
856 gMC->Gsvolu("PUCP", "BOX ", idtmed[701], dpucp,3) ;
858 yO = ( fGeom->GetAirFilledBoxSize(1) - fGeom->GetUpperCoolingPlateThickness() ) / 2.
859 - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetModuleBoxThickness()
860 - fGeom->GetUpperPlateThickness() - fGeom->GetSecondUpperPlateThickness() - fGeom->GetUpperCoolingPlateThickness() ) ;
862 gMC->Gspos("PUCP", 1, "PAIR", 0.0, yO, 0.0, 0, "ONLY") ;
865 // --- Define Al Support Plate, position it inside PAIR ---
866 // --- right beneath PTCB ---
867 // --- Al Support Plate thickness ---
870 dpasp[0] = fGeom->GetAirFilledBoxSize(0) / 2.0 ;
871 dpasp[1] = fGeom->GetSupportPlateThickness() / 2.0 ;
872 dpasp[2] = fGeom->GetAirFilledBoxSize(2) / 2.0 ;
874 gMC->Gsvolu("PASP", "BOX ", idtmed[701], dpasp, 3) ;
876 yO = ( fGeom->GetAirFilledBoxSize(1) - fGeom->GetSupportPlateThickness() ) / 2.
877 - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance()
878 - fGeom->GetUpperPlateThickness() - fGeom->GetSecondUpperPlateThickness() + dpcbl[1] * 2 ) ;
880 gMC->Gspos("PASP", 1, "PAIR", 0.0, yO, 0.0, 0, "ONLY") ;
883 // --- Define Thermo Insulating Plate, position it inside PAIR ---
884 // --- right beneath PASP ---
885 // --- Lower Thermo Insulating Plate thickness ---
888 dptip[0] = fGeom->GetAirFilledBoxSize(0) / 2.0 ;
889 dptip[1] = fGeom->GetLowerThermoPlateThickness() / 2.0 ;
890 dptip[2] = fGeom->GetAirFilledBoxSize(2) / 2.0 ;
892 gMC->Gsvolu("PTIP", "BOX ", idtmed[706], dptip, 3) ;
894 yO = ( fGeom->GetAirFilledBoxSize(1) - fGeom->GetLowerThermoPlateThickness() ) / 2.
895 - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetUpperPlateThickness()
896 - fGeom->GetSecondUpperPlateThickness() + dpcbl[1] * 2 + fGeom->GetSupportPlateThickness() ) ;
898 gMC->Gspos("PTIP", 1, "PAIR", 0.0, yO, 0.0, 0, "ONLY") ;
901 // --- Define Textolit Plate, position it inside PAIR ---
902 // --- right beneath PTIP ---
903 // --- Lower Textolit Plate thickness ---
906 dptxp[0] = fGeom->GetAirFilledBoxSize(0) / 2.0 ;
907 dptxp[1] = fGeom->GetLowerTextolitPlateThickness() / 2.0 ;
908 dptxp[2] = fGeom->GetAirFilledBoxSize(2) / 2.0 ;
910 gMC->Gsvolu("PTXP", "BOX ", idtmed[707], dptxp, 3) ;
912 yO = ( fGeom->GetAirFilledBoxSize(1) - fGeom->GetLowerTextolitPlateThickness() ) / 2.
913 - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetUpperPlateThickness()
914 - fGeom->GetSecondUpperPlateThickness() + dpcbl[1] * 2 + fGeom->GetSupportPlateThickness()
915 + fGeom->GetLowerThermoPlateThickness() ) ;
917 gMC->Gspos("PTXP", 1, "PAIR", 0.0, yO, 0.0, 0, "ONLY") ;
921 //____________________________________________________________________________
922 void AliPHOSv0::CreateGeometryforPPSD()
924 // Create the PHOS-PPSD geometry for GEANT
929 Geant3 geometry tree of PHOS-PPSD in ALICE
932 <IMG Align=BOTTOM ALT="PPSD geant tree" SRC="../images/PPSDinAlice.gif">
937 // Get pointer to the array containing media indexes
938 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
940 // The box containing all ppsd's for one PHOS module filled with air
942 ppsd[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ;
943 ppsd[1] = fGeom->GetPPSDBoxSize(1) / 2.0 ;
944 ppsd[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
946 gMC->Gsvolu("PPSD", "BOX ", idtmed[798], ppsd, 3) ;
948 Float_t yO = fGeom->GetOuterBoxSize(1) / 2.0 ;
950 gMC->Gspos("PPSD", 1, "PHOS", 0.0, yO, 0.0, 0, "ONLY") ;
952 // Now we build a micromegas module
953 // The box containing the whole module filled with epoxy (FR4)
956 mppsd[0] = fGeom->GetPPSDModuleSize(0) / 2.0 ;
957 mppsd[1] = fGeom->GetPPSDModuleSize(1) / 2.0 ;
958 mppsd[2] = fGeom->GetPPSDModuleSize(2) / 2.0 ;
960 gMC->Gsvolu("MPPS", "BOX ", idtmed[708], mppsd, 3) ;
963 // 1. The Top Lid made of epoxy (FR4)
966 tlppsd[0] = fGeom->GetPPSDModuleSize(0) / 2.0 ;
967 tlppsd[1] = fGeom->GetLidThickness() / 2.0 ;
968 tlppsd[2] = fGeom->GetPPSDModuleSize(2) / 2.0 ;
970 gMC->Gsvolu("TLPS", "BOX ", idtmed[708], tlppsd, 3) ;
972 Float_t y0 = ( fGeom->GetMicromegas1Thickness() - fGeom->GetLidThickness() ) / 2. ;
974 gMC->Gspos("TLPS", 1, "MPPS", 0.0, y0, 0.0, 0, "ONLY") ;
976 // 2. the upper panel made of composite material
979 upppsd[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
980 upppsd[1] = fGeom->GetCompositeThickness() / 2.0 ;
981 upppsd[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
983 gMC->Gsvolu("UPPS", "BOX ", idtmed[709], upppsd, 3) ;
985 y0 = y0 - fGeom->GetLidThickness() / 2. - fGeom->GetCompositeThickness() / 2. ;
987 gMC->Gspos("UPPS", 1, "MPPS", 0.0, y0, 0.0, 0, "ONLY") ;
989 // 3. the anode made of Copper
992 anppsd[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
993 anppsd[1] = fGeom->GetAnodeThickness() / 2.0 ;
994 anppsd[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
996 gMC->Gsvolu("ANPS", "BOX ", idtmed[710], anppsd, 3) ;
998 y0 = y0 - fGeom->GetCompositeThickness() / 2. - fGeom->GetAnodeThickness() / 2. ;
1000 gMC->Gspos("ANPS", 1, "MPPS", 0.0, y0, 0.0, 0, "ONLY") ;
1002 // 4. the conversion gap + avalanche gap filled with gas
1005 ggppsd[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
1006 ggppsd[1] = ( fGeom->GetConversionGap() + fGeom->GetAvalancheGap() ) / 2.0 ;
1007 ggppsd[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
1009 gMC->Gsvolu("GGPS", "BOX ", idtmed[715], ggppsd, 3) ;
1011 // --- Divide GGPP in X (phi) and Z directions --
1012 gMC->Gsdvn("GROW", "GGPS", fGeom->GetNumberOfPadsPhi(), 1) ;
1013 gMC->Gsdvn("GCEL", "GROW", fGeom->GetNumberOfPadsZ() , 3) ;
1015 y0 = y0 - fGeom->GetAnodeThickness() / 2. - ( fGeom->GetConversionGap() + fGeom->GetAvalancheGap() ) / 2. ;
1017 gMC->Gspos("GGPS", 1, "MPPS", 0.0, y0, 0.0, 0, "ONLY") ;
1020 // 6. the cathode made of Copper
1023 cappsd[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
1024 cappsd[1] = fGeom->GetCathodeThickness() / 2.0 ;
1025 cappsd[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
1027 gMC->Gsvolu("CAPS", "BOX ", idtmed[710], cappsd, 3) ;
1029 y0 = y0 - ( fGeom->GetAvalancheGap() + fGeom->GetAvalancheGap() ) / 2. - fGeom->GetCathodeThickness() / 2. ;
1031 gMC->Gspos("CAPS", 1, "MPPS", 0.0, y0, 0.0, 0, "ONLY") ;
1033 // 7. the printed circuit made of G10
1036 pcppsd[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2,.0 ;
1037 pcppsd[1] = fGeom->GetPCThickness() / 2.0 ;
1038 pcppsd[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
1040 gMC->Gsvolu("PCPS", "BOX ", idtmed[711], cappsd, 3) ;
1042 y0 = y0 - fGeom->GetCathodeThickness() / 2. - fGeom->GetPCThickness() / 2. ;
1044 gMC->Gspos("PCPS", 1, "MPPS", 0.0, y0, 0.0, 0, "ONLY") ;
1046 // 8. the lower panel made of composite material
1049 lpppsd[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
1050 lpppsd[1] = fGeom->GetCompositeThickness() / 2.0 ;
1051 lpppsd[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
1053 gMC->Gsvolu("LPPS", "BOX ", idtmed[709], lpppsd, 3) ;
1055 y0 = y0 - fGeom->GetPCThickness() / 2. - fGeom->GetCompositeThickness() / 2. ;
1057 gMC->Gspos("LPPS", 1, "MPPS", 0.0, y0, 0.0, 0, "ONLY") ;
1059 // Position the fNumberOfModulesPhi x fNumberOfModulesZ modules (mppsd) inside PPSD to cover a PHOS module
1060 // the top and bottom one's (which are assumed identical) :
1062 Float_t yt = ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas1Thickness() ) / 2. ;
1063 Float_t yb = - ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas2Thickness() ) / 2. ;
1065 Int_t copyNumbertop = 0 ;
1066 Int_t copyNumberbot = fGeom->GetNumberOfModulesPhi() * fGeom->GetNumberOfModulesZ() ;
1068 Float_t x = ( fGeom->GetPPSDBoxSize(0) - fGeom->GetPPSDModuleSize(0) ) / 2. ;
1070 for ( Int_t iphi = 1; iphi <= fGeom->GetNumberOfModulesPhi(); iphi++ ) { // the number of micromegas modules in phi per PHOS module
1071 Float_t z = ( fGeom->GetPPSDBoxSize(2) - fGeom->GetPPSDModuleSize(2) ) / 2. ;
1073 for ( Int_t iz = 1; iz <= fGeom->GetNumberOfModulesZ(); iz++ ) { // the number of micromegas modules in z per PHOS module
1074 gMC->Gspos("MPPS", ++copyNumbertop, "PPSD", x, yt, z, 0, "ONLY") ;
1075 gMC->Gspos("MPPS", ++copyNumberbot, "PPSD", x, yb, z, 0, "ONLY") ;
1076 z = z - fGeom->GetPPSDModuleSize(2) ;
1077 } // end of Z module loop
1078 x = x - fGeom->GetPPSDModuleSize(0) ;
1079 } // end of phi module loop
1081 // The Lead converter between two air gaps
1085 uappsd[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ;
1086 uappsd[1] = fGeom->GetMicro1ToLeadGap() / 2.0 ;
1087 uappsd[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
1089 gMC->Gsvolu("UAPPSD", "BOX ", idtmed[798], uappsd, 3) ;
1091 y0 = ( fGeom->GetPPSDBoxSize(1) - 2 * fGeom->GetMicromegas1Thickness() - fGeom->GetMicro1ToLeadGap() ) / 2. ;
1093 gMC->Gspos("UAPPSD", 1, "PPSD", 0.0, y0, 0.0, 0, "ONLY") ;
1095 // 2. Lead converter
1098 lcppsd[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ;
1099 lcppsd[1] = fGeom->GetLeadConverterThickness() / 2.0 ;
1100 lcppsd[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
1102 gMC->Gsvolu("LCPPSD", "BOX ", idtmed[712], lcppsd, 3) ;
1104 y0 = y0 - fGeom->GetMicro1ToLeadGap() / 2. - fGeom->GetLeadConverterThickness() / 2. ;
1106 gMC->Gspos("LCPPSD", 1, "PPSD", 0.0, y0, 0.0, 0, "ONLY") ;
1111 lappsd[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ;
1112 lappsd[1] = fGeom->GetLeadToMicro2Gap() / 2.0 ;
1113 lappsd[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
1115 gMC->Gsvolu("LAPPSD", "BOX ", idtmed[798], lappsd, 3) ;
1117 y0 = y0 - fGeom->GetLeadConverterThickness() / 2. - fGeom->GetLeadToMicro2Gap() / 2. ;
1119 gMC->Gspos("LAPPSD", 1, "PPSD", 0.0, y0, 0.0, 0, "ONLY") ;
1123 //___________________________________________________________________________
1124 Int_t AliPHOSv0::Digitize(Float_t Energy)
1126 // Applies the energy calibration
1128 Float_t fB = 100000000. ;
1130 Int_t chan = Int_t(fA + Energy*fB ) ;
1133 //___________________________________________________________________________
1134 void AliPHOSv0::FinishEvent()
1136 // Makes the digits from the sum of summed hit in a single crystal or PPSD gas cell
1137 // Adds to the energy the electronic noise
1138 // Keeps digits with energy above fDigitThreshold
1143 TClonesArray &lDigits = *fDigits ;
1145 AliPHOSDigit * newdigit ;
1146 AliPHOSDigit * curdigit ;
1147 Bool_t deja = kFALSE ;
1149 for ( i = 0 ; i < fNTmpHits ; i++ ) {
1150 hit = (AliPHOSHit*)fTmpHits->At(i) ;
1151 newdigit = new AliPHOSDigit( hit->GetPrimary(), hit->GetId(), Digitize( hit->GetEnergy() ) ) ;
1153 for ( j = 0 ; j < fNdigits ; j++) {
1154 curdigit = (AliPHOSDigit*) lDigits[j] ;
1155 if ( *curdigit == *newdigit) {
1156 *curdigit = *curdigit + *newdigit ;
1161 new(lDigits[fNdigits]) AliPHOSDigit(* newdigit) ;
1168 // Noise induced by the PIN diode of the PbWO crystals
1170 Float_t energyandnoise ;
1171 for ( i = 0 ; i < fNdigits ; i++ ) {
1172 newdigit = (AliPHOSDigit * ) fDigits->At(i) ;
1173 fGeom->AbsToRelNumbering(newdigit->GetId(), relid) ;
1175 if (relid[1]==0){ // Digits belong to EMC (PbW0_4 crystals)
1176 energyandnoise = newdigit->GetAmp() + Digitize(gRandom->Gaus(0., fPinElectronicNoise)) ;
1178 if (energyandnoise < 0 )
1179 energyandnoise = 0 ;
1181 newdigit->SetAmp(energyandnoise) ;
1183 if ( newdigit->GetAmp() < fDigitThreshold ) // if threshold not surpassed, remove digit from list
1184 fDigits->RemoveAt(i) ;
1187 fDigits->Compress() ;
1192 //____________________________________________________________________________
1193 void AliPHOSv0::Init(void)
1195 // Just prints an information message
1200 for(i=0;i<35;i++) printf("*");
1201 printf(" PHOS_INIT ");
1202 for(i=0;i<35;i++) printf("*");
1205 // Here the PHOS initialisation code (if any!)
1207 for(i=0;i<80;i++) printf("*");
1212 //___________________________________________________________________________
1213 void AliPHOSv0::MakeBranch(Option_t* opt)
1215 // Create new branche in the current Root Tree in the digit Tree
1217 AliDetector::MakeBranch(opt) ;
1219 char branchname[10];
1220 sprintf(branchname,"%s",GetName());
1221 char *cdD = strstr(opt,"D");
1223 if (fDigits && gAlice->TreeD() && cdD) {
1224 gAlice->TreeD()->Branch(branchname,&fDigits, fBufferSize);
1228 //_____________________________________________________________________________
1229 void AliPHOSv0::Reconstruction(AliPHOSReconstructioner * Reconstructioner)
1231 // 1. Reinitializes the existing RecPoint, TrackSegment, and RecParticles Lists and
1232 // 2. Creates a branch in TreeR for each list
1233 // 3. Steers the reconstruction processes
1234 // 4. Saves the 3 lists in TreeR
1235 // 5. Write the Tree to File
1237 fReconstructioner = Reconstructioner ;
1239 char branchname[10] ;
1244 fEmcClusters->Delete() ;
1245 delete fEmcClusters ;
1248 fEmcClusters= new RecPointsList("AliPHOSEmcRecPoint", 100) ;
1249 if ( fEmcClusters && gAlice->TreeR() ) {
1250 sprintf(branchname,"%sERP",GetName()) ;
1251 gAlice->TreeR()->Branch(branchname, &fEmcClusters, fBufferSize);
1254 if (fPpsdClusters) {
1255 fPpsdClusters->Delete() ;
1256 delete fPpsdClusters ;
1259 fPpsdClusters = new RecPointsList("AliPHOSPpsdRecPoint", 100) ;
1260 if ( fPpsdClusters && gAlice->TreeR() ) {
1261 sprintf(branchname,"%sPRP",GetName()) ;
1262 gAlice->TreeR()->Branch(branchname, &fPpsdClusters, fBufferSize);
1265 if (fTrackSegments) {
1266 fTrackSegments->Delete() ;
1267 delete fTrackSegments ;
1268 fTrackSegments = 0 ;
1270 fTrackSegments = new TrackSegmentsList("AliPHOSTrackSegment", 100) ;
1271 if ( fTrackSegments && gAlice->TreeR() ) {
1272 sprintf(branchname,"%sTS",GetName()) ;
1273 gAlice->TreeR()->Branch(branchname, &fTrackSegments, fBufferSize);
1276 if (fRecParticles) {
1277 fRecParticles->Delete() ;
1278 delete fRecParticles ;
1281 fRecParticles = new RecParticlesList("AliPHOSRecParticle", 100) ;
1282 if ( fRecParticles && gAlice->TreeR() ) {
1283 sprintf(branchname,"%sRP",GetName()) ;
1284 gAlice->TreeR()->Branch(branchname, &fRecParticles, fBufferSize);
1289 fReconstructioner->Make(fDigits, fEmcClusters, fPpsdClusters, fTrackSegments, fRecParticles);
1293 gAlice->TreeR()->Fill() ;
1297 gAlice->TreeR()->Write() ;
1301 //____________________________________________________________________________
1302 void AliPHOSv0::StepManager(void)
1304 // Accumulates hits as long as the track stays in a single crystal or PPSD gas Cell
1306 Int_t relid[4] ; // (box, layer, row, column) indices
1307 Float_t xyze[4] ; // position wrt MRS and energy deposited
1308 TLorentzVector pos ;
1311 Int_t primary = gAlice->GetPrimary( gAlice->CurrentTrack() );
1312 TString name = fGeom->GetName() ;
1313 if ( name == "GPS2" ) { // the CPV is a PPSD
1314 if( gMC->CurrentVolID(copy) == gMC->VolId("GCEL") ) // We are inside a gas cell
1316 gMC->TrackPosition(pos) ;
1320 xyze[3] = gMC->Edep() ;
1322 if ( xyze[3] != 0 ) { // there is deposited energy
1323 gMC->CurrentVolOffID(5, relid[0]) ; // get the PHOS Module number
1324 gMC->CurrentVolOffID(3, relid[1]) ; // get the Micromegas Module number
1325 // 1-> Geom->GetNumberOfModulesPhi() * fGeom->GetNumberOfModulesZ() upper
1326 // > fGeom->GetNumberOfModulesPhi() * fGeom->GetNumberOfModulesZ() lower
1327 gMC->CurrentVolOffID(1, relid[2]) ; // get the row number of the cell
1328 gMC->CurrentVolID(relid[3]) ; // get the column number
1330 // get the absolute Id number
1333 fGeom->RelToAbsNumbering(relid, absid) ;
1335 // add current hit to the hit list
1336 AddHit(primary, absid, xyze);
1338 } // there is deposited energy
1339 } // We are inside the gas of the CPV
1340 } // GPS2 configuration
1342 if(gMC->CurrentVolID(copy) == gMC->VolId("PXTL") ) // We are inside a PBWO crystal
1344 gMC->TrackPosition(pos) ;
1348 xyze[3] = gMC->Edep() ;
1350 if ( xyze[3] != 0 ) {
1351 gMC->CurrentVolOffID(10, relid[0]) ; // get the PHOS module number ;
1352 relid[1] = 0 ; // means PBW04
1353 gMC->CurrentVolOffID(4, relid[2]) ; // get the row number inside the module
1354 gMC->CurrentVolOffID(3, relid[3]) ; // get the cell number inside the module
1356 // get the absolute Id number
1359 fGeom->RelToAbsNumbering(relid, absid) ;
1361 // add current hit to the hit list
1363 AddHit(primary, absid, xyze);
1365 } // there is deposited energy
1366 } // we are inside a PHOS Xtal