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 **************************************************************************/
17 /* History of cvs commits:
20 * Revision 1.83 2006/11/14 17:11:15 hristov
21 * Removing inheritances from TAttLine, TAttMarker and AliRndm in AliModule. The copy constructor and assignment operators are moved to the private part of the class and not implemented. The corresponding changes are propagated to the detectors
23 * Revision 1.82 2006/09/27 19:55:57 kharlov
24 * Alignment object with symbolic volume names are introduced
26 * Revision 1.81 2006/03/04 20:25:56 kharlov
27 * Set geom parameters from CDB
29 * Revision 1.80 2005/06/17 07:39:07 hristov
30 * Removing GetDebug and SetDebug from AliRun and AliModule. Using AliLog for the messages
32 * Revision 1.79 2005/05/28 14:19:05 schutz
33 * Compilation warnings fixed by T.P.
37 //_________________________________________________________________________
38 // Implementation version v0 of PHOS Manager class
39 // An object of this class does not produce hits nor digits
40 // It is the one to use if you do not want to produce outputs in TREEH or TREED
42 //*-- Author: Yves Schutz (SUBATECH) & Dmitri Peressounko (RRC KI & SUBATECH)
45 // --- ROOT system ---
49 #include <TGeometry.h>
55 #include <TVirtualMC.h>
56 #include <TGeoManager.h>
58 // --- Standard library ---
63 // --- AliRoot header files ---
66 #include "AliPHOSGeometry.h"
67 #include "AliPHOSLoader.h"
68 #include "AliPHOSv0.h"
74 //____________________________________________________________________________
75 AliPHOSv0::AliPHOSv0(const char *name, const char *title):
78 // ctor : title is used to identify the layout
82 //____________________________________________________________________________
83 void AliPHOSv0::BuildGeometry()
85 // Build the PHOS geometry for the ROOT display
89 PHOS in ALICE displayed by root
95 <IMG Align=BOTTOM ALT="All Views" SRC="../images/AliPHOSv0AllViews.gif">
100 <IMG Align=BOTTOM ALT="Front View" SRC="../images/AliPHOSv0FrontView.gif">
105 <IMG Align=BOTTOM ALT="3D View 1" SRC="../images/AliPHOSv03DView1.gif">
110 <IMG Align=BOTTOM ALT="3D View 2" SRC="../images/AliPHOSv03DView2.gif">
116 this->BuildGeometryforEMC() ;
117 this->BuildGeometryforCPV() ;
121 //____________________________________________________________________________
122 void AliPHOSv0:: BuildGeometryforEMC(void)
124 // Build the PHOS-EMC geometry for the ROOT display
126 const Int_t kColorPHOS = kRed ;
127 const Int_t kColorXTAL = kBlue ;
129 Double_t const kRADDEG = 180.0 / TMath::Pi() ;
131 AliPHOSGeometry * geom = GetGeometry() ;
132 AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
133 Float_t * boxparams = emcg->GetEMCParams() ;
135 new TTRD1("OuterBox", "PHOS box", "void",boxparams[0],boxparams[1],boxparams[2], boxparams[3] );
140 Float_t * cribox = emcg->GetInnerThermoHalfSize() ;
141 new TBRIK( "CrystalsBox", "PHOS crystals box", "void", cribox[0], cribox[2], cribox[1] ) ;
143 // position PHOS into ALICE
145 Float_t r = geom->GetIPtoOuterCoverDistance() + boxparams[3] ;
147 TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
149 char * nodename = new char[20] ;
150 char * rotname = new char[20] ;
152 new TRotMatrix("cribox", "cribox", 90, 0, 90, 90, 0, 0);
154 for( Int_t i = 1; i <= geom->GetNModules(); i++ ) {
156 Float_t angle = geom->GetPHOSAngle(i) ;
157 sprintf(rotname, "%s%d", "rot", number++) ;
158 new TRotMatrix(rotname, rotname, 90, angle, 0, 0, 90, 270 + angle);
161 sprintf(nodename,"%s%d", "Module", i) ;
162 Float_t x = r * TMath::Sin( angle / kRADDEG ) ;
163 Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
164 TNode * outerboxnode = new TNode(nodename, nodename, "OuterBox", x, y, 0, rotname ) ;
165 outerboxnode->SetLineColor(kColorPHOS) ;
166 fNodes->Add(outerboxnode) ;
169 Float_t z = -boxparams[3] - geom->GetIPtoOuterCoverDistance() +
170 cribox[1] + geom->GetIPtoCrystalSurface() ;
171 TNode * crystalsboxnode = new TNode(nodename, nodename, "CrystalsBox", 0, 0, z) ;
172 crystalsboxnode->SetLineColor(kColorXTAL) ;
173 fNodes->Add(crystalsboxnode) ;
181 //____________________________________________________________________________
182 void AliPHOSv0:: BuildGeometryforCPV(void)
184 // Build the PHOS-CPV geometry for the ROOT display
185 // Author: Yuri Kharlov 11 September 2000
190 CPV displayed by root
195 <td>CPV perspective view</td>
196 <td>CPV front view </td>
200 <td> <img height=300 width=290 src="../images/CPVRootPersp.gif"> </td>
201 <td> <img height=300 width=290 src="../images/CPVRootFront.gif"> </td>
209 const Double_t kRADDEG = 180.0 / TMath::Pi() ;
210 const Int_t kColorCPV = kGreen ;
211 const Int_t kColorFrame = kYellow ;
212 const Int_t kColorGassiplex = kRed;
213 const Int_t kColorPCB = kCyan;
215 AliPHOSGeometry * geom = GetGeometry() ;
217 // Box for a full PHOS module
219 new TBRIK ("CPVBox", "CPV box", "void", geom->GetCPVBoxSize(0)/2,
220 geom->GetCPVBoxSize(1)/2,
221 geom->GetCPVBoxSize(2)/2 );
222 new TBRIK ("CPVFrameLR", "CPV frame Left-Right", "void", geom->GetCPVFrameSize(0)/2,
223 geom->GetCPVFrameSize(1)/2,
224 geom->GetCPVBoxSize(2)/2 );
225 new TBRIK ("CPVFrameUD", "CPV frame Up-Down", "void", geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0),
226 geom->GetCPVFrameSize(1)/2,
227 geom->GetCPVFrameSize(2)/2);
228 new TBRIK ("CPVPCB", "CPV PCB", "void", geom->GetCPVActiveSize(0)/2,
229 geom->GetCPVTextoliteThickness()/2,
230 geom->GetCPVActiveSize(1)/2);
231 new TBRIK ("CPVGassiplex", "CPV Gassiplex PCB", "void", geom->GetGassiplexChipSize(0)/2,
232 geom->GetGassiplexChipSize(1)/2,
233 geom->GetGassiplexChipSize(2)/2);
235 // position CPV into ALICE
237 char * nodename = new char[25] ;
238 char * rotname = new char[25] ;
240 Float_t r = geom->GetIPtoCPVDistance() + geom->GetCPVBoxSize(1) / 2.0 ;
242 TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
244 Int_t lastModule = 0 ;
245 lastModule = geom->GetNModules();
247 for( Int_t i = 1; i <= lastModule; i++ ) { // the number of PHOS modules
251 Float_t angle = geom->GetPHOSAngle(i) ;
252 sprintf(rotname, "%s%d", "rotg", number+i) ;
253 new TRotMatrix(rotname, rotname, 90, angle, 90, 90 + angle, 0, 0);
255 sprintf(nodename, "%s%d", "CPVModule", i) ;
256 Float_t x = r * TMath::Sin( angle / kRADDEG ) ;
257 Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
259 TNode * cpvBoxNode = new TNode(nodename , nodename ,"CPVBox", x, y, 0, rotname ) ;
260 cpvBoxNode->SetLineColor(kColorCPV) ;
261 fNodes->Add(cpvBoxNode) ;
264 // inside each CPV box:
268 for (j=0; j<=1; j++) {
269 sprintf(nodename, "CPVModule%d Frame%d", i, j+1) ;
270 x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
271 TNode * cpvFrameNode = new TNode(nodename , nodename ,"CPVFrameLR", x, 0, 0) ;
272 cpvFrameNode->SetLineColor(kColorFrame) ;
273 fNodes->Add(cpvFrameNode) ;
275 sprintf(nodename, "CPVModule%d Frame%d", i, j+3) ;
276 z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
277 cpvFrameNode = new TNode(nodename , nodename ,"CPVFrameUD", 0, 0, z) ;
278 cpvFrameNode->SetLineColor(kColorFrame) ;
279 fNodes->Add(cpvFrameNode) ;
282 // 4 printed circuit boards
283 for (j=0; j<4; j++) {
284 sprintf(nodename, "CPVModule%d PCB%d", i, j+1) ;
285 y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(j) + geom->GetCPVTextoliteThickness()/2;
286 TNode * cpvPCBNode = new TNode(nodename , nodename ,"CPVPCB", 0, y, 0) ;
287 cpvPCBNode->SetLineColor(kColorPCB) ;
288 fNodes->Add(cpvPCBNode) ;
292 Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
293 Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ() + 1);
294 y = geom->GetCPVFrameSize(1)/2 - geom->GetFTPosition(0) +
295 geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
296 for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
297 x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
298 for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
299 z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
300 sprintf(nodename, "CPVModule%d Chip(%dx%d)", i, ix+1,iz+1) ;
301 TNode * cpvGassiplexNode = new TNode(nodename , nodename ,"CPVGassiplex", x, y, z) ;
302 cpvGassiplexNode->SetLineColor(kColorGassiplex) ;
303 fNodes->Add(cpvGassiplexNode) ;
313 //____________________________________________________________________________
314 void AliPHOSv0::CreateGeometry()
316 // Create the PHOS geometry for Geant
318 AliPHOSv0 *phostmp = dynamic_cast<AliPHOSv0*>(gAlice->GetModule("PHOS")) ;
320 if ( phostmp == NULL ) {
322 fprintf(stderr, "PHOS detector not found!\n") ;
327 AliPHOSGeometry * geom = GetGeometry() ;
329 // Get pointer to the array containing media indeces
330 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
332 // Create a PHOS module.
334 gMC->Gsvolu("PHOS", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;
336 this->CreateGeometryforEMC() ;
338 if (strstr(fTitle.Data(),"noCPV") == 0)
339 this->CreateGeometryforCPV() ;
341 this->CreateGeometryforSupport() ;
343 // --- Position PHOS mdules in ALICE setup ---
347 for (Int_t iModule = 0; iModule < geom->GetNModules(); iModule++ ) {
350 for (iXYZ=0; iXYZ<3; iXYZ++)
351 for (iAngle=0; iAngle<2; iAngle++)
352 angle[iXYZ][iAngle] = geom->GetModuleAngle(iModule,iXYZ, iAngle);
353 AliMatrix(idrotm[iModule],
354 angle[0][0],angle[0][1],
355 angle[1][0],angle[1][1],
356 angle[2][0],angle[2][1]) ;
359 for (iXYZ=0; iXYZ<3; iXYZ++)
360 pos[iXYZ] = geom->GetModuleCenter(iModule,iXYZ);
361 gMC->Gspos("PHOS", iModule+1, "ALIC", pos[0], pos[1], pos[2],
362 idrotm[iModule], "ONLY") ;
367 //____________________________________________________________________________
368 void AliPHOSv0::CreateGeometryforEMC()
370 // Create the PHOS-EMC geometry for GEANT
371 // Author: Dmitri Peressounko August 2001
372 // The used coordinate system:
373 // 1. in Module: X along longer side, Y out of beam, Z along shorter side (along beam)
374 // 2. In Strip the same: X along longer side, Y out of beam, Z along shorter side (along beam)
380 Geant3 geometry tree of PHOS-EMC in ALICE
383 <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/EMCinAlice.gif">
388 // Get pointer to the array containing media indexes
389 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
391 AliPHOSGeometry * geom = GetGeometry() ;
392 AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
394 // ======= Define the strip ===============
396 gMC->Gsvolu("PSTR", "BOX ", idtmed[716], emcg->GetStripHalfSize(), 3) ; //Made of stell
398 // --- define air volume (cell of the honeycomb)
399 gMC->Gsvolu("PCEL", "BOX ", idtmed[798], emcg->GetAirCellHalfSize(), 3);
401 // --- define wrapped crystal and put it into AirCell
403 gMC->Gsvolu("PWRA", "BOX ", idtmed[702], emcg->GetWrappedHalfSize(), 3);
404 Float_t * pin = emcg->GetAPDHalfSize() ;
405 Float_t * preamp = emcg->GetPreampHalfSize() ;
406 Float_t y = (emcg->GetAirGapLed()-2*pin[1]-2*preamp[1])/2;
407 gMC->Gspos("PWRA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
409 // --- Define crystall and put it into wrapped crystall ---
410 gMC->Gsvolu("PXTL", "BOX ", idtmed[699], emcg->GetCrystalHalfSize(), 3) ;
411 gMC->Gspos("PXTL", 1, "PWRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
413 // --- define APD/PIN preamp and put it into AirCell
415 gMC->Gsvolu("PPIN", "BOX ", idtmed[705], emcg->GetAPDHalfSize(), 3) ;
416 Float_t * crystal = emcg->GetCrystalHalfSize() ;
417 y = crystal[1] + emcg->GetAirGapLed() /2 - preamp[1];
418 gMC->Gspos("PPIN", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
420 gMC->Gsvolu("PREA", "BOX ", idtmed[711], emcg->GetPreampHalfSize(), 3) ; // Here I assumed preamp
421 // as a printed Circuit
422 y = crystal[1] + emcg->GetAirGapLed() /2 + pin[1] ; // May it should be changed
423 gMC->Gspos("PREA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ; // to ceramics?
426 // --- Fill strip with wrapped cristalls in Air Cells
428 Float_t* splate = emcg->GetSupportPlateHalfSize();
430 Float_t* acel = emcg->GetAirCellHalfSize() ;
432 for(icel = 1; icel <= emcg->GetNCellsInStrip(); icel++){
433 Float_t x = (2*icel - 1 - emcg->GetNCellsInStrip())* acel[0] ;
434 gMC->Gspos("PCEL", icel, "PSTR", x, y, 0.0, 0, "ONLY") ;
437 // --- define the support plate, hole in it and position it in strip ----
438 gMC->Gsvolu("PSUP", "BOX ", idtmed[701], emcg->GetSupportPlateHalfSize(), 3) ;
440 gMC->Gsvolu("PSHO", "BOX ", idtmed[798], emcg->GetSupportPlateInHalfSize(), 3) ;
441 Float_t z = emcg->GetSupportPlateThickness()/2 ;
442 gMC->Gspos("PSHO", 1, "PSUP", 0.0, 0.0, z, 0, "ONLY") ;
445 gMC->Gspos("PSUP", 1, "PSTR", 0.0, y, 0.0, 0, "ONLY") ;
448 // ========== Fill module with strips and put them into inner thermoinsulation=============
449 gMC->Gsvolu("PTII", "BOX ", idtmed[706], emcg->GetInnerThermoHalfSize(), 3) ;
451 Float_t * inthermo = emcg->GetInnerThermoHalfSize() ;
452 Float_t * strip = emcg->GetStripHalfSize() ;
453 y = inthermo[1] - strip[1] ;
458 for(irow = 0; irow < emcg->GetNStripX(); irow ++){
459 Float_t x = (2*irow + 1 - emcg->GetNStripX())* strip[0] ;
460 for(icol = 0; icol < emcg->GetNStripZ(); icol ++){
461 z = (2*icol + 1 - emcg->GetNStripZ()) * strip[2] ;
462 gMC->Gspos("PSTR", nr, "PTII", x, y, z, 0, "ONLY") ;
468 // ------- define the air gap between thermoinsulation and cooler
469 gMC->Gsvolu("PAGA", "BOX ", idtmed[798], emcg->GetAirGapHalfSize(), 3) ;
470 Float_t * agap = emcg->GetAirGapHalfSize() ;
471 y = agap[1] - inthermo[1] ;
473 gMC->Gspos("PTII", 1, "PAGA", 0.0, y, 0.0, 0, "ONLY") ;
477 // ------- define the Al passive cooler
478 gMC->Gsvolu("PCOR", "BOX ", idtmed[701], emcg->GetCoolerHalfSize(), 3) ;
479 Float_t * cooler = emcg->GetCoolerHalfSize() ;
480 y = cooler[1] - agap[1] ;
482 gMC->Gspos("PAGA", 1, "PCOR", 0.0, y, 0.0, 0, "ONLY") ;
484 // ------- define the outer thermoinsulating cover
485 gMC->Gsvolu("PTIO", "TRD1", idtmed[706], emcg->GetOuterThermoParams(), 4) ;
486 Float_t * outparams = emcg->GetOuterThermoParams() ;
489 AliMatrix(idrotm[1], 90.0, 0.0, 0.0, 0.0, 90.0, 270.0) ;
490 // Frame in outer thermoinsulation and so on: z out of beam, y along beam, x across beam
492 z = outparams[3] - cooler[1] ;
493 gMC->Gspos("PCOR", 1, "PTIO", 0., 0.0, z, idrotm[1], "ONLY") ;
495 // -------- Define the outer Aluminium cover -----
496 gMC->Gsvolu("PCOL", "TRD1", idtmed[701], emcg->GetAlCoverParams(), 4) ;
497 Float_t * covparams = emcg->GetAlCoverParams() ;
498 z = covparams[3] - outparams[3] ;
499 gMC->Gspos("PTIO", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
501 // --------- Define front fiberglass cover -----------
502 gMC->Gsvolu("PFGC", "BOX ", idtmed[717], emcg->GetFiberGlassHalfSize(), 3) ;
504 gMC->Gspos("PFGC", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
506 //=============This is all with cold section==============
509 //------ Warm Section --------------
510 gMC->Gsvolu("PWAR", "BOX ", idtmed[701], emcg->GetWarmAlCoverHalfSize(), 3) ;
511 Float_t * warmcov = emcg->GetWarmAlCoverHalfSize() ;
513 // --- Define the outer thermoinsulation ---
514 gMC->Gsvolu("PWTI", "BOX ", idtmed[706], emcg->GetWarmThermoHalfSize(), 3) ;
515 Float_t * warmthermo = emcg->GetWarmThermoHalfSize() ;
516 z = -warmcov[2] + warmthermo[2] ;
518 gMC->Gspos("PWTI", 1, "PWAR", 0., 0.0, z, 0, "ONLY") ;
520 // --- Define cables area and put in it T-supports ----
521 gMC->Gsvolu("PCA1", "BOX ", idtmed[718], emcg->GetTCables1HalfSize(), 3) ;
522 Float_t * cbox = emcg->GetTCables1HalfSize() ;
524 gMC->Gsvolu("PBE1", "BOX ", idtmed[701], emcg->GetTSupport1HalfSize(), 3) ;
525 Float_t * beams = emcg->GetTSupport1HalfSize() ;
527 for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
528 Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
529 gMC->Gspos("PBE1", isup, "PCA1", x, 0.0, 0.0, 0, "ONLY") ;
532 z = -warmthermo[2] + cbox[2] ;
533 gMC->Gspos("PCA1", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;
535 gMC->Gsvolu("PCA2", "BOX ", idtmed[718], emcg->GetTCables2HalfSize(), 3) ;
536 Float_t * cbox2 = emcg->GetTCables2HalfSize() ;
538 gMC->Gsvolu("PBE2", "BOX ", idtmed[701], emcg->GetTSupport2HalfSize(), 3) ;
539 for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
540 Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
541 gMC->Gspos("PBE2", isup, "PCA2", x, 0.0, 0.0, 0, "ONLY") ;
544 z = -warmthermo[2] + 2*cbox[2] + cbox2[2];
545 gMC->Gspos("PCA2", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;
548 // --- Define frame ---
549 gMC->Gsvolu("PFRX", "BOX ", idtmed[716], emcg->GetFrameXHalfSize(), 3) ;
550 Float_t * posit = emcg->GetFrameXPosition() ;
551 gMC->Gspos("PFRX", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
552 gMC->Gspos("PFRX", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
554 gMC->Gsvolu("PFRZ", "BOX ", idtmed[716], emcg->GetFrameZHalfSize(), 3) ;
555 posit = emcg->GetFrameZPosition() ;
556 gMC->Gspos("PFRZ", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
557 gMC->Gspos("PFRZ", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
559 // --- Define Fiber Glass support ---
560 gMC->Gsvolu("PFG1", "BOX ", idtmed[717], emcg->GetFGupXHalfSize(), 3) ;
561 posit = emcg->GetFGupXPosition() ;
562 gMC->Gspos("PFG1", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
563 gMC->Gspos("PFG1", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
565 gMC->Gsvolu("PFG2", "BOX ", idtmed[717], emcg->GetFGupZHalfSize(), 3) ;
566 posit = emcg->GetFGupZPosition() ;
567 gMC->Gspos("PFG2", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
568 gMC->Gspos("PFG2", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
570 gMC->Gsvolu("PFG3", "BOX ", idtmed[717], emcg->GetFGlowXHalfSize(), 3) ;
571 posit = emcg->GetFGlowXPosition() ;
572 gMC->Gspos("PFG3", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
573 gMC->Gspos("PFG3", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
575 gMC->Gsvolu("PFG4", "BOX ", idtmed[717], emcg->GetFGlowZHalfSize(), 3) ;
576 posit = emcg->GetFGlowZPosition() ;
577 gMC->Gspos("PFG4", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
578 gMC->Gspos("PFG4", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
580 // --- Define Air Gap for FEE electronics -----
582 gMC->Gsvolu("PAFE", "BOX ", idtmed[798], emcg->GetFEEAirHalfSize(), 3) ;
583 posit = emcg->GetFEEAirPosition() ;
584 gMC->Gspos("PAFE", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
586 // Define the EMC module volume and combine Cool and Warm sections
588 gMC->Gsvolu("PEMC", "TRD1", idtmed[798], emcg->GetEMCParams(), 4) ;
591 gMC->Gspos("PCOL", 1, "PEMC", 0., 0., z, 0, "ONLY") ;
593 gMC->Gspos("PWAR", 1, "PEMC", 0., 0., z, 0, "ONLY") ;
596 // Put created EMC geometry into PHOS volume
598 z = geom->GetCPVBoxSize(1) / 2. ;
599 gMC->Gspos("PEMC", 1, "PHOS", 0., 0., z, 0, "ONLY") ;
603 //____________________________________________________________________________
604 void AliPHOSv0::CreateGeometryforCPV()
606 // Create the PHOS-CPV geometry for GEANT
607 // Author: Yuri Kharlov 11 September 2000
611 Geant3 geometry of PHOS-CPV in ALICE
616 <td>CPV perspective view</td>
617 <td>CPV front view </td>
621 <td> <img height=300 width=290 src="../images/CPVallPersp.gif"> </td>
622 <td> <img height=300 width=290 src="../images/CPVallFront.gif"> </td>
626 <td>One CPV module, perspective view </td>
627 <td>One CPV module, front view (extended in vertical direction) </td>
631 <td><img height=300 width=290 src="../images/CPVmodulePers.gif"></td>
632 <td><img height=300 width=290 src="../images/CPVmoduleSide.gif"></td>
638 Geant3 geometry tree of PHOS-CPV in ALICE
641 <img height=300 width=290 src="../images/CPVtree.gif">
646 Float_t par[3], x,y,z;
648 // Get pointer to the array containing media indexes
649 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
651 AliPHOSGeometry * geom = GetGeometry() ;
653 // The box containing all CPV for one PHOS module filled with air
654 par[0] = geom->GetCPVBoxSize(0) / 2.0 ;
655 par[1] = geom->GetCPVBoxSize(1) / 2.0 ;
656 par[2] = geom->GetCPVBoxSize(2) / 2.0 ;
657 gMC->Gsvolu("PCPV", "BOX ", idtmed[798], par, 3) ;
659 Float_t * emcParams = geom->GetEMCAGeometry()->GetEMCParams() ;
662 AliMatrix(rotm, 90.,0., 0., 0., 90., 90.) ;
664 gMC->Gspos("PCPV", 1, "PHOS", 0.0, 0.0, z, rotm, "ONLY") ;
668 par[0] = geom->GetGassiplexChipSize(0)/2.;
669 par[1] = geom->GetGassiplexChipSize(1)/2.;
670 par[2] = geom->GetGassiplexChipSize(2)/2.;
671 gMC->Gsvolu("PCPC","BOX ",idtmed[707],par,3);
673 // Cu+Ni foil covers Gassiplex board
675 par[1] = geom->GetCPVCuNiFoilThickness()/2;
676 gMC->Gsvolu("PCPD","BOX ",idtmed[710],par,3);
677 y = -(geom->GetGassiplexChipSize(1)/2 - par[1]);
678 gMC->Gspos("PCPD",1,"PCPC",0,y,0,0,"ONLY");
680 // Position of the chip inside CPV
682 Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
683 Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ() + 1);
685 y = geom->GetCPVFrameSize(1)/2 - geom->GetFTPosition(0) +
686 geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
687 for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
688 x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
689 for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
691 z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
692 gMC->Gspos("PCPC",copy,"PCPV",x,y,z,0,"ONLY");
696 // Foiled textolite (1 mm of textolite + 50 mkm of Cu + 6 mkm of Ni)
698 par[0] = geom->GetCPVActiveSize(0) / 2;
699 par[1] = geom->GetCPVTextoliteThickness() / 2;
700 par[2] = geom->GetCPVActiveSize(1) / 2;
701 gMC->Gsvolu("PCPF","BOX ",idtmed[707],par,3);
705 par[1] = (geom->GetFTPosition(2) - geom->GetFTPosition(1) - geom->GetCPVTextoliteThickness()) / 2;
706 gMC->Gsvolu("PCPG","BOX ",idtmed[715],par,3);
708 for (Int_t i=0; i<4; i++) {
709 y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(i) + geom->GetCPVTextoliteThickness()/2;
710 gMC->Gspos("PCPF",i+1,"PCPV",0,y,0,0,"ONLY");
712 y-= (geom->GetFTPosition(2) - geom->GetFTPosition(1)) / 2;
713 gMC->Gspos("PCPG",1,"PCPV ",0,y,0,0,"ONLY");
717 // Dummy sensitive plane in the middle of argone gas volume
720 gMC->Gsvolu("PCPQ","BOX ",idtmed[715],par,3);
721 gMC->Gspos ("PCPQ",1,"PCPG",0,0,0,0,"ONLY");
723 // Cu+Ni foil covers textolite
725 par[1] = geom->GetCPVCuNiFoilThickness() / 2;
726 gMC->Gsvolu("PCP1","BOX ",idtmed[710],par,3);
727 y = geom->GetCPVTextoliteThickness()/2 - par[1];
728 gMC->Gspos ("PCP1",1,"PCPF",0,y,0,0,"ONLY");
730 // Aluminum frame around CPV
732 par[0] = geom->GetCPVFrameSize(0)/2;
733 par[1] = geom->GetCPVFrameSize(1)/2;
734 par[2] = geom->GetCPVBoxSize(2) /2;
735 gMC->Gsvolu("PCF1","BOX ",idtmed[701],par,3);
737 par[0] = geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0);
738 par[1] = geom->GetCPVFrameSize(1)/2;
739 par[2] = geom->GetCPVFrameSize(2)/2;
740 gMC->Gsvolu("PCF2","BOX ",idtmed[701],par,3);
742 for (Int_t j=0; j<=1; j++) {
743 x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
744 gMC->Gspos("PCF1",j+1,"PCPV", x,0,0,0,"ONLY");
745 z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
746 gMC->Gspos("PCF2",j+1,"PCPV",0, 0,z,0,"ONLY");
752 //____________________________________________________________________________
753 void AliPHOSv0::CreateGeometryforSupport()
755 // Create the PHOS' support geometry for GEANT
759 Geant3 geometry of the PHOS's support
762 <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/PHOS_support.gif">
767 Float_t par[5], x0,y0,z0 ;
770 // Get pointer to the array containing media indexes
771 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
773 AliPHOSGeometry * geom = GetGeometry() ;
775 // --- Dummy box containing two rails on which PHOS support moves
776 // --- Put these rails to the bottom of the L3 magnet
778 par[0] = geom->GetRailRoadSize(0) / 2.0 ;
779 par[1] = geom->GetRailRoadSize(1) / 2.0 ;
780 par[2] = geom->GetRailRoadSize(2) / 2.0 ;
781 gMC->Gsvolu("PRRD", "BOX ", idtmed[798], par, 3) ;
783 y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) / 2.0) ;
784 gMC->Gspos("PRRD", 1, "ALIC", 0.0, y0, 0.0, 0, "ONLY") ;
786 // --- Dummy box containing one rail
788 par[0] = geom->GetRailOuterSize(0) / 2.0 ;
789 par[1] = geom->GetRailOuterSize(1) / 2.0 ;
790 par[2] = geom->GetRailOuterSize(2) / 2.0 ;
791 gMC->Gsvolu("PRAI", "BOX ", idtmed[798], par, 3) ;
793 for (i=0; i<2; i++) {
794 x0 = (2*i-1) * geom->GetDistanceBetwRails() / 2.0 ;
795 gMC->Gspos("PRAI", i, "PRRD", x0, 0.0, 0.0, 0, "ONLY") ;
798 // --- Upper and bottom steel parts of the rail
800 par[0] = geom->GetRailPart1(0) / 2.0 ;
801 par[1] = geom->GetRailPart1(1) / 2.0 ;
802 par[2] = geom->GetRailPart1(2) / 2.0 ;
803 gMC->Gsvolu("PRP1", "BOX ", idtmed[716], par, 3) ;
805 y0 = - (geom->GetRailOuterSize(1) - geom->GetRailPart1(1)) / 2.0 ;
806 gMC->Gspos("PRP1", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
807 y0 = (geom->GetRailOuterSize(1) - geom->GetRailPart1(1)) / 2.0 - geom->GetRailPart3(1);
808 gMC->Gspos("PRP1", 2, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
810 // --- The middle vertical steel parts of the rail
812 par[0] = geom->GetRailPart2(0) / 2.0 ;
813 par[1] = geom->GetRailPart2(1) / 2.0 ;
814 par[2] = geom->GetRailPart2(2) / 2.0 ;
815 gMC->Gsvolu("PRP2", "BOX ", idtmed[716], par, 3) ;
817 y0 = - geom->GetRailPart3(1) / 2.0 ;
818 gMC->Gspos("PRP2", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
820 // --- The most upper steel parts of the rail
822 par[0] = geom->GetRailPart3(0) / 2.0 ;
823 par[1] = geom->GetRailPart3(1) / 2.0 ;
824 par[2] = geom->GetRailPart3(2) / 2.0 ;
825 gMC->Gsvolu("PRP3", "BOX ", idtmed[716], par, 3) ;
827 y0 = (geom->GetRailOuterSize(1) - geom->GetRailPart3(1)) / 2.0 ;
828 gMC->Gspos("PRP3", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
830 // --- The wall of the cradle
831 // --- The wall is empty: steel thin walls and air inside
833 par[1] = TMath::Sqrt(TMath::Power((geom->GetIPtoCPVDistance() + geom->GetOuterBoxSize(3)),2) +
834 TMath::Power((geom->GetOuterBoxSize(1)/2),2))+10. ;
835 par[0] = par[1] - geom->GetCradleWall(1) ;
836 par[2] = geom->GetCradleWall(2) / 2.0 ;
837 par[3] = geom->GetCradleWall(3) ;
838 par[4] = geom->GetCradleWall(4) ;
839 gMC->Gsvolu("PCRA", "TUBS", idtmed[716], par, 5) ;
841 par[0] += geom->GetCradleWallThickness() ;
842 par[1] -= geom->GetCradleWallThickness() ;
843 par[2] -= geom->GetCradleWallThickness() ;
844 gMC->Gsvolu("PCRE", "TUBS", idtmed[798], par, 5) ;
845 gMC->Gspos ("PCRE", 1, "PCRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
847 for (i=0; i<2; i++) {
848 z0 = (2*i-1) * (geom->GetOuterBoxSize(2) + geom->GetCradleWall(2) )/ 2.0 ;
849 gMC->Gspos("PCRA", i, "ALIC", 0.0, 0.0, z0, 0, "ONLY") ;
852 // --- The "wheels" of the cradle
854 par[0] = geom->GetCradleWheel(0) / 2;
855 par[1] = geom->GetCradleWheel(1) / 2;
856 par[2] = geom->GetCradleWheel(2) / 2;
857 gMC->Gsvolu("PWHE", "BOX ", idtmed[716], par, 3) ;
859 y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) -
860 geom->GetCradleWheel(1)/2) ;
861 for (i=0; i<2; i++) {
862 z0 = (2*i-1) * ((geom->GetOuterBoxSize(2) + geom->GetCradleWheel(2))/ 2.0 +
863 geom->GetCradleWall(2));
864 for (j=0; j<2; j++) {
866 x0 = (2*j-1) * geom->GetDistanceBetwRails() / 2.0 ;
867 gMC->Gspos("PWHE", copy, "ALIC", x0, y0, z0, 0, "ONLY") ;
873 //_____________________________________________________________________________
874 void AliPHOSv0::AddAlignableVolumes() const
877 // Create entries for alignable volumes associating the symbolic volume
878 // name with the corresponding volume path. Needs to be syncronized with
879 // eventual changes in the geometry
880 // Alignable volumes are:
881 // 1) PHOS modules as a whole
884 // 4) Strip units (group of 2x8 crystals)
886 TString volpath, symname;
889 // Volume path /ALIC_1/PHOS_<i> => symbolic name /PHOS/Module<i>, <i>=1,2,3,4,5
891 TString physModulePath="/ALIC_1/PHOS_";
892 TString symbModuleName="PHOS/Module";
893 Int_t nModules = GetGeometry()->GetNModules();
895 for(Int_t iModule=1; iModule<=nModules; iModule++){
896 volpath = physModulePath;
898 symname = symbModuleName;
900 gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
903 // Alignable cradle walls
904 // Volume path /ALIC_1/PCRA_<i> => symbolic name /PHOS/Cradle<i>, <i>=0,1
906 TString physCradlePath="/ALIC_1/PCRA_";
907 TString symbCradleName="PHOS/Cradle";
910 for(Int_t iCradle=0; iCradle<nCradles; iCradle++){
911 volpath = physCradlePath;
913 symname = symbCradleName;
915 gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
919 // Volume path /ALIC_1/PWHE_<i> => symbolic name /PHOS/Wheel<i>, i=0,1,2,3
921 TString physWheelPath="/ALIC_1/PWHE_";
922 TString symbWheelName="PHOS/Wheel";
925 for(Int_t iWheel=0; iWheel<nWheels; iWheel++){
926 volpath = physWheelPath;
928 symname = symbWheelName;
930 gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
933 // Alignable strip units are not implemented yet (27.09.2006)
937 //____________________________________________________________________________
938 Float_t AliPHOSv0::ZMin(void) const
940 // Overall dimension of the PHOS (min)
942 AliPHOSGeometry * geom = GetGeometry() ;
944 return -geom->GetOuterBoxSize(2)/2.;
947 //____________________________________________________________________________
948 Float_t AliPHOSv0::ZMax(void) const
950 // Overall dimension of the PHOS (max)
952 AliPHOSGeometry * geom = GetGeometry() ;
954 return geom->GetOuterBoxSize(2)/2.;
957 //____________________________________________________________________________
958 void AliPHOSv0::Init(void)
960 // Just prints an information message
964 if(AliLog::GetGlobalDebugLevel()>0) {
968 Info("Init", "%s", st.Data()) ;
969 // Here the PHOS initialisation code (if any!)
971 AliPHOSGeometry * geom = GetGeometry() ;
974 Info("Init", "AliPHOS%s: PHOS geometry intialized for %s", Version().Data(), geom->GetName()) ;
976 Info("Init", "AliPHOS%s: PHOS geometry initialization failed !", Version().Data()) ;
978 Info("Init", "%s", st.Data()) ;