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
235 // The outer width of the chambers
243 // The outer lengths of the chambers
244 // Includes the spacings between the chambers!
245 Float_t length[kNplan][kNcham] = { { 124.0, 124.0, 110.0, 124.0, 124.0 }
246 , { 124.0, 124.0, 110.0, 124.0, 124.0 }
247 , { 131.0, 131.0, 110.0, 131.0, 131.0 }
248 , { 138.0, 138.0, 110.0, 138.0, 138.0 }
249 , { 145.0, 145.0, 110.0, 145.0, 145.0 }
250 , { 147.0, 147.0, 110.0, 147.0, 147.0 } };
252 for (icham = 0; icham < kNcham; icham++) {
253 for (iplan = 0; iplan < kNplan; iplan++) {
254 fClength[iplan][icham] = length[iplan][icham];
258 // The rotation matrix elements
260 for (isect = 0; isect < fgkNsect; isect++) {
261 phi = -2.0 * TMath::Pi() / (Float_t) fgkNsect * ((Float_t) isect + 0.5);
262 fRotA11[isect] = TMath::Cos(phi);
263 fRotA12[isect] = TMath::Sin(phi);
264 fRotA21[isect] = TMath::Sin(phi);
265 fRotA22[isect] = TMath::Cos(phi);
267 fRotB11[isect] = TMath::Cos(phi);
268 fRotB12[isect] = TMath::Sin(phi);
269 fRotB21[isect] = TMath::Sin(phi);
270 fRotB22[isect] = TMath::Cos(phi);
273 for (isect = 0; isect < fgkNsect; isect++) {
274 SetSMstatus(isect,1);
279 //_____________________________________________________________________________
280 void AliTRDgeometry::CreateGeometry(Int_t *idtmed)
283 // Create the TRD geometry without hole
286 // Names of the TRD volumina (xx = detector number):
288 // Volume (Air) wrapping the readout chamber components
289 // UTxx includes: UAxx, UDxx, UFxx, UUxx
291 // UUxx the services volume has been reduced by 7.42 mm
292 // in order to allow shifts in radial direction
294 // Lower part of the readout chambers (gas volume + radiator)
296 // UAxx Aluminum frames (Al)
297 // UBxx G10 frames (C)
298 // UCxx Inner volumes (Air)
300 // Upper part of the readout chambers (readout plane + fee)
302 // UDxx G10 frames (C)
303 // UExx Inner volumes of the G10 (Air)
304 // UFxx Aluminum frames (Al)
305 // UGxx Inner volumes of the Al (Air)
307 // Inner material layers
309 // UHxx Radiator (Rohacell)
310 // UIxx Entrance window (Mylar)
311 // UJxx Drift volume (Xe/CO2)
312 // UKxx Amplification volume (Xe/CO2)
313 // ULxx Pad plane (Cu)
314 // UMxx Support structure (Rohacell)
315 // UNxx ROB base material (C)
316 // UOxx ROB copper (Cu)
319 const Int_t kNparTrd = 4;
320 const Int_t kNparCha = 3;
326 Float_t parTrd[kNparTrd];
327 Float_t parCha[kNparCha];
332 // The TRD mother volume for one sector (Air), full length in z-direction
333 // Provides material for side plates of super module
334 parTrd[0] = fgkSwidth1/2.0;
335 parTrd[1] = fgkSwidth2/2.0;
336 parTrd[2] = fgkSlenTR1/2.0;
337 parTrd[3] = fgkSheight/2.0;
338 gMC->Gsvolu("UTR1","TRD1",idtmed[1302-1],parTrd,kNparTrd);
340 // The outer aluminum plates of the super module (Al)
341 parTrd[0] = fgkSwidth1/2.0;
342 parTrd[1] = fgkSwidth2/2.0;
343 parTrd[2] = fgkSlenTR1/2.0;
344 parTrd[3] = fgkSheight/2.0;
345 gMC->Gsvolu("UTS1","TRD1",idtmed[1301-1],parTrd,kNparTrd);
347 // The inner part of the TRD mother volume for one sector (Air),
348 // full length in z-direction
349 parTrd[0] = fgkSwidth1/2.0 - fgkSMpltT;
350 parTrd[1] = fgkSwidth2/2.0 - fgkSMpltT;
351 parTrd[2] = fgkSlenTR1/2.0;
352 parTrd[3] = fgkSheight/2.0 - fgkSMpltT;
353 gMC->Gsvolu("UTI1","TRD1",idtmed[1302-1],parTrd,kNparTrd);
355 for (Int_t icham = 0; icham < kNcham; icham++) {
356 for (Int_t iplan = 0; iplan < kNplan; iplan++) {
358 Int_t iDet = GetDetectorSec(iplan,icham);
360 // The lower part of the readout chambers (gas volume + radiator)
361 // The aluminum frames
362 sprintf(cTagV,"UA%02d",iDet);
363 parCha[0] = fCwidth[iplan]/2.0;
364 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
365 parCha[2] = fgkCraH/2.0 + fgkCdrH/2.0;
366 fChamberUAboxd[iDet][0] = parCha[0];
367 fChamberUAboxd[iDet][1] = parCha[1];
368 fChamberUAboxd[iDet][2] = parCha[2];
369 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parCha,kNparCha);
371 sprintf(cTagV,"UB%02d",iDet);
372 parCha[0] = fCwidth[iplan]/2.0 - fgkCalT;
375 gMC->Gsvolu(cTagV,"BOX ",idtmed[1307-1],parCha,kNparCha);
376 // The inner part (air)
377 sprintf(cTagV,"UC%02d",iDet);
378 parCha[0] = fCwidth[iplan]/2.0 - fgkCalT - fgkCclsT;
379 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0- fgkCclfT;
381 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
383 // The upper part of the readout chambers (readout plane)
385 sprintf(cTagV,"UD%02d",iDet);
386 parCha[0] = fCwidth[iplan]/2.0 + fgkCroW;
387 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
388 parCha[2] = fgkCamH/2.0;
389 fChamberUDboxd[iDet][0] = parCha[0];
390 fChamberUDboxd[iDet][1] = parCha[1];
391 fChamberUDboxd[iDet][2] = parCha[2];
392 gMC->Gsvolu(cTagV,"BOX ",idtmed[1307-1],parCha,kNparCha);
393 // The inner part of the G10 frame (air)
394 sprintf(cTagV,"UE%02d",iDet);
395 parCha[0] = fCwidth[iplan]/2.0 + fgkCroW - fgkCcuT;
396 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0- fgkCcuT;
398 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
399 // The aluminum frames
400 sprintf(cTagV,"UF%02d",iDet);
401 parCha[0] = fCwidth[iplan]/2.0 + fgkCroW;
402 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
403 parCha[2] = fgkCroH/2.0;
404 fChamberUFboxd[iDet][0] = parCha[0];
405 fChamberUFboxd[iDet][1] = parCha[1];
406 fChamberUFboxd[iDet][2] = parCha[2];
407 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parCha,kNparCha);
408 // The inner part of the aluminum frames
409 sprintf(cTagV,"UG%02d",iDet);
410 parCha[0] = fCwidth[iplan]/2.0 + fgkCroW - fgkCauT;
411 parCha[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0- fgkCauT;
413 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
415 // The material layers inside the chambers
418 // Rohacell layer (radiator)
419 parCha[2] = fgkRaThick/2.0;
420 sprintf(cTagV,"UH%02d",iDet);
421 gMC->Gsvolu(cTagV,"BOX ",idtmed[1315-1],parCha,kNparCha);
422 // Mylar layer (entrance window + HV cathode)
423 parCha[2] = fgkMyThick/2.0;
424 sprintf(cTagV,"UI%02d",iDet);
425 gMC->Gsvolu(cTagV,"BOX ",idtmed[1308-1],parCha,kNparCha);
426 // Xe/Isobutane layer (drift volume)
427 parCha[2] = fgkDrThick/2.0;
428 sprintf(cTagV,"UJ%02d",iDet);
429 gMC->Gsvolu(cTagV,"BOX ",idtmed[1309-1],parCha,kNparCha);
430 // Xe/Isobutane layer (amplification volume)
431 parCha[2] = fgkAmThick/2.0;
432 sprintf(cTagV,"UK%02d",iDet);
433 gMC->Gsvolu(cTagV,"BOX ",idtmed[1309-1],parCha,kNparCha);
434 // Cu layer (pad plane)
435 parCha[2] = fgkCuThick/2.0;
436 sprintf(cTagV,"UL%02d",iDet);
437 gMC->Gsvolu(cTagV,"BOX ",idtmed[1305-1],parCha,kNparCha);
438 // G10 layer (support structure / honeycomb)
439 parCha[2] = fgkSuThick/2.0;
440 sprintf(cTagV,"UM%02d",iDet);
441 gMC->Gsvolu(cTagV,"BOX ",idtmed[1313-1],parCha,kNparCha);
442 // G10 layer (readout board)
443 parCha[2] = fgkRpThick/2;
444 sprintf(cTagV,"UN%02d",iDet);
445 gMC->Gsvolu(cTagV,"BOX ",idtmed[1313-1],parCha,kNparCha);
446 // Cu layer (readout board)
447 parCha[2] = fgkRcThick/2.0;
448 sprintf(cTagV,"UO%02d",iDet);
449 gMC->Gsvolu(cTagV,"BOX ",idtmed[1306-1],parCha,kNparCha);
451 // Position the layers in the chambers
455 // Rohacell layer (radiator)
457 sprintf(cTagV,"UH%02d",iDet);
458 sprintf(cTagM,"UC%02d",iDet);
459 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
460 // Mylar layer (entrance window + HV cathode)
462 sprintf(cTagV,"UI%02d",iDet);
463 sprintf(cTagM,"UC%02d",iDet);
464 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
465 // Xe/Isobutane layer (drift volume)
467 sprintf(cTagV,"UJ%02d",iDet);
468 sprintf(cTagM,"UC%02d",iDet);
469 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
471 // Xe/Isobutane layer (amplification volume)
473 sprintf(cTagV,"UK%02d",iDet);
474 sprintf(cTagM,"UE%02d",iDet);
475 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
477 // Cu layer (pad plane)
479 sprintf(cTagV,"UL%02d",iDet);
480 sprintf(cTagM,"UG%02d",iDet);
481 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
482 // G10 layer (support structure)
484 sprintf(cTagV,"UM%02d",iDet);
485 sprintf(cTagM,"UG%02d",iDet);
486 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
487 // G10 layer (readout board)
489 sprintf(cTagV,"UN%02d",iDet);
490 sprintf(cTagM,"UG%02d",iDet);
491 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
492 // Cu layer (readout board)
494 sprintf(cTagV,"UO%02d",iDet);
495 sprintf(cTagM,"UG%02d",iDet);
496 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
498 // Position the inner volumes of the chambers in the frames
502 // The inside of the lower G10 frame
503 sprintf(cTagV,"UC%02d",iDet);
504 sprintf(cTagM,"UB%02d",iDet);
505 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
506 // The lower G10 frame inside the aluminum frame
507 sprintf(cTagV,"UB%02d",iDet);
508 sprintf(cTagM,"UA%02d",iDet);
509 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
510 // The inside of the upper G10 frame
511 sprintf(cTagV,"UE%02d",iDet);
512 sprintf(cTagM,"UD%02d",iDet);
513 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
514 // The inside of the upper aluminum frame
515 sprintf(cTagV,"UG%02d",iDet);
516 sprintf(cTagM,"UF%02d",iDet);
517 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
519 // Position the frames of the chambers in the TRD mother volume
521 ypos = - fClength[iplan][0] - fClength[iplan][1] - fClength[iplan][2]/2.0;
522 for (Int_t ic = 0; ic < icham; ic++) {
523 ypos += fClength[iplan][ic];
525 ypos += fClength[iplan][icham]/2.0;
526 zpos = fgkVrocsm + fgkCraH/2.0 + fgkCdrH/2.0 - fgkSheight/2.0
527 + iplan * (fgkCH + fgkVspace);
528 // The lower aluminum frame, radiator + drift region
529 sprintf(cTagV,"UA%02d",iDet);
530 fChamberUAorig[iDet][0] = xpos;
531 fChamberUAorig[iDet][1] = ypos;
532 fChamberUAorig[iDet][2] = zpos;
533 // The upper G10 frame, amplification region
534 sprintf(cTagV,"UD%02d",iDet);
535 zpos += fgkCamH/2.0 + fgkCraH/2.0 + fgkCdrH/2.0;
536 fChamberUDorig[iDet][0] = xpos;
537 fChamberUDorig[iDet][1] = ypos;
538 fChamberUDorig[iDet][2] = zpos;
539 // The upper aluminum frame
540 sprintf(cTagV,"UF%02d",iDet);
541 zpos += fgkCroH/2.0 + fgkCamH/2.0;
542 fChamberUForig[iDet][0] = xpos;
543 fChamberUForig[iDet][1] = ypos;
544 fChamberUForig[iDet][2] = zpos;
549 // Create the volumes of the super module frame
552 // Create the volumes of the services
553 CreateServices(idtmed);
555 for (Int_t icham = 0; icham < kNcham; icham++) {
556 for (Int_t iplan = 0; iplan < kNplan; iplan++) {
557 GroupChamber(iplan,icham,idtmed);
564 gMC->Gspos("UTI1",1,"UTS1",xpos,ypos,zpos,0,"ONLY");
569 gMC->Gspos("UTS1",1,"UTR1",xpos,ypos,zpos,0,"ONLY");
571 // Put the TRD volumes into the space frame mother volumes
572 // if enabled via status flag
576 for (Int_t isect = 0; isect < kNsect; isect++) {
577 if (fSMstatus[isect]) {
578 sprintf(cTagV,"BTRD%d",isect);
579 gMC->Gspos("UTR1",1,cTagV,xpos,ypos,zpos,0,"ONLY");
585 //_____________________________________________________________________________
586 void AliTRDgeometry::CreateFrame(Int_t *idtmed)
589 // Create the geometry of the frame of the supermodule
591 // Names of the TRD services volumina
593 // USRL Support rails for the chambers (Al)
594 // USxx Support cross bars between the chambers (Al)
606 // The chamber support rails
609 const Float_t kSRLwid = 2.00;
610 const Float_t kSRLhgt = 2.3;
611 const Float_t kSRLdst = 0.6;
612 const Int_t kNparSRL = 3;
613 Float_t parSRL[kNparSRL];
614 parSRL[0] = kSRLwid/2.0;
615 parSRL[1] = fgkSlenTR1/2.;
616 parSRL[2] = kSRLhgt/2.0;
617 gMC->Gsvolu("USRL","BOX ",idtmed[1301-1],parSRL,kNparSRL);
622 for (iplan = 0; iplan < kNplan; iplan++) {
623 xpos = fCwidth[iplan]/2.0 + kSRLwid/2.0 + kSRLdst;
625 zpos = fgkVrocsm + fgkCraH + fgkCdrH - fgkSheight/2.0 - kSRLhgt/2.0
626 + iplan * (fgkCH + fgkVspace);
627 gMC->Gspos("USRL",iplan+1 ,"UTI1", xpos,ypos,zpos,0,"ONLY");
628 gMC->Gspos("USRL",iplan+1+ kNplan,"UTI1",-xpos,ypos,zpos,0,"ONLY");
632 // The cross bars between the chambers
635 const Float_t kSCBwid = 1.0;
636 const Int_t kNparSCB = 3;
637 Float_t parSCB[kNparSCB];
638 parSCB[1] = kSCBwid/2.0;
639 parSCB[2] = fgkCH/2.0;
644 for (iplan = 0; iplan < kNplan; iplan++) {
646 parSCB[0] = fCwidth[iplan]/2.0 + kSRLdst/2.0;
648 sprintf(cTagV,"US0%01d",iplan);
649 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
651 ypos = fgkSlenTR1/2.0 - kSCBwid/2.0;
652 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
653 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
655 sprintf(cTagV,"US1%01d",iplan);
656 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
658 ypos = fClength[iplan][2]/2.0 + fClength[iplan][1];
659 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
660 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
662 sprintf(cTagV,"US2%01d",iplan);
663 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
665 ypos = fClength[iplan][2]/2.0;
666 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
667 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
669 sprintf(cTagV,"US3%01d",iplan);
670 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
672 ypos = - fClength[iplan][2]/2.0;
673 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
674 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
676 sprintf(cTagV,"US4%01d",iplan);
677 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
679 ypos = - fClength[iplan][2]/2.0 - fClength[iplan][1];
680 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
681 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
683 sprintf(cTagV,"US5%01d",iplan);
684 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
686 ypos = - fgkSlenTR1/2.0 + kSCBwid/2.0;
687 zpos = fgkVrocsm + fgkCH/2.0 - fgkSheight/2.0 + iplan * (fgkCH + fgkVspace);
688 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
694 //_____________________________________________________________________________
695 void AliTRDgeometry::CreateServices(Int_t *idtmed)
698 // Create the geometry of the services
700 // Names of the TRD services volumina
702 // UTCL Cooling arterias (Al)
703 // UTCW Cooling arterias (Water)
704 // UUxx Volumes for the services at the chambers (Air)
705 // UTPW Power bars (Cu)
706 // UTCP Cooling pipes (Al)
707 // UTCH Cooling pipes (Water)
708 // UTPL Power lines (Cu)
709 // UMCM Readout MCMs (G10/Cu/Si)
721 // The rotation matrices
722 const Int_t kNmatrix = 4;
723 Int_t matrix[kNmatrix];
724 gMC->Matrix(matrix[0], 100.0, 0.0, 90.0, 90.0, 10.0, 0.0);
725 gMC->Matrix(matrix[1], 80.0, 0.0, 90.0, 90.0, 10.0, 180.0);
726 gMC->Matrix(matrix[2], 0.0, 0.0, 90.0, 90.0, 90.0, 0.0);
727 gMC->Matrix(matrix[3], 180.0, 0.0, 90.0, 90.0, 90.0, 180.0);
729 AliTRDCommonParam *commonParam = AliTRDCommonParam::Instance();
731 AliError("Could not get common parameters\n");
736 // The cooling arterias
739 // Width of the cooling arterias
740 const Float_t kCOLwid = 0.5;
741 // Height of the cooling arterias
742 const Float_t kCOLhgt = 5.5;
743 // Positioning of the cooling
744 const Float_t kCOLposx = 1.6;
745 const Float_t kCOLposz = -0.2;
746 // Thickness of the walls of the cooling arterias
747 const Float_t kCOLthk = 0.1;
748 const Int_t kNparCOL = 3;
749 Float_t parCOL[kNparCOL];
750 parCOL[0] = kCOLwid/2.0;
751 parCOL[1] = fgkSlenTR1/2.0;
752 parCOL[2] = kCOLhgt/2.0;
753 gMC->Gsvolu("UTCL","BOX ",idtmed[1324-1],parCOL,kNparCOL);
754 parCOL[0] -= kCOLthk;
755 parCOL[1] = fgkSlenTR1/2.0;
756 parCOL[2] -= kCOLthk;
757 gMC->Gsvolu("UTCW","BOX ",idtmed[1314-1],parCOL,kNparCOL);
762 gMC->Gspos("UTCW",1,"UTCL", xpos,ypos,zpos,0,"ONLY");
764 for (iplan = 1; iplan < kNplan; iplan++) {
766 xpos = fCwidth[iplan]/2.0 + kCOLwid/2.0 + kCOLposx;
768 zpos = fgkVrocsm + kCOLhgt/2.0 - fgkSheight/2.0 + kCOLposz
769 + iplan * (fgkCH + fgkVspace);
770 gMC->Gspos("UTCL",iplan ,"UTI1", xpos,ypos,zpos,matrix[0],"ONLY");
771 gMC->Gspos("UTCL",iplan+kNplan,"UTI1",-xpos,ypos,zpos,matrix[1],"ONLY");
775 // The upper most layer (reaching into TOF acceptance)
776 xpos = fCwidth[5]/2.0 - kCOLhgt/2.0 - 2.3;
778 zpos = fgkVrocsm + kCOLwid/2.0 - fgkSheight/2.0
779 + 6.0*fgkCH + 6.0*fgkVspace;
781 gMC->Gspos("UTCL",6 ,"UTI1", xpos,ypos,zpos,matrix[3],"ONLY");
782 gMC->Gspos("UTCL",6+kNplan,"UTI1",-xpos,ypos,zpos,matrix[3],"ONLY");
788 const Float_t kPWRwid = 0.6;
789 const Float_t kPWRhgt = 4.5;
790 const Float_t kPWRposx = 1.05;
791 const Float_t kPWRposz = 0.9;
792 const Int_t kNparPWR = 3;
793 Float_t parPWR[kNparPWR];
794 parPWR[0] = kPWRwid/2.0;
795 parPWR[1] = fgkSlenTR1/2.0;
796 parPWR[2] = kPWRhgt/2.0;
797 gMC->Gsvolu("UTPW","BOX ",idtmed[1325-1],parPWR,kNparPWR);
799 for (iplan = 1; iplan < kNplan; iplan++) {
801 xpos = fCwidth[iplan]/2.0 + kPWRwid/2.0 + kPWRposx;
803 zpos = fgkVrocsm + kPWRhgt/2.0 - fgkSheight/2.0 + kPWRposz
804 + iplan * (fgkCH + fgkVspace);
805 gMC->Gspos("UTPW",iplan ,"UTI1", xpos,ypos,zpos,matrix[0],"ONLY");
806 gMC->Gspos("UTPW",iplan+kNplan,"UTI1",-xpos,ypos,zpos,matrix[1],"ONLY");
810 // The upper most layer (reaching into TOF acceptance)
811 xpos = fCwidth[5]/2.0 + kPWRhgt/2.0 - 2.3;
813 zpos = fgkVrocsm + kPWRwid/2.0 - fgkSheight/2.0
814 + 6.0*fgkCH + 6.0*fgkVspace;
815 gMC->Gspos("UTPW",6 ,"UTI1", xpos,ypos,zpos,matrix[3],"ONLY");
816 gMC->Gspos("UTPW",6+kNplan,"UTI1",-xpos,ypos,zpos,matrix[3],"ONLY");
819 // The volumes for the services at the chambers
822 const Int_t kNparServ = 3;
823 Float_t parServ[kNparServ];
825 for (icham = 0; icham < kNcham; icham++) {
826 for (iplan = 0; iplan < kNplan; iplan++) {
828 Int_t iDet = GetDetectorSec(iplan,icham);
830 sprintf(cTagV,"UU%02d",iDet);
831 parServ[0] = fCwidth[iplan]/2.0;
832 parServ[1] = fClength[iplan][icham]/2.0 - fgkHspace/2.0;
833 // ???? !!!!!!!!!!!!!!
834 parServ[2] = fgkVspace/2.0 - 0.742/2.0;
835 fChamberUUboxd[iDet][0] = parServ[0];
836 fChamberUUboxd[iDet][1] = parServ[1];
837 fChamberUUboxd[iDet][2] = parServ[2];
838 gMC->Gsvolu(cTagV,"BOX",idtmed[1302-1],parServ,kNparServ);
841 ypos = - fClength[iplan][0] - fClength[iplan][1] - fClength[iplan][2]/2.0;
842 for (Int_t ic = 0; ic < icham; ic++) {
843 ypos += fClength[iplan][ic];
845 ypos += fClength[iplan][icham]/2.0;
846 zpos = fgkVrocsm + fgkCH + fgkVspace/2.0 - fgkSheight/2.0
847 + iplan * (fgkCH + fgkVspace);
849 fChamberUUorig[iDet][0] = xpos;
850 fChamberUUorig[iDet][1] = ypos;
851 fChamberUUorig[iDet][2] = zpos;
857 // The cooling pipes inside the service volumes
860 const Int_t kNparTube = 3;
861 Float_t parTube[kNparTube];
862 // The aluminum pipe for the cooling
866 gMC->Gsvolu("UTCP","TUBE",idtmed[1324-1],parTube,0);
869 parTube[1] = 0.2/2.0;
871 gMC->Gsvolu("UTCH","TUBE",idtmed[1314-1],parTube,kNparTube);
872 // Water inside the cooling pipe
876 gMC->Gspos("UTCH",1,"UTCP",xpos,ypos,zpos,0,"ONLY");
878 // Position the cooling pipes in the mother volume
879 const Int_t kNpar = 3;
881 for (icham = 0; icham < kNcham; icham++) {
882 for (iplan = 0; iplan < kNplan; iplan++) {
883 Int_t iDet = GetDetectorSec(iplan,icham);
884 Int_t iCopy = GetDetector(iplan,icham,0) * 100;
885 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
886 Float_t ySize = (GetChamberLength(iplan,icham) - 2.0*fgkRpadW)
887 / ((Float_t) nMCMrow);
888 sprintf(cTagV,"UU%02d",iDet);
889 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
891 ypos = (0.5 + iMCMrow) * ySize - 1.9
892 - fClength[iplan][icham]/2.0 + fgkHspace/2.0;
893 zpos = 0.0 + 0.742/2.0;
895 par[1] = 0.3/2.0; // Thickness of the cooling pipes
896 par[2] = fCwidth[iplan]/2.0;
897 gMC->Gsposp("UTCP",iCopy+iMCMrow,cTagV,xpos,ypos,zpos
898 ,matrix[2],"ONLY",par,kNpar);
907 // The copper power lines
911 gMC->Gsvolu("UTPL","TUBE",idtmed[1305-1],parTube,0);
913 // Position the power lines in the mother volume
914 for (icham = 0; icham < kNcham; icham++) {
915 for (iplan = 0; iplan < kNplan; iplan++) {
916 Int_t iDet = GetDetectorSec(iplan,icham);
917 Int_t iCopy = GetDetector(iplan,icham,0) * 100;
918 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
919 Float_t ySize = (GetChamberLength(iplan,icham) - 2.0*fgkRpadW)
920 / ((Float_t) nMCMrow);
921 sprintf(cTagV,"UU%02d",iDet);
922 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
924 ypos = (0.5 + iMCMrow) * ySize - 1.0
925 - fClength[iplan][icham]/2.0 + fgkHspace/2.0;
926 zpos = -0.4 + 0.742/2.0;
928 par[1] = 0.2/2.0; // Thickness of the power lines
929 par[2] = fCwidth[iplan]/2.0;
930 gMC->Gsposp("UTPL",iCopy+iMCMrow,cTagV,xpos,ypos,zpos
931 ,matrix[2],"ONLY",par,kNpar);
940 // The mother volume for the MCMs (air)
941 const Int_t kNparMCM = 3;
942 Float_t parMCM[kNparMCM];
945 parMCM[2] = 0.14/2.0;
946 gMC->Gsvolu("UMCM","BOX",idtmed[1302-1],parMCM,kNparMCM);
948 // The MCM carrier G10 layer
952 gMC->Gsvolu("UMC1","BOX",idtmed[1319-1],parMCM,kNparMCM);
953 // The MCM carrier Cu layer
956 parMCM[2] = 0.0162/2.0;
957 gMC->Gsvolu("UMC2","BOX",idtmed[1318-1],parMCM,kNparMCM);
958 // The silicon of the chips
961 parMCM[2] = 0.003/2.0;
962 gMC->Gsvolu("UMC3","BOX",idtmed[1320-1],parMCM,kNparMCM);
964 // Put the MCM material inside the MCM mother volume
967 zpos = -0.07 + 0.1/2.0;
968 gMC->Gspos("UMC1",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
969 zpos += 0.1/2.0 + 0.0162/2.0;
970 gMC->Gspos("UMC2",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
971 zpos += 0.00162/2 + 0.003/2.0;
972 gMC->Gspos("UMC3",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
974 // Position the MCMs in the mother volume
975 for (icham = 0; icham < kNcham; icham++) {
976 for (iplan = 0; iplan < kNplan; iplan++) {
977 Int_t iDet = GetDetectorSec(iplan,icham);
978 Int_t iCopy = GetDetector(iplan,icham,0) * 1000;
979 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
980 Float_t ySize = (GetChamberLength(iplan,icham) - 2.0*fgkRpadW)
981 / ((Float_t) nMCMrow);
983 Float_t xSize = (GetChamberWidth(iplan) - 2.0* fgkCpadW)
984 / ((Float_t) nMCMcol);
985 sprintf(cTagV,"UU%02d",iDet);
986 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
987 for (Int_t iMCMcol = 0; iMCMcol < nMCMcol; iMCMcol++) {
988 xpos = (0.5 + iMCMcol) * xSize + 1.0
989 - fCwidth[iplan]/2.0;
990 ypos = (0.5 + iMCMrow) * ySize + 1.0
991 - fClength[iplan][icham]/2.0 + fgkHspace/2.0;
992 zpos = -0.4 + 0.742/2.0;
994 par[1] = 0.2/2.0; // Thickness of the power lines
995 par[2] = fCwidth[iplan]/2.0;
996 gMC->Gspos("UMCM",iCopy+iMCMrow*10+iMCMcol,cTagV
997 ,xpos,ypos,zpos,0,"ONLY");
1006 //_____________________________________________________________________________
1007 void AliTRDgeometry::GroupChamber(Int_t iplan, Int_t icham, Int_t *idtmed)
1010 // Group volumes UA, UD, UF, UU in a single chamber (Air)
1011 // UA, UD, UF, UU are boxes
1015 const Int_t kNparCha = 3;
1017 Int_t iDet = GetDetectorSec(iplan,icham);
1027 for (Int_t i = 0; i < 3; i++) {
1028 xyzMin[i] = +9999.0;
1029 xyzMax[i] = -9999.0;
1032 for (Int_t i = 0; i < 3; i++) {
1034 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUAorig[iDet][i]-fChamberUAboxd[iDet][i]);
1035 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUAorig[iDet][i]+fChamberUAboxd[iDet][i]);
1037 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUDorig[iDet][i]-fChamberUDboxd[iDet][i]);
1038 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUDorig[iDet][i]+fChamberUDboxd[iDet][i]);
1040 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUForig[iDet][i]-fChamberUFboxd[iDet][i]);
1041 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUForig[iDet][i]+fChamberUFboxd[iDet][i]);
1043 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUUorig[iDet][i]-fChamberUUboxd[iDet][i]);
1044 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUUorig[iDet][i]+fChamberUUboxd[iDet][i]);
1046 xyzOrig[i] = 0.5*(xyzMax[i]+xyzMin[i]);
1047 xyzBoxd[i] = 0.5*(xyzMax[i]-xyzMin[i]);
1051 sprintf(cTagM,"UT%02d",iDet);
1052 gMC->Gsvolu(cTagM,"BOX ",idtmed[1302-1],xyzBoxd,kNparCha);
1054 sprintf(cTagV,"UA%02d",iDet);
1055 gMC->Gspos(cTagV,1,cTagM,
1056 fChamberUAorig[iDet][0]-xyzOrig[0],
1057 fChamberUAorig[iDet][1]-xyzOrig[1],
1058 fChamberUAorig[iDet][2]-xyzOrig[2],
1061 sprintf(cTagV,"UD%02d",iDet);
1062 gMC->Gspos(cTagV,1,cTagM,
1063 fChamberUDorig[iDet][0]-xyzOrig[0],
1064 fChamberUDorig[iDet][1]-xyzOrig[1],
1065 fChamberUDorig[iDet][2]-xyzOrig[2],
1068 sprintf(cTagV,"UF%02d",iDet);
1069 gMC->Gspos(cTagV,1,cTagM,
1070 fChamberUForig[iDet][0]-xyzOrig[0],
1071 fChamberUForig[iDet][1]-xyzOrig[1],
1072 fChamberUForig[iDet][2]-xyzOrig[2],
1075 sprintf(cTagV,"UU%02d",iDet);
1076 gMC->Gspos(cTagV,1,cTagM,
1077 fChamberUUorig[iDet][0]-xyzOrig[0],
1078 fChamberUUorig[iDet][1]-xyzOrig[1],
1079 fChamberUUorig[iDet][2]-xyzOrig[2],
1082 sprintf(cTagV,"UT%02d",iDet);
1083 gMC->Gspos(cTagV,1,"UTI1",xyzOrig[0],xyzOrig[1],xyzOrig[2],0,"ONLY");
1087 //_____________________________________________________________________________
1088 Bool_t AliTRDgeometry::Local2Global(Int_t idet, Double_t *local
1089 , Double_t *global) const
1092 // Converts local pad-coordinates (row,col,time) into
1093 // global ALICE reference frame coordinates (x,y,z)
1096 Int_t icham = GetChamber(idet); // Chamber info (0-4)
1097 Int_t isect = GetSector(idet); // Sector info (0-17)
1098 Int_t iplan = GetPlane(idet); // Plane info (0-5)
1100 return Local2Global(iplan,icham,isect,local,global);
1104 //_____________________________________________________________________________
1105 Bool_t AliTRDgeometry::Local2Global(Int_t iplan, Int_t icham, Int_t isect
1106 , Double_t *local, Double_t *global) const
1109 // Converts local pad-coordinates (row,col,time) into
1110 // global ALICE reference frame coordinates (x,y,z)
1113 AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
1115 AliError("Could not get common parameters\n");
1119 AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
1121 AliError("Could not get calibration data\n");
1125 AliTRDpadPlane *padPlane = commonParam->GetPadPlane(iplan,icham);
1127 // calculate (x,y,z) position in rotated chamber
1128 Int_t row = ((Int_t) local[0]);
1129 Int_t col = ((Int_t) local[1]);
1130 Float_t timeSlice = local[2] + 0.5;
1131 Float_t time0 = GetTime0(iplan);
1133 Int_t idet = GetDetector(iplan, icham, isect);
1136 rot[0] = time0 - (timeSlice - calibration->GetT0(idet, col, row))
1137 * calibration->GetVdrift(idet, col, row)
1138 / calibration->GetSamplingFrequency();
1139 rot[1] = padPlane->GetColPos(col) - 0.5 * padPlane->GetColSize(col);
1140 rot[2] = padPlane->GetRowPos(row) - 0.5 * padPlane->GetRowSize(row);
1142 // Rotate back to original position
1143 return RotateBack(idet,rot,global);
1147 //_____________________________________________________________________________
1148 Bool_t AliTRDgeometry::Global2Local(Int_t mode, Double_t *local, Double_t *global
1149 , Int_t* index) const
1152 // Converts local pad-coordinates (row,col,time) into
1153 // global ALICE reference frame coordinates (x,y,z)
1155 // index[0] = plane number
1156 // index[1] = chamber number
1157 // index[2] = sector number
1159 // mode = 0 - local coordinate in y, z, x - rotated global
1162 Int_t idet = GetDetector(index[0],index[1],index[2]); // Detector number
1163 RotateBack(idet,global,local);
1173 //_____________________________________________________________________________
1174 Bool_t AliTRDgeometry::Global2Detector(Double_t global[3], Int_t index[3])
1177 // Find detector for given global point - Ideal geometry
1180 // input = global position
1182 // index[0] = plane number
1183 // index[1] = chamber number
1184 // index[2] = sector number
1190 Float_t fi = TMath::ATan2(global[1],global[0]);
1192 fi += 2.0 * TMath::Pi();
1194 index[2] = fgkNsect - 1 - TMath::Nint((fi - GetAlpha()/2.0) / GetAlpha());
1199 Float_t locx = global[0] * fRotA11[index[2]] + global[1] * fRotA12[index[2]];
1201 Float_t max = locx - GetTime0(0);
1202 for (Int_t iplane = 1; iplane < fgkNplan; iplane++) {
1203 Float_t dist = TMath::Abs(locx - GetTime0(iplane));
1213 if (TMath::Abs(global[2]) < 0.5*GetChamberLength(index[0],2)) {
1217 Double_t localZ = global[2];
1218 if (global[2] > 0.0) {
1219 localZ -= 0.5*(GetChamberLength(index[0],2)+GetChamberLength(index[0],1));
1220 index[1] = (TMath::Abs(localZ) < 0.5*GetChamberLength(index[0],3)) ? 1 : 0;
1223 localZ += 0.5*(GetChamberLength(index[0],2)+GetChamberLength(index[0],3));
1224 index[1] = (TMath::Abs(localZ) < 0.5*GetChamberLength(index[0],1)) ? 3 : 4;
1232 //_____________________________________________________________________________
1233 Bool_t AliTRDgeometry::Rotate(Int_t d, Double_t *pos, Double_t *rot) const
1236 // Rotates all chambers in the position of sector 0 and transforms
1237 // the coordinates in the ALICE restframe <pos> into the
1238 // corresponding local frame <rot>.
1241 Int_t sector = GetSector(d);
1243 rot[0] = pos[0] * fRotA11[sector] + pos[1] * fRotA12[sector];
1244 rot[1] = -pos[0] * fRotA21[sector] + pos[1] * fRotA22[sector];
1251 //_____________________________________________________________________________
1252 Bool_t AliTRDgeometry::RotateBack(Int_t d, Double_t *rot, Double_t *pos) const
1255 // Rotates a chambers from the position of sector 0 into its
1256 // original position and transforms the corresponding local frame
1257 // coordinates <rot> into the coordinates of the ALICE restframe <pos>.
1260 Int_t sector = GetSector(d);
1262 pos[0] = rot[0] * fRotB11[sector] + rot[1] * fRotB12[sector];
1263 pos[1] = -rot[0] * fRotB21[sector] + rot[1] * fRotB22[sector];
1270 //_____________________________________________________________________________
1271 Int_t AliTRDgeometry::GetDetectorSec(Int_t p, Int_t c)
1274 // Convert plane / chamber into detector number for one single sector
1277 return (p + c * fgkNplan);
1281 //_____________________________________________________________________________
1282 Int_t AliTRDgeometry::GetDetector(Int_t p, Int_t c, Int_t s)
1285 // Convert plane / chamber / sector into detector number
1288 return (p + c * fgkNplan + s * fgkNplan * fgkNcham);
1292 //_____________________________________________________________________________
1293 Int_t AliTRDgeometry::GetPlane(Int_t d) const
1296 // Reconstruct the plane number from the detector number
1299 return ((Int_t) (d % fgkNplan));
1303 //_____________________________________________________________________________
1304 Int_t AliTRDgeometry::GetChamber(Int_t d) const
1307 // Reconstruct the chamber number from the detector number
1310 return ((Int_t) (d % (fgkNplan * fgkNcham)) / fgkNplan);
1314 //_____________________________________________________________________________
1315 Int_t AliTRDgeometry::GetSector(Int_t d) const
1318 // Reconstruct the sector number from the detector number
1321 return ((Int_t) (d / (fgkNplan * fgkNcham)));
1325 //_____________________________________________________________________________
1326 AliTRDgeometry* AliTRDgeometry::GetGeometry(AliRunLoader *runLoader)
1329 // Load the geometry from the galice file
1333 runLoader = AliRunLoader::GetRunLoader();
1336 AliErrorGeneral("AliTRDgeometry::GetGeometry","No run loader");
1340 TDirectory *saveDir = gDirectory;
1341 runLoader->CdGAFile();
1343 // Try from the galice.root file
1344 AliTRDgeometry *geom = (AliTRDgeometry *) gDirectory->Get("TRDgeometry");
1347 // If it is not in the file, try to get it from the run loader
1348 AliTRD *trd = (AliTRD *) runLoader->GetAliRun()->GetDetector("TRD");
1349 geom = trd->GetGeometry();
1352 AliErrorGeneral("AliTRDgeometry::GetGeometry","Geometry not found");
1361 //_____________________________________________________________________________
1362 Bool_t AliTRDgeometry::ReadGeoMatrices()
1365 // Read geo matrices from current gGeoManager for each TRD sector
1371 fMatrixArray = new TObjArray(kNdet);
1372 fMatrixCorrectionArray = new TObjArray(kNdet);
1373 fMatrixGeo = new TObjArray(kNdet);
1374 AliAlignObjAngles o;
1376 for (Int_t iLayer = AliAlignObj::kTRD1; iLayer <= AliAlignObj::kTRD6; iLayer++) {
1377 for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
1379 UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,iModule);
1380 const char *symname = AliAlignObj::SymName(volid);
1381 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
1382 const char *path = symname;
1383 if(pne) path=pne->GetTitle();
1384 if (!gGeoManager->cd(path)) return kFALSE;
1385 TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
1386 Int_t iLayerTRD = iLayer - AliAlignObj::kTRD1;
1387 Int_t isector = Nsect() - 1 - (iModule/Ncham());
1388 Int_t ichamber = Ncham() - 1 - (iModule%Ncham());
1389 Int_t lid = GetDetector(iLayerTRD,ichamber,isector);
1392 // Local geo system z-x-y to x-y--z
1394 fMatrixGeo->AddAt(new TGeoHMatrix(*m),lid);
1396 TGeoRotation mchange;
1397 mchange.RotateY(90);
1398 mchange.RotateX(90);
1400 TGeoHMatrix gMatrix(mchange.Inverse());
1401 gMatrix.MultiplyLeft(m);
1402 fMatrixArray->AddAt(new TGeoHMatrix(gMatrix),lid);
1405 // Cluster transformation matrix
1407 TGeoHMatrix rotMatrix(mchange.Inverse());
1408 rotMatrix.MultiplyLeft(m);
1409 Double_t sectorAngle = 20.0 * (isector % 18) + 10.0;
1410 TGeoHMatrix rotSector;
1411 rotSector.RotateZ(sectorAngle);
1412 rotMatrix.MultiplyLeft(&rotSector);
1414 fMatrixCorrectionArray->AddAt(new TGeoHMatrix(rotMatrix),lid);