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 ///////////////////////////////////////////////////////////////////////////////
25 #include <TGeoManager.h>
26 #include <TGeoPhysicalNode.h>
27 #include <TGeoMatrix.h>
30 #include "AliRunLoader.h"
31 #include "AliAlignObj.h"
32 #include "AliAlignObjAngles.h"
36 #include "AliTRDcalibDB.h"
37 #include "AliTRDCommonParam.h"
38 #include "AliTRDgeometry.h"
39 #include "AliTRDpadPlane.h"
41 ClassImp(AliTRDgeometry)
43 //_____________________________________________________________________________
46 // The geometry constants
48 const Int_t AliTRDgeometry::fgkNsect = kNsect;
49 const Int_t AliTRDgeometry::fgkNplan = kNplan;
50 const Int_t AliTRDgeometry::fgkNcham = kNcham;
51 const Int_t AliTRDgeometry::fgkNdet = kNdet;
54 // Dimensions of the detector
57 // Inner and outer radius of the mother volumes
58 const Float_t AliTRDgeometry::fgkRmin = 294.0;
59 const Float_t AliTRDgeometry::fgkRmax = 368.0;
61 // Upper and lower length of the mother volumes
62 const Float_t AliTRDgeometry::fgkZmax1 = 378.35;
63 const Float_t AliTRDgeometry::fgkZmax2 = 302.0;
65 // Parameter of the BTR mother volumes
66 const Float_t AliTRDgeometry::fgkSheight = 77.9;
67 const Float_t AliTRDgeometry::fgkSwidth1 = 94.881;
68 const Float_t AliTRDgeometry::fgkSwidth2 = 122.353;
69 const Float_t AliTRDgeometry::fgkSlenTR1 = 751.0;
70 const Float_t AliTRDgeometry::fgkSlenTR2 = 313.5;
71 const Float_t AliTRDgeometry::fgkSlenTR3 = 159.5;
73 // The super module side plates
74 const Float_t AliTRDgeometry::fgkSMpltT = 0.2;
75 //const Float_t AliTRDgeometry::fgkSMgapT = 0.5;
77 // Height of different chamber parts
79 const Float_t AliTRDgeometry::fgkCraH = 4.8;
81 const Float_t AliTRDgeometry::fgkCdrH = 3.0;
82 // Amplification region
83 const Float_t AliTRDgeometry::fgkCamH = 0.7;
85 const Float_t AliTRDgeometry::fgkCroH = 2.316;
87 const Float_t AliTRDgeometry::fgkCH = AliTRDgeometry::fgkCraH
88 + AliTRDgeometry::fgkCdrH
89 + AliTRDgeometry::fgkCamH
90 + AliTRDgeometry::fgkCroH;
92 // Vertical spacing of the chambers
93 const Float_t AliTRDgeometry::fgkVspace = 1.784;
95 // Horizontal spacing of the chambers
96 const Float_t AliTRDgeometry::fgkHspace = 2.0;
98 // Radial distance of the first ROC to the outer plates of the SM
99 const Float_t AliTRDgeometry::fgkVrocsm = 1.2;
101 // Thicknesses of different parts of the chamber frame
102 // Lower aluminum frame
103 const Float_t AliTRDgeometry::fgkCalT = 0.3;
104 // Lower G10 frame sides
105 const Float_t AliTRDgeometry::fgkCclsT = 0.3;
106 // Lower G10 frame front
107 const Float_t AliTRDgeometry::fgkCclfT = 1.0;
109 const Float_t AliTRDgeometry::fgkCcuT = 0.9;
111 const Float_t AliTRDgeometry::fgkCauT = 1.5;
113 // Additional width of the readout chamber frames
114 const Float_t AliTRDgeometry::fgkCroW = 0.9;
116 // Difference of outer chamber width and pad plane width
117 //const Float_t AliTRDgeometry::fgkCpadW = 1.0;
118 const Float_t AliTRDgeometry::fgkCpadW = 0.0;
119 const Float_t AliTRDgeometry::fgkRpadW = 1.0;
122 // Thickness of the the material layers
124 const Float_t AliTRDgeometry::fgkRaThick = 0.3646;
125 const Float_t AliTRDgeometry::fgkMyThick = 0.005;
126 const Float_t AliTRDgeometry::fgkDrThick = AliTRDgeometry::fgkCdrH;
127 const Float_t AliTRDgeometry::fgkAmThick = AliTRDgeometry::fgkCamH;
128 const Float_t AliTRDgeometry::fgkXeThick = AliTRDgeometry::fgkDrThick
129 + AliTRDgeometry::fgkAmThick;
130 const Float_t AliTRDgeometry::fgkCuThick = 0.0072;
131 const Float_t AliTRDgeometry::fgkSuThick = 0.06;
132 const Float_t AliTRDgeometry::fgkFeThick = 0.0044;
133 const Float_t AliTRDgeometry::fgkCoThick = 0.02;
134 const Float_t AliTRDgeometry::fgkWaThick = 0.02;
135 const Float_t AliTRDgeometry::fgkRcThick = 0.0058;
136 const Float_t AliTRDgeometry::fgkRpThick = 0.0632;
139 // Position of the material layers
141 const Float_t AliTRDgeometry::fgkRaZpos = -1.50;
142 const Float_t AliTRDgeometry::fgkMyZpos = 0.895;
143 const Float_t AliTRDgeometry::fgkDrZpos = 2.4;
144 const Float_t AliTRDgeometry::fgkAmZpos = 0.0;
145 const Float_t AliTRDgeometry::fgkCuZpos = -0.9995;
146 const Float_t AliTRDgeometry::fgkSuZpos = 0.0000;
147 const Float_t AliTRDgeometry::fgkFeZpos = 0.0322;
148 const Float_t AliTRDgeometry::fgkCoZpos = 0.97;
149 const Float_t AliTRDgeometry::fgkWaZpos = 0.99;
150 const Float_t AliTRDgeometry::fgkRcZpos = 1.04;
151 const Float_t AliTRDgeometry::fgkRpZpos = 1.0;
153 const Double_t AliTRDgeometry::fgkTime0Base = Rmin() + CraHght() + CdrHght() + CamHght()/2.;
154 const Float_t AliTRDgeometry::fgkTime0[6] = { fgkTime0Base + 0 * (Cheight() + Cspace()),
155 fgkTime0Base + 1 * (Cheight() + Cspace()),
156 fgkTime0Base + 2 * (Cheight() + Cspace()),
157 fgkTime0Base + 3 * (Cheight() + Cspace()),
158 fgkTime0Base + 4 * (Cheight() + Cspace()),
159 fgkTime0Base + 5 * (Cheight() + Cspace()) };
161 //_____________________________________________________________________________
162 AliTRDgeometry::AliTRDgeometry()
165 ,fMatrixCorrectionArray(0)
170 // AliTRDgeometry default constructor
177 //_____________________________________________________________________________
178 AliTRDgeometry::AliTRDgeometry(const AliTRDgeometry &g)
180 ,fMatrixArray(g.fMatrixArray)
181 ,fMatrixCorrectionArray(g.fMatrixCorrectionArray)
182 ,fMatrixGeo(g.fMatrixGeo)
185 // AliTRDgeometry copy constructor
192 //_____________________________________________________________________________
193 AliTRDgeometry::~AliTRDgeometry()
196 // AliTRDgeometry destructor
204 if (fMatrixCorrectionArray) {
205 delete fMatrixCorrectionArray;
206 fMatrixCorrectionArray = 0;
211 //_____________________________________________________________________________
212 AliTRDgeometry &AliTRDgeometry::operator=(const AliTRDgeometry &g)
215 // Assignment operator
218 if (this != &g) Init();
224 //_____________________________________________________________________________
225 void AliTRDgeometry::Init()
228 // Initializes the geometry parameter
230 // The maximum number of pads
231 // and the position of pad 0,0,0
233 // chambers seen from the top:
234 // +----------------------------+
240 // +----------------------------+ +------>
242 // chambers seen from the side: ^
243 // +----------------------------+ drift|
246 // +----------------------------+ +------>
249 // IMPORTANT: time bin 0 is now the first one in the drift region
250 // closest to the readout !!!
257 // The outer width of the chambers
265 // The outer lengths of the chambers
266 // Includes the spacings between the chambers!
267 Float_t length[kNplan][kNcham] = { { 124.0, 124.0, 110.0, 124.0, 124.0 }
268 , { 124.0, 124.0, 110.0, 124.0, 124.0 }
269 , { 131.0, 131.0, 110.0, 131.0, 131.0 }
270 , { 138.0, 138.0, 110.0, 138.0, 138.0 }
271 , { 145.0, 145.0, 110.0, 145.0, 145.0 }
272 , { 147.0, 147.0, 110.0, 147.0, 147.0 } };
274 for (icham = 0; icham < kNcham; icham++) {
275 for (iplan = 0; iplan < kNplan; iplan++) {
276 fClength[iplan][icham] = length[iplan][icham];
280 // The rotation matrix elements
282 for (isect = 0; isect < fgkNsect; isect++) {
283 phi = -2.0 * TMath::Pi() / (Float_t) fgkNsect * ((Float_t) isect + 0.5);
284 fRotA11[isect] = TMath::Cos(phi);
285 fRotA12[isect] = TMath::Sin(phi);
286 fRotA21[isect] = TMath::Sin(phi);
287 fRotA22[isect] = TMath::Cos(phi);
289 fRotB11[isect] = TMath::Cos(phi);
290 fRotB12[isect] = TMath::Sin(phi);
291 fRotB21[isect] = TMath::Sin(phi);
292 fRotB22[isect] = TMath::Cos(phi);
295 for (isect = 0; isect < fgkNsect; isect++) {
296 SetSMstatus(isect,1);
301 //_____________________________________________________________________________
302 void AliTRDgeometry::CreateGeometry(Int_t *idtmed)
305 // Create the TRD geometry without hole
308 // Names of the TRD volumina (xx = detector number):
310 // Volume (Air) wrapping the readout chamber components
311 // UTxx includes: UAxx, UDxx, UFxx, UUxx
313 // UUxx the services volume has been reduced by 7.42 mm
314 // in order to allow shifts in radial direction
316 // Lower part of the readout chambers (gas volume + radiator)
318 // UAxx Aluminum frames (Al)
319 // UBxx G10 frames (C)
320 // UCxx Inner volumes (Air)
322 // Upper part of the readout chambers (readout plane + fee)
324 // UDxx G10 frames (C)
325 // UExx Inner volumes of the G10 (Air)
326 // UFxx Aluminum frames (Al)
327 // UGxx Inner volumes of the Al (Air)
329 // Inner material layers
331 // UHxx Radiator (Rohacell)
332 // UIxx Entrance window (Mylar)
333 // UJxx Drift volume (Xe/CO2)
334 // UKxx Amplification volume (Xe/CO2)
335 // ULxx Pad plane (Cu)
336 // UMxx Support structure (Rohacell)
337 // UNxx ROB base material (C)
338 // UOxx ROB copper (Cu)
341 const Int_t kNparTrd = 4;
342 const Int_t kNparCha = 3;
348 Float_t parTrd[kNparTrd];
349 Float_t parCha[kNparCha];
354 // The TRD mother volume for one sector (Air), full length in z-direction
355 // Provides material for side plates of super module
356 parTrd[0] = fgkSwidth1/2.0;
357 parTrd[1] = fgkSwidth2/2.0;
358 parTrd[2] = fgkSlenTR1/2.0;
359 parTrd[3] = fgkSheight/2.0;
360 gMC->Gsvolu("UTR1","TRD1",idtmed[1302-1],parTrd,kNparTrd);
363 // The outer aluminum plates of the super module (Al)
364 parTrd[0] = fgkSwidth1/2.0;
365 parTrd[1] = fgkSwidth2/2.0;
366 parTrd[2] = fgkSlenTR1/2.0;
367 parTrd[3] = fgkSheight/2.0;
368 gMC->Gsvolu("UTS1","TRD1",idtmed[1301-1],parTrd,kNparTrd);
370 // The inner part of the TRD mother volume for one sector (Air),
371 // full length in z-direction
372 parTrd[0] = fgkSwidth1/2.0 - fgkSMpltT;
373 parTrd[1] = fgkSwidth2/2.0 - fgkSMpltT;
374 parTrd[2] = fgkSlenTR1/2.0;
375 parTrd[3] = fgkSheight/2.0 - fgkSMpltT;
376 gMC->Gsvolu("UTI1","TRD1",idtmed[1302-1],parTrd,kNparTrd);
378 for (Int_t icham = 0; icham < kNcham; icham++) {
379 for (Int_t iplan = 0; iplan < kNplan; iplan++) {
381 Int_t iDet = GetDetectorSec(iplan,icham);
383 // The lower part of the readout chambers (gas volume + radiator)
384 // The aluminum frames
385 sprintf(cTagV,"UA%02d",iDet);
386 parCha[0] = fCwidth[iplan]/2.0;
387 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
388 parCha[2] = fgkCraH/2.0 + fgkCdrH/2.0;
389 fChamberUAboxd[iDet][0] = parCha[0];
390 fChamberUAboxd[iDet][1] = parCha[1];
391 fChamberUAboxd[iDet][2] = parCha[2];
392 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parCha,kNparCha);
394 sprintf(cTagV,"UB%02d",iDet);
395 parCha[0] = fCwidth[iplan]/2.0 - fgkCalT;
398 gMC->Gsvolu(cTagV,"BOX ",idtmed[1307-1],parCha,kNparCha);
399 // The inner part (air)
400 sprintf(cTagV,"UC%02d",iDet);
401 parCha[0] = fCwidth[iplan]/2.0 - fgkCalT - fgkCclsT;
402 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0- fgkCclfT;
404 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
406 // The upper part of the readout chambers (readout plane)
408 sprintf(cTagV,"UD%02d",iDet);
409 parCha[0] = fCwidth[iplan]/2.0 + fgkCroW;
410 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
411 parCha[2] = fgkCamH/2.0;
412 fChamberUDboxd[iDet][0] = parCha[0];
413 fChamberUDboxd[iDet][1] = parCha[1];
414 fChamberUDboxd[iDet][2] = parCha[2];
415 gMC->Gsvolu(cTagV,"BOX ",idtmed[1307-1],parCha,kNparCha);
416 // The inner part of the G10 frame (air)
417 sprintf(cTagV,"UE%02d",iDet);
418 parCha[0] = fCwidth[iplan]/2.0 + fgkCroW - fgkCcuT;
419 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0- fgkCcuT;
421 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
422 // The aluminum frames
423 sprintf(cTagV,"UF%02d",iDet);
424 parCha[0] = fCwidth[iplan]/2.0 + fgkCroW;
425 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
426 parCha[2] = fgkCroH/2.0;
427 fChamberUFboxd[iDet][0] = parCha[0];
428 fChamberUFboxd[iDet][1] = parCha[1];
429 fChamberUFboxd[iDet][2] = parCha[2];
430 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parCha,kNparCha);
431 // The inner part of the aluminum frames
432 sprintf(cTagV,"UG%02d",iDet);
433 parCha[0] = fCwidth[iplan]/2.0 + fgkCroW - fgkCauT;
434 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0- fgkCauT;
436 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
438 // The material layers inside the chambers
441 // Rohacell layer (radiator)
442 parCha[2] = fgkRaThick/2.0;
443 sprintf(cTagV,"UH%02d",iDet);
444 gMC->Gsvolu(cTagV,"BOX ",idtmed[1315-1],parCha,kNparCha);
445 // Mylar layer (entrance window + HV cathode)
446 parCha[2] = fgkMyThick/2.0;
447 sprintf(cTagV,"UI%02d",iDet);
448 gMC->Gsvolu(cTagV,"BOX ",idtmed[1308-1],parCha,kNparCha);
449 // Xe/Isobutane layer (drift volume)
450 parCha[2] = fgkDrThick/2.0;
451 sprintf(cTagV,"UJ%02d",iDet);
452 gMC->Gsvolu(cTagV,"BOX ",idtmed[1309-1],parCha,kNparCha);
453 // Xe/Isobutane layer (amplification volume)
454 parCha[2] = fgkAmThick/2.0;
455 sprintf(cTagV,"UK%02d",iDet);
456 gMC->Gsvolu(cTagV,"BOX ",idtmed[1309-1],parCha,kNparCha);
457 // Cu layer (pad plane)
458 parCha[2] = fgkCuThick/2.0;
459 sprintf(cTagV,"UL%02d",iDet);
460 gMC->Gsvolu(cTagV,"BOX ",idtmed[1305-1],parCha,kNparCha);
461 // G10 layer (support structure / honeycomb)
462 parCha[2] = fgkSuThick/2.0;
463 sprintf(cTagV,"UM%02d",iDet);
464 gMC->Gsvolu(cTagV,"BOX ",idtmed[1313-1],parCha,kNparCha);
465 // G10 layer (readout board)
466 parCha[2] = fgkRpThick/2;
467 sprintf(cTagV,"UN%02d",iDet);
468 gMC->Gsvolu(cTagV,"BOX ",idtmed[1313-1],parCha,kNparCha);
469 // Cu layer (readout board)
470 parCha[2] = fgkRcThick/2.0;
471 sprintf(cTagV,"UO%02d",iDet);
472 gMC->Gsvolu(cTagV,"BOX ",idtmed[1306-1],parCha,kNparCha);
474 // Position the layers in the chambers
478 // Rohacell layer (radiator)
480 sprintf(cTagV,"UH%02d",iDet);
481 sprintf(cTagM,"UC%02d",iDet);
482 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
483 // Mylar layer (entrance window + HV cathode)
485 sprintf(cTagV,"UI%02d",iDet);
486 sprintf(cTagM,"UC%02d",iDet);
487 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
488 // Xe/Isobutane layer (drift volume)
490 sprintf(cTagV,"UJ%02d",iDet);
491 sprintf(cTagM,"UC%02d",iDet);
492 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
494 // Xe/Isobutane layer (amplification volume)
496 sprintf(cTagV,"UK%02d",iDet);
497 sprintf(cTagM,"UE%02d",iDet);
498 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
500 // Cu layer (pad plane)
502 sprintf(cTagV,"UL%02d",iDet);
503 sprintf(cTagM,"UG%02d",iDet);
504 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
505 // G10 layer (support structure)
507 sprintf(cTagV,"UM%02d",iDet);
508 sprintf(cTagM,"UG%02d",iDet);
509 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
510 // G10 layer (readout board)
512 sprintf(cTagV,"UN%02d",iDet);
513 sprintf(cTagM,"UG%02d",iDet);
514 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
515 // Cu layer (readout board)
517 sprintf(cTagV,"UO%02d",iDet);
518 sprintf(cTagM,"UG%02d",iDet);
519 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
521 // Position the inner volumes of the chambers in the frames
525 // The inside of the lower G10 frame
526 sprintf(cTagV,"UC%02d",iDet);
527 sprintf(cTagM,"UB%02d",iDet);
528 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
529 // The lower G10 frame inside the aluminum frame
530 sprintf(cTagV,"UB%02d",iDet);
531 sprintf(cTagM,"UA%02d",iDet);
532 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
533 // The inside of the upper G10 frame
534 sprintf(cTagV,"UE%02d",iDet);
535 sprintf(cTagM,"UD%02d",iDet);
536 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
537 // The inside of the upper aluminum frame
538 sprintf(cTagV,"UG%02d",iDet);
539 sprintf(cTagM,"UF%02d",iDet);
540 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
542 // Position the frames of the chambers in the TRD mother volume
544 ypos = - fClength[iplan][0] - fClength[iplan][1] - fClength[iplan][2]/2.0;
545 for (Int_t ic = 0; ic < icham; ic++) {
546 ypos += fClength[iplan][ic];
548 ypos += fClength[iplan][icham]/2.0;
549 zpos = fgkVrocsm + fgkCraH/2.0 + fgkCdrH/2.0 - fgkSheight/2.0
550 + iplan * (fgkCH + fgkVspace);
551 // The lower aluminum frame, radiator + drift region
552 sprintf(cTagV,"UA%02d",iDet);
553 fChamberUAorig[iDet][0] = xpos;
554 fChamberUAorig[iDet][1] = ypos;
555 fChamberUAorig[iDet][2] = zpos;
556 // The upper G10 frame, amplification region
557 sprintf(cTagV,"UD%02d",iDet);
558 zpos += fgkCamH/2.0 + fgkCraH/2.0 + fgkCdrH/2.0;
559 fChamberUDorig[iDet][0] = xpos;
560 fChamberUDorig[iDet][1] = ypos;
561 fChamberUDorig[iDet][2] = zpos;
562 // The upper aluminum frame
563 sprintf(cTagV,"UF%02d",iDet);
564 zpos += fgkCroH/2.0 + fgkCamH/2.0;
565 fChamberUForig[iDet][0] = xpos;
566 fChamberUForig[iDet][1] = ypos;
567 fChamberUForig[iDet][2] = zpos;
572 // Create the volumes of the super module frame
575 // Create the volumes of the services
576 CreateServices(idtmed);
578 for (Int_t icham = 0; icham < kNcham; icham++) {
579 for (Int_t iplan = 0; iplan < kNplan; iplan++) {
580 GroupChamber(iplan,icham,idtmed);
587 gMC->Gspos("UTI1",1,"UTS1",xpos,ypos,zpos,0,"ONLY");
592 gMC->Gspos("UTS1",1,"UTR1",xpos,ypos,zpos,0,"ONLY");
594 // Put the TRD volumes into the space frame mother volumes
595 // if enabled via status flag
599 for (Int_t isect = 0; isect < kNsect; isect++) {
600 if (fSMstatus[isect]) {
601 sprintf(cTagV,"BTRD%d",isect);
602 gMC->Gspos("UTR1",1,cTagV,xpos,ypos,zpos,0,"ONLY");
608 //_____________________________________________________________________________
609 void AliTRDgeometry::CreateFrame(Int_t *idtmed)
612 // Create the geometry of the frame of the supermodule
614 // Names of the TRD services volumina
616 // USRL Support rails for the chambers (Al)
617 // USxx Support cross bars between the chambers (Al)
629 // The chamber support rails
632 const Float_t kSRLwid = 2.00;
633 const Float_t kSRLhgt = 2.3;
634 const Float_t kSRLdst = 0.6;
635 const Int_t kNparSRL = 3;
636 Float_t parSRL[kNparSRL];
637 parSRL[0] = kSRLwid/2.0;
638 parSRL[1] = fgkSlenTR1/2.;
639 parSRL[2] = kSRLhgt/2.0;
640 gMC->Gsvolu("USRL","BOX ",idtmed[1301-1],parSRL,kNparSRL);
645 for (iplan = 0; iplan < kNplan; iplan++) {
646 xpos = fCwidth[iplan]/2.0 + kSRLwid/2.0 + kSRLdst;
648 zpos = fgkVrocsm + fgkCraH + fgkCdrH - fgkSheight/2.0 - kSRLhgt/2.0
649 + iplan * (fgkCH + fgkVspace);
650 gMC->Gspos("USRL",iplan+1 ,"UTI1", xpos,ypos,zpos,0,"ONLY");
651 gMC->Gspos("USRL",iplan+1+ kNplan,"UTI1",-xpos,ypos,zpos,0,"ONLY");
655 // The cross bars between the chambers
658 const Float_t kSCBwid = 1.0;
659 const Int_t kNparSCB = 3;
660 Float_t parSCB[kNparSCB];
661 parSCB[1] = kSCBwid/2.0;
662 parSCB[2] = fgkCH/2.0;
667 for (iplan = 0; iplan < kNplan; iplan++) {
669 parSCB[0] = fCwidth[iplan]/2.0 + kSRLdst/2.0;
671 sprintf(cTagV,"US0%01d",iplan);
672 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
674 ypos = fgkSlenTR1/2.0 - kSCBwid/2.0;
675 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
676 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
678 sprintf(cTagV,"US1%01d",iplan);
679 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
681 ypos = fClength[iplan][2]/2.0 + fClength[iplan][1];
682 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
683 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
685 sprintf(cTagV,"US2%01d",iplan);
686 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
688 ypos = fClength[iplan][2]/2.0;
689 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
690 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
692 sprintf(cTagV,"US3%01d",iplan);
693 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
695 ypos = - fClength[iplan][2]/2.0;
696 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
697 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
699 sprintf(cTagV,"US4%01d",iplan);
700 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
702 ypos = - fClength[iplan][2]/2.0 - fClength[iplan][1];
703 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
704 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
706 sprintf(cTagV,"US5%01d",iplan);
707 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
709 ypos = - fgkSlenTR1/2.0 + kSCBwid/2.0;
710 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
711 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
717 //_____________________________________________________________________________
718 void AliTRDgeometry::CreateServices(Int_t *idtmed)
721 // Create the geometry of the services
723 // Names of the TRD services volumina
725 // UTCL Cooling arterias (Al)
726 // UTCW Cooling arterias (Water)
727 // UUxx Volumes for the services at the chambers (Air)
728 // UTPW Power bars (Cu)
729 // UTCP Cooling pipes (Al)
730 // UTCH Cooling pipes (Water)
731 // UTPL Power lines (Cu)
732 // UMCM Readout MCMs (G10/Cu/Si)
744 // The rotation matrices
745 const Int_t kNmatrix = 3;
746 Int_t matrix[kNmatrix];
747 gMC->Matrix(matrix[0], 100.0, 0.0, 90.0, 90.0, 10.0, 0.0);
748 gMC->Matrix(matrix[1], 80.0, 0.0, 90.0, 90.0, 10.0, 180.0);
749 gMC->Matrix(matrix[2], 0.0, 0.0, 90.0, 90.0, 90.0, 0.0);
751 AliTRDCommonParam *commonParam = AliTRDCommonParam::Instance();
753 AliError("Could not get common parameters\n");
758 // The cooling arterias
761 // Width of the cooling arterias
762 const Float_t kCOLwid = 0.5;
763 // Height of the cooling arterias
764 const Float_t kCOLhgt = 5.5;
765 // Positioning of the cooling
766 const Float_t kCOLposx = 1.6;
767 const Float_t kCOLposz = -0.2;
768 // Thickness of the walls of the cooling arterias
769 const Float_t kCOLthk = 0.1;
770 const Int_t kNparCOL = 3;
771 Float_t parCOL[kNparCOL];
772 parCOL[0] = kCOLwid/2.0;
773 parCOL[1] = fgkSlenTR1/2.0;
774 parCOL[2] = kCOLhgt/2.0;
775 gMC->Gsvolu("UTCL","BOX ",idtmed[1324-1],parCOL,kNparCOL);
776 parCOL[0] -= kCOLthk;
777 parCOL[1] = fgkSlenTR1/2.0;
778 parCOL[2] -= kCOLthk;
779 gMC->Gsvolu("UTCW","BOX ",idtmed[1314-1],parCOL,kNparCOL);
784 gMC->Gspos("UTCW",1,"UTCL", xpos,ypos,zpos,0,"ONLY");
786 for (iplan = 0; iplan < kNplan; iplan++) {
787 xpos = fCwidth[iplan]/2.0 + kCOLwid/2.0 + kCOLposx;
789 zpos = fgkVrocsm + kCOLhgt/2.0 - fgkSheight/2.0 + kCOLposz
790 + iplan * (fgkCH + fgkVspace);
791 // To avoid overlaps !
792 if (iplan == 0) zpos += 0.25;
793 gMC->Gspos("UTCL",iplan+1 ,"UTI1", xpos,ypos,zpos,matrix[0],"ONLY");
794 gMC->Gspos("UTCL",iplan+1+ kNplan,"UTI1",-xpos,ypos,zpos,matrix[1],"ONLY");
801 const Float_t kPWRwid = 0.6;
802 const Float_t kPWRhgt = 4.5;
803 const Float_t kPWRposx = 1.05;
804 const Float_t kPWRposz = 0.9;
805 const Int_t kNparPWR = 3;
806 Float_t parPWR[kNparPWR];
807 parPWR[0] = kPWRwid/2.0;
808 parPWR[1] = fgkSlenTR1/2.0;
809 parPWR[2] = kPWRhgt/2.0;
810 gMC->Gsvolu("UTPW","BOX ",idtmed[1325-1],parPWR,kNparPWR);
812 for (iplan = 0; iplan < kNplan; iplan++) {
814 xpos = fCwidth[iplan]/2.0 + kPWRwid/2.0 + kPWRposx;
816 zpos = fgkVrocsm + kPWRhgt/2.0 - fgkSheight/2.0 + kPWRposz
817 + iplan * (fgkCH + fgkVspace);
818 gMC->Gspos("UTPW",iplan+1 ,"UTI1", xpos,ypos,zpos,matrix[0],"ONLY");
819 gMC->Gspos("UTPW",iplan+1+ kNplan,"UTI1",-xpos,ypos,zpos,matrix[1],"ONLY");
824 // The volumes for the services at the chambers
827 const Int_t kNparServ = 3;
828 Float_t parServ[kNparServ];
830 for (icham = 0; icham < kNcham; icham++) {
831 for (iplan = 0; iplan < kNplan; iplan++) {
833 Int_t iDet = GetDetectorSec(iplan,icham);
835 sprintf(cTagV,"UU%02d",iDet);
836 parServ[0] = fCwidth[iplan]/2.0;
837 parServ[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
838 // ???? !!!!!!!!!!!!!!
839 parServ[2] = fgkVspace/2.0 - 0.742/2.0;
840 fChamberUUboxd[iDet][0] = parServ[0];
841 fChamberUUboxd[iDet][1] = parServ[1];
842 fChamberUUboxd[iDet][2] = parServ[2];
843 gMC->Gsvolu(cTagV,"BOX",idtmed[1302-1],parServ,kNparServ);
846 ypos = - fClength[iplan][0] - fClength[iplan][1] - fClength[iplan][2]/2.0;
847 for (Int_t ic = 0; ic < icham; ic++) {
848 ypos += fClength[iplan][ic];
850 ypos += fClength[iplan][icham]/2.0;
851 zpos = fgkVrocsm + fgkCH + fgkVspace/2.0 - fgkSheight/2.0
852 + iplan * (fgkCH + fgkVspace);
854 fChamberUUorig[iDet][0] = xpos;
855 fChamberUUorig[iDet][1] = ypos;
856 fChamberUUorig[iDet][2] = zpos;
862 // The cooling pipes inside the service volumes
865 const Int_t kNparTube = 3;
866 Float_t parTube[kNparTube];
867 // The aluminum pipe for the cooling
871 gMC->Gsvolu("UTCP","TUBE",idtmed[1324-1],parTube,0);
874 parTube[1] = 0.2/2.0;
876 gMC->Gsvolu("UTCH","TUBE",idtmed[1314-1],parTube,kNparTube);
877 // Water inside the cooling pipe
881 gMC->Gspos("UTCH",1,"UTCP",xpos,ypos,zpos,0,"ONLY");
883 // Position the cooling pipes in the mother volume
884 const Int_t kNpar = 3;
886 for (icham = 0; icham < kNcham; icham++) {
887 for (iplan = 0; iplan < kNplan; iplan++) {
888 Int_t iDet = GetDetectorSec(iplan,icham);
889 Int_t iCopy = GetDetector(iplan,icham,0) * 100;
890 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
891 Float_t ySize = (GetChamberLength(iplan,icham) - 2.0*fgkRpadW)
892 / ((Float_t) nMCMrow);
893 sprintf(cTagV,"UU%02d",iDet);
894 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
896 ypos = (0.5 + iMCMrow) * ySize - 1.9
897 - fClength[iplan][icham]/2.0 + fgkHspace/2.0;
898 zpos = 0.0 + 0.742/2.0;
900 par[1] = 0.3/2.0; // Thickness of the cooling pipes
901 par[2] = fCwidth[iplan]/2.0;
902 gMC->Gsposp("UTCP",iCopy+iMCMrow,cTagV,xpos,ypos,zpos
903 ,matrix[2],"ONLY",par,kNpar);
912 // The copper power lines
916 gMC->Gsvolu("UTPL","TUBE",idtmed[1305-1],parTube,0);
918 // Position the power lines in the mother volume
919 for (icham = 0; icham < kNcham; icham++) {
920 for (iplan = 0; iplan < kNplan; iplan++) {
921 Int_t iDet = GetDetectorSec(iplan,icham);
922 Int_t iCopy = GetDetector(iplan,icham,0) * 100;
923 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
924 Float_t ySize = (GetChamberLength(iplan,icham) - 2.0*fgkRpadW)
925 / ((Float_t) nMCMrow);
926 sprintf(cTagV,"UU%02d",iDet);
927 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
929 ypos = (0.5 + iMCMrow) * ySize - 1.0
930 - fClength[iplan][icham]/2.0 + fgkHspace/2.0;
931 zpos = -0.4 + 0.742/2.0;
933 par[1] = 0.2/2.0; // Thickness of the power lines
934 par[2] = fCwidth[iplan]/2.0;
935 gMC->Gsposp("UTPL",iCopy+iMCMrow,cTagV,xpos,ypos,zpos
936 ,matrix[2],"ONLY",par,kNpar);
945 // The mother volume for the MCMs (air)
946 const Int_t kNparMCM = 3;
947 Float_t parMCM[kNparMCM];
950 parMCM[2] = 0.14/2.0;
951 gMC->Gsvolu("UMCM","BOX",idtmed[1302-1],parMCM,kNparMCM);
953 // The MCM carrier G10 layer
957 gMC->Gsvolu("UMC1","BOX",idtmed[1319-1],parMCM,kNparMCM);
958 // The MCM carrier Cu layer
961 parMCM[2] = 0.0162/2.0;
962 gMC->Gsvolu("UMC2","BOX",idtmed[1318-1],parMCM,kNparMCM);
963 // The silicon of the chips
966 parMCM[2] = 0.003/2.0;
967 gMC->Gsvolu("UMC3","BOX",idtmed[1320-1],parMCM,kNparMCM);
969 // Put the MCM material inside the MCM mother volume
972 zpos = -0.07 + 0.1/2.0;
973 gMC->Gspos("UMC1",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
974 zpos += 0.1/2.0 + 0.0162/2.0;
975 gMC->Gspos("UMC2",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
976 zpos += 0.00162/2 + 0.003/2.0;
977 gMC->Gspos("UMC3",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
979 // Position the MCMs in the mother volume
980 for (icham = 0; icham < kNcham; icham++) {
981 for (iplan = 0; iplan < kNplan; iplan++) {
982 // Take out upper plane until TRD mothervolume is adjusted
983 //for (iplan = 0; iplan < kNplan-1; iplan++) {
984 Int_t iDet = GetDetectorSec(iplan,icham);
985 Int_t iCopy = GetDetector(iplan,icham,0) * 1000;
986 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
987 Float_t ySize = (GetChamberLength(iplan,icham) - 2.0*fgkRpadW)
988 / ((Float_t) nMCMrow);
990 Float_t xSize = (GetChamberWidth(iplan) - 2.0* fgkCpadW)
991 / ((Float_t) nMCMcol);
992 sprintf(cTagV,"UU%02d",iDet);
993 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
994 for (Int_t iMCMcol = 0; iMCMcol < nMCMcol; iMCMcol++) {
995 xpos = (0.5 + iMCMcol) * xSize + 1.0
996 - fCwidth[iplan]/2.0;
997 ypos = (0.5 + iMCMrow) * ySize + 1.0
998 - fClength[iplan][icham]/2.0 + fgkHspace/2.0;
999 zpos = -0.4 + 0.742/2.0;
1001 par[1] = 0.2/2.0; // Thickness of the power lines
1002 par[2] = fCwidth[iplan]/2.0;
1003 gMC->Gspos("UMCM",iCopy+iMCMrow*10+iMCMcol,cTagV
1004 ,xpos,ypos,zpos,0,"ONLY");
1013 //_____________________________________________________________________________
1014 void AliTRDgeometry::GroupChamber(Int_t iplan, Int_t icham, Int_t *idtmed)
1017 // Group volumes UA, UD, UF, UU in a single chamber (Air)
1018 // UA, UD, UF, UU are boxes
1022 const Int_t kNparCha = 3;
1024 Int_t iDet = GetDetectorSec(iplan,icham);
1034 for (Int_t i = 0; i < 3; i++) {
1035 xyzMin[i] = +9999.0;
1036 xyzMax[i] = -9999.0;
1039 for (Int_t i = 0; i < 3; i++) {
1041 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUAorig[iDet][i]-fChamberUAboxd[iDet][i]);
1042 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUAorig[iDet][i]+fChamberUAboxd[iDet][i]);
1044 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUDorig[iDet][i]-fChamberUDboxd[iDet][i]);
1045 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUDorig[iDet][i]+fChamberUDboxd[iDet][i]);
1047 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUForig[iDet][i]-fChamberUFboxd[iDet][i]);
1048 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUForig[iDet][i]+fChamberUFboxd[iDet][i]);
1050 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUUorig[iDet][i]-fChamberUUboxd[iDet][i]);
1051 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUUorig[iDet][i]+fChamberUUboxd[iDet][i]);
1053 xyzOrig[i] = 0.5*(xyzMax[i]+xyzMin[i]);
1054 xyzBoxd[i] = 0.5*(xyzMax[i]-xyzMin[i]);
1058 sprintf(cTagM,"UT%02d",iDet);
1059 gMC->Gsvolu(cTagM,"BOX ",idtmed[1302-1],xyzBoxd,kNparCha);
1061 sprintf(cTagV,"UA%02d",iDet);
1062 gMC->Gspos(cTagV,1,cTagM,
1063 fChamberUAorig[iDet][0]-xyzOrig[0],
1064 fChamberUAorig[iDet][1]-xyzOrig[1],
1065 fChamberUAorig[iDet][2]-xyzOrig[2],
1068 sprintf(cTagV,"UD%02d",iDet);
1069 gMC->Gspos(cTagV,1,cTagM,
1070 fChamberUDorig[iDet][0]-xyzOrig[0],
1071 fChamberUDorig[iDet][1]-xyzOrig[1],
1072 fChamberUDorig[iDet][2]-xyzOrig[2],
1075 sprintf(cTagV,"UF%02d",iDet);
1076 gMC->Gspos(cTagV,1,cTagM,
1077 fChamberUForig[iDet][0]-xyzOrig[0],
1078 fChamberUForig[iDet][1]-xyzOrig[1],
1079 fChamberUForig[iDet][2]-xyzOrig[2],
1082 sprintf(cTagV,"UU%02d",iDet);
1083 gMC->Gspos(cTagV,1,cTagM,
1084 fChamberUUorig[iDet][0]-xyzOrig[0],
1085 fChamberUUorig[iDet][1]-xyzOrig[1],
1086 fChamberUUorig[iDet][2]-xyzOrig[2],
1089 sprintf(cTagV,"UT%02d",iDet);
1090 gMC->Gspos(cTagV,1,"UTI1",xyzOrig[0],xyzOrig[1],xyzOrig[2],0,"ONLY");
1094 //_____________________________________________________________________________
1095 Bool_t AliTRDgeometry::Local2Global(Int_t idet, Double_t *local
1096 , Double_t *global) const
1099 // Converts local pad-coordinates (row,col,time) into
1100 // global ALICE reference frame coordinates (x,y,z)
1103 Int_t icham = GetChamber(idet); // Chamber info (0-4)
1104 Int_t isect = GetSector(idet); // Sector info (0-17)
1105 Int_t iplan = GetPlane(idet); // Plane info (0-5)
1107 return Local2Global(iplan,icham,isect,local,global);
1111 //_____________________________________________________________________________
1112 Bool_t AliTRDgeometry::Local2Global(Int_t iplan, Int_t icham, Int_t isect
1113 , Double_t *local, Double_t *global) const
1116 // Converts local pad-coordinates (row,col,time) into
1117 // global ALICE reference frame coordinates (x,y,z)
1120 AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
1122 AliError("Could not get common parameters\n");
1126 AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
1128 AliError("Could not get calibration data\n");
1132 AliTRDpadPlane *padPlane = commonParam->GetPadPlane(iplan,icham);
1134 // calculate (x,y,z) position in rotated chamber
1135 Int_t row = ((Int_t) local[0]);
1136 Int_t col = ((Int_t) local[1]);
1137 Float_t timeSlice = local[2] + 0.5;
1138 Float_t time0 = GetTime0(iplan);
1140 Int_t idet = GetDetector(iplan, icham, isect);
1143 rot[0] = time0 - (timeSlice - calibration->GetT0(idet, col, row))
1144 * calibration->GetVdrift(idet, col, row)
1145 / calibration->GetSamplingFrequency();
1146 rot[1] = padPlane->GetColPos(col) - 0.5 * padPlane->GetColSize(col);
1147 rot[2] = padPlane->GetRowPos(row) - 0.5 * padPlane->GetRowSize(row);
1149 // Rotate back to original position
1150 return RotateBack(idet,rot,global);
1154 //_____________________________________________________________________________
1155 Bool_t AliTRDgeometry::Global2Local(Int_t mode, Double_t *local, Double_t *global
1156 , Int_t* index) const
1159 // Converts local pad-coordinates (row,col,time) into
1160 // global ALICE reference frame coordinates (x,y,z)
1162 // index[0] = plane number
1163 // index[1] = chamber number
1164 // index[2] = sector number
1166 // mode = 0 - local coordinate in y, z, x - rotated global
1169 Int_t idet = GetDetector(index[0],index[1],index[2]); // Detector number
1170 RotateBack(idet,global,local);
1180 //_____________________________________________________________________________
1181 Bool_t AliTRDgeometry::Global2Detector(Double_t global[3], Int_t index[3])
1184 // Find detector for given global point - Ideal geometry
1187 // input = global position
1189 // index[0] = plane number
1190 // index[1] = chamber number
1191 // index[2] = sector number
1197 Float_t fi = TMath::ATan2(global[1],global[0]);
1199 fi += 2.0 * TMath::Pi();
1201 index[2] = fgkNsect - 1 - TMath::Nint((fi - GetAlpha()/2.0) / GetAlpha());
1206 Float_t locx = global[0] * fRotA11[index[2]] + global[1] * fRotA12[index[2]];
1208 Float_t max = locx - GetTime0(0);
1209 for (Int_t iplane = 1; iplane < fgkNplan; iplane++) {
1210 Float_t dist = TMath::Abs(locx - GetTime0(iplane));
1220 if (TMath::Abs(global[2]) < 0.5*GetChamberLength(index[0],2)) {
1224 Double_t localZ = global[2];
1225 if (global[2] > 0.0) {
1226 localZ -= 0.5*(GetChamberLength(index[0],2)+GetChamberLength(index[0],1));
1227 index[1] = (TMath::Abs(localZ) < 0.5*GetChamberLength(index[0],3)) ? 1 : 0;
1230 localZ += 0.5*(GetChamberLength(index[0],2)+GetChamberLength(index[0],3));
1231 index[1] = (TMath::Abs(localZ) < 0.5*GetChamberLength(index[0],1)) ? 3 : 4;
1239 //_____________________________________________________________________________
1240 Bool_t AliTRDgeometry::Rotate(Int_t d, Double_t *pos, Double_t *rot) const
1243 // Rotates all chambers in the position of sector 0 and transforms
1244 // the coordinates in the ALICE restframe <pos> into the
1245 // corresponding local frame <rot>.
1248 Int_t sector = GetSector(d);
1250 rot[0] = pos[0] * fRotA11[sector] + pos[1] * fRotA12[sector];
1251 rot[1] = -pos[0] * fRotA21[sector] + pos[1] * fRotA22[sector];
1258 //_____________________________________________________________________________
1259 Bool_t AliTRDgeometry::RotateBack(Int_t d, Double_t *rot, Double_t *pos) const
1262 // Rotates a chambers from the position of sector 0 into its
1263 // original position and transforms the corresponding local frame
1264 // coordinates <rot> into the coordinates of the ALICE restframe <pos>.
1267 Int_t sector = GetSector(d);
1269 pos[0] = rot[0] * fRotB11[sector] + rot[1] * fRotB12[sector];
1270 pos[1] = -rot[0] * fRotB21[sector] + rot[1] * fRotB22[sector];
1277 //_____________________________________________________________________________
1278 Int_t AliTRDgeometry::GetDetectorSec(Int_t p, Int_t c)
1281 // Convert plane / chamber into detector number for one single sector
1284 return (p + c * fgkNplan);
1288 //_____________________________________________________________________________
1289 Int_t AliTRDgeometry::GetDetector(Int_t p, Int_t c, Int_t s)
1292 // Convert plane / chamber / sector into detector number
1295 return (p + c * fgkNplan + s * fgkNplan * fgkNcham);
1299 //_____________________________________________________________________________
1300 Int_t AliTRDgeometry::GetPlane(Int_t d) const
1303 // Reconstruct the plane number from the detector number
1306 return ((Int_t) (d % fgkNplan));
1310 //_____________________________________________________________________________
1311 Int_t AliTRDgeometry::GetChamber(Int_t d) const
1314 // Reconstruct the chamber number from the detector number
1317 return ((Int_t) (d % (fgkNplan * fgkNcham)) / fgkNplan);
1321 //_____________________________________________________________________________
1322 Int_t AliTRDgeometry::GetSector(Int_t d) const
1325 // Reconstruct the sector number from the detector number
1328 return ((Int_t) (d / (fgkNplan * fgkNcham)));
1332 //_____________________________________________________________________________
1333 AliTRDgeometry* AliTRDgeometry::GetGeometry(AliRunLoader *runLoader)
1336 // Load the geometry from the galice file
1339 if (!runLoader) runLoader = AliRunLoader::GetRunLoader();
1341 AliErrorGeneral("AliTRDgeometry::GetGeometry","No run loader");
1345 TDirectory *saveDir = gDirectory;
1346 runLoader->CdGAFile();
1348 // Try from the galice.root file
1349 AliTRDgeometry *geom = (AliTRDgeometry *) gDirectory->Get("TRDgeometry");
1352 // It is not in the file, try to get it from gAlice,
1353 // which corresponds to the run loader
1354 AliTRD *trd = (AliTRD *) runLoader->GetAliRun()->GetDetector("TRD");
1355 geom = trd->GetGeometry();
1358 AliErrorGeneral("AliTRDgeometry::GetGeometry","Geometry not found");
1367 //_____________________________________________________________________________
1368 Bool_t AliTRDgeometry::ReadGeoMatrices()
1371 // Read geo matrices from current gGeoManager for each TRD sector
1377 fMatrixArray = new TObjArray(kNdet);
1378 fMatrixCorrectionArray = new TObjArray(kNdet);
1379 fMatrixGeo = new TObjArray(kNdet);
1380 AliAlignObjAngles o;
1382 for (Int_t iLayer = AliAlignObj::kTRD1; iLayer <= AliAlignObj::kTRD6; iLayer++) {
1383 for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
1385 UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,iModule);
1386 const char *symname = AliAlignObj::SymName(volid);
1387 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
1388 const char *path = symname;
1389 if(pne) path=pne->GetTitle();
1390 if (!gGeoManager->cd(path)) return kFALSE;
1391 TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
1392 Int_t iLayerTRD = iLayer - AliAlignObj::kTRD1;
1393 Int_t isector = Nsect() - 1 - (iModule/Ncham());
1394 Int_t ichamber = Ncham() - 1 - (iModule%Ncham());
1395 Int_t lid = GetDetector(iLayerTRD,ichamber,isector);
1398 // Local geo system z-x-y to x-y--z
1400 fMatrixGeo->AddAt(new TGeoHMatrix(*m),lid);
1402 TGeoRotation mchange;
1403 mchange.RotateY(90);
1404 mchange.RotateX(90);
1406 TGeoHMatrix gMatrix(mchange.Inverse());
1407 gMatrix.MultiplyLeft(m);
1408 fMatrixArray->AddAt(new TGeoHMatrix(gMatrix),lid);
1411 // Cluster transformation matrix
1413 TGeoHMatrix rotMatrix(mchange.Inverse());
1414 rotMatrix.MultiplyLeft(m);
1415 Double_t sectorAngle = 20.0 * (isector % 18) + 10.0;
1416 TGeoHMatrix rotSector;
1417 rotSector.RotateZ(sectorAngle);
1418 rotMatrix.MultiplyLeft(&rotSector);
1420 fMatrixCorrectionArray->AddAt(new TGeoHMatrix(rotMatrix),lid);