The changes w.r.t. the previous version:
[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   Float_t x1=xyz[0];
117   Float_t y1=xyz[1];
118   Float_t cos,sin;
119   AdjustAngles(sector,cos,sin);
120   xyz[0]= x1*cos - y1*sin;
121   xyz[1]= x1*sin + y1*cos;
122 }
123
124 void 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       }
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);      
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       {
161         sector=Int_t((angle-fOuterAngleShift)/fOuterAngle)+fNInnerSector;
162         AdjustAngles(sector,cos,sin);        
163         x1=xyz[0]*cos + xyz[1]*sin;
164         y1=-xyz[0]*sin + xyz[1]*cos;      
165         if (xyz[2]<0)   sector+=(fNOuterSector>>1);            
166       }
167     else   
168       if (xyz[2]<0) sector+=(fNInnerSector>>1);    
169
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;    
180    xyz[2]=z_end-TMath::Abs(xyz[2]);  
181   }   //endif we don't have information about sector
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
192     if (sector<fNInnerSector) {
193       padrow =Int_t( (x1-fPadRowLow[0])/fPadPitchLength+1.5)-1;
194     }
195     else {
196       padrow =Int_t( (x1-fPadRowUp[0])/fPadPitchLength+1.5)-1;
197     }
198     //if we store relative position calculate position relative to pad row
199     if (rel==kTRUE){
200       if (sector<fNInnerSector)
201         x1-=padrow*fPadPitchLength+fPadRowLow[0];
202       else 
203         x1-=padrow*fPadPitchLength+fPadRowUp[0];
204     }      
205     xyz[0]=x1;
206     xyz[1]=y1;
207     xyz[2]=z_end-TMath::Abs(xyz[2]);  
208   }
209 }
210
211 void 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
216   Float_t  nofpads = GetNPads(sector,padrow);
217   Float_t padc=(nofpads+1)/2; // this is the "central" pad for a row
218   pad = y/(fPadPitchWidth)+padc;
219   time=z/fZWidth;  
220 }
221 void 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 
226    Float_t  nofpads = GetNPads(sector,padrow);
227    Float_t padc=(nofpads+1)/2; // this is the "central" pad for a row
228    y=(pad-padc)*fPadPitchWidth;
229    z=time*fZWidth;
230 }
231
232 Int_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
252 Int_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   //
258   if (sector<fNInnerSector) return sector*fnRowLow+row;
259   return (fNInnerSector*fnRowLow)+(sector-fNInnerSector)*fnRowUp+row;  
260 }
261
262 Bool_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;
269   Int_t outindex = fNInnerSector*fnRowLow;
270   if (index<outindex) {
271     sector = index/fnRowLow;
272     row    = index - sector*fnRowLow;
273     return kTRUE;
274   }
275   index-= outindex;
276   sector = index/fnRowUp;
277   row    = index - sector*fnRowUp;
278   return kTRUE;         
279
280
281
282
283 Int_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
296 void AliTPCParam::SetDefault()
297 {
298   //set default TPC param   
299   fbStatus = kFALSE;
300   //set sector  parameters
301   fInnerRadiusLow = kInnerRadiusLow;
302   fOuterRadiusLow = kOuterRadiusLow;
303   fInnerRadiusUp  = kInnerRadiusUp;
304   fOuterRadiusUp  = kOuterRadiusUp;   
305   SetSectorAngles(kInnerAngle,kInnerAngleShift, kOuterAngle, kOuterAngleShift); 
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; 
326   fDriftV=kDriftV;  
327   fMaxTBin = kMaxTBin;
328   fbStatus = Update();
329 }
330
331 void  AliTPCParam::AdjustAngles(Int_t isec, Float_t &cos, Float_t &sin) const
332 {
333   //
334   //set cosinus and sinus of rotation angles for sector isec
335   //
336   cos=fRotAngle[isec*2];
337   sin=fRotAngle[isec*2+1];
338 }
339           
340 Bool_t AliTPCParam::Update()
341 {
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   //
348   fbStatus = kFALSE;
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------------------------------------
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   }
385   if (fPadPitchLength<fPadLength) {
386     cout<<"ERROR !!! Pitch length  smaller then length of pad \n"<<flush;
387     return kFALSE;
388   } 
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;
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.;
403        fPadRowUp[i] = x;
404        fnPadsUp[i] = 1+2*(Int_t)(y/fPadPitchWidth) ;        
405        
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;
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.;
414        fPadRowLow[i] = x;
415        fnPadsLow[i] = 1+2*(Int_t)(y/fPadPitchWidth) ;
416          
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;  
423   fNtRows = fNInnerSector*fnRowLow+fNOuterSector*fnRowUp;
424   fbStatus = kTRUE;
425   return kTRUE;
426 }
427
428
429
430 Bool_t AliTPCParam::GetStatus()
431 {
432   //get information about object consistency
433   return fbStatus;
434 }
435
436 Int_t AliTPCParam::GetNRowLow() const
437 {
438   //get the number of pad rows in low sector
439   return fnRowLow;
440 }
441 Int_t AliTPCParam::GetNRowUp() const
442 {
443   //get the number of pad rows in up sector
444   return fnRowUp;
445 }
446 Float_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
455 Float_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
464 Int_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
474 Int_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
484 void 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;
492       //sector parameters      
493       R__b >> fInnerRadiusLow;
494       R__b >> fInnerRadiusUp;
495       R__b >> fOuterRadiusLow;
496       R__b >> fOuterRadiusUp;
497       R__b >> fInnerAngle;
498       R__b >> fInnerAngleShift;
499       R__b >> fOuterAngle;
500       R__b >> fOuterAngleShift;
501       //pad parameters
502       R__b >> fPadPitchLength;
503       R__b >> fPadPitchWidth;
504       R__b >> fPadLength;
505       R__b >> fPadWidth;
506
507       R__b >> fnWires;
508       //gas parameters
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       
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       //
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;
533       R__b << fInnerAngle;
534       R__b << fInnerAngleShift;
535       R__b << fOuterAngle;
536       R__b << fOuterAngleShift;
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