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