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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 // TRD geometry class //
22 ///////////////////////////////////////////////////////////////////////////////
26 #include <TGeoManager.h>
27 #include <TGeoPhysicalNode.h>
28 #include <TGeoMatrix.h>
31 #include "AliRunLoader.h"
32 #include "AliTRDgeometry.h"
33 #include "AliTRDpadPlane.h"
35 #include "AliAlignObj.h"
36 #include "AliAlignObjAngles.h"
40 #include "AliTRDcalibDB.h"
41 #include "AliTRDCommonParam.h"
43 ClassImp(AliTRDgeometry)
45 //_____________________________________________________________________________
48 // The geometry constants
50 const Int_t AliTRDgeometry::fgkNsect = kNsect;
51 const Int_t AliTRDgeometry::fgkNplan = kNplan;
52 const Int_t AliTRDgeometry::fgkNcham = kNcham;
53 const Int_t AliTRDgeometry::fgkNdet = kNdet;
56 // Dimensions of the detector
59 // Inner and outer radius of the mother volumes
60 const Float_t AliTRDgeometry::fgkRmin = 294.0;
61 const Float_t AliTRDgeometry::fgkRmax = 368.0;
63 // Upper and lower length of the mother volumes
64 const Float_t AliTRDgeometry::fgkZmax1 = 378.35;
65 const Float_t AliTRDgeometry::fgkZmax2 = 302.0;
67 // Parameter of the BTR mother volumes
69 //const Float_t AliTRDgeometry::fgkSheight = 74.0;
70 const Float_t AliTRDgeometry::fgkSheight = 74.86;
71 const Float_t AliTRDgeometry::fgkSwidth1 = 99.613;
73 //const Float_t AliTRDgeometry::fgkSwidth2 = 125.707;
74 const Float_t AliTRDgeometry::fgkSwidth2 = 126.012;
75 const Float_t AliTRDgeometry::fgkSlenTR1 = 751.0;
76 const Float_t AliTRDgeometry::fgkSlenTR2 = 313.5;
77 const Float_t AliTRDgeometry::fgkSlenTR3 = 159.5;
79 // The super module side plates
80 const Float_t AliTRDgeometry::fgkSMpltT = 0.2;
81 const Float_t AliTRDgeometry::fgkSMgapT = 0.5;
83 // Height of different chamber parts
85 const Float_t AliTRDgeometry::fgkCraH = 4.8;
87 const Float_t AliTRDgeometry::fgkCdrH = 3.0;
88 // Amplification region
89 const Float_t AliTRDgeometry::fgkCamH = 0.7;
91 const Float_t AliTRDgeometry::fgkCroH = 2.316;
93 const Float_t AliTRDgeometry::fgkCH = AliTRDgeometry::fgkCraH
94 + AliTRDgeometry::fgkCdrH
95 + AliTRDgeometry::fgkCamH
96 + AliTRDgeometry::fgkCroH;
98 // Vertical spacing of the chambers
99 const Float_t AliTRDgeometry::fgkVspace = 1.784;
101 // Horizontal spacing of the chambers
102 const Float_t AliTRDgeometry::fgkHspace = 2.0;
104 // Thicknesses of different parts of the chamber frame
105 // Lower aluminum frame
106 const Float_t AliTRDgeometry::fgkCalT = 0.3;
107 // Lower G10 frame sides
108 const Float_t AliTRDgeometry::fgkCclsT = 0.3;
109 // Lower G10 frame front
110 const Float_t AliTRDgeometry::fgkCclfT = 1.0;
112 const Float_t AliTRDgeometry::fgkCcuT = 0.9;
114 const Float_t AliTRDgeometry::fgkCauT = 1.5;
116 // Additional width of the readout chamber frames
117 const Float_t AliTRDgeometry::fgkCroW = 0.9;
119 // Difference of outer chamber width and pad plane width
120 //const Float_t AliTRDgeometry::fgkCpadW = 1.0;
121 const Float_t AliTRDgeometry::fgkCpadW = 0.0;
122 const Float_t AliTRDgeometry::fgkRpadW = 1.0;
125 // Thickness of the the material layers
127 const Float_t AliTRDgeometry::fgkRaThick = 0.3646;
128 const Float_t AliTRDgeometry::fgkMyThick = 0.005;
129 const Float_t AliTRDgeometry::fgkDrThick = AliTRDgeometry::fgkCdrH;
130 const Float_t AliTRDgeometry::fgkAmThick = AliTRDgeometry::fgkCamH;
131 const Float_t AliTRDgeometry::fgkXeThick = AliTRDgeometry::fgkDrThick
132 + AliTRDgeometry::fgkAmThick;
133 const Float_t AliTRDgeometry::fgkCuThick = 0.001;
134 const Float_t AliTRDgeometry::fgkSuThick = 0.06;
135 const Float_t AliTRDgeometry::fgkFeThick = 0.0044;
136 const Float_t AliTRDgeometry::fgkCoThick = 0.02;
137 const Float_t AliTRDgeometry::fgkWaThick = 0.02;
140 // Position of the material layers
142 const Float_t AliTRDgeometry::fgkRaZpos = -1.50;
143 const Float_t AliTRDgeometry::fgkMyZpos = 0.895;
144 const Float_t AliTRDgeometry::fgkDrZpos = 2.4;
145 const Float_t AliTRDgeometry::fgkAmZpos = 0.0;
146 const Float_t AliTRDgeometry::fgkCuZpos = -0.9995;
147 const Float_t AliTRDgeometry::fgkSuZpos = 0.0000;
148 const Float_t AliTRDgeometry::fgkFeZpos = 0.0322;
149 const Float_t AliTRDgeometry::fgkCoZpos = 0.97;
150 const Float_t AliTRDgeometry::fgkWaZpos = 0.99;
152 const Double_t AliTRDgeometry::fgkTime0Base = Rmin() + CraHght() + CdrHght() + CamHght()/2.;
153 const Float_t AliTRDgeometry::fgkTime0[6] = { fgkTime0Base + 0 * (Cheight() + Cspace()),
154 fgkTime0Base + 1 * (Cheight() + Cspace()),
155 fgkTime0Base + 2 * (Cheight() + Cspace()),
156 fgkTime0Base + 3 * (Cheight() + Cspace()),
157 fgkTime0Base + 4 * (Cheight() + Cspace()),
158 fgkTime0Base + 5 * (Cheight() + Cspace()) };
160 //_____________________________________________________________________________
161 AliTRDgeometry::AliTRDgeometry():AliGeometry()
164 // AliTRDgeometry default constructor
168 fMatrixCorrectionArray = 0;
174 //_____________________________________________________________________________
175 AliTRDgeometry::~AliTRDgeometry()
178 // AliTRDgeometry destructor
182 delete fMatrixCorrectionArray;
186 //_____________________________________________________________________________
187 void AliTRDgeometry::Init()
190 // Initializes the geometry parameter
192 // The maximum number of pads
193 // and the position of pad 0,0,0
195 // chambers seen from the top:
196 // +----------------------------+
202 // +----------------------------+ +------>
204 // chambers seen from the side: ^
205 // +----------------------------+ drift|
208 // +----------------------------+ +------>
211 // IMPORTANT: time bin 0 is now the first one in the drift region
212 // closest to the readout !!!
219 // The outer width of the chambers
227 // The outer lengths of the chambers
228 // Includes the spacings between the chambers!
229 Float_t length[kNplan][kNcham] = { { 124.0, 124.0, 110.0, 124.0, 124.0 }
230 , { 124.0, 124.0, 110.0, 124.0, 124.0 }
231 , { 131.0, 131.0, 110.0, 131.0, 131.0 }
232 , { 138.0, 138.0, 110.0, 138.0, 138.0 }
233 , { 145.0, 145.0, 110.0, 145.0, 145.0 }
234 , { 147.0, 147.0, 110.0, 147.0, 147.0 } };
236 for (icham = 0; icham < kNcham; icham++) {
237 for (iplan = 0; iplan < kNplan; iplan++) {
238 fClength[iplan][icham] = length[iplan][icham];
242 // The rotation matrix elements
244 for (isect = 0; isect < fgkNsect; isect++) {
245 phi = -2.0 * TMath::Pi() / (Float_t) fgkNsect * ((Float_t) isect + 0.5);
246 fRotA11[isect] = TMath::Cos(phi);
247 fRotA12[isect] = TMath::Sin(phi);
248 fRotA21[isect] = TMath::Sin(phi);
249 fRotA22[isect] = TMath::Cos(phi);
251 fRotB11[isect] = TMath::Cos(phi);
252 fRotB12[isect] = TMath::Sin(phi);
253 fRotB21[isect] = TMath::Sin(phi);
254 fRotB22[isect] = TMath::Cos(phi);
257 for (isect = 0; isect < fgkNsect; isect++) {
258 SetSMstatus(isect,1);
263 //_____________________________________________________________________________
264 void AliTRDgeometry::CreateGeometry(Int_t *idtmed)
267 // Create the TRD geometry without hole
270 // Names of the TRD volumina (xx = detector number):
272 // Volume (Air) wrapping the readout chamber components
273 // UTxx includes: UAxx, UDxx, UFxx, UUxx
275 // UUxx the services volume has been reduced by 7.42 mm
276 // in order to allow shifts in radial direction
278 // Lower part of the readout chambers (gas volume + radiator)
280 // UAxx Aluminum frames (Al)
281 // UBxx G10 frames (C)
282 // UCxx Inner volumes (Air)
284 // Upper part of the readout chambers (readout plane + fee)
286 // UDxx G10 frames (C)
287 // UExx Inner volumes of the G10 (Air)
288 // UFxx Aluminum frames (Al)
289 // UGxx Inner volumes of the Al (Air)
291 // Inner material layers
293 // UHxx Radiator (Rohacell)
294 // UIxx Entrance window (Mylar)
295 // UJxx Drift volume (Xe/CO2)
296 // UKxx Amplification volume (Xe/CO2)
297 // ULxx Pad plane (Cu)
298 // UMxx Support structure (Rohacell)
301 const Int_t kNparTrd = 4;
302 const Int_t kNparCha = 3;
304 Float_t xpos, ypos, zpos;
306 Float_t parTrd[kNparTrd];
307 Float_t parCha[kNparCha];
312 // The TRD mother volume for one sector (Air), full length in z-direction
313 // Provides material for side plates of super module
314 parTrd[0] = fgkSwidth1/2.;
315 parTrd[1] = fgkSwidth2/2.;
316 parTrd[2] = fgkSlenTR1/2.;
317 parTrd[3] = fgkSheight/2.;
318 gMC->Gsvolu("UTR1","TRD1",idtmed[1302-1],parTrd,kNparTrd);
321 // The side plates of the super module (Al)
322 parTrd[0] = fgkSwidth1/2. - fgkSMgapT;
323 parTrd[1] = fgkSwidth2/2. - fgkSMgapT;
324 parTrd[2] = fgkSlenTR1/2.;
325 parTrd[3] = fgkSheight/2.;
326 gMC->Gsvolu("UTS1","TRD1",idtmed[1301-1],parTrd,kNparTrd);
328 // The inner part of the TRD mother volume for one sector (Air),
329 // full length in z-direction
330 parTrd[0] = fgkSwidth1/2. - fgkSMgapT - fgkSMpltT;
331 parTrd[1] = fgkSwidth2/2. - fgkSMgapT - fgkSMpltT;
332 parTrd[2] = fgkSlenTR1/2.;
333 parTrd[3] = fgkSheight/2.;
334 gMC->Gsvolu("UTI1","TRD1",idtmed[1302-1],parTrd,kNparTrd);
336 for (Int_t icham = 0; icham < kNcham; icham++) {
337 for (Int_t iplan = 0; iplan < kNplan; iplan++) {
339 Int_t iDet = GetDetectorSec(iplan,icham);
341 // The lower part of the readout chambers (gas volume + radiator)
342 // The aluminum frames
343 sprintf(cTagV,"UA%02d",iDet);
344 parCha[0] = fCwidth[iplan]/2.;
345 parCha[1] = fClength[iplan][icham]/2. - fgkHspace/2.;
346 parCha[2] = fgkCraH/2. + fgkCdrH/2.;
347 fChamberUAboxd[iDet][0] = parCha[0];
348 fChamberUAboxd[iDet][1] = parCha[1];
349 fChamberUAboxd[iDet][2] = parCha[2];
350 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parCha,kNparCha);
352 sprintf(cTagV,"UB%02d",iDet);
353 parCha[0] = fCwidth[iplan]/2. - fgkCalT;
356 gMC->Gsvolu(cTagV,"BOX ",idtmed[1307-1],parCha,kNparCha);
357 // The inner part (air)
358 sprintf(cTagV,"UC%02d",iDet);
359 parCha[0] = fCwidth[iplan]/2. - fgkCalT - fgkCclsT;
360 parCha[1] = fClength[iplan][icham]/2. - fgkHspace/2.- fgkCclfT;
362 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
364 // The upper part of the readout chambers (readout plane)
366 sprintf(cTagV,"UD%02d",iDet);
367 parCha[0] = fCwidth[iplan]/2. + fgkCroW;
368 parCha[1] = fClength[iplan][icham]/2. - fgkHspace/2.;
369 parCha[2] = fgkCamH/2.;
370 fChamberUDboxd[iDet][0] = parCha[0];
371 fChamberUDboxd[iDet][1] = parCha[1];
372 fChamberUDboxd[iDet][2] = parCha[2];
373 gMC->Gsvolu(cTagV,"BOX ",idtmed[1307-1],parCha,kNparCha);
374 // The inner part of the G10 frame (air)
375 sprintf(cTagV,"UE%02d",iDet);
376 parCha[0] = fCwidth[iplan]/2. + fgkCroW - fgkCcuT;
377 parCha[1] = fClength[iplan][icham]/2. - fgkHspace/2.- fgkCcuT;
379 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
380 // The aluminum frames
381 sprintf(cTagV,"UF%02d",iDet);
382 parCha[0] = fCwidth[iplan]/2. + fgkCroW;
383 parCha[1] = fClength[iplan][icham]/2. - fgkHspace/2.;
384 parCha[2] = fgkCroH/2.;
385 fChamberUFboxd[iDet][0] = parCha[0];
386 fChamberUFboxd[iDet][1] = parCha[1];
387 fChamberUFboxd[iDet][2] = parCha[2];
388 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parCha,kNparCha);
389 // The inner part of the aluminum frames
390 sprintf(cTagV,"UG%02d",iDet);
391 parCha[0] = fCwidth[iplan]/2. + fgkCroW - fgkCauT;
392 parCha[1] = fClength[iplan][icham]/2. - fgkHspace/2.- fgkCauT;
394 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
396 // The material layers inside the chambers
399 // Rohacell layer (radiator)
400 parCha[2] = fgkRaThick/2;
401 sprintf(cTagV,"UH%02d",iDet);
402 gMC->Gsvolu(cTagV,"BOX ",idtmed[1315-1],parCha,kNparCha);
403 // Mylar layer (entrance window + HV cathode)
404 parCha[2] = fgkMyThick/2;
405 sprintf(cTagV,"UI%02d",iDet);
406 gMC->Gsvolu(cTagV,"BOX ",idtmed[1308-1],parCha,kNparCha);
407 // Xe/Isobutane layer (drift volume)
408 parCha[2] = fgkDrThick/2.;
409 sprintf(cTagV,"UJ%02d",iDet);
410 gMC->Gsvolu(cTagV,"BOX ",idtmed[1309-1],parCha,kNparCha);
411 // Xe/Isobutane layer (amplification volume)
412 parCha[2] = fgkAmThick/2.;
413 sprintf(cTagV,"UK%02d",iDet);
414 gMC->Gsvolu(cTagV,"BOX ",idtmed[1309-1],parCha,kNparCha);
415 // Cu layer (pad plane)
416 parCha[2] = fgkCuThick/2;
417 sprintf(cTagV,"UL%02d",iDet);
418 gMC->Gsvolu(cTagV,"BOX ",idtmed[1305-1],parCha,kNparCha);
419 // G10 layer (support structure / honeycomb)
420 parCha[2] = fgkSuThick/2;
421 sprintf(cTagV,"UM%02d",iDet);
422 gMC->Gsvolu(cTagV,"BOX ",idtmed[1313-1],parCha,kNparCha);
424 // Position the layers in the chambers
428 // Rohacell layer (radiator)
430 sprintf(cTagV,"UH%02d",iDet);
431 sprintf(cTagM,"UC%02d",iDet);
432 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
433 // Mylar layer (entrance window + HV cathode)
435 sprintf(cTagV,"UI%02d",iDet);
436 sprintf(cTagM,"UC%02d",iDet);
437 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
438 // Xe/Isobutane layer (drift volume)
440 sprintf(cTagV,"UJ%02d",iDet);
441 sprintf(cTagM,"UC%02d",iDet);
442 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
444 // Xe/Isobutane layer (amplification volume)
446 sprintf(cTagV,"UK%02d",iDet);
447 sprintf(cTagM,"UE%02d",iDet);
448 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
450 // Cu layer (pad plane)
452 sprintf(cTagV,"UL%02d",iDet);
453 sprintf(cTagM,"UG%02d",iDet);
454 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
455 // G10 layer (support structure)
457 sprintf(cTagV,"UM%02d",iDet);
458 sprintf(cTagM,"UG%02d",iDet);
459 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
461 // Position the inner volumes of the chambers in the frames
465 // The inside of the lower G10 frame
466 sprintf(cTagV,"UC%02d",iDet);
467 sprintf(cTagM,"UB%02d",iDet);
468 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
469 // The lower G10 frame inside the aluminum frame
470 sprintf(cTagV,"UB%02d",iDet);
471 sprintf(cTagM,"UA%02d",iDet);
472 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
473 // The inside of the upper G10 frame
474 sprintf(cTagV,"UE%02d",iDet);
475 sprintf(cTagM,"UD%02d",iDet);
476 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
477 // The inside of the upper aluminum frame
478 sprintf(cTagV,"UG%02d",iDet);
479 sprintf(cTagM,"UF%02d",iDet);
480 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
482 // Position the frames of the chambers in the TRD mother volume
484 ypos = - fClength[iplan][0] - fClength[iplan][1] - fClength[iplan][2]/2.;
485 for (Int_t ic = 0; ic < icham; ic++) {
486 ypos += fClength[iplan][ic];
488 ypos += fClength[iplan][icham]/2.;
489 zpos = fgkCraH/2. + fgkCdrH/2. - fgkSheight/2. + iplan * (fgkCH + fgkVspace);
490 // The lower aluminum frame, radiator + drift region
491 sprintf(cTagV,"UA%02d",iDet);
492 fChamberUAorig[iDet][0] = xpos;
493 fChamberUAorig[iDet][1] = ypos;
494 fChamberUAorig[iDet][2] = zpos;
495 // The upper G10 frame, amplification region
496 sprintf(cTagV,"UD%02d",iDet);
497 zpos += fgkCamH/2. + fgkCraH/2. + fgkCdrH/2.;
498 fChamberUDorig[iDet][0] = xpos;
499 fChamberUDorig[iDet][1] = ypos;
500 fChamberUDorig[iDet][2] = zpos;
501 // The upper aluminum frame
502 sprintf(cTagV,"UF%02d",iDet);
503 zpos += fgkCroH/2. + fgkCamH/2.;
504 fChamberUForig[iDet][0] = xpos;
505 fChamberUForig[iDet][1] = ypos;
506 fChamberUForig[iDet][2] = zpos;
511 // Create the volumes of the super module frame
514 // Create the volumes of the services
515 CreateServices(idtmed);
517 for (Int_t icham = 0; icham < kNcham; icham++) {
518 for (Int_t iplan = 0; iplan < kNplan; iplan++) {
519 GroupChamber(iplan,icham,idtmed);
526 gMC->Gspos("UTI1",1,"UTS1",xpos,ypos,zpos,0,"ONLY");
531 gMC->Gspos("UTS1",1,"UTR1",xpos,ypos,zpos,0,"ONLY");
533 // Put the TRD volumes into the space frame mother volumes
534 // if enabled via status flag
538 for (Int_t isect = 0; isect < kNsect; isect++) {
539 if (fSMstatus[isect]) {
540 sprintf(cTagV,"BTRD%d",isect);
541 gMC->Gspos("UTR1",1,cTagV,xpos,ypos,zpos,0,"ONLY");
547 //_____________________________________________________________________________
548 void AliTRDgeometry::CreateFrame(Int_t *idtmed)
551 // Create the geometry of the frame of the supermodule
553 // Names of the TRD services volumina
555 // USRL Support rails for the chambers (Al)
556 // USxx Support cross bars between the chambers (Al)
568 // The chamber support rails
571 const Float_t kSRLwid = 2.0;
572 const Float_t kSRLhgt = 2.3;
573 const Float_t kSRLdst = 0.6;
574 const Int_t kNparSRL = 3;
575 Float_t parSRL[kNparSRL];
576 parSRL[0] = kSRLwid/2.;
577 parSRL[1] = fgkSlenTR1/2.;
578 parSRL[2] = kSRLhgt/2.;
579 gMC->Gsvolu("USRL","BOX ",idtmed[1301-1],parSRL,kNparSRL);
584 for (iplan = 0; iplan < kNplan; iplan++) {
586 xpos = fCwidth[iplan]/2. + kSRLwid/2. + kSRLdst;
588 zpos = fgkCraH + fgkCdrH - fgkSheight/2. - kSRLhgt/2.
589 + iplan * (fgkCH + fgkVspace);
590 gMC->Gspos("USRL",iplan+1 ,"UTI1", xpos,ypos,zpos,0,"ONLY");
591 gMC->Gspos("USRL",iplan+1+ kNplan,"UTI1",-xpos,ypos,zpos,0,"ONLY");
596 // The cross bars between the chambers
599 const Float_t kSCBwid = 1.0;
600 const Int_t kNparSCB = 3;
601 Float_t parSCB[kNparSCB];
602 parSCB[1] = kSCBwid/2.;
603 parSCB[2] = fgkCH/2.;
608 for (iplan = 0; iplan < kNplan; iplan++) {
610 parSCB[0] = fCwidth[iplan]/2. + kSRLdst/2.;
612 sprintf(cTagV,"US0%01d",iplan);
613 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
615 ypos = fgkSlenTR1/2. - kSCBwid/2.;
616 zpos = fgkCH/2. - fgkSheight/2. + iplan * (fgkCH + fgkVspace);
617 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
619 sprintf(cTagV,"US1%01d",iplan);
620 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
622 ypos = fClength[iplan][2]/2. + fClength[iplan][1];
623 zpos = fgkCH/2. - fgkSheight/2. + iplan * (fgkCH + fgkVspace);
624 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
626 sprintf(cTagV,"US2%01d",iplan);
627 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
629 ypos = fClength[iplan][2]/2.;
630 zpos = fgkCH/2. - fgkSheight/2. + iplan * (fgkCH + fgkVspace);
631 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
633 sprintf(cTagV,"US3%01d",iplan);
634 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
636 ypos = - fClength[iplan][2]/2.;
637 zpos = fgkCH/2. - fgkSheight/2. + iplan * (fgkCH + fgkVspace);
638 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
640 sprintf(cTagV,"US4%01d",iplan);
641 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
643 ypos = - fClength[iplan][2]/2. - fClength[iplan][1];
644 zpos = fgkCH/2. - fgkSheight/2. + iplan * (fgkCH + fgkVspace);
645 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
647 sprintf(cTagV,"US5%01d",iplan);
648 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
650 ypos = - fgkSlenTR1/2. + kSCBwid/2.;
651 zpos = fgkCH/2. - fgkSheight/2. + iplan * (fgkCH + fgkVspace);
652 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
658 //_____________________________________________________________________________
659 void AliTRDgeometry::CreateServices(Int_t *idtmed)
662 // Create the geometry of the services
664 // Names of the TRD services volumina
666 // UTCL Cooling arterias (Al)
667 // UTCW Cooling arterias (Water)
668 // UUxx Volumes for the services at the chambers (Air)
669 // UTPW Power bars (Cu)
670 // UTCP Cooling pipes (Al)
671 // UTCH Cooling pipes (Water)
672 // UTPL Power lines (Cu)
673 // UMCM Readout MCMs (G10/Cu/Si)
685 // The rotation matrices
686 const Int_t kNmatrix = 3;
687 Int_t matrix[kNmatrix];
688 gMC->Matrix(matrix[0],100.0, 0.0, 90.0, 90.0, 10.0, 0.0);
689 gMC->Matrix(matrix[1], 80.0, 0.0, 90.0, 90.0, 10.0,180.0);
690 gMC->Matrix(matrix[2], 0.0, 0.0, 90.0, 90.0, 90.0, 0.0);
692 AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
695 AliError("Could not get common params\n");
700 // The cooling arterias
703 // Width of the cooling arterias
704 const Float_t kCOLwid = 0.5;
705 // Height of the cooling arterias
706 const Float_t kCOLhgt = 5.5;
707 // Positioning of the cooling
708 const Float_t kCOLposx = 1.6;
709 const Float_t kCOLposz = -0.2;
710 // Thickness of the walls of the cooling arterias
711 const Float_t kCOLthk = 0.1;
712 const Int_t kNparCOL = 3;
713 Float_t parCOL[kNparCOL];
714 parCOL[0] = kCOLwid/2.;
715 parCOL[1] = fgkSlenTR1/2.;
716 parCOL[2] = kCOLhgt/2.;
717 gMC->Gsvolu("UTCL","BOX ",idtmed[1324-1],parCOL,kNparCOL);
718 parCOL[0] -= kCOLthk;
719 parCOL[1] = fgkSlenTR1/2.;
720 parCOL[2] -= kCOLthk;
721 gMC->Gsvolu("UTCW","BOX ",idtmed[1314-1],parCOL,kNparCOL);
726 gMC->Gspos("UTCW",1,"UTCL", xpos,ypos,zpos,0,"ONLY");
728 for (iplan = 0; iplan < kNplan; iplan++) { // CHECK FOR OVERLAPS !!!
729 //for (iplan = 1; iplan < kNplan; iplan++) {
731 xpos = fCwidth[iplan]/2. + kCOLwid/2. + kCOLposx;
733 zpos = kCOLhgt/2. - fgkSheight/2. + kCOLposz + iplan * (fgkCH + fgkVspace);
734 if (iplan == 0) zpos += 0.25; // To avoid overlaps !
735 gMC->Gspos("UTCL",iplan+1 ,"UTI1", xpos,ypos,zpos,matrix[0],"ONLY");
736 gMC->Gspos("UTCL",iplan+1+ kNplan,"UTI1",-xpos,ypos,zpos,matrix[1],"ONLY");
744 const Float_t kPWRwid = 0.6;
745 const Float_t kPWRhgt = 4.5;
746 const Float_t kPWRposx = 1.05;
747 const Float_t kPWRposz = 0.9;
748 const Int_t kNparPWR = 3;
749 Float_t parPWR[kNparPWR];
750 parPWR[0] = kPWRwid/2.;
751 parPWR[1] = fgkSlenTR1/2.;
752 parPWR[2] = kPWRhgt/2.;
753 gMC->Gsvolu("UTPW","BOX ",idtmed[1325-1],parPWR,kNparPWR);
755 for (iplan = 0; iplan < kNplan; iplan++) { // CHECK FOR OVERLAPS !!!
756 //for (iplan = 1; iplan < kNplan; iplan++) {
758 xpos = fCwidth[iplan]/2. + kPWRwid/2. + kPWRposx;
760 zpos = kPWRhgt/2. - fgkSheight/2. + kPWRposz + iplan * (fgkCH + fgkVspace);
761 gMC->Gspos("UTPW",iplan+1 ,"UTI1", xpos,ypos,zpos,matrix[0],"ONLY");
762 gMC->Gspos("UTPW",iplan+1+ kNplan,"UTI1",-xpos,ypos,zpos,matrix[1],"ONLY");
767 // The volumes for the services at the chambers
770 const Int_t kNparServ = 3;
771 Float_t parServ[kNparServ];
773 for (icham = 0; icham < kNcham; icham++) {
774 for (iplan = 0; iplan < kNplan; iplan++) {
775 // Take out upper plane until TRD mothervolume is adjusted
776 //for (iplan = 0; iplan < kNplan-1; iplan++) {
778 Int_t iDet = GetDetectorSec(iplan,icham);
780 sprintf(cTagV,"UU%02d",iDet);
781 parServ[0] = fCwidth[iplan]/2.;
782 parServ[1] = fClength[iplan][icham]/2. - fgkHspace/2.;
783 parServ[2] = fgkVspace/2. - 0.742/2.;
784 fChamberUUboxd[iDet][0] = parServ[0];
785 fChamberUUboxd[iDet][1] = parServ[1];
786 fChamberUUboxd[iDet][2] = parServ[2];
788 gMC->Gsvolu(cTagV,"BOX",idtmed[1302-1],parServ,kNparServ);
790 ypos = - fClength[iplan][0] - fClength[iplan][1] - fClength[iplan][2]/2.;
791 for (Int_t ic = 0; ic < icham; ic++) {
792 ypos += fClength[iplan][ic];
794 ypos += fClength[iplan][icham]/2.;
795 zpos = fgkCH + fgkVspace/2. - fgkSheight/2. + iplan * (fgkCH + fgkVspace);
797 fChamberUUorig[iDet][0] = xpos;
798 fChamberUUorig[iDet][1] = ypos;
799 fChamberUUorig[iDet][2] = zpos;
805 // The cooling pipes inside the service volumes
808 const Int_t kNparTube = 3;
809 Float_t parTube[kNparTube];
810 // The aluminum pipe for the cooling
814 gMC->Gsvolu("UTCP","TUBE",idtmed[1324-1],parTube,0);
819 gMC->Gsvolu("UTCH","TUBE",idtmed[1314-1],parTube,kNparTube);
820 // Water inside the cooling pipe
824 gMC->Gspos("UTCH",1,"UTCP",xpos,ypos,zpos,0,"ONLY");
826 // Position the cooling pipes in the mother volume
827 const Int_t kNpar = 3;
829 for (icham = 0; icham < kNcham; icham++) {
830 for (iplan = 0; iplan < kNplan; iplan++) {
831 // Take out upper plane until TRD mothervolume is adjusted
832 //for (iplan = 0; iplan < kNplan-1; iplan++) {
833 Int_t iDet = GetDetectorSec(iplan,icham);
834 Int_t iCopy = GetDetector(iplan,icham,0) * 100;
835 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
836 Float_t ySize = (GetChamberLength(iplan,icham) - 2.*fgkRpadW)
837 / ((Float_t) nMCMrow);
838 sprintf(cTagV,"UU%02d",iDet);
839 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
841 ypos = (0.5 + iMCMrow) * ySize - 1.9
842 - fClength[iplan][icham]/2. + fgkHspace/2.;
843 zpos = 0.0 + 0.742/2.;
845 par[1] = 0.3/2.; // Thickness of the cooling pipes
846 par[2] = fCwidth[iplan]/2.;
847 gMC->Gsposp("UTCP",iCopy+iMCMrow,cTagV,xpos,ypos,zpos
848 ,matrix[2],"ONLY",par,kNpar);
857 // The copper power lines
861 gMC->Gsvolu("UTPL","TUBE",idtmed[1305-1],parTube,0);
863 // Position the power lines in the mother volume
864 for (icham = 0; icham < kNcham; icham++) {
865 for (iplan = 0; iplan < kNplan; iplan++) {
866 // Take out upper plane until TRD mothervolume is adjusted
867 //for (iplan = 0; iplan < kNplan-1; iplan++) {
868 Int_t iDet = GetDetectorSec(iplan,icham);
869 Int_t iCopy = GetDetector(iplan,icham,0) * 100;
870 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
871 Float_t ySize = (GetChamberLength(iplan,icham) - 2.*fgkRpadW)
872 / ((Float_t) nMCMrow);
873 sprintf(cTagV,"UU%02d",iDet);
874 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
876 ypos = (0.5 + iMCMrow) * ySize - 1.0
877 - fClength[iplan][icham]/2. + fgkHspace/2.;
878 zpos = -0.4 + 0.742/2.;
880 par[1] = 0.2/2.; // Thickness of the power lines
881 par[2] = fCwidth[iplan]/2.;
882 gMC->Gsposp("UTPL",iCopy+iMCMrow,cTagV,xpos,ypos,zpos
883 ,matrix[2],"ONLY",par,kNpar);
892 // The mother volume for the MCMs (air)
893 const Int_t kNparMCM = 3;
894 Float_t parMCM[kNparMCM];
898 gMC->Gsvolu("UMCM","BOX",idtmed[1302-1],parMCM,kNparMCM);
900 // The MCM carrier G10 layer
904 gMC->Gsvolu("UMC1","BOX",idtmed[1319-1],parMCM,kNparMCM);
905 // The MCM carrier Cu layer
908 parMCM[2] = 0.0162/2.;
909 gMC->Gsvolu("UMC2","BOX",idtmed[1318-1],parMCM,kNparMCM);
910 // The silicon of the chips
913 parMCM[2] = 0.003/2.;
914 gMC->Gsvolu("UMC3","BOX",idtmed[1320-1],parMCM,kNparMCM);
916 // Put the MCM material inside the MCM mother volume
919 zpos = -0.07 + 0.1/2.;
920 gMC->Gspos("UMC1",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
921 zpos += 0.1/2. + 0.0162/2.;
922 gMC->Gspos("UMC2",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
923 zpos += 0.00162/2 + 0.003/2.;
924 gMC->Gspos("UMC3",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
926 // Position the MCMs in the mother volume
927 for (icham = 0; icham < kNcham; icham++) {
928 for (iplan = 0; iplan < kNplan; iplan++) {
929 // Take out upper plane until TRD mothervolume is adjusted
930 //for (iplan = 0; iplan < kNplan-1; iplan++) {
931 Int_t iDet = GetDetectorSec(iplan,icham);
932 Int_t iCopy = GetDetector(iplan,icham,0) * 1000;
933 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
934 Float_t ySize = (GetChamberLength(iplan,icham) - 2.*fgkRpadW)
935 / ((Float_t) nMCMrow);
937 Float_t xSize = (GetChamberWidth(iplan) - 2.* fgkCpadW)
938 / ((Float_t) nMCMcol);
939 sprintf(cTagV,"UU%02d",iDet);
940 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
941 for (Int_t iMCMcol = 0; iMCMcol < nMCMcol; iMCMcol++) {
942 xpos = (0.5 + iMCMcol) * xSize + 1.0
944 ypos = (0.5 + iMCMrow) * ySize + 1.0
945 - fClength[iplan][icham]/2. + fgkHspace/2.;
946 zpos = -0.4 + 0.742/2.;
948 par[1] = 0.2/2.; // Thickness of the power lines
949 par[2] = fCwidth[iplan]/2.;
950 gMC->Gspos("UMCM",iCopy+iMCMrow*10+iMCMcol,cTagV
951 ,xpos,ypos,zpos,0,"ONLY");
960 //_____________________________________________________________________________
961 void AliTRDgeometry::GroupChamber(Int_t iplan, Int_t icham, Int_t *idtmed)
964 // Group volumes UA, UD, UF, UU in a single chamber (Air)
965 // UA, UD, UF, UU are boxes
968 // ... for the moment there are no services (UU) for the upper plane !
971 const Int_t kNparCha = 3;
973 Int_t iDet = GetDetectorSec(iplan,icham);
983 for (Int_t i = 0; i < 3; i++) {
984 xyzMin[i] = +9999; xyzMax[i] = -9999;
987 for (Int_t i = 0; i < 3; i++) {
989 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUAorig[iDet][i]-fChamberUAboxd[iDet][i]);
990 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUAorig[iDet][i]+fChamberUAboxd[iDet][i]);
992 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUDorig[iDet][i]-fChamberUDboxd[iDet][i]);
993 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUDorig[iDet][i]+fChamberUDboxd[iDet][i]);
995 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUForig[iDet][i]-fChamberUFboxd[iDet][i]);
996 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUForig[iDet][i]+fChamberUFboxd[iDet][i]);
999 //if (iplan < (kNplan-1)) {
1000 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUUorig[iDet][i]-fChamberUUboxd[iDet][i]);
1001 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUUorig[iDet][i]+fChamberUUboxd[iDet][i]);
1004 xyzOrig[i] = 0.5*(xyzMax[i]+xyzMin[i]);
1005 xyzBoxd[i] = 0.5*(xyzMax[i]-xyzMin[i]);
1009 sprintf(cTagM,"UT%02d",iDet);
1011 gMC->Gsvolu(cTagM,"BOX ",idtmed[1302-1],xyzBoxd,kNparCha);
1013 sprintf(cTagV,"UA%02d",iDet);
1014 gMC->Gspos(cTagV,1,cTagM,
1015 fChamberUAorig[iDet][0]-xyzOrig[0],
1016 fChamberUAorig[iDet][1]-xyzOrig[1],
1017 fChamberUAorig[iDet][2]-xyzOrig[2],
1020 sprintf(cTagV,"UD%02d",iDet);
1021 gMC->Gspos(cTagV,1,cTagM,
1022 fChamberUDorig[iDet][0]-xyzOrig[0],
1023 fChamberUDorig[iDet][1]-xyzOrig[1],
1024 fChamberUDorig[iDet][2]-xyzOrig[2],
1027 sprintf(cTagV,"UF%02d",iDet);
1028 gMC->Gspos(cTagV,1,cTagM,
1029 fChamberUForig[iDet][0]-xyzOrig[0],
1030 fChamberUForig[iDet][1]-xyzOrig[1],
1031 fChamberUForig[iDet][2]-xyzOrig[2],
1035 //if (iplan < (kNplan-1)) {
1036 sprintf(cTagV,"UU%02d",iDet);
1037 gMC->Gspos(cTagV,1,cTagM,
1038 fChamberUUorig[iDet][0]-xyzOrig[0],
1039 fChamberUUorig[iDet][1]-xyzOrig[1],
1040 fChamberUUorig[iDet][2]-xyzOrig[2],
1045 sprintf(cTagV,"UT%02d",iDet);
1046 gMC->Gspos(cTagV,1,"UTI1",xyzOrig[0],xyzOrig[1],xyzOrig[2],0,"ONLY");
1050 //_____________________________________________________________________________
1051 Bool_t AliTRDgeometry::Local2Global(Int_t idet, Double_t *local
1052 , Double_t *global) const
1055 // Converts local pad-coordinates (row,col,time) into
1056 // global ALICE reference frame coordinates (x,y,z)
1059 Int_t icham = GetChamber(idet); // Chamber info (0-4)
1060 Int_t isect = GetSector(idet); // Sector info (0-17)
1061 Int_t iplan = GetPlane(idet); // Plane info (0-5)
1063 return Local2Global(iplan,icham,isect,local,global);
1067 //_____________________________________________________________________________
1068 Bool_t AliTRDgeometry::Local2Global(Int_t iplan, Int_t icham, Int_t isect
1069 , Double_t *local, Double_t *global) const
1072 // Converts local pad-coordinates (row,col,time) into
1073 // global ALICE reference frame coordinates (x,y,z)
1076 AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
1080 AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
1084 AliTRDpadPlane *padPlane = commonParam->GetPadPlane(iplan,icham);
1086 // calculate (x,y,z) position in rotated chamber
1087 Int_t row = ((Int_t) local[0]);
1088 Int_t col = ((Int_t) local[1]);
1089 Float_t timeSlice = local[2] + 0.5;
1090 Float_t time0 = GetTime0(iplan);
1092 Int_t idet = GetDetector(iplan, icham, isect);
1095 rot[0] = time0 - (timeSlice - calibration->GetT0(idet, col, row))
1096 * calibration->GetVdrift(idet, col, row)/calibration->GetSamplingFrequency();
1097 rot[1] = padPlane->GetColPos(col) - 0.5 * padPlane->GetColSize(col);
1098 rot[2] = padPlane->GetRowPos(row) - 0.5 * padPlane->GetRowSize(row);
1100 // Rotate back to original position
1101 return RotateBack(idet,rot,global);
1105 //_____________________________________________________________________________
1106 Bool_t AliTRDgeometry::Global2Local(Int_t mode, Double_t *local, Double_t *global
1107 , Int_t* index) const
1110 // Converts local pad-coordinates (row,col,time) into
1111 // global ALICE reference frame coordinates (x,y,z)
1113 // index[0] = plane number
1114 // index[1] = chamber number
1115 // index[2] = sector number
1117 // mode=0 - local coordinate in y, z, x - rotated global
1118 // mode=2 - local coordinate in pad, and pad row, x - rotated global
1121 Int_t idet = GetDetector(index[0],index[1],index[2]); // Detector number
1122 RotateBack(idet,global,local);
1123 if (mode == 0) return kTRUE;
1129 //_____________________________________________________________________________
1130 Bool_t AliTRDgeometry::Global2Detector(Double_t global[3], Int_t index[3])
1133 // Find detector for given global point - Ideal geometry
1136 // input = global position
1138 // index[0] = plane number
1139 // index[1] = chamber number
1140 // index[2] = sector number
1146 Float_t fi = TMath::ATan2(global[1],global[0]);
1148 fi += 2*TMath::Pi();
1150 index[2] = fgkNsect - 1 - TMath::Nint((fi - GetAlpha()/2.)/GetAlpha());
1155 Float_t locx = global[0] * fRotA11[index[2]] + global[1] * fRotA12[index[2]];
1157 Float_t max = locx - GetTime0(0);
1158 for (Int_t iplane=1; iplane<fgkNplan;iplane++){
1159 Float_t dist = TMath::Abs(locx - GetTime0(iplane));
1169 if (TMath::Abs(global[2]) < 0.5*GetChamberLength(index[0],2)){
1173 Double_t localZ = global[2];
1175 localZ -= 0.5*(GetChamberLength(index[0],2)+GetChamberLength(index[0],1));
1176 index[1] = (TMath::Abs(localZ) < 0.5*GetChamberLength(index[0],3)) ? 1:0;
1179 localZ += 0.5*(GetChamberLength(index[0],2)+GetChamberLength(index[0],3));
1180 index[1] = (TMath::Abs(localZ) < 0.5*GetChamberLength(index[0],1)) ? 3:4;
1188 //_____________________________________________________________________________
1189 Bool_t AliTRDgeometry::Rotate(Int_t d, Double_t *pos, Double_t *rot) const
1192 // Rotates all chambers in the position of sector 0 and transforms
1193 // the coordinates in the ALICE restframe <pos> into the
1194 // corresponding local frame <rot>.
1197 Int_t sector = GetSector(d);
1199 rot[0] = pos[0] * fRotA11[sector] + pos[1] * fRotA12[sector];
1200 rot[1] = -pos[0] * fRotA21[sector] + pos[1] * fRotA22[sector];
1207 //_____________________________________________________________________________
1208 Bool_t AliTRDgeometry::RotateBack(Int_t d, Double_t *rot, Double_t *pos) const
1211 // Rotates a chambers from the position of sector 0 into its
1212 // original position and transforms the corresponding local frame
1213 // coordinates <rot> into the coordinates of the ALICE restframe <pos>.
1216 Int_t sector = GetSector(d);
1218 pos[0] = rot[0] * fRotB11[sector] + rot[1] * fRotB12[sector];
1219 pos[1] = -rot[0] * fRotB21[sector] + rot[1] * fRotB22[sector];
1226 //_____________________________________________________________________________
1227 Int_t AliTRDgeometry::GetDetectorSec(Int_t p, Int_t c)
1230 // Convert plane / chamber into detector number for one single sector
1233 return (p + c * fgkNplan);
1237 //_____________________________________________________________________________
1238 Int_t AliTRDgeometry::GetDetector(Int_t p, Int_t c, Int_t s)
1241 // Convert plane / chamber / sector into detector number
1244 return (p + c * fgkNplan + s * fgkNplan * fgkNcham);
1248 //_____________________________________________________________________________
1249 Int_t AliTRDgeometry::GetPlane(Int_t d) const
1252 // Reconstruct the plane number from the detector number
1255 return ((Int_t) (d % fgkNplan));
1259 //_____________________________________________________________________________
1260 Int_t AliTRDgeometry::GetChamber(Int_t d) const
1263 // Reconstruct the chamber number from the detector number
1266 return ((Int_t) (d % (fgkNplan * fgkNcham)) / fgkNplan);
1270 //_____________________________________________________________________________
1271 Int_t AliTRDgeometry::GetSector(Int_t d) const
1274 // Reconstruct the sector number from the detector number
1277 return ((Int_t) (d / (fgkNplan * fgkNcham)));
1281 //_____________________________________________________________________________
1282 AliTRDgeometry* AliTRDgeometry::GetGeometry(AliRunLoader* runLoader)
1285 // load the geometry from the galice file
1288 if (!runLoader) runLoader = AliRunLoader::GetRunLoader();
1290 ::Error("AliTRDgeometry::GetGeometry", "No run loader");
1294 TDirectory* saveDir = gDirectory;
1295 runLoader->CdGAFile();
1297 // Try from the galice.root file
1298 AliTRDgeometry* geom = (AliTRDgeometry*) gDirectory->Get("TRDgeometry");
1301 // It is not in the file, try to get it from gAlice,
1302 // which corresponds to the run loader
1303 AliTRD * trd = (AliTRD*)runLoader->GetAliRun()->GetDetector("TRD");
1304 geom = trd->GetGeometry();
1306 if (!geom) ::Error("AliTRDgeometry::GetGeometry", "Geometry not found");
1313 //_____________________________________________________________________________
1314 Bool_t AliTRDgeometry::ReadGeoMatrices()
1317 // Read geo matrices from current gGeoManager for each TRD sector
1320 if (!gGeoManager) return kFALSE;
1321 fMatrixArray = new TObjArray(kNdet);
1322 fMatrixCorrectionArray = new TObjArray(kNdet);
1323 fMatrixGeo = new TObjArray(kNdet);
1324 AliAlignObjAngles o;
1326 for (Int_t iLayer = AliAlignObj::kTRD1; iLayer <= AliAlignObj::kTRD6; iLayer++) {
1327 for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
1328 UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,iModule);
1329 const char *path = AliAlignObj::GetVolPath(volid);
1330 if (!gGeoManager->cd(path)) return kFALSE;
1331 TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
1332 Int_t iLayerTRD = iLayer-AliAlignObj::kTRD1;
1333 Int_t isector = Nsect()-1-(iModule/Ncham());
1334 Int_t ichamber = Ncham()-1-(iModule%Ncham());
1335 Int_t lid = GetDetector(iLayerTRD,ichamber,isector);
1338 // local geo system z-x-y to x-y--z
1340 fMatrixGeo->AddAt(new TGeoHMatrix(*m),lid);
1342 TGeoRotation mchange;
1343 mchange.RotateY(90); mchange.RotateX(90);
1345 TGeoHMatrix gMatrix(mchange.Inverse());
1346 gMatrix.MultiplyLeft(m);
1347 fMatrixArray->AddAt(new TGeoHMatrix(gMatrix),lid);
1350 // Cluster transformation matrix
1352 TGeoHMatrix rotMatrix(mchange.Inverse());
1353 rotMatrix.MultiplyLeft(m);
1354 Double_t sectorAngle = 20.*(isector%18)+10;
1355 TGeoHMatrix rotSector;
1356 rotSector.RotateZ(sectorAngle);
1357 rotMatrix.MultiplyLeft(&rotSector);
1359 fMatrixCorrectionArray->AddAt(new TGeoHMatrix(rotMatrix),lid);