Fixes for building of DA (Anshul)
[u/mrichter/AliRoot.git] / TPC / AliTPCseed.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
18
19 //-----------------------------------------------------------------
20 //           Implementation of the TPC seed class
21 //        This class is used by the AliTPCtrackerMI class
22 //      Origin: Marian Ivanov, CERN, Marian.Ivanov@cern.ch
23 //-----------------------------------------------------------------
24 #include "TClonesArray.h"
25 #include "TGraphErrors.h"
26 #include "AliTPCseed.h"
27 #include "AliTPCReconstructor.h"
28 #include "AliTPCClusterParam.h"
29 #include "AliTPCCalPad.h"
30 #include "AliTPCCalROC.h"
31 #include "AliTPCcalibDB.h"
32 #include "AliTPCParam.h"
33 #include "AliMathBase.h"
34 #include "AliTPCTransform.h"
35 #include "AliSplineFit.h"
36 #include "AliCDBManager.h"
37 #include "AliTPCcalibDButil.h"
38
39
40 ClassImp(AliTPCseed)
41
42
43
44 AliTPCseed::AliTPCseed():
45   AliTPCtrack(),
46   fEsd(0x0),
47   fClusterOwner(kFALSE),
48   fRow(0),
49   fSector(-1),
50   fRelativeSector(-1),
51   fCurrentSigmaY2(1e10),
52   fCurrentSigmaZ2(1e10),
53   fCMeanSigmaY2p30(-1.),   //! current mean sigma Y2 - mean30%
54   fCMeanSigmaZ2p30(-1.),   //! current mean sigma Z2 - mean30%
55   fCMeanSigmaY2p30R(-1.),   //! current mean sigma Y2 - mean2%
56   fCMeanSigmaZ2p30R(-1.),   //! current mean sigma Z2 - mean2%
57   //
58   fErrorY2(1e10),
59   fErrorZ2(1e10),
60   fCurrentCluster(0x0),
61   fCurrentClusterIndex1(-1),
62   fInDead(kFALSE),
63   fIsSeeding(kFALSE),
64   fNoCluster(0),
65   fSort(0),
66   fBSigned(kFALSE),
67   fSeedType(0),
68   fSeed1(-1),
69   fSeed2(-1),
70   fMAngular(0),
71   fCircular(0),
72   fClusterMap(159),
73   fSharedMap(159)
74 {
75   //
76   for (Int_t i=0;i<160;i++) SetClusterIndex2(i,-3);
77   for (Int_t i=0;i<160;i++) fClusterPointer[i]=0;
78   for (Int_t i=0;i<3;i++)   fKinkIndexes[i]=0;
79   for (Int_t i=0;i<AliPID::kSPECIES;i++)   fTPCr[i]=0.2;
80   for (Int_t i=0;i<4;i++) {
81     fDEDX[i] = 0.;
82     fSDEDX[i] = 1e10;
83     fNCDEDX[i] = 0;
84   }
85   for (Int_t i=0;i<12;i++) fOverlapLabels[i] = -1;
86   //  for (Int_t i=0;i<160;i++) fClusterMap[i]=kFALSE;
87   //for (Int_t i=0;i<160;i++) fSharedMap[i]=kFALSE;
88   fClusterMap.ResetAllBits(kFALSE);
89   fSharedMap.ResetAllBits(kFALSE);
90
91 }
92
93 AliTPCseed::AliTPCseed(const AliTPCseed &s, Bool_t clusterOwner):
94   AliTPCtrack(s),
95   fEsd(0x0),
96   fClusterOwner(clusterOwner),
97   fRow(0),
98   fSector(-1),
99   fRelativeSector(-1),
100   fCurrentSigmaY2(-1),
101   fCurrentSigmaZ2(-1),
102   fCMeanSigmaY2p30(-1.),   //! current mean sigma Y2 - mean30%
103   fCMeanSigmaZ2p30(-1.),   //! current mean sigma Z2 - mean30%
104   fCMeanSigmaY2p30R(-1.),   //! current mean sigma Y2 - mean2%
105   fCMeanSigmaZ2p30R(-1.),   //! current mean sigma Z2 - mean2%
106   fErrorY2(1e10),
107   fErrorZ2(1e10),
108   fCurrentCluster(0x0),
109   fCurrentClusterIndex1(-1),
110   fInDead(kFALSE),
111   fIsSeeding(kFALSE),
112   fNoCluster(0),
113   fSort(0),
114   fBSigned(kFALSE),
115   fSeedType(0),
116   fSeed1(-1),
117   fSeed2(-1),
118   fMAngular(0),
119   fCircular(0),
120   fClusterMap(s.fClusterMap),
121   fSharedMap(s.fSharedMap)
122 {
123   //---------------------
124   // dummy copy constructor
125   //-------------------------
126   for (Int_t i=0;i<160;i++) {
127     fClusterPointer[i]=0;
128     if (fClusterOwner){
129       if (s.fClusterPointer[i])
130         fClusterPointer[i] = new AliTPCclusterMI(*(s.fClusterPointer[i]));
131     }else{
132       fClusterPointer[i] = s.fClusterPointer[i];
133     }
134     fTrackPoints[i] = s.fTrackPoints[i];
135   }
136   for (Int_t i=0;i<160;i++) fIndex[i] = s.fIndex[i];
137   for (Int_t i=0;i<AliPID::kSPECIES;i++)   fTPCr[i]=s.fTPCr[i];
138   for (Int_t i=0;i<4;i++) {
139     fDEDX[i] = s.fDEDX[i];
140     fSDEDX[i] = s.fSDEDX[i];
141     fNCDEDX[i] = s.fNCDEDX[i];
142   }
143   for (Int_t i=0;i<12;i++) fOverlapLabels[i] = s.fOverlapLabels[i];
144
145 }
146
147
148 AliTPCseed::AliTPCseed(const AliTPCtrack &t):
149   AliTPCtrack(t),
150   fEsd(0x0),
151   fClusterOwner(kFALSE),
152   fRow(0),
153   fSector(-1),
154   fRelativeSector(-1),
155   fCurrentSigmaY2(-1),
156   fCurrentSigmaZ2(-1),
157   fCMeanSigmaY2p30(-1.),   //! current mean sigma Y2 - mean30%
158   fCMeanSigmaZ2p30(-1.),   //! current mean sigma Z2 - mean30%
159   fCMeanSigmaY2p30R(-1.),   //! current mean sigma Y2 - mean2%
160   fCMeanSigmaZ2p30R(-1.),   //! current mean sigma Z2 - mean2%
161   fErrorY2(1e10),
162   fErrorZ2(1e10),
163   fCurrentCluster(0x0),
164   fCurrentClusterIndex1(-1),
165   fInDead(kFALSE),
166   fIsSeeding(kFALSE),
167   fNoCluster(0),
168   fSort(0),
169   fBSigned(kFALSE),
170   fSeedType(0),
171   fSeed1(-1),
172   fSeed2(-1),
173   fMAngular(0),
174   fCircular(0),
175   fClusterMap(159),
176   fSharedMap(159)
177 {
178   //
179   // Constructor from AliTPCtrack
180   //
181   fFirstPoint =0;
182   for (Int_t i=0;i<5;i++)   fTPCr[i]=0.2;
183   for (Int_t i=0;i<160;i++) {
184     fClusterPointer[i] = 0;
185     Int_t index = t.GetClusterIndex(i);
186     if (index>=-1){ 
187       SetClusterIndex2(i,index);
188     }
189     else{
190       SetClusterIndex2(i,-3); 
191     }    
192   }
193   for (Int_t i=0;i<4;i++) {
194     fDEDX[i] = 0.;
195     fSDEDX[i] = 1e10;
196     fNCDEDX[i] = 0;
197   }
198   for (Int_t i=0;i<12;i++) fOverlapLabels[i] = -1;
199   
200   //for (Int_t i=0;i<160;i++) fClusterMap[i]=kFALSE;
201   //for (Int_t i=0;i<160;i++) fSharedMap[i]=kFALSE;
202   fClusterMap.ResetAllBits(kFALSE);
203   fSharedMap.ResetAllBits(kFALSE);
204
205 }
206
207 AliTPCseed::AliTPCseed(Double_t xr, Double_t alpha, const Double_t xx[5],
208                        const Double_t cc[15], Int_t index):      
209   AliTPCtrack(xr, alpha, xx, cc, index),
210   fEsd(0x0),
211   fClusterOwner(kFALSE),
212   fRow(0),
213   fSector(-1),
214   fRelativeSector(-1),
215   fCurrentSigmaY2(-1),
216   fCurrentSigmaZ2(-1),
217   fCMeanSigmaY2p30(-1.),   //! current mean sigma Y2 - mean30%
218   fCMeanSigmaZ2p30(-1.),   //! current mean sigma Z2 - mean30%
219   fCMeanSigmaY2p30R(-1.),   //! current mean sigma Y2 - mean2%
220   fCMeanSigmaZ2p30R(-1.),   //! current mean sigma Z2 - mean2%
221   fErrorY2(1e10),
222   fErrorZ2(1e10),
223   fCurrentCluster(0x0),
224   fCurrentClusterIndex1(-1),
225   fInDead(kFALSE),
226   fIsSeeding(kFALSE),
227   fNoCluster(0),
228   fSort(0),
229   fBSigned(kFALSE),
230   fSeedType(0),
231   fSeed1(-1),
232   fSeed2(-1),
233   fMAngular(0),
234   fCircular(0),
235   fClusterMap(159),
236   fSharedMap(159)
237 {
238   //
239   // Constructor
240   //
241   fFirstPoint =0;
242   for (Int_t i=0;i<160;i++) SetClusterIndex2(i,-3);
243   for (Int_t i=0;i<160;i++) fClusterPointer[i]=0;
244   for (Int_t i=0;i<5;i++)   fTPCr[i]=0.2;
245   for (Int_t i=0;i<4;i++) {
246     fDEDX[i] = 0.;
247     fSDEDX[i] = 1e10;
248     fNCDEDX[i] = 0;
249   }
250   for (Int_t i=0;i<12;i++) fOverlapLabels[i] = -1;
251 }
252
253 AliTPCseed::~AliTPCseed(){
254   //
255   // destructor
256   fNoCluster =0;
257   if (fClusterOwner){
258     for (Int_t icluster=0; icluster<160; icluster++){
259       delete fClusterPointer[icluster];
260     }
261   }
262
263 }
264 //_________________________________________________
265 AliTPCseed & AliTPCseed::operator=(const AliTPCseed &param)
266 {
267   //
268   // assignment operator 
269   //
270   if(this!=&param){
271     AliTPCtrack::operator=(param);
272     fEsd =param.fEsd; 
273     for(Int_t i = 0;i<160;++i)fClusterPointer[i] = param.fClusterPointer[i]; // this is not allocated by AliTPCSeed
274     fClusterOwner = param.fClusterOwner;
275     // leave out fPoint, they are also not copied in the copy ctor...
276     // but deleted in the dtor... strange...
277     fRow            = param.fRow;
278     fSector         = param.fSector;
279     fRelativeSector = param.fRelativeSector;
280     fCurrentSigmaY2 = param.fCurrentSigmaY2;
281     fCurrentSigmaZ2 = param.fCurrentSigmaZ2;
282     fErrorY2        = param.fErrorY2;
283     fErrorZ2        = param.fErrorZ2;
284     fCurrentCluster = param.fCurrentCluster; // this is not allocated by AliTPCSeed
285     fCurrentClusterIndex1 = param.fCurrentClusterIndex1; 
286     fInDead         = param.fInDead;
287     fIsSeeding      = param.fIsSeeding;
288     fNoCluster      = param.fNoCluster;
289     fSort           = param.fSort;
290     fBSigned        = param.fBSigned;
291     for(Int_t i = 0;i<4;++i){
292       fDEDX[i]   = param.fDEDX[i];
293       fSDEDX[i]  = param.fSDEDX[i];
294       fNCDEDX[i] = param.fNCDEDX[i];
295     }
296     for(Int_t i = 0;i<AliPID::kSPECIES;++i)fTPCr[i] = param.fTPCr[i];
297     
298     fSeedType = param.fSeedType;
299     fSeed1    = param.fSeed1;
300     fSeed2    = param.fSeed2;
301     for(Int_t i = 0;i<12;++i)fOverlapLabels[i] = param.fOverlapLabels[i];
302     fMAngular = param.fMAngular;
303     fCircular = param.fCircular;
304     for(int i = 0;i<160;++i)fTrackPoints[i] =  param.fTrackPoints[i];
305     fClusterMap = param.fClusterMap;
306     fSharedMap = param.fSharedMap;
307   }
308   return (*this);
309 }
310 //____________________________________________________
311 AliTPCTrackerPoint * AliTPCseed::GetTrackPoint(Int_t i)
312 {
313   //
314   // 
315   return &fTrackPoints[i];
316 }
317
318
319
320 Double_t AliTPCseed::GetDensityFirst(Int_t n)
321 {
322   //
323   //
324   // return cluster for n rows bellow first point
325   Int_t nfoundable = 1;
326   Int_t nfound      = 1;
327   for (Int_t i=fLastPoint-1;i>0&&nfoundable<n; i--){
328     Int_t index = GetClusterIndex2(i);
329     if (index!=-1) nfoundable++;
330     if (index>0) nfound++;
331   }
332   if (nfoundable<n) return 0;
333   return Double_t(nfound)/Double_t(nfoundable);
334
335 }
336
337
338 void AliTPCseed::GetClusterStatistic(Int_t first, Int_t last, Int_t &found, Int_t &foundable, Int_t &shared, Bool_t plus2)
339 {
340   // get cluster stat.  on given region
341   //
342   found       = 0;
343   foundable   = 0;
344   shared      =0;
345   for (Int_t i=first;i<last; i++){
346     Int_t index = GetClusterIndex2(i);
347     if (index!=-1) foundable++;
348     if (index&0x8000) continue;
349     if (fClusterPointer[i]) {
350       found++;
351     }
352     else 
353       continue;
354
355     if (fClusterPointer[i]->IsUsed(10)) {
356       shared++;
357       continue;
358     }
359     if (!plus2) continue; //take also neighborhoud
360     //
361     if ( (i>0) && fClusterPointer[i-1]){
362       if (fClusterPointer[i-1]->IsUsed(10)) {
363         shared++;
364         continue;
365       }
366     }
367     if ( fClusterPointer[i+1]){
368       if (fClusterPointer[i+1]->IsUsed(10)) {
369         shared++;
370         continue;
371       }
372     }
373     
374   }
375   //if (shared>found){
376     //Error("AliTPCseed::GetClusterStatistic","problem\n");
377   //}
378 }
379
380
381
382
383
384 void AliTPCseed::Reset(Bool_t all)
385 {
386   //
387   //
388   SetNumberOfClusters(0);
389   fNFoundable = 0;
390   SetChi2(0);
391   ResetCovariance(10.);
392   /*
393   if (fTrackPoints){
394     for (Int_t i=0;i<8;i++){
395       delete [] fTrackPoints[i];
396     }
397     delete fTrackPoints;
398     fTrackPoints =0;
399   }
400   */
401
402   if (all){   
403     for (Int_t i=0;i<200;i++) SetClusterIndex2(i,-3);
404     for (Int_t i=0;i<160;i++) fClusterPointer[i]=0;
405   }
406
407 }
408
409
410 void AliTPCseed::Modify(Double_t factor)
411 {
412
413   //------------------------------------------------------------------
414   //This function makes a track forget its history :)  
415   //------------------------------------------------------------------
416   if (factor<=0) {
417     ResetCovariance(10.);
418     return;
419   }
420   ResetCovariance(factor);
421
422   SetNumberOfClusters(0);
423   fNFoundable =0;
424   SetChi2(0);
425   fRemoval = 0;
426   fCurrentSigmaY2 = 0.000005;
427   fCurrentSigmaZ2 = 0.000005;
428   fNoCluster     = 0;
429   //fFirstPoint = 160;
430   //fLastPoint  = 0;
431 }
432
433
434
435
436 Int_t  AliTPCseed::GetProlongation(Double_t xk, Double_t &y, Double_t & z) const
437 {
438   //-----------------------------------------------------------------
439   // This function find proloncation of a track to a reference plane x=xk.
440   // doesn't change internal state of the track
441   //-----------------------------------------------------------------
442   
443   Double_t x1=GetX(), x2=x1+(xk-x1), dx=x2-x1;
444
445   if (TMath::Abs(GetSnp()+GetC()*dx) >= AliTPCReconstructor::GetMaxSnpTrack()) {   
446     return 0;
447   }
448
449   //  Double_t y1=fP0, z1=fP1;
450   Double_t c1=GetSnp(), r1=sqrt((1.-c1)*(1.+c1));
451   Double_t c2=c1 + GetC()*dx, r2=sqrt((1.-c2)*(1.+c2));
452   
453   y = GetY();
454   z = GetZ();
455   //y += dx*(c1+c2)/(r1+r2);
456   //z += dx*(c1+c2)/(c1*r2 + c2*r1)*fP3;
457   
458   Double_t dy = dx*(c1+c2)/(r1+r2);
459   Double_t dz = 0;
460   //
461   Double_t delta = GetC()*dx*(c1+c2)/(c1*r2 + c2*r1);
462   /*
463   if (TMath::Abs(delta)>0.0001){
464     dz = fP3*TMath::ASin(delta)/fP4;
465   }else{
466     dz = dx*fP3*(c1+c2)/(c1*r2 + c2*r1);
467   }
468   */
469   //  dz =  fP3*AliTPCFastMath::FastAsin(delta)/fP4;
470   dz =  GetTgl()*TMath::ASin(delta)/GetC();
471   //
472   y+=dy;
473   z+=dz;
474   
475
476   return 1;  
477 }
478
479
480 //_____________________________________________________________________________
481 Double_t AliTPCseed::GetPredictedChi2(const AliCluster *c) const 
482 {
483   //-----------------------------------------------------------------
484   // This function calculates a predicted chi2 increment.
485   //-----------------------------------------------------------------
486   Double_t p[2]={c->GetY(), c->GetZ()};
487   Double_t cov[3]={fErrorY2, 0., fErrorZ2};
488
489   Float_t dx = ((AliTPCclusterMI*)c)->GetX()-GetX();
490   if (TMath::Abs(dx)>0){
491     Float_t ty = TMath::Tan(TMath::ASin(GetSnp()));
492     Float_t dy = dx*ty;
493     Float_t dz = dx*TMath::Sqrt(1.+ty*ty)*GetTgl();
494     p[0] = c->GetY()-dy;  
495     p[1] = c->GetZ()-dz;  
496   }
497   return AliExternalTrackParam::GetPredictedChi2(p,cov);
498 }
499
500 //_________________________________________________________________________________________
501
502
503 Int_t AliTPCseed::Compare(const TObject *o) const {
504   //-----------------------------------------------------------------
505   // This function compares tracks according to the sector - for given sector according z
506   //-----------------------------------------------------------------
507   AliTPCseed *t=(AliTPCseed*)o;
508
509   if (fSort == 0){
510     if (t->fRelativeSector>fRelativeSector) return -1;
511     if (t->fRelativeSector<fRelativeSector) return 1;
512     Double_t z2 = t->GetZ();
513     Double_t z1 = GetZ();
514     if (z2>z1) return 1;
515     if (z2<z1) return -1;
516     return 0;
517   }
518   else {
519     Float_t f2 =1;
520     f2 = 1-20*TMath::Sqrt(t->GetSigma1Pt2())/(t->OneOverPt()+0.0066);
521     if (t->fBConstrain) f2=1.2;
522
523     Float_t f1 =1;
524     f1 = 1-20*TMath::Sqrt(GetSigma1Pt2())/(OneOverPt()+0.0066);
525
526     if (fBConstrain)   f1=1.2;
527  
528     if (t->GetNumberOfClusters()*f2 <GetNumberOfClusters()*f1) return -1;
529     else return +1;
530   }
531 }
532
533
534
535
536 //_____________________________________________________________________________
537 Bool_t AliTPCseed::Update(const AliCluster *c, Double_t chisq, Int_t index)
538 {
539   //-----------------------------------------------------------------
540   // This function associates a cluster with this track.
541   //-----------------------------------------------------------------
542   Int_t n=GetNumberOfClusters();
543   Int_t idx=GetClusterIndex(n);    // save the current cluster index
544
545   AliCluster cl(*c);  cl.SetSigmaY2(fErrorY2); cl.SetSigmaZ2(fErrorZ2);
546   Float_t dx = ((AliTPCclusterMI*)c)->GetX()-GetX();
547   if (TMath::Abs(dx)>0){
548     Float_t ty = TMath::Tan(TMath::ASin(GetSnp()));
549     Float_t dy = dx*ty;
550     Float_t dz = dx*TMath::Sqrt(1.+ty*ty)*GetTgl();
551     cl.SetY(c->GetY()-dy);  
552     cl.SetZ(c->GetZ()-dz);  
553   }
554
555   if (!AliTPCtrack::Update(&cl,chisq,index)) return kFALSE;
556   
557   if (fCMeanSigmaY2p30<0){
558     fCMeanSigmaY2p30= c->GetSigmaY2();   //! current mean sigma Y2 - mean30%
559     fCMeanSigmaZ2p30= c->GetSigmaZ2();   //! current mean sigma Z2 - mean30%    
560     fCMeanSigmaY2p30R = 1;   //! current mean sigma Y2 - mean5%
561     fCMeanSigmaZ2p30R = 1;   //! current mean sigma Z2 - mean5%
562   }
563   //
564   fCMeanSigmaY2p30= 0.70*fCMeanSigmaY2p30 +0.30*c->GetSigmaY2();   
565   fCMeanSigmaZ2p30= 0.70*fCMeanSigmaZ2p30 +0.30*c->GetSigmaZ2();  
566   if (fCurrentSigmaY2>0){
567     fCMeanSigmaY2p30R = 0.7*fCMeanSigmaY2p30R  +0.3*c->GetSigmaY2()/fCurrentSigmaY2;  
568     fCMeanSigmaZ2p30R = 0.7*fCMeanSigmaZ2p30R  +0.3*c->GetSigmaZ2()/fCurrentSigmaZ2;   
569   }
570
571
572   SetClusterIndex(n,idx);          // restore the current cluster index
573   return kTRUE;
574 }
575
576
577
578 //_____________________________________________________________________________
579 Float_t AliTPCseed::CookdEdx(Double_t low, Double_t up,Int_t i1, Int_t i2, Bool_t /* onlyused */) {
580   //-----------------------------------------------------------------
581   // This funtion calculates dE/dX within the "low" and "up" cuts.
582   //-----------------------------------------------------------------
583   // CookdEdxAnalytical(Double_t low, Double_t up, Int_t type, Int_t i1, Int_t i2, Int_t returnVal)
584   AliTPCParam *param = AliTPCcalibDB::Instance()->GetParameters();
585   
586   Int_t row0 = param->GetNRowLow();
587   Int_t row1 = row0+param->GetNRowUp1();
588   Int_t row2 = row1+param->GetNRowUp2();
589   const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
590   Int_t useTot = 0;
591   if (recoParam) useTot = (recoParam->GetUseTotCharge())? 0:1;
592   //
593   //
594   //
595   fDEDX[0]      = CookdEdxAnalytical(low,up,useTot ,i1  ,i2,   0);
596   fDEDX[1]      = CookdEdxAnalytical(low,up,useTot ,0   ,row0, 0);
597   fDEDX[2]      = CookdEdxAnalytical(low,up,useTot ,row0,row1, 0);
598   fDEDX[3]      = CookdEdxAnalytical(low,up,useTot ,row1,row2, 0);
599   //
600   fSDEDX[0]     = CookdEdxAnalytical(low,up,useTot ,i1  ,i2,   1);
601   fSDEDX[1]     = CookdEdxAnalytical(low,up,useTot ,0   ,row0, 1);
602   fSDEDX[2]     = CookdEdxAnalytical(low,up,useTot ,row0,row1, 1);
603   fSDEDX[3]     = CookdEdxAnalytical(low,up,useTot ,row1,row2, 1);
604   //
605   fNCDEDX[0]    = TMath::Nint(CookdEdxAnalytical(low,up,useTot ,i1  ,i2,   2));
606   fNCDEDX[1]    = TMath::Nint(CookdEdxAnalytical(low,up,useTot ,0   ,row0, 2));
607   fNCDEDX[2]    = TMath::Nint(CookdEdxAnalytical(low,up,useTot ,row0,row1, 2));
608   fNCDEDX[3]    = TMath::Nint(CookdEdxAnalytical(low,up,useTot ,row1,row2, 2));
609
610   SetdEdx(fDEDX[0]);
611   return fDEDX[0];
612
613 //  return CookdEdxNorm(low,up,0,i1,i2,1,0,2);
614
615
616 //   Float_t amp[200];
617 //   Float_t angular[200];
618 //   Float_t weight[200];
619 //   Int_t index[200];
620 //   //Int_t nc = 0;
621 //   Float_t meanlog = 100.;
622   
623 //   Float_t mean[4]  = {0,0,0,0};
624 //   Float_t sigma[4] = {1000,1000,1000,1000};
625 //   Int_t nc[4]      = {0,0,0,0};
626 //   Float_t norm[4]    = {1000,1000,1000,1000};
627 //   //
628 //   //
629 //   fNShared =0;
630
631 //   Float_t gainGG = 1;
632 //   if (AliTPCcalibDB::Instance()->GetParameters()){
633 //     gainGG= AliTPCcalibDB::Instance()->GetParameters()->GetGasGain()/20000.;  //relative gas gain
634 //   }
635
636
637 //   for (Int_t of =0; of<4; of++){    
638 //     for (Int_t i=of+i1;i<i2;i+=4)
639 //       {
640 //      Int_t clindex = fIndex[i];
641 //      if (clindex<0||clindex&0x8000) continue;
642
643 //      //AliTPCTrackPoint * point = (AliTPCTrackPoint *) arr.At(i);
644 //      AliTPCTrackerPoint * point = GetTrackPoint(i);
645 //      //AliTPCTrackerPoint * pointm = GetTrackPoint(i-1);
646 //      //AliTPCTrackerPoint * pointp = 0;
647 //      //if (i<159) pointp = GetTrackPoint(i+1);
648
649 //      if (point==0) continue;
650 //      AliTPCclusterMI * cl = fClusterPointer[i];
651 //      if (cl==0) continue;    
652 //      if (onlyused && (!cl->IsUsed(10))) continue;
653 //      if (cl->IsUsed(11)) {
654 //        fNShared++;
655 //        continue;
656 //      }
657 //      Int_t   type   = cl->GetType();
658 //      //if (point->fIsShared){
659 //      //  fNShared++;
660 //      //  continue;
661 //      //}
662 //      //if (pointm) 
663 //      //  if (pointm->fIsShared) continue;
664 //      //if (pointp) 
665 //      //  if (pointp->fIsShared) continue;
666
667 //      if (type<0) continue;
668 //      //if (type>10) continue;       
669 //      //if (point->GetErrY()==0) continue;
670 //      //if (point->GetErrZ()==0) continue;
671
672 //      //Float_t ddy = (point->GetY()-cl->GetY())/point->GetErrY();
673 //      //Float_t ddz = (point->GetZ()-cl->GetZ())/point->GetErrZ();
674 //      //if ((ddy*ddy+ddz*ddz)>10) continue; 
675
676
677 //      //      if (point->GetCPoint().GetMax()<5) continue;
678 //      if (cl->GetMax()<5) continue;
679 //      Float_t angley = point->GetAngleY();
680 //      Float_t anglez = point->GetAngleZ();
681
682 //      Float_t rsigmay2 =  point->GetSigmaY();
683 //      Float_t rsigmaz2 =  point->GetSigmaZ();
684 //      /*
685 //      Float_t ns = 1.;
686 //      if (pointm){
687 //        rsigmay +=  pointm->GetTPoint().GetSigmaY();
688 //        rsigmaz +=  pointm->GetTPoint().GetSigmaZ();
689 //        ns+=1.;
690 //      }
691 //      if (pointp){
692 //        rsigmay +=  pointp->GetTPoint().GetSigmaY();
693 //        rsigmaz +=  pointp->GetTPoint().GetSigmaZ();
694 //        ns+=1.;
695 //      }
696 //      rsigmay/=ns;
697 //      rsigmaz/=ns;
698 //      */
699
700 //      Float_t rsigma = TMath::Sqrt(rsigmay2*rsigmaz2);
701
702 //      Float_t ampc   = 0;     // normalization to the number of electrons
703 //      if (i>64){
704 //        //      ampc = 1.*point->GetCPoint().GetMax();
705 //        ampc = 1.*cl->GetMax();
706 //        //ampc = 1.*point->GetCPoint().GetQ();          
707 //        //      AliTPCClusterPoint & p = point->GetCPoint();
708 //        //      Float_t dy = TMath::Abs(Int_t( TMath::Abs(p.GetY()/0.6)) - TMath::Abs(p.GetY()/0.6)+0.5);
709 //        // Float_t iz =  (250.0-TMath::Abs(p.GetZ())+0.11)/0.566;
710 //        //Float_t dz = 
711 //        //  TMath::Abs( Int_t(iz) - iz + 0.5);
712 //        //ampc *= 1.15*(1-0.3*dy);
713 //        //ampc *= 1.15*(1-0.3*dz);
714 //        //      Float_t zfactor = (AliTPCReconstructor::GetCtgRange()-0.0004*TMath::Abs(point->GetCPoint().GetZ()));
715 //        //ampc               *=zfactor; 
716 //      }
717 //      else{ 
718 //        //ampc = 1.0*point->GetCPoint().GetMax(); 
719 //        ampc = 1.0*cl->GetMax(); 
720 //        //ampc = 1.0*point->GetCPoint().GetQ(); 
721 //        //AliTPCClusterPoint & p = point->GetCPoint();
722 //        // Float_t dy = TMath::Abs(Int_t( TMath::Abs(p.GetY()/0.4)) - TMath::Abs(p.GetY()/0.4)+0.5);
723 //        //Float_t iz =  (250.0-TMath::Abs(p.GetZ())+0.11)/0.566;
724 //        //Float_t dz = 
725 //        //  TMath::Abs( Int_t(iz) - iz + 0.5);
726
727 //        //ampc *= 1.15*(1-0.3*dy);
728 //        //ampc *= 1.15*(1-0.3*dz);
729 //        //    Float_t zfactor = (1.02-0.000*TMath::Abs(point->GetCPoint().GetZ()));
730 //        //ampc               *=zfactor; 
731
732 //      }
733 //      ampc *= 2.0;     // put mean value to channel 50
734 //      //ampc *= 0.58;     // put mean value to channel 50
735 //      Float_t w      =  1.;
736 //      //      if (type>0)  w =  1./(type/2.-0.5); 
737 //      //      Float_t z = TMath::Abs(cl->GetZ());
738 //      if (i<64) {
739 //        ampc /= 0.6;
740 //        //ampc /= (1+0.0008*z);
741 //      } else
742 //        if (i>128){
743 //          ampc /=1.5;
744 //          //ampc /= (1+0.0008*z);
745 //        }else{
746 //          //ampc /= (1+0.0008*z);
747 //        }
748         
749 //      if (type<0) {  //amp at the border - lower weight
750 //        // w*= 2.;
751           
752 //        continue;
753 //      }
754 //      if (rsigma>1.5) ampc/=1.3;  // if big backround
755 //      amp[nc[of]]        = ampc;
756 //      amp[nc[of]]       /=gainGG;
757 //      angular[nc[of]]    = TMath::Sqrt(1.+angley*angley+anglez*anglez);
758 //      weight[nc[of]]     = w;
759 //      nc[of]++;
760 //       }
761     
762 //     TMath::Sort(nc[of],amp,index,kFALSE);
763 //     Float_t sumamp=0;
764 //     Float_t sumamp2=0;
765 //     Float_t sumw=0;
766 //     //meanlog = amp[index[Int_t(nc[of]*0.33)]];
767 //     meanlog = 50;
768 //     for (Int_t i=int(nc[of]*low+0.5);i<int(nc[of]*up+0.5);i++){
769 //       Float_t ampl      = amp[index[i]]/angular[index[i]];
770 //       ampl              = meanlog*TMath::Log(1.+ampl/meanlog);
771 //       //
772 //       sumw    += weight[index[i]]; 
773 //       sumamp  += weight[index[i]]*ampl;
774 //       sumamp2 += weight[index[i]]*ampl*ampl;
775 //       norm[of]    += angular[index[i]]*weight[index[i]];
776 //     }
777 //     if (sumw<1){ 
778 //       SetdEdx(0);  
779 //     }
780 //     else {
781 //       norm[of] /= sumw;
782 //       mean[of]  = sumamp/sumw;
783 //       sigma[of] = sumamp2/sumw-mean[of]*mean[of];
784 //       if (sigma[of]>0.1) 
785 //      sigma[of] = TMath::Sqrt(sigma[of]);
786 //       else
787 //      sigma[of] = 1000;
788       
789 //     mean[of] = (TMath::Exp(mean[of]/meanlog)-1)*meanlog;
790 //     //mean  *=(1-0.02*(sigma/(mean*0.17)-1.));
791 //     //mean *=(1-0.1*(norm-1.));
792 //     }
793 //   }
794
795 //   Float_t dedx =0;
796 //   fSdEdx =0;
797 //   fMAngular =0;
798 //   //  mean[0]*= (1-0.05*(sigma[0]/(0.01+mean[1]*0.18)-1));
799 //   //  mean[1]*= (1-0.05*(sigma[1]/(0.01+mean[0]*0.18)-1));
800
801   
802 //   //  dedx = (mean[0]* TMath::Sqrt((1.+nc[0]))+ mean[1]* TMath::Sqrt((1.+nc[1])) )/ 
803 //   //  (  TMath::Sqrt((1.+nc[0]))+TMath::Sqrt((1.+nc[1])));
804
805 //   Int_t norm2 = 0;
806 //   Int_t norm3 = 0;
807 //   for (Int_t i =0;i<4;i++){
808 //     if (nc[i]>2&&nc[i]<1000){
809 //       dedx      += mean[i] *nc[i];
810 //       fSdEdx    += sigma[i]*(nc[i]-2);
811 //       fMAngular += norm[i] *nc[i];    
812 //       norm2     += nc[i];
813 //       norm3     += nc[i]-2;
814 //     }
815 //     fDEDX[i]  = mean[i];             
816 //     fSDEDX[i] = sigma[i];            
817 //     fNCDEDX[i]= nc[i]; 
818 //   }
819
820 //   if (norm3>0){
821 //     dedx   /=norm2;
822 //     fSdEdx /=norm3;
823 //     fMAngular/=norm2;
824 //   }
825 //   else{
826 //     SetdEdx(0);
827 //     return 0;
828 //   }
829 //   //  Float_t dedx1 =dedx;
830 //   /*
831 //   dedx =0;
832 //   for (Int_t i =0;i<4;i++){
833 //     if (nc[i]>2&&nc[i]<1000){
834 //       mean[i]   = mean[i]*(1-0.12*(sigma[i]/(fSdEdx)-1.));
835 //       dedx      += mean[i] *nc[i];
836 //     }
837 //     fDEDX[i]  = mean[i];                
838 //   }
839 //   dedx /= norm2;
840 //   */
841
842   
843 //   SetdEdx(dedx);
844 //   return dedx;
845 }
846
847 void AliTPCseed::CookPID()
848 {
849   //
850   // cook PID information according dEdx
851   //
852   Double_t fRange = 10.;
853   Double_t fRes   = 0.1;
854   Double_t fMIP   = 47.;
855   //
856   Int_t ns=AliPID::kSPECIES;
857   Double_t sumr =0;
858   for (Int_t j=0; j<ns; j++) {
859     Double_t mass=AliPID::ParticleMass(j);
860     Double_t mom=GetP();
861     Double_t dedx=fdEdx/fMIP;
862     Double_t bethe=AliMathBase::BetheBlochAleph(mom/mass); 
863     Double_t sigma=fRes*bethe;
864     if (sigma>0.001){
865       if (TMath::Abs(dedx-bethe) > fRange*sigma) {
866         fTPCr[j]=TMath::Exp(-0.5*fRange*fRange)/sigma;
867         sumr+=fTPCr[j];
868         continue;
869       }
870       fTPCr[j]=TMath::Exp(-0.5*(dedx-bethe)*(dedx-bethe)/(sigma*sigma))/sigma;
871       sumr+=fTPCr[j];
872     }
873     else{
874       fTPCr[j]=1.;
875       sumr+=fTPCr[j];
876     }
877   }
878   for (Int_t j=0; j<ns; j++) {
879     fTPCr[j]/=sumr;           //normalize
880   }
881 }
882
883 Double_t AliTPCseed::GetYat(Double_t xk) const {
884 //-----------------------------------------------------------------
885 // This function calculates the Y-coordinate of a track at the plane x=xk.
886 //-----------------------------------------------------------------
887   if (TMath::Abs(GetSnp())>AliTPCReconstructor::GetMaxSnpTrack()) return 0.; //patch 01 jan 06
888     Double_t c1=GetSnp(), r1=TMath::Sqrt((1.-c1)*(1.+c1));
889     Double_t c2=c1+GetC()*(xk-GetX());
890     if (TMath::Abs(c2)>AliTPCReconstructor::GetMaxSnpTrack()) return 0;
891     Double_t r2=TMath::Sqrt((1.-c2)*(1.+c2));
892     return GetY() + (xk-GetX())*(c1+c2)/(r1+r2);
893 }
894
895 void AliTPCseed::SetClusterMapBit(int ibit, Bool_t state)
896 {
897   fClusterMap[ibit] = state;
898 }
899 Bool_t AliTPCseed::GetClusterMapBit(int ibit)
900 {
901   return fClusterMap[ibit];
902 }
903 void AliTPCseed::SetSharedMapBit(int ibit, Bool_t state)
904 {
905   fSharedMap[ibit] = state;
906 }
907 Bool_t AliTPCseed::GetSharedMapBit(int ibit)
908 {
909   return fSharedMap[ibit];
910 }
911
912
913
914
915
916 Float_t  AliTPCseed::CookdEdxNorm(Double_t low, Double_t up, Int_t type, Int_t i1, Int_t i2, Bool_t shapeNorm,Int_t posNorm, Int_t padNorm, Int_t returnVal){
917  
918   //
919   // calculates dedx using the cluster
920   // low    -  up specify trunc mean range  - default form 0-0.7
921   // type   -  1 - max charge  or 0- total charge in cluster 
922   //           //2- max no corr 3- total+ correction
923   // i1-i2  -  the pad-row range used for calculation
924   // shapeNorm - kTRUE  -taken from OCDB
925   //           
926   // posNorm   - usage of pos normalization 
927   // padNorm   - pad type normalization
928   // returnVal - 0 return mean
929   //           - 1 return RMS
930   //           - 2 return number of clusters
931   //           
932   // normalization parametrization taken from AliTPCClusterParam
933   //
934   AliTPCClusterParam * parcl = AliTPCcalibDB::Instance()->GetClusterParam();
935   AliTPCParam * param = AliTPCcalibDB::Instance()->GetParameters();
936   if (!parcl)  return 0;
937   if (!param) return 0;
938   Int_t row0 = param->GetNRowLow();
939   Int_t row1 = row0+param->GetNRowUp1();
940
941   Float_t amp[160];
942   Int_t   indexes[160];
943   Int_t   ncl=0;
944   //
945   //
946   Float_t gainGG      = 1;  // gas gain factor -always enabled
947   Float_t gainPad     = 1;  // gain map  - used always
948   Float_t corrShape   = 1;  // correction due angular effect, diffusion and electron attachment
949   Float_t corrPos     = 1;  // local position correction - if posNorm enabled
950   Float_t corrPadType = 1;  // pad type correction - if padNorm enabled
951   Float_t corrNorm    = 1;  // normalization factor - set Q to channel 50
952   //   
953   //
954   //
955   if (AliTPCcalibDB::Instance()->GetParameters()){
956     gainGG= AliTPCcalibDB::Instance()->GetParameters()->GetGasGain()/20000;  //relative gas gain
957   }
958
959   const Float_t ktany = TMath::Tan(TMath::DegToRad()*10);
960   const Float_t kedgey =3.;
961   //
962   //
963   for (Int_t irow=i1; irow<i2; irow++){
964     AliTPCclusterMI* cluster = GetClusterPointer(irow);
965     if (!cluster) continue;
966     if (TMath::Abs(cluster->GetY())>cluster->GetX()*ktany-kedgey) continue; // edge cluster
967     Float_t charge= (type%2)? cluster->GetMax():cluster->GetQ();
968     Int_t  ipad= 0;
969     if (irow>=row0) ipad=1;
970     if (irow>=row1) ipad=2;    
971     //
972     //
973     //
974     AliTPCCalPad * gainMap =  AliTPCcalibDB::Instance()->GetDedxGainFactor();
975     if (gainMap) {
976       //
977       // Get gainPad - pad by pad calibration
978       //
979       Float_t factor = 1;      
980       AliTPCCalROC * roc = gainMap->GetCalROC(cluster->GetDetector());
981       if (irow < row0) { // IROC
982         factor = roc->GetValue(irow, TMath::Nint(cluster->GetPad()));
983       } else {         // OROC
984         factor = roc->GetValue(irow - row0, TMath::Nint(cluster->GetPad()));
985       }
986       if (factor>0.5) gainPad=factor;
987     }
988     //
989     //do position and angular normalization
990     //
991     if (shapeNorm){
992       if (type<=1){
993         //      
994         AliTPCTrackerPoint * point = GetTrackPoint(irow);
995         Float_t              ty = TMath::Abs(point->GetAngleY());
996         Float_t              tz = TMath::Abs(point->GetAngleZ()*TMath::Sqrt(1+ty*ty));
997         
998         Float_t dr    = (250.-TMath::Abs(cluster->GetZ()))/250.;
999         corrShape  = parcl->Qnorm(ipad,type,dr,ty,tz);
1000       }
1001     }
1002     
1003     if (posNorm>0){
1004       //
1005       // Do position normalization - relative distance to 
1006       // center of pad- time bin
1007       // Work in progress
1008       //      corrPos = parcl->QnormPos(ipad,type, cluster->GetPad(),
1009       //                                cluster->GetTimeBin(), cluster->GetZ(),
1010       //                                cluster->GetSigmaY2(),cluster->GetSigmaZ2(),
1011       //                                cluster->GetMax(),cluster->GetQ());
1012       // scaled response function
1013       Float_t yres0 = parcl->GetRMS0(0,ipad,0,0)/param->GetPadPitchWidth(cluster->GetDetector());
1014       Float_t zres0 = parcl->GetRMS0(1,ipad,0,0)/param->GetZWidth();
1015       //
1016       
1017       AliTPCTrackerPoint * point = GetTrackPoint(irow);
1018       Float_t              ty = TMath::Abs(point->GetAngleY());
1019       Float_t              tz = TMath::Abs(point->GetAngleZ()*TMath::Sqrt(1+ty*ty));
1020       
1021       if (type==1) corrPos = 
1022         parcl->QmaxCorrection(cluster->GetDetector(), cluster->GetRow(),cluster->GetPad(), 
1023                               cluster->GetTimeBin(),ty,tz,yres0,zres0,0.4);
1024       if (type==0) corrPos = 
1025         parcl->QtotCorrection(cluster->GetDetector(), cluster->GetRow(),cluster->GetPad(), 
1026                               cluster->GetTimeBin(),ty,tz,yres0,zres0,cluster->GetQ(),2.5,0.4);
1027       if (posNorm==3){
1028         Float_t dr    = (250.-TMath::Abs(cluster->GetZ()))/250.;
1029         Double_t signtgl = (cluster->GetZ()*point->GetAngleZ()>0)? 1:-1;
1030         Double_t p2 = TMath::Abs(TMath::Sin(TMath::ATan(ty)));
1031         Float_t corrHis = parcl->QnormHis(ipad,type,dr,p2,TMath::Abs(point->GetAngleZ())*signtgl);
1032         if (corrHis>0) corrPos*=corrHis;
1033       }
1034
1035     }
1036
1037     if (padNorm==1){
1038       //taken from OCDB
1039       if (type==0 && parcl->QpadTnorm()) corrPadType = (*parcl->QpadTnorm())[ipad];
1040       if (type==1 && parcl->QpadMnorm()) corrPadType = (*parcl->QpadMnorm())[ipad];
1041
1042     }
1043     if (padNorm==2){
1044       corrPadType  =param->GetPadPitchLength(cluster->GetDetector(),cluster->GetRow());
1045       //use hardwired - temp fix
1046       if (type==0) corrNorm=3.;
1047       if (type==1) corrNorm=1.;
1048     }
1049     //
1050     amp[ncl]=charge;
1051     amp[ncl]/=gainGG;
1052     amp[ncl]/=gainPad;
1053     amp[ncl]/=corrShape;
1054     amp[ncl]/=corrPadType;
1055     amp[ncl]/=corrPos;
1056     amp[ncl]/=corrNorm; 
1057     //
1058     ncl++;
1059   }
1060
1061   if (type>3) return ncl; 
1062   TMath::Sort(ncl,amp, indexes, kFALSE);
1063
1064   if (ncl<10) return 0;
1065   
1066   Float_t suma=0;
1067   Float_t suma2=0;  
1068   Float_t sumn=0;
1069   Int_t icl0=TMath::Nint(ncl*low);
1070   Int_t icl1=TMath::Nint(ncl*up);
1071   for (Int_t icl=icl0; icl<icl1;icl++){
1072     suma+=amp[indexes[icl]];
1073     suma2+=amp[indexes[icl]]*amp[indexes[icl]];
1074     sumn++;
1075   }
1076   Float_t mean =suma/sumn;
1077   Float_t rms  =TMath::Sqrt(TMath::Abs(suma2/sumn-mean*mean));
1078   //
1079   // do time-dependent correction for pressure and temperature variations
1080   UInt_t runNumber = 1;
1081   Float_t corrTimeGain = 1;
1082   AliTPCTransform * trans = AliTPCcalibDB::Instance()->GetTransform();
1083   const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
1084   if (trans && recoParam->GetUseGainCorrectionTime()>0) {
1085     runNumber = trans->GetCurrentRunNumber();
1086     //AliTPCcalibDB::Instance()->SetRun(runNumber);
1087     TObjArray * timeGainSplines = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(runNumber);
1088     if (timeGainSplines) {
1089       UInt_t time = trans->GetCurrentTimeStamp();
1090       AliSplineFit * fitMIP = (AliSplineFit *) timeGainSplines->At(0);
1091       AliSplineFit * fitFPcosmic = (AliSplineFit *) timeGainSplines->At(1);
1092       if (fitMIP) {
1093         corrTimeGain = AliTPCcalibDButil::EvalGraphConst(fitMIP, time);/*fitMIP->Eval(time);*/
1094       } else {
1095         if (fitFPcosmic) corrTimeGain = AliTPCcalibDButil::EvalGraphConst(fitFPcosmic, time);/*fitFPcosmic->Eval(time);*/ 
1096       }
1097     }
1098   }
1099   mean /= corrTimeGain;
1100   rms /= corrTimeGain;
1101   //
1102   if (returnVal==1) return rms;
1103   if (returnVal==2) return ncl;
1104   return mean;
1105 }
1106
1107 Float_t  AliTPCseed::CookdEdxAnalytical(Double_t low, Double_t up, Int_t type, Int_t i1, Int_t i2, Int_t returnVal, Int_t rowThres){
1108  
1109   //
1110   // calculates dedx using the cluster
1111   // low    -  up specify trunc mean range  - default form 0-0.7
1112   // type   -  1 - max charge  or 0- total charge in cluster 
1113   //           //2- max no corr 3- total+ correction
1114   // i1-i2  -  the pad-row range used for calculation
1115   //           
1116   // posNorm   - usage of pos normalization 
1117   // returnVal - 0 return mean
1118   //           - 1 return RMS
1119   //           - 2 return number of clusters
1120   //
1121   // rowThres  - number of rows before and after given pad row to check for clusters below threshold
1122   //           
1123   // normalization parametrization taken from AliTPCClusterParam
1124   //
1125   AliTPCClusterParam * parcl = AliTPCcalibDB::Instance()->GetClusterParam();
1126   AliTPCParam * param = AliTPCcalibDB::Instance()->GetParameters();
1127   if (!parcl)  return 0;
1128   if (!param) return 0;
1129   Int_t row0 = param->GetNRowLow();
1130   Int_t row1 = row0+param->GetNRowUp1();
1131
1132   Float_t amp[160];
1133   Int_t   indexes[160];
1134   Int_t   ncl=0;
1135   Int_t   nclBelowThr = 0; // counts number of clusters below threshold
1136   //
1137   //
1138   Float_t gainGG      = 1;  // gas gain factor -always enabled
1139   Float_t gainPad     = 1;  // gain map  - used always
1140   Float_t corrPos     = 1;  // local position correction - if posNorm enabled
1141   //   
1142   //
1143   //
1144   if (AliTPCcalibDB::Instance()->GetParameters()){
1145     gainGG= AliTPCcalibDB::Instance()->GetParameters()->GetGasGain()/20000;  //relative gas gain
1146   }
1147   //
1148   // extract time-dependent correction for pressure and temperature variations
1149   //
1150   UInt_t runNumber = 1;
1151   Float_t corrTimeGain = 1;
1152   TObjArray * timeGainSplines = 0x0;
1153   TGraphErrors * grPadEqual = 0x0;
1154   //
1155   AliTPCTransform * trans = AliTPCcalibDB::Instance()->GetTransform();
1156   const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
1157   //
1158   if (recoParam->GetNeighborRowsDedx() == 0) rowThres = 0;
1159   //
1160   if (trans) {
1161       runNumber = trans->GetCurrentRunNumber();
1162       //AliTPCcalibDB::Instance()->SetRun(runNumber);
1163       timeGainSplines = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(runNumber);
1164       if (timeGainSplines && recoParam->GetUseGainCorrectionTime()>0) {
1165         UInt_t time = trans->GetCurrentTimeStamp();
1166         AliSplineFit * fitMIP = (AliSplineFit *) timeGainSplines->At(0);
1167         AliSplineFit * fitFPcosmic = (AliSplineFit *) timeGainSplines->At(1);
1168         if (fitMIP) {
1169           corrTimeGain =  AliTPCcalibDButil::EvalGraphConst(fitMIP, time); /*fitMIP->Eval(time);*/
1170         } else {
1171           if (fitFPcosmic) corrTimeGain = AliTPCcalibDButil::EvalGraphConst(fitFPcosmic, time); /*fitFPcosmic->Eval(time); */
1172         }
1173         //
1174         if (type==1) grPadEqual = (TGraphErrors * ) timeGainSplines->FindObject("TGRAPHERRORS_MEANQMAX_PADREGIONGAIN_BEAM_ALL");
1175         if (type==0) grPadEqual = (TGraphErrors * ) timeGainSplines->FindObject("TGRAPHERRORS_MEANQTOT_PADREGIONGAIN_BEAM_ALL");
1176       }
1177   }   
1178   
1179   const Float_t kClusterShapeCut = 1.5; // IMPPRTANT TO DO: move value to AliTPCRecoParam
1180   const Float_t ktany = TMath::Tan(TMath::DegToRad()*10);
1181   const Float_t kedgey =3.;
1182   //
1183   //
1184   for (Int_t irow=i1; irow<i2; irow++){
1185     AliTPCclusterMI* cluster = GetClusterPointer(irow);
1186     if (!cluster && irow > 1 && irow < 157) {
1187       Bool_t isClBefore = kFALSE;
1188       Bool_t isClAfter  = kFALSE;
1189       for(Int_t ithres = 1; ithres <= rowThres; ithres++) {
1190         AliTPCclusterMI * clusterBefore = GetClusterPointer(irow - ithres);
1191         if (clusterBefore) isClBefore = kTRUE;
1192         AliTPCclusterMI * clusterAfter  = GetClusterPointer(irow + ithres);
1193         if (clusterAfter) isClAfter = kTRUE;
1194       }
1195       if (isClBefore && isClAfter) nclBelowThr++;
1196     }
1197     if (!cluster) continue;
1198     //
1199     //
1200     if (TMath::Abs(cluster->GetY())>cluster->GetX()*ktany-kedgey) continue; // edge cluster
1201     //
1202     AliTPCTrackerPoint * point = GetTrackPoint(irow);
1203     if (point==0) continue;    
1204     Float_t rsigmay = TMath::Sqrt(point->GetSigmaY());
1205     if (rsigmay > kClusterShapeCut) continue;
1206     //
1207     if (cluster->IsUsed(11)) continue; // remove shared clusters for PbPb
1208     //
1209     Float_t charge= (type%2)? cluster->GetMax():cluster->GetQ();
1210     Int_t  ipad= 0;
1211     if (irow>=row0) ipad=1;
1212     if (irow>=row1) ipad=2;    
1213     //
1214     //
1215     //
1216     AliTPCCalPad * gainMap =  AliTPCcalibDB::Instance()->GetDedxGainFactor();
1217     if (gainMap) {
1218       //
1219       // Get gainPad - pad by pad calibration
1220       //
1221       Float_t factor = 1;      
1222       AliTPCCalROC * roc = gainMap->GetCalROC(cluster->GetDetector());
1223       if (irow < row0) { // IROC
1224         factor = roc->GetValue(irow, TMath::Nint(cluster->GetPad()));
1225       } else {         // OROC
1226         factor = roc->GetValue(irow - row0, TMath::Nint(cluster->GetPad()));
1227       }
1228       if (factor>0.3) gainPad=factor;
1229     }
1230     //
1231     // Do position normalization - relative distance to 
1232     // center of pad- time bin
1233     
1234     Float_t              ty = TMath::Abs(point->GetAngleY());
1235     Float_t              tz = TMath::Abs(point->GetAngleZ()*TMath::Sqrt(1+ty*ty));
1236     Float_t yres0 = parcl->GetRMS0(0,ipad,0,0)/param->GetPadPitchWidth(cluster->GetDetector());
1237     Float_t zres0 = parcl->GetRMS0(1,ipad,0,0)/param->GetZWidth();
1238
1239     yres0 *=parcl->GetQnormCorr(ipad, type,0);
1240     zres0 *=parcl->GetQnormCorr(ipad, type,1);
1241     Float_t effLength=parcl->GetQnormCorr(ipad, type,4)*0.5;
1242     Float_t effDiff  =(parcl->GetQnormCorr(ipad, type,2)+parcl->GetQnormCorr(ipad, type,3))*0.5;
1243     //
1244     if (type==1) {
1245       corrPos = parcl->GetQnormCorr(ipad, type,5)*
1246         parcl->QmaxCorrection(cluster->GetDetector(), cluster->GetRow(),cluster->GetPad(), 
1247                               cluster->GetTimeBin(),ty,tz,yres0,zres0,effLength,effDiff);
1248       Float_t drm   = 0.5-TMath::Abs(cluster->GetZ()/250.);
1249       corrPos*=(1+parcl->GetQnormCorr(ipad, type+2,0)*drm);
1250       corrPos*=(1+parcl->GetQnormCorr(ipad, type+2,1)*ty*ty);
1251       corrPos*=(1+parcl->GetQnormCorr(ipad, type+2,2)*tz*tz);
1252       //
1253     }
1254     if (type==0) {
1255       corrPos = parcl->GetQnormCorr(ipad, type,5)*
1256         parcl->QtotCorrection(cluster->GetDetector(), cluster->GetRow(),cluster->GetPad(), 
1257                               cluster->GetTimeBin(),ty,tz,yres0,zres0,cluster->GetQ(),2.5,effLength,effDiff);
1258       
1259       Float_t drm   = 0.5-TMath::Abs(cluster->GetZ()/250.);
1260       corrPos*=(1+parcl->GetQnormCorr(ipad, type+2,0)*drm);
1261       corrPos*=(1+parcl->GetQnormCorr(ipad, type+2,1)*ty*ty);
1262       corrPos*=(1+parcl->GetQnormCorr(ipad, type+2,2)*tz*tz);
1263       //
1264     }
1265     //
1266     // pad region equalization outside of cluster param
1267     //
1268     Float_t gainEqualPadRegion = 1;
1269     if (grPadEqual) gainEqualPadRegion = grPadEqual->Eval(ipad);
1270     //
1271     amp[ncl]=charge;
1272     amp[ncl]/=gainGG;
1273     amp[ncl]/=gainPad;
1274     amp[ncl]/=corrPos;
1275     amp[ncl]/=gainEqualPadRegion;
1276     //
1277     ncl++;
1278   }
1279
1280   if (type>3) return ncl; 
1281   TMath::Sort(ncl,amp, indexes, kFALSE);
1282   //
1283   if (ncl<10) return 0;
1284   //
1285   Double_t * ampWithBelow = new Double_t[ncl + nclBelowThr];
1286   for(Int_t iCl = 0; iCl < ncl + nclBelowThr; iCl++) {
1287     if (iCl < nclBelowThr) {
1288       ampWithBelow[iCl] = amp[indexes[0]];
1289     } else {
1290       ampWithBelow[iCl] = amp[indexes[iCl - nclBelowThr]];
1291     }
1292   }
1293   //printf("DEBUG: %i shit %f", nclBelowThr, amp[indexes[0]]);
1294   //
1295   Float_t suma=0;
1296   Float_t suma2=0;  
1297   Float_t sumn=0;
1298   Int_t icl0=TMath::Nint((ncl + nclBelowThr)*low);
1299   Int_t icl1=TMath::Nint((ncl + nclBelowThr)*up);
1300   for (Int_t icl=icl0; icl<icl1;icl++){
1301     suma+=ampWithBelow[icl];
1302     suma2+=ampWithBelow[icl]*ampWithBelow[icl];
1303     sumn++;
1304   }
1305   delete [] ampWithBelow;
1306   Float_t mean =suma/sumn;
1307   Float_t rms  =TMath::Sqrt(TMath::Abs(suma2/sumn-mean*mean));
1308   //
1309   mean /= corrTimeGain;
1310   rms /= corrTimeGain;
1311   //
1312   if (returnVal==1) return rms;
1313   if (returnVal==2) return ncl;
1314   return mean;
1315 }
1316
1317
1318
1319
1320 Float_t  AliTPCseed::CookShape(Int_t type){
1321   //
1322   //
1323   //
1324  //-----------------------------------------------------------------
1325   // This funtion calculates dE/dX within the "low" and "up" cuts.
1326   //-----------------------------------------------------------------
1327   Float_t means=0;
1328   Float_t meanc=0;
1329   for (Int_t i =0; i<160;i++)    {
1330     AliTPCTrackerPoint * point = GetTrackPoint(i);
1331     if (point==0) continue;
1332
1333     AliTPCclusterMI * cl = fClusterPointer[i];
1334     if (cl==0) continue;        
1335     
1336     Float_t rsigmay =  TMath::Sqrt(point->GetSigmaY());
1337     Float_t rsigmaz =  TMath::Sqrt(point->GetSigmaZ());
1338     Float_t rsigma =   (rsigmay+rsigmaz)*0.5;
1339     if (type==0) means+=rsigma;
1340     if (type==1) means+=rsigmay;
1341     if (type==2) means+=rsigmaz;
1342     meanc++;
1343   }
1344   Float_t mean = (meanc>0)? means/meanc:0;
1345   return mean;
1346 }
1347
1348
1349
1350 Int_t  AliTPCseed::RefitTrack(AliTPCseed *seed, AliExternalTrackParam * parin, AliExternalTrackParam * parout){
1351   //
1352   // Refit the track
1353   // return value - number of used clusters
1354   // 
1355   //
1356   const Int_t kMinNcl =10;
1357   AliTPCseed *track=new AliTPCseed(*seed);
1358   Int_t sector=-1;
1359   // reset covariance
1360   //
1361   Double_t covar[15];
1362   for (Int_t i=0;i<15;i++) covar[i]=0;
1363   covar[0]=10.*10.;
1364   covar[2]=10.*10.;
1365   covar[5]=10.*10./(64.*64.);
1366   covar[9]=10.*10./(64.*64.);
1367   covar[14]=1*1;
1368   //
1369
1370   Float_t xmin=1000, xmax=-10000;
1371   Int_t imin=158, imax=0;
1372   for (Int_t i=0;i<160;i++) {
1373     AliTPCclusterMI *c=track->GetClusterPointer(i);
1374     if (!c) continue;
1375     if (sector<0) sector = c->GetDetector();
1376     if (c->GetX()<xmin) xmin=c->GetX();
1377     if (c->GetX()>xmax) xmax=c->GetX();
1378     if (i<imin) imin=i;
1379     if (i>imax) imax=i;
1380   }
1381   if(imax-imin<kMinNcl) {
1382     delete track;
1383     return 0 ;
1384   }
1385   // Not succes to rotate
1386   if (!track->Rotate(TMath::DegToRad()*(sector%18*20.+10.)-track->GetAlpha())) {
1387     delete track;
1388     return 0;
1389   }
1390   //
1391   //
1392   // fit from inner to outer row
1393   //
1394   AliExternalTrackParam paramIn;
1395   AliExternalTrackParam paramOut;
1396   Bool_t isOK=kTRUE;
1397   Int_t ncl=0;
1398   //
1399   //
1400   //
1401   for (Int_t i=imin; i<=imax; i++){
1402     AliTPCclusterMI *c=track->GetClusterPointer(i);
1403     if (!c) continue;
1404     //    if (RejectCluster(c,track)) continue;
1405     sector = (c->GetDetector()%18);
1406     if (!track->Rotate(TMath::DegToRad()*(sector%18*20.+10.)-track->GetAlpha())) {
1407       //continue;
1408     }
1409     Double_t r[3]={c->GetX(),c->GetY(),c->GetZ()};
1410     Double_t cov[3]={0.01,0.,0.01}; //TODO: correct error parametrisation
1411     if (!track->PropagateTo(r[0])) {
1412       isOK=kFALSE;
1413     }
1414     if ( !((static_cast<AliExternalTrackParam*>(track)->Update(&r[1],cov)))) isOK=kFALSE;
1415   }
1416   if (!isOK) { delete track; return 0;}
1417   track->AddCovariance(covar);
1418   //
1419   //
1420   //
1421   for (Int_t i=imax; i>=imin; i--){
1422     AliTPCclusterMI *c=track->GetClusterPointer(i);
1423     if (!c) continue;
1424     //if (RejectCluster(c,track)) continue;
1425     sector = (c->GetDetector()%18);
1426     if (!track->Rotate(TMath::DegToRad()*(sector%18*20.+10.)-track->GetAlpha())) {
1427       //continue;
1428     }
1429     Double_t r[3]={c->GetX(),c->GetY(),c->GetZ()};
1430     Double_t cov[3]={0.01,0.,0.01}; //TODO: correct error parametrisation
1431     if (!track->PropagateTo(r[0])) {
1432       isOK=kFALSE;
1433     }
1434     if ( !((static_cast<AliExternalTrackParam*>(track)->Update(&r[1],cov)))) isOK=kFALSE;
1435   }
1436   //if (!isOK) { delete track; return 0;}
1437   paramIn = *track;
1438   track->AddCovariance(covar);
1439   //
1440   //
1441   for (Int_t i=imin; i<=imax; i++){
1442     AliTPCclusterMI *c=track->GetClusterPointer(i);
1443     if (!c) continue;
1444     sector = (c->GetDetector()%18);
1445     if (!track->Rotate(TMath::DegToRad()*(sector%18*20.+10.)-track->GetAlpha())) {
1446       //continue;
1447     }
1448     ncl++;
1449     //if (RejectCluster(c,track)) continue;
1450     Double_t r[3]={c->GetX(),c->GetY(),c->GetZ()};
1451     Double_t cov[3]={0.01,0.,0.01}; //TODO: correct error parametrisation
1452     if (!track->PropagateTo(r[0])) {
1453       isOK=kFALSE;
1454     }
1455     if ( !((static_cast<AliExternalTrackParam*>(track)->Update(&r[1],cov)))) isOK=kFALSE;
1456   }
1457   //if (!isOK) { delete track; return 0;}
1458   paramOut=*track;
1459   //
1460   //
1461   //
1462   if (parin) (*parin)=paramIn;
1463   if (parout) (*parout)=paramOut;
1464   delete track;
1465   return ncl;
1466 }
1467
1468
1469
1470 Bool_t AliTPCseed::RefitTrack(AliTPCseed* /*seed*/, Bool_t /*out*/){
1471   //
1472   //
1473   //
1474   return kFALSE;
1475 }
1476
1477
1478
1479
1480
1481
1482 void  AliTPCseed::GetError(AliTPCclusterMI* cluster, AliExternalTrackParam * param, 
1483                                   Double_t& erry, Double_t &errz)
1484 {
1485   //
1486   // Get cluster error at given position
1487   //
1488   AliTPCClusterParam *clusterParam = AliTPCcalibDB::Instance()->GetClusterParam();
1489   Double_t tany,tanz;  
1490   Double_t snp1=param->GetSnp();
1491   tany=snp1/TMath::Sqrt((1.-snp1)*(1.+snp1));
1492   //
1493   Double_t tgl1=param->GetTgl();
1494   tanz=tgl1/TMath::Sqrt((1.-snp1)*(1.+snp1));
1495   //
1496   Int_t padSize = 0;                          // short pads
1497   if (cluster->GetDetector() >= 36) {
1498     padSize = 1;                              // medium pads 
1499     if (cluster->GetRow() > 63) padSize = 2; // long pads
1500   }
1501
1502   erry  = clusterParam->GetError0Par( 0, padSize, (250.0 - TMath::Abs(cluster->GetZ())), TMath::Abs(tany) );
1503   errz  = clusterParam->GetError0Par( 1, padSize, (250.0 - TMath::Abs(cluster->GetZ())), TMath::Abs(tanz) );
1504 }
1505
1506
1507 void  AliTPCseed::GetShape(AliTPCclusterMI* cluster, AliExternalTrackParam * param, 
1508                                   Double_t& rmsy, Double_t &rmsz)
1509 {
1510   //
1511   // Get cluster error at given position
1512   //
1513   AliTPCClusterParam *clusterParam = AliTPCcalibDB::Instance()->GetClusterParam();
1514   Double_t tany,tanz;  
1515   Double_t snp1=param->GetSnp();
1516   tany=snp1/TMath::Sqrt((1.-snp1)*(1.+snp1));
1517   //
1518   Double_t tgl1=param->GetTgl();
1519   tanz=tgl1/TMath::Sqrt((1.-snp1)*(1.+snp1));
1520   //
1521   Int_t padSize = 0;                          // short pads
1522   if (cluster->GetDetector() >= 36) {
1523     padSize = 1;                              // medium pads 
1524     if (cluster->GetRow() > 63) padSize = 2; // long pads
1525   }
1526
1527   rmsy  = clusterParam->GetRMSQ( 0, padSize, (250.0 - TMath::Abs(cluster->GetZ())), TMath::Abs(tany), TMath::Abs(cluster->GetMax()) );
1528   rmsz  = clusterParam->GetRMSQ( 1, padSize, (250.0 - TMath::Abs(cluster->GetZ())), TMath::Abs(tanz) ,TMath::Abs(cluster->GetMax()));
1529 }
1530
1531
1532
1533 Double_t AliTPCseed::GetQCorrGeom(Float_t ty, Float_t tz){
1534   //Geoetrical
1535   //ty    - tangent in local y direction
1536   //tz    - tangent 
1537   //
1538   Float_t norm=TMath::Sqrt(1+ty*ty+tz*tz);
1539   return norm;
1540 }
1541
1542 Double_t AliTPCseed::GetQCorrShape(Int_t ipad, Int_t type,Float_t z, Float_t ty, Float_t tz, Float_t /*q*/, Float_t /*thr*/){
1543   //
1544   // Q normalization
1545   //
1546   // return value =  Q Normalization factor
1547   // Normalization - 1 - shape factor part for full drift          
1548   //                 1 - electron attachment for 0 drift
1549
1550   // Input parameters:
1551   //
1552   // ipad - 0 short pad
1553   //        1 medium pad
1554   //        2 long pad
1555   //
1556   // type - 0 qmax
1557   //      - 1 qtot
1558   //
1559   //z     - z position (-250,250 cm)
1560   //ty    - tangent in local y direction
1561   //tz    - tangent 
1562   //
1563
1564   AliTPCClusterParam * paramCl = AliTPCcalibDB::Instance()->GetClusterParam();
1565   AliTPCParam   * paramTPC = AliTPCcalibDB::Instance()->GetParameters();
1566  
1567   if (!paramCl) return 1;
1568   //
1569   Double_t dr =  250.-TMath::Abs(z); 
1570   Double_t sy =  paramCl->GetRMS0( 0,ipad, dr, TMath::Abs(ty));
1571   Double_t sy0=  paramCl->GetRMS0(0,ipad, 250, 0);
1572   Double_t sz =  paramCl->GetRMS0( 1,ipad, dr, TMath::Abs(tz));
1573   Double_t sz0=  paramCl->GetRMS0(1,ipad, 250, 0);
1574
1575   Double_t sfactorMax = TMath::Sqrt(sy0*sz0/(sy*sz));
1576
1577  
1578   Double_t dt = 1000000*(dr/paramTPC->GetDriftV());  //time in microsecond
1579   Double_t attProb = TMath::Exp(-paramTPC->GetAttCoef()*paramTPC->GetOxyCont()*dt);
1580   //
1581   //
1582   if (type==0) return sfactorMax*attProb;
1583
1584   return attProb;
1585
1586
1587 }
1588