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