]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TPC/AliTPCtrackerMI.cxx
New class for PID constants and methods. Changes in all related code (T.Kuhr)
[u/mrichter/AliRoot.git] / TPC / AliTPCtrackerMI.cxx
index 1fa2679d2636b6df3b34f4b98886df39e9bd15e0..4b7d8530bff7760e1a6c8b207b4f17560fc1a5ca 100644 (file)
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 
-/*
-$Log$
-Revision 1.18  2003/10/17 15:42:14  kowal2
-Back to the previous version. The warning was erronously generated
-by the compiler
-
-Revision 1.17  2003/10/17 12:28:02  kowal2
-Removed "always true" comparison
-
-Revision 1.16  2003/10/17 12:01:16  kowal2
-Removed compiler warning.
-
-Revision 1.15  2003/09/29 11:56:58  kowal2
-bug fix2
-
-Revision 1.14  2003/09/29 11:39:43  kowal2
-bug fix
-
-Revision 1.13  2003/09/29 11:28:19  kowal2
-completly rewritten
-
-Revision 1.9.4.3  2003/06/23 14:47:10  hristov
-Minor fix
-
-Revision 1.9.4.2  2003/06/23 10:06:13  hristov
-Updated information about the overlapping clusters (M.Ivanov)
-
-Revision 1.9.4.1  2003/06/19 06:59:58  hristov
-Updated version of parallel tracking (M.Ivanov)
-
-Revision 1.9  2003/03/19 17:14:11  hristov
-Load/UnloadClusters added to the base class and the derived classes changed correspondingly. Possibility to give 2 input files for ITS and TPC tracks in PropagateBack. TRD tracker uses fEventN from the base class (T.Kuhr)
-
-Revision 1.8  2003/03/05 11:16:15  kowal2
-Logs added
-
-*/
-
-
-
-
-
-
-
-/*
-  AliTPC parallel tracker - 
-  How to use?  - 
-  run AliTPCFindClusters.C macro - clusters neccessary for tracker are founded
-  run AliTPCFindTracksMI.C macro - to find tracks
-  tracks are written to AliTPCtracks.root file
-  for comparison also seeds are written to the same file - to special branch
-*/
 
 //-------------------------------------------------------
 //          Implementation of the TPC tracker
 //
 //   Origin: Marian Ivanov   Marian.Ivanov@cern.ch
 // 
+//  AliTPC parallel tracker - 
+//  How to use?  - 
+//  run AliTPCFindClusters.C macro - clusters neccessary for tracker are founded
+//  run AliTPCFindTracksMI.C macro - to find tracks
+//  tracks are written to AliTPCtracks.root file
+//  for comparison also seeds are written to the same file - to special branch
 //-------------------------------------------------------
-#include <TObjArray.h>
+
+
+/* $Id$ */
+
+
+
+#include "Riostream.h"
+#include <TClonesArray.h>
 #include <TFile.h>
+#include <TObjArray.h>
 #include <TTree.h>
-#include "Riostream.h"
 
-#include "AliTPCtrackerMI.h"
-#include "AliTPCclusterMI.h"
-#include "AliTPCParam.h"
-#include "AliTPCClustersRow.h"
 #include "AliComplexCluster.h"
-#include "AliTPCpolyTrack.h"
-#include "TStopwatch.h"
 #include "AliESD.h"
 #include "AliHelix.h"
-#include "TGraph.h"
-//
 #include "AliRunLoader.h"
+#include "AliTPCClustersRow.h"
+#include "AliTPCParam.h"
+#include "AliTPCclusterMI.h"
+#include "AliTPCpolyTrack.h"
+#include "AliTPCreco.h" 
+#include "AliTPCtrackerMI.h"
+#include "TStopwatch.h"
 
-
+#include "AliTPCReconstructor.h"
+#include "AliESDkink.h"
+//
 
 ClassImp(AliTPCseed)
 ClassImp(AliTPCtrackerMI)
 
 
-class TPCFastMath {
+class AliTPCFastMath {
 public:
-  TPCFastMath();  
+  AliTPCFastMath();  
   static Double_t FastAsin(Double_t x);   
  private: 
-  static Double_t fgFastAsin[20000];
+  static Double_t fgFastAsin[20000];  //lookup table for fast asin computation
 };
 
-Double_t TPCFastMath::fgFastAsin[20000];
+Double_t AliTPCFastMath::fgFastAsin[20000];
+AliTPCFastMath gAliTPCFastMath; // needed to fill the LUT
 
-TPCFastMath::TPCFastMath(){
+AliTPCFastMath::AliTPCFastMath(){
+  //
+  // initialized lookup table;
   for (Int_t i=0;i<10000;i++){
     fgFastAsin[2*i] = TMath::ASin(i/10000.);
     fgFastAsin[2*i+1] = (TMath::ASin((i+1)/10000.)-fgFastAsin[2*i]);
   }
 }
 
-Double_t TPCFastMath::FastAsin(Double_t x){
+Double_t AliTPCFastMath::FastAsin(Double_t x){
+  //
+  // return asin using lookup table
   if (x>0){
     Int_t index = int(x*10000);
     return fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1];
@@ -123,11 +90,13 @@ Double_t TPCFastMath::FastAsin(Double_t x){
   return -(fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1]);
 }
 
-TPCFastMath gTPCMath;
 
 
 
 Int_t AliTPCtrackerMI::UpdateTrack(AliTPCseed * track, Int_t accept){
+  //
+  //update track information using current cluster - track->fCurrentCluster
+
 
   AliTPCclusterMI* c =track->fCurrentCluster;
   if (accept>0) track->fCurrentClusterIndex1 |=0x8000;  //sign not accepted clusters
@@ -140,8 +109,7 @@ Int_t AliTPCtrackerMI::UpdateTrack(AliTPCseed * track, Int_t accept){
   track->fSector = sec;
   //  Int_t index = i&0xFFFF;
   if (sec>=fParam->GetNInnerSector()) track->fRow += fParam->GetNRowLow(); 
-  track->SetClusterIndex2(track->fRow, i);
-  
+  track->SetClusterIndex2(track->fRow, i);  
   //track->fFirstPoint = row;
   //if ( track->fLastPoint<row) track->fLastPoint =row;
   //  if (track->fRow<0 || track->fRow>160) {
@@ -290,7 +258,22 @@ AliTracker(), fkNIS(par->GetNInnerSector()/2), fkNOS(par->GetNOuterSector()/2)
   fDebug     =0;
   fEvent     =0;
 }
-
+//________________________________________________________________________
+AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCtrackerMI &t):
+  AliTracker(t),
+  fkNIS(t.fkNIS),
+  fkNOS(t.fkNOS)
+{
+  //------------------------------------
+  // dummy copy constructor
+  //------------------------------------------------------------------
+}
+AliTPCtrackerMI & AliTPCtrackerMI::operator=(const AliTPCtrackerMI& /*r*/){
+  //------------------------------
+  // dummy 
+  //--------------------------------------------------------------
+  return *this;
+}
 //_____________________________________________________________________________
 AliTPCtrackerMI::~AliTPCtrackerMI() {
   //------------------------------------------------------------------
@@ -308,15 +291,17 @@ void AliTPCtrackerMI::SetIO()
 {
   //
   fNewIO   =  kTRUE;
-  fInput   =  AliRunLoader::GetTreeR("TPC", kFALSE,AliConfig::fgkDefaultEventFolderName);
-  fOutput  =  AliRunLoader::GetTreeT("TPC", kTRUE,AliConfig::fgkDefaultEventFolderName);
-  AliTPCtrack *iotrack= new AliTPCtrack;
-  //    iotrack->fHelixIn   = new TClonesArray("AliHelix");
-  //iotrack->fHelixOut  = new TClonesArray("AliHelix");    
-  fOutput->Branch("tracks","AliTPCtrack",&iotrack,32000,100);
-  delete iotrack;
+  fInput   =  AliRunLoader::GetTreeR("TPC", kFALSE,AliConfig::GetDefaultEventFolderName());
+  
+  fOutput  =  AliRunLoader::GetTreeT("TPC", kTRUE,AliConfig::GetDefaultEventFolderName());
+  if (fOutput){
+    AliTPCtrack *iotrack= new AliTPCtrack;
+    fOutput->Branch("tracks","AliTPCtrack",&iotrack,32000,100);
+    delete iotrack;
+  }
 }
 
+
 void AliTPCtrackerMI::SetIO(TTree * input, TTree * output, AliESD * event)
 {
 
@@ -365,35 +350,138 @@ void AliTPCtrackerMI::SetIO(TTree * input, TTree * output, AliESD * event)
   fEvent  = event;  
 }
 
-void AliTPCtrackerMI::WriteTracks()
+void AliTPCtrackerMI::FillESD(TObjArray* arr)
 {
   //
-  // write tracks to the given output tree -
-  // output specified with SetIO routine
-  if (!fSeeds)  return;
+  //
+  //fill esds using updated tracks
   if (fEvent){
     // write tracks to the event
     // store index of the track
-    Int_t nseed=fSeeds->GetEntriesFast();
+    Int_t nseed=arr->GetEntriesFast();
+    //FindKinks(arr,fEvent);
     for (Int_t i=0; i<nseed; i++) {
-      AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i);    
+      AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
       if (!pt) continue; 
-      AliESDtrack iotrack;
-      iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);       
-      //iotrack.SetTPCindex(i);
-      fEvent->AddTrack(&iotrack);         
+      pt->UpdatePoints();
+      pt->PropagateTo(fParam->GetInnerRadiusLow());
+      if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
+       AliESDtrack iotrack;
+       iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
+       iotrack.SetTPCPoints(pt->GetPoints());
+       iotrack.SetKinkIndexes(pt->GetKinkIndexes());
+       //iotrack.SetTPCindex(i);
+       fEvent->AddTrack(&iotrack);
+       continue;
+      }
+       
+      if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->fNFoundable))>0.55) {
+       AliESDtrack iotrack;
+       iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
+       iotrack.SetTPCPoints(pt->GetPoints());
+       //iotrack.SetTPCindex(i);
+       iotrack.SetKinkIndexes(pt->GetKinkIndexes());
+       fEvent->AddTrack(&iotrack);
+       continue;
+      } 
+      //
+      // short tracks  - maybe decays
+
+      if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->fNFoundable))>0.70) {
+       Int_t found,foundable,shared;
+       pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
+       if ( (found>20) && (pt->fNShared/float(pt->GetNumberOfClusters())<0.2)){
+         AliESDtrack iotrack;
+         iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);    
+         //iotrack.SetTPCindex(i);
+         iotrack.SetTPCPoints(pt->GetPoints());
+         iotrack.SetKinkIndexes(pt->GetKinkIndexes());
+         fEvent->AddTrack(&iotrack);
+         continue;
+       }
+      }       
+      
+      if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->fNFoundable))>0.8) {
+       Int_t found,foundable,shared;
+       pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
+       if (found<20) continue;
+       if (pt->fNShared/float(pt->GetNumberOfClusters())>0.2) continue;
+       //
+       AliESDtrack iotrack;
+       iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);      
+       iotrack.SetTPCPoints(pt->GetPoints());
+       iotrack.SetKinkIndexes(pt->GetKinkIndexes());
+       //iotrack.SetTPCindex(i);
+       fEvent->AddTrack(&iotrack);
+       continue;
+      }   
+      // short tracks  - secondaties
+      //
+      if ( (pt->GetNumberOfClusters()>30) ) {
+       Int_t found,foundable,shared;
+       pt->GetClusterStatistic(128,158,found, foundable,shared,kFALSE);
+       if ( (found>20) && (pt->fNShared/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
+         AliESDtrack iotrack;
+         iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);    
+         iotrack.SetTPCPoints(pt->GetPoints());
+         iotrack.SetKinkIndexes(pt->GetKinkIndexes());
+         //iotrack.SetTPCindex(i);
+         fEvent->AddTrack(&iotrack);
+         continue;
+       }
+      }       
+      
+      if ( (pt->GetNumberOfClusters()>15)) {
+       Int_t found,foundable,shared;
+       pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE);
+       if (found<15) continue;
+       if (pt->fNShared/float(pt->GetNumberOfClusters())>0.2) continue;
+       if (float(found)/float(foundable)<0.8) continue;
+       //
+       AliESDtrack iotrack;
+       iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);      
+       iotrack.SetTPCPoints(pt->GetPoints());
+       iotrack.SetKinkIndexes(pt->GetKinkIndexes());
+       //iotrack.SetTPCindex(i);
+       fEvent->AddTrack(&iotrack);
+       continue;
+      }   
     }
   }
+  printf("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks());
+}
+
+void AliTPCtrackerMI::WriteTracks(TTree * tree)
+{
+  //
+  // write tracks from seed array to selected tree
+  //
+  fOutput  = tree;
+  if (fOutput){
+    AliTPCtrack *iotrack= new AliTPCtrack;
+    fOutput->Branch("tracks","AliTPCtrack",&iotrack,32000,100);
+  }
+  WriteTracks();
+}
+
+void AliTPCtrackerMI::WriteTracks()
+{
+  //
+  // write tracks to the given output tree -
+  // output specified with SetIO routine
+  if (!fSeeds)  return;
+  if (!fOutput){
+    SetIO();
+  }
 
-  
   if (fOutput){
     AliTPCtrack *iotrack= 0;
     Int_t nseed=fSeeds->GetEntriesFast();
-    for (Int_t i=0; i<nseed; i++) {
-      iotrack= (AliTPCtrack*)fSeeds->UncheckedAt(i);
-      if (iotrack) break;      
-    }
-    
+    //for (Int_t i=0; i<nseed; i++) {
+    //  iotrack= (AliTPCtrack*)fSeeds->UncheckedAt(i);
+    //  if (iotrack) break;      
+    //}    
     //TBranch * br = fOutput->Branch("tracks","AliTPCtrack",&iotrack,32000,100);
     TBranch * br = fOutput->GetBranch("tracks");
     br->SetAddress(&iotrack);
@@ -401,15 +489,19 @@ void AliTPCtrackerMI::WriteTracks()
     for (Int_t i=0; i<nseed; i++) {
       AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i);    
       if (!pt) continue;    
-      iotrack = pt;
+      AliTPCtrack * track = new AliTPCtrack(*pt);
+      iotrack = track;
       pt->fLab2 =i; 
       //      br->SetAddress(&iotrack);
       fOutput->Fill();
+      delete track;
       iotrack =0;
     }
+    //fOutput->GetDirectory()->cd();
+    //fOutput->Write();
   }
-    // delete iotrack;
-    //
+  // delete iotrack;
+  //
   if (fSeedTree){
     //write the full seed information if specified in debug mode
       
@@ -839,10 +931,10 @@ void AliTPCseed::Modify(Double_t factor)
     return;
   }
   fC00*=factor;
-  fC10*=factor;  fC11*=factor;
-  fC20*=factor;  fC21*=factor;  fC22*=factor;
-  fC30*=factor;  fC31*=factor;  fC32*=factor;  fC33*=factor;
-  fC40*=factor;  fC41*=factor;  fC42*=factor;  fC43*=factor;  fC44*=factor;
+  fC10*=0;  fC11*=factor;
+  fC20*=0;  fC21*=0;  fC22*=factor;
+  fC30*=0;  fC31*=0;  fC32*=0;  fC33*=factor;
+  fC40*=0;  fC41*=0;  fC42*=0;  fC43*=0;  fC44*=factor;
   SetNumberOfClusters(0);
   fNFoundable =0;
   SetChi2(0);
@@ -890,7 +982,7 @@ Int_t  AliTPCseed::GetProlongation(Double_t xk, Double_t &y, Double_t & z) const
     dz = dx*fP3*(c1+c2)/(c1*r2 + c2*r1);
   }
   */
-  dz =  fP3*TPCFastMath::FastAsin(delta)/fP4;
+  dz =  fP3*AliTPCFastMath::FastAsin(delta)/fP4;
   //
   y+=dy;
   z+=dz;
@@ -1038,7 +1130,7 @@ Int_t AliTPCseed::Update(const AliTPCclusterMI *c, Double_t chisq, UInt_t /*inde
 
 
 //_____________________________________________________________________________
-Double_t AliTPCtrackerMI::f1old(Double_t x1,Double_t y1,
+Double_t AliTPCtrackerMI::F1old(Double_t x1,Double_t y1,
                    Double_t x2,Double_t y2,
                    Double_t x3,Double_t y3) 
 {
@@ -1059,7 +1151,7 @@ Double_t AliTPCtrackerMI::f1old(Double_t x1,Double_t y1,
 
 
 //_____________________________________________________________________________
-Double_t AliTPCtrackerMI::f1(Double_t x1,Double_t y1,
+Double_t AliTPCtrackerMI::F1(Double_t x1,Double_t y1,
                    Double_t x2,Double_t y2,
                    Double_t x3,Double_t y3) 
 {
@@ -1085,7 +1177,7 @@ Double_t AliTPCtrackerMI::f1(Double_t x1,Double_t y1,
 }
 
 
-Double_t AliTPCtrackerMI::f2(Double_t x1,Double_t y1,
+Double_t AliTPCtrackerMI::F2(Double_t x1,Double_t y1,
                    Double_t x2,Double_t y2,
                    Double_t x3,Double_t y3) 
 {
@@ -1115,7 +1207,7 @@ Double_t AliTPCtrackerMI::f2(Double_t x1,Double_t y1,
 
 
 //_____________________________________________________________________________
-Double_t AliTPCtrackerMI::f2old(Double_t x1,Double_t y1,
+Double_t AliTPCtrackerMI::F2old(Double_t x1,Double_t y1,
                    Double_t x2,Double_t y2,
                    Double_t x3,Double_t y3) 
 {
@@ -1134,7 +1226,7 @@ Double_t AliTPCtrackerMI::f2old(Double_t x1,Double_t y1,
 }
 
 //_____________________________________________________________________________
-Double_t AliTPCtrackerMI::f3(Double_t x1,Double_t y1, 
+Double_t AliTPCtrackerMI::F3(Double_t x1,Double_t y1, 
                    Double_t x2,Double_t y2,
                    Double_t z1,Double_t z2) 
 {
@@ -1145,7 +1237,7 @@ Double_t AliTPCtrackerMI::f3(Double_t x1,Double_t y1,
 }
 
 
-Double_t AliTPCtrackerMI::f3n(Double_t x1,Double_t y1, 
+Double_t AliTPCtrackerMI::F3n(Double_t x1,Double_t y1, 
                    Double_t x2,Double_t y2,
                    Double_t z1,Double_t z2, Double_t c) 
 {
@@ -1160,8 +1252,8 @@ Double_t AliTPCtrackerMI::f3n(Double_t x1,Double_t y1,
   Double_t d  =  TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
   if (TMath::Abs(d*c*0.5)>1) return 0;
   //  Double_t   angle2    =  TMath::ASin(d*c*0.5);
-  //  Double_t   angle2    =  TPCFastMath::FastAsin(d*c*0.5);
-  Double_t   angle2    = (d*c*0.5>0.1)? TMath::ASin(d*c*0.5): TPCFastMath::FastAsin(d*c*0.5);
+  //  Double_t   angle2    =  AliTPCFastMath::FastAsin(d*c*0.5);
+  Double_t   angle2    = (d*c*0.5>0.1)? TMath::ASin(d*c*0.5): AliTPCFastMath::FastAsin(d*c*0.5);
 
   angle2  = (z1-z2)*c/(angle2*2.);
   return angle2;
@@ -1191,10 +1283,10 @@ Bool_t   AliTPCtrackerMI::GetProlongation(Double_t x1, Double_t x2, Double_t x[5
   if (TMath::Abs(delta)>0.01){
     dz = x[3]*TMath::ASin(delta)/x[4];
   }else{
-    dz = x[3]*TPCFastMath::FastAsin(delta)/x[4];
+    dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
   }
   
-  //dz = x[3]*TPCFastMath::FastAsin(delta)/x[4];
+  //dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
 
   y+=dy;
   z+=dz;
@@ -1202,7 +1294,13 @@ Bool_t   AliTPCtrackerMI::GetProlongation(Double_t x1, Double_t x2, Double_t x[5
   return kTRUE;  
 }
 
-
+Int_t  AliTPCtrackerMI::LoadClusters (TTree *tree)
+{
+  //
+  //
+  fInput = tree;
+  return LoadClusters();
+}
 
 Int_t  AliTPCtrackerMI::LoadClusters()
 {
@@ -1266,20 +1364,22 @@ void AliTPCtrackerMI::UnloadClusters()
   for (Int_t sec = 0;sec<fkNOS;sec++)
     for (Int_t row = 0;row<nrows;row++){
       AliTPCRow*  tpcrow = &(fOuterSec[sec%fkNOS][row]);
-      if (tpcrow){
-       if (tpcrow->fClusters1) delete []tpcrow->fClusters1; 
-       if (tpcrow->fClusters2) delete []tpcrow->fClusters2; 
-      }
+      //      if (tpcrow){
+      //       if (tpcrow->fClusters1) delete []tpcrow->fClusters1; 
+      //       if (tpcrow->fClusters2) delete []tpcrow->fClusters2; 
+      //}
+      tpcrow->ResetClusters();
     }
   //
   nrows = fInnerSec->GetNRows();
   for (Int_t sec = 0;sec<fkNIS;sec++)
     for (Int_t row = 0;row<nrows;row++){
       AliTPCRow*  tpcrow = &(fInnerSec[sec%fkNIS][row]);
-      if (tpcrow){
-       if (tpcrow->fClusters1) delete []tpcrow->fClusters1; 
-       if (tpcrow->fClusters2) delete []tpcrow->fClusters2; 
-      }
+      //if (tpcrow){
+      //       if (tpcrow->fClusters1) delete []tpcrow->fClusters1; 
+      //if (tpcrow->fClusters2) delete []tpcrow->fClusters2; 
+      //}
+      tpcrow->ResetClusters();
     }
 
   return ;
@@ -1392,27 +1492,38 @@ AliTPCclusterMI *AliTPCtrackerMI::GetClusterMI(Int_t index) const {
   //--------------------------------------------------------------------
   Int_t sec=(index&0xff000000)>>24; 
   Int_t row=(index&0x00ff0000)>>16; 
-  Int_t ncl=(index&0x0000ffff)>>00;
+  Int_t ncl=(index&0x00007fff)>>00;
 
   const AliTPCRow * tpcrow=0;
   AliTPCclusterMI * clrow =0;
+
   if (sec<fkNIS*2){
     tpcrow = &(fInnerSec[sec%fkNIS][row]);
-    if (sec<fkNIS) 
+    if (tpcrow==0) return 0;
+
+    if (sec<fkNIS) {
+      if (tpcrow->fN1<=ncl) return 0;
       clrow = tpcrow->fClusters1;
-    else
+    }
+    else {
+      if (tpcrow->fN2<=ncl) return 0;
       clrow = tpcrow->fClusters2;
+    }
   }
-  else{
+  else {
     tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
-    if (sec-2*fkNIS<fkNOS)
+    if (tpcrow==0) return 0;
+
+    if (sec-2*fkNIS<fkNOS) {
+      if (tpcrow->fN1<=ncl) return 0;
       clrow = tpcrow->fClusters1;
-    else
+    }
+    else {
+      if (tpcrow->fN2<=ncl) return 0;
       clrow = tpcrow->fClusters2;
+    }
   }
-  if (tpcrow==0) return 0;
-  if (tpcrow->GetN()<=ncl) return 0;
-  //  return (AliTPCclusterMI*)(*tpcrow)[ncl];      
+
   return &(clrow[ncl]);      
   
 }
@@ -1425,16 +1536,59 @@ Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
   //-----------------------------------------------------------------
   //
   Double_t  x= GetXrow(nr), ymax=GetMaxY(nr);
-
-  //  if (t.GetRadius()>x+10 ) return 0;
-  //  t.PropagateTo(x+0.02);
-  //t.PropagateTo(x+0.01);
-  if (!t.PropagateTo(x)) {
-    t.fRemoval = 10;
-    return 0;
+  AliTPCclusterMI *cl=0;
+  Int_t tpcindex= t.GetClusterIndex2(nr);
+  //
+  // update current shape info every 5 pad-row
+  //  if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
+    GetShape(&t,nr);    
+    //}
+  //  
+  if (fIteration>0 && tpcindex>=-1){  //if we have already clusters 
+    //        
+    if (tpcindex==-1) return 0; //track in dead zone
+    if (tpcindex>0){     //
+      cl = t.fClusterPointer[nr];
+      if ( (cl==0) ) cl = GetClusterMI(tpcindex);
+      t.fCurrentClusterIndex1 = tpcindex; 
+    }
+    if (cl){      
+      Int_t relativesector = ((tpcindex&0xff000000)>>24)%18;  // if previously accepted cluster in different sector
+      Float_t angle = relativesector*fSectors->GetAlpha()+fSectors->GetAlphaShift();
+      //
+      if (angle<-TMath::Pi()) angle += 2*TMath::Pi();
+      if (angle>=TMath::Pi()) angle -= 2*TMath::Pi();
+      
+      if (TMath::Abs(angle-t.GetAlpha())>0.001){
+       Double_t rotation = angle-t.GetAlpha();
+       t.fRelativeSector= relativesector;
+       t.Rotate(rotation);     
+      }
+      t.PropagateTo(x);
+      //
+      t.fCurrentCluster = cl; 
+      t.fRow = nr;
+      Int_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);
+      if ((tpcindex&0x8000)==0) accept =0;
+      if (accept<3) { 
+       //if founded cluster is acceptible
+       if (cl->IsUsed(11)) {  // id cluster is shared inrease uncertainty
+         t.fErrorY2 += 0.03;
+         t.fErrorZ2 += 0.03; 
+         t.fErrorY2 *= 3;
+         t.fErrorZ2 *= 3; 
+       }
+       t.fNFoundable++;
+       UpdateTrack(&t,accept);
+       return 1;
+      }    
+    }
   }
+  if (fIteration>1) return 0;  // not look for new cluster during refitting
   //
-  Double_t  y=t.GetY(), z=t.GetZ();
+  UInt_t index=0;
+  if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;
+  Double_t  y=t.GetYat(x);
   if (TMath::Abs(y)>ymax){
     if (y > ymax) {
       t.fRelativeSector= (t.fRelativeSector+1) % fN;
@@ -1445,33 +1599,16 @@ Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
       if (!t.Rotate(-fSectors->GetAlpha())) 
        return 0;
     }
-    if (!t.PropagateTo(x)) {
-      return 0;
-    } 
-    y=t.GetY();
+    //return 1;
   }
   //
-  // update current shape info every 3 pad-row
-  if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
-    //t.fCurrentSigmaY = GetSigmaY(&t);
-    //t.fCurrentSigmaZ = GetSigmaZ(&t);
-    GetShape(&t,nr);    
-  }
-  //  
-  AliTPCclusterMI *cl=0;
-  UInt_t index=0;
-  
-  
-  //Int_t nr2 = nr;
-  if (t.GetClusterIndex2(nr)>0){ 
-    //
-    //cl = GetClusterMI(t.GetClusterIndex2(nr));
-    index = t.GetClusterIndex2(nr);    
-    cl = t.fClusterPointer[nr];
-    if ( (cl==0) && (index>0)) cl = GetClusterMI(index);
-    t.fCurrentClusterIndex1 = index; 
+  if (!t.PropagateTo(x)) {
+    if (fIteration==0) t.fRemoval = 10;
+    return 0;
   }
-  
+  y=t.GetY(); 
+  Double_t z=t.GetZ();
+  //
   const AliTPCRow &krow=GetRow(t.fRelativeSector,nr);
   if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
   Double_t  roady  =1.;
@@ -1484,34 +1621,28 @@ Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
   } 
   else
     {
-      if (TMath::Abs(z)<(1.05*x+10)) t.fNFoundable++;
+      if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10)) t.fNFoundable++;
       else
        return 0;
     }   
   //calculate 
-  if (cl){
-    t.fCurrentCluster = cl; 
-    t.fRow = nr;
-    Int_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);
-    if (accept<3) { 
-      //if founded cluster is acceptible
-      UpdateTrack(&t,accept);
-      return 1;
-    }    
-  }
-
   if (krow) {
     //    cl = krow.FindNearest2(y+10.,z,roady,roadz,index);    
     cl = krow.FindNearest2(y,z,roady,roadz,index);    
     if (cl) t.fCurrentClusterIndex1 = krow.GetIndex(index);       
   }  
-  //  t.fNoCluster++;
-
   if (cl) {
     t.fCurrentCluster = cl; 
     t.fRow = nr;
+    if (fIteration==2&&cl->IsUsed(10)) return 0; 
     Int_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);
-    
+    if (fIteration==2&&cl->IsUsed(11)) {
+      t.fErrorY2 += 0.03;
+      t.fErrorZ2 += 0.03; 
+      t.fErrorY2 *= 3;
+      t.fErrorZ2 *= 3; 
+    }
+    /*    
     if (t.fCurrentCluster->IsUsed(10)){
       //
       //     
@@ -1522,11 +1653,11 @@ Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
        return 0;
       }
     }
-    
+    */
     if (accept<3) UpdateTrack(&t,accept);
 
   } else {  
-    if (t.fNFoundable*0.5 > t.GetNumberOfClusters()) t.fRemoval=10;
+    if ( fIteration==0 && t.fNFoundable*0.5 > t.GetNumberOfClusters()) t.fRemoval=10;
     
   }
   return 1;
@@ -1546,7 +1677,6 @@ Int_t AliTPCtrackerMI::FollowToNextFast(AliTPCseed& t, Int_t nr) {
   //
   //
   if (TMath::Abs(y)>ymax){
-    return 0;
     
     if (y > ymax) {
       t.fRelativeSector= (t.fRelativeSector+1) % fN;
@@ -1588,7 +1718,7 @@ Int_t AliTPCtrackerMI::FollowToNextFast(AliTPCseed& t, Int_t nr) {
   } 
   else
     {
-      if (TMath::Abs(z)>(1.05*x+10)) t.SetClusterIndex2(row,-1);
+      if (TMath::Abs(z)>(AliTPCReconstructor::GetCtgRange()*x+10)) t.SetClusterIndex2(row,-1);
     }   
   //calculate 
   
@@ -1654,10 +1784,11 @@ Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t,  Int_t nr) {
       if (!t.Rotate(-fSectors->GetAlpha())) 
        return 0;
     }
-    if (!t.PropagateTo(x)){
-      return 0;
-    }
-    y = t.GetY();    
+    //    if (!t.PropagateTo(x)){
+    //  return 0;
+    //}
+    return 1;
+    //y = t.GetY();    
   }
   //
 
@@ -1670,7 +1801,7 @@ Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t,  Int_t nr) {
   } 
   else
     {
-      if (TMath::Abs(t.GetZ())<(1.05*t.GetX()+10)) t.fNFoundable++;
+      if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10)) t.fNFoundable++;
       else
        return 0;      
     }
@@ -1688,12 +1819,28 @@ Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t,  Int_t nr) {
   Double_t roady = 1.;
   Double_t roadz = 1.;
   //
+
+  if (!cl){
+    index = t.GetClusterIndex2(nr);    
+    if ( (index>0) && (index&0x8000)==0){
+      cl = t.fClusterPointer[nr];
+      if ( (cl==0) && (index>0)) cl = GetClusterMI(index);
+      t.fCurrentClusterIndex1 = index;
+      if (cl) {
+       t.fCurrentCluster  = cl;
+       return 1;
+      }
+    }
+  }
+
   if (krow) {    
     //cl = krow.FindNearest2(y+10,z,roady,roadz,index);      
     cl = krow.FindNearest2(y,z,roady,roadz,index);      
   }
-  t.fCurrentCluster  = cl;
+
   if (cl) t.fCurrentClusterIndex1 = krow.GetIndex(index);   
+  t.fCurrentCluster  = cl;
+
   return 1;
 }
 
@@ -1720,7 +1867,7 @@ Int_t AliTPCtrackerMI::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
        return 0;
       }
     }   
-
+    if (fIteration>0) accept = 0;
     if (accept<3)  UpdateTrack(&t,accept);  
  
   } else {
@@ -1750,9 +1897,38 @@ Int_t AliTPCtrackerMI::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step) {
   t.fRelativeSector = Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
     
   Int_t first = GetRowNumber(xt)-1;
-  for (Int_t nr= first; nr>=rf; nr-=step) {    
+  for (Int_t nr= first; nr>=rf; nr-=step) {
+    // update kink info
+    if (t.GetKinkIndexes()[0]>0){
+      for (Int_t i=0;i<3;i++){
+       Int_t index = t.GetKinkIndexes()[i];
+       if (index==0) break;
+       if (index<0) continue;
+       //
+       AliESDkink * kink = fEvent->GetKink(index-1);
+       if (!kink){
+         printf("PROBLEM\n");
+       }
+       else{
+         Int_t kinkrow = kink->fRow0+Int_t(1./(0.1+kink->fAngle[2]));
+         if (kinkrow==nr){
+           AliExternalTrackParam paramd(t);
+           kink->SetDaughter(paramd);
+           kink->Update();
+           kink->fStatus+=100;
+         }
+       }
+      }
+    }
+
+    if (nr==80) t.UpdateReference();
+    if (nr<fInnerSec->GetNRows()) 
+      fSectors = fInnerSec;
+    else
+      fSectors = fOuterSec;
     if (FollowToNext(t,nr)==0) 
-      if (!t.IsActive()) return 0;
+      if (!t.IsActive()) 
+       return 0;
     
   }   
   return 1;
@@ -1795,13 +1971,37 @@ Int_t AliTPCtrackerMI::FollowBackProlongation(AliTPCseed& t, Int_t rf) {
   if (alpha < 0.            ) alpha += 2.*TMath::Pi();  
   t.fRelativeSector = Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
     
-  Int_t first = 0;
-  first = t.fFirstPoint+3;
+  Int_t first = t.fFirstPoint;
   //
   if (first<0) first=0;
-  for (Int_t nr=first+1; nr<=rf; nr++) {
+  for (Int_t nr=first; nr<=rf; nr++) {
     //if ( (t.GetSnp()<0.9))
-      FollowToNext(t,nr);                                                             
+    if (t.GetKinkIndexes()[0]<0){
+      for (Int_t i=0;i<3;i++){
+       Int_t index = t.GetKinkIndexes()[i];
+       if (index==0) break;
+       if (index>0) continue;
+       index = TMath::Abs(index);
+       AliESDkink * kink = fEvent->GetKink(index-1);
+       if (!kink){
+         printf("PROBLEM\n");
+       }
+       else{
+         Int_t kinkrow = kink->fRow0-Int_t(1./(0.1+kink->fAngle[2]));
+         if (kinkrow==nr){
+           AliExternalTrackParam paramm(t);
+           kink->SetMother(paramm);
+           kink->Update();
+           kink->fStatus+=10;
+         }
+       }
+      }
+    }
+    if (nr<fInnerSec->GetNRows()) 
+      fSectors = fInnerSec;
+    else
+      fSectors = fOuterSec;
+    FollowToNext(t,nr);                                                             
   }   
   return 1;
 }
@@ -1963,7 +2163,7 @@ void  AliTPCtrackerMI::RemoveDouble(TObjArray * arr, Float_t factor1, Float_t fa
   //sort trackss according sectors
   //
   if (fDebug&1) {
-    printf("Number of tracks before double removal- %d\n",arr->GetEntries());
+    Info("RemoveDouble","Number of tracks before double removal- %d\n",arr->GetEntries());
   }
   //
   for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
@@ -2035,7 +2235,7 @@ void  AliTPCtrackerMI::RemoveDouble(TObjArray * arr, Float_t factor1, Float_t fa
   }
   arr->Compress();
   if (fDebug&1) {
-    printf("Number of tracks after double removal- %d\n",arr->GetEntries());
+    Info("RemoveDouble","Number of tracks after double removal- %d\n",arr->GetEntries());
   }
 }
 
@@ -2044,7 +2244,7 @@ void  AliTPCtrackerMI::RemoveDouble(TObjArray * arr, Float_t factor1, Float_t fa
 
 
 
-void AliTPCtrackerMI::SortTracks(TObjArray * arr, Int_t mode)
+void AliTPCtrackerMI::SortTracks(TObjArray * arr, Int_t mode) const
 {
   //
   //sort tracks in array according mode criteria
@@ -2121,35 +2321,118 @@ void AliTPCtrackerMI::RemoveUsed(TObjArray * arr, Float_t factor1,  Float_t fact
     
   }
   fNtracks = good;
-
-  printf("\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
+  if (fDebug>0){
+    Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
+  }
 }
 
-void AliTPCtrackerMI::UnsignClusters() 
+
+void AliTPCtrackerMI::RemoveUsed2(TObjArray * arr, Float_t factor1,  Float_t factor2, Int_t minimal)
 {
+
+  //Loop over all tracks and remove "overlaps"
   //
-  // loop over all clusters and unsign them
   //
-  
-  for (Int_t sec=0;sec<fkNIS;sec++){
-    for (Int_t row=0;row<fInnerSec->GetNRows();row++){
-      AliTPCclusterMI *cl = fInnerSec[sec][row].fClusters1;
-      for (Int_t icl =0;icl< fInnerSec[sec][row].fN1;icl++)
-       //      if (cl[icl].IsUsed(10))         
-       cl[icl].Use(-1);
-      cl = fInnerSec[sec][row].fClusters2;
-      for (Int_t icl =0;icl< fInnerSec[sec][row].fN2;icl++)
-       //if (cl[icl].IsUsed(10))       
-         cl[icl].Use(-1);      
+  UnsignClusters();
+  //
+  Int_t nseed = arr->GetEntriesFast();  
+  Float_t * quality = new Float_t[nseed];
+  Int_t   * indexes = new Int_t[nseed];
+  Int_t good =0;
+  //
+  //
+  for (Int_t i=0; i<nseed; i++) {
+    AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
+    if (!pt){
+      quality[i]=-1;
+      continue;
     }
+    pt->UpdatePoints();    //select first last max dens points
+    Float_t * points = pt->GetPoints();
+    if (points[3]<0.8) quality[i] =-1;
+    //
+    quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
   }
-  
-  for (Int_t sec=0;sec<fkNOS;sec++){
-    for (Int_t row=0;row<fOuterSec->GetNRows();row++){
-      AliTPCclusterMI *cl = fOuterSec[sec][row].fClusters1;
-      for (Int_t icl =0;icl< fOuterSec[sec][row].fN1;icl++)
-       //if (cl[icl].IsUsed(10))       
-         cl[icl].Use(-1);
+  TMath::Sort(nseed,quality,indexes);
+  //
+  //
+  for (Int_t itrack=0; itrack<nseed; itrack++) {
+    Int_t trackindex = indexes[itrack];
+    AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);    
+    if (quality[trackindex]<0){
+      if (pt) {
+       delete arr->RemoveAt(trackindex);
+      }
+      else{
+       arr->RemoveAt(trackindex);
+      }
+      continue;
+    }
+    //
+    Int_t first = Int_t(pt->GetPoints()[0]);
+    Int_t last  = Int_t(pt->GetPoints()[2]);
+    Double_t factor = (pt->fBConstrain) ? factor1: factor2;
+    //
+    Int_t found,foundable,shared;
+    pt->GetClusterStatistic(first,last, found, foundable,shared,kFALSE);
+    Float_t sharedfactor = Float_t(shared)/Float_t(found);
+    //
+    if (Float_t(shared)/Float_t(found)>factor){
+      if (pt->GetKinkIndexes()[0]!=0) continue;  //don't remove tracks  - part of the kinks
+      delete arr->RemoveAt(trackindex);
+      continue;
+    }
+
+    if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){  //remove short tracks
+      if (pt->GetKinkIndexes()[0]!=0) continue;  //don't remove tracks  - part of the kinks
+      delete arr->RemoveAt(trackindex);
+      continue;
+    }
+
+    good++;
+    if (sharedfactor>0.4) continue;
+    for (Int_t i=first; i<last; i++) {
+      Int_t index=pt->GetClusterIndex2(i);
+      // if (index<0 || index&0x8000 ) continue;
+      if (index<0 || index&0x8000 ) continue;
+      AliTPCclusterMI *c= pt->fClusterPointer[i];        
+      if (!c) continue;
+      c->Use(10);  
+    }    
+  }
+  fNtracks = good;
+  if (fDebug>0){
+    Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
+  }
+  delete []quality;
+  delete []indexes;
+}
+
+void AliTPCtrackerMI::UnsignClusters() 
+{
+  //
+  // loop over all clusters and unsign them
+  //
+  
+  for (Int_t sec=0;sec<fkNIS;sec++){
+    for (Int_t row=0;row<fInnerSec->GetNRows();row++){
+      AliTPCclusterMI *cl = fInnerSec[sec][row].fClusters1;
+      for (Int_t icl =0;icl< fInnerSec[sec][row].fN1;icl++)
+       //      if (cl[icl].IsUsed(10))         
+       cl[icl].Use(-1);
+      cl = fInnerSec[sec][row].fClusters2;
+      for (Int_t icl =0;icl< fInnerSec[sec][row].fN2;icl++)
+       //if (cl[icl].IsUsed(10))       
+         cl[icl].Use(-1);      
+    }
+  }
+  
+  for (Int_t sec=0;sec<fkNOS;sec++){
+    for (Int_t row=0;row<fOuterSec->GetNRows();row++){
+      AliTPCclusterMI *cl = fOuterSec[sec][row].fClusters1;
+      for (Int_t icl =0;icl< fOuterSec[sec][row].fN1;icl++)
+       //if (cl[icl].IsUsed(10))       
+         cl[icl].Use(-1);
       cl = fOuterSec[sec][row].fClusters2;
       for (Int_t icl =0;icl< fOuterSec[sec][row].fN2;icl++)
        //if (cl[icl].IsUsed(10))       
@@ -2318,7 +2601,7 @@ void AliTPCtrackerMI::SignClusters(TObjArray * arr, Float_t fnumber, Float_t fde
 }
 
 
-void  AliTPCtrackerMI::StopNotActive(TObjArray * arr, Int_t row0, Float_t th0, Float_t th1, Float_t th2)
+void  AliTPCtrackerMI::StopNotActive(TObjArray * arr, Int_t row0, Float_t th0, Float_t th1, Float_t th2) const
 {
   // stop not active tracks
   // take th1 as threshold for number of founded to number of foundable on last 10 active rows
@@ -2338,7 +2621,7 @@ void  AliTPCtrackerMI::StopNotActive(TObjArray * arr, Int_t row0, Float_t th0, F
 
 
 void  AliTPCtrackerMI::StopNotActive(AliTPCseed * seed, Int_t row0, Float_t th0, Float_t th1,
- Float_t th2)
+ Float_t th2) const
 {
   // stop not active tracks
   // take th1 as threshold for number of founded to number of foundable on last 10 active rows
@@ -2372,6 +2655,43 @@ void  AliTPCtrackerMI::StopNotActive(AliTPCseed * seed, Int_t row0, Float_t th0,
 }
 
 
+Int_t AliTPCtrackerMI::RefitInward(AliESD *event)
+{
+  //
+  // back propagation of ESD tracks
+  //
+  //return 0;
+  fEvent = event;
+  ReadSeeds(event,2);
+  fIteration=2;
+  //PrepareForProlongation(fSeeds,1);
+  PropagateForward2(fSeeds);
+  Int_t ntracks=0;
+  Int_t nseed = fSeeds->GetEntriesFast();
+  for (Int_t i=0;i<nseed;i++){
+    AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
+    if (!seed) continue;
+    seed->PropagateTo(fParam->GetInnerRadiusLow());
+    seed->UpdatePoints();
+    AliESDtrack *esd=event->GetTrack(i);
+    seed->CookdEdx(0.02,0.6);
+    CookLabel(seed,0.1); //For comparison only
+    if (seed->GetNumberOfClusters()>15){
+      esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit); 
+      esd->SetTPCPoints(seed->GetPoints());
+      ntracks++;
+    }
+    else{
+      //printf("problem\n");
+    }
+  }
+  //FindKinks(fSeeds,event);
+  Info("RefitInward","Number of refitted tracks %d",ntracks);
+  fEvent =0;
+  //WriteTracks();
+  return 0;
+}
+
 
 Int_t AliTPCtrackerMI::PropagateBack(AliESD *event)
 {
@@ -2380,24 +2700,37 @@ Int_t AliTPCtrackerMI::PropagateBack(AliESD *event)
   //
 
   fEvent = event;
-  ReadSeeds(event);
+  fIteration = 1;
+  ReadSeeds(event,0);
   PropagateBack(fSeeds);
   Int_t nseed = fSeeds->GetEntriesFast();
+  Int_t ntracks=0;
   for (Int_t i=0;i<nseed;i++){
     AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
+    if (!seed) continue;
+    if (seed->GetKinkIndex(0)<0)  UpdateKinkQualityM(seed);  // update quality informations for kinks
+    seed->UpdatePoints();
     AliESDtrack *esd=event->GetTrack(i);
-    seed->CookdEdx(0.02,0.06);
+    seed->CookdEdx(0.02,0.6);
     CookLabel(seed,0.1); //For comparison only
-    esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
+    if (seed->GetNumberOfClusters()>15){
+      esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
+      esd->SetTPCPoints(seed->GetPoints());
+      ntracks++;
+    }
   }
+  //FindKinks(fSeeds,event);
+  Info("PropagateBack","Number of back propagated tracks %d",ntracks);
   fEvent =0;
-  WriteTracks();
+  //WriteTracks();
   return 0;
 }
 
 
 void AliTPCtrackerMI::DeleteSeeds()
 {
+  //
+  //delete Seeds
   Int_t nseed = fSeeds->GetEntriesFast();
   for (Int_t i=0;i<nseed;i++){
     AliTPCseed * seed = (AliTPCseed*)fSeeds->At(i);
@@ -2407,26 +2740,49 @@ void AliTPCtrackerMI::DeleteSeeds()
   fSeeds =0;
 }
 
-void AliTPCtrackerMI::ReadSeeds(AliESD *event)
+void AliTPCtrackerMI::ReadSeeds(AliESD *event, Int_t direction)
 {
   //
   //read seeds from the event
   
   Int_t nentr=event->GetNumberOfTracks();
-  Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
+  if (fDebug>0){
+    Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
+  }
   if (fSeeds) 
     DeleteSeeds();
   if (!fSeeds){   
-    fSeeds = new TObjArray;
+    fSeeds = new TObjArray(nentr);
   }
-  
-  //  Int_t ntrk=0;
+  UnsignClusters();
+  //  Int_t ntrk=0;  
   for (Int_t i=0; i<nentr; i++) {
     AliESDtrack *esd=event->GetTrack(i);
-    ULong_t status=esd->GetStatus();    
-    const AliTPCtrack t(*esd);
-    AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
-    if (status==AliESDtrack::kTPCin) seed->Modify(0.8);
+    ULong_t status=esd->GetStatus();
+    if (!(status&AliESDtrack::kTPCin)) continue;
+    AliTPCtrack t(*esd);
+    AliTPCseed *seed=new AliTPCseed(t/*,t.GetAlpha()*/);seed->ResetClusters();
+    for (Int_t ikink=0;ikink<3;ikink++) seed->GetKinkIndexes()[ikink] = esd->GetKinkIndex(ikink);
+    if ((status==AliESDtrack::kTPCin)&&(direction==1)) seed->ResetCovariance(); 
+    if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance();
+    if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
+      fSeeds->AddAt(0,i);
+      delete seed;
+      continue;    
+    }
+    if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) > 0 )  {
+      Double_t par0[5],par1[5],x;
+      esd->GetInnerExternalParameters(x,par0);
+      esd->GetExternalParameters(x,par1);
+      Double_t delta1 = TMath::Abs(par0[4]-par1[4])/(0.000000001+TMath::Abs(par0[4]+par1[4]));
+      Double_t delta2 = TMath::Abs(par0[3]-par1[3]);
+      Double_t trdchi2=0;
+      if (esd->GetTRDncls()>0) trdchi2 = esd->GetTRDchi2()/esd->GetTRDncls();
+      //reset covariance if suspicious 
+      if ( (delta1>0.1) || (delta2>0.006) ||trdchi2>7.)
+       seed->ResetCovariance();
+    }
+
     //
     //
     // rotate to the local coordinate system
@@ -2438,15 +2794,46 @@ void AliTPCtrackerMI::ReadSeeds(AliESD *event)
     if (alpha < 0.            ) alpha += 2.*TMath::Pi();
     Int_t ns=Int_t(alpha/fSectors->GetAlpha())%fN;
     alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
+    if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
+    if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
     alpha-=seed->GetAlpha();  
-    if (!seed->Rotate(alpha)) continue;
+    if (!seed->Rotate(alpha)) {
+      delete seed;
+      continue;
+    }
+    seed->fEsd = esd;
     //
-    seed->PropagateTo(fSectors->GetX(0));
+    //seed->PropagateTo(fSectors->GetX(0));
     //
     //    Int_t index = esd->GetTPCindex();
     //AliTPCseed * seed2= (AliTPCseed*)fSeeds->At(index);
-    
-    fSeeds->AddLast(seed);
+    //if (direction==2){
+    //  AliTPCseed * seed2  = ReSeed(seed,0.,0.5,1.);
+    //  if (seed2) {
+    // delete seed;
+    // seed = seed2;
+    //  }
+    //}
+    //
+    // sign clusters
+    for (Int_t irow=0;irow<160;irow++){
+      Int_t index = seed->GetClusterIndex2(irow);    
+      if (index>0){ 
+       //
+       AliTPCclusterMI * cl = GetClusterMI(index);
+       seed->fClusterPointer[irow] = cl;
+       if (cl){
+         if ((index & 0x8000)==0){
+           cl->Use(10);  // accepted cluster     
+         }else{
+           cl->Use(6);   // close cluster not accepted
+         }     
+       }else{
+          Info("ReadSeeds","Not found cluster");
+       }
+      }
+    }
+    fSeeds->AddAt(seed,i);
   }
 }
 
@@ -2582,8 +2969,8 @@ void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
        
        //Double_t dfi0   = 2.*TMath::ASin(dvertex*c0*0.5);
        //Double_t dfi1   = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
-       Double_t dfi0   = 2.*TPCFastMath::FastAsin(dvertex*c0*0.5);
-       Double_t dfi1   = 2.*TPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);  
+       Double_t dfi0   = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
+       Double_t dfi1   = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);  
        //
        //
        Double_t z0  =  kcl->GetZ();  
@@ -2659,17 +3046,17 @@ void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
        Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
        //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
 
-       Double_t f40=(f1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
-       Double_t f42=(f1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
-       Double_t f43=(f1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
-       Double_t f20=(f2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
-       Double_t f22=(f2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
-       Double_t f23=(f2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
+       Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
+       Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
+       Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
+       Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
+       Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
+       Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
        
-       Double_t f30=(f3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
-       Double_t f31=(f3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
-       Double_t f32=(f3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
-       Double_t f34=(f3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
+       Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
+       Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
+       Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
+       Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
        
         c[0]=sy1;
         c[1]=0.;       c[2]=sz1;
@@ -2762,8 +3149,8 @@ void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
       }
     }
   }
-  if (fDebug>1){
-    //    printf("\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
+  if (fDebug>3){
+    Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
   }
   delete seed;
 }
@@ -2934,14 +3321,14 @@ void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
                        
       x[0]=y1;
       x[1]=z1;
-      x[4]=f1(x1,y1,x2,y2,x3,y3);
+      x[4]=F1(x1,y1,x2,y2,x3,y3);
       //if (TMath::Abs(x[4]) >= cuts[0]) continue;
       nin0++;
       //
-      x[2]=f2(x1,y1,x2,y2,x3,y3);
+      x[2]=F2(x1,y1,x2,y2,x3,y3);
       nin1++;
       //
-      x[3]=f3n(x1,y1,x2,y2,z1,z2,x[4]);
+      x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
       //if (TMath::Abs(x[3]) > cuts[3]) continue;
       nin2++;
       //
@@ -2950,17 +3337,17 @@ void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
       Double_t sy2=0.1,  sz2=0.1;
       Double_t sy3=0.1,  sy=0.1, sz=0.1;
       
-      Double_t f40=(f1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
-      Double_t f42=(f1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
-      Double_t f43=(f1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
-      Double_t f20=(f2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
-      Double_t f22=(f2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
-      Double_t f23=(f2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
+      Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
+      Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
+      Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
+      Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
+      Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
+      Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
       
-      Double_t f30=(f3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
-      Double_t f31=(f3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
-      Double_t f32=(f3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
-      Double_t f34=(f3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
+      Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
+      Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
+      Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
+      Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
       
       c[0]=sy1;
       c[1]=0.;       c[2]=sz1; 
@@ -3020,8 +3407,8 @@ void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
     }
   }
   
-  if (fDebug>1){
-    //    printf("\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2,nout3);
+  if (fDebug>3){
+    Info("MakeSeeds5","\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2,nout3);
   }
   delete seed;
 }
@@ -3206,14 +3593,14 @@ void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
        }
        x[0]=y1;
        x[1]=z1;
-       x[4]=f1(x1,y1,x2,y2,x3,y3);
+       x[4]=F1(x1,y1,x2,y2,x3,y3);
                
        //      if (TMath::Abs(x[4]) >= cuts[0]) continue;  //
-       x[2]=f2(x1,y1,x2,y2,x3,y3);
+       x[2]=F2(x1,y1,x2,y2,x3,y3);
        
        //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
-       //x[3]=f3(x1,y1,x2,y2,z1,z2);
-       x[3]=f3n(x1,y1,x3,y3,z1,z3,x[4]);
+       //x[3]=F3(x1,y1,x2,y2,z1,z2);
+       x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
        //if (TMath::Abs(x[3]) > cuts[3]) continue;
 
        
@@ -3226,17 +3613,17 @@ void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
          sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
        }
        
-       Double_t f40=(f1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
-       Double_t f42=(f1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
-       Double_t f43=(f1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
-       Double_t f20=(f2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
-       Double_t f22=(f2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
-       Double_t f23=(f2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
-
-       Double_t f30=(f3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
-       Double_t f31=(f3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
-       Double_t f32=(f3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
-       Double_t f34=(f3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
+       Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
+       Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
+       Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
+       Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
+       Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
+       Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
+
+       Double_t f30=(F3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
+       Double_t f31=(F3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
+       Double_t f32=(F3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
+       Double_t f34=(F3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
 
        
        c[0]=sy1;
@@ -3277,8 +3664,8 @@ void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
       }
     }  // if accepted seed
   }
-  if (fDebug>1){
-    printf("\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
+  if (fDebug>3){
+    Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
   }
   delete seed;
 }
@@ -3288,7 +3675,7 @@ AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *track, Float_t r0, Float_t r1,
 {
   //
   //
-  //reseed
+  //reseed using track points
   Int_t p0 = int(r0*track->GetNumberOfClusters());     // point 0 
   Int_t p1 = int(r1*track->GetNumberOfClusters());
   Int_t p2 = int(r2*track->GetNumberOfClusters());   // last point
@@ -3367,10 +3754,10 @@ AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *track, Float_t r0, Float_t r1,
   //
   x[0]=x2[1];
   x[1]=x2[2];
-  x[4]=f1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
+  x[4]=F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
   //  if (x[4]>1) return 0;
-  x[2]=f2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
-  x[3]=f3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
+  x[2]=F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
+  x[3]=F3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
   //if (TMath::Abs(x[3]) > 2.2)  return 0;
   //if (TMath::Abs(x[2]) > 1.99) return 0;
   //  
@@ -3380,17 +3767,17 @@ AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *track, Float_t r0, Float_t r1,
   Double_t sy2=0.01+track->GetSigmaY2(), sz2=0.01+track->GetSigmaZ2();
   Double_t sy3=0.01+track->GetSigmaY2();
   //
-  Double_t f40=(f1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
-  Double_t f42=(f1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
-  Double_t f43=(f1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
-  Double_t f20=(f2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
-  Double_t f22=(f2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
-  Double_t f23=(f2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
-  //
-  Double_t f30=(f3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
-  Double_t f31=(f3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
-  Double_t f32=(f3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
-  Double_t f34=(f3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
+  Double_t f40=(F1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
+  Double_t f42=(F1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
+  Double_t f43=(F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
+  Double_t f20=(F2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
+  Double_t f22=(F2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
+  Double_t f23=(F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
+  //
+  Double_t f30=(F3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
+  Double_t f31=(F3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
+  Double_t f32=(F3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
+  Double_t f34=(F3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
   
   
   c[0]=sy1;
@@ -3416,6 +3803,451 @@ AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *track, Float_t r0, Float_t r1,
   return seed;
 }
 
+
+AliTPCseed *AliTPCtrackerMI::ReSeed(AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
+{
+  //
+  //
+  //reseed using founded clusters 
+  //
+  // Find the number of clusters
+  Int_t nclusters = 0;
+  for (Int_t irow=0;irow<160;irow++){
+    if (track->GetClusterIndex(irow)>0) nclusters++;
+  }
+  //
+  Int_t ipos[3];
+  ipos[0] = TMath::Max(int(r0*nclusters),0);             // point 0 cluster
+  ipos[1] = TMath::Min(int(r1*nclusters),nclusters-1);   // 
+  ipos[2] = TMath::Min(int(r2*nclusters),nclusters-1);   // last point
+  //
+  //
+  Double_t  xyz[3][3];
+  Int_t     row[3],sec[3]={0,0,0};
+  //
+  // find track row position at given ratio of the length
+  Int_t index=-1;
+  for (Int_t irow=0;irow<160;irow++){    
+    if (track->GetClusterIndex2(irow)<0) continue;
+    index++;
+    for (Int_t ipoint=0;ipoint<3;ipoint++){
+      if (index<=ipos[ipoint]) row[ipoint] = irow;
+    }        
+  }
+  //
+  //Get cluster and sector position
+  for (Int_t ipoint=0;ipoint<3;ipoint++){
+    Int_t clindex = track->GetClusterIndex2(row[ipoint]);
+    AliTPCclusterMI * cl = GetClusterMI(clindex);
+    if (cl==0) {
+      //Error("Bug\n");
+      //      AliTPCclusterMI * cl = GetClusterMI(clindex);
+      return 0;
+    }
+    sec[ipoint]     = ((clindex&0xff000000)>>24)%18;
+    xyz[ipoint][0]  = GetXrow(row[ipoint]);
+    xyz[ipoint][1]  = cl->GetY();
+    xyz[ipoint][2]  = cl->GetZ();
+  }
+  //
+  //
+  // Calculate seed state vector and covariance matrix
+
+  Double_t alpha, cs,sn, xx2,yy2;
+  //
+  alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
+  cs = TMath::Cos(alpha);
+  sn = TMath::Sin(alpha); 
+  xx2= xyz[1][0]*cs-xyz[1][1]*sn;
+  yy2= xyz[1][0]*sn+xyz[1][1]*cs;
+  xyz[1][0] = xx2;
+  xyz[1][1] = yy2;
+  //
+  alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
+  cs = TMath::Cos(alpha);
+  sn = TMath::Sin(alpha); 
+  xx2= xyz[0][0]*cs-xyz[0][1]*sn;
+  yy2= xyz[0][0]*sn+xyz[0][1]*cs;
+  xyz[0][0] = xx2;
+  xyz[0][1] = yy2;
+  //
+  //
+  //
+  Double_t x[5],c[15];
+  //
+  x[0]=xyz[2][1];
+  x[1]=xyz[2][2];
+  x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
+  x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
+  x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
+  //  
+  Double_t sy =0.1,  sz =0.1;
+  //
+  Double_t sy1=0.2, sz1=0.2;
+  Double_t sy2=0.2, sz2=0.2;
+  Double_t sy3=0.2;
+  //
+  Double_t f40=(F1(xyz[2][0],xyz[2][1]+sy,xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1])-x[4])/sy;
+  Double_t f42=(F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1]+sy,xyz[0][0],xyz[0][1])-x[4])/sy;
+  Double_t f43=(F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]+sy)-x[4])/sy;
+  Double_t f20=(F2(xyz[2][0],xyz[2][1]+sy,xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1])-x[2])/sy;
+  Double_t f22=(F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1]+sy,xyz[0][0],xyz[0][1])-x[2])/sy;
+  Double_t f23=(F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]+sy)-x[2])/sy;
+  //
+  Double_t f30=(F3(xyz[2][0],xyz[2][1]+sy,xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2])-x[3])/sy;
+  Double_t f31=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2]+sz,xyz[0][2])-x[3])/sz;
+  Double_t f32=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1]+sy,xyz[2][2],xyz[0][2])-x[3])/sy;
+  Double_t f34=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2]+sz)-x[3])/sz;
+  
+  
+  c[0]=sy1;
+  c[1]=0.;       c[2]=sz1;
+  c[3]=f20*sy1;  c[4]=0.;       c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
+  c[6]=f30*sy1;  c[7]=f31*sz1;  c[8]=f30*sy1*f20+f32*sy2*f22;
+  c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
+  c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
+  c[13]=f30*sy1*f40+f32*sy2*f42;
+  c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
+  
+  //  Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
+  AliTPCseed *seed=new  AliTPCseed(0, x, c, xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift());
+  seed->fLastPoint  = row[2];
+  seed->fFirstPoint = row[2];  
+  return seed;
+}
+
+void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
+{
+  //
+  //  find kinks
+  //
+  //
+  TObjArray *kinks= new TObjArray(10000);
+  Int_t nentries = array->GetEntriesFast();
+  AliHelix *helixes      = new AliHelix[nentries];
+  Int_t    *sign         = new Int_t[nentries];
+  Int_t    *nclusters    = new Int_t[nentries];
+  Float_t  *alpha        = new Float_t[nentries];
+  AliESDkink * kink      = new AliESDkink();
+  Int_t      * usage     = new Int_t[nentries];
+  Float_t  *zm             = new Float_t[nentries];
+  Float_t  *fim            = new Float_t[nentries];
+
+  //
+  //
+  for (Int_t i=0;i<nentries;i++){
+    sign[i]=0;
+    usage[i]=0;
+    AliTPCseed* track = (AliTPCseed*)array->At(i);    
+    if (!track) continue;
+    track->UpdatePoints();
+    if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
+      nclusters[i]=track->GetNumberOfClusters();
+      alpha[i] = track->GetAlpha();
+      new (&helixes[i]) AliHelix(*track);
+      sign[i] = (track->GetC()>0) ? -1:1;
+      Double_t x,y,z;
+      x=160;
+      if (track->GetProlongation(x,y,z)){
+       zm[i]  = z;
+       fim[i] = alpha[i]+TMath::ATan2(y,x);
+      }
+      else{
+       zm[i]  = track->GetZ();
+       fim[i] = alpha[i];
+      }
+    }
+  }
+  //
+  //
+  TStopwatch timer;
+  timer.Start();
+  Int_t ncandidates =0;
+  Int_t nall =0;
+  Int_t ntracks=0; 
+  Double_t phase[2][2],radius[2];
+  //
+  //
+  for (Int_t i =0;i<nentries;i++){
+    if (sign[i]==0) continue;
+    AliTPCseed * track0 = (AliTPCseed*)array->At(i);
+    ntracks++;
+    //
+    Double_t cradius0 = 40*40;
+    Double_t cradius1 = 270*270;
+    Double_t cdist1=8.;
+    Double_t cdist2=8.;
+    Double_t cdist3=0.55; 
+    for (Int_t j =i+1;j<nentries;j++){
+      nall++;
+      if (sign[j]*sign[i]<1) continue;
+      if ( (nclusters[i]+nclusters[j])>200) continue;
+      if ( (nclusters[i]+nclusters[j])<80) continue;
+      if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
+      if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
+      //AliTPCseed * track1 = (AliTPCseed*)array->At(j);  Double_t phase[2][2],radius[2];    
+      Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
+      if (npoints<1) continue;
+      // cuts on radius      
+      if (npoints==1){
+       if (radius[0]<cradius0||radius[0]>cradius1) continue;
+      }
+      else{
+       if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
+      }
+      //      
+      Double_t delta1=10000,delta2=10000;
+      // cuts on the intersection radius
+      helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
+      if (radius[0]<20&&delta1<1) continue; //intersection at vertex
+      if (radius[0]<10&&delta1<3) continue; //intersection at vertex
+      if (npoints==2){ 
+       helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
+       if (radius[1]<20&&delta2<1) continue;  //intersection at vertex
+       if (radius[1]<10&&delta2<3) continue;  //intersection at vertex 
+      }
+      //
+      Double_t distance1 = TMath::Min(delta1,delta2);
+      if (distance1>cdist1) continue;  // cut on DCA linear approximation
+      //
+      npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
+      helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
+      if (radius[0]<20&&delta1<1) continue; //intersection at vertex
+      if (radius[0]<10&&delta1<3) continue; //intersection at vertex
+      //
+      if (npoints==2){ 
+       helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);   
+       if (radius[1]<20&&delta2<1) continue;  //intersection at vertex
+       if (radius[1]<10&&delta2<3) continue;  //intersection at vertex 
+      }            
+      distance1 = TMath::Min(delta1,delta2);
+      Float_t rkink =0;
+      if (delta1<delta2){
+       rkink = TMath::Sqrt(radius[0]);
+      }
+      else{
+       rkink = TMath::Sqrt(radius[1]);
+      }
+      if (distance1>cdist2) continue;
+      //
+      //
+      AliTPCseed * track1 = (AliTPCseed*)array->At(j);
+      //
+      //
+      Int_t row0 = GetRowNumber(rkink); 
+      if (row0<10)  continue;
+      if (row0>150) continue;
+      //
+      //
+      Float_t dens00=-1,dens01=-1;
+      Float_t dens10=-1,dens11=-1;
+      //
+      Int_t found,foundable,shared;
+      track0->GetClusterStatistic(0,row0-5, found, foundable,shared,kFALSE);
+      if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
+      track0->GetClusterStatistic(row0+5,155, found, foundable,shared,kFALSE);
+      if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
+      //
+      track1->GetClusterStatistic(0,row0-5, found, foundable,shared,kFALSE);
+      if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
+      track1->GetClusterStatistic(row0+5,155, found, foundable,shared,kFALSE);
+      if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
+      //
+      if (dens00<dens10 && dens01<dens11) continue;
+      if (dens00>dens10 && dens01>dens11) continue;
+      if (TMath::Max(dens00,dens10)<0.1)  continue;
+      if (TMath::Max(dens01,dens11)<0.3)  continue;
+      //
+      if (TMath::Min(dens00,dens10)>0.6)  continue;
+      if (TMath::Min(dens01,dens11)>0.6)  continue;
+
+      //
+      AliTPCseed * ktrack0, *ktrack1;
+      if (dens00>dens10){
+       ktrack0 = track0;
+       ktrack1 = track1;
+      }
+      else{
+       ktrack0 = track1;
+       ktrack1 = track0;
+      }
+      if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
+      AliExternalTrackParam paramm(*ktrack0);
+      AliExternalTrackParam paramd(*ktrack1);
+      if (row0>60&&ktrack1->GetReference().X()>90.) new (&paramd) AliExternalTrackParam(ktrack1->GetReference()); 
+      //
+      //
+      kink->SetMother(paramm);
+      kink->SetDaughter(paramd);
+      kink->Update();
+
+      Float_t x[3] = { kink->fXr[0],kink->fXr[1],kink->fXr[2]};
+      Int_t index[4];
+      fParam->Transform0to1(x,index);
+      fParam->Transform1to2(x,index);
+      row0 = GetRowNumber(x[0]); 
+
+      if (kink->fRr<100) continue;
+      if (kink->fRr>240) continue;
+      if (kink->fDist2>cdist3) continue;
+      Float_t dird = kink->fPdr[0]*kink->fXr[0]+kink->fPdr[1]*kink->fXr[1];  // rough direction estimate
+      if (dird<0) continue;
+
+      Float_t dirm = kink->fPm[0]*kink->fXr[0]+kink->fPm[1]*kink->fXr[1];  // rough direction estimate
+      if (dirm<0) continue;
+      Float_t mpt = TMath::Sqrt(kink->fPm[0]*kink->fPm[0]+kink->fPm[1]*kink->fPm[1]);
+      if (mpt<0.2) continue;
+
+
+      Double_t qt   =  TMath::Sin(kink->fAngle[2])*ktrack1->P();
+      if (qt>0.35) continue; 
+      
+      kink->fLab[0] = CookLabel(ktrack0,0.4,0,row0);
+      kink->fLab[1] = CookLabel(ktrack1,0.4,row0,160);
+      if (dens00>dens10){
+       kink->fTPCdensity[0][0] = dens00;
+       kink->fTPCdensity[0][1] = dens01;
+       kink->fTPCdensity[1][0] = dens10;
+       kink->fTPCdensity[1][1] = dens11;
+       kink->fIndex[0] = i;
+       kink->fIndex[1] = j;
+       kink->fZm[0] = zm[i];
+       kink->fZm[1] = zm[j];
+       kink->fFi[0] = fim[i];
+       kink->fFi[1] = fim[j];
+      }
+      else{
+       kink->fTPCdensity[0][0] = dens10;
+       kink->fTPCdensity[0][1] = dens11;
+       kink->fTPCdensity[1][0] = dens00;
+       kink->fTPCdensity[1][1] = dens01;
+       kink->fIndex[0] = j;
+       kink->fIndex[1] = i;
+       kink->fZm[0] = zm[j];
+       kink->fZm[1] = zm[i];
+       kink->fFi[0] = fim[j];
+       kink->fFi[1] = fim[i];
+
+      }
+      if (kink->GetTPCDensityFactor()<0.8) continue;
+      if ((2-kink->GetTPCDensityFactor())*kink->fDist2 >0.25) continue;
+      if (kink->fAngle[2]*ktrack0->P()<0.003) continue; //too small angle
+      if (kink->fAngle[2]>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
+      if (kink->fAngle[2]>0.2&&kink->fTPCdensity[0][1]) continue;
+      if (kink->fAngle[2]<0.02) continue;
+
+
+      //
+      Int_t drow = Int_t(2./TMath::Tan(0.3+kink->fAngle[2]));  // overlap region defined
+      kink->fRow0 = row0;
+      Float_t shapesum =0;
+      Float_t sum = 0;
+      for ( Int_t row = row0-drow; row<row0+drow;row++){
+       if (row<0) continue;
+       if (row>155) continue;
+       if (ktrack0->fClusterPointer[row]){
+         AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
+         shapesum+=point->GetSigmaY()+point->GetSigmaZ();
+         sum++;
+       }
+       if (ktrack1->fClusterPointer[row]){
+         AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
+         shapesum+=point->GetSigmaY()+point->GetSigmaZ();
+         sum++;
+       }       
+      }
+      if (sum<4){
+       kink->fShapeFactor=-1;
+      }
+      else{
+       kink->fShapeFactor = shapesum/sum;
+      }
+      
+      //      esd->AddKink(kink);
+      kinks->AddLast(kink);
+      kink = new AliESDkink;
+      ncandidates++;
+    }
+  }
+  Int_t nkinks = kinks->GetEntriesFast();
+  Float_t *quality     = new Float_t[nkinks];
+  Int_t   * indexes = new Int_t[nkinks];
+  for (Int_t i=0;i<nkinks;i++){
+    quality[i] =100000;
+    AliESDkink *kink = (AliESDkink*)kinks->At(i);
+    if (kink) quality[i] = kink->fDist2*(2.-kink->GetTPCDensityFactor());
+  }
+  TMath::Sort(nkinks,quality,indexes,kFALSE);
+  
+  for (Int_t i=0;i<nkinks;i++){
+    AliESDkink * kink = (AliESDkink*) kinks->At(indexes[i]);
+    Int_t index0 = kink->fIndex[0];
+    Int_t index1 = kink->fIndex[1];
+    kink->fMultiple[0] = usage[index0];
+    kink->fMultiple[1] = usage[index1];
+    if (kink->fMultiple[0]+kink->fMultiple[1]>2) continue;
+    if (kink->fMultiple[0]+kink->fMultiple[1]>0 && quality[indexes[i]]>0.2) continue;
+
+    Int_t index = esd->AddKink(kink);
+    AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
+    AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
+    ktrack0->fKinkIndexes[usage[index0]] = -(index+1);
+    ktrack1->fKinkIndexes[usage[index1]] =  (index+1);
+    usage[index0]++;
+    usage[index1]++;
+  }
+  delete [] quality;
+  delete [] indexes;
+
+  delete[] fim;
+  delete[] zm;
+  delete [] usage;
+  delete[] alpha;
+  delete[] nclusters;
+  delete[] sign;
+  delete[] helixes;
+  kinks->Delete();
+  delete kinks;
+
+  printf("Ncandidates=\t%d\t%d\t%d\n",ncandidates,ntracks,nall);
+  timer.Print();
+}
+
+
+
+void AliTPCtrackerMI::UpdateKinkQualityM(AliTPCseed * seed){
+  //
+  // update Kink quality information for mother after back propagation
+  //
+  if (seed->GetKinkIndex(0)>=0) return; 
+  for (Int_t ikink=0;ikink<3;ikink++){
+    Int_t index = seed->GetKinkIndex(ikink);
+    if (index>=0) break;
+    index = TMath::Abs(index)-1;
+    AliESDkink * kink = fEvent->GetKink(index);
+    kink->fTPCdensity2[0][0]=-1;
+    kink->fTPCdensity2[0][1]=-1;
+    //
+    Int_t row0 = kink->fRow0 - Int_t( 2./ (0.05+kink->fAngle[2]));
+    if (row0<15) row0=15;
+    //
+    Int_t row1 = kink->fRow0 + Int_t( 2./ (0.05+kink->fAngle[2]));
+    if (row1>145) row1=145;
+    //
+    Int_t found,foundable,shared;
+    seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
+    if (foundable>5)   kink->fTPCdensity2[0][0] = Float_t(found)/Float_t(foundable);
+    seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
+    if (foundable>5)   kink->fTPCdensity2[0][1] = Float_t(found)/Float_t(foundable);
+    if (kink->fTPCdensity2[0][1]>0.5) kink->fStatus=-100000;
+    if (kink->fTPCdensity2[0][0]<0.5) kink->fStatus=-100000;
+    if (kink->fTPCdensity2[0][0]-kink->fTPCdensity2[0][1]<0.2) kink->fStatus=-100000;
+
+    if (kink->fDist2>1) kink->fStatus=-10000;
+  }
+    
+}
+
 Int_t  AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed, Float_t th)
 {
   //
@@ -3495,9 +4327,9 @@ Int_t  AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed, Float_t th)
   Double_t xh[5],xm = x[padm];  
   xh[0]=yt[i2];
   xh[1]=zt[i2];
-  xh[4]=f1(xt[i2],yt[i2],xt[padm],yt[padm],xt[i1],yt[i1]);  
-  xh[2]=f2(xt[i2],yt[i2],xt[padm],yt[padm],xt[i1],yt[i1]);
-  xh[3]=f3n(xt[i2],yt[i2],xt[i1],yt[i1],zt[i2],zt[i1],xh[4]);
+  xh[4]=F1(xt[i2],yt[i2],xt[padm],yt[padm],xt[i1],yt[i1]);  
+  xh[2]=F2(xt[i2],yt[i2],xt[padm],yt[padm],xt[i1],yt[i1]);
+  xh[3]=F3n(xt[i2],yt[i2],xt[i1],yt[i1],zt[i2],zt[i1],xh[4]);
   //
   //
   for (Int_t i=i1;i<=i2;i++){
@@ -3506,9 +4338,9 @@ Int_t  AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed, Float_t th)
     GetProlongation(x[i2], x[i],xh,yy,zz);
     if (TMath::Abs(y[i]-yy)>4||TMath::Abs(z[i]-zz)>4){
       //Double_t xxh[5];
-      //xxh[4]=f1old(x[i2],y[i2],x[padm],y[padm],x[i1],y[i1]);  
-      //xxh[2]=f2old(x[i2],y[i2],x[padm],y[padm],x[i1],y[i1]);
-      printf("problem\n");
+      //xxh[4]=F1old(x[i2],y[i2],x[padm],y[padm],x[i1],y[i1]);  
+      //xxh[2]=F2old(x[i2],y[i2],x[padm],y[padm],x[i1],y[i1]);
+      Error("AliTPCtrackerMI::CheckKinkPoint","problem\n");
     }
     y[i] = y[i] - yy;
     z[i] = z[i] - zz;
@@ -3719,7 +4551,8 @@ Int_t AliTPCtrackerMI::ReadSeeds(const TFile *inp) {
   Int_t n=(Int_t)seedTree->GetEntries();
   for (Int_t i=0; i<n; i++) {
      seedTree->GetEvent(i);
-     fSeeds->AddLast(new AliTPCseed(*seed,seed->GetAlpha()));
+     seed->ResetClusters();
+     fSeeds->AddLast(new AliTPCseed(*seed/*,seed->GetAlpha()*/));
   }
   
   delete seed;
@@ -3728,6 +4561,19 @@ Int_t AliTPCtrackerMI::ReadSeeds(const TFile *inp) {
   return 0;
 }
 
+Int_t AliTPCtrackerMI::Clusters2Tracks (AliESD *esd)
+{
+  //
+  if (fSeeds) DeleteSeeds();
+  fEvent = esd;
+  Clusters2Tracks();
+  if (!fSeeds) return 1;
+  FillESD(fSeeds);
+  return 0;
+  //
+}
+
+
 //_____________________________________________________________________________
 Int_t AliTPCtrackerMI::Clusters2Tracks() {
   //-----------------------------------------------------------------
@@ -3735,20 +4581,13 @@ Int_t AliTPCtrackerMI::Clusters2Tracks() {
   //-----------------------------------------------------------------
   TDirectory *savedir=gDirectory; 
   TStopwatch timer;
-  //
-  if (!fInput) SetIO();  //set default IO using loaders
-  if (!fInput){
-     cerr<<"AliTPCtrackerMI::Clusters2Tracks(): input file is not open !\n";
-     return 1;
-  }
-  LoadClusters();
-  //
+
   fIteration = 0;
   fSeeds = Tracking();
 
-
-  printf("Time for tracking: \t");timer.Print();timer.Start();
-
+  if (fDebug>0){
+    Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
+  }
   //activate again some tracks
   for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
     AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;    
@@ -3767,11 +4606,12 @@ Int_t AliTPCtrackerMI::Clusters2Tracks() {
       }
     } 
   }
-  RemoveDouble(fSeeds,0.2,0.6,11);
-  //RemoveUsed(fSeeds,0.9,0.9,6);
-  //RemoveUsed(fSeeds,0.8,0.8,6);
-  //RemoveUsed(fSeeds,0.7,0.7,6);
-  RemoveUsed(fSeeds,0.5,0.5,6);
+  //
+  RemoveUsed2(fSeeds,0.85,0.85,0);
+  FindKinks(fSeeds,fEvent);
+  RemoveUsed2(fSeeds,0.5,0.4,30);
+  //RemoveDouble(fSeeds,0.2,0.6,11);
+  //  RemoveUsed(fSeeds,0.5,0.5,6);
 
   //
   Int_t nseed=fSeeds->GetEntriesFast();
@@ -3787,11 +4627,12 @@ Int_t AliTPCtrackerMI::Clusters2Tracks() {
     CookLabel(pt,0.1); //For comparison only
     //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
     if ((pt->IsActive() || (pt->fRemoval==10) )){
-      cerr<<found++<<'\r';      
+      found++;      
+      if (fDebug>0) cerr<<found<<'\r';      
+      pt->fLab2 = i;
     }
     else
       delete fSeeds->RemoveAt(i);
-    pt->fLab2 = i;
   }
 
   
@@ -3814,34 +4655,43 @@ Int_t AliTPCtrackerMI::Clusters2Tracks() {
     //    CheckKinkPoint(&t,0.05);
     //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
     if ((pt->IsActive() || (pt->fRemoval==10) )){
-      cerr<<found++<<'\r';      
+      found++;
+      if (fDebug>0){
+       cerr<<found<<'\r';      
+      }
+      pt->fLab2 = i;
     }
     else
       delete fSeeds->RemoveAt(i);
-    pt->fLab2 = i;
+    //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
+    //if (seed1){
+    //  FollowProlongation(*seed1,0);
+    //  Int_t n = seed1->GetNumberOfClusters();
+    //  printf("fP4\t%f\t%f\n",seed1->GetC(),pt->GetC());
+    //  printf("fN\t%d\t%d\n", seed1->GetNumberOfClusters(),pt->GetNumberOfClusters());
+    //
+    //}
+    //AliTPCseed * seed2 = ReSeed(pt,0.95,0.5,0.05);
+    
   }
 
   SortTracks(fSeeds, 1);
   
-  /*
+  /*    
   fIteration = 1;
-  PrepareForBackProlongation(fSeeds,0.5);
+  PrepareForBackProlongation(fSeeds,5.);
   PropagateBack(fSeeds);
   printf("Time for back propagation: \t");timer.Print();timer.Start();
   
   fIteration = 2;
   
-  PrepareForProlongation(fSeeds,1.);
-  PropagateForward();
-  
-  fSectors = fOuterSec;
-  ParallelTracking(fSeeds,fSectors->GetNRows()-1,0);
-  fSectors = fInnerSec;
-  ParallelTracking(fSeeds,fSectors->GetNRows()-1,0);
+  PrepareForProlongation(fSeeds,5.);
+  PropagateForward2(fSeeds);
+   
   printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
   // RemoveUsed(fSeeds,0.7,0.7,6);
   //RemoveOverlap(fSeeds,0.9,7,kTRUE);
+   
   nseed=fSeeds->GetEntriesFast();
   found = 0;
   for (Int_t i=0; i<nseed; i++) {
@@ -3865,22 +4715,15 @@ Int_t AliTPCtrackerMI::Clusters2Tracks() {
   */
  
   //  fNTracks = found;
-  printf("Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
-  //
-  if (fOutput) {
-    WriteTracks();
+  if (fDebug>0){
+    Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
   }
-  if (!fNewIO)  fOutput->Write();
-  else
-    AliRunLoader::GetDetectorLoader("TPC",AliConfig::fgkDefaultEventFolderName)->WriteTracks("OVERWRITE");
-
-
-  cerr<<"Number of found tracks : "<<"\t"<<found<<endl;  
+  //
+  //  cerr<<"Number of found tracks : "<<"\t"<<found<<endl;  
+  Info("Clusters2Tracks","Number of found tracks %d",found);  
   savedir->cd();
-  //if (seedtree) delete seedtree;
   //  UnloadClusters();
-  //printf("Time for unloading cluster: \t"); timer.Print();timer.Start();
-  
+  //  
   return 0;
 }
 
@@ -3912,7 +4755,7 @@ TObjArray * AliTPCtrackerMI::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_
     if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
   }
   if (fDebug>0){
-    printf("\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
+    Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
     timer.Print();
     timer.Start();
   }
@@ -3998,7 +4841,7 @@ TObjArray * AliTPCtrackerMI::Tracking()
   fdensity = 2.;
   
   if (fDebug>0){
-    printf("\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
+    Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
     timer.Print();
     timer.Start();
   }
@@ -4067,7 +4910,7 @@ TObjArray * AliTPCtrackerMI::Tracking()
   }
  
   if (fDebug>0){
-    printf("\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
+    Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
     timer.Print();
     timer.Start();
   }
@@ -4078,7 +4921,7 @@ TObjArray * AliTPCtrackerMI::Tracking()
 }
 
 
-void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *arr2)
+void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *arr2) const
 {
   //
   //sum tracks to common container
@@ -4134,13 +4977,18 @@ void  AliTPCtrackerMI::ParallelTracking(TObjArray * arr, Int_t rfirst, Int_t rla
 
 
   //
-  for (Int_t nr=rfirst; nr>=rlast; nr--){      
+  for (Int_t nr=rfirst; nr>=rlast; nr--){ 
+    if (nr<fInnerSec->GetNRows()) 
+      fSectors = fInnerSec;
+    else
+      fSectors = fOuterSec;
     // make indexes with the cluster tracks for given       
 
     // find nearest cluster
     for (Int_t i=0; i<nseed; i++) {
       AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;       
       if (!pt) continue;
+      if (nr==80) pt->UpdateReference();
       if (!pt->IsActive()) continue;
       //      if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fParam->GetNRowLow())<nr) continue;
       if (pt->fRelativeSector>17) {
@@ -4162,7 +5010,7 @@ void  AliTPCtrackerMI::ParallelTracking(TObjArray * arr, Int_t rfirst, Int_t rla
   }    
 }
 
-void AliTPCtrackerMI::PrepareForBackProlongation(TObjArray * arr,Float_t fac)
+void AliTPCtrackerMI::PrepareForBackProlongation(TObjArray * arr,Float_t fac) const
 {
   //
   //
@@ -4198,7 +5046,7 @@ void AliTPCtrackerMI::PrepareForBackProlongation(TObjArray * arr,Float_t fac)
 
 
 }
-void AliTPCtrackerMI::PrepareForProlongation(TObjArray * arr, Float_t fac)
+void AliTPCtrackerMI::PrepareForProlongation(TObjArray * arr, Float_t fac) const
 {
   //
   //
@@ -4225,22 +5073,24 @@ Int_t AliTPCtrackerMI::PropagateBack(TObjArray * arr)
   Int_t nseed= arr->GetEntriesFast();
   for (Int_t i=0;i<nseed;i++){
     AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
-    if (pt) { 
-      AliTPCseed *pt2 = new AliTPCseed(*pt);
+    if (pt&& pt->GetKinkIndex(0)<=0) { 
+      //AliTPCseed *pt2 = new AliTPCseed(*pt);
       fSectors = fInnerSec;
-      FollowBackProlongation(*pt,fSectors->GetNRows()-1);
-      fSectors = fOuterSec;
-      FollowBackProlongation(*pt,fSectors->GetNRows()-1);
-      fSectors = fOuterSec;
-      if (pt->GetNumberOfClusters()<35 && pt->GetLabel()>0 ){
-       printf("\n%d",pt->GetLabel());
-       fSectors = fInnerSec;
-       FollowBackProlongation(*pt2,fSectors->GetNRows()-1);
-       fSectors = fOuterSec;
-       FollowBackProlongation(*pt2,fSectors->GetNRows()-1);
-       fSectors = fOuterSec;
-      }
-    }      
+      //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
+      //fSectors = fOuterSec;
+      FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);     
+      //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
+      //       Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
+      //       FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
+      //}
+    }
+    if (pt&& pt->GetKinkIndex(0)>0) {
+      AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
+      pt->fFirstPoint = kink->fRow0;
+      fSectors = fInnerSec;
+      FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);  
+    }
+    
   }
   return 0;
 }
@@ -4252,24 +5102,12 @@ Int_t AliTPCtrackerMI::PropagateForward2(TObjArray * arr)
   // make forward propagation
   //
   Int_t nseed= arr->GetEntriesFast();
+  //
   for (Int_t i=0;i<nseed;i++){
     AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
     if (pt) { 
-      AliTPCseed *pt2 = new AliTPCseed(*pt);
-      fSectors = fOuterSec;
-      FollowProlongation(*pt,0);
-      fSectors = fOuterSec;
       FollowProlongation(*pt,0);
-      fSectors = fInnerSec;
-      if (pt->GetNumberOfClusters()<35 && pt->GetLabel()>0 ){
-       printf("\n%d",pt->GetLabel());
-       fSectors = fOuterSec;
-       FollowProlongation(*pt2,0);
-       fSectors = fOuterSec;
-       FollowProlongation(*pt2,0);
-       fSectors = fOuterSec;
-      }
-    }      
+    }
   }
   return 0;
 }
@@ -4277,10 +5115,25 @@ Int_t AliTPCtrackerMI::PropagateForward2(TObjArray * arr)
 
 Int_t AliTPCtrackerMI::PropagateForward()
 {
+  //
+  // propagate track forward
+  //UnsignClusters();
+  Int_t nseed = fSeeds->GetEntriesFast();
+  for (Int_t i=0;i<nseed;i++){
+    AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
+    if (pt){
+      AliTPCseed &t = *pt;
+      Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
+      if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();  
+      if (alpha < 0.            ) alpha += 2.*TMath::Pi();  
+      t.fRelativeSector = Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
+    }
+  }
+  
   fSectors = fOuterSec;
-  ParallelTracking(fSeeds,fSectors->GetNRows()-1,0);
+  ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
   fSectors = fInnerSec;
-  ParallelTracking(fSeeds,fSectors->GetNRows()-1,0);
+  ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
   //WriteTracks();
   return 1;
 }
@@ -4377,8 +5230,6 @@ Float_t  AliTPCtrackerMI::GetSigmaZ(AliTPCseed * seed)
 }
 
 
-
-
 //__________________________________________________________________________
 void AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong) const {
   //--------------------------------------------------------------------
@@ -4386,8 +5237,8 @@ void AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong) const {
   //--------------------------------------------------------------------
   Int_t noc=t->GetNumberOfClusters();
   if (noc<10){
-    printf("\nnot founded prolongation\n\n\n");
-    t->Dump();
+    //printf("\nnot founded prolongation\n\n\n");
+    //t->Dump();
     return ;
   }
   Int_t lb[160];
@@ -4461,6 +5312,114 @@ void AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong) const {
   //delete[] clusters;
 }
 
+
+//__________________________________________________________________________
+Int_t AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong,Int_t first, Int_t last) const {
+  //--------------------------------------------------------------------
+  //This function "cooks" a track label. If label<0, this track is fake.
+  //--------------------------------------------------------------------
+  Int_t noc=t->GetNumberOfClusters();
+  if (noc<10){
+    //printf("\nnot founded prolongation\n\n\n");
+    //t->Dump();
+    return -1;
+  }
+  Int_t lb[160];
+  Int_t mx[160];
+  AliTPCclusterMI *clusters[160];
+  //
+  for (Int_t i=0;i<160;i++) {
+    clusters[i]=0;
+    lb[i]=mx[i]=0;
+  }
+
+  Int_t i;
+  Int_t current=0;
+  for (i=0; i<160 && current<noc; i++) {
+    if (i<first) continue;
+    if (i>last)  continue;
+     Int_t index=t->GetClusterIndex2(i);
+     if (index<=0) continue; 
+     if (index&0x8000) continue;
+     //     
+     //clusters[current]=GetClusterMI(index);
+     if (t->fClusterPointer[i]){
+       clusters[current]=t->fClusterPointer[i];     
+       current++;
+     }
+  }
+  noc = current;
+  if (noc<5) return -1;
+  Int_t lab=123456789;
+  for (i=0; i<noc; i++) {
+    AliTPCclusterMI *c=clusters[i];
+    if (!c) continue;
+    lab=TMath::Abs(c->GetLabel(0));
+    Int_t j;
+    for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
+    lb[j]=lab;
+    (mx[j])++;
+  }
+
+  Int_t max=0;
+  for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
+    
+  for (i=0; i<noc; i++) {
+    AliTPCclusterMI *c=clusters[i]; 
+    if (!c) continue;
+    if (TMath::Abs(c->GetLabel(1)) == lab ||
+        TMath::Abs(c->GetLabel(2)) == lab ) max++;
+  }
+
+  if ((1.- Float_t(max)/noc) > wrong) lab=-lab;
+
+  else {
+     Int_t tail=Int_t(0.10*noc);
+     max=0;
+     Int_t ind=0;
+     for (i=1; i<=160&&ind<tail; i++) {
+       //       AliTPCclusterMI *c=clusters[noc-i];
+       AliTPCclusterMI *c=clusters[i];
+       if (!c) continue;
+       if (lab == TMath::Abs(c->GetLabel(0)) ||
+           lab == TMath::Abs(c->GetLabel(1)) ||
+           lab == TMath::Abs(c->GetLabel(2))) max++;
+       ind++;
+     }
+     if (max < Int_t(0.5*tail)) lab=-lab;
+  }
+
+  //  t->SetLabel(lab);
+  return lab;
+  //  delete[] lb;
+  //delete[] mx;
+  //delete[] clusters;
+}
+
+
+Int_t  AliTPCtrackerMI::AliTPCSector::GetRowNumber(Double_t x) const 
+{
+  //return pad row number for this x
+  Double_t r;
+  if (fN < 64){
+    r=fRow[fN-1].GetX();
+    if (x > r) return fN;
+    r=fRow[0].GetX();
+    if (x < r) return -1;
+    return Int_t((x-r)/fPadPitchLength + 0.5);}
+  else{    
+    r=fRow[fN-1].GetX();
+    if (x > r) return fN;
+    r=fRow[0].GetX();
+    if (x < r) return -1;
+    Double_t r1=fRow[64].GetX();
+    if(x<r1){       
+      return Int_t((x-r)/f1PadPitchLength + 0.5);}
+    else{
+      return (Int_t((x-r1)/f2PadPitchLength + 0.5)+64);} 
+  }
+}
+
 //_________________________________________________________________________
 void AliTPCtrackerMI::AliTPCSector::Setup(const AliTPCParam *par, Int_t f) {
   //-----------------------------------------------------------------------
@@ -4494,9 +5453,19 @@ void AliTPCtrackerMI::AliTPCSector::Setup(const AliTPCParam *par, Int_t f) {
   } 
 }
 
+AliTPCtrackerMI::AliTPCRow::AliTPCRow() {
+  //
+  // default constructor
+  fN=0;
+  fN1=0;
+  fN2=0;
+  fClusters1=0;
+  fClusters2=0;
+}
 
 AliTPCtrackerMI::AliTPCRow::~AliTPCRow(){
   //
+
 }
 
 
@@ -4517,6 +5486,20 @@ AliTPCtrackerMI::AliTPCRow::InsertCluster(const AliTPCclusterMI* c, UInt_t index
   fIndex[i]=index; fClusters[i]=c; fN++;
 }
 
+void AliTPCtrackerMI::AliTPCRow::ResetClusters() {
+   //
+   // reset clusters
+   fN  = 0; 
+   fN1 = 0;
+   fN2 = 0;
+   //delete[] fClusterArray; 
+   if (fClusters1) delete []fClusters1; 
+   if (fClusters2) delete []fClusters2; 
+   //fClusterArray=0;
+   fClusters1 = 0;
+   fClusters2 = 0;
+}
+
 
 //___________________________________________________________________
 Int_t AliTPCtrackerMI::AliTPCRow::Find(Double_t z) const {
@@ -4621,12 +5604,11 @@ AliTPCseed::AliTPCseed():AliTPCtrack(){
   fRemoval =0; 
   for (Int_t i=0;i<200;i++) SetClusterIndex2(i,-3);
   for (Int_t i=0;i<160;i++) fClusterPointer[i]=0;
-
+  for (Int_t i=0;i<3;i++)   fKinkIndexes[i]=0;
   fPoints = 0;
   fEPoints = 0;
   fNFoundable =0;
   fNShared  =0;
-  //  fTrackPoints =0;
   fRemoval = 0;
   fSort =0;
   fFirstPoint =0;
@@ -4634,19 +5616,30 @@ AliTPCseed::AliTPCseed():AliTPCtrack(){
   fBSigned = kFALSE;
   fSeed1 =-1;
   fSeed2 =-1;
+  fCurrentCluster =0;
+  fCurrentSigmaY2=0;
+  fCurrentSigmaZ2=0;
+}
+AliTPCseed::AliTPCseed(const AliTPCseed &s):AliTPCtrack(s){
+  //---------------------
+  // dummy copy constructor
+  //-------------------------
 }
-
 AliTPCseed::AliTPCseed(const AliTPCtrack &t):AliTPCtrack(t){
+  //
+  //copy constructor
   fPoints = 0;
   fEPoints = 0;
   fNShared  =0; 
   //  fTrackPoints =0;
   fRemoval =0;
   fSort =0;
+  for (Int_t i=0;i<3;i++)   fKinkIndexes[i]=t.GetKinkIndex(i);
+
   for (Int_t i=0;i<160;i++) {
     fClusterPointer[i] = 0;
     Int_t index = t.GetClusterIndex(i);
-    if (index>0) {
+    if (index>=-1){ 
       SetClusterIndex2(i,index);
     }
     else{
@@ -4658,16 +5651,21 @@ AliTPCseed::AliTPCseed(const AliTPCtrack &t):AliTPCtrack(t){
   fBSigned = kFALSE;
   fSeed1 =-1;
   fSeed2 =-1;
+  fCurrentCluster =0;
+  fCurrentSigmaY2=0;
+  fCurrentSigmaZ2=0;
 }
-
+/*
 AliTPCseed::AliTPCseed(const AliKalmanTrack &t, Double_t a):AliTPCtrack(t,a){
+  //
+  //copy constructor
   fRow=0;
   for (Int_t i=0;i<160;i++) {
     fClusterPointer[i] = 0;
     Int_t index = t.GetClusterIndex(i);
     SetClusterIndex2(i,index);
   }
-  
+  for (Int_t i=0;i<3;i++)   fKinkIndexes[i]=0;
   fPoints = 0;
   fEPoints = 0;
   fNFoundable =0; 
@@ -4680,16 +5678,23 @@ AliTPCseed::AliTPCseed(const AliKalmanTrack &t, Double_t a):AliTPCtrack(t,a){
   fBSigned = kFALSE;
   fSeed1 =-1;
   fSeed2 =-1;
+  fCurrentCluster =0;
+  fCurrentSigmaY2=0;
+  fCurrentSigmaZ2=0;
+
 }
+*/
 
-AliTPCseed::AliTPCseed(UInt_t index, const Double_t xx[5], const Double_t cc[15], 
-                                       Double_t xr, Double_t alpha):      
+AliTPCseed::AliTPCseed(UInt_t index,  const Double_t xx[5], const Double_t cc[15], 
+                                        Double_t xr, Double_t alpha):      
   AliTPCtrack(index, xx, cc, xr, alpha) {
+   //
   //
-  //
+  //constructor
   fRow =0;
   for (Int_t i=0;i<200;i++) SetClusterIndex2(i,-3);
   for (Int_t i=0;i<160;i++) fClusterPointer[i]=0;
+  for (Int_t i=0;i<3;i++)   fKinkIndexes[i]=0;
   fPoints = 0;
   fEPoints = 0;
   fNFoundable =0;
@@ -4704,9 +5709,14 @@ AliTPCseed::AliTPCseed(UInt_t index, const Double_t xx[5], const Double_t cc[15]
   fBSigned = kFALSE;
   fSeed1 =-1;
   fSeed2 =-1;
+  fCurrentCluster =0;
+  fCurrentSigmaY2=0;
+  fCurrentSigmaZ2=0;
 }
 
 AliTPCseed::~AliTPCseed(){
+  //
+  // destructor
   if (fPoints) delete fPoints;
   fPoints =0;
   if (fEPoints) delete fEPoints;
@@ -4801,9 +5811,9 @@ void AliTPCseed::GetClusterStatistic(Int_t first, Int_t last, Int_t &found, Int_
     }
     
   }
-  if (shared>found){
-    printf("problem\n");
-  }
+  //if (shared>found){
+    //Error("AliTPCseed::GetClusterStatistic","problem\n");
+  //}
 }
 
 //_____________________________________________________________________________
@@ -4905,7 +5915,7 @@ void AliTPCseed::CookdEdx(Double_t low, Double_t up,Int_t i1, Int_t i2, Bool_t o
          //  TMath::Abs( Int_t(iz) - iz + 0.5);
          //ampc *= 1.15*(1-0.3*dy);
          //ampc *= 1.15*(1-0.3*dz);
-         //      Float_t zfactor = (1.05-0.0004*TMath::Abs(point->GetCPoint().GetZ()));
+         //      Float_t zfactor = (AliTPCReconstructor::GetCtgRange()-0.0004*TMath::Abs(point->GetCPoint().GetZ()));
          //ampc               *=zfactor; 
        }
        else{ 
@@ -5043,17 +6053,17 @@ void AliTPCseed::CookdEdx(Double_t low, Double_t up,Int_t i1, Int_t i2, Bool_t o
   Double_t p=TMath::Sqrt((1.+ GetTgl()*GetTgl())/(Get1Pt()*Get1Pt()));
 
   if (p<0.6) {
-    if (dedx < 39.+ 12./(p+0.25)/(p+0.25)) { SetMass(0.13957); return;}
-    if (dedx < 39.+ 12./p/p) { SetMass(0.49368); return;}
-    SetMass(0.93827); return;
+    if (dedx < 39.+ 12./(p+0.25)/(p+0.25)) { SetMass(AliPID::ParticleMass(AliPID::kPion)); return;}
+    if (dedx < 39.+ 12./p/p) { SetMass(AliPID::ParticleMass(AliPID::kKaon)); return;}
+    SetMass(AliPID::ParticleMass(AliPID::kProton)); return;
   }
 
   if (p<1.2) {
-    if (dedx < 39.+ 12./(p+0.25)/(p+0.25)) { SetMass(0.13957); return;}
-    SetMass(0.93827); return;
+    if (dedx < 39.+ 12./(p+0.25)/(p+0.25)) { SetMass(AliPID::ParticleMass(AliPID::kPion)); return;}
+    SetMass(AliPID::ParticleMass(AliPID::kProton)); return;
   }
 
-  SetMass(0.13957); return;
+  SetMass(AliPID::ParticleMass(AliPID::kPion)); return;
 
 }