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