8f32e747c5022a1590cc370bb6315a2f19f947f1
[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.11  2000/11/02 07:33:48  kowal2
19 Automatic streamer generation.
20
21 Revision 1.10  2000/07/10 20:57:39  hristov
22 Update of TPC code and macros by M.Kowalski
23
24 Revision 1.9  2000/06/30 12:07:50  kowal2
25 Updated from the TPC-PreRelease branch
26
27 Revision 1.8.4.4  2000/06/26 07:39:42  kowal2
28 Changes to obey the coding rules
29
30 Revision 1.8.4.3  2000/06/25 08:38:41  kowal2
31 Splitted from AliTPCtracking
32   
33 Revision 1.8.4.2  2000/06/14 16:48:24  kowal2
34 Parameter setting improved. Removed compiler warnings
35
36 Revision 1.8.4.1  2000/06/09 07:12:21  kowal2  
37
38 Updated defaults
39
40 Revision 1.8  2000/04/17 09:37:33  kowal2
41 removed obsolete AliTPCDigitsDisplay.C
42
43 Revision 1.7.8.2  2000/04/10 08:44:51  kowal2
44
45 New transformations added
46 Different pad and pad-rows geometries for different sectors
47
48 Revision 1.7.8.1  2000/04/10 07:56:53  kowal2
49 Not used anymore - removed
50
51 Revision 1.7  1999/10/08 13:10:35  fca
52 Values in SetDefault are in radiants
53
54 Revision 1.6  1999/10/08 06:27:59  fca
55 Defaults updated
56
57 Revision 1.5  1999/10/05 17:18:27  fca
58 Correct GetWire check on even/odd fnWires
59
60 Revision 1.4  1999/09/29 09:24:34  fca
61 Introduction of the Copyright and cvs Log
62
63 */
64
65 ///////////////////////////////////////////////////////////////////////
66 //  Manager and of geomety  classes for set: TPC                     //
67 //                                                                   //
68 //  !sectors are numbered from  0                                     //
69 //  !pad rows are numbered from 0                                     //
70 //  
71 //  12.6.   changed z relative 
72 //  Origin:  Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk // 
73 //                                                                   //  
74 ///////////////////////////////////////////////////////////////////////
75
76 //
77
78 #include <iostream.h>
79 #include <TMath.h>
80 #include <TObject.h>
81 #include <TRandom.h>
82 #include <AliTPCParam.h>
83
84
85
86
87 ClassImp(AliTPCParam)
88
89
90 //___________________________________________
91 AliTPCParam::AliTPCParam()
92 {   
93   //
94   //constructor sets the default parameters
95   //
96
97   fResponseBin = 0;
98   fResponseWeight = 0;
99   fRotAngle = 0;
100   SetTitle("75x40_100x60");
101   SetDefault();  
102 }
103
104 AliTPCParam::~AliTPCParam()
105 {
106   //
107   //destructor deletes some dynamicaly alocated variables
108   //
109
110   if (fResponseBin!=0)    delete [] fResponseBin;
111   if (fResponseWeight!=0) delete [] fResponseWeight;
112   if (fRotAngle      !=0) delete [] fRotAngle;
113
114 }
115
116
117
118
119 Int_t  AliTPCParam::Transform0to1(Float_t *xyz, Int_t * index)  const
120 {
121   //
122   // calculates sector number (index[1], undefined on input)
123   // xyz intact
124   //
125
126   Float_t angle,x1;
127   Int_t sector;
128   Float_t r = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
129   if ((xyz[0]==0)&&(xyz[1]==0)) angle = 0.;
130   else
131     {
132       angle =TMath::ASin(xyz[1]/r);
133       if   (xyz[0]<0)   angle=TMath::Pi()-angle;
134       if ( (xyz[0]>0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle;
135     }
136
137   sector=Int_t((angle-fInnerAngleShift)/fInnerAngle);      
138  
139   Float_t cos,sin;
140   AdjustCosSin(sector,cos,sin);
141   x1=xyz[0]*cos + xyz[1]*sin;
142
143   if (x1>fOuterRadiusLow)
144     {
145       sector=Int_t((angle-fOuterAngleShift)/fOuterAngle)+fNInnerSector;      
146       if (xyz[2]<0)     sector+=(fNOuterSector>>1);            
147     }
148     else   
149       if (xyz[2]<0) sector+=(fNInnerSector>>1);    
150   index[1]=sector; // calculated sector number
151   index[0]=1; // indicates system after transformation
152   return sector;
153 }
154
155 Bool_t  AliTPCParam::Transform(Float_t *xyz, Int_t *index, Int_t* oindex)
156 {
157   //transformation from input coodination system to output coordination system
158   switch (index[0]){
159   case 0:
160     break;
161   };
162
163   return kFALSE;
164
165 }
166
167 Int_t AliTPCParam::GetPadRow(Float_t *xyz, Int_t *index) const 
168 {
169   //
170   //calculates pad row of point xyz - transformation to system 8 (digit system)
171   //
172   Int_t system = index[0];
173   if (0==system) {
174     Transform0to1(xyz,index); 
175     system=1;
176   }
177   if (1==system) {
178     Transform1to2(xyz,index); 
179     system=2;
180   }
181     
182   if (fGeometryType==0){ //straight row    
183     if (2==system) {
184       Transform2to3(xyz,index);       
185       system=3;
186     } 
187     if (3==system) {
188       Transform3to4(xyz,index);
189       system=4; 
190     }
191     if (4==system) {
192       Transform4to8(xyz,index);
193       system=8;     
194     }
195     if (8==system) {
196       index[0]=8;
197       return index[2];
198     } 
199   }
200
201   if (fGeometryType==1){ //cylindrical geometry    
202     if (2==system) {
203       Transform2to5(xyz,index);       
204       system=5;
205     } 
206     if (5==system) {
207       Transform2to3(xyz,index);
208       system=6;
209     }
210     if (6==system) {
211       Transform3to4(xyz,index); 
212       system=7;
213     }
214     if (8==system) {
215       index[0]=8;
216       return index[2];
217     }
218   } 
219   index[0]=system;
220   return -1; //if no reasonable system     
221 }
222
223 void  AliTPCParam::SetSectorAngles(Float_t innerangle, Float_t innershift, Float_t outerangle,
224                         Float_t outershift)
225 {
226   //
227   // set opening angles  
228   const static  Float_t  kDegtoRad = 0.01745329251994;
229   fInnerAngle = innerangle;       //opening angle of Inner sector
230   fInnerAngleShift = innershift;  //shift of first inner sector center to the 0
231   fOuterAngle = outerangle;       //opening angle of outer sector
232   fOuterAngleShift = outershift;  //shift of first sector center to the 0  
233   fInnerAngle *=kDegtoRad;
234   fInnerAngleShift *=kDegtoRad;
235   fOuterAngle *=kDegtoRad;
236   fOuterAngleShift *=kDegtoRad;
237 }
238
239 Float_t  AliTPCParam::GetInnerAngle() const
240 {
241   //return angle 
242   return fInnerAngle;
243
244 }
245
246 Float_t  AliTPCParam::GetInnerAngleShift() const
247 {  
248   //return angle   
249   return fInnerAngleShift;  
250 }
251 Float_t  AliTPCParam::GetOuterAngle() const
252
253   //return angle 
254   return fOuterAngle;
255
256 Float_t  AliTPCParam::GetOuterAngleShift() const
257
258   //return angle 
259
260      return fOuterAngleShift;
261
262
263
264 Int_t AliTPCParam::GetIndex(Int_t sector, Int_t row)
265 {
266   //
267   //give index of the given sector and pad row 
268   //no control if the sectors and rows  are reasonable !!!
269   //
270   if (sector<fNInnerSector) return sector*fNRowLow+row;
271   return (fNInnerSector*fNRowLow)+(sector-fNInnerSector)*fNRowUp+row;  
272 }
273
274 Bool_t   AliTPCParam::AdjustSectorRow(Int_t index, Int_t & sector, Int_t &row) const
275 {
276   //
277   //return sector and padrow for given index
278   //if index is reasonable returns true else return false
279   //
280   if ( (index<0) || (index>fNtRows))  return kFALSE;
281   Int_t outindex = fNInnerSector*fNRowLow;
282   if (index<outindex) {
283     sector = index/fNRowLow;
284     row    = index - sector*fNRowLow;
285     return kTRUE;
286   }
287   index-= outindex;
288   sector = index/fNRowUp;
289   row    = index - sector*fNRowUp;
290   sector += fNInnerSector;
291   return kTRUE;         
292
293
294 void AliTPCParam::SetDefault()
295 {
296   //
297   //set default parameters
298   //
299   //const static  Int_t kMaxRows=600; 
300   //
301   //sector default parameters
302   //
303   const static  Float_t kInnerRadiusLow = 82.97;
304   const static  Float_t kOuterRadiusLow = 133.58;
305   const static  Float_t kInnerRadiusUp  = 133.17;
306   const static  Float_t kOuterRadiusUp  = 247.78;
307   const static  Float_t kInnerAngle = 20; // 20 degrees
308   const static  Float_t kInnerAngleShift = 10;
309   const static  Float_t kOuterAngle = 20; //  20 degrees
310   const static  Float_t kOuterAngleShift = 10;
311   const static  Float_t kInnerFrameSpace = 1.5;
312   const static  Float_t kOuterFrameSpace = 1.5;
313   const static  Float_t kInnerWireMount = 1.370825926;
314   const static  Float_t kOuterWireMount = 1.370825926;
315   const static  Float_t kZLength =250.;
316   const static  Int_t   kGeometryType = 0; //straight rows 
317   //
318   //wires default parameters
319   //
320   const static Int_t    kNInnerWiresPerPad = 3;
321   const static Int_t    kInnerDummyWire = 2;
322   const static Float_t  kInnerOffWire = 0.5;
323   const static Int_t    kNOuterWiresPerPad = 4;
324   const static Int_t    kOuterDummyWire = 2;
325   const static Float_t  kOuterOffWire = 0.5;
326   //
327   //pad default parameters
328   // 
329   const static Float_t  kInnerPadPitchLength = 0.75;
330   const static Float_t  kInnerPadPitchWidth = 0.40;
331   const static Float_t  kInnerPadLength = 0.75;
332   const static Float_t  kInnerPadWidth = 0.40;
333   const static Float_t  kOuterPadPitchLength = 1.0;
334   const static Float_t  kOuterPadPitchWidth = 0.6;
335   const static Float_t  kOuterPadLength = 1.0;
336   const static Float_t  kOuterPadWidth = 0.6;
337   const static Bool_t   kBMWPCReadout = kTRUE; //MWPC readout - another possibility GEM 
338   const static Int_t    kNCrossRows = 1; //number of rows to cross-talk
339   
340   //
341   //gas default parameters
342   //
343   const static  Float_t  kDiffT = 2.2e-2; 
344   const static  Float_t  kDiffL = 2.2e-2;
345   const static  Float_t  kGasGain = 2.e4;
346   const static  Float_t  kDriftV  =2.83e6;
347   const static  Float_t  kOmegaTau = 0.145;
348   const static  Float_t  kAttCoef = 250.;
349   const static  Float_t  kOxyCont = 5.e-6;
350   //
351   //electronic default parameters
352   //
353   const static  Float_t  kPadCoupling=0.5;
354   const static  Int_t    kZeroSup=2;
355   const static  Float_t  kNoise = 1000;                            
356   const static  Float_t  kChipGain = 12;
357   const static  Float_t  kChipNorm = 0.4;
358   const static  Float_t  kTSample = 2.e-7; 
359   const static  Float_t  kTFWHM   = 1.9e-7;  //fwhm of charge distribution
360   const static  Int_t    kMaxTBin =445;  
361   const static  Int_t    kADCSat  =1024;  
362   const static  Float_t  kADCDynRange =2000.;  
363   //
364   //
365   //
366   const static  Float_t kBField =0.2; 
367   const static  Float_t kNPrimLoss =10.9;
368   const static  Float_t kNTotalLoss =39.9;
369   // 
370   //response constants
371   //
372   const static Int_t     kNResponseMax=100;
373   const static Float_t   kResponseThreshold=0.01;     
374   fbStatus = kFALSE;
375   //
376   //set sector parameters
377   //
378   SetInnerRadiusLow(kInnerRadiusLow);
379   SetOuterRadiusLow(kOuterRadiusLow);
380   SetInnerRadiusUp(kInnerRadiusUp);
381   SetOuterRadiusUp(kOuterRadiusUp);
382   SetInnerFrameSpace(kInnerFrameSpace);
383   SetOuterFrameSpace(kOuterFrameSpace);
384   SetInnerWireMount(kInnerWireMount);
385   SetOuterWireMount(kOuterWireMount);
386   SetSectorAngles(kInnerAngle,kInnerAngleShift,kOuterAngle,kOuterAngleShift);
387   SetZLength(kZLength);
388   SetGeometryType(kGeometryType);
389   //
390   //set wire parameters
391   //
392   SetInnerNWires(kNInnerWiresPerPad);
393   SetInnerDummyWire(kInnerDummyWire);
394   SetInnerOffWire(kInnerOffWire);
395   SetOuterNWires(kNOuterWiresPerPad);
396   SetOuterDummyWire(kOuterDummyWire);
397   SetOuterOffWire(kOuterOffWire);
398   //
399   //set pad parameter
400   //
401   SetInnerPadPitchLength(kInnerPadPitchLength);
402   SetInnerPadPitchWidth(kInnerPadPitchWidth);
403   SetInnerPadLength(kInnerPadLength);
404   SetInnerPadWidth(kInnerPadWidth);
405   SetOuterPadPitchLength(kOuterPadPitchLength);
406   SetOuterPadPitchWidth(kOuterPadPitchWidth);
407   SetOuterPadLength(kOuterPadLength);
408   SetOuterPadWidth(kOuterPadWidth); 
409   SetMWPCReadout(kBMWPCReadout);
410   SetNCrossRows(kNCrossRows);
411   //
412   //set gas paremeters
413   //
414   SetDiffT(kDiffT);
415   SetDiffL(kDiffL);
416   SetGasGain(kGasGain);
417   SetDriftV(kDriftV);
418   SetOmegaTau(kOmegaTau);
419   SetAttCoef(kAttCoef);
420   SetOxyCont(kOxyCont);
421   //
422   //set electronivc parameters  
423   //
424   SetPadCoupling(kPadCoupling);
425   SetZeroSup(kZeroSup);
426   SetNoise(kNoise);
427   SetChipGain(kChipGain);
428   SetChipNorm(kChipNorm);   
429   SetTSample(kTSample);
430   SetTFWHM(kTFWHM);
431   SetMaxTBin(kMaxTBin);
432   SetADCSat(kADCSat);
433   SetADCDynRange(kADCDynRange);
434   //set magnetic field
435   SetBField(kBField);
436   SetNPrimLoss(kNPrimLoss);
437   SetNTotalLoss(kNTotalLoss);
438   //
439   //set response  parameters  
440   //
441   SetNResponseMax(kNResponseMax); 
442   SetResponseThreshold(static_cast<int>(kResponseThreshold));
443 }
444
445           
446 Bool_t AliTPCParam::Update()
447 {
448   //
449   // update some calculated parameter which must be updated after changing "base"
450   // parameters 
451   // for example we can change size of pads and according this recalculate number
452   // of pad rows, number of of pads in given row ....
453   //
454   const Float_t kQel = 1.602e-19; // elementary charge
455   fbStatus = kFALSE;
456
457   Int_t i,j;  //loop variables because HP 
458   //-----------------Sector section------------------------------------------
459   //calclulate number of sectors
460   fNInnerSector = Int_t(4*TMath::Pi()/fInnerAngle+0.2); 
461        // number of inner sectors - factor 0.2 to don't be influnced by inprecision
462   if (fNInnerSector%2) return kFALSE;
463   fNOuterSector = Int_t(4*TMath::Pi()/fOuterAngle+0.2); 
464   if (fNOuterSector%2) return kFALSE;
465   fNSector  = fNInnerSector+fNOuterSector;
466
467   if (fRotAngle!=0) delete [] fRotAngle;
468   fRotAngle = new Float_t[4*fNSector];
469   //calculate sin and cosine of rotations angle     
470   //sectors angles numbering from 0
471
472   j=fNInnerSector*2;
473   Float_t angle = fInnerAngleShift; 
474   for (i=0; j<fNInnerSector*4; i+=4, j+=4 , angle +=fInnerAngle){
475     fRotAngle[i]=TMath::Cos(angle);
476     fRotAngle[i+1]=TMath::Sin(angle);
477     fRotAngle[j] =  fRotAngle[i];
478     fRotAngle[j+1] =  fRotAngle[i+1];
479     fRotAngle[i+2] =angle;
480     fRotAngle[j+2] =angle;    
481   }
482   angle = fOuterAngleShift; 
483   j=(fNInnerSector+fNOuterSector/2)*4;
484   for (i=fNInnerSector*4; j<fNSector*4; i+=4,j+=4, angle +=fOuterAngle){
485     fRotAngle[i]=TMath::Cos(angle);
486     fRotAngle[i+1]=TMath::Sin(angle);
487     fRotAngle[j] =  fRotAngle[i];
488     fRotAngle[j+1] =  fRotAngle[i+1];
489     fRotAngle[i+2] =angle;
490     fRotAngle[j+2] =angle;    
491   }
492   fZWidth = fTSample*fDriftV;  
493   fTotalNormFac = fPadCoupling*fChipNorm*kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
494   fNoiseNormFac = kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
495   //wire section 
496   Int_t nwire;
497   Float_t wspace; //available space for wire
498   Float_t dummyspace; //dummyspace for wire
499
500   fInnerWWPitch = Float_t((Double_t)fInnerPadPitchLength/(Double_t)fNInnerWiresPerPad);  
501   wspace =fInnerRadiusUp-fInnerRadiusLow-2*fInnerOffWire;
502   nwire = Int_t(wspace/fInnerWWPitch);
503   wspace = Float_t(nwire)*fInnerWWPitch;
504   dummyspace =(fInnerRadiusUp-fInnerRadiusLow-wspace)/2.; 
505   fRInnerFirstWire = fInnerRadiusLow+dummyspace;
506   fRInnerLastWire = fRInnerFirstWire+fInnerWWPitch*(Float_t)(nwire);
507
508   fOuterWWPitch = Float_t((Double_t)fOuterPadPitchLength/(Double_t)fNOuterWiresPerPad);  
509   wspace =fOuterRadiusUp-fOuterRadiusLow-2*fOuterOffWire;
510   nwire = Int_t(wspace/fOuterWWPitch);
511   wspace = Float_t(nwire)*fOuterWWPitch;
512   dummyspace =(fOuterRadiusUp-fOuterRadiusLow-wspace)/2.; 
513   fROuterFirstWire = fOuterRadiusLow+dummyspace;
514   fROuterLastWire = fROuterFirstWire+fOuterWWPitch*(Float_t)(nwire);
515
516   
517   //
518   //response data
519   //
520   if (fResponseBin==0) delete [] fResponseBin;
521   if (fResponseWeight==0) delete [] fResponseBin;
522   fResponseBin    = new Int_t[3*fNResponseMax];
523   fResponseWeight = new Float_t[fNResponseMax];
524   
525   fbStatus = kTRUE;
526   return kTRUE;
527 }
528
529
530
531 Bool_t AliTPCParam::GetStatus()
532 {
533   //get information about object consistency
534   return fbStatus;
535 }
536
537 Int_t AliTPCParam::GetNRowLow() const
538 {
539   //get the number of pad rows in low sector
540   return fNRowLow;
541 }
542 Int_t AliTPCParam::GetNRowUp() const
543 {
544   //get the number of pad rows in up sector
545   return fNRowUp;
546 }
547 Float_t AliTPCParam::GetPadRowRadiiLow(Int_t irow) const
548 {
549   //get the pad row (irow) radii
550   if ( !(irow<0) && (irow<fNRowLow) ) 
551     return  fPadRowLow[irow];
552   else
553     return 0;
554 }
555
556 Float_t AliTPCParam::GetPadRowRadiiUp(Int_t irow) const
557 {
558   //get the pad row (irow) radii
559  if ( !(irow<0) && (irow<fNRowUp) ) 
560     return  fPadRowUp[irow];
561   else
562     return 0;
563 }
564
565 Int_t AliTPCParam::GetNPadsLow(Int_t irow) const
566 {
567   //get the number of pads in row irow
568   if ( !(irow<0) && (irow<fNRowLow) ) 
569     return  fNPadsLow[irow];
570   else
571     return 0;
572 }
573
574
575 Int_t AliTPCParam::GetNPadsUp(Int_t irow) const
576 {
577   //get the number of pads in row irow
578   if ( !(irow<0) && (irow<fNRowUp) ) 
579     return  fNPadsUp[irow];
580   else
581     return 0;
582 }
583