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.84 2006/12/20 16:56:43 kharlov
21 * Optional geometry without CPV
23 * Revision 1.83 2006/11/14 17:11:15 hristov
24 * 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
26 * Revision 1.82 2006/09/27 19:55:57 kharlov
27 * Alignment object with symbolic volume names are introduced
29 * Revision 1.81 2006/03/04 20:25:56 kharlov
30 * Set geom parameters from CDB
32 * Revision 1.80 2005/06/17 07:39:07 hristov
33 * Removing GetDebug and SetDebug from AliRun and AliModule. Using AliLog for the messages
35 * Revision 1.79 2005/05/28 14:19:05 schutz
36 * Compilation warnings fixed by T.P.
40 //_________________________________________________________________________
41 // Implementation version v0 of PHOS Manager class
42 // An object of this class does not produce hits nor digits
43 // It is the one to use if you do not want to produce outputs in TREEH or TREED
45 //*-- Author: Yves Schutz (SUBATECH) & Dmitri Peressounko (RRC KI & SUBATECH)
48 // --- ROOT system ---
52 #include <TGeometry.h>
58 #include <TVirtualMC.h>
59 #include <TGeoManager.h>
61 // --- Standard library ---
66 // --- AliRoot header files ---
69 #include "AliPHOSGeometry.h"
70 #include "AliPHOSLoader.h"
71 #include "AliPHOSv0.h"
77 //____________________________________________________________________________
78 AliPHOSv0::AliPHOSv0(const char *name, const char *title):
81 // ctor : title is used to identify the layout
85 //____________________________________________________________________________
86 void AliPHOSv0::BuildGeometry()
88 // Build the PHOS geometry for the ROOT display
92 PHOS in ALICE displayed by root
98 <IMG Align=BOTTOM ALT="All Views" SRC="../images/AliPHOSv0AllViews.gif">
103 <IMG Align=BOTTOM ALT="Front View" SRC="../images/AliPHOSv0FrontView.gif">
108 <IMG Align=BOTTOM ALT="3D View 1" SRC="../images/AliPHOSv03DView1.gif">
113 <IMG Align=BOTTOM ALT="3D View 2" SRC="../images/AliPHOSv03DView2.gif">
119 this->BuildGeometryforEMC() ;
120 this->BuildGeometryforCPV() ;
124 //____________________________________________________________________________
125 void AliPHOSv0:: BuildGeometryforEMC(void)
127 // Build the PHOS-EMC geometry for the ROOT display
129 const Int_t kColorPHOS = kRed ;
130 const Int_t kColorXTAL = kBlue ;
132 Double_t const kRADDEG = 180.0 / TMath::Pi() ;
134 AliPHOSGeometry * geom = GetGeometry() ;
135 AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
136 Float_t * boxparams = emcg->GetEMCParams() ;
138 new TTRD1("OuterBox", "PHOS box", "void",boxparams[0],boxparams[1],boxparams[2], boxparams[3] );
143 Float_t * cribox = emcg->GetInnerThermoHalfSize() ;
144 new TBRIK( "CrystalsBox", "PHOS crystals box", "void", cribox[0], cribox[2], cribox[1] ) ;
146 // position PHOS into ALICE
148 Float_t r = geom->GetIPtoOuterCoverDistance() + boxparams[3] ;
150 TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
152 char * nodename = new char[20] ;
153 char * rotname = new char[20] ;
155 new TRotMatrix("cribox", "cribox", 90, 0, 90, 90, 0, 0);
157 for( Int_t i = 1; i <= geom->GetNModules(); i++ ) {
159 Float_t angle = geom->GetPHOSAngle(i) ;
160 sprintf(rotname, "%s%d", "rot", number++) ;
161 new TRotMatrix(rotname, rotname, 90, angle, 0, 0, 90, 270 + angle);
164 sprintf(nodename,"%s%d", "Module", i) ;
165 Float_t x = r * TMath::Sin( angle / kRADDEG ) ;
166 Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
167 TNode * outerboxnode = new TNode(nodename, nodename, "OuterBox", x, y, 0, rotname ) ;
168 outerboxnode->SetLineColor(kColorPHOS) ;
169 fNodes->Add(outerboxnode) ;
172 Float_t z = -boxparams[3] - geom->GetIPtoOuterCoverDistance() +
173 cribox[1] + geom->GetIPtoCrystalSurface() ;
174 TNode * crystalsboxnode = new TNode(nodename, nodename, "CrystalsBox", 0, 0, z) ;
175 crystalsboxnode->SetLineColor(kColorXTAL) ;
176 fNodes->Add(crystalsboxnode) ;
184 //____________________________________________________________________________
185 void AliPHOSv0:: BuildGeometryforCPV(void)
187 // Build the PHOS-CPV geometry for the ROOT display
188 // Author: Yuri Kharlov 11 September 2000
193 CPV displayed by root
198 <td>CPV perspective view</td>
199 <td>CPV front view </td>
203 <td> <img height=300 width=290 src="../images/CPVRootPersp.gif"> </td>
204 <td> <img height=300 width=290 src="../images/CPVRootFront.gif"> </td>
212 const Double_t kRADDEG = 180.0 / TMath::Pi() ;
213 const Int_t kColorCPV = kGreen ;
214 const Int_t kColorFrame = kYellow ;
215 const Int_t kColorGassiplex = kRed;
216 const Int_t kColorPCB = kCyan;
218 AliPHOSGeometry * geom = GetGeometry() ;
220 // Box for a full PHOS module
222 new TBRIK ("CPVBox", "CPV box", "void", geom->GetCPVBoxSize(0)/2,
223 geom->GetCPVBoxSize(1)/2,
224 geom->GetCPVBoxSize(2)/2 );
225 new TBRIK ("CPVFrameLR", "CPV frame Left-Right", "void", geom->GetCPVFrameSize(0)/2,
226 geom->GetCPVFrameSize(1)/2,
227 geom->GetCPVBoxSize(2)/2 );
228 new TBRIK ("CPVFrameUD", "CPV frame Up-Down", "void", geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0),
229 geom->GetCPVFrameSize(1)/2,
230 geom->GetCPVFrameSize(2)/2);
231 new TBRIK ("CPVPCB", "CPV PCB", "void", geom->GetCPVActiveSize(0)/2,
232 geom->GetCPVTextoliteThickness()/2,
233 geom->GetCPVActiveSize(1)/2);
234 new TBRIK ("CPVGassiplex", "CPV Gassiplex PCB", "void", geom->GetGassiplexChipSize(0)/2,
235 geom->GetGassiplexChipSize(1)/2,
236 geom->GetGassiplexChipSize(2)/2);
238 // position CPV into ALICE
240 char * nodename = new char[25] ;
241 char * rotname = new char[25] ;
243 Float_t r = geom->GetIPtoCPVDistance() + geom->GetCPVBoxSize(1) / 2.0 ;
245 TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
247 Int_t lastModule = 0 ;
248 lastModule = geom->GetNModules();
250 for( Int_t i = 1; i <= lastModule; i++ ) { // the number of PHOS modules
254 Float_t angle = geom->GetPHOSAngle(i) ;
255 sprintf(rotname, "%s%d", "rotg", number+i) ;
256 new TRotMatrix(rotname, rotname, 90, angle, 90, 90 + angle, 0, 0);
258 sprintf(nodename, "%s%d", "CPVModule", i) ;
259 Float_t x = r * TMath::Sin( angle / kRADDEG ) ;
260 Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
262 TNode * cpvBoxNode = new TNode(nodename , nodename ,"CPVBox", x, y, 0, rotname ) ;
263 cpvBoxNode->SetLineColor(kColorCPV) ;
264 fNodes->Add(cpvBoxNode) ;
267 // inside each CPV box:
271 for (j=0; j<=1; j++) {
272 sprintf(nodename, "CPVModule%d Frame%d", i, j+1) ;
273 x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
274 TNode * cpvFrameNode = new TNode(nodename , nodename ,"CPVFrameLR", x, 0, 0) ;
275 cpvFrameNode->SetLineColor(kColorFrame) ;
276 fNodes->Add(cpvFrameNode) ;
278 sprintf(nodename, "CPVModule%d Frame%d", i, j+3) ;
279 z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
280 cpvFrameNode = new TNode(nodename , nodename ,"CPVFrameUD", 0, 0, z) ;
281 cpvFrameNode->SetLineColor(kColorFrame) ;
282 fNodes->Add(cpvFrameNode) ;
285 // 4 printed circuit boards
286 for (j=0; j<4; j++) {
287 sprintf(nodename, "CPVModule%d PCB%d", i, j+1) ;
288 y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(j) + geom->GetCPVTextoliteThickness()/2;
289 TNode * cpvPCBNode = new TNode(nodename , nodename ,"CPVPCB", 0, y, 0) ;
290 cpvPCBNode->SetLineColor(kColorPCB) ;
291 fNodes->Add(cpvPCBNode) ;
295 Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
296 Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ() + 1);
297 y = geom->GetCPVFrameSize(1)/2 - geom->GetFTPosition(0) +
298 geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
299 for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
300 x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
301 for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
302 z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
303 sprintf(nodename, "CPVModule%d Chip(%dx%d)", i, ix+1,iz+1) ;
304 TNode * cpvGassiplexNode = new TNode(nodename , nodename ,"CPVGassiplex", x, y, z) ;
305 cpvGassiplexNode->SetLineColor(kColorGassiplex) ;
306 fNodes->Add(cpvGassiplexNode) ;
316 //____________________________________________________________________________
317 void AliPHOSv0::CreateGeometry()
319 // Create the PHOS geometry for Geant
321 AliPHOSv0 *phostmp = dynamic_cast<AliPHOSv0*>(gAlice->GetModule("PHOS")) ;
323 if ( phostmp == NULL ) {
325 fprintf(stderr, "PHOS detector not found!\n") ;
330 AliPHOSGeometry * geom = GetGeometry() ;
332 // Get pointer to the array containing media indeces
333 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
335 // Create a PHOS module.
337 gMC->Gsvolu("PHOS", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;
339 this->CreateGeometryforEMC() ;
341 if (strstr(fTitle.Data(),"noCPV") == 0)
342 this->CreateGeometryforCPV() ;
344 this->CreateGeometryforSupport() ;
346 // --- Position PHOS mdules in ALICE setup ---
350 for (Int_t iModule = 0; iModule < geom->GetNModules(); iModule++ ) {
353 for (iXYZ=0; iXYZ<3; iXYZ++)
354 for (iAngle=0; iAngle<2; iAngle++)
355 angle[iXYZ][iAngle] = geom->GetModuleAngle(iModule,iXYZ, iAngle);
356 AliMatrix(idrotm[iModule],
357 angle[0][0],angle[0][1],
358 angle[1][0],angle[1][1],
359 angle[2][0],angle[2][1]) ;
362 for (iXYZ=0; iXYZ<3; iXYZ++)
363 pos[iXYZ] = geom->GetModuleCenter(iModule,iXYZ);
364 gMC->Gspos("PHOS", iModule+1, "ALIC", pos[0], pos[1], pos[2],
365 idrotm[iModule], "ONLY") ;
370 //____________________________________________________________________________
371 void AliPHOSv0::CreateGeometryforEMC()
373 // Create the PHOS-EMC geometry for GEANT
374 // Author: Dmitri Peressounko August 2001
375 // The used coordinate system:
376 // 1. in Module: X along longer side, Y out of beam, Z along shorter side (along beam)
377 // 2. In Strip the same: X along longer side, Y out of beam, Z along shorter side (along beam)
383 Geant3 geometry tree of PHOS-EMC in ALICE
386 <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/EMCinAlice.gif">
391 // Get pointer to the array containing media indexes
392 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
394 AliPHOSGeometry * geom = GetGeometry() ;
395 AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
397 // ======= Define the strip ===============
399 gMC->Gsvolu("PSTR", "BOX ", idtmed[716], emcg->GetStripHalfSize(), 3) ; //Made of stell
401 // --- define air volume (cell of the honeycomb)
402 gMC->Gsvolu("PCEL", "BOX ", idtmed[798], emcg->GetAirCellHalfSize(), 3);
404 // --- define wrapped crystal and put it into AirCell
406 gMC->Gsvolu("PWRA", "BOX ", idtmed[702], emcg->GetWrappedHalfSize(), 3);
407 Float_t * pin = emcg->GetAPDHalfSize() ;
408 Float_t * preamp = emcg->GetPreampHalfSize() ;
409 Float_t y = (emcg->GetAirGapLed()-2*pin[1]-2*preamp[1])/2;
410 gMC->Gspos("PWRA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
412 // --- Define crystall and put it into wrapped crystall ---
413 gMC->Gsvolu("PXTL", "BOX ", idtmed[699], emcg->GetCrystalHalfSize(), 3) ;
414 gMC->Gspos("PXTL", 1, "PWRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
416 // --- define APD/PIN preamp and put it into AirCell
418 gMC->Gsvolu("PPIN", "BOX ", idtmed[705], emcg->GetAPDHalfSize(), 3) ;
419 Float_t * crystal = emcg->GetCrystalHalfSize() ;
420 y = crystal[1] + emcg->GetAirGapLed() /2 - preamp[1];
421 gMC->Gspos("PPIN", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
423 gMC->Gsvolu("PREA", "BOX ", idtmed[711], emcg->GetPreampHalfSize(), 3) ; // Here I assumed preamp
424 // as a printed Circuit
425 y = crystal[1] + emcg->GetAirGapLed() /2 + pin[1] ; // May it should be changed
426 gMC->Gspos("PREA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ; // to ceramics?
429 // --- Fill strip with wrapped cristalls in Air Cells
431 Float_t* splate = emcg->GetSupportPlateHalfSize();
433 Float_t* acel = emcg->GetAirCellHalfSize() ;
436 for(Int_t lev = 2, icel = 1; icel <= emcg->GetNCellsXInStrip()*emcg->GetNCellsZInStrip(); icel += 2, lev += 2){
437 Float_t x = (2*(lev / 2) - 1 - emcg->GetNCellsXInStrip())* acel[0] ;
439 gMC->Gspos("PCEL", icel, "PSTR", x, y, +z, 0, "ONLY") ;
440 gMC->Gspos("PCEL", icel + 1, "PSTR", x, y, -z, 0, "ONLY") ;
443 // --- define the support plate, hole in it and position it in strip ----
444 gMC->Gsvolu("PSUP", "BOX ", idtmed[701], emcg->GetSupportPlateHalfSize(), 3) ;
446 gMC->Gsvolu("PSHO", "BOX ", idtmed[798], emcg->GetSupportPlateInHalfSize(), 3) ;
447 Float_t z = emcg->GetSupportPlateThickness()/2 ;
448 gMC->Gspos("PSHO", 1, "PSUP", 0.0, 0.0, z, 0, "ONLY") ;
451 gMC->Gspos("PSUP", 1, "PSTR", 0.0, y, 0.0, 0, "ONLY") ;
454 // ========== Fill module with strips and put them into inner thermoinsulation=============
455 gMC->Gsvolu("PTII", "BOX ", idtmed[706], emcg->GetInnerThermoHalfSize(), 3) ;
457 Float_t * inthermo = emcg->GetInnerThermoHalfSize() ;
458 Float_t * strip = emcg->GetStripHalfSize() ;
459 y = inthermo[1] - strip[1] ;
464 for(irow = 0; irow < emcg->GetNStripX(); irow ++){
465 Float_t x = (2*irow + 1 - emcg->GetNStripX())* strip[0] ;
466 for(icol = 0; icol < emcg->GetNStripZ(); icol ++){
467 z = (2*icol + 1 - emcg->GetNStripZ()) * strip[2] ;
468 gMC->Gspos("PSTR", nr, "PTII", x, y, z, 0, "ONLY") ;
474 // ------- define the air gap between thermoinsulation and cooler
475 gMC->Gsvolu("PAGA", "BOX ", idtmed[798], emcg->GetAirGapHalfSize(), 3) ;
476 Float_t * agap = emcg->GetAirGapHalfSize() ;
477 y = agap[1] - inthermo[1] ;
479 gMC->Gspos("PTII", 1, "PAGA", 0.0, y, 0.0, 0, "ONLY") ;
483 // ------- define the Al passive cooler
484 gMC->Gsvolu("PCOR", "BOX ", idtmed[701], emcg->GetCoolerHalfSize(), 3) ;
485 Float_t * cooler = emcg->GetCoolerHalfSize() ;
486 y = cooler[1] - agap[1] ;
488 gMC->Gspos("PAGA", 1, "PCOR", 0.0, y, 0.0, 0, "ONLY") ;
490 // ------- define the outer thermoinsulating cover
491 gMC->Gsvolu("PTIO", "TRD1", idtmed[706], emcg->GetOuterThermoParams(), 4) ;
492 Float_t * outparams = emcg->GetOuterThermoParams() ;
495 AliMatrix(idrotm[1], 90.0, 0.0, 0.0, 0.0, 90.0, 270.0) ;
496 // Frame in outer thermoinsulation and so on: z out of beam, y along beam, x across beam
498 z = outparams[3] - cooler[1] ;
499 gMC->Gspos("PCOR", 1, "PTIO", 0., 0.0, z, idrotm[1], "ONLY") ;
501 // -------- Define the outer Aluminium cover -----
502 gMC->Gsvolu("PCOL", "TRD1", idtmed[701], emcg->GetAlCoverParams(), 4) ;
503 Float_t * covparams = emcg->GetAlCoverParams() ;
504 z = covparams[3] - outparams[3] ;
505 gMC->Gspos("PTIO", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
507 // --------- Define front fiberglass cover -----------
508 gMC->Gsvolu("PFGC", "BOX ", idtmed[717], emcg->GetFiberGlassHalfSize(), 3) ;
510 gMC->Gspos("PFGC", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
512 //=============This is all with cold section==============
515 //------ Warm Section --------------
516 gMC->Gsvolu("PWAR", "BOX ", idtmed[701], emcg->GetWarmAlCoverHalfSize(), 3) ;
517 Float_t * warmcov = emcg->GetWarmAlCoverHalfSize() ;
519 // --- Define the outer thermoinsulation ---
520 gMC->Gsvolu("PWTI", "BOX ", idtmed[706], emcg->GetWarmThermoHalfSize(), 3) ;
521 Float_t * warmthermo = emcg->GetWarmThermoHalfSize() ;
522 z = -warmcov[2] + warmthermo[2] ;
524 gMC->Gspos("PWTI", 1, "PWAR", 0., 0.0, z, 0, "ONLY") ;
526 // --- Define cables area and put in it T-supports ----
527 gMC->Gsvolu("PCA1", "BOX ", idtmed[718], emcg->GetTCables1HalfSize(), 3) ;
528 Float_t * cbox = emcg->GetTCables1HalfSize() ;
530 gMC->Gsvolu("PBE1", "BOX ", idtmed[701], emcg->GetTSupport1HalfSize(), 3) ;
531 Float_t * beams = emcg->GetTSupport1HalfSize() ;
533 for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
534 Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
535 gMC->Gspos("PBE1", isup, "PCA1", x, 0.0, 0.0, 0, "ONLY") ;
538 z = -warmthermo[2] + cbox[2] ;
539 gMC->Gspos("PCA1", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;
541 gMC->Gsvolu("PCA2", "BOX ", idtmed[718], emcg->GetTCables2HalfSize(), 3) ;
542 Float_t * cbox2 = emcg->GetTCables2HalfSize() ;
544 gMC->Gsvolu("PBE2", "BOX ", idtmed[701], emcg->GetTSupport2HalfSize(), 3) ;
545 for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
546 Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
547 gMC->Gspos("PBE2", isup, "PCA2", x, 0.0, 0.0, 0, "ONLY") ;
550 z = -warmthermo[2] + 2*cbox[2] + cbox2[2];
551 gMC->Gspos("PCA2", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;
554 // --- Define frame ---
555 gMC->Gsvolu("PFRX", "BOX ", idtmed[716], emcg->GetFrameXHalfSize(), 3) ;
556 Float_t * posit = emcg->GetFrameXPosition() ;
557 gMC->Gspos("PFRX", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
558 gMC->Gspos("PFRX", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
560 gMC->Gsvolu("PFRZ", "BOX ", idtmed[716], emcg->GetFrameZHalfSize(), 3) ;
561 posit = emcg->GetFrameZPosition() ;
562 gMC->Gspos("PFRZ", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
563 gMC->Gspos("PFRZ", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
565 // --- Define Fiber Glass support ---
566 gMC->Gsvolu("PFG1", "BOX ", idtmed[717], emcg->GetFGupXHalfSize(), 3) ;
567 posit = emcg->GetFGupXPosition() ;
568 gMC->Gspos("PFG1", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
569 gMC->Gspos("PFG1", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
571 gMC->Gsvolu("PFG2", "BOX ", idtmed[717], emcg->GetFGupZHalfSize(), 3) ;
572 posit = emcg->GetFGupZPosition() ;
573 gMC->Gspos("PFG2", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
574 gMC->Gspos("PFG2", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
576 gMC->Gsvolu("PFG3", "BOX ", idtmed[717], emcg->GetFGlowXHalfSize(), 3) ;
577 posit = emcg->GetFGlowXPosition() ;
578 gMC->Gspos("PFG3", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
579 gMC->Gspos("PFG3", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
581 gMC->Gsvolu("PFG4", "BOX ", idtmed[717], emcg->GetFGlowZHalfSize(), 3) ;
582 posit = emcg->GetFGlowZPosition() ;
583 gMC->Gspos("PFG4", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
584 gMC->Gspos("PFG4", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
586 // --- Define Air Gap for FEE electronics -----
588 gMC->Gsvolu("PAFE", "BOX ", idtmed[798], emcg->GetFEEAirHalfSize(), 3) ;
589 posit = emcg->GetFEEAirPosition() ;
590 gMC->Gspos("PAFE", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
592 // Define the EMC module volume and combine Cool and Warm sections
594 gMC->Gsvolu("PEMC", "TRD1", idtmed[798], emcg->GetEMCParams(), 4) ;
597 gMC->Gspos("PCOL", 1, "PEMC", 0., 0., z, 0, "ONLY") ;
599 gMC->Gspos("PWAR", 1, "PEMC", 0., 0., z, 0, "ONLY") ;
602 // Put created EMC geometry into PHOS volume
604 z = geom->GetCPVBoxSize(1) / 2. ;
605 gMC->Gspos("PEMC", 1, "PHOS", 0., 0., z, 0, "ONLY") ;
609 //____________________________________________________________________________
610 void AliPHOSv0::CreateGeometryforCPV()
612 // Create the PHOS-CPV geometry for GEANT
613 // Author: Yuri Kharlov 11 September 2000
617 Geant3 geometry of PHOS-CPV in ALICE
622 <td>CPV perspective view</td>
623 <td>CPV front view </td>
627 <td> <img height=300 width=290 src="../images/CPVallPersp.gif"> </td>
628 <td> <img height=300 width=290 src="../images/CPVallFront.gif"> </td>
632 <td>One CPV module, perspective view </td>
633 <td>One CPV module, front view (extended in vertical direction) </td>
637 <td><img height=300 width=290 src="../images/CPVmodulePers.gif"></td>
638 <td><img height=300 width=290 src="../images/CPVmoduleSide.gif"></td>
644 Geant3 geometry tree of PHOS-CPV in ALICE
647 <img height=300 width=290 src="../images/CPVtree.gif">
652 Float_t par[3], x,y,z;
654 // Get pointer to the array containing media indexes
655 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
657 AliPHOSGeometry * geom = GetGeometry() ;
659 // The box containing all CPV for one PHOS module filled with air
660 par[0] = geom->GetCPVBoxSize(0) / 2.0 ;
661 par[1] = geom->GetCPVBoxSize(1) / 2.0 ;
662 par[2] = geom->GetCPVBoxSize(2) / 2.0 ;
663 gMC->Gsvolu("PCPV", "BOX ", idtmed[798], par, 3) ;
665 Float_t * emcParams = geom->GetEMCAGeometry()->GetEMCParams() ;
668 AliMatrix(rotm, 90.,0., 0., 0., 90., 90.) ;
670 gMC->Gspos("PCPV", 1, "PHOS", 0.0, 0.0, z, rotm, "ONLY") ;
674 par[0] = geom->GetGassiplexChipSize(0)/2.;
675 par[1] = geom->GetGassiplexChipSize(1)/2.;
676 par[2] = geom->GetGassiplexChipSize(2)/2.;
677 gMC->Gsvolu("PCPC","BOX ",idtmed[707],par,3);
679 // Cu+Ni foil covers Gassiplex board
681 par[1] = geom->GetCPVCuNiFoilThickness()/2;
682 gMC->Gsvolu("PCPD","BOX ",idtmed[710],par,3);
683 y = -(geom->GetGassiplexChipSize(1)/2 - par[1]);
684 gMC->Gspos("PCPD",1,"PCPC",0,y,0,0,"ONLY");
686 // Position of the chip inside CPV
688 Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
689 Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ() + 1);
691 y = geom->GetCPVFrameSize(1)/2 - geom->GetFTPosition(0) +
692 geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
693 for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
694 x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
695 for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
697 z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
698 gMC->Gspos("PCPC",copy,"PCPV",x,y,z,0,"ONLY");
702 // Foiled textolite (1 mm of textolite + 50 mkm of Cu + 6 mkm of Ni)
704 par[0] = geom->GetCPVActiveSize(0) / 2;
705 par[1] = geom->GetCPVTextoliteThickness() / 2;
706 par[2] = geom->GetCPVActiveSize(1) / 2;
707 gMC->Gsvolu("PCPF","BOX ",idtmed[707],par,3);
711 par[1] = (geom->GetFTPosition(2) - geom->GetFTPosition(1) - geom->GetCPVTextoliteThickness()) / 2;
712 gMC->Gsvolu("PCPG","BOX ",idtmed[715],par,3);
714 for (Int_t i=0; i<4; i++) {
715 y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(i) + geom->GetCPVTextoliteThickness()/2;
716 gMC->Gspos("PCPF",i+1,"PCPV",0,y,0,0,"ONLY");
718 y-= (geom->GetFTPosition(2) - geom->GetFTPosition(1)) / 2;
719 gMC->Gspos("PCPG",1,"PCPV ",0,y,0,0,"ONLY");
723 // Dummy sensitive plane in the middle of argone gas volume
726 gMC->Gsvolu("PCPQ","BOX ",idtmed[715],par,3);
727 gMC->Gspos ("PCPQ",1,"PCPG",0,0,0,0,"ONLY");
729 // Cu+Ni foil covers textolite
731 par[1] = geom->GetCPVCuNiFoilThickness() / 2;
732 gMC->Gsvolu("PCP1","BOX ",idtmed[710],par,3);
733 y = geom->GetCPVTextoliteThickness()/2 - par[1];
734 gMC->Gspos ("PCP1",1,"PCPF",0,y,0,0,"ONLY");
736 // Aluminum frame around CPV
738 par[0] = geom->GetCPVFrameSize(0)/2;
739 par[1] = geom->GetCPVFrameSize(1)/2;
740 par[2] = geom->GetCPVBoxSize(2) /2;
741 gMC->Gsvolu("PCF1","BOX ",idtmed[701],par,3);
743 par[0] = geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0);
744 par[1] = geom->GetCPVFrameSize(1)/2;
745 par[2] = geom->GetCPVFrameSize(2)/2;
746 gMC->Gsvolu("PCF2","BOX ",idtmed[701],par,3);
748 for (Int_t j=0; j<=1; j++) {
749 x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
750 gMC->Gspos("PCF1",j+1,"PCPV", x,0,0,0,"ONLY");
751 z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
752 gMC->Gspos("PCF2",j+1,"PCPV",0, 0,z,0,"ONLY");
758 //____________________________________________________________________________
759 void AliPHOSv0::CreateGeometryforSupport()
761 // Create the PHOS' support geometry for GEANT
765 Geant3 geometry of the PHOS's support
768 <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/PHOS_support.gif">
773 Float_t par[5], x0,y0,z0 ;
776 // Get pointer to the array containing media indexes
777 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
779 AliPHOSGeometry * geom = GetGeometry() ;
781 // --- Dummy box containing two rails on which PHOS support moves
782 // --- Put these rails to the bottom of the L3 magnet
784 par[0] = geom->GetRailRoadSize(0) / 2.0 ;
785 par[1] = geom->GetRailRoadSize(1) / 2.0 ;
786 par[2] = geom->GetRailRoadSize(2) / 2.0 ;
787 gMC->Gsvolu("PRRD", "BOX ", idtmed[798], par, 3) ;
789 y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) / 2.0) ;
790 gMC->Gspos("PRRD", 1, "ALIC", 0.0, y0, 0.0, 0, "ONLY") ;
792 // --- Dummy box containing one rail
794 par[0] = geom->GetRailOuterSize(0) / 2.0 ;
795 par[1] = geom->GetRailOuterSize(1) / 2.0 ;
796 par[2] = geom->GetRailOuterSize(2) / 2.0 ;
797 gMC->Gsvolu("PRAI", "BOX ", idtmed[798], par, 3) ;
799 for (i=0; i<2; i++) {
800 x0 = (2*i-1) * geom->GetDistanceBetwRails() / 2.0 ;
801 gMC->Gspos("PRAI", i, "PRRD", x0, 0.0, 0.0, 0, "ONLY") ;
804 // --- Upper and bottom steel parts of the rail
806 par[0] = geom->GetRailPart1(0) / 2.0 ;
807 par[1] = geom->GetRailPart1(1) / 2.0 ;
808 par[2] = geom->GetRailPart1(2) / 2.0 ;
809 gMC->Gsvolu("PRP1", "BOX ", idtmed[716], par, 3) ;
811 y0 = - (geom->GetRailOuterSize(1) - geom->GetRailPart1(1)) / 2.0 ;
812 gMC->Gspos("PRP1", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
813 y0 = (geom->GetRailOuterSize(1) - geom->GetRailPart1(1)) / 2.0 - geom->GetRailPart3(1);
814 gMC->Gspos("PRP1", 2, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
816 // --- The middle vertical steel parts of the rail
818 par[0] = geom->GetRailPart2(0) / 2.0 ;
819 par[1] = geom->GetRailPart2(1) / 2.0 ;
820 par[2] = geom->GetRailPart2(2) / 2.0 ;
821 gMC->Gsvolu("PRP2", "BOX ", idtmed[716], par, 3) ;
823 y0 = - geom->GetRailPart3(1) / 2.0 ;
824 gMC->Gspos("PRP2", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
826 // --- The most upper steel parts of the rail
828 par[0] = geom->GetRailPart3(0) / 2.0 ;
829 par[1] = geom->GetRailPart3(1) / 2.0 ;
830 par[2] = geom->GetRailPart3(2) / 2.0 ;
831 gMC->Gsvolu("PRP3", "BOX ", idtmed[716], par, 3) ;
833 y0 = (geom->GetRailOuterSize(1) - geom->GetRailPart3(1)) / 2.0 ;
834 gMC->Gspos("PRP3", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
836 // --- The wall of the cradle
837 // --- The wall is empty: steel thin walls and air inside
839 par[1] = TMath::Sqrt(TMath::Power((geom->GetIPtoCPVDistance() + geom->GetOuterBoxSize(3)),2) +
840 TMath::Power((geom->GetOuterBoxSize(1)/2),2))+10. ;
841 par[0] = par[1] - geom->GetCradleWall(1) ;
842 par[2] = geom->GetCradleWall(2) / 2.0 ;
843 par[3] = geom->GetCradleWall(3) ;
844 par[4] = geom->GetCradleWall(4) ;
845 gMC->Gsvolu("PCRA", "TUBS", idtmed[716], par, 5) ;
847 par[0] += geom->GetCradleWallThickness() ;
848 par[1] -= geom->GetCradleWallThickness() ;
849 par[2] -= geom->GetCradleWallThickness() ;
850 gMC->Gsvolu("PCRE", "TUBS", idtmed[798], par, 5) ;
851 gMC->Gspos ("PCRE", 1, "PCRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
853 for (i=0; i<2; i++) {
854 z0 = (2*i-1) * (geom->GetOuterBoxSize(2) + geom->GetCradleWall(2) )/ 2.0 ;
855 gMC->Gspos("PCRA", i, "ALIC", 0.0, 0.0, z0, 0, "ONLY") ;
858 // --- The "wheels" of the cradle
860 par[0] = geom->GetCradleWheel(0) / 2;
861 par[1] = geom->GetCradleWheel(1) / 2;
862 par[2] = geom->GetCradleWheel(2) / 2;
863 gMC->Gsvolu("PWHE", "BOX ", idtmed[716], par, 3) ;
865 y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) -
866 geom->GetCradleWheel(1)/2) ;
867 for (i=0; i<2; i++) {
868 z0 = (2*i-1) * ((geom->GetOuterBoxSize(2) + geom->GetCradleWheel(2))/ 2.0 +
869 geom->GetCradleWall(2));
870 for (j=0; j<2; j++) {
872 x0 = (2*j-1) * geom->GetDistanceBetwRails() / 2.0 ;
873 gMC->Gspos("PWHE", copy, "ALIC", x0, y0, z0, 0, "ONLY") ;
879 //_____________________________________________________________________________
880 void AliPHOSv0::AddAlignableVolumes() const
883 // Create entries for alignable volumes associating the symbolic volume
884 // name with the corresponding volume path. Needs to be syncronized with
885 // eventual changes in the geometry
886 // Alignable volumes are:
887 // 1) PHOS modules as a whole
890 // 4) Strip units (group of 2x8 crystals)
892 TString volpath, symname;
895 // Volume path /ALIC_1/PHOS_<i> => symbolic name /PHOS/Module<i>, <i>=1,2,3,4,5
897 TString physModulePath="/ALIC_1/PHOS_";
898 TString symbModuleName="PHOS/Module";
899 Int_t nModules = GetGeometry()->GetNModules();
901 for(Int_t iModule=1; iModule<=nModules; iModule++){
902 volpath = physModulePath;
904 symname = symbModuleName;
906 gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
909 // Alignable cradle walls
910 // Volume path /ALIC_1/PCRA_<i> => symbolic name /PHOS/Cradle<i>, <i>=0,1
912 TString physCradlePath="/ALIC_1/PCRA_";
913 TString symbCradleName="PHOS/Cradle";
916 for(Int_t iCradle=0; iCradle<nCradles; iCradle++){
917 volpath = physCradlePath;
919 symname = symbCradleName;
921 gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
925 // Volume path /ALIC_1/PWHE_<i> => symbolic name /PHOS/Wheel<i>, i=0,1,2,3
927 TString physWheelPath="/ALIC_1/PWHE_";
928 TString symbWheelName="PHOS/Wheel";
931 for(Int_t iWheel=0; iWheel<nWheels; iWheel++){
932 volpath = physWheelPath;
934 symname = symbWheelName;
936 gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
939 //Physical strip path is a combination of: physModulePath + module number +
940 //physStripPath + strip number == ALIC_1/PHOS_N/..../PSTR_M
941 const Int_t nStripsX = GetGeometry()->GetEMCAGeometry()->GetNStripX();
942 const Int_t nStripsZ = GetGeometry()->GetEMCAGeometry()->GetNStripZ();
943 TString partialPhysStripName(100);
944 TString fullPhysStripName(100);
945 TString partialSymbStripName(100);
946 TString fullSymbStripName(100);
948 for(Int_t module = 1; module <= nModules; ++module){
949 partialPhysStripName = physModulePath;
950 partialPhysStripName += module;
951 partialPhysStripName += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1/PSTR_";
953 partialSymbStripName = symbModuleName;
954 partialSymbStripName += module;
955 partialSymbStripName += "/Strip_";
957 for(Int_t i = 0, ind1D = 1; i < nStripsX; ++i){//ind1D starts from 1 (PSTR_1...PSTR_224...)
958 for(Int_t j = 0; j < nStripsZ; ++j, ++ind1D){
959 fullPhysStripName = partialPhysStripName;
960 fullPhysStripName += ind1D;
962 fullSymbStripName = partialSymbStripName;
963 fullSymbStripName += i;//ind1D;
964 fullSymbStripName += '_';
965 fullSymbStripName += j;
967 gGeoManager->SetAlignableEntry(fullSymbStripName.Data(), fullPhysStripName.Data());
973 //____________________________________________________________________________
974 Float_t AliPHOSv0::ZMin(void) const
976 // Overall dimension of the PHOS (min)
978 AliPHOSGeometry * geom = GetGeometry() ;
980 return -geom->GetOuterBoxSize(2)/2.;
983 //____________________________________________________________________________
984 Float_t AliPHOSv0::ZMax(void) const
986 // Overall dimension of the PHOS (max)
988 AliPHOSGeometry * geom = GetGeometry() ;
990 return geom->GetOuterBoxSize(2)/2.;
993 //____________________________________________________________________________
994 void AliPHOSv0::Init(void)
996 // Just prints an information message
1000 if(AliLog::GetGlobalDebugLevel()>0) {
1004 Info("Init", "%s", st.Data()) ;
1005 // Here the PHOS initialisation code (if any!)
1007 AliPHOSGeometry * geom = GetGeometry() ;
1010 Info("Init", "AliPHOS%s: PHOS geometry intialized for %s", Version().Data(), geom->GetName()) ;
1012 Info("Init", "AliPHOS%s: PHOS geometry initialization failed !", Version().Data()) ;
1014 Info("Init", "%s", st.Data()) ;