Line data Source code
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 <TFolder.h>
82 : #include <TGeometry.h>
83 : #include <TROOT.h>
84 : #include <TRandom.h>
85 : #include <TTree.h>
86 : #include <TVirtualMC.h>
87 : #include <TGeoPhysicalNode.h>
88 : #include <TGeoManager.h>
89 : #include <TGeoMatrix.h>
90 : #include <TVector3.h>
91 :
92 : // --- Standard library ---
93 :
94 : #include <string.h>
95 : #include <stdlib.h>
96 :
97 : // --- AliRoot header files ---
98 :
99 : #include "AliConst.h"
100 : #include "AliPHOSGeometry.h"
101 : #include "AliPHOSLoader.h"
102 : #include "AliPHOSv0.h"
103 : #include "AliRun.h"
104 : #include "AliLog.h"
105 : #include "AliGeomManager.h"
106 :
107 20 : ClassImp(AliPHOSv0)
108 :
109 : //____________________________________________________________________________
110 : AliPHOSv0::AliPHOSv0(const char *name, const char *title):
111 1 : AliPHOS(name,title),
112 1 : fCreateCPV(kFALSE),
113 1 : fCreateHalfMod(kFALSE)
114 3 : {
115 : // ctor : title is used to identify the layout
116 : //Check possible configurations
117 :
118 14 : for(Int_t mod=0; mod<6; mod++){
119 6 : fActiveModule[mod]=kFALSE ;
120 6 : fActiveCPV[mod]=kFALSE ;
121 : }
122 : //Default geometries
123 : //for period 2009-2013
124 2 : if(strstr(title,"Run1")!=0){
125 1 : fCreateCPV=kFALSE ;
126 1 : fCreateHalfMod=kFALSE;
127 1 : fActiveModule[1]=kTRUE ;
128 1 : fActiveModule[2]=kTRUE ;
129 1 : fActiveModule[3]=kTRUE ;
130 : //NO CPV in Run1
131 1 : }
132 : else{
133 : //for period 2015-2018
134 0 : if(strstr(title,"Run2")!=0){
135 0 : fCreateCPV=kTRUE ;
136 0 : fCreateHalfMod=kTRUE;
137 0 : fActiveModule[1]=kTRUE ;
138 0 : fActiveModule[2]=kTRUE ;
139 0 : fActiveModule[3]=kTRUE ;
140 0 : fActiveModule[4]=kTRUE ;
141 0 : fActiveCPV[3]=kTRUE ;
142 0 : }
143 : else{
144 : //custom geometry can be set in form
145 : //Modxxx_CPVyyy, where xxx- list of PHOS modules in geometry, yyy -list of modules with CPVallFront
146 : Bool_t isOK=kFALSE ;
147 0 : TString a(title);
148 0 : Int_t modPos=a.Index("Mod",0,TString::kIgnoreCase) ;
149 0 : Int_t cpvPos=a.Index("CPV",0,TString::kIgnoreCase) ;
150 0 : Int_t size = a.Sizeof() ;
151 0 : Int_t modEnd=(cpvPos>modPos)?cpvPos:size ;
152 0 : Int_t cpvEnd=(cpvPos>modPos)?size:modPos ;
153 0 : for(Int_t mod=1; mod<6; mod++){
154 0 : Int_t imod=a.Index(Form("%d",mod),modPos);
155 0 : if(imod>modPos && imod<modEnd){
156 0 : fActiveModule[mod]=kTRUE ;
157 : isOK=kTRUE ;
158 0 : if(mod==4)
159 0 : fCreateHalfMod=kTRUE;
160 : }
161 0 : Int_t icpv=a.Index(Form("%d",mod),cpvPos);
162 0 : if(icpv>cpvPos && icpv<cpvEnd){
163 0 : fActiveCPV[mod]=kTRUE ;
164 0 : fCreateCPV=kTRUE ;
165 0 : }
166 : }
167 0 : if(!isOK){
168 0 : AliFatal(Form("Unknown PHOS configuration: %s. Possible: 'Run1' for 2009-2013, 'Run2' for 2015-2018', 'Modxxx_CPVyyy' for castom",title)) ;
169 : }
170 0 : }
171 : }
172 :
173 1 : GetGeometry() ;
174 :
175 :
176 1 : }
177 :
178 : //____________________________________________________________________________
179 : void AliPHOSv0::CreateGeometry()
180 : {
181 : // Create the PHOS geometry for Geant
182 :
183 4 : AliPHOSv0 *phostmp = dynamic_cast<AliPHOSv0*>(gAlice->GetModule("PHOS")) ;
184 :
185 1 : if ( phostmp == NULL ) {
186 :
187 0 : fprintf(stderr, "PHOS detector not found!\n") ;
188 0 : return;
189 :
190 : }
191 :
192 1 : AliPHOSGeometry * geom = GetGeometry() ;
193 :
194 : // Get pointer to the array containing media indeces
195 1 : Int_t *idtmed = fIdtmed->GetArray() - 699 ;
196 :
197 : // Create a PHOS module.
198 :
199 1 : TVirtualMC::GetMC()->Gsvolu("PHOS", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;
200 1 : if(fCreateHalfMod){
201 0 : TVirtualMC::GetMC()->Gsvolu("PHOH", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;
202 0 : }
203 1 : if(fCreateCPV){
204 0 : TVirtualMC::GetMC()->Gsvolu("PHOC", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;
205 0 : }
206 :
207 1 : this->CreateGeometryforEMC() ;
208 : //Should we create 4-th module
209 :
210 1 : if (fCreateCPV)
211 0 : this->CreateGeometryforCPV() ;
212 :
213 1 : this->CreateGeometryforSupport() ;
214 :
215 : // --- Position PHOS mdules in ALICE setup ---
216 1 : Int_t idrotm[99] ;
217 : Int_t iXYZ,iAngle;
218 1 : char im[5] ;
219 12 : for (Int_t iModule = 0; iModule < 5 ; iModule++ ) {
220 5 : snprintf(im,5,"%d",iModule+1) ;
221 5 : if(!fActiveModule[iModule+1])
222 : continue ;
223 3 : Float_t angle[3][2];
224 24 : for (iXYZ=0; iXYZ<3; iXYZ++)
225 54 : for (iAngle=0; iAngle<2; iAngle++)
226 18 : angle[iXYZ][iAngle] = geom->GetModuleAngle(iModule,iXYZ, iAngle);
227 6 : AliMatrix(idrotm[iModule],
228 3 : angle[0][0],angle[0][1],
229 3 : angle[1][0],angle[1][1],
230 3 : angle[2][0],angle[2][1]) ;
231 :
232 3 : Float_t pos[3];
233 24 : for (iXYZ=0; iXYZ<3; iXYZ++)
234 9 : pos[iXYZ] = geom->GetModuleCenter(iModule,iXYZ);
235 3 : if(iModule==3){ //special 1/2 module
236 0 : TVirtualMC::GetMC()->Gspos("PHOH", iModule+1, "ALIC", pos[0], pos[1], pos[2],
237 0 : idrotm[iModule], "ONLY") ;
238 0 : }
239 : else{
240 6 : if(fActiveCPV[iModule+1]){ //use module with CPV
241 3 : TVirtualMC::GetMC()->Gspos("PHOC", iModule+1, "ALIC", pos[0], pos[1], pos[2],
242 3 : idrotm[iModule], "ONLY") ;
243 0 : }
244 : else{ //module wihtout CPV
245 3 : TVirtualMC::GetMC()->Gspos("PHOS", iModule+1, "ALIC", pos[0], pos[1], pos[2],
246 : idrotm[iModule], "ONLY") ;
247 : }
248 : }
249 3 : }
250 2 : }
251 :
252 : //____________________________________________________________________________
253 : void AliPHOSv0::CreateGeometryforEMC()
254 : {
255 : // Create the PHOS-EMC geometry for GEANT
256 : // Author: Dmitri Peressounko August 2001
257 : // The used coordinate system:
258 : // 1. in Module: X along longer side, Y out of beam, Z along shorter side (along beam)
259 : // 2. In Strip the same: X along longer side, Y out of beam, Z along shorter side (along beam)
260 :
261 :
262 : //BEGIN_HTML
263 : /*
264 : <H2>
265 : Geant3 geometry tree of PHOS-EMC in ALICE
266 : </H2>
267 : <P><CENTER>
268 : <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/EMCinAlice.gif">
269 : </CENTER><P>
270 : */
271 : //END_HTML
272 :
273 : // Get pointer to the array containing media indexes
274 2 : Int_t *idtmed = fIdtmed->GetArray() - 699 ;
275 :
276 1 : AliPHOSGeometry * geom = GetGeometry() ;
277 1 : AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
278 1 : Float_t par[4];
279 : Int_t ipar;
280 :
281 : // ======= Define the strip ===============
282 :
283 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetStripHalfSize() + ipar);
284 1 : TVirtualMC::GetMC()->Gsvolu("PSTR", "BOX ", idtmed[716], par, 3) ; //Made of steel
285 :
286 : // --- define steel volume (cell of the strip unit)
287 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetAirCellHalfSize() + ipar);
288 1 : TVirtualMC::GetMC()->Gsvolu("PCEL", "BOX ", idtmed[798], par, 3);
289 :
290 : // --- define wrapped crystal and put it into steel cell
291 :
292 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetWrappedHalfSize() + ipar);
293 1 : TVirtualMC::GetMC()->Gsvolu("PWRA", "BOX ", idtmed[702], par, 3);
294 1 : const Float_t * pin = emcg->GetAPDHalfSize() ;
295 1 : const Float_t * preamp = emcg->GetPreampHalfSize() ;
296 1 : Float_t y = (emcg->GetAirGapLed()-2*pin[1]-2*preamp[1])/2;
297 1 : TVirtualMC::GetMC()->Gspos("PWRA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
298 :
299 : // --- Define crystal and put it into wrapped crystall ---
300 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetCrystalHalfSize() + ipar);
301 1 : TVirtualMC::GetMC()->Gsvolu("PXTL", "BOX ", idtmed[699], par, 3) ;
302 1 : TVirtualMC::GetMC()->Gspos("PXTL", 1, "PWRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
303 :
304 : // --- define APD/PIN preamp and put it into AirCell
305 :
306 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetAPDHalfSize() + ipar);
307 1 : TVirtualMC::GetMC()->Gsvolu("PPIN", "BOX ", idtmed[705], par, 3) ;
308 1 : const Float_t * crystal = emcg->GetCrystalHalfSize() ;
309 1 : y = crystal[1] + emcg->GetAirGapLed() /2 - preamp[1];
310 1 : TVirtualMC::GetMC()->Gspos("PPIN", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
311 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetPreampHalfSize() + ipar);
312 1 : TVirtualMC::GetMC()->Gsvolu("PREA", "BOX ", idtmed[711], par, 3) ; // Here I assumed preamp as a printed Circuit
313 1 : y = crystal[1] + emcg->GetAirGapLed() /2 + pin[1] ; // May it should be changed
314 1 : TVirtualMC::GetMC()->Gspos("PREA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ; // to ceramics?
315 :
316 :
317 : // --- Fill strip with wrapped cristals in steel cells
318 :
319 1 : const Float_t* splate = emcg->GetSupportPlateHalfSize();
320 1 : y = -splate[1] ;
321 1 : const Float_t* acel = emcg->GetAirCellHalfSize() ;
322 :
323 18 : for(Int_t lev = 2, icel = 1;
324 9 : icel <= emcg->GetNCellsXInStrip()*emcg->GetNCellsZInStrip();
325 8 : icel += 2, lev += 2) {
326 8 : Float_t x = (2*(lev / 2) - 1 - emcg->GetNCellsXInStrip())* acel[0] ;
327 8 : Float_t z = acel[2];
328 8 : TVirtualMC::GetMC()->Gspos("PCEL", icel, "PSTR", x, y, +z, 0, "ONLY") ;
329 8 : TVirtualMC::GetMC()->Gspos("PCEL", icel + 1, "PSTR", x, y, -z, 0, "ONLY") ;
330 : }
331 :
332 : // --- define the support plate, hole in it and position it in strip ----
333 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetSupportPlateHalfSize() + ipar);
334 1 : TVirtualMC::GetMC()->Gsvolu("PSUP", "BOX ", idtmed[701], par, 3) ;
335 :
336 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetSupportPlateInHalfSize() + ipar);
337 1 : TVirtualMC::GetMC()->Gsvolu("PSHO", "BOX ", idtmed[798], par, 3) ;
338 1 : Float_t z = emcg->GetSupportPlateThickness()/2 ;
339 1 : TVirtualMC::GetMC()->Gspos("PSHO", 1, "PSUP", 0.0, 0.0, z, 0, "ONLY") ;
340 :
341 1 : y = acel[1] ;
342 1 : TVirtualMC::GetMC()->Gspos("PSUP", 1, "PSTR", 0.0, y, 0.0, 0, "ONLY") ;
343 :
344 :
345 : // ========== Fill module with strips and put them into inner thermoinsulation=============
346 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetInnerThermoHalfSize() + ipar);
347 1 : TVirtualMC::GetMC()->Gsvolu("PTII", "BOX ", idtmed[706], par, 3) ;
348 :
349 1 : if(fCreateHalfMod)
350 0 : TVirtualMC::GetMC()->Gsvolu("PTIH", "BOX ", idtmed[706], par, 3) ;
351 :
352 :
353 1 : const Float_t * inthermo = emcg->GetInnerThermoHalfSize() ;
354 1 : const Float_t * strip = emcg->GetStripHalfSize() ;
355 1 : y = inthermo[1] - strip[1] ;
356 : Int_t irow;
357 : Int_t nr = 1 ;
358 : Int_t icol ;
359 :
360 18 : for(irow = 0; irow < emcg->GetNStripX(); irow ++){
361 8 : Float_t x = (2*irow + 1 - emcg->GetNStripX())* strip[0] ;
362 464 : for(icol = 0; icol < emcg->GetNStripZ(); icol ++){
363 224 : z = (2*icol + 1 - emcg->GetNStripZ()) * strip[2] ;
364 224 : TVirtualMC::GetMC()->Gspos("PSTR", nr, "PTII", x, y, z, 0, "ONLY") ;
365 224 : nr++ ;
366 : }
367 : }
368 1 : if(fCreateHalfMod){
369 : nr = 1 ;
370 0 : for(irow = 0; irow < emcg->GetNStripX(); irow ++){
371 0 : Float_t x = (2*irow + 1 - emcg->GetNStripX())* strip[0] ;
372 0 : for(icol = 0; icol < emcg->GetNStripZ(); icol ++){
373 0 : z = (2*icol + 1 - emcg->GetNStripZ()) * strip[2] ;
374 0 : if(irow>=emcg->GetNStripX()/2)
375 0 : TVirtualMC::GetMC()->Gspos("PSTR", nr, "PTIH", x, y, z, 0, "ONLY") ;
376 0 : nr++ ;
377 : }
378 : }
379 : }
380 :
381 : // ------- define the air gap between thermoinsulation and cooler
382 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetAirGapHalfSize() + ipar);
383 1 : TVirtualMC::GetMC()->Gsvolu("PAGA", "BOX ", idtmed[798], par, 3) ;
384 1 : if(fCreateHalfMod)
385 0 : TVirtualMC::GetMC()->Gsvolu("PAGH", "BOX ", idtmed[798], par, 3) ;
386 1 : const Float_t * agap = emcg->GetAirGapHalfSize() ;
387 1 : y = agap[1] - inthermo[1] ;
388 :
389 1 : TVirtualMC::GetMC()->Gspos("PTII", 1, "PAGA", 0.0, y, 0.0, 0, "ONLY") ;
390 1 : if(fCreateHalfMod)
391 0 : TVirtualMC::GetMC()->Gspos("PTIH", 1, "PAGH", 0.0, y, 0.0, 0, "ONLY") ;
392 :
393 :
394 : // ------- define the Al passive cooler
395 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetCoolerHalfSize() + ipar);
396 1 : TVirtualMC::GetMC()->Gsvolu("PCOR", "BOX ", idtmed[701], par, 3) ;
397 1 : if(fCreateHalfMod)
398 0 : TVirtualMC::GetMC()->Gsvolu("PCOH", "BOX ", idtmed[701], par, 3) ;
399 :
400 1 : const Float_t * cooler = emcg->GetCoolerHalfSize() ;
401 1 : y = cooler[1] - agap[1] ;
402 :
403 1 : TVirtualMC::GetMC()->Gspos("PAGA", 1, "PCOR", 0.0, y, 0.0, 0, "ONLY") ;
404 1 : if(fCreateHalfMod)
405 0 : TVirtualMC::GetMC()->Gspos("PAGH", 1, "PCOH", 0.0, y, 0.0, 0, "ONLY") ;
406 :
407 : // ------- define the outer thermoinsulating cover
408 10 : for (ipar=0; ipar<4; ipar++) par[ipar] = *(emcg->GetOuterThermoParams() + ipar);
409 1 : TVirtualMC::GetMC()->Gsvolu("PTIO", "TRD1", idtmed[706], par, 4) ;
410 1 : if(fCreateHalfMod)
411 0 : TVirtualMC::GetMC()->Gsvolu("PIOH", "TRD1", idtmed[706], par, 4) ;
412 1 : const Float_t * outparams = emcg->GetOuterThermoParams() ;
413 :
414 1 : Int_t idrotm[99] ;
415 1 : AliMatrix(idrotm[1], 90.0, 0.0, 0.0, 0.0, 90.0, 270.0) ;
416 : // Frame in outer thermoinsulation and so on: z out of beam, y along beam, x across beam
417 :
418 1 : z = outparams[3] - cooler[1] ;
419 1 : TVirtualMC::GetMC()->Gspos("PCOR", 1, "PTIO", 0., 0.0, z, idrotm[1], "ONLY") ;
420 1 : if(fCreateHalfMod)
421 0 : TVirtualMC::GetMC()->Gspos("PCOH", 1, "PIOH", 0., 0.0, z, idrotm[1], "ONLY") ;
422 :
423 : // -------- Define the outer Aluminium cover -----
424 10 : for (ipar=0; ipar<4; ipar++) par[ipar] = *(emcg->GetAlCoverParams() + ipar);
425 1 : TVirtualMC::GetMC()->Gsvolu("PCOL", "TRD1", idtmed[701], par, 4) ;
426 1 : if(fCreateHalfMod)
427 0 : TVirtualMC::GetMC()->Gsvolu("PCLH", "TRD1", idtmed[701], par, 4) ;
428 :
429 1 : const Float_t * covparams = emcg->GetAlCoverParams() ;
430 1 : z = covparams[3] - outparams[3] ;
431 1 : TVirtualMC::GetMC()->Gspos("PTIO", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
432 1 : if(fCreateHalfMod)
433 0 : TVirtualMC::GetMC()->Gspos("PIOH", 1, "PCLH", 0., 0.0, z, 0, "ONLY") ;
434 :
435 : // --------- Define front fiberglass cover -----------
436 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFiberGlassHalfSize() + ipar);
437 1 : TVirtualMC::GetMC()->Gsvolu("PFGC", "BOX ", idtmed[717], par, 3) ;
438 1 : z = - outparams[3] ;
439 1 : TVirtualMC::GetMC()->Gspos("PFGC", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
440 1 : if(fCreateHalfMod)
441 0 : TVirtualMC::GetMC()->Gspos("PFGC", 1, "PCLH", 0., 0.0, z, 0, "ONLY") ;
442 :
443 : //=============This is all with cold section==============
444 :
445 :
446 : //------ Warm Section --------------
447 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetWarmAlCoverHalfSize() + ipar);
448 1 : TVirtualMC::GetMC()->Gsvolu("PWAR", "BOX ", idtmed[701], par, 3) ;
449 1 : const Float_t * warmcov = emcg->GetWarmAlCoverHalfSize() ;
450 :
451 : // --- Define the outer thermoinsulation ---
452 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetWarmThermoHalfSize() + ipar);
453 1 : TVirtualMC::GetMC()->Gsvolu("PWTI", "BOX ", idtmed[706], par, 3) ;
454 1 : const Float_t * warmthermo = emcg->GetWarmThermoHalfSize() ;
455 1 : z = -warmcov[2] + warmthermo[2] ;
456 :
457 1 : TVirtualMC::GetMC()->Gspos("PWTI", 1, "PWAR", 0., 0.0, z, 0, "ONLY") ;
458 :
459 : // --- Define cables area and put in it T-supports ----
460 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTCables1HalfSize() + ipar);
461 1 : TVirtualMC::GetMC()->Gsvolu("PCA1", "BOX ", idtmed[718], par, 3) ;
462 1 : const Float_t * cbox = emcg->GetTCables1HalfSize() ;
463 :
464 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTSupport1HalfSize() + ipar);
465 1 : TVirtualMC::GetMC()->Gsvolu("PBE1", "BOX ", idtmed[701], par, 3) ;
466 1 : const Float_t * beams = emcg->GetTSupport1HalfSize() ;
467 : Int_t isup ;
468 20 : for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
469 9 : Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
470 9 : TVirtualMC::GetMC()->Gspos("PBE1", isup, "PCA1", x, 0.0, 0.0, 0, "ONLY") ;
471 : }
472 :
473 1 : z = -warmthermo[2] + cbox[2];
474 1 : TVirtualMC::GetMC()->Gspos("PCA1", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;
475 :
476 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTCables2HalfSize() + ipar);
477 1 : TVirtualMC::GetMC()->Gsvolu("PCA2", "BOX ", idtmed[718], par, 3) ;
478 1 : const Float_t * cbox2 = emcg->GetTCables2HalfSize() ;
479 :
480 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetTSupport2HalfSize() + ipar);
481 1 : TVirtualMC::GetMC()->Gsvolu("PBE2", "BOX ", idtmed[701], par, 3) ;
482 20 : for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
483 9 : Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
484 9 : TVirtualMC::GetMC()->Gspos("PBE2", isup, "PCA2", x, 0.0, 0.0, 0, "ONLY") ;
485 : }
486 :
487 1 : z = -warmthermo[2] + 2*cbox[2] + cbox2[2];
488 1 : TVirtualMC::GetMC()->Gspos("PCA2", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;
489 :
490 : // --- Define frame ---
491 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFrameXHalfSize() + ipar);
492 1 : TVirtualMC::GetMC()->Gsvolu("PFRX", "BOX ", idtmed[716], par, 3) ;
493 1 : const Float_t * posit1 = emcg->GetFrameXPosition() ;
494 1 : TVirtualMC::GetMC()->Gspos("PFRX", 1, "PWTI", posit1[0], posit1[1], posit1[2], 0, "ONLY") ;
495 1 : TVirtualMC::GetMC()->Gspos("PFRX", 2, "PWTI", posit1[0], -posit1[1], posit1[2], 0, "ONLY") ;
496 :
497 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFrameZHalfSize() + ipar);
498 1 : TVirtualMC::GetMC()->Gsvolu("PFRZ", "BOX ", idtmed[716], par, 3) ;
499 1 : const Float_t * posit2 = emcg->GetFrameZPosition() ;
500 1 : TVirtualMC::GetMC()->Gspos("PFRZ", 1, "PWTI", posit2[0], posit2[1], posit2[2], 0, "ONLY") ;
501 1 : TVirtualMC::GetMC()->Gspos("PFRZ", 2, "PWTI", -posit2[0], posit2[1], posit2[2], 0, "ONLY") ;
502 :
503 : // --- Define Fiber Glass support ---
504 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGupXHalfSize() + ipar);
505 1 : TVirtualMC::GetMC()->Gsvolu("PFG1", "BOX ", idtmed[717], par, 3) ;
506 1 : const Float_t * posit3 = emcg->GetFGupXPosition() ;
507 1 : TVirtualMC::GetMC()->Gspos("PFG1", 1, "PWTI", posit3[0], posit3[1], posit3[2], 0, "ONLY") ;
508 1 : TVirtualMC::GetMC()->Gspos("PFG1", 2, "PWTI", posit3[0], -posit3[1], posit3[2], 0, "ONLY") ;
509 :
510 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGupZHalfSize() + ipar);
511 1 : TVirtualMC::GetMC()->Gsvolu("PFG2", "BOX ", idtmed[717], par, 3) ;
512 1 : const Float_t * posit4 = emcg->GetFGupZPosition();
513 1 : TVirtualMC::GetMC()->Gspos("PFG2", 1, "PWTI", posit4[0], posit4[1], posit4[2], 0, "ONLY") ;
514 1 : TVirtualMC::GetMC()->Gspos("PFG2", 2, "PWTI", -posit4[0], posit4[1], posit4[2], 0, "ONLY") ;
515 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGlowXHalfSize() + ipar);
516 1 : TVirtualMC::GetMC()->Gsvolu("PFG3", "BOX ", idtmed[717], par, 3) ;
517 1 : const Float_t * posit5 = emcg->GetFGlowXPosition() ;
518 1 : TVirtualMC::GetMC()->Gspos("PFG3", 1, "PWTI", posit5[0], posit5[1], posit5[2], 0, "ONLY") ;
519 1 : TVirtualMC::GetMC()->Gspos("PFG3", 2, "PWTI", posit5[0], -posit5[1], posit5[2], 0, "ONLY") ;
520 :
521 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFGlowZHalfSize() + ipar);
522 1 : TVirtualMC::GetMC()->Gsvolu("PFG4", "BOX ", idtmed[717], par, 3) ;
523 1 : const Float_t * posit6 = emcg->GetFGlowZPosition() ;
524 1 : TVirtualMC::GetMC()->Gspos("PFG4", 1, "PWTI", posit6[0], posit6[1], posit6[2], 0, "ONLY") ;
525 1 : TVirtualMC::GetMC()->Gspos("PFG4", 2, "PWTI", -posit6[0], posit6[1], posit6[2], 0, "ONLY") ;
526 :
527 : // --- Define Air Gap for FEE electronics -----
528 8 : for (ipar=0; ipar<3; ipar++) par[ipar] = *(emcg->GetFEEAirHalfSize() + ipar);
529 1 : TVirtualMC::GetMC()->Gsvolu("PAFE", "BOX ", idtmed[798], par, 3) ;
530 1 : const Float_t * posit7 = emcg->GetFEEAirPosition() ;
531 1 : TVirtualMC::GetMC()->Gspos("PAFE", 1, "PWTI", posit7[0], posit7[1], posit7[2], 0, "ONLY") ;
532 :
533 : // Define the EMC module volume and combine Cool and Warm sections
534 10 : for (ipar=0; ipar<4; ipar++) par[ipar] = *(emcg->GetEMCParams() + ipar);
535 1 : TVirtualMC::GetMC()->Gsvolu("PEMC", "TRD1", idtmed[798], par, 4) ;
536 1 : if(fCreateHalfMod)
537 0 : TVirtualMC::GetMC()->Gsvolu("PEMH", "TRD1", idtmed[798], par, 4) ;
538 1 : z = - warmcov[2] ;
539 1 : TVirtualMC::GetMC()->Gspos("PCOL", 1, "PEMC", 0., 0., z, 0, "ONLY") ;
540 1 : if(fCreateHalfMod)
541 0 : TVirtualMC::GetMC()->Gspos("PCLH", 1, "PEMH", 0., 0., z, 0, "ONLY") ;
542 1 : z = covparams[3] ;
543 1 : TVirtualMC::GetMC()->Gspos("PWAR", 1, "PEMC", 0., 0., z, 0, "ONLY") ;
544 1 : if(fCreateHalfMod)
545 0 : TVirtualMC::GetMC()->Gspos("PWAR", 1, "PEMH", 0., 0., z, 0, "ONLY") ;
546 :
547 :
548 : // Put created EMC geometry into PHOS volume
549 :
550 1 : z = geom->GetCPVBoxSize(1) / 2. ;
551 : //normal PHOS module
552 1 : TVirtualMC::GetMC()->Gspos("PEMC", 1, "PHOS", 0., 0., z, 0, "ONLY") ;
553 1 : if(fCreateCPV) //Module with CPV
554 0 : TVirtualMC::GetMC()->Gspos("PEMC", 1, "PHOC", 0., 0., z, 0, "ONLY") ;
555 1 : if(fCreateHalfMod) //half of PHOS module
556 0 : TVirtualMC::GetMC()->Gspos("PEMH", 1, "PHOH", 0., 0., z, 0, "ONLY") ;
557 :
558 1 : }
559 :
560 : //____________________________________________________________________________
561 : void AliPHOSv0::CreateGeometryforCPV()
562 : {
563 :
564 0 : printf("Create CPV geometry \n") ;
565 :
566 : // Create the PHOS-CPV geometry for GEANT
567 : // Author: Yuri Kharlov 11 September 2000
568 : //BEGIN_HTML
569 : /*
570 : <H2>
571 : Geant3 geometry of PHOS-CPV in ALICE
572 : </H2>
573 : <table width=700>
574 :
575 : <tr>
576 : <td>CPV perspective view</td>
577 : <td>CPV front view </td>
578 : </tr>
579 :
580 : <tr>
581 : <td> <img height=300 width=290 src="../images/CPVallPersp.gif"> </td>
582 : <td> <img height=300 width=290 src="../images/CPVallFront.gif"> </td>
583 : </tr>
584 :
585 : <tr>
586 : <td>One CPV module, perspective view </td>
587 : <td>One CPV module, front view (extended in vertical direction) </td>
588 : </tr>
589 :
590 : <tr>
591 : <td><img height=300 width=290 src="../images/CPVmodulePers.gif"></td>
592 : <td><img height=300 width=290 src="../images/CPVmoduleSide.gif"></td>
593 : </tr>
594 :
595 : </table>
596 :
597 : <H2>
598 : Geant3 geometry tree of PHOS-CPV in ALICE
599 : </H2>
600 : <center>
601 : <img height=300 width=290 src="../images/CPVtree.gif">
602 : </center>
603 : */
604 : //END_HTML
605 :
606 0 : Float_t par[3], x,y,z;
607 :
608 : // Get pointer to the array containing media indexes
609 0 : Int_t *idtmed = fIdtmed->GetArray() - 699 ;
610 :
611 0 : AliPHOSGeometry * geom = GetGeometry() ;
612 :
613 : // The box containing all CPV for one PHOS module filled with air
614 0 : par[0] = geom->GetCPVBoxSize(0) / 2.0 ;
615 0 : par[1] = geom->GetCPVBoxSize(1) / 2.0 ;
616 0 : par[2] = geom->GetCPVBoxSize(2) / 2.0 ;
617 0 : TVirtualMC::GetMC()->Gsvolu("PCPV", "BOX ", idtmed[798], par, 3) ;
618 :
619 0 : const Float_t * emcParams = geom->GetEMCAGeometry()->GetEMCParams() ;
620 0 : z = - emcParams[3] ;
621 0 : Int_t rotm ;
622 0 : AliMatrix(rotm, 90.,0., 0., 0., 90., 90.) ;
623 :
624 0 : TVirtualMC::GetMC()->Gspos("PCPV", 1, "PHOC", 0.0, 0.0, z, rotm, "ONLY") ;
625 :
626 : // Gassiplex board
627 :
628 0 : par[0] = geom->GetGassiplexChipSize(0)/2.;
629 0 : par[1] = geom->GetGassiplexChipSize(1)/2.;
630 0 : par[2] = geom->GetGassiplexChipSize(2)/2.;
631 0 : TVirtualMC::GetMC()->Gsvolu("PCPC","BOX ",idtmed[707],par,3);
632 :
633 : // Cu+Ni foil covers Gassiplex board
634 :
635 0 : par[1] = geom->GetCPVCuNiFoilThickness()/2;
636 0 : TVirtualMC::GetMC()->Gsvolu("PCPD","BOX ",idtmed[710],par,3);
637 0 : y = -(geom->GetGassiplexChipSize(1)/2 - par[1]);
638 0 : TVirtualMC::GetMC()->Gspos("PCPD",1,"PCPC",0,y,0,0,"ONLY");
639 :
640 : // Position of the chip inside CPV
641 :
642 0 : Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
643 0 : Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ() + 1);
644 : Int_t copy = 0;
645 0 : y = geom->GetCPVFrameSize(1)/2 - geom->GetFTPosition(0) +
646 0 : geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
647 0 : for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
648 0 : x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
649 0 : for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
650 0 : copy++;
651 0 : z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
652 0 : TVirtualMC::GetMC()->Gspos("PCPC",copy,"PCPV",x,y,z,0,"ONLY");
653 : }
654 : }
655 :
656 : // Foiled textolite (1 mm of textolite + 50 mkm of Cu + 6 mkm of Ni)
657 :
658 0 : par[0] = geom->GetCPVActiveSize(0) / 2;
659 0 : par[1] = geom->GetCPVTextoliteThickness() / 2;
660 0 : par[2] = geom->GetCPVActiveSize(1) / 2;
661 0 : TVirtualMC::GetMC()->Gsvolu("PCPF","BOX ",idtmed[707],par,3);
662 :
663 : // Argon gas volume
664 :
665 0 : par[1] = (geom->GetFTPosition(2) - geom->GetFTPosition(1) - geom->GetCPVTextoliteThickness()) / 2;
666 0 : TVirtualMC::GetMC()->Gsvolu("PCPG","BOX ",idtmed[715],par,3);
667 :
668 0 : for (Int_t i=0; i<4; i++) {
669 0 : y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(i) + geom->GetCPVTextoliteThickness()/2;
670 0 : TVirtualMC::GetMC()->Gspos("PCPF",i+1,"PCPV",0,y,0,0,"ONLY");
671 0 : if(i==1){
672 0 : y-= (geom->GetFTPosition(2) - geom->GetFTPosition(1)) / 2;
673 0 : TVirtualMC::GetMC()->Gspos("PCPG",1,"PCPV ",0,y,0,0,"ONLY");
674 0 : }
675 : }
676 :
677 : // Dummy sensitive plane in the middle of argone gas volume
678 :
679 0 : par[1]=0.001;
680 0 : TVirtualMC::GetMC()->Gsvolu("PCPQ","BOX ",idtmed[715],par,3);
681 0 : TVirtualMC::GetMC()->Gspos ("PCPQ",1,"PCPG",0,0,0,0,"ONLY");
682 :
683 : // Cu+Ni foil covers textolite
684 :
685 0 : par[1] = geom->GetCPVCuNiFoilThickness() / 2;
686 0 : TVirtualMC::GetMC()->Gsvolu("PCP1","BOX ",idtmed[710],par,3);
687 0 : y = geom->GetCPVTextoliteThickness()/2 - par[1];
688 0 : TVirtualMC::GetMC()->Gspos ("PCP1",1,"PCPF",0,y,0,0,"ONLY");
689 :
690 : // Aluminum frame around CPV
691 :
692 0 : par[0] = geom->GetCPVFrameSize(0)/2;
693 0 : par[1] = geom->GetCPVFrameSize(1)/2;
694 0 : par[2] = geom->GetCPVBoxSize(2) /2;
695 0 : TVirtualMC::GetMC()->Gsvolu("PCF1","BOX ",idtmed[701],par,3);
696 :
697 0 : par[0] = geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0);
698 0 : par[1] = geom->GetCPVFrameSize(1)/2;
699 0 : par[2] = geom->GetCPVFrameSize(2)/2;
700 0 : TVirtualMC::GetMC()->Gsvolu("PCF2","BOX ",idtmed[701],par,3);
701 :
702 0 : for (Int_t j=0; j<=1; j++) {
703 0 : x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
704 0 : TVirtualMC::GetMC()->Gspos("PCF1",j+1,"PCPV", x,0,0,0,"ONLY");
705 0 : z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
706 0 : TVirtualMC::GetMC()->Gspos("PCF2",j+1,"PCPV",0, 0,z,0,"ONLY");
707 : }
708 :
709 0 : }
710 :
711 :
712 : //____________________________________________________________________________
713 : void AliPHOSv0::CreateGeometryforSupport()
714 : {
715 : // Create the PHOS' support geometry for GEANT
716 : //BEGIN_HTML
717 : /*
718 : <H2>
719 : Geant3 geometry of the PHOS's support
720 : </H2>
721 : <P><CENTER>
722 : <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/PHOS_support.gif">
723 : </CENTER><P>
724 : */
725 : //END_HTML
726 :
727 2 : Float_t par[5], x0,y0,z0 ;
728 : Int_t i,j,copy;
729 :
730 : // Get pointer to the array containing media indexes
731 1 : Int_t *idtmed = fIdtmed->GetArray() - 699 ;
732 :
733 1 : AliPHOSGeometry * geom = GetGeometry() ;
734 :
735 : // --- Dummy box containing two rails on which PHOS support moves
736 : // --- Put these rails to the bottom of the L3 magnet
737 :
738 1 : par[0] = geom->GetRailRoadSize(0) / 2.0 ;
739 1 : par[1] = geom->GetRailRoadSize(1) / 2.0 ;
740 1 : par[2] = geom->GetRailRoadSize(2) / 2.0 ;
741 1 : TVirtualMC::GetMC()->Gsvolu("PRRD", "BOX ", idtmed[798], par, 3) ;
742 :
743 1 : y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) / 2.0) ;
744 1 : TVirtualMC::GetMC()->Gspos("PRRD", 1, "ALIC", 0.0, y0, 0.0, 0, "ONLY") ;
745 :
746 : // --- Dummy box containing one rail
747 :
748 1 : par[0] = geom->GetRailOuterSize(0) / 2.0 ;
749 1 : par[1] = geom->GetRailOuterSize(1) / 2.0 ;
750 1 : par[2] = geom->GetRailOuterSize(2) / 2.0 ;
751 1 : TVirtualMC::GetMC()->Gsvolu("PRAI", "BOX ", idtmed[798], par, 3) ;
752 :
753 6 : for (i=0; i<2; i++) {
754 2 : x0 = (2*i-1) * geom->GetDistanceBetwRails() / 2.0 ;
755 2 : TVirtualMC::GetMC()->Gspos("PRAI", i, "PRRD", x0, 0.0, 0.0, 0, "ONLY") ;
756 : }
757 :
758 : // --- Upper and bottom steel parts of the rail
759 :
760 1 : par[0] = geom->GetRailPart1(0) / 2.0 ;
761 1 : par[1] = geom->GetRailPart1(1) / 2.0 ;
762 1 : par[2] = geom->GetRailPart1(2) / 2.0 ;
763 1 : TVirtualMC::GetMC()->Gsvolu("PRP1", "BOX ", idtmed[716], par, 3) ;
764 :
765 1 : y0 = - (geom->GetRailOuterSize(1) - geom->GetRailPart1(1)) / 2.0 ;
766 1 : TVirtualMC::GetMC()->Gspos("PRP1", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
767 1 : y0 = (geom->GetRailOuterSize(1) - geom->GetRailPart1(1)) / 2.0 - geom->GetRailPart3(1);
768 1 : TVirtualMC::GetMC()->Gspos("PRP1", 2, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
769 :
770 : // --- The middle vertical steel parts of the rail
771 :
772 1 : par[0] = geom->GetRailPart2(0) / 2.0 ;
773 1 : par[1] = geom->GetRailPart2(1) / 2.0 ;
774 1 : par[2] = geom->GetRailPart2(2) / 2.0 ;
775 1 : TVirtualMC::GetMC()->Gsvolu("PRP2", "BOX ", idtmed[716], par, 3) ;
776 :
777 1 : y0 = - geom->GetRailPart3(1) / 2.0 ;
778 1 : TVirtualMC::GetMC()->Gspos("PRP2", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
779 :
780 : // --- The most upper steel parts of the rail
781 :
782 1 : par[0] = geom->GetRailPart3(0) / 2.0 ;
783 1 : par[1] = geom->GetRailPart3(1) / 2.0 ;
784 1 : par[2] = geom->GetRailPart3(2) / 2.0 ;
785 1 : TVirtualMC::GetMC()->Gsvolu("PRP3", "BOX ", idtmed[716], par, 3) ;
786 :
787 1 : y0 = (geom->GetRailOuterSize(1) - geom->GetRailPart3(1)) / 2.0 ;
788 1 : TVirtualMC::GetMC()->Gspos("PRP3", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
789 :
790 : // --- The wall of the cradle
791 : // --- The wall is empty: steel thin walls and air inside
792 :
793 3 : par[1] = TMath::Sqrt(TMath::Power((geom->GetIPtoCPVDistance() + geom->GetOuterBoxSize(3)),2) +
794 2 : TMath::Power((geom->GetOuterBoxSize(1)/2),2))+10. ;
795 1 : par[0] = par[1] - geom->GetCradleWall(1) ;
796 1 : par[2] = geom->GetCradleWall(2) / 2.0 ;
797 1 : par[3] = geom->GetCradleWall(3) ;
798 1 : par[4] = geom->GetCradleWall(4) ;
799 1 : TVirtualMC::GetMC()->Gsvolu("PCRA", "TUBS", idtmed[716], par, 5) ;
800 :
801 1 : par[0] += geom->GetCradleWallThickness() ;
802 1 : par[1] -= geom->GetCradleWallThickness() ;
803 1 : par[2] -= geom->GetCradleWallThickness() ;
804 1 : TVirtualMC::GetMC()->Gsvolu("PCRE", "TUBS", idtmed[798], par, 5) ;
805 1 : TVirtualMC::GetMC()->Gspos ("PCRE", 1, "PCRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
806 :
807 6 : for (i=0; i<2; i++) {
808 2 : z0 = (2*i-1) * (geom->GetOuterBoxSize(2) + geom->GetCradleWall(2) )/ 2.0 ;
809 2 : TVirtualMC::GetMC()->Gspos("PCRA", i, "ALIC", 0.0, 0.0, z0, 0, "ONLY") ;
810 : }
811 :
812 : // --- The "wheels" of the cradle
813 :
814 1 : par[0] = geom->GetCradleWheel(0) / 2;
815 1 : par[1] = geom->GetCradleWheel(1) / 2;
816 1 : par[2] = geom->GetCradleWheel(2) / 2;
817 1 : TVirtualMC::GetMC()->Gsvolu("PWHE", "BOX ", idtmed[716], par, 3) ;
818 :
819 2 : y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) -
820 1 : geom->GetCradleWheel(1)/2) ;
821 6 : for (i=0; i<2; i++) {
822 4 : z0 = (2*i-1) * ((geom->GetOuterBoxSize(2) + geom->GetCradleWheel(2))/ 2.0 +
823 2 : geom->GetCradleWall(2));
824 12 : for (j=0; j<2; j++) {
825 4 : copy = 2*i + j;
826 4 : x0 = (2*j-1) * geom->GetDistanceBetwRails() / 2.0 ;
827 4 : TVirtualMC::GetMC()->Gspos("PWHE", copy, "ALIC", x0, y0, z0, 0, "ONLY") ;
828 : }
829 : }
830 :
831 1 : }
832 :
833 : //_____________________________________________________________________________
834 : void AliPHOSv0::AddAlignableVolumes() const
835 : {
836 : //
837 : // Create entries for alignable volumes associating the symbolic volume
838 : // name with the corresponding volume path. Needs to be syncronized with
839 : // eventual changes in the geometry
840 : // Alignable volumes are:
841 : // 1) PHOS modules as a whole
842 : // 2) Cradle
843 : // 3) Cradle wheels
844 : // 4) Strip units (group of 2x8 crystals)
845 :
846 2 : TString volpath, symname;
847 :
848 : // Alignable modules
849 : // Volume path /ALIC_1/PHOS_<i> => symbolic name /PHOS/Module<i>, <i>=1,2,3,4,5
850 :
851 : AliGeomManager::ELayerID idPHOS1 = AliGeomManager::kPHOS1;
852 : AliGeomManager::ELayerID idPHOS2 = AliGeomManager::kPHOS2;
853 : Int_t modUID, modnum = 0;
854 1 : TString physModulePath="/ALIC_1/PHOS_";
855 1 : TString physModulePath2="/ALIC_1/PHOH_";
856 1 : TString physModulePath3="/ALIC_1/PHOC_";
857 1 : TString symbModuleName="PHOS/Module";
858 2 : Int_t nModules = GetGeometry()->GetNModules();
859 :
860 12 : for(Int_t iModule=1; iModule<=nModules; iModule++){
861 5 : if(!fActiveModule[iModule])
862 : continue ;
863 6 : modUID = AliGeomManager::LayerToVolUID(idPHOS1,iModule-1);
864 3 : if(iModule==4)
865 0 : volpath = physModulePath2;
866 : else
867 3 : if(fActiveCPV[iModule])
868 0 : volpath = physModulePath3;
869 : else
870 3 : volpath = physModulePath;
871 3 : volpath += iModule;
872 : // volpath += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1";
873 :
874 : // Check the volume path if not all 5 modules exist
875 9 : if (!gGeoManager->CheckPath(volpath.Data())) {
876 0 : AliError(Form("Volume path %s not valid!",volpath.Data()));
877 : continue;
878 : }
879 :
880 3 : symname = symbModuleName;
881 3 : symname += iModule;
882 12 : if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
883 : continue ;
884 : // AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
885 :
886 : // Creates the Tracking to Local transformation matrix for PHOS modules
887 3 : TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
888 :
889 6 : Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
890 3 : TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
891 :
892 6 : TGeoHMatrix *matTtoL = new TGeoHMatrix;
893 3 : matTtoL->RotateZ(-90.+angle);
894 6 : matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
895 3 : alignableEntry->SetMatrix(matTtoL);
896 3 : }
897 :
898 : //Aligning of CPV should be done for volume PCPV_1
899 1 : symbModuleName="PHOS/Module";
900 : modnum=0;
901 12 : for(Int_t iModule=1; iModule<=nModules; iModule++){
902 5 : if(!fActiveCPV[iModule])
903 : continue ;
904 0 : modUID = AliGeomManager::LayerToVolUID(idPHOS2,iModule-1);
905 0 : volpath = physModulePath3;
906 0 : volpath += iModule;
907 0 : volpath += "/PCPV_1";
908 : // Check the volume path
909 0 : if (!gGeoManager->CheckPath(volpath.Data())) {
910 0 : AliError(Form("Volume path %s not valid!",volpath.Data()));
911 : continue;
912 : }
913 :
914 0 : symname = symbModuleName;
915 0 : symname += iModule;
916 0 : symname += "/CPV";
917 0 : if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
918 0 : AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
919 :
920 : // Creates the TGeo Local to Tracking transformation matrix ...
921 0 : TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
922 :
923 0 : Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
924 0 : TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
925 :
926 0 : TGeoHMatrix *matTtoL = new TGeoHMatrix;
927 0 : matTtoL->RotateZ(-90.+angle);
928 0 : matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
929 0 : alignableEntry->SetMatrix(matTtoL);
930 :
931 0 : }
932 :
933 :
934 : // Alignable cradle walls
935 : // Volume path /ALIC_1/PCRA_<i> => symbolic name /PHOS/Cradle<i>, <i>=0,1
936 :
937 1 : TString physCradlePath="/ALIC_1/PCRA_";
938 1 : TString symbCradleName="PHOS/Cradle";
939 : Int_t nCradles = 2;
940 :
941 6 : for(Int_t iCradle=0; iCradle<nCradles; iCradle++){
942 2 : volpath = physCradlePath;
943 2 : volpath += iCradle;
944 2 : symname = symbCradleName;
945 2 : symname += iCradle;
946 6 : gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
947 : }
948 :
949 : // Alignable wheels
950 : // Volume path /ALIC_1/PWHE_<i> => symbolic name /PHOS/Wheel<i>, i=0,1,2,3
951 :
952 1 : TString physWheelPath="/ALIC_1/PWHE_";
953 1 : TString symbWheelName="PHOS/Wheel";
954 : Int_t nWheels = 4;
955 :
956 10 : for(Int_t iWheel=0; iWheel<nWheels; iWheel++){
957 4 : volpath = physWheelPath;
958 4 : volpath += iWheel;
959 4 : symname = symbWheelName;
960 4 : symname += iWheel;
961 12 : gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
962 : }
963 :
964 :
965 : /*
966 : //Physical strip path is a combination of: physModulePath + module number +
967 : //physStripPath + strip number == ALIC_1/PHOS_N/..../PSTR_M
968 : const Int_t nStripsX = GetGeometry()->GetEMCAGeometry()->GetNStripX();
969 : const Int_t nStripsZ = GetGeometry()->GetEMCAGeometry()->GetNStripZ();
970 : TString partialPhysStripName(100);
971 : TString fullPhysStripName(100);
972 : TString partialSymbStripName(100);
973 : TString fullSymbStripName(100);
974 :
975 : for(Int_t module = 1; module <= nModules; ++module){
976 :
977 : snprintf(im,5,"%d",module) ;
978 : if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
979 : continue ;
980 :
981 : volpath = physModulePath;
982 : volpath += module;
983 : // Check the volume path if not all 5 modules exist
984 : if (!gGeoManager->CheckPath(volpath.Data())) {
985 : AliError(Form("Volume path %s does not exist",volpath.Data())) ;
986 : continue;
987 : }
988 :
989 : partialPhysStripName = physModulePath;
990 : partialPhysStripName += module;
991 : if(module!=4)
992 : partialPhysStripName += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1/PSTR_";
993 : else
994 : partialPhysStripName += "/PEMH_1/PCLH_1/PIOH_1/PCOH_1/PAGH_1/PTIH_1/PSTR_";
995 :
996 : partialSymbStripName = symbModuleName;
997 : partialSymbStripName += module;
998 : partialSymbStripName += "/Strip_";
999 :
1000 : for(Int_t i = 0, ind1D = 1; i < nStripsX; ++i){//ind1D starts from 1 (PSTR_1...PSTR_224...)
1001 : for(Int_t j = 0; j < nStripsZ; ++j, ++ind1D){
1002 : fullPhysStripName = partialPhysStripName;
1003 : fullPhysStripName += ind1D;
1004 :
1005 : fullSymbStripName = partialSymbStripName;
1006 : fullSymbStripName += i;//ind1D;
1007 : fullSymbStripName += '_';
1008 : fullSymbStripName += j;
1009 :
1010 : gGeoManager->SetAlignableEntry(fullSymbStripName.Data(), fullPhysStripName.Data());
1011 :
1012 : // Creates the TGeo Local to Tracking transformation matrix ...
1013 : TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntry(fullSymbStripName.Data()) ;
1014 : const char *path = alignableEntry->GetTitle();
1015 : if (!gGeoManager->cd(path))
1016 : AliFatal(Form("Volume path %s not valid!",path));
1017 : TGeoHMatrix matLtoT = *gGeoManager->GetCurrentMatrix() ;
1018 : Double_t refl[3]={-1.,-1.,-1.} ;
1019 : matLtoT.SetScale(refl) ;
1020 : TGeoHMatrix *matTtoL = new TGeoHMatrix(matLtoT.Inverse());
1021 :
1022 : char phosPath[50] ;
1023 : snprintf(phosPath,50,"/ALIC_1/PHOS_%d",module) ;
1024 : if (!gGeoManager->cd(phosPath)){
1025 : AliFatal("Geo manager can not find path \n");
1026 : }
1027 : TGeoHMatrix *mPHOS = gGeoManager->GetCurrentMatrix();
1028 : if (mPHOS)
1029 : matTtoL->Multiply(mPHOS);
1030 : else{
1031 : AliFatal("Geo matrixes are not loaded \n") ;
1032 : }
1033 : //Switch y<->z
1034 : Double_t rot[9]={1.,0.,0., 0.,1.,0., 0.,0.,1.} ;
1035 : matTtoL->SetRotation(rot) ;
1036 : alignableEntry->SetMatrix(matTtoL);
1037 : */
1038 : /*
1039 : //Check poisition of corner cell of the strip
1040 : AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
1041 : Int_t relid[4] ;
1042 : relid[0] = module ;
1043 : relid[1] = 0 ;
1044 : Int_t iStrip=ind1D ;
1045 : Int_t icell=1 ;
1046 : Int_t raw = geom->GetEMCAGeometry()->GetNCellsXInStrip()*((iStrip-1)/geom->GetEMCAGeometry()->GetNStripZ()) +
1047 : 1 + (icell-1)/geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
1048 : Int_t col = geom->GetEMCAGeometry()->GetNCellsZInStrip()*(1+(iStrip-1)%geom->GetEMCAGeometry()->GetNStripZ()) -
1049 : (icell-1)%geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
1050 : if(col==0) col=geom->GetNZ() ;
1051 : relid[2] = raw ;
1052 : relid[3] = col ;
1053 : Float_t xG,zG ;
1054 : geom->RelPosInModule(relid, xG, zG) ;
1055 : printf("============\n") ;
1056 : printf("Geometry: x=%f, z=%f \n",xG,zG) ;
1057 : Int_t absid ;
1058 : geom->RelToAbsNumbering(relid,absid) ;
1059 : Double_t pos[3]= {-2.2*3.5,0.0,1.1}; //Position incide the strip (Y coordinalte is not important)
1060 : Double_t posC[3]={0.0,0.0,0.}; //Global position
1061 :
1062 : matTtoL->MasterToLocal(pos,posC);
1063 : printf("Matrix: x=%f, z=%f, y=%f \n",posC[0],posC[2],posC[1]) ;
1064 : */
1065 : // }
1066 : // }
1067 : // }
1068 1 : }
1069 :
1070 : //____________________________________________________________________________
1071 : Float_t AliPHOSv0::ZMin(void) const
1072 : {
1073 : // Overall dimension of the PHOS (min)
1074 :
1075 0 : AliPHOSGeometry * geom = GetGeometry() ;
1076 :
1077 0 : return -geom->GetOuterBoxSize(2)/2.;
1078 : }
1079 :
1080 : //____________________________________________________________________________
1081 : Float_t AliPHOSv0::ZMax(void) const
1082 : {
1083 : // Overall dimension of the PHOS (max)
1084 :
1085 0 : AliPHOSGeometry * geom = GetGeometry() ;
1086 :
1087 0 : return geom->GetOuterBoxSize(2)/2.;
1088 : }
1089 :
1090 : //____________________________________________________________________________
1091 : void AliPHOSv0::Init(void)
1092 : {
1093 : // Just prints an information message
1094 :
1095 : Int_t i;
1096 :
1097 2 : if(AliLog::GetGlobalDebugLevel()>0) {
1098 0 : TString st ;
1099 0 : for(i=0;i<35;i++)
1100 0 : st += "*";
1101 0 : Info("Init", "%s", st.Data()) ;
1102 : // Here the PHOS initialisation code (if any!)
1103 :
1104 0 : AliPHOSGeometry * geom = GetGeometry() ;
1105 :
1106 0 : if (geom!=0)
1107 0 : Info("Init", "AliPHOS%s: PHOS geometry intialized for %s", Version().Data(), geom->GetName()) ;
1108 : else
1109 0 : Info("Init", "AliPHOS%s: PHOS geometry initialization failed !", Version().Data()) ;
1110 :
1111 0 : Info("Init", "%s", st.Data()) ;
1112 0 : }
1113 1 : }
|