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