]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - PHOS/AliPHOSv0.cxx
No reason to make the Merge method private !
[u/mrichter/AliRoot.git] / PHOS / AliPHOSv0.cxx
... / ...
CommitLineData
1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15/* $Id$ */
16
17/* History of cvs commits:
18 *
19 * $Log$
20 * Revision 1.94 2007/10/18 08:40:02 kharlov
21 * Misalignment-related bug fixed
22 *
23 * Revision 1.93 2007/10/06 22:24:40 kharlov
24 * Bug in strip unit geometry is corrected
25 *
26 * Revision 1.92 2007/07/04 16:38:19 policheh
27 * Tracking2LocalCS matrices corrected for CPV.
28 *
29 * Revision 1.91 2007/07/02 14:50:49 policheh
30 * Tracking2LocalCS matrices corrected.
31 *
32 * Revision 1.90 2007/05/24 13:04:05 policheh
33 * AddAlignableVolumes: local to tracking CS transformation matrices creates for each
34 * PHOS supermodule
35 *
36 * Revision 1.89 2007/04/24 14:34:39 hristov
37 * Additional protection: do not search for alignable object if the CPV is not in the geometry
38 *
39 * Revision 1.88 2007/04/19 15:28:30 kharlov
40 * Modify strip unit geometry according to the final drawings (Timur)
41 *
42 * Revision 1.87 2007/04/01 07:37:10 kharlov
43 * TGeo RS to Local RS transf matr added
44 *
45 * Revision 1.86 2007/03/06 06:55:46 kharlov
46 * DP:Misalignment of CPV added
47 *
48 * Revision 1.85 2007/03/01 11:37:37 kharlov
49 * Strip units changed from 8x1 to 8x2 (T.Pocheptsov)
50 *
51 * Revision 1.84 2006/12/20 16:56:43 kharlov
52 * Optional geometry without CPV
53 *
54 * Revision 1.83 2006/11/14 17:11:15 hristov
55 * 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
56 *
57 * Revision 1.82 2006/09/27 19:55:57 kharlov
58 * Alignment object with symbolic volume names are introduced
59 *
60 * Revision 1.81 2006/03/04 20:25:56 kharlov
61 * Set geom parameters from CDB
62 *
63 * Revision 1.80 2005/06/17 07:39:07 hristov
64 * Removing GetDebug and SetDebug from AliRun and AliModule. Using AliLog for the messages
65 *
66 * Revision 1.79 2005/05/28 14:19:05 schutz
67 * Compilation warnings fixed by T.P.
68 *
69 */
70
71//_________________________________________________________________________
72// Implementation version v0 of PHOS Manager class
73// An object of this class does not produce hits nor digits
74// It is the one to use if you do not want to produce outputs in TREEH or TREED
75//
76//*-- Author: Yves Schutz (SUBATECH) & Dmitri Peressounko (RRC KI & SUBATECH)
77
78
79// --- ROOT system ---
80
81#include <TBRIK.h>
82#include <TFolder.h>
83#include <TGeometry.h>
84#include <TNode.h>
85#include <TROOT.h>
86#include <TRandom.h>
87#include <TTRD1.h>
88#include <TTree.h>
89#include <TVirtualMC.h>
90#include <TGeoPhysicalNode.h>
91#include <TGeoManager.h>
92#include <TGeoMatrix.h>
93#include <TVector3.h>
94
95// --- Standard library ---
96
97#include <string.h>
98#include <stdlib.h>
99
100// --- AliRoot header files ---
101
102#include "AliConst.h"
103#include "AliPHOSGeometry.h"
104#include "AliPHOSLoader.h"
105#include "AliPHOSv0.h"
106#include "AliRun.h"
107#include "AliLog.h"
108#include "AliGeomManager.h"
109
110ClassImp(AliPHOSv0)
111
112//____________________________________________________________________________
113AliPHOSv0::AliPHOSv0(const char *name, const char *title):
114 AliPHOS(name,title)
115{
116 // ctor : title is used to identify the layout
117 GetGeometry() ;
118}
119
120//____________________________________________________________________________
121void AliPHOSv0::BuildGeometry()
122{
123 // Build the PHOS geometry for the ROOT display
124 //BEGIN_HTML
125 /*
126 <H2>
127 PHOS in ALICE displayed by root
128 </H2>
129 <UL>
130 <LI> All Views
131 <P>
132 <CENTER>
133 <IMG Align=BOTTOM ALT="All Views" SRC="../images/AliPHOSv0AllViews.gif">
134 </CENTER></P></LI>
135 <LI> Front View
136 <P>
137 <CENTER>
138 <IMG Align=BOTTOM ALT="Front View" SRC="../images/AliPHOSv0FrontView.gif">
139 </CENTER></P></LI>
140 <LI> 3D View 1
141 <P>
142 <CENTER>
143 <IMG Align=BOTTOM ALT="3D View 1" SRC="../images/AliPHOSv03DView1.gif">
144 </CENTER></P></LI>
145 <LI> 3D View 2
146 <P>
147 <CENTER>
148 <IMG Align=BOTTOM ALT="3D View 2" SRC="../images/AliPHOSv03DView2.gif">
149 </CENTER></P></LI>
150 </UL>
151 */
152 //END_HTML
153
154 this->BuildGeometryforEMC() ;
155 this->BuildGeometryforCPV() ;
156
157}
158
159//____________________________________________________________________________
160void AliPHOSv0:: BuildGeometryforEMC(void)
161{
162 // Build the PHOS-EMC geometry for the ROOT display
163
164 const Int_t kColorPHOS = kRed ;
165 const Int_t kColorXTAL = kBlue ;
166
167 Double_t const kRADDEG = 180.0 / TMath::Pi() ;
168
169 AliPHOSGeometry * geom = GetGeometry() ;
170 AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
171 Float_t * boxparams = emcg->GetEMCParams() ;
172
173 new TTRD1("OuterBox", "PHOS box", "void",boxparams[0],boxparams[1],boxparams[2], boxparams[3] );
174
175
176 // Crystals Box
177
178 Float_t * cribox = emcg->GetInnerThermoHalfSize() ;
179 new TBRIK( "CrystalsBox", "PHOS crystals box", "void", cribox[0], cribox[2], cribox[1] ) ;
180
181 // position PHOS into ALICE
182
183 Float_t r = geom->GetIPtoOuterCoverDistance() + boxparams[3] ;
184 Int_t number = 988 ;
185 TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
186
187 char * nodename = new char[20] ;
188 char * rotname = new char[20] ;
189
190 new TRotMatrix("cribox", "cribox", 90, 0, 90, 90, 0, 0);
191
192 for( Int_t i = 1; i <= geom->GetNModules(); i++ ) {
193
194 Float_t angle = geom->GetPHOSAngle(i) ;
195 sprintf(rotname, "%s%d", "rot", number++) ;
196 new TRotMatrix(rotname, rotname, 90, angle, 0, 0, 90, 270 + angle);
197
198 top->cd();
199 sprintf(nodename,"%s%d", "Module", i) ;
200 Float_t x = r * TMath::Sin( angle / kRADDEG ) ;
201 Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
202 TNode * outerboxnode = new TNode(nodename, nodename, "OuterBox", x, y, 0, rotname ) ;
203 outerboxnode->SetLineColor(kColorPHOS) ;
204 fNodes->Add(outerboxnode) ;
205 outerboxnode->cd() ;
206
207 Float_t z = -boxparams[3] - geom->GetIPtoOuterCoverDistance() +
208 cribox[1] + geom->GetIPtoCrystalSurface() ;
209 TNode * crystalsboxnode = new TNode(nodename, nodename, "CrystalsBox", 0, 0, z) ;
210 crystalsboxnode->SetLineColor(kColorXTAL) ;
211 fNodes->Add(crystalsboxnode) ;
212 }
213
214 delete[] rotname ;
215 delete[] nodename ;
216}
217
218
219//____________________________________________________________________________
220void AliPHOSv0:: BuildGeometryforCPV(void)
221{
222 // Build the PHOS-CPV geometry for the ROOT display
223 // Author: Yuri Kharlov 11 September 2000
224 //
225 //BEGIN_HTML
226 /*
227 <H2>
228 CPV displayed by root
229 </H2>
230 <table width=700>
231
232 <tr>
233 <td>CPV perspective view</td>
234 <td>CPV front view </td>
235 </tr>
236
237 <tr>
238 <td> <img height=300 width=290 src="../images/CPVRootPersp.gif"> </td>
239 <td> <img height=300 width=290 src="../images/CPVRootFront.gif"> </td>
240 </tr>
241
242 </table>
243
244 */
245 //END_HTML
246
247 const Double_t kRADDEG = 180.0 / TMath::Pi() ;
248 const Int_t kColorCPV = kGreen ;
249 const Int_t kColorFrame = kYellow ;
250 const Int_t kColorGassiplex = kRed;
251 const Int_t kColorPCB = kCyan;
252
253 AliPHOSGeometry * geom = GetGeometry() ;
254
255 // Box for a full PHOS module
256
257 new TBRIK ("CPVBox", "CPV box", "void", geom->GetCPVBoxSize(0)/2,
258 geom->GetCPVBoxSize(1)/2,
259 geom->GetCPVBoxSize(2)/2 );
260 new TBRIK ("CPVFrameLR", "CPV frame Left-Right", "void", geom->GetCPVFrameSize(0)/2,
261 geom->GetCPVFrameSize(1)/2,
262 geom->GetCPVBoxSize(2)/2 );
263 new TBRIK ("CPVFrameUD", "CPV frame Up-Down", "void", geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0),
264 geom->GetCPVFrameSize(1)/2,
265 geom->GetCPVFrameSize(2)/2);
266 new TBRIK ("CPVPCB", "CPV PCB", "void", geom->GetCPVActiveSize(0)/2,
267 geom->GetCPVTextoliteThickness()/2,
268 geom->GetCPVActiveSize(1)/2);
269 new TBRIK ("CPVGassiplex", "CPV Gassiplex PCB", "void", geom->GetGassiplexChipSize(0)/2,
270 geom->GetGassiplexChipSize(1)/2,
271 geom->GetGassiplexChipSize(2)/2);
272
273 // position CPV into ALICE
274
275 char * nodename = new char[25] ;
276 char * rotname = new char[25] ;
277
278 Float_t r = geom->GetIPtoCPVDistance() + geom->GetCPVBoxSize(1) / 2.0 ;
279 Int_t number = 988 ;
280 TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
281
282 Int_t lastModule = 0 ;
283 lastModule = geom->GetNModules();
284
285 for( Int_t i = 1; i <= lastModule; i++ ) { // the number of PHOS modules
286
287 // One CPV module
288
289 Float_t angle = geom->GetPHOSAngle(i) ;
290 sprintf(rotname, "%s%d", "rotg", number+i) ;
291 new TRotMatrix(rotname, rotname, 90, angle, 90, 90 + angle, 0, 0);
292 top->cd();
293 sprintf(nodename, "%s%d", "CPVModule", i) ;
294 Float_t x = r * TMath::Sin( angle / kRADDEG ) ;
295 Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
296 Float_t z;
297 TNode * cpvBoxNode = new TNode(nodename , nodename ,"CPVBox", x, y, 0, rotname ) ;
298 cpvBoxNode->SetLineColor(kColorCPV) ;
299 fNodes->Add(cpvBoxNode) ;
300 cpvBoxNode->cd() ;
301
302 // inside each CPV box:
303
304 // Frame around CPV
305 Int_t j;
306 for (j=0; j<=1; j++) {
307 sprintf(nodename, "CPVModule%d Frame%d", i, j+1) ;
308 x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
309 TNode * cpvFrameNode = new TNode(nodename , nodename ,"CPVFrameLR", x, 0, 0) ;
310 cpvFrameNode->SetLineColor(kColorFrame) ;
311 fNodes->Add(cpvFrameNode) ;
312
313 sprintf(nodename, "CPVModule%d Frame%d", i, j+3) ;
314 z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
315 cpvFrameNode = new TNode(nodename , nodename ,"CPVFrameUD", 0, 0, z) ;
316 cpvFrameNode->SetLineColor(kColorFrame) ;
317 fNodes->Add(cpvFrameNode) ;
318 }
319
320 // 4 printed circuit boards
321 for (j=0; j<4; j++) {
322 sprintf(nodename, "CPVModule%d PCB%d", i, j+1) ;
323 y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(j) + geom->GetCPVTextoliteThickness()/2;
324 TNode * cpvPCBNode = new TNode(nodename , nodename ,"CPVPCB", 0, y, 0) ;
325 cpvPCBNode->SetLineColor(kColorPCB) ;
326 fNodes->Add(cpvPCBNode) ;
327 }
328
329 // Gassiplex chips
330 Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
331 Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ() + 1);
332 y = geom->GetCPVFrameSize(1)/2 - geom->GetFTPosition(0) +
333 geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
334 for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
335 x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
336 for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
337 z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
338 sprintf(nodename, "CPVModule%d Chip(%dx%d)", i, ix+1,iz+1) ;
339 TNode * cpvGassiplexNode = new TNode(nodename , nodename ,"CPVGassiplex", x, y, z) ;
340 cpvGassiplexNode->SetLineColor(kColorGassiplex) ;
341 fNodes->Add(cpvGassiplexNode) ;
342 }
343 }
344
345 } // PHOS modules
346
347 delete[] rotname ;
348 delete[] nodename ;
349}
350
351//____________________________________________________________________________
352void AliPHOSv0::CreateGeometry()
353{
354 // Create the PHOS geometry for Geant
355
356 AliPHOSv0 *phostmp = dynamic_cast<AliPHOSv0*>(gAlice->GetModule("PHOS")) ;
357
358 if ( phostmp == NULL ) {
359
360 fprintf(stderr, "PHOS detector not found!\n") ;
361 return;
362
363 }
364
365 AliPHOSGeometry * geom = GetGeometry() ;
366
367 // Get pointer to the array containing media indeces
368 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
369
370 // Create a PHOS module.
371
372 gMC->Gsvolu("PHOS", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;
373
374 this->CreateGeometryforEMC() ;
375
376 if (strstr(fTitle.Data(),"noCPV") == 0)
377 this->CreateGeometryforCPV() ;
378
379 this->CreateGeometryforSupport() ;
380
381 // --- Position PHOS mdules in ALICE setup ---
382 Int_t idrotm[99] ;
383 Int_t iXYZ,iAngle;
384 char im[5] ;
385 Bool_t anyModuleCreated=0 ;
386 for (Int_t iModule = 0; iModule < 5 ; iModule++ ) {
387 sprintf(im,"%d",iModule+1) ;
388 if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
389 continue ;
390 anyModuleCreated=1 ;
391 Float_t angle[3][2];
392 for (iXYZ=0; iXYZ<3; iXYZ++)
393 for (iAngle=0; iAngle<2; iAngle++)
394 angle[iXYZ][iAngle] = geom->GetModuleAngle(iModule,iXYZ, iAngle);
395 AliMatrix(idrotm[iModule],
396 angle[0][0],angle[0][1],
397 angle[1][0],angle[1][1],
398 angle[2][0],angle[2][1]) ;
399
400 Float_t pos[3];
401 for (iXYZ=0; iXYZ<3; iXYZ++)
402 pos[iXYZ] = geom->GetModuleCenter(iModule,iXYZ);
403 gMC->Gspos("PHOS", iModule+1, "ALIC", pos[0], pos[1], pos[2],
404 idrotm[iModule], "ONLY") ;
405 }
406 if(!anyModuleCreated)
407 AliError("No one PHOS module was created") ;
408}
409
410//____________________________________________________________________________
411void AliPHOSv0::CreateGeometryforEMC()
412{
413 // Create the PHOS-EMC geometry for GEANT
414 // Author: Dmitri Peressounko August 2001
415 // The used coordinate system:
416 // 1. in Module: X along longer side, Y out of beam, Z along shorter side (along beam)
417 // 2. In Strip the same: X along longer side, Y out of beam, Z along shorter side (along beam)
418
419
420 //BEGIN_HTML
421 /*
422 <H2>
423 Geant3 geometry tree of PHOS-EMC in ALICE
424 </H2>
425 <P><CENTER>
426 <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/EMCinAlice.gif">
427 </CENTER><P>
428 */
429 //END_HTML
430
431 // Get pointer to the array containing media indexes
432 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
433
434 AliPHOSGeometry * geom = GetGeometry() ;
435 AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
436
437 // ======= Define the strip ===============
438
439 gMC->Gsvolu("PSTR", "BOX ", idtmed[716], emcg->GetStripHalfSize(), 3) ; //Made of steel
440
441 // --- define steel volume (cell of the strip unit)
442// gMC->Gsvolu("PCEL", "BOX ", idtmed[798], emcg->GetSteelCellHalfSize(), 3);
443 gMC->Gsvolu("PCEL", "BOX ", idtmed[798], emcg->GetAirCellHalfSize(), 3);
444
445 // --- define wrapped crystal and put it into steel cell
446
447 gMC->Gsvolu("PWRA", "BOX ", idtmed[702], emcg->GetWrappedHalfSize(), 3);
448 Float_t * pin = emcg->GetAPDHalfSize() ;
449 Float_t * preamp = emcg->GetPreampHalfSize() ;
450 Float_t y = (emcg->GetAirGapLed()-2*pin[1]-2*preamp[1])/2;
451 gMC->Gspos("PWRA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
452
453 // --- Define crystal and put it into wrapped crystall ---
454 gMC->Gsvolu("PXTL", "BOX ", idtmed[699], emcg->GetCrystalHalfSize(), 3) ;
455 gMC->Gspos("PXTL", 1, "PWRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
456
457 // --- define APD/PIN preamp and put it into AirCell
458
459 gMC->Gsvolu("PPIN", "BOX ", idtmed[705], emcg->GetAPDHalfSize(), 3) ;
460 Float_t * crystal = emcg->GetCrystalHalfSize() ;
461 y = crystal[1] + emcg->GetAirGapLed() /2 - preamp[1];
462 gMC->Gspos("PPIN", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
463
464 gMC->Gsvolu("PREA", "BOX ", idtmed[711], emcg->GetPreampHalfSize(), 3) ; // Here I assumed preamp
465 // as a printed Circuit
466 y = crystal[1] + emcg->GetAirGapLed() /2 + pin[1] ; // May it should be changed
467 gMC->Gspos("PREA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ; // to ceramics?
468
469
470 // --- Fill strip with wrapped cristals in steel cells
471
472 Float_t* splate = emcg->GetSupportPlateHalfSize();
473 y = -splate[1] ;
474// Float_t* acel = emcg->GetSteelCellHalfSize() ;
475 Float_t* acel = emcg->GetAirCellHalfSize() ;
476
477 for(Int_t lev = 2, icel = 1; icel <= emcg->GetNCellsXInStrip()*emcg->GetNCellsZInStrip(); icel += 2, lev += 2){
478 Float_t x = (2*(lev / 2) - 1 - emcg->GetNCellsXInStrip())* acel[0] ;
479 Float_t z = acel[2];
480 gMC->Gspos("PCEL", icel, "PSTR", x, y, +z, 0, "ONLY") ;
481 gMC->Gspos("PCEL", icel + 1, "PSTR", x, y, -z, 0, "ONLY") ;
482 }
483
484 // --- define the support plate, hole in it and position it in strip ----
485 gMC->Gsvolu("PSUP", "BOX ", idtmed[701], emcg->GetSupportPlateHalfSize(), 3) ;
486
487 gMC->Gsvolu("PSHO", "BOX ", idtmed[798], emcg->GetSupportPlateInHalfSize(), 3) ;
488 Float_t z = emcg->GetSupportPlateThickness()/2 ;
489 gMC->Gspos("PSHO", 1, "PSUP", 0.0, 0.0, z, 0, "ONLY") ;
490
491 y = acel[1] ;
492 gMC->Gspos("PSUP", 1, "PSTR", 0.0, y, 0.0, 0, "ONLY") ;
493
494
495 // ========== Fill module with strips and put them into inner thermoinsulation=============
496 gMC->Gsvolu("PTII", "BOX ", idtmed[706], emcg->GetInnerThermoHalfSize(), 3) ;
497
498 Float_t * inthermo = emcg->GetInnerThermoHalfSize() ;
499 Float_t * strip = emcg->GetStripHalfSize() ;
500 y = inthermo[1] - strip[1] ;
501 Int_t irow;
502 Int_t nr = 1 ;
503 Int_t icol ;
504
505 for(irow = 0; irow < emcg->GetNStripX(); irow ++){
506 Float_t x = (2*irow + 1 - emcg->GetNStripX())* strip[0] ;
507 for(icol = 0; icol < emcg->GetNStripZ(); icol ++){
508 z = (2*icol + 1 - emcg->GetNStripZ()) * strip[2] ;
509 gMC->Gspos("PSTR", nr, "PTII", x, y, z, 0, "ONLY") ;
510 nr++ ;
511 }
512 }
513
514
515 // ------- define the air gap between thermoinsulation and cooler
516 gMC->Gsvolu("PAGA", "BOX ", idtmed[798], emcg->GetAirGapHalfSize(), 3) ;
517 Float_t * agap = emcg->GetAirGapHalfSize() ;
518 y = agap[1] - inthermo[1] ;
519
520 gMC->Gspos("PTII", 1, "PAGA", 0.0, y, 0.0, 0, "ONLY") ;
521
522
523
524 // ------- define the Al passive cooler
525 gMC->Gsvolu("PCOR", "BOX ", idtmed[701], emcg->GetCoolerHalfSize(), 3) ;
526 Float_t * cooler = emcg->GetCoolerHalfSize() ;
527 y = cooler[1] - agap[1] ;
528
529 gMC->Gspos("PAGA", 1, "PCOR", 0.0, y, 0.0, 0, "ONLY") ;
530
531 // ------- define the outer thermoinsulating cover
532 gMC->Gsvolu("PTIO", "TRD1", idtmed[706], emcg->GetOuterThermoParams(), 4) ;
533 Float_t * outparams = emcg->GetOuterThermoParams() ;
534
535 Int_t idrotm[99] ;
536 AliMatrix(idrotm[1], 90.0, 0.0, 0.0, 0.0, 90.0, 270.0) ;
537 // Frame in outer thermoinsulation and so on: z out of beam, y along beam, x across beam
538
539 z = outparams[3] - cooler[1] ;
540 gMC->Gspos("PCOR", 1, "PTIO", 0., 0.0, z, idrotm[1], "ONLY") ;
541
542 // -------- Define the outer Aluminium cover -----
543 gMC->Gsvolu("PCOL", "TRD1", idtmed[701], emcg->GetAlCoverParams(), 4) ;
544 Float_t * covparams = emcg->GetAlCoverParams() ;
545 z = covparams[3] - outparams[3] ;
546 gMC->Gspos("PTIO", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
547
548 // --------- Define front fiberglass cover -----------
549 gMC->Gsvolu("PFGC", "BOX ", idtmed[717], emcg->GetFiberGlassHalfSize(), 3) ;
550 z = - outparams[3] ;
551 gMC->Gspos("PFGC", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
552
553 //=============This is all with cold section==============
554
555
556 //------ Warm Section --------------
557 gMC->Gsvolu("PWAR", "BOX ", idtmed[701], emcg->GetWarmAlCoverHalfSize(), 3) ;
558 Float_t * warmcov = emcg->GetWarmAlCoverHalfSize() ;
559
560 // --- Define the outer thermoinsulation ---
561 gMC->Gsvolu("PWTI", "BOX ", idtmed[706], emcg->GetWarmThermoHalfSize(), 3) ;
562 Float_t * warmthermo = emcg->GetWarmThermoHalfSize() ;
563 z = -warmcov[2] + warmthermo[2] ;
564
565 gMC->Gspos("PWTI", 1, "PWAR", 0., 0.0, z, 0, "ONLY") ;
566
567 // --- Define cables area and put in it T-supports ----
568 gMC->Gsvolu("PCA1", "BOX ", idtmed[718], emcg->GetTCables1HalfSize(), 3) ;
569 Float_t * cbox = emcg->GetTCables1HalfSize() ;
570
571 gMC->Gsvolu("PBE1", "BOX ", idtmed[701], emcg->GetTSupport1HalfSize(), 3) ;
572 Float_t * beams = emcg->GetTSupport1HalfSize() ;
573 Int_t isup ;
574 for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
575 Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
576 gMC->Gspos("PBE1", isup, "PCA1", x, 0.0, 0.0, 0, "ONLY") ;
577 }
578
579 z = -warmthermo[2] + cbox[2];
580 gMC->Gspos("PCA1", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;
581
582 gMC->Gsvolu("PCA2", "BOX ", idtmed[718], emcg->GetTCables2HalfSize(), 3) ;
583 Float_t * cbox2 = emcg->GetTCables2HalfSize() ;
584
585 gMC->Gsvolu("PBE2", "BOX ", idtmed[701], emcg->GetTSupport2HalfSize(), 3) ;
586 for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
587 Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
588 gMC->Gspos("PBE2", isup, "PCA2", x, 0.0, 0.0, 0, "ONLY") ;
589 }
590
591 z = -warmthermo[2] + 2*cbox[2] + cbox2[2];
592 gMC->Gspos("PCA2", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;
593
594
595 // --- Define frame ---
596 gMC->Gsvolu("PFRX", "BOX ", idtmed[716], emcg->GetFrameXHalfSize(), 3) ;
597 Float_t * posit = emcg->GetFrameXPosition() ;
598 gMC->Gspos("PFRX", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
599 gMC->Gspos("PFRX", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
600
601 gMC->Gsvolu("PFRZ", "BOX ", idtmed[716], emcg->GetFrameZHalfSize(), 3) ;
602 posit = emcg->GetFrameZPosition() ;
603 gMC->Gspos("PFRZ", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
604 gMC->Gspos("PFRZ", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
605
606 // --- Define Fiber Glass support ---
607 gMC->Gsvolu("PFG1", "BOX ", idtmed[717], emcg->GetFGupXHalfSize(), 3) ;
608 posit = emcg->GetFGupXPosition() ;
609 gMC->Gspos("PFG1", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
610 gMC->Gspos("PFG1", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
611
612 gMC->Gsvolu("PFG2", "BOX ", idtmed[717], emcg->GetFGupZHalfSize(), 3) ;
613 posit = emcg->GetFGupZPosition();
614 gMC->Gspos("PFG2", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
615 gMC->Gspos("PFG2", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
616
617 gMC->Gsvolu("PFG3", "BOX ", idtmed[717], emcg->GetFGlowXHalfSize(), 3) ;
618 posit = emcg->GetFGlowXPosition() ;
619 gMC->Gspos("PFG3", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
620 gMC->Gspos("PFG3", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
621
622 gMC->Gsvolu("PFG4", "BOX ", idtmed[717], emcg->GetFGlowZHalfSize(), 3) ;
623 posit = emcg->GetFGlowZPosition() ;
624 gMC->Gspos("PFG4", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
625 gMC->Gspos("PFG4", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
626
627 // --- Define Air Gap for FEE electronics -----
628
629 gMC->Gsvolu("PAFE", "BOX ", idtmed[798], emcg->GetFEEAirHalfSize(), 3) ;
630 posit = emcg->GetFEEAirPosition() ;
631 gMC->Gspos("PAFE", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ;
632
633 // Define the EMC module volume and combine Cool and Warm sections
634
635 gMC->Gsvolu("PEMC", "TRD1", idtmed[798], emcg->GetEMCParams(), 4) ;
636
637 z = - warmcov[2] ;
638 gMC->Gspos("PCOL", 1, "PEMC", 0., 0., z, 0, "ONLY") ;
639 z = covparams[3] ;
640 gMC->Gspos("PWAR", 1, "PEMC", 0., 0., z, 0, "ONLY") ;
641
642
643 // Put created EMC geometry into PHOS volume
644
645 z = geom->GetCPVBoxSize(1) / 2. ;
646 gMC->Gspos("PEMC", 1, "PHOS", 0., 0., z, 0, "ONLY") ;
647
648}
649
650//____________________________________________________________________________
651void AliPHOSv0::CreateGeometryforCPV()
652{
653 // Create the PHOS-CPV geometry for GEANT
654 // Author: Yuri Kharlov 11 September 2000
655 //BEGIN_HTML
656 /*
657 <H2>
658 Geant3 geometry of PHOS-CPV in ALICE
659 </H2>
660 <table width=700>
661
662 <tr>
663 <td>CPV perspective view</td>
664 <td>CPV front view </td>
665 </tr>
666
667 <tr>
668 <td> <img height=300 width=290 src="../images/CPVallPersp.gif"> </td>
669 <td> <img height=300 width=290 src="../images/CPVallFront.gif"> </td>
670 </tr>
671
672 <tr>
673 <td>One CPV module, perspective view </td>
674 <td>One CPV module, front view (extended in vertical direction) </td>
675 </tr>
676
677 <tr>
678 <td><img height=300 width=290 src="../images/CPVmodulePers.gif"></td>
679 <td><img height=300 width=290 src="../images/CPVmoduleSide.gif"></td>
680 </tr>
681
682 </table>
683
684 <H2>
685 Geant3 geometry tree of PHOS-CPV in ALICE
686 </H2>
687 <center>
688 <img height=300 width=290 src="../images/CPVtree.gif">
689 </center>
690 */
691 //END_HTML
692
693 Float_t par[3], x,y,z;
694
695 // Get pointer to the array containing media indexes
696 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
697
698 AliPHOSGeometry * geom = GetGeometry() ;
699
700 // The box containing all CPV for one PHOS module filled with air
701 par[0] = geom->GetCPVBoxSize(0) / 2.0 ;
702 par[1] = geom->GetCPVBoxSize(1) / 2.0 ;
703 par[2] = geom->GetCPVBoxSize(2) / 2.0 ;
704 gMC->Gsvolu("PCPV", "BOX ", idtmed[798], par, 3) ;
705
706 Float_t * emcParams = geom->GetEMCAGeometry()->GetEMCParams() ;
707 z = - emcParams[3] ;
708 Int_t rotm ;
709 AliMatrix(rotm, 90.,0., 0., 0., 90., 90.) ;
710
711 gMC->Gspos("PCPV", 1, "PHOS", 0.0, 0.0, z, rotm, "ONLY") ;
712
713 // Gassiplex board
714
715 par[0] = geom->GetGassiplexChipSize(0)/2.;
716 par[1] = geom->GetGassiplexChipSize(1)/2.;
717 par[2] = geom->GetGassiplexChipSize(2)/2.;
718 gMC->Gsvolu("PCPC","BOX ",idtmed[707],par,3);
719
720 // Cu+Ni foil covers Gassiplex board
721
722 par[1] = geom->GetCPVCuNiFoilThickness()/2;
723 gMC->Gsvolu("PCPD","BOX ",idtmed[710],par,3);
724 y = -(geom->GetGassiplexChipSize(1)/2 - par[1]);
725 gMC->Gspos("PCPD",1,"PCPC",0,y,0,0,"ONLY");
726
727 // Position of the chip inside CPV
728
729 Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
730 Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ() + 1);
731 Int_t copy = 0;
732 y = geom->GetCPVFrameSize(1)/2 - geom->GetFTPosition(0) +
733 geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
734 for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
735 x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
736 for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
737 copy++;
738 z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
739 gMC->Gspos("PCPC",copy,"PCPV",x,y,z,0,"ONLY");
740 }
741 }
742
743 // Foiled textolite (1 mm of textolite + 50 mkm of Cu + 6 mkm of Ni)
744
745 par[0] = geom->GetCPVActiveSize(0) / 2;
746 par[1] = geom->GetCPVTextoliteThickness() / 2;
747 par[2] = geom->GetCPVActiveSize(1) / 2;
748 gMC->Gsvolu("PCPF","BOX ",idtmed[707],par,3);
749
750 // Argon gas volume
751
752 par[1] = (geom->GetFTPosition(2) - geom->GetFTPosition(1) - geom->GetCPVTextoliteThickness()) / 2;
753 gMC->Gsvolu("PCPG","BOX ",idtmed[715],par,3);
754
755 for (Int_t i=0; i<4; i++) {
756 y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(i) + geom->GetCPVTextoliteThickness()/2;
757 gMC->Gspos("PCPF",i+1,"PCPV",0,y,0,0,"ONLY");
758 if(i==1){
759 y-= (geom->GetFTPosition(2) - geom->GetFTPosition(1)) / 2;
760 gMC->Gspos("PCPG",1,"PCPV ",0,y,0,0,"ONLY");
761 }
762 }
763
764 // Dummy sensitive plane in the middle of argone gas volume
765
766 par[1]=0.001;
767 gMC->Gsvolu("PCPQ","BOX ",idtmed[715],par,3);
768 gMC->Gspos ("PCPQ",1,"PCPG",0,0,0,0,"ONLY");
769
770 // Cu+Ni foil covers textolite
771
772 par[1] = geom->GetCPVCuNiFoilThickness() / 2;
773 gMC->Gsvolu("PCP1","BOX ",idtmed[710],par,3);
774 y = geom->GetCPVTextoliteThickness()/2 - par[1];
775 gMC->Gspos ("PCP1",1,"PCPF",0,y,0,0,"ONLY");
776
777 // Aluminum frame around CPV
778
779 par[0] = geom->GetCPVFrameSize(0)/2;
780 par[1] = geom->GetCPVFrameSize(1)/2;
781 par[2] = geom->GetCPVBoxSize(2) /2;
782 gMC->Gsvolu("PCF1","BOX ",idtmed[701],par,3);
783
784 par[0] = geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0);
785 par[1] = geom->GetCPVFrameSize(1)/2;
786 par[2] = geom->GetCPVFrameSize(2)/2;
787 gMC->Gsvolu("PCF2","BOX ",idtmed[701],par,3);
788
789 for (Int_t j=0; j<=1; j++) {
790 x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
791 gMC->Gspos("PCF1",j+1,"PCPV", x,0,0,0,"ONLY");
792 z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
793 gMC->Gspos("PCF2",j+1,"PCPV",0, 0,z,0,"ONLY");
794 }
795
796}
797
798
799//____________________________________________________________________________
800void AliPHOSv0::CreateGeometryforSupport()
801{
802 // Create the PHOS' support geometry for GEANT
803 //BEGIN_HTML
804 /*
805 <H2>
806 Geant3 geometry of the PHOS's support
807 </H2>
808 <P><CENTER>
809 <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/PHOS_support.gif">
810 </CENTER><P>
811 */
812 //END_HTML
813
814 Float_t par[5], x0,y0,z0 ;
815 Int_t i,j,copy;
816
817 // Get pointer to the array containing media indexes
818 Int_t *idtmed = fIdtmed->GetArray() - 699 ;
819
820 AliPHOSGeometry * geom = GetGeometry() ;
821
822 // --- Dummy box containing two rails on which PHOS support moves
823 // --- Put these rails to the bottom of the L3 magnet
824
825 par[0] = geom->GetRailRoadSize(0) / 2.0 ;
826 par[1] = geom->GetRailRoadSize(1) / 2.0 ;
827 par[2] = geom->GetRailRoadSize(2) / 2.0 ;
828 gMC->Gsvolu("PRRD", "BOX ", idtmed[798], par, 3) ;
829
830 y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) / 2.0) ;
831 gMC->Gspos("PRRD", 1, "ALIC", 0.0, y0, 0.0, 0, "ONLY") ;
832
833 // --- Dummy box containing one rail
834
835 par[0] = geom->GetRailOuterSize(0) / 2.0 ;
836 par[1] = geom->GetRailOuterSize(1) / 2.0 ;
837 par[2] = geom->GetRailOuterSize(2) / 2.0 ;
838 gMC->Gsvolu("PRAI", "BOX ", idtmed[798], par, 3) ;
839
840 for (i=0; i<2; i++) {
841 x0 = (2*i-1) * geom->GetDistanceBetwRails() / 2.0 ;
842 gMC->Gspos("PRAI", i, "PRRD", x0, 0.0, 0.0, 0, "ONLY") ;
843 }
844
845 // --- Upper and bottom steel parts of the rail
846
847 par[0] = geom->GetRailPart1(0) / 2.0 ;
848 par[1] = geom->GetRailPart1(1) / 2.0 ;
849 par[2] = geom->GetRailPart1(2) / 2.0 ;
850 gMC->Gsvolu("PRP1", "BOX ", idtmed[716], par, 3) ;
851
852 y0 = - (geom->GetRailOuterSize(1) - geom->GetRailPart1(1)) / 2.0 ;
853 gMC->Gspos("PRP1", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
854 y0 = (geom->GetRailOuterSize(1) - geom->GetRailPart1(1)) / 2.0 - geom->GetRailPart3(1);
855 gMC->Gspos("PRP1", 2, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
856
857 // --- The middle vertical steel parts of the rail
858
859 par[0] = geom->GetRailPart2(0) / 2.0 ;
860 par[1] = geom->GetRailPart2(1) / 2.0 ;
861 par[2] = geom->GetRailPart2(2) / 2.0 ;
862 gMC->Gsvolu("PRP2", "BOX ", idtmed[716], par, 3) ;
863
864 y0 = - geom->GetRailPart3(1) / 2.0 ;
865 gMC->Gspos("PRP2", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
866
867 // --- The most upper steel parts of the rail
868
869 par[0] = geom->GetRailPart3(0) / 2.0 ;
870 par[1] = geom->GetRailPart3(1) / 2.0 ;
871 par[2] = geom->GetRailPart3(2) / 2.0 ;
872 gMC->Gsvolu("PRP3", "BOX ", idtmed[716], par, 3) ;
873
874 y0 = (geom->GetRailOuterSize(1) - geom->GetRailPart3(1)) / 2.0 ;
875 gMC->Gspos("PRP3", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
876
877 // --- The wall of the cradle
878 // --- The wall is empty: steel thin walls and air inside
879
880 par[1] = TMath::Sqrt(TMath::Power((geom->GetIPtoCPVDistance() + geom->GetOuterBoxSize(3)),2) +
881 TMath::Power((geom->GetOuterBoxSize(1)/2),2))+10. ;
882 par[0] = par[1] - geom->GetCradleWall(1) ;
883 par[2] = geom->GetCradleWall(2) / 2.0 ;
884 par[3] = geom->GetCradleWall(3) ;
885 par[4] = geom->GetCradleWall(4) ;
886 gMC->Gsvolu("PCRA", "TUBS", idtmed[716], par, 5) ;
887
888 par[0] += geom->GetCradleWallThickness() ;
889 par[1] -= geom->GetCradleWallThickness() ;
890 par[2] -= geom->GetCradleWallThickness() ;
891 gMC->Gsvolu("PCRE", "TUBS", idtmed[798], par, 5) ;
892 gMC->Gspos ("PCRE", 1, "PCRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
893
894 for (i=0; i<2; i++) {
895 z0 = (2*i-1) * (geom->GetOuterBoxSize(2) + geom->GetCradleWall(2) )/ 2.0 ;
896 gMC->Gspos("PCRA", i, "ALIC", 0.0, 0.0, z0, 0, "ONLY") ;
897 }
898
899 // --- The "wheels" of the cradle
900
901 par[0] = geom->GetCradleWheel(0) / 2;
902 par[1] = geom->GetCradleWheel(1) / 2;
903 par[2] = geom->GetCradleWheel(2) / 2;
904 gMC->Gsvolu("PWHE", "BOX ", idtmed[716], par, 3) ;
905
906 y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) -
907 geom->GetCradleWheel(1)/2) ;
908 for (i=0; i<2; i++) {
909 z0 = (2*i-1) * ((geom->GetOuterBoxSize(2) + geom->GetCradleWheel(2))/ 2.0 +
910 geom->GetCradleWall(2));
911 for (j=0; j<2; j++) {
912 copy = 2*i + j;
913 x0 = (2*j-1) * geom->GetDistanceBetwRails() / 2.0 ;
914 gMC->Gspos("PWHE", copy, "ALIC", x0, y0, z0, 0, "ONLY") ;
915 }
916 }
917
918}
919
920//_____________________________________________________________________________
921void AliPHOSv0::AddAlignableVolumes() const
922{
923 //
924 // Create entries for alignable volumes associating the symbolic volume
925 // name with the corresponding volume path. Needs to be syncronized with
926 // eventual changes in the geometry
927 // Alignable volumes are:
928 // 1) PHOS modules as a whole
929 // 2) Cradle
930 // 3) Cradle wheels
931 // 4) Strip units (group of 2x8 crystals)
932
933 TString volpath, symname;
934
935 // Alignable modules
936 // Volume path /ALIC_1/PHOS_<i> => symbolic name /PHOS/Module<i>, <i>=1,2,3,4,5
937
938 AliGeomManager::ELayerID idPHOS1 = AliGeomManager::kPHOS1;
939 AliGeomManager::ELayerID idPHOS2 = AliGeomManager::kPHOS2;
940 Int_t modUID, modnum = 0;
941 TString physModulePath="/ALIC_1/PHOS_";
942 TString symbModuleName="PHOS/Module";
943 Int_t nModules = GetGeometry()->GetNModules();
944
945 char im[5] ;
946 for(Int_t iModule=1; iModule<=nModules; iModule++){
947 sprintf(im,"%d",iModule) ;
948 modUID = AliGeomManager::LayerToVolUID(idPHOS1,modnum++);
949 if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
950 continue ;
951 volpath = physModulePath;
952 volpath += iModule;
953 // volpath += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1";
954
955 // Check the volume path if not all 5 modules exist
956 if (!gGeoManager->CheckPath(volpath.Data())) {
957 AliError(Form("Volume path %s not valid!",volpath.Data()));
958 continue;
959 }
960
961 symname = symbModuleName;
962 symname += iModule;
963 if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
964 continue ;
965// AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
966
967 // Creates the Tracking to Local transformation matrix for PHOS modules
968 TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
969
970 Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
971 TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
972
973 TGeoHMatrix *matTtoL = new TGeoHMatrix;
974 matTtoL->RotateZ(-90.+angle);
975 matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
976 alignableEntry->SetMatrix(matTtoL);
977 }
978
979 //Aligning of CPV should be done for volume PCPV_1
980 symbModuleName="PHOS/Module";
981 modnum=0;
982 for(Int_t iModule=1; iModule<=nModules; iModule++){
983 if(strstr(GetTitle(),"noCPV"))
984 continue ;
985 sprintf(im,"%d",iModule) ;
986 modUID = AliGeomManager::LayerToVolUID(idPHOS2,modnum++);
987 if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0)
988 continue ;
989 volpath = physModulePath;
990 volpath += iModule;
991 volpath += "/PCPV_1";
992 // Check the volume path
993 if (!gGeoManager->CheckPath(volpath.Data())) {
994 AliError(Form("Volume path %s not valid!",volpath.Data()));
995 continue;
996 }
997
998 symname = symbModuleName;
999 symname += iModule;
1000 symname += "/CPV";
1001 if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
1002 AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
1003
1004 // Creates the TGeo Local to Tracking transformation matrix ...
1005 TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
1006
1007 Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
1008 TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
1009
1010 TGeoHMatrix *matTtoL = new TGeoHMatrix;
1011 matTtoL->RotateZ(-90.+angle);
1012 matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
1013 alignableEntry->SetMatrix(matTtoL);
1014
1015 }
1016
1017
1018 // Alignable cradle walls
1019 // Volume path /ALIC_1/PCRA_<i> => symbolic name /PHOS/Cradle<i>, <i>=0,1
1020
1021 TString physCradlePath="/ALIC_1/PCRA_";
1022 TString symbCradleName="PHOS/Cradle";
1023 Int_t nCradles = 2;
1024
1025 for(Int_t iCradle=0; iCradle<nCradles; iCradle++){
1026 volpath = physCradlePath;
1027 volpath += iCradle;
1028 symname = symbCradleName;
1029 symname += iCradle;
1030 gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
1031 }
1032
1033 // Alignable wheels
1034 // Volume path /ALIC_1/PWHE_<i> => symbolic name /PHOS/Wheel<i>, i=0,1,2,3
1035
1036 TString physWheelPath="/ALIC_1/PWHE_";
1037 TString symbWheelName="PHOS/Wheel";
1038 Int_t nWheels = 4;
1039
1040 for(Int_t iWheel=0; iWheel<nWheels; iWheel++){
1041 volpath = physWheelPath;
1042 volpath += iWheel;
1043 symname = symbWheelName;
1044 symname += iWheel;
1045 gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
1046 }
1047
1048 //Physical strip path is a combination of: physModulePath + module number +
1049 //physStripPath + strip number == ALIC_1/PHOS_N/..../PSTR_M
1050 const Int_t nStripsX = GetGeometry()->GetEMCAGeometry()->GetNStripX();
1051 const Int_t nStripsZ = GetGeometry()->GetEMCAGeometry()->GetNStripZ();
1052 TString partialPhysStripName(100);
1053 TString fullPhysStripName(100);
1054 TString partialSymbStripName(100);
1055 TString fullSymbStripName(100);
1056
1057 for(Int_t module = 1; module <= nModules; ++module){
1058
1059 sprintf(im,"%d",module) ;
1060 if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
1061 continue ;
1062
1063 volpath = physModulePath;
1064 volpath += module;
1065 // Check the volume path if not all 5 modules exist
1066 if (!gGeoManager->CheckPath(volpath.Data())) {
1067 AliError(Form("Volume path %s does not exist",volpath.Data())) ;
1068 continue;
1069 }
1070
1071 partialPhysStripName = physModulePath;
1072 partialPhysStripName += module;
1073 partialPhysStripName += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1/PSTR_";
1074
1075 partialSymbStripName = symbModuleName;
1076 partialSymbStripName += module;
1077 partialSymbStripName += "/Strip_";
1078
1079 for(Int_t i = 0, ind1D = 1; i < nStripsX; ++i){//ind1D starts from 1 (PSTR_1...PSTR_224...)
1080 for(Int_t j = 0; j < nStripsZ; ++j, ++ind1D){
1081 fullPhysStripName = partialPhysStripName;
1082 fullPhysStripName += ind1D;
1083
1084 fullSymbStripName = partialSymbStripName;
1085 fullSymbStripName += i;//ind1D;
1086 fullSymbStripName += '_';
1087 fullSymbStripName += j;
1088
1089 gGeoManager->SetAlignableEntry(fullSymbStripName.Data(), fullPhysStripName.Data());
1090
1091 // Creates the TGeo Local to Tracking transformation matrix ...
1092 TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntry(fullSymbStripName.Data()) ;
1093 const char *path = alignableEntry->GetTitle();
1094 if (!gGeoManager->cd(path))
1095 AliFatal(Form("Volume path %s not valid!",path));
1096 TGeoHMatrix matLtoT = *gGeoManager->GetCurrentMatrix() ;
1097 Double_t refl[3]={-1.,-1.,-1.} ;
1098 matLtoT.SetScale(refl) ;
1099 TGeoHMatrix *matTtoL = new TGeoHMatrix(matLtoT.Inverse());
1100
1101 char phosPath[50] ;
1102 sprintf(phosPath,"/ALIC_1/PHOS_%d",module) ;
1103 if (!gGeoManager->cd(phosPath)){
1104 AliFatal("Geo manager can not find path \n");
1105 }
1106 TGeoHMatrix *mPHOS = gGeoManager->GetCurrentMatrix();
1107 if (mPHOS)
1108 matTtoL->Multiply(mPHOS);
1109 else{
1110 AliFatal("Geo matrixes are not loaded \n") ;
1111 }
1112 //Switch y<->z
1113 Double_t rot[9]={1.,0.,0., 0.,1.,0., 0.,0.,1.} ;
1114 matTtoL->SetRotation(rot) ;
1115 alignableEntry->SetMatrix(matTtoL);
1116
1117/*
1118 //Check poisition of corner cell of the strip
1119 AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
1120 Int_t relid[4] ;
1121 relid[0] = module ;
1122 relid[1] = 0 ;
1123 Int_t iStrip=ind1D ;
1124 Int_t icell=1 ;
1125 Int_t raw = geom->GetEMCAGeometry()->GetNCellsXInStrip()*((iStrip-1)/geom->GetEMCAGeometry()->GetNStripZ()) +
1126 1 + (icell-1)/geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
1127 Int_t col = geom->GetEMCAGeometry()->GetNCellsZInStrip()*(1+(iStrip-1)%geom->GetEMCAGeometry()->GetNStripZ()) -
1128 (icell-1)%geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
1129 if(col==0) col=geom->GetNZ() ;
1130 relid[2] = raw ;
1131 relid[3] = col ;
1132 Float_t xG,zG ;
1133 geom->RelPosInModule(relid, xG, zG) ;
1134printf("============\n") ;
1135printf("Geometry: x=%f, z=%f \n",xG,zG) ;
1136 Int_t absid ;
1137 geom->RelToAbsNumbering(relid,absid) ;
1138 Double_t pos[3]= {-2.2*3.5,0.0,1.1}; //Position incide the strip (Y coordinalte is not important)
1139 Double_t posC[3]={0.0,0.0,0.}; //Global position
1140
1141 matTtoL->MasterToLocal(pos,posC);
1142printf("Matrix: x=%f, z=%f, y=%f \n",posC[0],posC[2],posC[1]) ;
1143*/
1144 }
1145 }
1146 }
1147}
1148
1149//____________________________________________________________________________
1150Float_t AliPHOSv0::ZMin(void) const
1151{
1152 // Overall dimension of the PHOS (min)
1153
1154 AliPHOSGeometry * geom = GetGeometry() ;
1155
1156 return -geom->GetOuterBoxSize(2)/2.;
1157}
1158
1159//____________________________________________________________________________
1160Float_t AliPHOSv0::ZMax(void) const
1161{
1162 // Overall dimension of the PHOS (max)
1163
1164 AliPHOSGeometry * geom = GetGeometry() ;
1165
1166 return geom->GetOuterBoxSize(2)/2.;
1167}
1168
1169//____________________________________________________________________________
1170void AliPHOSv0::Init(void)
1171{
1172 // Just prints an information message
1173
1174 Int_t i;
1175
1176 if(AliLog::GetGlobalDebugLevel()>0) {
1177 TString st ;
1178 for(i=0;i<35;i++)
1179 st += "*";
1180 Info("Init", "%s", st.Data()) ;
1181 // Here the PHOS initialisation code (if any!)
1182
1183 AliPHOSGeometry * geom = GetGeometry() ;
1184
1185 if (geom!=0)
1186 Info("Init", "AliPHOS%s: PHOS geometry intialized for %s", Version().Data(), geom->GetName()) ;
1187 else
1188 Info("Init", "AliPHOS%s: PHOS geometry initialization failed !", Version().Data()) ;
1189
1190 Info("Init", "%s", st.Data()) ;
1191 }
1192}