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