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.85 2007/03/01 11:37:37 kharlov
21 * Strip units changed from 8x1 to 8x2 (T.Pocheptsov)
23 * Revision 1.84 2006/12/20 16:56:43 kharlov
24 * Optional geometry without CPV
26 * Revision 1.83 2006/11/14 17:11:15 hristov
27 * 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
29 * Revision 1.82 2006/09/27 19:55:57 kharlov
30 * Alignment object with symbolic volume names are introduced
32 * Revision 1.81 2006/03/04 20:25:56 kharlov
33 * Set geom parameters from CDB
35 * Revision 1.80 2005/06/17 07:39:07 hristov
36 * Removing GetDebug and SetDebug from AliRun and AliModule. Using AliLog for the messages
38 * Revision 1.79 2005/05/28 14:19:05 schutz
39 * Compilation warnings fixed by T.P.
43 //_________________________________________________________________________
44 // Implementation version v0 of PHOS Manager class
45 // An object of this class does not produce hits nor digits
46 // It is the one to use if you do not want to produce outputs in TREEH or TREED
48 //*-- Author: Yves Schutz (SUBATECH) & Dmitri Peressounko (RRC KI & SUBATECH)
51 // --- ROOT system ---
55 #include <TGeometry.h>
61 #include <TVirtualMC.h>
62 #include <TGeoManager.h>
64 // --- Standard library ---
69 // --- AliRoot header files ---
72 #include "AliPHOSGeometry.h"
73 #include "AliPHOSLoader.h"
74 #include "AliPHOSv0.h"
80 //____________________________________________________________________________
81 AliPHOSv0::AliPHOSv0(const char *name, const char *title):
84 // ctor : title is used to identify the layout
88 //____________________________________________________________________________
89 void AliPHOSv0::BuildGeometry()
91 // Build the PHOS geometry for the ROOT display
95 PHOS in ALICE displayed by root
101 <IMG Align=BOTTOM ALT="All Views" SRC="../images/AliPHOSv0AllViews.gif">
106 <IMG Align=BOTTOM ALT="Front View" SRC="../images/AliPHOSv0FrontView.gif">
111 <IMG Align=BOTTOM ALT="3D View 1" SRC="../images/AliPHOSv03DView1.gif">
116 <IMG Align=BOTTOM ALT="3D View 2" SRC="../images/AliPHOSv03DView2.gif">
122 this->BuildGeometryforEMC() ;
123 this->BuildGeometryforCPV() ;
127 //____________________________________________________________________________
128 void AliPHOSv0:: BuildGeometryforEMC(void)
130 // Build the PHOS-EMC geometry for the ROOT display
132 const Int_t kColorPHOS = kRed ;
133 const Int_t kColorXTAL = kBlue ;
135 Double_t const kRADDEG = 180.0 / TMath::Pi() ;
137 AliPHOSGeometry * geom = GetGeometry() ;
138 AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
139 Float_t * boxparams = emcg->GetEMCParams() ;
141 new TTRD1("OuterBox", "PHOS box", "void",boxparams[0],boxparams[1],boxparams[2], boxparams[3] );
146 Float_t * cribox = emcg->GetInnerThermoHalfSize() ;
147 new TBRIK( "CrystalsBox", "PHOS crystals box", "void", cribox[0], cribox[2], cribox[1] ) ;
149 // position PHOS into ALICE
151 Float_t r = geom->GetIPtoOuterCoverDistance() + boxparams[3] ;
153 TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
155 char * nodename = new char[20] ;
156 char * rotname = new char[20] ;
158 new TRotMatrix("cribox", "cribox", 90, 0, 90, 90, 0, 0);
160 for( Int_t i = 1; i <= geom->GetNModules(); i++ ) {
162 Float_t angle = geom->GetPHOSAngle(i) ;
163 sprintf(rotname, "%s%d", "rot", number++) ;
164 new TRotMatrix(rotname, rotname, 90, angle, 0, 0, 90, 270 + angle);
167 sprintf(nodename,"%s%d", "Module", i) ;
168 Float_t x = r * TMath::Sin( angle / kRADDEG ) ;
169 Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
170 TNode * outerboxnode = new TNode(nodename, nodename, "OuterBox", x, y, 0, rotname ) ;
171 outerboxnode->SetLineColor(kColorPHOS) ;
172 fNodes->Add(outerboxnode) ;
175 Float_t z = -boxparams[3] - geom->GetIPtoOuterCoverDistance() +
176 cribox[1] + geom->GetIPtoCrystalSurface() ;
177 TNode * crystalsboxnode = new TNode(nodename, nodename, "CrystalsBox", 0, 0, z) ;
178 crystalsboxnode->SetLineColor(kColorXTAL) ;
179 fNodes->Add(crystalsboxnode) ;
187 //____________________________________________________________________________
188 void AliPHOSv0:: BuildGeometryforCPV(void)
190 // Build the PHOS-CPV geometry for the ROOT display
191 // Author: Yuri Kharlov 11 September 2000
196 CPV displayed by root
201 <td>CPV perspective view</td>
202 <td>CPV front view </td>
206 <td> <img height=300 width=290 src="../images/CPVRootPersp.gif"> </td>
207 <td> <img height=300 width=290 src="../images/CPVRootFront.gif"> </td>
215 const Double_t kRADDEG = 180.0 / TMath::Pi() ;
216 const Int_t kColorCPV = kGreen ;
217 const Int_t kColorFrame = kYellow ;
218 const Int_t kColorGassiplex = kRed;
219 const Int_t kColorPCB = kCyan;
221 AliPHOSGeometry * geom = GetGeometry() ;
223 // Box for a full PHOS module
225 new TBRIK ("CPVBox", "CPV box", "void", geom->GetCPVBoxSize(0)/2,
226 geom->GetCPVBoxSize(1)/2,
227 geom->GetCPVBoxSize(2)/2 );
228 new TBRIK ("CPVFrameLR", "CPV frame Left-Right", "void", geom->GetCPVFrameSize(0)/2,
229 geom->GetCPVFrameSize(1)/2,
230 geom->GetCPVBoxSize(2)/2 );
231 new TBRIK ("CPVFrameUD", "CPV frame Up-Down", "void", geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0),
232 geom->GetCPVFrameSize(1)/2,
233 geom->GetCPVFrameSize(2)/2);
234 new TBRIK ("CPVPCB", "CPV PCB", "void", geom->GetCPVActiveSize(0)/2,
235 geom->GetCPVTextoliteThickness()/2,
236 geom->GetCPVActiveSize(1)/2);
237 new TBRIK ("CPVGassiplex", "CPV Gassiplex PCB", "void", geom->GetGassiplexChipSize(0)/2,
238 geom->GetGassiplexChipSize(1)/2,
239 geom->GetGassiplexChipSize(2)/2);
241 // position CPV into ALICE
243 char * nodename = new char[25] ;
244 char * rotname = new char[25] ;
246 Float_t r = geom->GetIPtoCPVDistance() + geom->GetCPVBoxSize(1) / 2.0 ;
248 TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
250 Int_t lastModule = 0 ;
251 lastModule = geom->GetNModules();
253 for( Int_t i = 1; i <= lastModule; i++ ) { // the number of PHOS modules
257 Float_t angle = geom->GetPHOSAngle(i) ;
258 sprintf(rotname, "%s%d", "rotg", number+i) ;
259 new TRotMatrix(rotname, rotname, 90, angle, 90, 90 + angle, 0, 0);
261 sprintf(nodename, "%s%d", "CPVModule", i) ;
262 Float_t x = r * TMath::Sin( angle / kRADDEG ) ;
263 Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
265 TNode * cpvBoxNode = new TNode(nodename , nodename ,"CPVBox", x, y, 0, rotname ) ;
266 cpvBoxNode->SetLineColor(kColorCPV) ;
267 fNodes->Add(cpvBoxNode) ;
270 // inside each CPV box:
274 for (j=0; j<=1; j++) {
275 sprintf(nodename, "CPVModule%d Frame%d", i, j+1) ;
276 x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
277 TNode * cpvFrameNode = new TNode(nodename , nodename ,"CPVFrameLR", x, 0, 0) ;
278 cpvFrameNode->SetLineColor(kColorFrame) ;
279 fNodes->Add(cpvFrameNode) ;
281 sprintf(nodename, "CPVModule%d Frame%d", i, j+3) ;
282 z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
283 cpvFrameNode = new TNode(nodename , nodename ,"CPVFrameUD", 0, 0, z) ;
284 cpvFrameNode->SetLineColor(kColorFrame) ;
285 fNodes->Add(cpvFrameNode) ;
288 // 4 printed circuit boards
289 for (j=0; j<4; j++) {
290 sprintf(nodename, "CPVModule%d PCB%d", i, j+1) ;
291 y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(j) + geom->GetCPVTextoliteThickness()/2;
292 TNode * cpvPCBNode = new TNode(nodename , nodename ,"CPVPCB", 0, y, 0) ;
293 cpvPCBNode->SetLineColor(kColorPCB) ;
294 fNodes->Add(cpvPCBNode) ;
298 Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
299 Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ() + 1);
300 y = geom->GetCPVFrameSize(1)/2 - geom->GetFTPosition(0) +
301 geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
302 for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
303 x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
304 for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
305 z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
306 sprintf(nodename, "CPVModule%d Chip(%dx%d)", i, ix+1,iz+1) ;
307 TNode * cpvGassiplexNode = new TNode(nodename , nodename ,"CPVGassiplex", x, y, z) ;
308 cpvGassiplexNode->SetLineColor(kColorGassiplex) ;
309 fNodes->Add(cpvGassiplexNode) ;
319 //____________________________________________________________________________
320 void AliPHOSv0::CreateGeometry()
322 // Create the PHOS geometry for Geant
324 AliPHOSv0 *phostmp = dynamic_cast<AliPHOSv0*>(gAlice->GetModule("PHOS")) ;
326 if ( phostmp == NULL ) {
328 fprintf(stderr, "PHOS detector not found!\n") ;
333 AliPHOSGeometry * geom = GetGeometry() ;
335 // Get pointer to the array containing media indeces
336 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
338 // Create a PHOS module.
340 gMC->Gsvolu("PHOS", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;
342 this->CreateGeometryforEMC() ;
344 if (strstr(fTitle.Data(),"noCPV") == 0)
345 this->CreateGeometryforCPV() ;
347 this->CreateGeometryforSupport() ;
349 // --- Position PHOS mdules in ALICE setup ---
353 for (Int_t iModule = 0; iModule < geom->GetNModules(); iModule++ ) {
356 for (iXYZ=0; iXYZ<3; iXYZ++)
357 for (iAngle=0; iAngle<2; iAngle++)
358 angle[iXYZ][iAngle] = geom->GetModuleAngle(iModule,iXYZ, iAngle);
359 AliMatrix(idrotm[iModule],
360 angle[0][0],angle[0][1],
361 angle[1][0],angle[1][1],
362 angle[2][0],angle[2][1]) ;
365 for (iXYZ=0; iXYZ<3; iXYZ++)
366 pos[iXYZ] = geom->GetModuleCenter(iModule,iXYZ);
367 gMC->Gspos("PHOS", iModule+1, "ALIC", pos[0], pos[1], pos[2],
368 idrotm[iModule], "ONLY") ;
373 //____________________________________________________________________________
374 void AliPHOSv0::CreateGeometryforEMC()
376 // Create the PHOS-EMC geometry for GEANT
377 // Author: Dmitri Peressounko August 2001
378 // The used coordinate system:
379 // 1. in Module: X along longer side, Y out of beam, Z along shorter side (along beam)
380 // 2. In Strip the same: X along longer side, Y out of beam, Z along shorter side (along beam)
386 Geant3 geometry tree of PHOS-EMC in ALICE
389 <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/EMCinAlice.gif">
394 // Get pointer to the array containing media indexes
395 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
397 AliPHOSGeometry * geom = GetGeometry() ;
398 AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
400 // ======= Define the strip ===============
402 gMC->Gsvolu("PSTR", "BOX ", idtmed[716], emcg->GetStripHalfSize(), 3) ; //Made of stell
404 // --- define air volume (cell of the honeycomb)
405 gMC->Gsvolu("PCEL", "BOX ", idtmed[798], emcg->GetAirCellHalfSize(), 3);
407 // --- define wrapped crystal and put it into AirCell
409 gMC->Gsvolu("PWRA", "BOX ", idtmed[702], emcg->GetWrappedHalfSize(), 3);
410 Float_t * pin = emcg->GetAPDHalfSize() ;
411 Float_t * preamp = emcg->GetPreampHalfSize() ;
412 Float_t y = (emcg->GetAirGapLed()-2*pin[1]-2*preamp[1])/2;
413 gMC->Gspos("PWRA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
415 // --- Define crystall and put it into wrapped crystall ---
416 gMC->Gsvolu("PXTL", "BOX ", idtmed[699], emcg->GetCrystalHalfSize(), 3) ;
417 gMC->Gspos("PXTL", 1, "PWRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
419 // --- define APD/PIN preamp and put it into AirCell
421 gMC->Gsvolu("PPIN", "BOX ", idtmed[705], emcg->GetAPDHalfSize(), 3) ;
422 Float_t * crystal = emcg->GetCrystalHalfSize() ;
423 y = crystal[1] + emcg->GetAirGapLed() /2 - preamp[1];
424 gMC->Gspos("PPIN", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
426 gMC->Gsvolu("PREA", "BOX ", idtmed[711], emcg->GetPreampHalfSize(), 3) ; // Here I assumed preamp
427 // as a printed Circuit
428 y = crystal[1] + emcg->GetAirGapLed() /2 + pin[1] ; // May it should be changed
429 gMC->Gspos("PREA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ; // to ceramics?
432 // --- Fill strip with wrapped cristalls in Air Cells
434 Float_t* splate = emcg->GetSupportPlateHalfSize();
436 Float_t* acel = emcg->GetAirCellHalfSize() ;
438 for(Int_t lev = 2, icel = 1; icel <= emcg->GetNCellsXInStrip()*emcg->GetNCellsZInStrip(); icel += 2, lev += 2){
439 Float_t x = (2*(lev / 2) - 1 - emcg->GetNCellsXInStrip())* acel[0] ;
441 gMC->Gspos("PCEL", icel, "PSTR", x, y, +z, 0, "ONLY") ;
442 gMC->Gspos("PCEL", icel + 1, "PSTR", x, y, -z, 0, "ONLY") ;
445 // --- define the support plate, hole in it and position it in strip ----
446 gMC->Gsvolu("PSUP", "BOX ", idtmed[701], emcg->GetSupportPlateHalfSize(), 3) ;
448 gMC->Gsvolu("PSHO", "BOX ", idtmed[798], emcg->GetSupportPlateInHalfSize(), 3) ;
449 Float_t z = emcg->GetSupportPlateThickness()/2 ;
450 gMC->Gspos("PSHO", 1, "PSUP", 0.0, 0.0, z, 0, "ONLY") ;
453 gMC->Gspos("PSUP", 1, "PSTR", 0.0, y, 0.0, 0, "ONLY") ;
456 // ========== Fill module with strips and put them into inner thermoinsulation=============
457 gMC->Gsvolu("PTII", "BOX ", idtmed[706], emcg->GetInnerThermoHalfSize(), 3) ;
459 Float_t * inthermo = emcg->GetInnerThermoHalfSize() ;
460 Float_t * strip = emcg->GetStripHalfSize() ;
461 y = inthermo[1] - strip[1] ;
466 for(irow = 0; irow < emcg->GetNStripX(); irow ++){
467 Float_t x = (2*irow + 1 - emcg->GetNStripX())* strip[0] ;
468 for(icol = 0; icol < emcg->GetNStripZ(); icol ++){
469 z = (2*icol + 1 - emcg->GetNStripZ()) * strip[2] ;
470 gMC->Gspos("PSTR", nr, "PTII", x, y, z, 0, "ONLY") ;
476 // ------- define the air gap between thermoinsulation and cooler
477 gMC->Gsvolu("PAGA", "BOX ", idtmed[798], emcg->GetAirGapHalfSize(), 3) ;
478 Float_t * agap = emcg->GetAirGapHalfSize() ;
479 y = agap[1] - inthermo[1] ;
481 gMC->Gspos("PTII", 1, "PAGA", 0.0, y, 0.0, 0, "ONLY") ;
485 // ------- define the Al passive cooler
486 gMC->Gsvolu("PCOR", "BOX ", idtmed[701], emcg->GetCoolerHalfSize(), 3) ;
487 Float_t * cooler = emcg->GetCoolerHalfSize() ;
488 y = cooler[1] - agap[1] ;
490 gMC->Gspos("PAGA", 1, "PCOR", 0.0, y, 0.0, 0, "ONLY") ;
492 // ------- define the outer thermoinsulating cover
493 gMC->Gsvolu("PTIO", "TRD1", idtmed[706], emcg->GetOuterThermoParams(), 4) ;
494 Float_t * outparams = emcg->GetOuterThermoParams() ;
497 AliMatrix(idrotm[1], 90.0, 0.0, 0.0, 0.0, 90.0, 270.0) ;
498 // Frame in outer thermoinsulation and so on: z out of beam, y along beam, x across beam
500 z = outparams[3] - cooler[1] ;
501 gMC->Gspos("PCOR", 1, "PTIO", 0., 0.0, z, idrotm[1], "ONLY") ;
503 // -------- Define the outer Aluminium cover -----
504 gMC->Gsvolu("PCOL", "TRD1", idtmed[701], emcg->GetAlCoverParams(), 4) ;
505 Float_t * covparams = emcg->GetAlCoverParams() ;
506 z = covparams[3] - outparams[3] ;
507 gMC->Gspos("PTIO", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
509 // --------- Define front fiberglass cover -----------
510 gMC->Gsvolu("PFGC", "BOX ", idtmed[717], emcg->GetFiberGlassHalfSize(), 3) ;
512 gMC->Gspos("PFGC", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
514 //=============This is all with cold section==============
517 //------ Warm Section --------------
518 gMC->Gsvolu("PWAR", "BOX ", idtmed[701], emcg->GetWarmAlCoverHalfSize(), 3) ;
519 Float_t * warmcov = emcg->GetWarmAlCoverHalfSize() ;
521 // --- Define the outer thermoinsulation ---
522 gMC->Gsvolu("PWTI", "BOX ", idtmed[706], emcg->GetWarmThermoHalfSize(), 3) ;
523 Float_t * warmthermo = emcg->GetWarmThermoHalfSize() ;
524 z = -warmcov[2] + warmthermo[2] ;
526 gMC->Gspos("PWTI", 1, "PWAR", 0., 0.0, z, 0, "ONLY") ;
528 // --- Define cables area and put in it T-supports ----
529 gMC->Gsvolu("PCA1", "BOX ", idtmed[718], emcg->GetTCables1HalfSize(), 3) ;
530 Float_t * cbox = emcg->GetTCables1HalfSize() ;
532 gMC->Gsvolu("PBE1", "BOX ", idtmed[701], emcg->GetTSupport1HalfSize(), 3) ;
533 Float_t * beams = emcg->GetTSupport1HalfSize() ;
535 for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
536 Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
537 gMC->Gspos("PBE1", isup, "PCA1", x, 0.0, 0.0, 0, "ONLY") ;
540 z = -warmthermo[2] + cbox[2] ;
541 gMC->Gspos("PCA1", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;
543 gMC->Gsvolu("PCA2", "BOX ", idtmed[718], emcg->GetTCables2HalfSize(), 3) ;
544 Float_t * cbox2 = emcg->GetTCables2HalfSize() ;
546 gMC->Gsvolu("PBE2", "BOX ", idtmed[701], emcg->GetTSupport2HalfSize(), 3) ;
547 for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
548 Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
549 gMC->Gspos("PBE2", isup, "PCA2", x, 0.0, 0.0, 0, "ONLY") ;
552 z = -warmthermo[2] + 2*cbox[2] + cbox2[2];
553 gMC->Gspos("PCA2", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;
556 // --- Define frame ---
557 gMC->Gsvolu("PFRX", "BOX ", idtmed[716], emcg->GetFrameXHalfSize(), 3) ;
558 Float_t * posit = emcg->GetFrameXPosition() ;
559 gMC->Gspos("PFRX", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
560 gMC->Gspos("PFRX", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
562 gMC->Gsvolu("PFRZ", "BOX ", idtmed[716], emcg->GetFrameZHalfSize(), 3) ;
563 posit = emcg->GetFrameZPosition() ;
564 gMC->Gspos("PFRZ", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
565 gMC->Gspos("PFRZ", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
567 // --- Define Fiber Glass support ---
568 gMC->Gsvolu("PFG1", "BOX ", idtmed[717], emcg->GetFGupXHalfSize(), 3) ;
569 posit = emcg->GetFGupXPosition() ;
570 gMC->Gspos("PFG1", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
571 gMC->Gspos("PFG1", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
573 gMC->Gsvolu("PFG2", "BOX ", idtmed[717], emcg->GetFGupZHalfSize(), 3) ;
574 posit = emcg->GetFGupZPosition() ;
575 gMC->Gspos("PFG2", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
576 gMC->Gspos("PFG2", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
578 gMC->Gsvolu("PFG3", "BOX ", idtmed[717], emcg->GetFGlowXHalfSize(), 3) ;
579 posit = emcg->GetFGlowXPosition() ;
580 gMC->Gspos("PFG3", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
581 gMC->Gspos("PFG3", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
583 gMC->Gsvolu("PFG4", "BOX ", idtmed[717], emcg->GetFGlowZHalfSize(), 3) ;
584 posit = emcg->GetFGlowZPosition() ;
585 gMC->Gspos("PFG4", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
586 gMC->Gspos("PFG4", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
588 // --- Define Air Gap for FEE electronics -----
590 gMC->Gsvolu("PAFE", "BOX ", idtmed[798], emcg->GetFEEAirHalfSize(), 3) ;
591 posit = emcg->GetFEEAirPosition() ;
592 gMC->Gspos("PAFE", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
594 // Define the EMC module volume and combine Cool and Warm sections
596 gMC->Gsvolu("PEMC", "TRD1", idtmed[798], emcg->GetEMCParams(), 4) ;
599 gMC->Gspos("PCOL", 1, "PEMC", 0., 0., z, 0, "ONLY") ;
601 gMC->Gspos("PWAR", 1, "PEMC", 0., 0., z, 0, "ONLY") ;
604 // Put created EMC geometry into PHOS volume
606 z = geom->GetCPVBoxSize(1) / 2. ;
607 gMC->Gspos("PEMC", 1, "PHOS", 0., 0., z, 0, "ONLY") ;
611 //____________________________________________________________________________
612 void AliPHOSv0::CreateGeometryforCPV()
614 // Create the PHOS-CPV geometry for GEANT
615 // Author: Yuri Kharlov 11 September 2000
619 Geant3 geometry of PHOS-CPV in ALICE
624 <td>CPV perspective view</td>
625 <td>CPV front view </td>
629 <td> <img height=300 width=290 src="../images/CPVallPersp.gif"> </td>
630 <td> <img height=300 width=290 src="../images/CPVallFront.gif"> </td>
634 <td>One CPV module, perspective view </td>
635 <td>One CPV module, front view (extended in vertical direction) </td>
639 <td><img height=300 width=290 src="../images/CPVmodulePers.gif"></td>
640 <td><img height=300 width=290 src="../images/CPVmoduleSide.gif"></td>
646 Geant3 geometry tree of PHOS-CPV in ALICE
649 <img height=300 width=290 src="../images/CPVtree.gif">
654 Float_t par[3], x,y,z;
656 // Get pointer to the array containing media indexes
657 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
659 AliPHOSGeometry * geom = GetGeometry() ;
661 // The box containing all CPV for one PHOS module filled with air
662 par[0] = geom->GetCPVBoxSize(0) / 2.0 ;
663 par[1] = geom->GetCPVBoxSize(1) / 2.0 ;
664 par[2] = geom->GetCPVBoxSize(2) / 2.0 ;
665 gMC->Gsvolu("PCPV", "BOX ", idtmed[798], par, 3) ;
667 Float_t * emcParams = geom->GetEMCAGeometry()->GetEMCParams() ;
670 AliMatrix(rotm, 90.,0., 0., 0., 90., 90.) ;
672 gMC->Gspos("PCPV", 1, "PHOS", 0.0, 0.0, z, rotm, "ONLY") ;
676 par[0] = geom->GetGassiplexChipSize(0)/2.;
677 par[1] = geom->GetGassiplexChipSize(1)/2.;
678 par[2] = geom->GetGassiplexChipSize(2)/2.;
679 gMC->Gsvolu("PCPC","BOX ",idtmed[707],par,3);
681 // Cu+Ni foil covers Gassiplex board
683 par[1] = geom->GetCPVCuNiFoilThickness()/2;
684 gMC->Gsvolu("PCPD","BOX ",idtmed[710],par,3);
685 y = -(geom->GetGassiplexChipSize(1)/2 - par[1]);
686 gMC->Gspos("PCPD",1,"PCPC",0,y,0,0,"ONLY");
688 // Position of the chip inside CPV
690 Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
691 Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ() + 1);
693 y = geom->GetCPVFrameSize(1)/2 - geom->GetFTPosition(0) +
694 geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
695 for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
696 x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
697 for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
699 z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
700 gMC->Gspos("PCPC",copy,"PCPV",x,y,z,0,"ONLY");
704 // Foiled textolite (1 mm of textolite + 50 mkm of Cu + 6 mkm of Ni)
706 par[0] = geom->GetCPVActiveSize(0) / 2;
707 par[1] = geom->GetCPVTextoliteThickness() / 2;
708 par[2] = geom->GetCPVActiveSize(1) / 2;
709 gMC->Gsvolu("PCPF","BOX ",idtmed[707],par,3);
713 par[1] = (geom->GetFTPosition(2) - geom->GetFTPosition(1) - geom->GetCPVTextoliteThickness()) / 2;
714 gMC->Gsvolu("PCPG","BOX ",idtmed[715],par,3);
716 for (Int_t i=0; i<4; i++) {
717 y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(i) + geom->GetCPVTextoliteThickness()/2;
718 gMC->Gspos("PCPF",i+1,"PCPV",0,y,0,0,"ONLY");
720 y-= (geom->GetFTPosition(2) - geom->GetFTPosition(1)) / 2;
721 gMC->Gspos("PCPG",1,"PCPV ",0,y,0,0,"ONLY");
725 // Dummy sensitive plane in the middle of argone gas volume
728 gMC->Gsvolu("PCPQ","BOX ",idtmed[715],par,3);
729 gMC->Gspos ("PCPQ",1,"PCPG",0,0,0,0,"ONLY");
731 // Cu+Ni foil covers textolite
733 par[1] = geom->GetCPVCuNiFoilThickness() / 2;
734 gMC->Gsvolu("PCP1","BOX ",idtmed[710],par,3);
735 y = geom->GetCPVTextoliteThickness()/2 - par[1];
736 gMC->Gspos ("PCP1",1,"PCPF",0,y,0,0,"ONLY");
738 // Aluminum frame around CPV
740 par[0] = geom->GetCPVFrameSize(0)/2;
741 par[1] = geom->GetCPVFrameSize(1)/2;
742 par[2] = geom->GetCPVBoxSize(2) /2;
743 gMC->Gsvolu("PCF1","BOX ",idtmed[701],par,3);
745 par[0] = geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0);
746 par[1] = geom->GetCPVFrameSize(1)/2;
747 par[2] = geom->GetCPVFrameSize(2)/2;
748 gMC->Gsvolu("PCF2","BOX ",idtmed[701],par,3);
750 for (Int_t j=0; j<=1; j++) {
751 x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
752 gMC->Gspos("PCF1",j+1,"PCPV", x,0,0,0,"ONLY");
753 z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
754 gMC->Gspos("PCF2",j+1,"PCPV",0, 0,z,0,"ONLY");
760 //____________________________________________________________________________
761 void AliPHOSv0::CreateGeometryforSupport()
763 // Create the PHOS' support geometry for GEANT
767 Geant3 geometry of the PHOS's support
770 <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/PHOS_support.gif">
775 Float_t par[5], x0,y0,z0 ;
778 // Get pointer to the array containing media indexes
779 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
781 AliPHOSGeometry * geom = GetGeometry() ;
783 // --- Dummy box containing two rails on which PHOS support moves
784 // --- Put these rails to the bottom of the L3 magnet
786 par[0] = geom->GetRailRoadSize(0) / 2.0 ;
787 par[1] = geom->GetRailRoadSize(1) / 2.0 ;
788 par[2] = geom->GetRailRoadSize(2) / 2.0 ;
789 gMC->Gsvolu("PRRD", "BOX ", idtmed[798], par, 3) ;
791 y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) / 2.0) ;
792 gMC->Gspos("PRRD", 1, "ALIC", 0.0, y0, 0.0, 0, "ONLY") ;
794 // --- Dummy box containing one rail
796 par[0] = geom->GetRailOuterSize(0) / 2.0 ;
797 par[1] = geom->GetRailOuterSize(1) / 2.0 ;
798 par[2] = geom->GetRailOuterSize(2) / 2.0 ;
799 gMC->Gsvolu("PRAI", "BOX ", idtmed[798], par, 3) ;
801 for (i=0; i<2; i++) {
802 x0 = (2*i-1) * geom->GetDistanceBetwRails() / 2.0 ;
803 gMC->Gspos("PRAI", i, "PRRD", x0, 0.0, 0.0, 0, "ONLY") ;
806 // --- Upper and bottom steel parts of the rail
808 par[0] = geom->GetRailPart1(0) / 2.0 ;
809 par[1] = geom->GetRailPart1(1) / 2.0 ;
810 par[2] = geom->GetRailPart1(2) / 2.0 ;
811 gMC->Gsvolu("PRP1", "BOX ", idtmed[716], par, 3) ;
813 y0 = - (geom->GetRailOuterSize(1) - geom->GetRailPart1(1)) / 2.0 ;
814 gMC->Gspos("PRP1", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
815 y0 = (geom->GetRailOuterSize(1) - geom->GetRailPart1(1)) / 2.0 - geom->GetRailPart3(1);
816 gMC->Gspos("PRP1", 2, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
818 // --- The middle vertical steel parts of the rail
820 par[0] = geom->GetRailPart2(0) / 2.0 ;
821 par[1] = geom->GetRailPart2(1) / 2.0 ;
822 par[2] = geom->GetRailPart2(2) / 2.0 ;
823 gMC->Gsvolu("PRP2", "BOX ", idtmed[716], par, 3) ;
825 y0 = - geom->GetRailPart3(1) / 2.0 ;
826 gMC->Gspos("PRP2", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
828 // --- The most upper steel parts of the rail
830 par[0] = geom->GetRailPart3(0) / 2.0 ;
831 par[1] = geom->GetRailPart3(1) / 2.0 ;
832 par[2] = geom->GetRailPart3(2) / 2.0 ;
833 gMC->Gsvolu("PRP3", "BOX ", idtmed[716], par, 3) ;
835 y0 = (geom->GetRailOuterSize(1) - geom->GetRailPart3(1)) / 2.0 ;
836 gMC->Gspos("PRP3", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
838 // --- The wall of the cradle
839 // --- The wall is empty: steel thin walls and air inside
841 par[1] = TMath::Sqrt(TMath::Power((geom->GetIPtoCPVDistance() + geom->GetOuterBoxSize(3)),2) +
842 TMath::Power((geom->GetOuterBoxSize(1)/2),2))+10. ;
843 par[0] = par[1] - geom->GetCradleWall(1) ;
844 par[2] = geom->GetCradleWall(2) / 2.0 ;
845 par[3] = geom->GetCradleWall(3) ;
846 par[4] = geom->GetCradleWall(4) ;
847 gMC->Gsvolu("PCRA", "TUBS", idtmed[716], par, 5) ;
849 par[0] += geom->GetCradleWallThickness() ;
850 par[1] -= geom->GetCradleWallThickness() ;
851 par[2] -= geom->GetCradleWallThickness() ;
852 gMC->Gsvolu("PCRE", "TUBS", idtmed[798], par, 5) ;
853 gMC->Gspos ("PCRE", 1, "PCRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
855 for (i=0; i<2; i++) {
856 z0 = (2*i-1) * (geom->GetOuterBoxSize(2) + geom->GetCradleWall(2) )/ 2.0 ;
857 gMC->Gspos("PCRA", i, "ALIC", 0.0, 0.0, z0, 0, "ONLY") ;
860 // --- The "wheels" of the cradle
862 par[0] = geom->GetCradleWheel(0) / 2;
863 par[1] = geom->GetCradleWheel(1) / 2;
864 par[2] = geom->GetCradleWheel(2) / 2;
865 gMC->Gsvolu("PWHE", "BOX ", idtmed[716], par, 3) ;
867 y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) -
868 geom->GetCradleWheel(1)/2) ;
869 for (i=0; i<2; i++) {
870 z0 = (2*i-1) * ((geom->GetOuterBoxSize(2) + geom->GetCradleWheel(2))/ 2.0 +
871 geom->GetCradleWall(2));
872 for (j=0; j<2; j++) {
874 x0 = (2*j-1) * geom->GetDistanceBetwRails() / 2.0 ;
875 gMC->Gspos("PWHE", copy, "ALIC", x0, y0, z0, 0, "ONLY") ;
881 //_____________________________________________________________________________
882 void AliPHOSv0::AddAlignableVolumes() const
885 // Create entries for alignable volumes associating the symbolic volume
886 // name with the corresponding volume path. Needs to be syncronized with
887 // eventual changes in the geometry
888 // Alignable volumes are:
889 // 1) PHOS modules as a whole
892 // 4) Strip units (group of 2x8 crystals)
894 TString volpath, symname;
897 // Volume path /ALIC_1/PHOS_<i> => symbolic name /PHOS/Module<i>, <i>=1,2,3,4,5
899 TString physModulePath="/ALIC_1/PHOS_";
900 TString symbModuleName="PHOS/Module";
901 Int_t nModules = GetGeometry()->GetNModules();
903 for(Int_t iModule=1; iModule<=nModules; iModule++){
904 volpath = physModulePath;
906 symname = symbModuleName;
908 gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
911 //Aligning of CPV should be done for volume PCPV_1
912 symbModuleName="PHOS/Module";
913 for(Int_t iModule=1; iModule<=nModules; iModule++){
914 volpath = physModulePath;
916 volpath += "/PCPV_1";
917 symname = symbModuleName;
920 gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
924 // Alignable cradle walls
925 // Volume path /ALIC_1/PCRA_<i> => symbolic name /PHOS/Cradle<i>, <i>=0,1
927 TString physCradlePath="/ALIC_1/PCRA_";
928 TString symbCradleName="PHOS/Cradle";
931 for(Int_t iCradle=0; iCradle<nCradles; iCradle++){
932 volpath = physCradlePath;
934 symname = symbCradleName;
936 gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
940 // Volume path /ALIC_1/PWHE_<i> => symbolic name /PHOS/Wheel<i>, i=0,1,2,3
942 TString physWheelPath="/ALIC_1/PWHE_";
943 TString symbWheelName="PHOS/Wheel";
946 for(Int_t iWheel=0; iWheel<nWheels; iWheel++){
947 volpath = physWheelPath;
949 symname = symbWheelName;
951 gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
954 //Physical strip path is a combination of: physModulePath + module number +
955 //physStripPath + strip number == ALIC_1/PHOS_N/..../PSTR_M
956 const Int_t nStripsX = GetGeometry()->GetEMCAGeometry()->GetNStripX();
957 const Int_t nStripsZ = GetGeometry()->GetEMCAGeometry()->GetNStripZ();
958 TString partialPhysStripName(100);
959 TString fullPhysStripName(100);
960 TString partialSymbStripName(100);
961 TString fullSymbStripName(100);
963 for(Int_t module = 1; module <= nModules; ++module){
964 partialPhysStripName = physModulePath;
965 partialPhysStripName += module;
966 partialPhysStripName += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1/PSTR_";
968 partialSymbStripName = symbModuleName;
969 partialSymbStripName += module;
970 partialSymbStripName += "/Strip_";
972 for(Int_t i = 0, ind1D = 1; i < nStripsX; ++i){//ind1D starts from 1 (PSTR_1...PSTR_224...)
973 for(Int_t j = 0; j < nStripsZ; ++j, ++ind1D){
974 fullPhysStripName = partialPhysStripName;
975 fullPhysStripName += ind1D;
977 fullSymbStripName = partialSymbStripName;
978 fullSymbStripName += i;//ind1D;
979 fullSymbStripName += '_';
980 fullSymbStripName += j;
982 gGeoManager->SetAlignableEntry(fullSymbStripName.Data(), fullPhysStripName.Data());
988 //____________________________________________________________________________
989 Float_t AliPHOSv0::ZMin(void) const
991 // Overall dimension of the PHOS (min)
993 AliPHOSGeometry * geom = GetGeometry() ;
995 return -geom->GetOuterBoxSize(2)/2.;
998 //____________________________________________________________________________
999 Float_t AliPHOSv0::ZMax(void) const
1001 // Overall dimension of the PHOS (max)
1003 AliPHOSGeometry * geom = GetGeometry() ;
1005 return geom->GetOuterBoxSize(2)/2.;
1008 //____________________________________________________________________________
1009 void AliPHOSv0::Init(void)
1011 // Just prints an information message
1015 if(AliLog::GetGlobalDebugLevel()>0) {
1019 Info("Init", "%s", st.Data()) ;
1020 // Here the PHOS initialisation code (if any!)
1022 AliPHOSGeometry * geom = GetGeometry() ;
1025 Info("Init", "AliPHOS%s: PHOS geometry intialized for %s", Version().Data(), geom->GetName()) ;
1027 Info("Init", "AliPHOS%s: PHOS geometry initialization failed !", Version().Data()) ;
1029 Info("Init", "%s", st.Data()) ;