]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - TPC/AliTPCParam.cxx
Added protection against zero calibration coefficients.
[u/mrichter/AliRoot.git] / TPC / AliTPCParam.cxx
... / ...
CommitLineData
1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16/* $Id$ */
17
18///////////////////////////////////////////////////////////////////////
19// Manager and of geomety classes for set: TPC //
20// //
21// !sectors are numbered from 0 //
22// !pad rows are numbered from 0 //
23//
24// 12.6. changed z relative
25// Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk //
26// //
27///////////////////////////////////////////////////////////////////////
28
29//
30
31#include <AliTPCParam.h>
32
33#include <TGeoManager.h>
34#include <TGeoPhysicalNode.h>
35#include "AliAlignObj.h"
36#include "AliAlignObjAngles.h"
37#include "AliLog.h"
38
39ClassImp(AliTPCParam)
40
41
42//___________________________________________
43AliTPCParam::AliTPCParam()
44 :AliDetectorParam(),
45 fbStatus(kFALSE),
46 fInnerRadiusLow(0.),
47 fInnerRadiusUp(0.),
48 fOuterRadiusUp(0.),
49 fOuterRadiusLow(0.),
50 fInnerAngle(0.),
51 fInnerAngleShift(0.),
52 fOuterAngle(0.),
53 fOuterAngleShift(0.),
54 fInnerFrameSpace(0.),
55 fOuterFrameSpace(0.),
56 fInnerWireMount(0.),
57 fOuterWireMount(0.),
58 fNInnerSector(0),
59 fNOuterSector(0),
60 fNSector(0),
61 fZLength(0),
62 fRotAngle(),
63 fGeometryType(0),
64 fTrackingMatrix(0),
65 fClusterMatrix(0),
66 fGlobalMatrix(0),
67 fNInnerWiresPerPad(0),
68 fInnerWWPitch(0),
69 fInnerDummyWire(0),
70 fInnerOffWire(0.),
71 fRInnerFirstWire(0.),
72 fRInnerLastWire(0.),
73 fLastWireUp1(0.),
74 fNOuter1WiresPerPad(0),
75 fNOuter2WiresPerPad(0),
76 fOuterWWPitch(0.),
77 fOuterDummyWire(0),
78 fOuterOffWire(0.),
79 fROuterFirstWire(0.),
80 fROuterLastWire(0.),
81 fInnerPadPitchLength(0.),
82 fInnerPadPitchWidth(0.),
83 fInnerPadLength(0.),
84 fInnerPadWidth(0.),
85 fOuter1PadPitchLength(0.),
86 fOuter2PadPitchLength(0.),
87 fOuterPadPitchWidth(0.),
88 fOuter1PadLength(0.),
89 fOuter2PadLength(0.),
90 fOuterPadWidth(0.),
91 fBMWPCReadout(kFALSE),
92 fNCrossRows(0),
93 fNRowLow(0),
94 fNRowUp1(0),
95 fNRowUp2(0),
96 fNRowUp(0),
97 fNtRows(0),
98 fDiffT(0.),
99 fDiffL(0.),
100 fGasGain(0.),
101 fDriftV(0.),
102 fOmegaTau(0.),
103 fAttCoef(0.),
104 fOxyCont(0.),
105 fPadCoupling(0.),
106 fZeroSup(0),
107 fNoise(0.),
108 fChipGain(0.),
109 fChipNorm(0.),
110 fTSample(0.),
111 fZWidth(0.),
112 fTSigma(0.),
113 fMaxTBin(0),
114 fADCSat(0),
115 fADCDynRange(0.),
116 fTotalNormFac(0.),
117 fNoiseNormFac(0.),
118 fNResponseMax(0),
119 fResponseThreshold(0.),
120 fCurrentMax(0),
121 fResponseBin(0),
122 fResponseWeight(0),
123 fGateDelay(0.),
124 fL1Delay(0.),
125 fNTBinsBeforeL1(0),
126 fNTBinsL1(0.)
127{
128 //
129 //constructor sets the default parameters
130 //
131
132 SetTitle("75x40_100x60_150x60");
133 SetDefault();
134}
135
136AliTPCParam::~AliTPCParam()
137{
138 //
139 //destructor deletes some dynamicaly alocated variables
140 //
141
142 if (fResponseBin!=0) delete [] fResponseBin;
143 if (fResponseWeight!=0) delete [] fResponseWeight;
144 if (fRotAngle !=0) delete [] fRotAngle;
145
146 if (fTrackingMatrix) {
147 for(Int_t i = 0; i < fNSector; i++)
148 delete fTrackingMatrix[i];
149 delete [] fTrackingMatrix;
150 }
151
152 if (fClusterMatrix) {
153 for(Int_t i = 0; i < fNSector; i++)
154 delete fClusterMatrix[i];
155 delete [] fClusterMatrix;
156 }
157
158 if (fGlobalMatrix) {
159 for(Int_t i = 0; i < fNSector; i++)
160 delete fGlobalMatrix[i];
161 delete [] fGlobalMatrix;
162 }
163
164}
165
166
167
168
169Int_t AliTPCParam::Transform0to1(Float_t *xyz, Int_t * index) const
170{
171 //
172 // calculates sector number (index[1], undefined on input)
173 // xyz intact
174 //
175
176 Float_t angle,x1;
177 Int_t sector;
178 Float_t r = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
179 if ((xyz[0]==0)&&(xyz[1]==0)) angle = 0.;
180 else
181 {
182 angle =TMath::ASin(xyz[1]/r);
183 if (xyz[0]<0) angle=TMath::Pi()-angle;
184 if ( (xyz[0]>0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle;
185 }
186
187 sector=Int_t(TMath::Nint((angle-fInnerAngleShift)/fInnerAngle));
188
189 Float_t cos,sin;
190 AdjustCosSin(sector,cos,sin);
191 x1=xyz[0]*cos + xyz[1]*sin;
192
193 if (x1>fOuterRadiusLow)
194 {
195 sector=Int_t(TMath::Nint((angle-fOuterAngleShift)/fOuterAngle))+fNInnerSector;
196 if (xyz[2]<0) sector+=(fNOuterSector>>1);
197 }
198 else
199 if (xyz[2]<0) sector+=(fNInnerSector>>1);
200 index[1]=sector; // calculated sector number
201 index[0]=1; // indicates system after transformation
202 return sector;
203}
204
205Bool_t AliTPCParam::Transform(Float_t */*xyz*/, Int_t *index, Int_t* /*oindex*/)
206{
207 //transformation from input coodination system to output coordination system
208 switch (index[0]){
209 case 0:
210 break;
211 };
212
213 return kFALSE;
214
215}
216
217Int_t AliTPCParam::GetPadRow(Float_t *xyz, Int_t *index) const
218{
219 //
220 //calculates pad row of point xyz - transformation to system 8 (digit system)
221 //
222 Int_t system = index[0];
223 if (0==system) {
224 Transform0to1(xyz,index);
225 system=1;
226 }
227 if (1==system) {
228 Transform1to2(xyz,index);
229 system=2;
230 }
231
232 if (fGeometryType==0){ //straight row
233 if (2==system) {
234 Transform2to3(xyz,index);
235 system=3;
236 }
237 if (3==system) {
238 Transform3to4(xyz,index);
239 system=4;
240 }
241 if (4==system) {
242 Transform4to8(xyz,index);
243 system=8;
244 }
245 if (8==system) {
246 index[0]=8;
247 return index[2];
248 }
249 }
250
251 if (fGeometryType==1){ //cylindrical geometry
252 if (2==system) {
253 Transform2to5(xyz,index);
254 system=5;
255 }
256 if (5==system) {
257 Transform2to3(xyz,index);
258 system=6;
259 }
260 if (6==system) {
261 Transform3to4(xyz,index);
262 system=7;
263 }
264 if (8==system) {
265 index[0]=8;
266 return index[2];
267 }
268 }
269 index[0]=system;
270 return -1; //if no reasonable system
271}
272
273void AliTPCParam::SetSectorAngles(Float_t innerangle, Float_t innershift, Float_t outerangle,
274 Float_t outershift)
275{
276 //
277 // set opening angles
278 static const Float_t kDegtoRad = 0.01745329251994;
279 fInnerAngle = innerangle; //opening angle of Inner sector
280 fInnerAngleShift = innershift; //shift of first inner sector center to the 0
281 fOuterAngle = outerangle; //opening angle of outer sector
282 fOuterAngleShift = outershift; //shift of first sector center to the 0
283 fInnerAngle *=kDegtoRad;
284 fInnerAngleShift *=kDegtoRad;
285 fOuterAngle *=kDegtoRad;
286 fOuterAngleShift *=kDegtoRad;
287}
288
289Float_t AliTPCParam::GetInnerAngle() const
290{
291 //return angle
292 return fInnerAngle;
293
294}
295
296Float_t AliTPCParam::GetInnerAngleShift() const
297{
298 //return angle
299 return fInnerAngleShift;
300}
301Float_t AliTPCParam::GetOuterAngle() const
302{
303 //return angle
304 return fOuterAngle;
305}
306Float_t AliTPCParam::GetOuterAngleShift() const
307{
308 //return angle
309
310 return fOuterAngleShift;
311}
312
313
314Int_t AliTPCParam::GetIndex(Int_t sector, Int_t row) const
315{
316 //
317 //give index of the given sector and pad row
318 //no control if the sectors and rows are reasonable !!!
319 //
320 if (sector<fNInnerSector) return sector*fNRowLow+row;
321 return (fNInnerSector*fNRowLow)+(sector-fNInnerSector)*fNRowUp+row;
322}
323
324Bool_t AliTPCParam::AdjustSectorRow(Int_t index, Int_t & sector, Int_t &row) const
325{
326 //
327 //return sector and padrow for given index
328 //if index is reasonable returns true else return false
329 //
330 if ( (index<0) || (index>fNtRows)) return kFALSE;
331 Int_t outindex = fNInnerSector*fNRowLow;
332 if (index<outindex) {
333 sector = index/fNRowLow;
334 row = index - sector*fNRowLow;
335 return kTRUE;
336 }
337 index-= outindex;
338 sector = index/fNRowUp;
339 row = index - sector*fNRowUp;
340 sector += fNInnerSector;
341 return kTRUE;
342}
343
344void AliTPCParam::SetDefault()
345{
346 //
347 //set default parameters
348 //
349 //const static Int_t kMaxRows=600;
350 //
351 //sector default parameters
352 //
353 static const Float_t kInnerRadiusLow = 83.65;
354 static const Float_t kInnerRadiusUp = 133.3;
355 static const Float_t kOuterRadiusLow = 133.5;
356 static const Float_t kOuterRadiusUp = 247.7;
357 static const Float_t kInnerAngle = 20; // 20 degrees
358 static const Float_t kInnerAngleShift = 10;
359 static const Float_t kOuterAngle = 20; // 20 degrees
360 static const Float_t kOuterAngleShift = 10;
361 static const Float_t kInnerFrameSpace = 1.5;
362 static const Float_t kOuterFrameSpace = 1.5;
363 static const Float_t kInnerWireMount = 1.2;
364 static const Float_t kOuterWireMount = 1.4;
365 static const Float_t kZLength =250.;
366 static const Int_t kGeometryType = 0; //straight rows
367 static const Int_t kNRowLow = 63;
368 static const Int_t kNRowUp1 = 64;
369 static const Int_t kNRowUp2 = 32;
370 static const Int_t kNRowUp = 96;
371 //
372 //wires default parameters
373 //
374 static const Int_t kNInnerWiresPerPad = 3;
375 static const Int_t kInnerDummyWire = 2;
376 static const Float_t kInnerWWPitch = 0.25;
377 static const Float_t kRInnerFirstWire = 84.475;
378 static const Float_t kRInnerLastWire = 132.475;
379 static const Float_t kInnerOffWire = 0.5;
380 static const Int_t kNOuter1WiresPerPad = 4;
381 static const Int_t kNOuter2WiresPerPad = 6;
382 static const Float_t kOuterWWPitch = 0.25;
383 static const Float_t kROuterFirstWire = 134.225;
384 static const Float_t kROuterLastWire = 246.975;
385 static const Int_t kOuterDummyWire = 2;
386 static const Float_t kOuterOffWire = 0.5;
387 //
388 //pad default parameters
389 //
390 static const Float_t kInnerPadPitchLength = 0.75;
391 static const Float_t kInnerPadPitchWidth = 0.40;
392 static const Float_t kInnerPadLength = 0.75;
393 static const Float_t kInnerPadWidth = 0.40;
394 static const Float_t kOuter1PadPitchLength = 1.0;
395 static const Float_t kOuterPadPitchWidth = 0.6;
396 static const Float_t kOuter1PadLength = 1.0;
397 static const Float_t kOuterPadWidth = 0.6;
398 static const Float_t kOuter2PadPitchLength = 1.5;
399 static const Float_t kOuter2PadLength = 1.5;
400
401 static const Bool_t kBMWPCReadout = kTRUE; //MWPC readout - another possibility GEM
402 static const Int_t kNCrossRows = 1; //number of rows to cross-talk
403
404 //
405 //gas default parameters
406 //
407 static const Float_t kDiffT = 2.2e-2;
408 static const Float_t kDiffL = 2.2e-2;
409 static const Float_t kGasGain = 2.e4;
410 static const Float_t kDriftV =2.83e6;
411 static const Float_t kOmegaTau = 0.145;
412 static const Float_t kAttCoef = 250.;
413 static const Float_t kOxyCont = 5.e-6;
414 //
415 //electronic default parameters
416 //
417 static const Float_t kPadCoupling=0.5;
418 static const Int_t kZeroSup=2;
419 static const Float_t kNoise = 1000;
420 static const Float_t kChipGain = 12;
421 static const Float_t kChipNorm = 0.4;
422 static const Float_t kTSample = 2.e-7;
423 static const Float_t kTFWHM = 1.9e-7; //fwhm of charge distribution
424 static const Int_t kMaxTBin =445;
425 static const Int_t kADCSat =1024;
426 static const Float_t kADCDynRange =2000.;
427 //
428 //response constants
429 //
430 static const Int_t kNResponseMax=100;
431 static const Float_t kResponseThreshold=0.01;
432 //L1 constants
433 // static const Float_t kGateDelay=6.1e-6; //In s
434 static const Float_t kGateDelay=0.; //For the moment no gating
435 // static const Float_t kL1Delay=6.5e-6; //In s
436 static const Float_t kL1Delay=0.; //For the moment no delay
437 // static const UShort_t kNTBinsBeforeL1=14;
438 static const UShort_t kNTBinsBeforeL1=0; //For the moment no shift
439 fbStatus = kFALSE;
440 //
441 //set sector parameters
442 //
443 SetInnerRadiusLow(kInnerRadiusLow);
444 SetOuterRadiusLow(kOuterRadiusLow);
445 SetInnerRadiusUp(kInnerRadiusUp);
446 SetOuterRadiusUp(kOuterRadiusUp);
447 SetInnerFrameSpace(kInnerFrameSpace);
448 SetOuterFrameSpace(kOuterFrameSpace);
449 SetInnerWireMount(kInnerWireMount);
450 SetOuterWireMount(kOuterWireMount);
451 SetSectorAngles(kInnerAngle,kInnerAngleShift,kOuterAngle,kOuterAngleShift);
452 SetZLength(kZLength);
453 SetGeometryType(kGeometryType);
454 SetRowNLow(kNRowLow);
455 SetRowNUp1 (kNRowUp1);
456 SetRowNUp2(kNRowUp2);
457 SetRowNUp(kNRowUp);
458 //
459 //set wire parameters
460 //
461 SetInnerNWires(kNInnerWiresPerPad);
462 SetInnerDummyWire(kInnerDummyWire);
463 SetInnerOffWire(kInnerOffWire);
464 SetOuter1NWires(kNOuter1WiresPerPad);
465 SetOuter2NWire(kNOuter2WiresPerPad);
466 SetOuterDummyWire(kOuterDummyWire);
467 SetOuterOffWire(kOuterOffWire);
468 SetInnerWWPitch(kInnerWWPitch);
469 SetRInnerFirstWire(kRInnerFirstWire);
470 SetRInnerLastWire(kRInnerLastWire);
471 SetOuterWWPitch(kOuterWWPitch);
472 SetROuterFirstWire(kROuterFirstWire);
473 SetROuterLastWire(kROuterLastWire);
474 //
475 //set pad parameter
476 //
477 SetInnerPadPitchLength(kInnerPadPitchLength);
478 SetInnerPadPitchWidth(kInnerPadPitchWidth);
479 SetInnerPadLength(kInnerPadLength);
480 SetInnerPadWidth(kInnerPadWidth);
481 SetOuter1PadPitchLength(kOuter1PadPitchLength);
482 SetOuter2PadPitchLength(kOuter2PadPitchLength);
483 SetOuterPadPitchWidth(kOuterPadPitchWidth);
484 SetOuter1PadLength(kOuter1PadLength);
485 SetOuter2PadLength(kOuter2PadLength);
486 SetOuterPadWidth(kOuterPadWidth);
487 SetMWPCReadout(kBMWPCReadout);
488 SetNCrossRows(kNCrossRows);
489 //
490 //set gas paremeters
491 //
492 SetDiffT(kDiffT);
493 SetDiffL(kDiffL);
494 SetGasGain(kGasGain);
495 SetDriftV(kDriftV);
496 SetOmegaTau(kOmegaTau);
497 SetAttCoef(kAttCoef);
498 SetOxyCont(kOxyCont);
499 //
500 //set electronivc parameters
501 //
502 SetPadCoupling(kPadCoupling);
503 SetZeroSup(kZeroSup);
504 SetNoise(kNoise);
505 SetChipGain(kChipGain);
506 SetChipNorm(kChipNorm);
507 SetTSample(kTSample);
508 SetTFWHM(kTFWHM);
509 SetMaxTBin(kMaxTBin);
510 SetADCSat(kADCSat);
511 SetADCDynRange(kADCDynRange);
512// //set magnetic field
513// SetBField(kBField);
514// SetNPrimLoss(kNPrimLoss);
515// SetNTotalLoss(kNTotalLoss);
516 //
517 //set response parameters
518 //
519 SetNResponseMax(kNResponseMax);
520 SetResponseThreshold(static_cast<int>(kResponseThreshold));
521 //L1 data
522 SetGateDelay(kGateDelay);
523 SetL1Delay(kL1Delay);
524 SetNTBinsBeforeL1(kNTBinsBeforeL1);
525}
526
527
528Bool_t AliTPCParam::Update()
529{
530 //
531 // update some calculated parameter which must be updated after changing "base"
532 // parameters
533 // for example we can change size of pads and according this recalculate number
534 // of pad rows, number of of pads in given row ....
535 //
536 const Float_t kQel = 1.602e-19; // elementary charge
537 fbStatus = kFALSE;
538
539 Int_t i,j; //loop variables because HP
540 //-----------------Sector section------------------------------------------
541 //calclulate number of sectors
542 fNInnerSector = Int_t(4*TMath::Pi()/fInnerAngle+0.2);
543 // number of inner sectors - factor 0.2 to don't be influnced by inprecision
544 if (fNInnerSector%2) return kFALSE;
545 fNOuterSector = Int_t(4*TMath::Pi()/fOuterAngle+0.2);
546 if (fNOuterSector%2) return kFALSE;
547 fNSector = fNInnerSector+fNOuterSector;
548
549 if (fRotAngle!=0) delete [] fRotAngle;
550 fRotAngle = new Float_t[4*fNSector];
551 //calculate sin and cosine of rotations angle
552 //sectors angles numbering from 0
553
554 j=fNInnerSector*2;
555 Float_t angle = fInnerAngleShift;
556 for (i=0; j<fNInnerSector*4; i+=4, j+=4 , angle +=fInnerAngle){
557 fRotAngle[i]=TMath::Cos(angle);
558 fRotAngle[i+1]=TMath::Sin(angle);
559 fRotAngle[j] = fRotAngle[i];
560 fRotAngle[j+1] = fRotAngle[i+1];
561 fRotAngle[i+2] =angle;
562 fRotAngle[j+2] =angle;
563 }
564 angle = fOuterAngleShift;
565 j=(fNInnerSector+fNOuterSector/2)*4;
566 for (i=fNInnerSector*4; j<fNSector*4; i+=4,j+=4, angle +=fOuterAngle){
567 fRotAngle[i]=TMath::Cos(angle);
568 fRotAngle[i+1]=TMath::Sin(angle);
569 fRotAngle[j] = fRotAngle[i];
570 fRotAngle[j+1] = fRotAngle[i+1];
571 fRotAngle[i+2] =angle;
572 fRotAngle[j+2] =angle;
573 }
574
575 fZWidth = fTSample*fDriftV;
576 fTotalNormFac = fPadCoupling*fChipNorm*kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
577 fNoiseNormFac = kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
578 //wire section
579 /* Int_t nwire;
580 Float_t wspace; //available space for wire
581 Float_t dummyspace; //dummyspace for wire
582
583 wspace =fInnerRadiusUp-fInnerRadiusLow-2*fInnerOffWire;
584 nwire = Int_t(wspace/fInnerWWPitch);
585 wspace = Float_t(nwire)*fInnerWWPitch;
586 dummyspace =(fInnerRadiusUp-fInnerRadiusLow-wspace)/2.;
587 wspace =fOuterRadiusUp-fOuterRadiusLow-2*fOuterOffWire;
588 nwire = Int_t(wspace/fOuterWWPitch);
589 wspace = Float_t(nwire)*fOuterWWPitch;
590 dummyspace =(fOuterRadiusUp-fOuterRadiusLow-wspace)/2.;
591 fROuterFirstWire = fOuterRadiusLow+dummyspace;
592 fROuterLastWire = fROuterFirstWire+fOuterWWPitch*(Float_t)(nwire);
593 */
594
595 //
596 //response data
597 //
598 if (fResponseBin==0) delete [] fResponseBin;
599 if (fResponseWeight==0) delete [] fResponseBin;
600 fResponseBin = new Int_t[3*fNResponseMax];
601 fResponseWeight = new Float_t[fNResponseMax];
602
603 //L1 data
604 fNTBinsL1 = fL1Delay/fTSample - (Float_t)fNTBinsBeforeL1;
605 fbStatus = kTRUE;
606 return kTRUE;
607}
608
609
610
611Bool_t AliTPCParam::ReadGeoMatrices(){
612 //
613 // read geo matrixes
614 //
615 if (!gGeoManager){
616 AliFatal("Geo manager not initialized\n");
617 }
618 AliAlignObjAngles o;
619 //
620 if (fTrackingMatrix) delete [] fTrackingMatrix;
621 fTrackingMatrix = new TGeoHMatrix*[fNSector];
622 if (fClusterMatrix) delete [] fClusterMatrix;
623 fClusterMatrix = new TGeoHMatrix*[fNSector];
624 if (fGlobalMatrix) delete [] fGlobalMatrix;
625 fGlobalMatrix = new TGeoHMatrix*[fNSector];
626 //
627 for (Int_t isec=0; isec<fNSector; isec++) {
628 fGlobalMatrix[isec] = 0;
629 fClusterMatrix[isec]= 0;
630 fTrackingMatrix[isec]=0;
631 AliAlignObj::ELayerID iLayer;
632 Int_t iModule;
633
634 if(isec<fNInnerSector) {
635 iLayer = AliAlignObj::kTPC1;
636 iModule = isec;
637 }
638 else {
639 iLayer = AliAlignObj::kTPC2;
640 iModule = isec - fNInnerSector;
641 }
642
643 UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,iModule);
644 const char *symname = AliAlignObj::SymName(volid);
645 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
646 const char *path = symname;
647 if(pne) path=pne->GetTitle();
648 if (!gGeoManager->cd(path)) return kFALSE;
649 TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
650
651 //
652 TGeoRotation mchange;
653 mchange.RotateY(90); mchange.RotateX(90);
654 Float_t ROCcenter[3];
655 GetChamberCenter(isec,ROCcenter);
656 //
657 // Convert to global coordinate system
658 //
659 fGlobalMatrix[isec] = new TGeoHMatrix(*m);
660 fGlobalMatrix[isec]->Multiply(&(mchange.Inverse()));
661 TGeoTranslation center("center",-ROCcenter[0],-ROCcenter[1],-ROCcenter[2]);
662 fGlobalMatrix[isec]->Multiply(&center);
663 //
664 // cluster correction matrix
665 //
666 fClusterMatrix[isec] = new TGeoHMatrix;
667 Double_t sectorAngle = 20.*(isec%18)+10;
668 TGeoHMatrix rotMatrix;
669 rotMatrix.RotateZ(sectorAngle);
670 if (GetGlobalMatrix(isec)->GetTranslation()[2]>0){
671 //
672 // mirrored system
673 //
674 TGeoRotation mirrorZ;
675 mirrorZ.SetAngles(90,0,90,90,180,0);
676 fClusterMatrix[isec]->Multiply(&mirrorZ);
677 }
678 TGeoTranslation trans(0,0,GetZLength());
679 fClusterMatrix[isec]->MultiplyLeft(&trans);
680 fClusterMatrix[isec]->MultiplyLeft((GetGlobalMatrix(isec)));
681 fClusterMatrix[isec]->MultiplyLeft(&(rotMatrix.Inverse()));
682 }
683 return kTRUE;
684}
685
686
687Bool_t AliTPCParam::GetStatus() const
688{
689 //get information about object consistency
690 return fbStatus;
691}
692
693Int_t AliTPCParam::GetNRowLow() const
694{
695 //get the number of pad rows in low sector
696 return fNRowLow;
697}
698Int_t AliTPCParam::GetNRowUp() const
699{
700 //get the number of pad rows in up sector
701 return fNRowUp;
702}
703Int_t AliTPCParam::GetNRowUp1() const
704{
705 //get the number of pad rows in up1 sector
706 return fNRowUp1;
707}
708Int_t AliTPCParam::GetNRowUp2() const
709{
710 //get the number of pad rows in up2 sector
711 return fNRowUp2;
712}
713Float_t AliTPCParam::GetPadRowRadiiLow(Int_t irow) const
714{
715 //get the pad row (irow) radii
716 if ( !(irow<0) && (irow<fNRowLow) )
717 return fPadRowLow[irow];
718 else
719 return 0;
720}
721
722Float_t AliTPCParam::GetPadRowRadiiUp(Int_t irow) const
723{
724 //get the pad row (irow) radii
725 if ( !(irow<0) && (irow<fNRowUp) )
726 return fPadRowUp[irow];
727 else
728 return 0;
729}
730
731Int_t AliTPCParam::GetNPadsLow(Int_t irow) const
732{
733 //get the number of pads in row irow
734 if ( !(irow<0) && (irow<fNRowLow) )
735 return fNPadsLow[irow];
736 else
737 return 0;
738}
739
740
741Int_t AliTPCParam::GetNPadsUp(Int_t irow) const
742{
743 //get the number of pads in row irow
744 if ( !(irow<0) && (irow<fNRowUp) )
745 return fNPadsUp[irow];
746 else
747 return 0;
748}
749Float_t AliTPCParam::GetYInner(Int_t irow) const
750{
751 return fYInner[irow];
752}
753
754
755Float_t AliTPCParam::GetYOuter(Int_t irow) const
756{
757 return fYOuter[irow];
758}
759
760Int_t AliTPCParam::GetSectorIndex(Float_t angle, Int_t row, Float_t z) const
761{
762 // returns the sector index
763 // takes as input the angle, index of the pad row and z position
764 if(row<0) return -1;
765
766 if (angle > 2.*TMath::Pi()) angle -= 2.*TMath::Pi();
767 if (angle < 0. ) angle += 2.*TMath::Pi();
768
769 Int_t sector;
770 if(row<fNRowLow) {
771 sector=Int_t(TMath::Nint((angle-fInnerAngleShift)/fInnerAngle));
772 if (z<0) sector += (fNInnerSector>>1);
773 }
774 else {
775 sector=Int_t(TMath::Nint((angle-fOuterAngleShift)/fOuterAngle))+fNInnerSector;
776 if (z<0) sector += (fNOuterSector>>1);
777 }
778
779 return sector;
780}
781
782Float_t AliTPCParam::GetChamberCenter(Int_t isec, Float_t * center) const
783{
784 // returns the default radial position
785 // of the readout chambers
786
787 const Float_t kROCcenterIn = 110.2;
788 const Float_t kROCcenterOut = 188.45;
789
790 if (isec<fNInnerSector){
791 if (center){
792 center[0] = kROCcenterIn;
793 center[1] = 0;
794 center[2] = -5.51;
795 }
796 return kROCcenterIn;
797 }
798 else{
799 if (center){
800 center[0] = kROCcenterOut;
801 center[1] = 0;
802 center[2] = -5.61;
803 }
804 return kROCcenterOut;
805 }
806}
807
808
809