Install macros
[u/mrichter/AliRoot.git] / TPC / TPCbase / 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 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////
19 //  Manager and of geomety  classes for set: TPC                     //
20 //                                                                   //
21 //  !sectors are numbered from  0                                     //
22 //  !pad rows are numbered from 0                                     //
23 //  
24 //  12.6.   changed z relative 
25 //  Origin:  Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk // 
26 //                                                                   //  
27 ///////////////////////////////////////////////////////////////////////
28
29 //
30
31 #include <AliTPCParam.h>
32
33 #include <TGeoManager.h>
34 #include <TGeoPhysicalNode.h>
35 #include <TString.h>
36 #include "AliAlignObj.h"
37 #include "AliAlignObjParams.h"
38 #include "AliLog.h"
39 #include "TGraphErrors.h"
40 #include "AliTPCcalibDB.h"
41 #include "AliTPCROC.h"
42 #include "AliMathBase.h"
43
44 TObjArray *AliTPCParam::fBBParam = 0;
45
46 ClassImp(AliTPCParam)
47
48
49 //___________________________________________
50 AliTPCParam::AliTPCParam()
51             :AliDetectorParam(),
52              fbStatus(kFALSE),
53              fInnerRadiusLow(0.),
54              fInnerRadiusUp(0.),
55              fOuterRadiusUp(0.),
56              fOuterRadiusLow(0.),
57              fInnerAngle(0.),
58              fInnerAngleShift(0.),
59              fOuterAngle(0.),
60              fOuterAngleShift(0.),
61              fInnerFrameSpace(0.),
62              fOuterFrameSpace(0.),
63              fInnerWireMount(0.),
64              fOuterWireMount(0.),
65              fNInnerSector(0),
66              fNOuterSector(0),
67              fNSector(0),
68              fZLength(0),
69              fRotAngle(),
70              fGeometryType(0),
71              fTrackingMatrix(0),
72              fClusterMatrix(0), 
73              fGlobalMatrix(0),
74              fNInnerWiresPerPad(0),
75              fInnerWWPitch(0),
76              fInnerDummyWire(0),
77              fInnerOffWire(0.),
78              fRInnerFirstWire(0.),
79              fRInnerLastWire(0.),
80              fLastWireUp1(0.),
81              fNOuter1WiresPerPad(0),
82              fNOuter2WiresPerPad(0),
83              fOuterWWPitch(0.),
84              fOuterDummyWire(0),
85              fOuterOffWire(0.),
86              fROuterFirstWire(0.),
87              fROuterLastWire(0.),
88              fInnerPadPitchLength(0.),
89              fInnerPadPitchWidth(0.),
90              fInnerPadLength(0.),
91              fInnerPadWidth(0.),
92              fOuter1PadPitchLength(0.),
93              fOuter2PadPitchLength(0.),
94              fOuterPadPitchWidth(0.),
95              fOuter1PadLength(0.),
96              fOuter2PadLength(0.),
97              fOuterPadWidth(0.),
98              fBMWPCReadout(kFALSE),
99              fNCrossRows(0),
100              fNRowLow(0),
101              fNRowUp1(0),
102              fNRowUp2(0),
103              fNRowUp(0),
104              fNtRows(0),
105              fDiffT(0.),
106              fDiffL(0.),
107              fGasGain(0.),
108              fDriftV(0.),
109              fOmegaTau(0.),
110              fAttCoef(0.),
111              fOxyCont(0.),
112              fFpot(0.),
113              fNprim(0.),
114              fNtot(0.),
115              fWmean(0.),
116              fExp(0.),
117              fEend(0.),
118              fBetheBloch(0x0),
119              fGainSlopesHV(0),   // graph with the gain slope as function of HV - per chamber
120              fGainSlopesPT(0),   // graph with the gain slope as function of P/T - per chamber
121              fPadCoupling(0.),
122              fZeroSup(0),
123              fNoise(0.),
124              fChipGain(0.),
125              fChipNorm(0.),
126              fTSample(0.),
127              fZWidth(0.),
128              fTSigma(0.),
129              fMaxTBin(0),
130              fADCSat(0),
131              fADCDynRange(0.),
132              fTotalNormFac(0.),
133              fNoiseNormFac(0.),
134              fNominalVoltage(),
135              fMaxVoltageDeviation(40.),
136              fMaxDipVoltage(2.),
137              fMaxHVfractionBad(.4),
138              fVoltageDipScanPeriod(1.),
139              fNResponseMax(0),
140              fResponseThreshold(0.),
141              fCurrentMax(0),
142              fResponseBin(0),
143              fResponseWeight(0),
144              fGateDelay(0.),
145              fL1Delay(0.),
146              fNTBinsBeforeL1(0),
147              fNTBinsL1(0.)   
148 {   
149   //
150   //constructor sets the default parameters
151   //
152
153   SetTitle("75x40_100x60_150x60");
154   SetDefault();  
155   if (!fBBParam) fBBParam= new TObjArray(1000);
156 }
157
158 AliTPCParam::~AliTPCParam()
159 {
160   //
161   //destructor deletes some dynamicaly alocated variables
162   //
163
164   if (fResponseBin!=0)    delete [] fResponseBin;
165   if (fResponseWeight!=0) delete [] fResponseWeight;
166   if (fRotAngle      !=0) delete [] fRotAngle;
167
168   CleanGeoMatrices();
169
170 }
171
172 Int_t  AliTPCParam::Transform0to1(Float_t *xyz, Int_t * index)  const
173 {
174   //
175   // calculates sector number (index[1], undefined on input)
176   // xyz intact
177   //
178
179   Float_t angle,x1;
180   Int_t sector;
181   Float_t r = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
182   if ((xyz[0]==0)&&(xyz[1]==0)) angle = 0.;
183   else
184     {
185       angle =TMath::ASin(xyz[1]/r);
186       if   (xyz[0]<0)   angle=TMath::Pi()-angle;
187       if ( (xyz[0]>0) && (xyz[1]<0) ) angle=2*TMath::Pi()+angle;
188     }
189
190   sector=Int_t(TMath::Nint((angle-fInnerAngleShift)/fInnerAngle));      
191  
192   Float_t cos,sin;
193   AdjustCosSin(sector,cos,sin);
194   x1=xyz[0]*cos + xyz[1]*sin;
195
196   if (x1>fOuterRadiusLow)
197     {
198       sector=Int_t(TMath::Nint((angle-fOuterAngleShift)/fOuterAngle))+fNInnerSector;      
199       if (xyz[2]<0)     sector+=(fNOuterSector>>1);            
200     }
201     else   
202       if (xyz[2]<0) sector+=(fNInnerSector>>1);  
203   if (sector<0 || sector>=fNSector) AliError(Form("Wrong sector %d",sector));
204   index[1]=sector; // calculated sector number
205   index[0]=1; // indicates system after transformation
206   return sector;
207 }
208
209 Bool_t  AliTPCParam::Transform(Float_t */*xyz*/, Int_t *index, Int_t* /*oindex*/)
210 {
211   //transformation from input coodination system to output coordination system
212   switch (index[0]){
213   case 0:
214     break;
215   };
216
217   return kFALSE;
218
219 }
220
221 Int_t AliTPCParam::GetPadRow(Float_t *xyz, Int_t *index) const 
222 {
223   //
224   //calculates pad row of point xyz - transformation to system 8 (digit system)
225   //
226   Int_t system = index[0];
227   if (0==system) {
228     Transform0to1(xyz,index); 
229     system=1;
230   }
231   if (1==system) {
232     Transform1to2(xyz,index); 
233     system=2;
234   }
235     
236   if (fGeometryType==0){ //straight row    
237     if (2==system) {
238       Transform2to3(xyz,index);       
239       system=3;
240     } 
241     if (3==system) {
242       Transform3to4(xyz,index);
243       system=4; 
244     }
245     if (4==system) {
246       Transform4to8(xyz,index);
247       system=8;     
248     }
249     if (8==system) {
250       index[0]=8;
251       return index[2];
252     } 
253   }
254
255   if (fGeometryType==1){ //cylindrical geometry    
256     if (2==system) {
257       Transform2to5(xyz,index);       
258       system=5;
259     } 
260     if (5==system) {
261       Transform2to3(xyz,index);
262       system=6;
263     }
264     if (6==system) {
265       Transform3to4(xyz,index); 
266       system=7;
267     }
268     if (8==system) {
269       index[0]=8;
270       return index[2];
271     }
272   } 
273   index[0]=system;
274   return -1; //if no reasonable system     
275 }
276
277 void  AliTPCParam::SetSectorAngles(Float_t innerangle, Float_t innershift, Float_t outerangle,
278                         Float_t outershift)
279 {
280   //
281   // set opening angles  
282   static const  Float_t  kDegtoRad = 0.01745329251994;
283   fInnerAngle = innerangle;       //opening angle of Inner sector
284   fInnerAngleShift = innershift;  //shift of first inner sector center to the 0
285   fOuterAngle = outerangle;       //opening angle of outer sector
286   fOuterAngleShift = outershift;  //shift of first sector center to the 0  
287   fInnerAngle *=kDegtoRad;
288   fInnerAngleShift *=kDegtoRad;
289   fOuterAngle *=kDegtoRad;
290   fOuterAngleShift *=kDegtoRad;
291 }
292
293 Float_t  AliTPCParam::GetInnerAngle() const
294 {
295   //return angle 
296   return fInnerAngle;
297
298 }
299
300 Float_t  AliTPCParam::GetInnerAngleShift() const
301 {  
302   //return angle   
303   return fInnerAngleShift;  
304 }
305 Float_t  AliTPCParam::GetOuterAngle() const
306
307   //return angle 
308   return fOuterAngle;
309
310 Float_t  AliTPCParam::GetOuterAngleShift() const
311
312   //return angle 
313
314      return fOuterAngleShift;
315
316
317
318 Int_t AliTPCParam::GetIndex(Int_t sector, Int_t row) const
319 {
320   //
321   //give index of the given sector and pad row 
322   //no control if the sectors and rows  are reasonable !!!
323   //
324   if (sector<fNInnerSector) return sector*fNRowLow+row;
325   return (fNInnerSector*fNRowLow)+(sector-fNInnerSector)*fNRowUp+row;  
326 }
327
328 Bool_t   AliTPCParam::AdjustSectorRow(Int_t index, Int_t & sector, Int_t &row) const
329 {
330   //
331   //return sector and padrow for given index
332   //if index is reasonable returns true else return false
333   //
334   if ( (index<0) || (index>fNtRows))  return kFALSE;
335   Int_t outindex = fNInnerSector*fNRowLow;
336   if (index<outindex) {
337     sector = index/fNRowLow;
338     row    = index - sector*fNRowLow;
339     return kTRUE;
340   }
341   index-= outindex;
342   sector = index/fNRowUp;
343   row    = index - sector*fNRowUp;
344   sector += fNInnerSector;
345   return kTRUE;         
346
347
348 void AliTPCParam::SetDefault()
349 {
350   //
351   //set default parameters
352   //
353   //const static  Int_t kMaxRows=600; 
354   //
355   //sector default parameters
356   //
357   static const  Float_t kInnerRadiusLow = 83.65;
358   static const  Float_t kInnerRadiusUp  = 133.3;
359   static const  Float_t kOuterRadiusLow = 133.5;
360   static const  Float_t kOuterRadiusUp  = 247.7;
361   static const  Float_t kInnerAngle = 20; // 20 degrees
362   static const  Float_t kInnerAngleShift = 10;
363   static const  Float_t kOuterAngle = 20; //  20 degrees
364   static const  Float_t kOuterAngleShift = 10;
365   static const  Float_t kInnerFrameSpace = 1.5;
366   static const  Float_t kOuterFrameSpace = 1.5;
367   static const  Float_t kInnerWireMount = 1.2;
368   static const  Float_t kOuterWireMount = 1.4;
369   static const  Float_t kZLength =250.;
370   static const  Int_t   kGeometryType = 0; //straight rows 
371   static const Int_t kNRowLow = 63;
372   static const Int_t kNRowUp1 = 64;
373   static const Int_t kNRowUp2 = 32;
374   static const Int_t  kNRowUp = 96;
375   //
376   //wires default parameters
377   //
378   static const Int_t    kNInnerWiresPerPad = 3;
379   static const Int_t    kInnerDummyWire = 2;
380   static const Float_t  kInnerWWPitch = 0.25;
381   static const Float_t  kRInnerFirstWire = 84.475;
382   static const Float_t  kRInnerLastWire = 132.475;
383   static const Float_t  kInnerOffWire = 0.5;
384   static const Int_t    kNOuter1WiresPerPad = 4;
385   static const Int_t    kNOuter2WiresPerPad = 6;
386   static const Float_t  kOuterWWPitch = 0.25;  
387   static const Float_t  kROuterFirstWire = 134.225;
388   static const Float_t  kROuterLastWire = 246.975;
389   static const Int_t    kOuterDummyWire = 2;
390   static const Float_t  kOuterOffWire = 0.5;
391   //
392   //pad default parameters
393   // 
394   static const Float_t  kInnerPadPitchLength = 0.75;
395   static const Float_t  kInnerPadPitchWidth = 0.40;
396   static const Float_t  kInnerPadLength = 0.75;
397   static const Float_t  kInnerPadWidth = 0.40;
398   static const Float_t  kOuter1PadPitchLength = 1.0;
399   static const Float_t  kOuterPadPitchWidth = 0.6;
400   static const Float_t  kOuter1PadLength = 1.0;
401   static const Float_t  kOuterPadWidth = 0.6;
402   static const Float_t  kOuter2PadPitchLength = 1.5;
403   static const Float_t  kOuter2PadLength = 1.5;
404
405   static const Bool_t   kBMWPCReadout = kTRUE; //MWPC readout - another possibility GEM 
406   static const Int_t    kNCrossRows = 1; //number of rows to cross-talk
407   
408   //
409   //gas default parameters
410   //
411   static const  Float_t  kDiffT = 2.2e-2; 
412   static const  Float_t  kDiffL = 2.2e-2;
413   static const  Float_t  kGasGain = 2.e4;
414   static const  Float_t  kDriftV  =2.83e6;
415   static const  Float_t  kOmegaTau = 0.145;
416   static const  Float_t  kAttCoef = 250.;
417   static const  Float_t  kOxyCont = 5.e-6;
418   static const  Float_t  kFpot = 22.77e-9;
419   static const  Float_t  kNprim=14.35;
420   static const  Float_t  kNtot=42.66;
421   static const  Float_t  kWmean = 35.97e-9;
422   static const  Float_t  kExp = 2.2;
423   static const  Float_t  kEend = 10.e-6; 
424   //
425   //electronic default parameters
426   //
427   static const  Float_t  kPadCoupling=0.5;
428   static const  Int_t    kZeroSup=2;
429   static const  Float_t  kNoise = 1000;                            
430   static const  Float_t  kChipGain = 12;
431   static const  Float_t  kChipNorm = 0.4;
432   static const  Float_t  kTSample = 2.e-7; 
433   static const  Float_t  kTFWHM   = 1.9e-7;  //fwhm of charge distribution
434   static const  Int_t    kMaxTBin =445;  
435   static const  Int_t    kADCSat  =1024;  
436   static const  Float_t  kADCDynRange =2000.;  
437   // 
438   //response constants
439   //
440   static const Int_t     kNResponseMax=100;
441   static const Float_t   kResponseThreshold=0.01;     
442   //L1 constants
443   //  static const Float_t   kGateDelay=6.1e-6; //In s
444   static const Float_t   kGateDelay=0.; //For the moment no gating
445   //  static const Float_t   kL1Delay=6.5e-6; //In s
446   static const Float_t   kL1Delay=0.; //For the moment no delay
447   //  static const UShort_t  kNTBinsBeforeL1=14;
448   static const UShort_t  kNTBinsBeforeL1=0; //For the moment no shift
449   fbStatus = kFALSE;
450   //
451   //set sector parameters
452   //
453   SetInnerRadiusLow(kInnerRadiusLow);
454   SetOuterRadiusLow(kOuterRadiusLow);
455   SetInnerRadiusUp(kInnerRadiusUp);
456   SetOuterRadiusUp(kOuterRadiusUp);
457   SetInnerFrameSpace(kInnerFrameSpace);
458   SetOuterFrameSpace(kOuterFrameSpace);
459   SetInnerWireMount(kInnerWireMount);
460   SetOuterWireMount(kOuterWireMount);
461   SetSectorAngles(kInnerAngle,kInnerAngleShift,kOuterAngle,kOuterAngleShift);
462   SetZLength(kZLength);
463   SetGeometryType(kGeometryType);
464   SetRowNLow(kNRowLow);
465   SetRowNUp1 (kNRowUp1);
466   SetRowNUp2(kNRowUp2);
467   SetRowNUp(kNRowUp);
468   //
469   //set wire parameters
470   //
471   SetInnerNWires(kNInnerWiresPerPad);
472   SetInnerDummyWire(kInnerDummyWire);
473   SetInnerOffWire(kInnerOffWire);
474   SetOuter1NWires(kNOuter1WiresPerPad);
475   SetOuter2NWire(kNOuter2WiresPerPad);
476   SetOuterDummyWire(kOuterDummyWire);
477   SetOuterOffWire(kOuterOffWire);
478   SetInnerWWPitch(kInnerWWPitch);
479   SetRInnerFirstWire(kRInnerFirstWire);
480   SetRInnerLastWire(kRInnerLastWire);
481   SetOuterWWPitch(kOuterWWPitch);
482   SetROuterFirstWire(kROuterFirstWire);
483   SetROuterLastWire(kROuterLastWire);  
484   //
485   //set pad parameter
486   //
487   SetInnerPadPitchLength(kInnerPadPitchLength);
488   SetInnerPadPitchWidth(kInnerPadPitchWidth);
489   SetInnerPadLength(kInnerPadLength);
490   SetInnerPadWidth(kInnerPadWidth);
491   SetOuter1PadPitchLength(kOuter1PadPitchLength); 
492   SetOuter2PadPitchLength(kOuter2PadPitchLength);
493   SetOuterPadPitchWidth(kOuterPadPitchWidth);
494   SetOuter1PadLength(kOuter1PadLength);
495   SetOuter2PadLength(kOuter2PadLength);
496   SetOuterPadWidth(kOuterPadWidth); 
497   SetMWPCReadout(kBMWPCReadout);
498   SetNCrossRows(kNCrossRows);
499   //
500   //set gas paremeters
501   //
502   SetDiffT(kDiffT);
503   SetDiffL(kDiffL);
504   SetGasGain(kGasGain);
505   SetDriftV(kDriftV);
506   SetOmegaTau(kOmegaTau);
507   SetAttCoef(kAttCoef);
508   SetOxyCont(kOxyCont);
509   SetFpot(kFpot);
510   SetNprim(kNprim);
511   SetNtot(kNtot);
512   SetWmean(kWmean);
513   SetExp(kExp);
514   SetEend(kEend);
515   //
516   SetComposition(0.9,0.,0.1,0.,0.,0.);// Ne-CO2 90/10
517   //
518   SetBetheBloch(GetBetheBlochParamAlice());
519   //
520   //set electronivc parameters  
521   //
522   SetPadCoupling(kPadCoupling);
523   SetZeroSup(kZeroSup);
524   SetNoise(kNoise);
525   SetChipGain(kChipGain);
526   SetChipNorm(kChipNorm);   
527   SetTSample(kTSample);
528   SetTFWHM(kTFWHM);
529   SetMaxTBin(kMaxTBin);
530   SetADCSat(kADCSat);
531   SetADCDynRange(kADCDynRange);
532   for (UInt_t i=0; i<36; i++)
533   {
534     SetNominalVoltage(1196.0, i);
535   }
536   for (UInt_t i=36; i<72; i++)
537   {
538     SetNominalVoltage(1417.0, i);
539   }
540 //   //set magnetic field
541 //   SetBField(kBField);
542 //   SetNPrimLoss(kNPrimLoss);
543 //   SetNTotalLoss(kNTotalLoss);
544   //
545   //set response  parameters  
546   //
547   SetNResponseMax(kNResponseMax); 
548   SetResponseThreshold(static_cast<int>(kResponseThreshold));
549   //L1 data
550   SetGateDelay(kGateDelay);
551   SetL1Delay(kL1Delay);
552   SetNTBinsBeforeL1(kNTBinsBeforeL1);
553   SetNominalGainSlopes();
554 }
555
556           
557 Bool_t AliTPCParam::Update()
558 {
559   //
560   // update some calculated parameter which must be updated after changing "base"
561   // parameters 
562   // for example we can change size of pads and according this recalculate number
563   // of pad rows, number of of pads in given row ....
564   //
565   const Float_t kQel = 1.602e-19; // elementary charge
566   fbStatus = kFALSE;
567
568   Int_t i,j;  //loop variables because HP 
569   //-----------------Sector section------------------------------------------
570   //calclulate number of sectors
571   fNInnerSector = Int_t(4*TMath::Pi()/fInnerAngle+0.2); 
572        // number of inner sectors - factor 0.2 to don't be influnced by inprecision
573   if (fNInnerSector%2) return kFALSE;
574   fNOuterSector = Int_t(4*TMath::Pi()/fOuterAngle+0.2); 
575   if (fNOuterSector%2) return kFALSE;
576   fNSector  = fNInnerSector+fNOuterSector;
577
578   if (fRotAngle!=0) delete [] fRotAngle;
579   fRotAngle = new Float_t[4*fNSector];
580   //calculate sin and cosine of rotations angle     
581   //sectors angles numbering from 0
582
583   j=fNInnerSector*2;
584   Float_t angle = fInnerAngleShift; 
585   for (i=0; j<fNInnerSector*4; i+=4, j+=4 , angle +=fInnerAngle){
586     fRotAngle[i]=TMath::Cos(angle);
587     fRotAngle[i+1]=TMath::Sin(angle);
588     fRotAngle[j] =  fRotAngle[i];
589     fRotAngle[j+1] =  fRotAngle[i+1];
590     fRotAngle[i+2] =angle;
591     fRotAngle[j+2] =angle;    
592   }
593   angle = fOuterAngleShift; 
594   j=(fNInnerSector+fNOuterSector/2)*4;
595   for (i=fNInnerSector*4; j<fNSector*4; i+=4,j+=4, angle +=fOuterAngle){
596     fRotAngle[i]=TMath::Cos(angle);
597     fRotAngle[i+1]=TMath::Sin(angle);
598     fRotAngle[j] =  fRotAngle[i];
599     fRotAngle[j+1] =  fRotAngle[i+1];
600     fRotAngle[i+2] =angle;
601     fRotAngle[j+2] =angle;    
602   }
603
604   fZWidth = fTSample*fDriftV;  
605   fTotalNormFac = fPadCoupling*fChipNorm*kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
606   fNoiseNormFac = kQel*1.e15*fChipGain*fADCSat/fADCDynRange;
607   //wire section 
608   /*  Int_t nwire;
609   Float_t wspace; //available space for wire
610   Float_t dummyspace; //dummyspace for wire
611  
612   wspace =fInnerRadiusUp-fInnerRadiusLow-2*fInnerOffWire;
613   nwire = Int_t(wspace/fInnerWWPitch);
614   wspace = Float_t(nwire)*fInnerWWPitch;
615   dummyspace =(fInnerRadiusUp-fInnerRadiusLow-wspace)/2.;  
616   wspace =fOuterRadiusUp-fOuterRadiusLow-2*fOuterOffWire;
617   nwire = Int_t(wspace/fOuterWWPitch);
618   wspace = Float_t(nwire)*fOuterWWPitch;
619   dummyspace =(fOuterRadiusUp-fOuterRadiusLow-wspace)/2.; 
620   fROuterFirstWire = fOuterRadiusLow+dummyspace;
621   fROuterLastWire = fROuterFirstWire+fOuterWWPitch*(Float_t)(nwire);
622   */
623   
624   //
625   //response data
626   //
627   if (fResponseBin) delete [] fResponseBin;
628   if (fResponseWeight) delete [] fResponseWeight;
629   fResponseBin    = new Int_t[3*fNResponseMax];
630   fResponseWeight = new Float_t[fNResponseMax];
631
632   //L1 data
633   fNTBinsL1 = fL1Delay/fTSample - (Float_t)fNTBinsBeforeL1;
634   fbStatus = kTRUE;
635   return kTRUE;
636 }
637
638 void AliTPCParam::CleanGeoMatrices(){
639   //
640   // clean geo matrices
641   //
642
643   if (fTrackingMatrix) {
644     for(Int_t i = 0; i < fNSector; i++)
645       delete fTrackingMatrix[i];
646     delete [] fTrackingMatrix;
647   }
648   
649   if (fClusterMatrix) {
650     for(Int_t i = 0; i < fNSector; i++)
651       delete fClusterMatrix[i];
652     delete [] fClusterMatrix;
653   }
654   
655   if (fGlobalMatrix) {
656     for(Int_t i = 0; i < fNSector; i++)
657       delete fGlobalMatrix[i];
658     delete [] fGlobalMatrix;
659   }
660   
661   return;
662 }
663
664 Bool_t AliTPCParam::ReadGeoMatrices(){
665   //
666   // read geo matrixes
667   //
668   if (!gGeoManager){
669     AliFatal("Geo manager not initialized\n");
670   }
671   AliAlignObjParams o;
672   //
673
674   // clean geo matrices
675   CleanGeoMatrices();
676
677   // create new geo matrices
678   fTrackingMatrix = new TGeoHMatrix*[fNSector];
679   fClusterMatrix = new TGeoHMatrix*[fNSector];
680   fGlobalMatrix = new TGeoHMatrix*[fNSector];
681   for (Int_t isec=0; isec<fNSector; isec++) {
682     fGlobalMatrix[isec] = 0;
683     fClusterMatrix[isec]= 0;
684     fTrackingMatrix[isec]=0;
685   }   
686   //
687   for (Int_t isec=0; isec<fNSector; isec++) {
688     fGlobalMatrix[isec] = 0;
689     fClusterMatrix[isec]= 0;
690     fTrackingMatrix[isec]=0;   
691     AliGeomManager::ELayerID iLayer;
692     Int_t iModule;
693
694     if(isec<fNInnerSector) {
695       iLayer = AliGeomManager::kTPC1;
696       iModule = isec;
697     }
698     else {
699       iLayer = AliGeomManager::kTPC2;
700       iModule = isec - fNInnerSector;
701     }
702
703     UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,iModule);
704     TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID(volid);
705     if(!pne)
706     {
707       AliError(Form("Alignable entry for volume ID %d not in geometry. Exiting!",volid));
708       return kFALSE;
709     }
710     const char *path = pne->GetTitle();
711     if (!gGeoManager->cd(path)) return kFALSE;
712     TGeoHMatrix *m = gGeoManager->GetCurrentMatrix();
713     // Since GEANT4 does not allow reflections, in this case the reflection
714     // component if the matrix is embedded by TGeo inside TGeoScaledShape
715     if (gGeoManager->GetCurrentVolume()->GetShape()->IsReflected()) 
716        m->ReflectZ(kFALSE, kTRUE);
717     //
718     TGeoRotation mchange; 
719     mchange.RotateY(90); mchange.RotateX(90);
720     Float_t ROCcenter[3]; 
721     GetChamberCenter(isec,ROCcenter);
722     //
723     // Convert to global coordinate system
724     //
725     fGlobalMatrix[isec] = new TGeoHMatrix(*m);
726     fGlobalMatrix[isec]->Multiply(&(mchange.Inverse()));
727     TGeoTranslation center("center",-ROCcenter[0],-ROCcenter[1],-ROCcenter[2]);
728     fGlobalMatrix[isec]->Multiply(&center);
729     //
730     //  cluster correction matrix
731     //
732     fClusterMatrix[isec] = new TGeoHMatrix;
733     Double_t sectorAngle = 20.*(isec%18)+10;
734     TGeoHMatrix  rotMatrix;
735     rotMatrix.RotateZ(sectorAngle);
736     if (GetGlobalMatrix(isec)->GetTranslation()[2]>0){
737       //
738       // mirrored system 
739       //
740       TGeoRotation mirrorZ;
741       mirrorZ.SetAngles(90,0,90,90,180,0);
742       fClusterMatrix[isec]->Multiply(&mirrorZ);
743     }
744     TGeoTranslation trans(0,0,GetZLength(isec));
745     fClusterMatrix[isec]->MultiplyLeft(&trans);
746     fClusterMatrix[isec]->MultiplyLeft((GetGlobalMatrix(isec)));        
747     fClusterMatrix[isec]->MultiplyLeft(&(rotMatrix.Inverse()));
748   }
749   return kTRUE;
750 }
751
752 TGeoHMatrix *  AliTPCParam::Tracking2LocalMatrix(const TGeoHMatrix * geoMatrix, Int_t sector) const{
753   //
754   // make local to tracking matrix
755   //
756   Double_t sectorAngle = 20.*(sector%18)+10;
757   TGeoHMatrix *newMatrix = new TGeoHMatrix();
758   newMatrix->RotateZ(sectorAngle);
759   newMatrix->MultiplyLeft(&(geoMatrix->Inverse()));
760   return newMatrix;
761 }
762
763
764
765
766 Bool_t AliTPCParam::GetStatus() const
767 {
768   //get information about object consistency
769   return fbStatus;
770 }
771
772 Int_t AliTPCParam::GetNRowLow() const
773 {
774   //get the number of pad rows in low sector
775   return fNRowLow;
776 }
777 Int_t AliTPCParam::GetNRowUp() const
778 {
779   //get the number of pad rows in up sector
780   return fNRowUp;
781 }
782 Int_t AliTPCParam::GetNRowUp1() const
783 {
784   //get the number of pad rows in up1 sector
785   return fNRowUp1;
786 }
787 Int_t AliTPCParam::GetNRowUp2() const
788 {
789   //get the number of pad rows in up2 sector
790   return fNRowUp2;
791 }
792 Float_t AliTPCParam::GetPadRowRadiiLow(Int_t irow) const
793 {
794   //get the pad row (irow) radii
795   if ( !(irow<0) && (irow<fNRowLow) ) 
796     return  fPadRowLow[irow];
797   else
798     return 0;
799 }
800
801 Float_t AliTPCParam::GetPadRowRadiiUp(Int_t irow) const
802 {
803   //get the pad row (irow) radii
804  if ( !(irow<0) && (irow<fNRowUp) ) 
805     return  fPadRowUp[irow];
806   else
807     return 0;
808 }
809
810 Int_t AliTPCParam::GetNPadsLow(Int_t irow) const
811 {
812   //get the number of pads in row irow
813   if ( !(irow<0) && (irow<fNRowLow) ) 
814     return  fNPadsLow[irow];
815   else
816     return 0;
817 }
818
819
820 Int_t AliTPCParam::GetNPadsUp(Int_t irow) const
821 {
822   //get the number of pads in row irow
823   if ( !(irow<0) && (irow<fNRowUp) ) 
824     return  fNPadsUp[irow];
825   else
826     return 0;
827 }
828
829 Int_t AliTPCParam::GetWireSegment(Int_t sector, Int_t row) const
830 {
831   //
832   // Get Anode wire segment index IROC --> 4 segments in [0,3], 7 segments OROC[4,10]
833   // 
834   // To  be speed-up using caching lookup table
835   //
836   Int_t wireIndex = -1;  
837   // check if the given set of sector and row is OK
838   if ( (sector<0 || sector>=72) || (row<0 || row>95) || (sector<36 && row>64) ){
839     AliError("No matching anode wire segment for this set of sector-row \n");
840     return wireIndex;
841   }  
842   // find the wire index for given sector-row
843   if ( sector<36 ){                               // IROC anode wire segments 
844     if (row<16) wireIndex=0;
845     else if (row>=16 && row<32) wireIndex=1;
846     else if (row>=32 && row<48) wireIndex=2;
847     else wireIndex=3;    
848   } else {                                        // OROC anode wire segments    
849     if (row<16) wireIndex=4;
850     else if ( row>=16 && row<32) wireIndex=5;
851     else if ( row>=32 && row<48) wireIndex=6;
852     else if ( row>=48 && row<64) wireIndex=7;
853     else if ( row>=64 && row<75) wireIndex=8;
854     else if ( row>=75 && row<85) wireIndex=9;
855     else wireIndex=10;
856   }    
857   return wireIndex;  
858 }
859
860 Int_t AliTPCParam::GetNPadsPerSegment(Int_t wireSegmentID) const
861 {
862   //
863   // Get the number of pads in a given anode wire segment
864   //
865   // check if the given segment index is OK 
866   // To be done (if needed) - cache the lookup table
867   //
868   if ( wireSegmentID<0 || wireSegmentID>10 ){
869     AliError("Wrong anode wire segment index. it should be [0,10] \n");
870     return -1;
871   }
872   // get sector type from wireSegmentID
873   Int_t sector = (wireSegmentID<4) ? 0 : 36; // ROC [0,35] --> IROC, ROC [36,71] --> OROC  
874   // get the upper and lower row number for the given wireSegmentID
875   Int_t segRowDown = 0;
876   Int_t segRowUp   = 0;
877   
878   if ( wireSegmentID == 0 || wireSegmentID == 4 ) {
879     segRowDown = 0;
880     segRowUp   = 16;
881   } else if ( wireSegmentID == 1 || wireSegmentID == 5 ) {
882     segRowDown = 16;
883     segRowUp   = 32;
884   } else if ( wireSegmentID == 2 || wireSegmentID == 6 ) {
885     segRowDown = 32;
886     segRowUp   = 48;
887   } else if ( wireSegmentID == 3 || wireSegmentID == 7 ) {
888     segRowDown = 48;
889     segRowUp   = 63;
890   } else if ( wireSegmentID == 8 ) {
891     segRowDown = 64;
892     segRowUp   = 75;
893   } else if ( wireSegmentID == 9 ) {
894     segRowDown = 75;
895     segRowUp   = 85;
896   } else {
897     segRowDown = 85;
898     segRowUp   = 95;
899   }  
900   // count the number of pads on the given segment
901   AliTPCROC *r=AliTPCROC::Instance();
902   Int_t nPads=0;
903   for (Int_t irow = segRowDown; irow < segRowUp ; irow++){
904     nPads += r->GetNPads(sector,irow);
905   }
906   return nPads;
907 }
908
909 Float_t AliTPCParam::GetYInner(Int_t irow) const
910 {
911   return fYInner[irow];
912 }
913
914
915 Float_t AliTPCParam::GetYOuter(Int_t irow) const
916 {
917   return fYOuter[irow];
918 }
919
920 Int_t AliTPCParam::GetSectorIndex(Float_t angle, Int_t row, Float_t z) const
921 {
922   // returns the sector index
923   // takes as input the angle, index of the pad row and z position
924   if(row<0) return -1;
925
926   if (angle > 2.*TMath::Pi()) angle -= 2.*TMath::Pi();
927   if (angle < 0.            ) angle += 2.*TMath::Pi();
928  
929   Int_t sector;
930   if(row<fNRowLow) {
931     sector=Int_t(TMath::Nint((angle-fInnerAngleShift)/fInnerAngle));
932     if (z<0) sector += (fNInnerSector>>1);
933   }
934   else {
935     sector=Int_t(TMath::Nint((angle-fOuterAngleShift)/fOuterAngle))+fNInnerSector;      
936     if (z<0) sector += (fNOuterSector>>1);
937   }    
938   
939   return sector;
940 }
941
942 Float_t AliTPCParam::GetChamberCenter(Int_t isec, Float_t * center) const
943 {
944   // returns the default radial position
945   // of the readout chambers
946
947   const Float_t kROCcenterIn = 110.2;
948   const Float_t kROCcenterOut = 188.45;
949
950   if (isec<fNInnerSector){
951     if (center){
952       center[0] = kROCcenterIn;
953       center[1] = 0; 
954       center[2] = -5.51-0.08; 
955     }
956     return kROCcenterIn;
957   }
958   else{
959     if (center){
960       center[0] = kROCcenterOut;
961       center[1] = 0; 
962       center[2] = -5.61-0.08; 
963     }
964     return kROCcenterOut;
965   }
966 }
967
968 void AliTPCParam::SetNominalGainSlopes(){
969   //
970   // Setting the nominal TPC gain slopes 
971   // Nominal values were obtained as a mena values foe 2010,2011, and 2012 data
972   // Differntial values can be provided per year
973   //
974   Float_t sector[72]={0};
975   Float_t gainHV[72]={0};
976   Float_t gainPT[72]={0};
977   //
978   for (Int_t isec=0; isec<72; isec++){
979     sector[isec]=isec;
980     gainHV[isec]=0.0115;  // change of the Gain dG/G  per 1 Volt  of voltage change(1/V) - it is roughly the same for IROC and OROC
981     gainPT[isec]=2.2;     // change of the Gains dG/G per P/T change ()
982   }
983   fGainSlopesHV = new TGraphErrors(72,sector,gainHV,0,0);
984   fGainSlopesPT = new TGraphErrors(72,sector,gainPT,0,0);
985   fGainSlopesHV->SetName("GainSlopesHV");
986   fGainSlopesPT->SetName("GainSlopesPT");
987 }
988
989
990 TVectorD * AliTPCParam::GetBetheBlochParamNa49(){
991   //
992   //  Parameters of the BB for the Aleph parametrization AliMathBase::BetheBlochAleph
993   //  Na49 parameters were used as first set of parameters for ALICE simulation
994   //  (see TPC TDR for details)
995   TVectorD v(5);
996   v(0)=0.76176e-1;
997   v(1)=10.632;
998   v(2)=0.13279e-4;
999   v(3)=1.8631;
1000   v(4)=1.9479;
1001   return new TVectorD(v);
1002 }
1003
1004 TVectorD * AliTPCParam::GetBetheBlochParamAlice(){
1005   //
1006   //
1007   //  Parameters of the BB for the Aleph parametrization AliMathBase::BetheBlochAleph
1008   //  Na49 parameters were used as first set of parameters for ALICE simulation
1009   //  Second set was obtained from ALICE 2009-2013 data taking 
1010   //  (see TPC TDR for details)
1011   //  
1012   TVectorD v(5);
1013   v[0] = 0.0851148;
1014   v[1] = 9.25771;
1015   v[2] = 2.6558e-05;
1016   v[3] = 2.32742;
1017   v[4] = 1.83039;
1018   return new TVectorD(v);
1019 }
1020
1021
1022 Double_t  AliTPCParam::BetheBlochAleph(Double_t bg, Int_t type){
1023   //
1024   //  GetBetheBloch retur values for the parametrs regieter at poition type 
1025   //  Used for visualization and comparison purposes
1026   TVectorD * paramBB =0;
1027   if (type==0) {
1028     AliTPCParam* param = AliTPCcalibDB::Instance()->GetParameters();
1029     if (param) paramBB=param->GetBetheBlochParameters();
1030   } 
1031   if (type>0){
1032     paramBB = (TVectorD*)fBBParam->At(type);
1033   }
1034   if (!paramBB) return 0;
1035   //
1036   return AliMathBase::BetheBlochAleph(bg,(*paramBB)(0),(*paramBB)(1),(*paramBB)(2),(*paramBB)(3),(*paramBB)(4)); 
1037 }
1038
1039
1040 void AliTPCParam::RegisterBBParam(TVectorD* param, Int_t position){
1041   //
1042   // 
1043   //
1044   fBBParam->AddAt(param,position);
1045 }