]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/AliTPCParam.cxx
New version from M.Kowalski
[u/mrichter/AliRoot.git] / TPC / AliTPCParam.cxx
CommitLineData
8c555625 1///////////////////////////////////////////////////////////////////////
2// Manager and of geomety classes for set: TPC //
3// //
1283eee5 4// !sectors are numbered from 0 //
5// !pad rows are numbered from 0 //
6//
7// 12.6. changed z relative
8c555625 8// Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk //
9// //
10///////////////////////////////////////////////////////////////////////
11
8c555625 12
13#include <iostream.h>
14#include <TMath.h>
1283eee5 15#include <TObject.h>
8c555625 16#include "AliTPCSecGeo.h"
1283eee5 17#include <AliTPCParam.h>
8c555625 18
19
20ClassImp(AliTPCParam)
21
1283eee5 22const static Int_t kMaxRows=600;
23
24
8c555625 25// default values
1283eee5 26const static Int_t kMaxTBin =512;
8c555625 27
8c555625 28
1283eee5 29const static Float_t kInnerRadiusLow = 89.45;
30const static Float_t kOuterRadiusLow = 143.725;
31const static Float_t kInnerRadiusUp = 134.55;
32const static Float_t kOuterRadiusUp = 248.275;
8c555625 33
1283eee5 34const static Float_t kInnerAngle = 0.523598775; // 30 degrees
35const static Float_t kInnerAngleShift = 0;
36const static Float_t kOuterAngle = 0.261799387; // 15 degrees
37const static Float_t kOuterAngleShift = 0;
8c555625 38
1283eee5 39const static Float_t kPadPitchLength = 2.05;
40const static Float_t kPadPitchWidth = 0.35;
41const static Float_t kPadLength = 2.05;
42const static Float_t kPadWidth = 0.35;
43
44// Number of wires per pad and wire-wire pitch
45const static Int_t knWires = 5;
46const static Float_t kDiffT = 2.2e-2;
47const static Float_t kDiffL = 2.2e-2;
48const static Float_t kDriftV =2.85e6;
8c555625 49
1283eee5 50const static Float_t kOmegaTau = 0.145;
51const static Float_t kAttCoef = 250.;
52const static Float_t kOxyCont = 5.e-6;
8c555625 53
1283eee5 54
55const static Float_t kChipGain = 24;
56const static Float_t kGasGain = 1e4;
57const static Float_t kTSample = 2.e-7; //TSAMPLE
58const static Float_t kTFWHM = 2.5e-7; //fwhm of charge distribution
8c555625 59
1283eee5 60const static Float_t kNoise = 500; //default noise = 1000 el
61const static Int_t kZeroSup=5;
62const static Float_t kPadCoupling=0.5;
8c555625 63//
1283eee5 64const static Float_t kEdgeSectorSpace = 1.15;
65const static Float_t kDegtoRad = 0.01745329251994;
66const static Float_t kRadtoDeg = 57.29577951309;
8c555625 67
68
69
70
71//___________________________________________
72AliTPCParam::AliTPCParam()
73{
74 //constructor set the default parameters
75 SetDefault();
76}
77
78
1283eee5 79void AliTPCParam::SetSectorAngles(Float_t innerangle, Float_t innershift, Float_t outerangle,
80 Float_t outershift, Bool_t inDegree)
81{
82 //
83 // set opening angles
84 fInnerAngle = innerangle; //opening angle of Inner sector
85 fInnerAngleShift = innershift; //shift of first inner sector center to the 0
86 fOuterAngle = outerangle; //opening angle of outer sector
87 fOuterAngleShift = outershift; //shift of first sector center to the 0
88 if (inDegree==kTRUE){
89 fInnerAngle *=kDegtoRad;
90 fInnerAngleShift *=kDegtoRad;
91 fOuterAngle *=kDegtoRad;
92 fOuterAngleShift *=kDegtoRad;
93 }
94}
95
96
8c555625 97void AliTPCParam::CRXYZtoXYZ(Float_t *xyz,
98 const Int_t &sector, const Int_t & padrow, Int_t option) const
99{
100 //transform relative coordinates to absolute
101 Bool_t rel = ( (option&2)!=0);
102 Float_t row_first;
1283eee5 103 row_first = (sector<=fNInnerSector) ? fPadRowLow[0] : fPadRowUp[0];
104 if (rel==kTRUE) //if the position is relative to pad row
8c555625 105 {
106 xyz[0]+=row_first;
107 xyz[0]+=(Int_t) padrow*fPadPitchLength;
108 }
1283eee5 109
110 xyz[2]=z_end-xyz[2];
3c0f9266 111 if (sector<fNInnerSector) {
1283eee5 112 if ( sector>=(fNInnerSector>>1)) xyz[2]*=-1.;
3c0f9266 113 } else {
114 if ( (sector-fNInnerSector) >= (fNOuterSector>>1) ) xyz[2]*=-1;
115 }
116
8c555625 117 Float_t x1=xyz[0];
118 Float_t y1=xyz[1];
119 Float_t cos,sin;
120 AdjustAngles(sector,cos,sin);
1283eee5 121 xyz[0]= x1*cos - y1*sin;
122 xyz[1]= x1*sin + y1*cos;
8c555625 123}
124
125void AliTPCParam::XYZtoCRXYZ(Float_t *xyz,
126 Int_t &sector, Int_t & padrow, Int_t option)
127{
128 //transform global position to the position relative to the sector padrow
129 //if option=0 X calculate absolute calculate sector
130 //if option=1 X absolute use input sector
131 //if option=2 X relative to pad row calculate sector
132 //if option=3 X relative use input sector
133 //!!!!!!!!! WE start to calculate rows from row = 0
134
135 Bool_t rel = ( (option&2)!=0);
136 //option 0 and 2 means that we don't have information about sector
137 //we calculate sector
138 if ((option&1)==0){
139 Float_t angle;
140 Float_t r = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
141 if ((xyz[0]==0)&&(xyz[1]==0)) angle = 0;
142 else
143 {
144 angle =TMath::ASin(xyz[1]/r);
145 if (xyz[0]<0) angle=TMath::Pi()-angle;
146 if ( (xyz[0]>0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle;
147 }
1283eee5 148 //transform global position to the position relative to the sector padrow
149 //fistly calculate xyz[0] radius for lover sector
150 //bacause in this moment we dont know in which sector we are
151 sector=Int_t((angle-fInnerAngleShift)/fInnerAngle);
8c555625 152 Float_t x1;
153 Float_t y1;
154 //firstly we suppose that we are in inner sector
155 Float_t cos,sin;
156 AdjustAngles(sector,cos,sin);
157
158 x1=xyz[0]*cos + xyz[1]*sin;
159 y1=-xyz[0]*sin + xyz[1]*cos;
160 if (x1>fOuterRadiusLow)
161 {
1283eee5 162 sector=Int_t((angle-fOuterAngleShift)/fOuterAngle)+fNInnerSector;
8c555625 163 AdjustAngles(sector,cos,sin);
164 x1=xyz[0]*cos + xyz[1]*sin;
165 y1=-xyz[0]*sin + xyz[1]*cos;
1283eee5 166 if (xyz[2]<0) sector+=(fNOuterSector>>1);
8c555625 167 }
168 else
1283eee5 169 if (xyz[2]<0) sector+=(fNInnerSector>>1);
170
8c555625 171 if (x1<fOuterRadiusLow)
172 padrow =Int_t( (x1-fPadRowLow[0])/fPadPitchLength+0.5);
173 else
174 padrow = Int_t( (x1-fPadRowUp[0])/fPadPitchLength+0.5);
175 if (rel==kTRUE)
176 if (x1<fOuterRadiusLow) x1-=padrow*fPadPitchLength+fPadRowLow[0];
177 else
178 x1-=padrow*fPadPitchLength+fPadRowUp[0];
179 xyz[0]=x1;
180 xyz[1]=y1;
1283eee5 181 xyz[2]=z_end-TMath::Abs(xyz[2]);
182 } //endif we don't have information about sector
8c555625 183 else{
184 //if we have information about sector
185 Float_t cos,sin;
186 AdjustAngles(sector,cos,sin);
187 Float_t x1;
188 Float_t y1;
189 //rotate to given sector
190 x1=xyz[0]*cos + xyz[1]*sin;
191 y1=-xyz[0]*sin + xyz[1]*cos;
192 //calculate pad row number
1283eee5 193 if (sector<fNInnerSector) {
8c555625 194 padrow =Int_t( (x1-fPadRowLow[0])/fPadPitchLength+1.5)-1;
8c555625 195 }
196 else {
197 padrow =Int_t( (x1-fPadRowUp[0])/fPadPitchLength+1.5)-1;
8c555625 198 }
199 //if we store relative position calculate position relative to pad row
200 if (rel==kTRUE){
1283eee5 201 if (sector<fNInnerSector)
8c555625 202 x1-=padrow*fPadPitchLength+fPadRowLow[0];
203 else
204 x1-=padrow*fPadPitchLength+fPadRowUp[0];
205 }
206 xyz[0]=x1;
207 xyz[1]=y1;
1283eee5 208 xyz[2]=z_end-TMath::Abs(xyz[2]);
8c555625 209 }
210}
211
212void AliTPCParam::CRYZtoTimePad(const Float_t &y, const Float_t &z,
213 Float_t &time, Float_t &pad,
214 Int_t sector, Int_t padrow)
215{
216 //transform position in cm to position in time slices and pads
1283eee5 217 Float_t nofpads = GetNPads(sector,padrow);
8c555625 218 Float_t padc=(nofpads+1)/2; // this is the "central" pad for a row
219 pad = y/(fPadPitchWidth)+padc;
1283eee5 220 time=z/fZWidth;
8c555625 221}
222void AliTPCParam::CRTimePadtoYZ(Float_t &y, Float_t &z,
223 const Float_t &time, const Float_t &pad,
224 Int_t sector, Int_t padrow)
225{
226 //transform position in time slices and pads to cm
1283eee5 227 Float_t nofpads = GetNPads(sector,padrow);
8c555625 228 Float_t padc=(nofpads+1)/2; // this is the "central" pad for a row
229 y=(pad-padc)*fPadPitchWidth;
1283eee5 230 z=time*fZWidth;
8c555625 231}
232
233Int_t AliTPCParam::GetWire(Float_t & x)
234{
235 //
236 //return wire number of pad for electron at relative position x
237 //to the center of the pad
238 //and adjust x to the wire position
239 //we suppose that if the wire number is even the center wire
240 //is at center of pad
241 //
242 Float_t xrel= x/fWWPitch;
243 if ((fnWires>>1)==0) xrel+=1;
244 else xrel+=0.5;
245 Int_t nw=Int_t(xrel);
246 if (xrel<0) nw-=1;
247
248 x=(nw*fWWPitch);
249 if ((fnWires>>1)==0) x-=fWWPitch/2.;
250 return nw;
251}
252
253Int_t AliTPCParam::GetIndex(Int_t sector, Int_t row)
254{
255 //
256 //give index of the given sector and pad row
257 //no control if the sectors and rows are reasonable !!!
258 //
1283eee5 259 if (sector<fNInnerSector) return sector*fnRowLow+row;
260 return (fNInnerSector*fnRowLow)+(sector-fNInnerSector)*fnRowUp+row;
8c555625 261}
262
263Bool_t AliTPCParam::AdjustSectorRow(Int_t index, Int_t & sector, Int_t &row)
264{
265 //
266 //return sector and padrow for given index
267 //if index is reasonable return true else return false
268 //
269 if ( (index<0) || (index>fNtRows)) return kFALSE;
1283eee5 270 Int_t outindex = fNInnerSector*fnRowLow;
8c555625 271 if (index<outindex) {
272 sector = index/fnRowLow;
273 row = index - sector*fnRowLow;
8c555625 274 return kTRUE;
275 }
276 index-= outindex;
277 sector = index/fnRowUp;
278 row = index - sector*fnRowUp;
8c555625 279 return kTRUE;
280}
281
282
283
284Int_t AliTPCParam::GetPadRow(Int_t isec, Float_t &x)
285{
286 //
287 //return the pad row for given x (transformed)
288 //
289 Float_t row_first=GetPadRowRadii(isec,0);
290 Int_t row = Int_t(( x-row_first+1.5*fPadPitchLength)/fPadPitchLength)-1;
291 //Int_t will make from -0.5 0 but we want to make -1 so we add and after substract 1
292 x -=row* fPadPitchLength+row_first;
293 if ( (row<0)||(row>=GetNRow(isec))) return -1;
294 else return row;
295}
296
297void AliTPCParam::SetDefault()
298{
299 //set default TPC param
300 fbStatus = kFALSE;
1283eee5 301 //set sector parameters
8c555625 302 fInnerRadiusLow = kInnerRadiusLow;
303 fOuterRadiusLow = kOuterRadiusLow;
304 fInnerRadiusUp = kInnerRadiusUp;
1283eee5 305 fOuterRadiusUp = kOuterRadiusUp;
306 SetSectorAngles(kInnerAngle,kInnerAngleShift, kOuterAngle, kOuterAngleShift);
8c555625 307 // set default pad size and shape
308 fPadPitchLength = kPadPitchLength;
309 fPadPitchWidth = kPadPitchWidth;
310 fPadLength = kPadLength;
311 fPadWidth = kPadWidth;
312 //
313 fnWires = knWires;
314 fWWPitch= kPadPitchLength/Float_t(knWires);
315 fDiffT = kDiffT;
316 fDiffL = kDiffL;
317 fOmegaTau = kOmegaTau;
318 fOxyCont = kOxyCont;
319 fAttCoef = kAttCoef;
320 fNoise = kNoise;
321 fChipGain = kChipGain;
322 fGasGain = kGasGain;
323 fZeroSup= kZeroSup;
324 fPadCoupling= kPadCoupling;
325 fTSample =kTSample;
326 fTSigma =kTFWHM/2.35;
1283eee5 327 fDriftV=kDriftV;
328 fMaxTBin = kMaxTBin;
8c555625 329 fbStatus = Update();
330}
331
332void AliTPCParam::AdjustAngles(Int_t isec, Float_t &cos, Float_t &sin) const
333{
1283eee5 334 //
8c555625 335 //set cosinus and sinus of rotation angles for sector isec
1283eee5 336 //
337 cos=fRotAngle[isec*2];
338 sin=fRotAngle[isec*2+1];
8c555625 339}
340
341Bool_t AliTPCParam::Update()
342{
1283eee5 343 //
344 // update some calculated parameter which must be updated after changing "base"
345 // parameters
346 // for example we can change size of pads and according this recalculate number
347 // of pad rows, number of of pads in given row ....
348 //
8c555625 349 fbStatus = kFALSE;
1283eee5 350
351 Int_t i,j; //loop variables because HP
352 //-----------------Sector section------------------------------------------
353 //calclulate number of sectors
354 fNInnerSector = Int_t(4*TMath::Pi()/fInnerAngle+0.2); // number of inner sectors - factor 0.2 to don't
355 //be influnced by inprecision
356 if (fNInnerSector%2) return kFALSE;
357 fNOuterSector = Int_t(4*TMath::Pi()/fOuterAngle+0.2);
358 if (fNOuterSector%2) return kFALSE;
359 fNSector = fNInnerSector+fNOuterSector;
360 //calculate sin and cosine of rotations angle
361 //sectors angles numbering from 0
362 j=fNInnerSector;
363 Float_t angle = fInnerAngleShift;
364 for (i=0; i<fNInnerSector*2; i+=2, j+=2 , angle +=fInnerAngle){
365 fRotAngle[i]=TMath::Cos(angle);
366 fRotAngle[i+1]=TMath::Sin(angle);
367 fRotAngle[j] = fRotAngle[i];
368 fRotAngle[j+1] = fRotAngle[i+1];
369 }
370 angle = fOuterAngleShift;
371 j=(fNInnerSector+fNOuterSector/2)*2;
372 for (i=fNInnerSector*2; i<fNSector*2; i+=2,j+=2, angle +=fOuterAngle){
373 fRotAngle[i]=TMath::Cos(angle);
374 fRotAngle[i+1]=TMath::Sin(angle);
375 fRotAngle[j] = fRotAngle[i];
376 fRotAngle[j+1] = fRotAngle[i+1];
377 }
378
379
380 //----------------PAD section------------------------------------
8c555625 381 //recalculate and check some geometric parameters
382 if (0.001>fPadPitchLength){
383 cout<<"ERROR !!! Small pad pitch length \n"<<flush;
384 return kFALSE;
385 }
8c555625 386 if (fPadPitchLength<fPadLength) {
387 cout<<"ERROR !!! Pitch length smaller then length of pad \n"<<flush;
388 return kFALSE;
389 }
8c555625 390 fnRowUp = Int_t((0.01+fOuterRadiusUp-fOuterRadiusLow)/fPadPitchLength)+1;
391 if ( kMaxRows<fnRowUp) fnRowUp = kMaxRows;
392 if (1>fnRowUp) return kFALSE;
393
394 fnRowLow = Int_t((0.01+fInnerRadiusUp-fInnerRadiusLow)/fPadPitchLength)+1;
395 if ( kMaxRows<fnRowLow) fnRowUp = kMaxRows;
396 if (1>fnRowLow) return kFALSE;
397 // adjust upper sectors pad row positions and pad numbers
398 for (i = 0;i<fnRowUp;i++)
399 {
400 Float_t x = fOuterRadiusLow +fPadPitchLength*(Float_t)i;
1283eee5 401 //Float_t y = x*2*tan(alpha_up/2)-kEdgeSectorSpace;
402 Float_t y = (x-0.5*fPadPitchLength)*tan(fOuterAngle/2)-kEdgeSectorSpace
403 -fPadPitchWidth/2.;
8c555625 404 fPadRowUp[i] = x;
1283eee5 405 fnPadsUp[i] = 1+2*(Int_t)(y/fPadPitchWidth) ;
406
8c555625 407 }
408 // adjust lower sectors pad row positions and pad numbers
409 for (i = 0;i<fnRowLow;i++)
410 {
411 Float_t x = fInnerRadiusLow +fPadPitchLength*(Float_t)i;
1283eee5 412 // Float_t y = x*2*tan(alpha_low/2)-kEdgeSectorSpace;
413 Float_t y = (x-0.5*fPadPitchLength)*tan(fInnerAngle/2)-kEdgeSectorSpace
414 -fPadPitchWidth/2.;
8c555625 415 fPadRowLow[i] = x;
1283eee5 416 fnPadsLow[i] = 1+2*(Int_t)(y/fPadPitchWidth) ;
417
8c555625 418 }
419
420 //that variable are not writen to the file there are calculated
421 //
422 fWWPitch= fPadPitchLength/Float_t(fnWires);
423 fZWidth = fTSample*fDriftV;
1283eee5 424 fNtRows = fNInnerSector*fnRowLow+fNOuterSector*fnRowUp;
8c555625 425 fbStatus = kTRUE;
426 return kTRUE;
427}
428
429
430
431Bool_t AliTPCParam::GetStatus()
432{
433 //get information about object consistency
434 return fbStatus;
435}
436
437Int_t AliTPCParam::GetNRowLow() const
438{
439 //get the number of pad rows in low sector
440 return fnRowLow;
441}
442Int_t AliTPCParam::GetNRowUp() const
443{
444 //get the number of pad rows in up sector
445 return fnRowUp;
446}
447Float_t AliTPCParam::GetPadRowRadiiLow(Int_t irow) const
448{
449 //get the pad row (irow) radii
450 if ( !(irow<0) && (irow<fnRowLow) )
451 return fPadRowLow[irow];
452 else
453 return 0;
454}
455
456Float_t AliTPCParam::GetPadRowRadiiUp(Int_t irow) const
457{
458 //get the pad row (irow) radii
459 if ( !(irow<0) && (irow<fnRowUp) )
460 return fPadRowUp[irow];
461 else
462 return 0;
463}
464
465Int_t AliTPCParam::GetNPadsLow(Int_t irow) const
466{
467 //get the number of pads in row irow
468 if ( !(irow<0) && (irow<fnRowLow) )
469 return fnPadsLow[irow];
470 else
471 return 0;
472}
473
474
475Int_t AliTPCParam::GetNPadsUp(Int_t irow) const
476{
477 //get the number of pads in row irow
478 if ( !(irow<0) && (irow<fnRowUp) )
479 return fnPadsUp[irow];
480 else
481 return 0;
482}
483
484
485void AliTPCParam::Streamer(TBuffer &R__b)
486{
487 // Stream an object of class AliTPC.
488
489 if (R__b.IsReading()) {
490 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
491 TObject::Streamer(R__b);
492 if (R__v < 2) return;
1283eee5 493 //sector parameters
8c555625 494 R__b >> fInnerRadiusLow;
495 R__b >> fInnerRadiusUp;
496 R__b >> fOuterRadiusLow;
497 R__b >> fOuterRadiusUp;
1283eee5 498 R__b >> fInnerAngle;
499 R__b >> fInnerAngleShift;
500 R__b >> fOuterAngle;
501 R__b >> fOuterAngleShift;
502 //pad parameters
8c555625 503 R__b >> fPadPitchLength;
504 R__b >> fPadPitchWidth;
505 R__b >> fPadLength;
506 R__b >> fPadWidth;
507
508 R__b >> fnWires;
1283eee5 509 //gas parameters
8c555625 510 R__b >>fDiffT;
511 R__b >>fDiffL;
512 R__b >>fGasGain;
513 R__b >>fDriftV;
514 R__b >>fOmegaTau;
515 R__b >>fOxyCont;
516 R__b >>fAttCoef;
517
8c555625 518 R__b >>fPadCoupling;
519 R__b >>fZeroSup;
520 R__b >>fNoise;
521 R__b >>fChipGain;
522
523 R__b >>fTSample;
524 R__b >>fTSigma;
525 //
8c555625 526 Update();
527 } else {
528 R__b.WriteVersion(AliTPCParam::IsA());
529 TObject::Streamer(R__b);
530 R__b << fInnerRadiusLow;
531 R__b << fInnerRadiusUp;
532 R__b << fOuterRadiusLow;
533 R__b << fOuterRadiusUp;
1283eee5 534 R__b << fInnerAngle;
535 R__b << fInnerAngleShift;
536 R__b << fOuterAngle;
537 R__b << fOuterAngleShift;
8c555625 538
539 R__b << fPadPitchLength;
540 R__b << fPadPitchWidth;
541 R__b << fPadLength;
542 R__b << fPadWidth;
543
544 R__b << fnWires;
545
546 R__b <<fDiffT;
547 R__b <<fDiffL;
548 R__b <<fGasGain;
549 R__b <<fDriftV;
550 R__b <<fOmegaTau;
551 R__b <<fOxyCont;
552 R__b <<fAttCoef;
553
554
555 R__b <<fPadCoupling;
556 R__b <<fZeroSup;
557 R__b <<fNoise;
558 R__b <<fChipGain;
559
560 R__b <<fTSample;
561 R__b <<fTSigma;
562 }
563}
564