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