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