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