]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCParam.cxx
33c6e3894cfe55f6b36c99460ac7d7047979c2ec
[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.6  1999/10/08 06:27:59  fca
19 Defaults updated
20
21 Revision 1.5  1999/10/05 17:18:27  fca
22 Correct GetWire check on even/odd fnWires
23
24 Revision 1.4  1999/09/29 09:24:34  fca
25 Introduction 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
48 ClassImp(AliTPCParam)
49
50 const static  Int_t kMaxRows=600;
51
52
53 // default values  
54 const static   Int_t kMaxTBin =512; 
55
56
57 const static  Float_t kInnerRadiusLow = 83.9;
58 const static  Float_t kOuterRadiusLow = 146.9;
59 const static  Float_t kInnerRadiusUp  = 141.3;
60 const static  Float_t kOuterRadiusUp  = 249.4;
61
62 const static  Float_t kInnerAngle = 0.34906585; // 20 degrees
63 const static  Float_t kInnerAngleShift = 0;
64 const static  Float_t kOuterAngle = 0.34906585; //  20 degrees
65 const static  Float_t kOuterAngleShift = 0;
66
67 const static Float_t kPadPitchLength = 2.05;
68 const static Float_t kPadPitchWidth = 0.35;
69 const static Float_t kPadLength = 2.05;
70 const static Float_t kPadWidth = 0.35;
71
72 //  Number of wires per pad and wire-wire pitch
73 const static Int_t knWires = 5;
74 const static  Float_t  kDiffT = 2.2e-2; 
75 const static  Float_t  kDiffL = 2.2e-2; 
76 const static  Float_t  kDriftV  =2.85e6;
77
78 const static  Float_t  kOmegaTau = 0.145;
79 const static  Float_t  kAttCoef = 250.;
80 const static  Float_t  kOxyCont = 5.e-6;
81
82
83 const static  Float_t  kChipGain = 12;
84 const static  Float_t  kGasGain = 2e4;
85 const static  Float_t  kTSample = 2.e-7; //TSAMPLE
86 const static  Float_t  kTFWHM   = 2.5e-7;  //fwhm of charge distribution
87  
88 const static  Float_t  kNoise = 1000;  //default noise = 1000 el 
89 const static  Int_t    kZeroSup=5;
90 const static  Float_t  kPadCoupling=0.5;
91 // 
92 const static  Float_t  kEdgeSectorSpace = 1.15;
93 const static  Float_t  kDegtoRad = 0.01745329251994;
94 const static  Float_t  kRadtoDeg = 57.29577951309;
95
96
97
98
99 //___________________________________________
100 AliTPCParam::AliTPCParam()
101 {   
102   //constructor set the default parameters
103   SetDefault();  
104 }
105
106
107 void  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
125 void 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
153 void 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
240 void 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 }
250 void 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
261 Int_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
281 Int_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
291 Bool_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
312 Int_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
325 void 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
360 void  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           
369 Bool_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
459 Bool_t AliTPCParam::GetStatus()
460 {
461   //get information about object consistency
462   return fbStatus;
463 }
464
465 Int_t AliTPCParam::GetNRowLow() const
466 {
467   //get the number of pad rows in low sector
468   return fnRowLow;
469 }
470 Int_t AliTPCParam::GetNRowUp() const
471 {
472   //get the number of pad rows in up sector
473   return fnRowUp;
474 }
475 Float_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
484 Float_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
493 Int_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
503 Int_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
513 void 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