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
68 const Float_t AliTRDgeometry::fgkSheight = 77.9;
69 const Float_t AliTRDgeometry::fgkSwidth1 = 94.881;
70 const Float_t AliTRDgeometry::fgkSwidth2 = 122.353;
71 const Float_t AliTRDgeometry::fgkSlenTR1 = 751.0;
72 const Float_t AliTRDgeometry::fgkSlenTR2 = 313.5;
73 const Float_t AliTRDgeometry::fgkSlenTR3 = 159.5;
75 // The super module side plates
76 const Float_t AliTRDgeometry::fgkSMpltT = 0.2;
77 //const Float_t AliTRDgeometry::fgkSMgapT = 0.5;
79 // Height of different chamber parts
81 const Float_t AliTRDgeometry::fgkCraH = 4.8;
83 const Float_t AliTRDgeometry::fgkCdrH = 3.0;
84 // Amplification region
85 const Float_t AliTRDgeometry::fgkCamH = 0.7;
87 const Float_t AliTRDgeometry::fgkCroH = 2.316;
89 const Float_t AliTRDgeometry::fgkCH = AliTRDgeometry::fgkCraH
90 + AliTRDgeometry::fgkCdrH
91 + AliTRDgeometry::fgkCamH
92 + AliTRDgeometry::fgkCroH;
94 // Vertical spacing of the chambers
95 const Float_t AliTRDgeometry::fgkVspace = 1.784;
97 // Horizontal spacing of the chambers
98 const Float_t AliTRDgeometry::fgkHspace = 2.0;
100 // Radial distance of the first ROC to the outer plates of the SM
101 const Float_t AliTRDgeometry::fgkVrocsm = 1.2;
103 // Thicknesses of different parts of the chamber frame
104 // Lower aluminum frame
105 const Float_t AliTRDgeometry::fgkCalT = 0.3;
106 // Lower G10 frame sides
107 const Float_t AliTRDgeometry::fgkCclsT = 0.3;
108 // Lower G10 frame front
109 const Float_t AliTRDgeometry::fgkCclfT = 1.0;
111 const Float_t AliTRDgeometry::fgkCcuT = 0.9;
113 const Float_t AliTRDgeometry::fgkCauT = 1.5;
115 // Additional width of the readout chamber frames
116 const Float_t AliTRDgeometry::fgkCroW = 0.9;
118 // Difference of outer chamber width and pad plane width
119 //const Float_t AliTRDgeometry::fgkCpadW = 1.0;
120 const Float_t AliTRDgeometry::fgkCpadW = 0.0;
121 const Float_t AliTRDgeometry::fgkRpadW = 1.0;
124 // Thickness of the the material layers
126 const Float_t AliTRDgeometry::fgkRaThick = 0.3646;
127 const Float_t AliTRDgeometry::fgkMyThick = 0.005;
128 const Float_t AliTRDgeometry::fgkDrThick = AliTRDgeometry::fgkCdrH;
129 const Float_t AliTRDgeometry::fgkAmThick = AliTRDgeometry::fgkCamH;
130 const Float_t AliTRDgeometry::fgkXeThick = AliTRDgeometry::fgkDrThick
131 + AliTRDgeometry::fgkAmThick;
132 const Float_t AliTRDgeometry::fgkCuThick = 0.0072;
133 const Float_t AliTRDgeometry::fgkSuThick = 0.06;
134 const Float_t AliTRDgeometry::fgkFeThick = 0.0044;
135 const Float_t AliTRDgeometry::fgkCoThick = 0.02;
136 const Float_t AliTRDgeometry::fgkWaThick = 0.02;
137 const Float_t AliTRDgeometry::fgkRcThick = 0.0058;
138 const Float_t AliTRDgeometry::fgkRpThick = 0.0632;
141 // Position of the material layers
143 const Float_t AliTRDgeometry::fgkRaZpos = -1.50;
144 const Float_t AliTRDgeometry::fgkMyZpos = 0.895;
145 const Float_t AliTRDgeometry::fgkDrZpos = 2.4;
146 const Float_t AliTRDgeometry::fgkAmZpos = 0.0;
147 const Float_t AliTRDgeometry::fgkCuZpos = -0.9995;
148 const Float_t AliTRDgeometry::fgkSuZpos = 0.0000;
149 const Float_t AliTRDgeometry::fgkFeZpos = 0.0322;
150 const Float_t AliTRDgeometry::fgkCoZpos = 0.97;
151 const Float_t AliTRDgeometry::fgkWaZpos = 0.99;
152 const Float_t AliTRDgeometry::fgkRcZpos = 1.04;
153 const Float_t AliTRDgeometry::fgkRpZpos = 1.0;
155 const Double_t AliTRDgeometry::fgkTime0Base = Rmin() + CraHght() + CdrHght() + CamHght()/2.;
156 const Float_t AliTRDgeometry::fgkTime0[6] = { fgkTime0Base + 0 * (Cheight() + Cspace()),
157 fgkTime0Base + 1 * (Cheight() + Cspace()),
158 fgkTime0Base + 2 * (Cheight() + Cspace()),
159 fgkTime0Base + 3 * (Cheight() + Cspace()),
160 fgkTime0Base + 4 * (Cheight() + Cspace()),
161 fgkTime0Base + 5 * (Cheight() + Cspace()) };
163 //_____________________________________________________________________________
164 AliTRDgeometry::AliTRDgeometry():AliGeometry()
167 // AliTRDgeometry default constructor
171 fMatrixCorrectionArray = 0;
177 //_____________________________________________________________________________
178 AliTRDgeometry::~AliTRDgeometry()
181 // AliTRDgeometry destructor
185 delete fMatrixCorrectionArray;
189 //_____________________________________________________________________________
190 void AliTRDgeometry::Init()
193 // Initializes the geometry parameter
195 // The maximum number of pads
196 // and the position of pad 0,0,0
198 // chambers seen from the top:
199 // +----------------------------+
205 // +----------------------------+ +------>
207 // chambers seen from the side: ^
208 // +----------------------------+ drift|
211 // +----------------------------+ +------>
214 // IMPORTANT: time bin 0 is now the first one in the drift region
215 // closest to the readout !!!
222 // The outer width of the chambers
230 // The outer lengths of the chambers
231 // Includes the spacings between the chambers!
232 Float_t length[kNplan][kNcham] = { { 124.0, 124.0, 110.0, 124.0, 124.0 }
233 , { 124.0, 124.0, 110.0, 124.0, 124.0 }
234 , { 131.0, 131.0, 110.0, 131.0, 131.0 }
235 , { 138.0, 138.0, 110.0, 138.0, 138.0 }
236 , { 145.0, 145.0, 110.0, 145.0, 145.0 }
237 , { 147.0, 147.0, 110.0, 147.0, 147.0 } };
239 for (icham = 0; icham < kNcham; icham++) {
240 for (iplan = 0; iplan < kNplan; iplan++) {
241 fClength[iplan][icham] = length[iplan][icham];
245 // The rotation matrix elements
247 for (isect = 0; isect < fgkNsect; isect++) {
248 phi = -2.0 * TMath::Pi() / (Float_t) fgkNsect * ((Float_t) isect + 0.5);
249 fRotA11[isect] = TMath::Cos(phi);
250 fRotA12[isect] = TMath::Sin(phi);
251 fRotA21[isect] = TMath::Sin(phi);
252 fRotA22[isect] = TMath::Cos(phi);
254 fRotB11[isect] = TMath::Cos(phi);
255 fRotB12[isect] = TMath::Sin(phi);
256 fRotB21[isect] = TMath::Sin(phi);
257 fRotB22[isect] = TMath::Cos(phi);
260 for (isect = 0; isect < fgkNsect; isect++) {
261 SetSMstatus(isect,1);
266 //_____________________________________________________________________________
267 void AliTRDgeometry::CreateGeometry(Int_t *idtmed)
270 // Create the TRD geometry without hole
273 // Names of the TRD volumina (xx = detector number):
275 // Volume (Air) wrapping the readout chamber components
276 // UTxx includes: UAxx, UDxx, UFxx, UUxx
278 // UUxx the services volume has been reduced by 7.42 mm
279 // in order to allow shifts in radial direction
281 // Lower part of the readout chambers (gas volume + radiator)
283 // UAxx Aluminum frames (Al)
284 // UBxx G10 frames (C)
285 // UCxx Inner volumes (Air)
287 // Upper part of the readout chambers (readout plane + fee)
289 // UDxx G10 frames (C)
290 // UExx Inner volumes of the G10 (Air)
291 // UFxx Aluminum frames (Al)
292 // UGxx Inner volumes of the Al (Air)
294 // Inner material layers
296 // UHxx Radiator (Rohacell)
297 // UIxx Entrance window (Mylar)
298 // UJxx Drift volume (Xe/CO2)
299 // UKxx Amplification volume (Xe/CO2)
300 // ULxx Pad plane (Cu)
301 // UMxx Support structure (Rohacell)
302 // UNxx ROB base material (C)
303 // UOxx ROB copper (Cu)
306 const Int_t kNparTrd = 4;
307 const Int_t kNparCha = 3;
309 Float_t xpos, ypos, zpos;
311 Float_t parTrd[kNparTrd];
312 Float_t parCha[kNparCha];
317 // The TRD mother volume for one sector (Air), full length in z-direction
318 // Provides material for side plates of super module
319 parTrd[0] = fgkSwidth1/2.;
320 parTrd[1] = fgkSwidth2/2.;
321 parTrd[2] = fgkSlenTR1/2.;
322 parTrd[3] = fgkSheight/2.;
323 gMC->Gsvolu("UTR1","TRD1",idtmed[1302-1],parTrd,kNparTrd);
326 // The outer aluminum plates of the super module (Al)
327 parTrd[0] = fgkSwidth1/2.;
328 parTrd[1] = fgkSwidth2/2.;
329 parTrd[2] = fgkSlenTR1/2.;
330 parTrd[3] = fgkSheight/2.;
331 gMC->Gsvolu("UTS1","TRD1",idtmed[1301-1],parTrd,kNparTrd);
333 // The inner part of the TRD mother volume for one sector (Air),
334 // full length in z-direction
335 parTrd[0] = fgkSwidth1/2. - fgkSMpltT;
336 parTrd[1] = fgkSwidth2/2. - fgkSMpltT;
337 parTrd[2] = fgkSlenTR1/2.;
338 parTrd[3] = fgkSheight/2. - fgkSMpltT;
339 gMC->Gsvolu("UTI1","TRD1",idtmed[1302-1],parTrd,kNparTrd);
341 for (Int_t icham = 0; icham < kNcham; icham++) {
342 for (Int_t iplan = 0; iplan < kNplan; iplan++) {
344 Int_t iDet = GetDetectorSec(iplan,icham);
346 // The lower part of the readout chambers (gas volume + radiator)
347 // The aluminum frames
348 sprintf(cTagV,"UA%02d",iDet);
349 parCha[0] = fCwidth[iplan]/2.;
350 parCha[1] = fClength[iplan][icham]/2. - fgkHspace/2.;
351 parCha[2] = fgkCraH/2. + fgkCdrH/2.;
352 fChamberUAboxd[iDet][0] = parCha[0];
353 fChamberUAboxd[iDet][1] = parCha[1];
354 fChamberUAboxd[iDet][2] = parCha[2];
355 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parCha,kNparCha);
357 sprintf(cTagV,"UB%02d",iDet);
358 parCha[0] = fCwidth[iplan]/2. - fgkCalT;
361 gMC->Gsvolu(cTagV,"BOX ",idtmed[1307-1],parCha,kNparCha);
362 // The inner part (air)
363 sprintf(cTagV,"UC%02d",iDet);
364 parCha[0] = fCwidth[iplan]/2. - fgkCalT - fgkCclsT;
365 parCha[1] = fClength[iplan][icham]/2. - fgkHspace/2.- fgkCclfT;
367 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
369 // The upper part of the readout chambers (readout plane)
371 sprintf(cTagV,"UD%02d",iDet);
372 parCha[0] = fCwidth[iplan]/2. + fgkCroW;
373 parCha[1] = fClength[iplan][icham]/2. - fgkHspace/2.;
374 parCha[2] = fgkCamH/2.;
375 fChamberUDboxd[iDet][0] = parCha[0];
376 fChamberUDboxd[iDet][1] = parCha[1];
377 fChamberUDboxd[iDet][2] = parCha[2];
378 gMC->Gsvolu(cTagV,"BOX ",idtmed[1307-1],parCha,kNparCha);
379 // The inner part of the G10 frame (air)
380 sprintf(cTagV,"UE%02d",iDet);
381 parCha[0] = fCwidth[iplan]/2. + fgkCroW - fgkCcuT;
382 parCha[1] = fClength[iplan][icham]/2. - fgkHspace/2.- fgkCcuT;
384 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
385 // The aluminum frames
386 sprintf(cTagV,"UF%02d",iDet);
387 parCha[0] = fCwidth[iplan]/2. + fgkCroW;
388 parCha[1] = fClength[iplan][icham]/2. - fgkHspace/2.;
389 parCha[2] = fgkCroH/2.;
390 fChamberUFboxd[iDet][0] = parCha[0];
391 fChamberUFboxd[iDet][1] = parCha[1];
392 fChamberUFboxd[iDet][2] = parCha[2];
393 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parCha,kNparCha);
394 // The inner part of the aluminum frames
395 sprintf(cTagV,"UG%02d",iDet);
396 parCha[0] = fCwidth[iplan]/2. + fgkCroW - fgkCauT;
397 parCha[1] = fClength[iplan][icham]/2. - fgkHspace/2.- fgkCauT;
399 gMC->Gsvolu(cTagV,"BOX ",idtmed[1302-1],parCha,kNparCha);
401 // The material layers inside the chambers
404 // Rohacell layer (radiator)
405 parCha[2] = fgkRaThick/2;
406 sprintf(cTagV,"UH%02d",iDet);
407 gMC->Gsvolu(cTagV,"BOX ",idtmed[1315-1],parCha,kNparCha);
408 // Mylar layer (entrance window + HV cathode)
409 parCha[2] = fgkMyThick/2;
410 sprintf(cTagV,"UI%02d",iDet);
411 gMC->Gsvolu(cTagV,"BOX ",idtmed[1308-1],parCha,kNparCha);
412 // Xe/Isobutane layer (drift volume)
413 parCha[2] = fgkDrThick/2.;
414 sprintf(cTagV,"UJ%02d",iDet);
415 gMC->Gsvolu(cTagV,"BOX ",idtmed[1309-1],parCha,kNparCha);
416 // Xe/Isobutane layer (amplification volume)
417 parCha[2] = fgkAmThick/2.;
418 sprintf(cTagV,"UK%02d",iDet);
419 gMC->Gsvolu(cTagV,"BOX ",idtmed[1309-1],parCha,kNparCha);
420 // Cu layer (pad plane)
421 parCha[2] = fgkCuThick/2;
422 sprintf(cTagV,"UL%02d",iDet);
423 gMC->Gsvolu(cTagV,"BOX ",idtmed[1305-1],parCha,kNparCha);
424 // G10 layer (support structure / honeycomb)
425 parCha[2] = fgkSuThick/2;
426 sprintf(cTagV,"UM%02d",iDet);
427 gMC->Gsvolu(cTagV,"BOX ",idtmed[1313-1],parCha,kNparCha);
428 // G10 layer (readout board)
429 parCha[2] = fgkRpThick/2;
430 sprintf(cTagV,"UN%02d",iDet);
431 gMC->Gsvolu(cTagV,"BOX ",idtmed[1313-1],parCha,kNparCha);
432 // Cu layer (readout board)
433 parCha[2] = fgkRcThick/2;
434 sprintf(cTagV,"UO%02d",iDet);
435 gMC->Gsvolu(cTagV,"BOX ",idtmed[1306-1],parCha,kNparCha);
437 // Position the layers in the chambers
441 // Rohacell layer (radiator)
443 sprintf(cTagV,"UH%02d",iDet);
444 sprintf(cTagM,"UC%02d",iDet);
445 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
446 // Mylar layer (entrance window + HV cathode)
448 sprintf(cTagV,"UI%02d",iDet);
449 sprintf(cTagM,"UC%02d",iDet);
450 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
451 // Xe/Isobutane layer (drift volume)
453 sprintf(cTagV,"UJ%02d",iDet);
454 sprintf(cTagM,"UC%02d",iDet);
455 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
457 // Xe/Isobutane layer (amplification volume)
459 sprintf(cTagV,"UK%02d",iDet);
460 sprintf(cTagM,"UE%02d",iDet);
461 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
463 // Cu layer (pad plane)
465 sprintf(cTagV,"UL%02d",iDet);
466 sprintf(cTagM,"UG%02d",iDet);
467 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
468 // G10 layer (support structure)
470 sprintf(cTagV,"UM%02d",iDet);
471 sprintf(cTagM,"UG%02d",iDet);
472 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
473 // G10 layer (readout board)
475 sprintf(cTagV,"UN%02d",iDet);
476 sprintf(cTagM,"UG%02d",iDet);
477 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
478 // Cu layer (readout board)
480 sprintf(cTagV,"UO%02d",iDet);
481 sprintf(cTagM,"UG%02d",iDet);
482 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
484 // Position the inner volumes of the chambers in the frames
488 // The inside of the lower G10 frame
489 sprintf(cTagV,"UC%02d",iDet);
490 sprintf(cTagM,"UB%02d",iDet);
491 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
492 // The lower G10 frame inside the aluminum frame
493 sprintf(cTagV,"UB%02d",iDet);
494 sprintf(cTagM,"UA%02d",iDet);
495 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
496 // The inside of the upper G10 frame
497 sprintf(cTagV,"UE%02d",iDet);
498 sprintf(cTagM,"UD%02d",iDet);
499 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
500 // The inside of the upper aluminum frame
501 sprintf(cTagV,"UG%02d",iDet);
502 sprintf(cTagM,"UF%02d",iDet);
503 gMC->Gspos(cTagV,1,cTagM,xpos,ypos,zpos,0,"ONLY");
505 // Position the frames of the chambers in the TRD mother volume
507 ypos = - fClength[iplan][0] - fClength[iplan][1] - fClength[iplan][2]/2.;
508 for (Int_t ic = 0; ic < icham; ic++) {
509 ypos += fClength[iplan][ic];
511 ypos += fClength[iplan][icham]/2.;
512 zpos = fgkVrocsm + fgkCraH/2. + fgkCdrH/2. - fgkSheight/2.
513 + iplan * (fgkCH + fgkVspace);
514 // The lower aluminum frame, radiator + drift region
515 sprintf(cTagV,"UA%02d",iDet);
516 fChamberUAorig[iDet][0] = xpos;
517 fChamberUAorig[iDet][1] = ypos;
518 fChamberUAorig[iDet][2] = zpos;
519 // The upper G10 frame, amplification region
520 sprintf(cTagV,"UD%02d",iDet);
521 zpos += fgkCamH/2. + fgkCraH/2. + fgkCdrH/2.;
522 fChamberUDorig[iDet][0] = xpos;
523 fChamberUDorig[iDet][1] = ypos;
524 fChamberUDorig[iDet][2] = zpos;
525 // The upper aluminum frame
526 sprintf(cTagV,"UF%02d",iDet);
527 zpos += fgkCroH/2. + fgkCamH/2.;
528 fChamberUForig[iDet][0] = xpos;
529 fChamberUForig[iDet][1] = ypos;
530 fChamberUForig[iDet][2] = zpos;
535 // Create the volumes of the super module frame
538 // Create the volumes of the services
539 CreateServices(idtmed);
541 for (Int_t icham = 0; icham < kNcham; icham++) {
542 for (Int_t iplan = 0; iplan < kNplan; iplan++) {
543 GroupChamber(iplan,icham,idtmed);
550 gMC->Gspos("UTI1",1,"UTS1",xpos,ypos,zpos,0,"ONLY");
555 gMC->Gspos("UTS1",1,"UTR1",xpos,ypos,zpos,0,"ONLY");
557 // Put the TRD volumes into the space frame mother volumes
558 // if enabled via status flag
562 for (Int_t isect = 0; isect < kNsect; isect++) {
563 if (fSMstatus[isect]) {
564 sprintf(cTagV,"BTRD%d",isect);
565 gMC->Gspos("UTR1",1,cTagV,xpos,ypos,zpos,0,"ONLY");
571 //_____________________________________________________________________________
572 void AliTRDgeometry::CreateFrame(Int_t *idtmed)
575 // Create the geometry of the frame of the supermodule
577 // Names of the TRD services volumina
579 // USRL Support rails for the chambers (Al)
580 // USxx Support cross bars between the chambers (Al)
592 // The chamber support rails
595 const Float_t kSRLwid = 2.0;
596 const Float_t kSRLhgt = 2.3;
597 const Float_t kSRLdst = 0.6;
598 const Int_t kNparSRL = 3;
599 Float_t parSRL[kNparSRL];
600 parSRL[0] = kSRLwid/2.;
601 parSRL[1] = fgkSlenTR1/2.;
602 parSRL[2] = kSRLhgt/2.;
603 gMC->Gsvolu("USRL","BOX ",idtmed[1301-1],parSRL,kNparSRL);
608 for (iplan = 0; iplan < kNplan; iplan++) {
610 xpos = fCwidth[iplan]/2. + kSRLwid/2. + kSRLdst;
612 zpos = fgkVrocsm + fgkCraH + fgkCdrH - fgkSheight/2. - kSRLhgt/2.
613 + iplan * (fgkCH + fgkVspace);
614 gMC->Gspos("USRL",iplan+1 ,"UTI1", xpos,ypos,zpos,0,"ONLY");
615 gMC->Gspos("USRL",iplan+1+ kNplan,"UTI1",-xpos,ypos,zpos,0,"ONLY");
620 // The cross bars between the chambers
623 const Float_t kSCBwid = 1.0;
624 const Int_t kNparSCB = 3;
625 Float_t parSCB[kNparSCB];
626 parSCB[1] = kSCBwid/2.;
627 parSCB[2] = fgkCH/2.;
632 for (iplan = 0; iplan < kNplan; iplan++) {
634 parSCB[0] = fCwidth[iplan]/2. + kSRLdst/2.;
636 sprintf(cTagV,"US0%01d",iplan);
637 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
639 ypos = fgkSlenTR1/2. - kSCBwid/2.;
640 zpos = fgkVrocsm + fgkCH/2. - fgkSheight/2. + iplan * (fgkCH + fgkVspace);
641 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
643 sprintf(cTagV,"US1%01d",iplan);
644 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
646 ypos = fClength[iplan][2]/2. + fClength[iplan][1];
647 zpos = fgkVrocsm + fgkCH/2. - fgkSheight/2. + iplan * (fgkCH + fgkVspace);
648 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
650 sprintf(cTagV,"US2%01d",iplan);
651 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
653 ypos = fClength[iplan][2]/2.;
654 zpos = fgkVrocsm + fgkCH/2. - fgkSheight/2. + iplan * (fgkCH + fgkVspace);
655 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
657 sprintf(cTagV,"US3%01d",iplan);
658 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
660 ypos = - fClength[iplan][2]/2.;
661 zpos = fgkVrocsm + fgkCH/2. - fgkSheight/2. + iplan * (fgkCH + fgkVspace);
662 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
664 sprintf(cTagV,"US4%01d",iplan);
665 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
667 ypos = - fClength[iplan][2]/2. - fClength[iplan][1];
668 zpos = fgkVrocsm + fgkCH/2. - fgkSheight/2. + iplan * (fgkCH + fgkVspace);
669 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
671 sprintf(cTagV,"US5%01d",iplan);
672 gMC->Gsvolu(cTagV,"BOX ",idtmed[1301-1],parSCB,kNparSCB);
674 ypos = - fgkSlenTR1/2. + kSCBwid/2.;
675 zpos = fgkVrocsm + fgkCH/2. - fgkSheight/2. + iplan * (fgkCH + fgkVspace);
676 gMC->Gspos(cTagV,1,"UTI1", xpos,ypos,zpos,0,"ONLY");
682 //_____________________________________________________________________________
683 void AliTRDgeometry::CreateServices(Int_t *idtmed)
686 // Create the geometry of the services
688 // Names of the TRD services volumina
690 // UTCL Cooling arterias (Al)
691 // UTCW Cooling arterias (Water)
692 // UUxx Volumes for the services at the chambers (Air)
693 // UTPW Power bars (Cu)
694 // UTCP Cooling pipes (Al)
695 // UTCH Cooling pipes (Water)
696 // UTPL Power lines (Cu)
697 // UMCM Readout MCMs (G10/Cu/Si)
709 // The rotation matrices
710 const Int_t kNmatrix = 3;
711 Int_t matrix[kNmatrix];
712 gMC->Matrix(matrix[0],100.0, 0.0, 90.0, 90.0, 10.0, 0.0);
713 gMC->Matrix(matrix[1], 80.0, 0.0, 90.0, 90.0, 10.0,180.0);
714 gMC->Matrix(matrix[2], 0.0, 0.0, 90.0, 90.0, 90.0, 0.0);
716 AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
719 AliError("Could not get common params\n");
724 // The cooling arterias
727 // Width of the cooling arterias
728 const Float_t kCOLwid = 0.5;
729 // Height of the cooling arterias
730 const Float_t kCOLhgt = 5.5;
731 // Positioning of the cooling
732 const Float_t kCOLposx = 1.6;
733 const Float_t kCOLposz = -0.2;
734 // Thickness of the walls of the cooling arterias
735 const Float_t kCOLthk = 0.1;
736 const Int_t kNparCOL = 3;
737 Float_t parCOL[kNparCOL];
738 parCOL[0] = kCOLwid/2.;
739 parCOL[1] = fgkSlenTR1/2.;
740 parCOL[2] = kCOLhgt/2.;
741 gMC->Gsvolu("UTCL","BOX ",idtmed[1324-1],parCOL,kNparCOL);
742 parCOL[0] -= kCOLthk;
743 parCOL[1] = fgkSlenTR1/2.;
744 parCOL[2] -= kCOLthk;
745 gMC->Gsvolu("UTCW","BOX ",idtmed[1314-1],parCOL,kNparCOL);
750 gMC->Gspos("UTCW",1,"UTCL", xpos,ypos,zpos,0,"ONLY");
752 for (iplan = 0; iplan < kNplan; iplan++) {
754 xpos = fCwidth[iplan]/2. + kCOLwid/2. + kCOLposx;
756 zpos = fgkVrocsm + kCOLhgt/2. - fgkSheight/2. + kCOLposz
757 + iplan * (fgkCH + fgkVspace);
758 if (iplan == 0) zpos += 0.25; // To avoid overlaps !
759 gMC->Gspos("UTCL",iplan+1 ,"UTI1", xpos,ypos,zpos,matrix[0],"ONLY");
760 gMC->Gspos("UTCL",iplan+1+ kNplan,"UTI1",-xpos,ypos,zpos,matrix[1],"ONLY");
768 const Float_t kPWRwid = 0.6;
769 const Float_t kPWRhgt = 4.5;
770 const Float_t kPWRposx = 1.05;
771 const Float_t kPWRposz = 0.9;
772 const Int_t kNparPWR = 3;
773 Float_t parPWR[kNparPWR];
774 parPWR[0] = kPWRwid/2.;
775 parPWR[1] = fgkSlenTR1/2.;
776 parPWR[2] = kPWRhgt/2.;
777 gMC->Gsvolu("UTPW","BOX ",idtmed[1325-1],parPWR,kNparPWR);
779 for (iplan = 0; iplan < kNplan; iplan++) {
781 xpos = fCwidth[iplan]/2. + kPWRwid/2. + kPWRposx;
783 zpos = fgkVrocsm + kPWRhgt/2. - fgkSheight/2. + kPWRposz
784 + iplan * (fgkCH + fgkVspace);
785 gMC->Gspos("UTPW",iplan+1 ,"UTI1", xpos,ypos,zpos,matrix[0],"ONLY");
786 gMC->Gspos("UTPW",iplan+1+ kNplan,"UTI1",-xpos,ypos,zpos,matrix[1],"ONLY");
791 // The volumes for the services at the chambers
794 const Int_t kNparServ = 3;
795 Float_t parServ[kNparServ];
797 for (icham = 0; icham < kNcham; icham++) {
798 for (iplan = 0; iplan < kNplan; iplan++) {
800 Int_t iDet = GetDetectorSec(iplan,icham);
802 sprintf(cTagV,"UU%02d",iDet);
803 parServ[0] = fCwidth[iplan]/2.;
804 parServ[1] = fClength[iplan][icham]/2. - fgkHspace/2.;
805 parServ[2] = fgkVspace/2. - 0.742/2.; //!!!!!!!!!!!!!!
806 fChamberUUboxd[iDet][0] = parServ[0];
807 fChamberUUboxd[iDet][1] = parServ[1];
808 fChamberUUboxd[iDet][2] = parServ[2];
809 gMC->Gsvolu(cTagV,"BOX",idtmed[1302-1],parServ,kNparServ);
812 ypos = - fClength[iplan][0] - fClength[iplan][1] - fClength[iplan][2]/2.;
813 for (Int_t ic = 0; ic < icham; ic++) {
814 ypos += fClength[iplan][ic];
816 ypos += fClength[iplan][icham]/2.;
817 zpos = fgkVrocsm + fgkCH + fgkVspace/2. - fgkSheight/2.
818 + iplan * (fgkCH + fgkVspace);
820 fChamberUUorig[iDet][0] = xpos;
821 fChamberUUorig[iDet][1] = ypos;
822 fChamberUUorig[iDet][2] = zpos;
828 // The cooling pipes inside the service volumes
831 const Int_t kNparTube = 3;
832 Float_t parTube[kNparTube];
833 // The aluminum pipe for the cooling
837 gMC->Gsvolu("UTCP","TUBE",idtmed[1324-1],parTube,0);
842 gMC->Gsvolu("UTCH","TUBE",idtmed[1314-1],parTube,kNparTube);
843 // Water inside the cooling pipe
847 gMC->Gspos("UTCH",1,"UTCP",xpos,ypos,zpos,0,"ONLY");
849 // Position the cooling pipes in the mother volume
850 const Int_t kNpar = 3;
852 for (icham = 0; icham < kNcham; icham++) {
853 for (iplan = 0; iplan < kNplan; iplan++) {
854 Int_t iDet = GetDetectorSec(iplan,icham);
855 Int_t iCopy = GetDetector(iplan,icham,0) * 100;
856 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
857 Float_t ySize = (GetChamberLength(iplan,icham) - 2.*fgkRpadW)
858 / ((Float_t) nMCMrow);
859 sprintf(cTagV,"UU%02d",iDet);
860 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
862 ypos = (0.5 + iMCMrow) * ySize - 1.9
863 - fClength[iplan][icham]/2. + fgkHspace/2.;
864 zpos = 0.0 + 0.742/2.;
866 par[1] = 0.3/2.; // Thickness of the cooling pipes
867 par[2] = fCwidth[iplan]/2.;
868 gMC->Gsposp("UTCP",iCopy+iMCMrow,cTagV,xpos,ypos,zpos
869 ,matrix[2],"ONLY",par,kNpar);
878 // The copper power lines
882 gMC->Gsvolu("UTPL","TUBE",idtmed[1305-1],parTube,0);
884 // Position the power lines in the mother volume
885 for (icham = 0; icham < kNcham; icham++) {
886 for (iplan = 0; iplan < kNplan; iplan++) {
887 Int_t iDet = GetDetectorSec(iplan,icham);
888 Int_t iCopy = GetDetector(iplan,icham,0) * 100;
889 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
890 Float_t ySize = (GetChamberLength(iplan,icham) - 2.*fgkRpadW)
891 / ((Float_t) nMCMrow);
892 sprintf(cTagV,"UU%02d",iDet);
893 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
895 ypos = (0.5 + iMCMrow) * ySize - 1.0
896 - fClength[iplan][icham]/2. + fgkHspace/2.;
897 zpos = -0.4 + 0.742/2.;
899 par[1] = 0.2/2.; // Thickness of the power lines
900 par[2] = fCwidth[iplan]/2.;
901 gMC->Gsposp("UTPL",iCopy+iMCMrow,cTagV,xpos,ypos,zpos
902 ,matrix[2],"ONLY",par,kNpar);
911 // The mother volume for the MCMs (air)
912 const Int_t kNparMCM = 3;
913 Float_t parMCM[kNparMCM];
917 gMC->Gsvolu("UMCM","BOX",idtmed[1302-1],parMCM,kNparMCM);
919 // The MCM carrier G10 layer
923 gMC->Gsvolu("UMC1","BOX",idtmed[1319-1],parMCM,kNparMCM);
924 // The MCM carrier Cu layer
927 parMCM[2] = 0.0162/2.;
928 gMC->Gsvolu("UMC2","BOX",idtmed[1318-1],parMCM,kNparMCM);
929 // The silicon of the chips
932 parMCM[2] = 0.003/2.;
933 gMC->Gsvolu("UMC3","BOX",idtmed[1320-1],parMCM,kNparMCM);
935 // Put the MCM material inside the MCM mother volume
938 zpos = -0.07 + 0.1/2.;
939 gMC->Gspos("UMC1",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
940 zpos += 0.1/2. + 0.0162/2.;
941 gMC->Gspos("UMC2",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
942 zpos += 0.00162/2 + 0.003/2.;
943 gMC->Gspos("UMC3",1,"UMCM",xpos,ypos,zpos,0,"ONLY");
945 // Position the MCMs in the mother volume
946 for (icham = 0; icham < kNcham; icham++) {
947 for (iplan = 0; iplan < kNplan; iplan++) {
948 // Take out upper plane until TRD mothervolume is adjusted
949 //for (iplan = 0; iplan < kNplan-1; iplan++) {
950 Int_t iDet = GetDetectorSec(iplan,icham);
951 Int_t iCopy = GetDetector(iplan,icham,0) * 1000;
952 Int_t nMCMrow = commonParam->GetRowMax(iplan,icham,0);
953 Float_t ySize = (GetChamberLength(iplan,icham) - 2.*fgkRpadW)
954 / ((Float_t) nMCMrow);
956 Float_t xSize = (GetChamberWidth(iplan) - 2.* fgkCpadW)
957 / ((Float_t) nMCMcol);
958 sprintf(cTagV,"UU%02d",iDet);
959 for (Int_t iMCMrow = 0; iMCMrow < nMCMrow; iMCMrow++) {
960 for (Int_t iMCMcol = 0; iMCMcol < nMCMcol; iMCMcol++) {
961 xpos = (0.5 + iMCMcol) * xSize + 1.0
963 ypos = (0.5 + iMCMrow) * ySize + 1.0
964 - fClength[iplan][icham]/2. + fgkHspace/2.;
965 zpos = -0.4 + 0.742/2.;
967 par[1] = 0.2/2.; // Thickness of the power lines
968 par[2] = fCwidth[iplan]/2.;
969 gMC->Gspos("UMCM",iCopy+iMCMrow*10+iMCMcol,cTagV
970 ,xpos,ypos,zpos,0,"ONLY");
979 //_____________________________________________________________________________
980 void AliTRDgeometry::GroupChamber(Int_t iplan, Int_t icham, Int_t *idtmed)
983 // Group volumes UA, UD, UF, UU in a single chamber (Air)
984 // UA, UD, UF, UU are boxes
988 const Int_t kNparCha = 3;
990 Int_t iDet = GetDetectorSec(iplan,icham);
1000 for (Int_t i = 0; i < 3; i++) {
1001 xyzMin[i] = +9999; xyzMax[i] = -9999;
1004 for (Int_t i = 0; i < 3; i++) {
1006 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUAorig[iDet][i]-fChamberUAboxd[iDet][i]);
1007 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUAorig[iDet][i]+fChamberUAboxd[iDet][i]);
1009 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUDorig[iDet][i]-fChamberUDboxd[iDet][i]);
1010 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUDorig[iDet][i]+fChamberUDboxd[iDet][i]);
1012 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUForig[iDet][i]-fChamberUFboxd[iDet][i]);
1013 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUForig[iDet][i]+fChamberUFboxd[iDet][i]);
1015 xyzMin[i] = TMath::Min(xyzMin[i],fChamberUUorig[iDet][i]-fChamberUUboxd[iDet][i]);
1016 xyzMax[i] = TMath::Max(xyzMax[i],fChamberUUorig[iDet][i]+fChamberUUboxd[iDet][i]);
1018 xyzOrig[i] = 0.5*(xyzMax[i]+xyzMin[i]);
1019 xyzBoxd[i] = 0.5*(xyzMax[i]-xyzMin[i]);
1023 sprintf(cTagM,"UT%02d",iDet);
1025 gMC->Gsvolu(cTagM,"BOX ",idtmed[1302-1],xyzBoxd,kNparCha);
1027 sprintf(cTagV,"UA%02d",iDet);
1028 gMC->Gspos(cTagV,1,cTagM,
1029 fChamberUAorig[iDet][0]-xyzOrig[0],
1030 fChamberUAorig[iDet][1]-xyzOrig[1],
1031 fChamberUAorig[iDet][2]-xyzOrig[2],
1034 sprintf(cTagV,"UD%02d",iDet);
1035 gMC->Gspos(cTagV,1,cTagM,
1036 fChamberUDorig[iDet][0]-xyzOrig[0],
1037 fChamberUDorig[iDet][1]-xyzOrig[1],
1038 fChamberUDorig[iDet][2]-xyzOrig[2],
1041 sprintf(cTagV,"UF%02d",iDet);
1042 gMC->Gspos(cTagV,1,cTagM,
1043 fChamberUForig[iDet][0]-xyzOrig[0],
1044 fChamberUForig[iDet][1]-xyzOrig[1],
1045 fChamberUForig[iDet][2]-xyzOrig[2],
1048 sprintf(cTagV,"UU%02d",iDet);
1049 gMC->Gspos(cTagV,1,cTagM,
1050 fChamberUUorig[iDet][0]-xyzOrig[0],
1051 fChamberUUorig[iDet][1]-xyzOrig[1],
1052 fChamberUUorig[iDet][2]-xyzOrig[2],
1055 sprintf(cTagV,"UT%02d",iDet);
1056 gMC->Gspos(cTagV,1,"UTI1",xyzOrig[0],xyzOrig[1],xyzOrig[2],0,"ONLY");
1060 //_____________________________________________________________________________
1061 Bool_t AliTRDgeometry::Local2Global(Int_t idet, Double_t *local
1062 , Double_t *global) const
1065 // Converts local pad-coordinates (row,col,time) into
1066 // global ALICE reference frame coordinates (x,y,z)
1069 Int_t icham = GetChamber(idet); // Chamber info (0-4)
1070 Int_t isect = GetSector(idet); // Sector info (0-17)
1071 Int_t iplan = GetPlane(idet); // Plane info (0-5)
1073 return Local2Global(iplan,icham,isect,local,global);
1077 //_____________________________________________________________________________
1078 Bool_t AliTRDgeometry::Local2Global(Int_t iplan, Int_t icham, Int_t isect
1079 , Double_t *local, Double_t *global) const
1082 // Converts local pad-coordinates (row,col,time) into
1083 // global ALICE reference frame coordinates (x,y,z)
1086 AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
1090 AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
1094 AliTRDpadPlane *padPlane = commonParam->GetPadPlane(iplan,icham);
1096 // calculate (x,y,z) position in rotated chamber
1097 Int_t row = ((Int_t) local[0]);
1098 Int_t col = ((Int_t) local[1]);
1099 Float_t timeSlice = local[2] + 0.5;
1100 Float_t time0 = GetTime0(iplan);
1102 Int_t idet = GetDetector(iplan, icham, isect);
1105 rot[0] = time0 - (timeSlice - calibration->GetT0(idet, col, row))
1106 * calibration->GetVdrift(idet, col, row)/calibration->GetSamplingFrequency();
1107 rot[1] = padPlane->GetColPos(col) - 0.5 * padPlane->GetColSize(col);
1108 rot[2] = padPlane->GetRowPos(row) - 0.5 * padPlane->GetRowSize(row);
1110 // Rotate back to original position
1111 return RotateBack(idet,rot,global);
1115 //_____________________________________________________________________________
1116 Bool_t AliTRDgeometry::Global2Local(Int_t mode, Double_t *local, Double_t *global
1117 , Int_t* index) const
1120 // Converts local pad-coordinates (row,col,time) into
1121 // global ALICE reference frame coordinates (x,y,z)
1123 // index[0] = plane number
1124 // index[1] = chamber number
1125 // index[2] = sector number
1127 // mode=0 - local coordinate in y, z, x - rotated global
1128 // mode=2 - local coordinate in pad, and pad row, x - rotated global
1131 Int_t idet = GetDetector(index[0],index[1],index[2]); // Detector number
1132 RotateBack(idet,global,local);
1133 if (mode == 0) return kTRUE;
1139 //_____________________________________________________________________________
1140 Bool_t AliTRDgeometry::Global2Detector(Double_t global[3], Int_t index[3])
1143 // Find detector for given global point - Ideal geometry
1146 // input = global position
1148 // index[0] = plane number
1149 // index[1] = chamber number
1150 // index[2] = sector number
1156 Float_t fi = TMath::ATan2(global[1],global[0]);
1158 fi += 2*TMath::Pi();
1160 index[2] = fgkNsect - 1 - TMath::Nint((fi - GetAlpha()/2.)/GetAlpha());
1165 Float_t locx = global[0] * fRotA11[index[2]] + global[1] * fRotA12[index[2]];
1167 Float_t max = locx - GetTime0(0);
1168 for (Int_t iplane=1; iplane<fgkNplan;iplane++){
1169 Float_t dist = TMath::Abs(locx - GetTime0(iplane));
1179 if (TMath::Abs(global[2]) < 0.5*GetChamberLength(index[0],2)){
1183 Double_t localZ = global[2];
1185 localZ -= 0.5*(GetChamberLength(index[0],2)+GetChamberLength(index[0],1));
1186 index[1] = (TMath::Abs(localZ) < 0.5*GetChamberLength(index[0],3)) ? 1:0;
1189 localZ += 0.5*(GetChamberLength(index[0],2)+GetChamberLength(index[0],3));
1190 index[1] = (TMath::Abs(localZ) < 0.5*GetChamberLength(index[0],1)) ? 3:4;
1198 //_____________________________________________________________________________
1199 Bool_t AliTRDgeometry::Rotate(Int_t d, Double_t *pos, Double_t *rot) const
1202 // Rotates all chambers in the position of sector 0 and transforms
1203 // the coordinates in the ALICE restframe <pos> into the
1204 // corresponding local frame <rot>.
1207 Int_t sector = GetSector(d);
1209 rot[0] = pos[0] * fRotA11[sector] + pos[1] * fRotA12[sector];
1210 rot[1] = -pos[0] * fRotA21[sector] + pos[1] * fRotA22[sector];
1217 //_____________________________________________________________________________
1218 Bool_t AliTRDgeometry::RotateBack(Int_t d, Double_t *rot, Double_t *pos) const
1221 // Rotates a chambers from the position of sector 0 into its
1222 // original position and transforms the corresponding local frame
1223 // coordinates <rot> into the coordinates of the ALICE restframe <pos>.
1226 Int_t sector = GetSector(d);
1228 pos[0] = rot[0] * fRotB11[sector] + rot[1] * fRotB12[sector];
1229 pos[1] = -rot[0] * fRotB21[sector] + rot[1] * fRotB22[sector];
1236 //_____________________________________________________________________________
1237 Int_t AliTRDgeometry::GetDetectorSec(Int_t p, Int_t c)
1240 // Convert plane / chamber into detector number for one single sector
1243 return (p + c * fgkNplan);
1247 //_____________________________________________________________________________
1248 Int_t AliTRDgeometry::GetDetector(Int_t p, Int_t c, Int_t s)
1251 // Convert plane / chamber / sector into detector number
1254 return (p + c * fgkNplan + s * fgkNplan * fgkNcham);
1258 //_____________________________________________________________________________
1259 Int_t AliTRDgeometry::GetPlane(Int_t d) const
1262 // Reconstruct the plane number from the detector number
1265 return ((Int_t) (d % fgkNplan));
1269 //_____________________________________________________________________________
1270 Int_t AliTRDgeometry::GetChamber(Int_t d) const
1273 // Reconstruct the chamber number from the detector number
1276 return ((Int_t) (d % (fgkNplan * fgkNcham)) / fgkNplan);
1280 //_____________________________________________________________________________
1281 Int_t AliTRDgeometry::GetSector(Int_t d) const
1284 // Reconstruct the sector number from the detector number
1287 return ((Int_t) (d / (fgkNplan * fgkNcham)));
1291 //_____________________________________________________________________________
1292 AliTRDgeometry* AliTRDgeometry::GetGeometry(AliRunLoader* runLoader)
1295 // load the geometry from the galice file
1298 if (!runLoader) runLoader = AliRunLoader::GetRunLoader();
1300 ::Error("AliTRDgeometry::GetGeometry", "No run loader");
1304 TDirectory* saveDir = gDirectory;
1305 runLoader->CdGAFile();
1307 // Try from the galice.root file
1308 AliTRDgeometry* geom = (AliTRDgeometry*) gDirectory->Get("TRDgeometry");
1311 // It is not in the file, try to get it from gAlice,
1312 // which corresponds to the run loader
1313 AliTRD * trd = (AliTRD*)runLoader->GetAliRun()->GetDetector("TRD");
1314 geom = trd->GetGeometry();
1316 if (!geom) ::Error("AliTRDgeometry::GetGeometry", "Geometry not found");
1323 //_____________________________________________________________________________
1324 Bool_t AliTRDgeometry::ReadGeoMatrices()
1327 // Read geo matrices from current gGeoManager for each TRD sector
1330 if (!gGeoManager) return kFALSE;
1331 fMatrixArray = new TObjArray(kNdet);
1332 fMatrixCorrectionArray = new TObjArray(kNdet);
1333 fMatrixGeo = new TObjArray(kNdet);
1334 AliAlignObjAngles o;
1336 for (Int_t iLayer = AliAlignObj::kTRD1; iLayer <= AliAlignObj::kTRD6; iLayer++) {
1337 for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
1338 UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,iModule);
1339 const char *path = AliAlignObj::GetVolPath(volid);
1340 if (!gGeoManager->cd(path)) return kFALSE;
1341 TGeoHMatrix* m = gGeoManager->GetCurrentMatrix();
1342 Int_t iLayerTRD = iLayer-AliAlignObj::kTRD1;
1343 Int_t isector = Nsect()-1-(iModule/Ncham());
1344 Int_t ichamber = Ncham()-1-(iModule%Ncham());
1345 Int_t lid = GetDetector(iLayerTRD,ichamber,isector);
1348 // local geo system z-x-y to x-y--z
1350 fMatrixGeo->AddAt(new TGeoHMatrix(*m),lid);
1352 TGeoRotation mchange;
1353 mchange.RotateY(90); mchange.RotateX(90);
1355 TGeoHMatrix gMatrix(mchange.Inverse());
1356 gMatrix.MultiplyLeft(m);
1357 fMatrixArray->AddAt(new TGeoHMatrix(gMatrix),lid);
1360 // Cluster transformation matrix
1362 TGeoHMatrix rotMatrix(mchange.Inverse());
1363 rotMatrix.MultiplyLeft(m);
1364 Double_t sectorAngle = 20.*(isector%18)+10;
1365 TGeoHMatrix rotSector;
1366 rotSector.RotateZ(sectorAngle);
1367 rotMatrix.MultiplyLeft(&rotSector);
1369 fMatrixCorrectionArray->AddAt(new TGeoHMatrix(rotMatrix),lid);