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