]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCParam.cxx
New version from M.Kowalski
[u/mrichter/AliRoot.git] / TPC / AliTPCParam.cxx
1 ///////////////////////////////////////////////////////////////////////
2 //  Manager and of geomety  classes for set: TPC                     //
3 //                                                                   //
4 //  !sectors are numbered from  0                                     //
5 //  !pad rows are numbered from 0                                     //
6 //  
7 //  12.6.   changed z relative 
8 //  Origin:  Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk // 
9 //                                                                   //  
10 ///////////////////////////////////////////////////////////////////////
11
12
13 #include <iostream.h>
14 #include <TMath.h>
15 #include <TObject.h>
16 #include "AliTPCSecGeo.h"
17 #include <AliTPCParam.h>
18
19
20 ClassImp(AliTPCParam)
21
22 const static  Int_t kMaxRows=600;
23
24
25 // default values  
26 const static   Int_t kMaxTBin =512; 
27
28
29 const static  Float_t kInnerRadiusLow = 89.45;
30 const static  Float_t kOuterRadiusLow = 143.725;
31 const static  Float_t kInnerRadiusUp  = 134.55;
32 const static  Float_t kOuterRadiusUp  = 248.275;
33
34 const static  Float_t kInnerAngle = 0.523598775; // 30 degrees
35 const static  Float_t kInnerAngleShift = 0;
36 const static  Float_t kOuterAngle = 0.261799387; //  15 degrees
37 const static  Float_t kOuterAngleShift = 0;
38
39 const static Float_t kPadPitchLength = 2.05;
40 const static Float_t kPadPitchWidth = 0.35;
41 const static Float_t kPadLength = 2.05;
42 const static Float_t kPadWidth = 0.35;
43
44 //  Number of wires per pad and wire-wire pitch
45 const static Int_t knWires = 5;
46 const static  Float_t  kDiffT = 2.2e-2; 
47 const static  Float_t  kDiffL = 2.2e-2; 
48 const static  Float_t  kDriftV  =2.85e6;
49
50 const static  Float_t  kOmegaTau = 0.145;
51 const static  Float_t  kAttCoef = 250.;
52 const static  Float_t  kOxyCont = 5.e-6;
53
54
55 const static  Float_t  kChipGain = 24;
56 const static  Float_t  kGasGain = 1e4;
57 const static  Float_t  kTSample = 2.e-7; //TSAMPLE
58 const static  Float_t  kTFWHM   = 2.5e-7;  //fwhm of charge distribution
59  
60 const static  Float_t  kNoise = 500;  //default noise = 1000 el 
61 const static  Int_t    kZeroSup=5;
62 const static  Float_t  kPadCoupling=0.5;
63 // 
64 const static  Float_t  kEdgeSectorSpace = 1.15;
65 const static  Float_t  kDegtoRad = 0.01745329251994;
66 const static  Float_t  kRadtoDeg = 57.29577951309;
67
68
69
70
71 //___________________________________________
72 AliTPCParam::AliTPCParam()
73 {   
74   //constructor set the default parameters
75   SetDefault();  
76 }
77
78
79 void  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
97 void 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; 
103   row_first = (sector<=fNInnerSector) ? fPadRowLow[0] : fPadRowUp[0]; 
104   if (rel==kTRUE)  //if the position is relative to pad row  
105     {
106       xyz[0]+=row_first;
107       xyz[0]+=(Int_t) padrow*fPadPitchLength;
108     }  
109
110   xyz[2]=z_end-xyz[2];
111   if (sector<fNInnerSector) {
112     if ( sector>=(fNInnerSector>>1))    xyz[2]*=-1.;
113   } else {
114     if ( (sector-fNInnerSector) >= (fNOuterSector>>1) )    xyz[2]*=-1;
115   }
116
117   Float_t x1=xyz[0];
118   Float_t y1=xyz[1];
119   Float_t cos,sin;
120   AdjustAngles(sector,cos,sin);
121   xyz[0]= x1*cos - y1*sin;
122   xyz[1]= x1*sin + y1*cos;
123 }
124
125 void 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       }
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);      
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       {
162         sector=Int_t((angle-fOuterAngleShift)/fOuterAngle)+fNInnerSector;
163         AdjustAngles(sector,cos,sin);        
164         x1=xyz[0]*cos + xyz[1]*sin;
165         y1=-xyz[0]*sin + xyz[1]*cos;      
166         if (xyz[2]<0)   sector+=(fNOuterSector>>1);            
167       }
168     else   
169       if (xyz[2]<0) sector+=(fNInnerSector>>1);    
170
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;    
181    xyz[2]=z_end-TMath::Abs(xyz[2]);  
182   }   //endif we don't have information about sector
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
193     if (sector<fNInnerSector) {
194       padrow =Int_t( (x1-fPadRowLow[0])/fPadPitchLength+1.5)-1;
195     }
196     else {
197       padrow =Int_t( (x1-fPadRowUp[0])/fPadPitchLength+1.5)-1;
198     }
199     //if we store relative position calculate position relative to pad row
200     if (rel==kTRUE){
201       if (sector<fNInnerSector)
202         x1-=padrow*fPadPitchLength+fPadRowLow[0];
203       else 
204         x1-=padrow*fPadPitchLength+fPadRowUp[0];
205     }      
206     xyz[0]=x1;
207     xyz[1]=y1;
208     xyz[2]=z_end-TMath::Abs(xyz[2]);  
209   }
210 }
211
212 void 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
217   Float_t  nofpads = GetNPads(sector,padrow);
218   Float_t padc=(nofpads+1)/2; // this is the "central" pad for a row
219   pad = y/(fPadPitchWidth)+padc;
220   time=z/fZWidth;  
221 }
222 void 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 
227    Float_t  nofpads = GetNPads(sector,padrow);
228    Float_t padc=(nofpads+1)/2; // this is the "central" pad for a row
229    y=(pad-padc)*fPadPitchWidth;
230    z=time*fZWidth;
231 }
232
233 Int_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
253 Int_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   //
259   if (sector<fNInnerSector) return sector*fnRowLow+row;
260   return (fNInnerSector*fnRowLow)+(sector-fNInnerSector)*fnRowUp+row;  
261 }
262
263 Bool_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;
270   Int_t outindex = fNInnerSector*fnRowLow;
271   if (index<outindex) {
272     sector = index/fnRowLow;
273     row    = index - sector*fnRowLow;
274     return kTRUE;
275   }
276   index-= outindex;
277   sector = index/fnRowUp;
278   row    = index - sector*fnRowUp;
279   return kTRUE;         
280
281
282
283
284 Int_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
297 void AliTPCParam::SetDefault()
298 {
299   //set default TPC param   
300   fbStatus = kFALSE;
301   //set sector  parameters
302   fInnerRadiusLow = kInnerRadiusLow;
303   fOuterRadiusLow = kOuterRadiusLow;
304   fInnerRadiusUp  = kInnerRadiusUp;
305   fOuterRadiusUp  = kOuterRadiusUp;   
306   SetSectorAngles(kInnerAngle,kInnerAngleShift, kOuterAngle, kOuterAngleShift); 
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; 
327   fDriftV=kDriftV;  
328   fMaxTBin = kMaxTBin;
329   fbStatus = Update();
330 }
331
332 void  AliTPCParam::AdjustAngles(Int_t isec, Float_t &cos, Float_t &sin) const
333 {
334   //
335   //set cosinus and sinus of rotation angles for sector isec
336   //
337   cos=fRotAngle[isec*2];
338   sin=fRotAngle[isec*2+1];
339 }
340           
341 Bool_t AliTPCParam::Update()
342 {
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   //
349   fbStatus = kFALSE;
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------------------------------------
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   }
386   if (fPadPitchLength<fPadLength) {
387     cout<<"ERROR !!! Pitch length  smaller then length of pad \n"<<flush;
388     return kFALSE;
389   } 
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;
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.;
404        fPadRowUp[i] = x;
405        fnPadsUp[i] = 1+2*(Int_t)(y/fPadPitchWidth) ;        
406        
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;
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.;
415        fPadRowLow[i] = x;
416        fnPadsLow[i] = 1+2*(Int_t)(y/fPadPitchWidth) ;
417          
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;  
424   fNtRows = fNInnerSector*fnRowLow+fNOuterSector*fnRowUp;
425   fbStatus = kTRUE;
426   return kTRUE;
427 }
428
429
430
431 Bool_t AliTPCParam::GetStatus()
432 {
433   //get information about object consistency
434   return fbStatus;
435 }
436
437 Int_t AliTPCParam::GetNRowLow() const
438 {
439   //get the number of pad rows in low sector
440   return fnRowLow;
441 }
442 Int_t AliTPCParam::GetNRowUp() const
443 {
444   //get the number of pad rows in up sector
445   return fnRowUp;
446 }
447 Float_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
456 Float_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
465 Int_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
475 Int_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
485 void 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;
493       //sector parameters      
494       R__b >> fInnerRadiusLow;
495       R__b >> fInnerRadiusUp;
496       R__b >> fOuterRadiusLow;
497       R__b >> fOuterRadiusUp;
498       R__b >> fInnerAngle;
499       R__b >> fInnerAngleShift;
500       R__b >> fOuterAngle;
501       R__b >> fOuterAngleShift;
502       //pad parameters
503       R__b >> fPadPitchLength;
504       R__b >> fPadPitchWidth;
505       R__b >> fPadLength;
506       R__b >> fPadWidth;
507
508       R__b >> fnWires;
509       //gas parameters
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       
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       //
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;
534       R__b << fInnerAngle;
535       R__b << fInnerAngleShift;
536       R__b << fOuterAngle;
537       R__b << fOuterAngleShift;
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