]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TPC/AliTPCtrackerMI.cxx
Removing obsolete macros which used the AliTPCtracker
[u/mrichter/AliRoot.git] / TPC / AliTPCtrackerMI.cxx
index c565a690cb750091e4154412ab981d43495f1707..4d5f0631fccb62922d7615bc6d5d7f61accafa9f 100644 (file)
 //   Origin: Marian Ivanov   Marian.Ivanov@cern.ch
 // 
 //  AliTPC parallel tracker
+//
+//  The track fitting is based on Kalaman filtering approach
+
+//  The track finding steps:
+//      1. Seeding - with and without vertex constraint
+//                 - seeding with vertex constain done at first n^2 proble
+//                 - seeding without vertex constraint n^3 problem
+//      2. Tracking - follow prolongation road - find cluster - update kalman track
+
+//  The seeding and tracking is repeated several times, in different seeding region.
+//  This approach enables to find the track which cannot be seeded in some region of TPC
+//  This can happen because of low momenta (track do not reach outer radius), or track is currently in the ded region between sectors, or the track is for the moment overlapped with other track (seed quality is poor) ...
+
+//  With this approach we reach almost 100 % efficiency also for high occupancy events.
+//  (If the seeding efficiency in a region is about 90 % than with logical or of several 
+//  regions we will reach 100% (in theory - supposing independence) 
+
+//  Repeating several seeding - tracking procedures some of the tracks can be find 
+//  several times. 
+
+//  The procedures to remove multi find tacks are impremented:
+//  RemoveUsed2 - fast procedure n problem - 
+//                 Algorithm - Sorting tracks according quality
+//                             remove tracks with some shared fraction 
+//                             Sharing in respect to all tacks 
+//                             Signing clusters in gold region
+//  FindSplitted - slower algorithm n^2
+//                 Sort the tracks according quality
+//                 Loop over pair of tracks
+//                 If overlap with other track bigger than threshold - remove track
+//  
+//  FindCurling  - Finds the pair of tracks which are curling
+//               - About 10% of tracks can be find with this procedure
+//                 The combinatorial background is too big to be used in High 
+//                  multiplicity environment 
+//               - n^2 problem - Slow procedure - currently it is disabled because of 
+//                  low efficiency
+//                 
+//  The number of splitted tracks can be reduced disabling the sharing of the cluster.
+//  tpcRecoParam-> SetClusterSharing(kFALSE);
+//  IT IS HIGHLY non recomended to use it in high flux enviroonment
+//  Even using this switch some tracks can be found more than once 
+//  (because of multiple seeding and low quality tracks which will not cross full chamber)
+//                          
+//
+// The tracker itself can be debugged  - the information about tracks can be stored in several // phases of the reconstruction
+// To enable storage of the TPC tracks in the ESD friend track
+// use AliTPCReconstructor::SetStreamLevel(n); 
+//
+// The debug level -  different procedure produce tree for numerical debugging
+//                    To enable them set AliTPCReconstructor::SetStreamLevel(n); where nis bigger 1
+//
+
+//
+// Adding systematic errors to the covariance:
+// 
+// The systematic errors due to the misalignment and miscalibration are added to the covariance matrix
+// of the tracks (not to the clusters as they are dependent):
+// The parameters form AliTPCRecoParam are used AliTPCRecoParam::GetSystematicError
+// The systematic errors are expressed there in RMS - position (cm), angle (rad), curvature (1/GeV)
+// The default values are 0. 
+//
+// The sytematic errors are added to the covariance matrix in following places:
+//
+// 1. During fisrt itteration - AliTPCtrackerMI::FillESD
+// 2. Second iteration - 
+//      2.a ITS->TPC   - AliTPCtrackerMI::ReadSeeds 
+//      2.b TPC->TRD   - AliTPCtrackerMI::PropagateBack
+// 3. Third iteration  -
+//      3.a TRD->TPC   - AliTPCtrackerMI::ReadSeeds
+//      3.b TPC->ITS   - AliTPCtrackerMI::RefitInward
+//
+// There are several places in the code which can be numerically debuged
+// This code is keeped in order to enable code development and to check the calibration implementtion
+//
+//      1. ErrParam stream  - dump information about 
+//         1.a) cluster
+//         2.a) cluster error estimate
+//         3.a) cluster shape estimate
+//
+//
+//  Debug streamer levels:
+//  
 //-------------------------------------------------------
 
 
 #include <TFile.h>
 #include <TObjArray.h>
 #include <TTree.h>
-
+#include <TGraphErrors.h>
+#include "AliLog.h"
 #include "AliComplexCluster.h"
-#include "AliESD.h"
-#include "AliESDkink.h"
+#include "AliESDEvent.h"
+#include "AliESDtrack.h"
+#include "AliESDVertex.h"
+#include "AliKink.h"
+#include "AliV0.h"
 #include "AliHelix.h"
 #include "AliRunLoader.h"
 #include "AliTPCClustersRow.h"
 #include "AliTPCParam.h"
 #include "AliTPCReconstructor.h"
-#include "AliTPCclusterMI.h"
 #include "AliTPCpolyTrack.h"
 #include "AliTPCreco.h"
-#include "AliTPCseed.h" 
+#include "AliTPCseed.h"
+
+#include "AliTPCtrackerSector.h" 
 #include "AliTPCtrackerMI.h"
 #include "TStopwatch.h"
 #include "AliTPCReconstructor.h"
-#include "AliESDkink.h"
-#include "AliPID.h"
-#include "TTreeStream.h"
 #include "AliAlignObj.h"
 #include "AliTrackPointArray.h"
+#include "TRandom.h"
+#include "AliTPCcalibDB.h"
+#include "AliTPCcalibDButil.h"
+#include "AliTPCTransform.h"
+#include "AliTPCClusterParam.h"
+#include "AliTPCdEdxInfo.h"
+#include "AliDCSSensorArray.h"
+#include "AliDCSSensor.h"
+#include "AliDAQ.h"
+#include "AliCosmicTracker.h"
 
 //
 
 ClassImp(AliTPCtrackerMI)
 
 
+
 class AliTPCFastMath {
 public:
   AliTPCFastMath();  
@@ -88,7 +184,44 @@ Double_t AliTPCFastMath::FastAsin(Double_t x){
   Int_t index = int(x*10000);
   return -(fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1]);
 }
+//__________________________________________________________________
+AliTPCtrackerMI::AliTPCtrackerMI()
+                :AliTracker(),
+                fkNIS(0),
+                fInnerSec(0),
+                fkNOS(0),
+                fOuterSec(0),
+                fN(0),
+                fSectors(0),
+                fInput(0),
+                fOutput(0),
+                fSeedTree(0),
+                fTreeDebug(0),
+                fEvent(0),
+                fDebug(0),
+                fNewIO(kFALSE),
+                fNtracks(0),
+                fSeeds(0),
+                fIteration(0),
+                fkParam(0),
+                fDebugStreamer(0),
+                fUseHLTClusters(4),
+                fSeedsPool(0),
+                fFreeSeedsID(500),
+                fNFreeSeeds(0),
+                fLastSeedID(-1)
+{
+  //
+  // default constructor
+  //
+  for (Int_t irow=0; irow<200; irow++){
+    fXRow[irow]=0;
+    fYMax[irow]=0;
+    fPadLength[irow]=0;
+  }
 
+}
+//_____________________________________________________________________
 
 
 
@@ -97,63 +230,65 @@ 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
-
-  UInt_t i = track->fCurrentClusterIndex1;
+  AliTPCclusterMI* c =track->GetCurrentCluster();
+  if (accept > 0) //sign not accepted clusters
+    track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() | 0x8000);  
+  else // unsign accpeted clusters
+    track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() & 0xffff7fff);  
+  UInt_t i = track->GetCurrentClusterIndex1();
 
   Int_t sec=(i&0xff000000)>>24; 
   //Int_t row = (i&0x00ff0000)>>16; 
-  track->fRow=(i&0x00ff0000)>>16;
-  track->fSector = sec;
+  track->SetRow((i&0x00ff0000)>>16);
+  track->SetSector(sec);
   //  Int_t index = i&0xFFFF;
-  if (sec>=fParam->GetNInnerSector()) track->fRow += fParam->GetNRowLow(); 
-  track->SetClusterIndex2(track->fRow, i);  
+  if (sec>=fkParam->GetNInnerSector()) track->SetRow(track->GetRow()+fkParam->GetNRowLow()); 
+  track->SetClusterIndex2(track->GetRow(), i);  
   //track->fFirstPoint = row;
   //if ( track->fLastPoint<row) track->fLastPoint =row;
   //  if (track->fRow<0 || track->fRow>160) {
   //  printf("problem\n");
   //}
-  if (track->fFirstPoint>track->fRow
-    track->fFirstPoint = track->fRow;
-  if (track->fLastPoint<track->fRow
-    track->fLastPoint  = track->fRow;
+  if (track->GetFirstPoint()>track->GetRow()
+    track->SetFirstPoint(track->GetRow());
+  if (track->GetLastPoint()<track->GetRow()
+    track->SetLastPoint(track->GetRow());
   
 
-  track->fClusterPointer[track->fRow] = c;  
+  track->SetClusterPointer(track->GetRow(),c);  
   //
 
   Double_t angle2 = track->GetSnp()*track->GetSnp();
-  angle2 = TMath::Sqrt(angle2/(1-angle2)); 
   //
   //SET NEW Track Point
   //
-  //  if (debug)
+  if (angle2<1) //PH sometimes angle2 is very big. To be investigated...
   {
-    AliTPCTrackerPoint   &point =*(track->GetTrackPoint(track->fRow));
+    angle2 = TMath::Sqrt(angle2/(1-angle2)); 
+    AliTPCTrackerPoint   &point =*(track->GetTrackPoint(track->GetRow()));
     //
-    point.SetSigmaY(c->GetSigmaY2()/track->fCurrentSigmaY2);
-    point.SetSigmaZ(c->GetSigmaZ2()/track->fCurrentSigmaZ2);
-    point.SetErrY(sqrt(track->fErrorY2));
-    point.SetErrZ(sqrt(track->fErrorZ2));
+    point.SetSigmaY(c->GetSigmaY2()/track->GetCurrentSigmaY2());
+    point.SetSigmaZ(c->GetSigmaZ2()/track->GetCurrentSigmaZ2());
+    point.SetErrY(sqrt(track->GetErrorY2()));
+    point.SetErrZ(sqrt(track->GetErrorZ2()));
     //
     point.SetX(track->GetX());
     point.SetY(track->GetY());
     point.SetZ(track->GetZ());
     point.SetAngleY(angle2);
     point.SetAngleZ(track->GetTgl());
-    if (point.fIsShared){
-      track->fErrorY2 *= 4;
-      track->fErrorZ2 *= 4;
+    if (point.IsShared()){
+      track->SetErrorY2(track->GetErrorY2()*4);
+      track->SetErrorZ2(track->GetErrorZ2()*4);
     }
   }  
 
-  Double_t chi2 = track->GetPredictedChi2(track->fCurrentCluster);
+  Double_t chi2 = track->GetPredictedChi2(track->GetCurrentCluster());
   //
-  track->fErrorY2 *= 1.3;
-  track->fErrorY2 += 0.01;    
-  track->fErrorZ2 *= 1.3;   
-  track->fErrorZ2 += 0.005;      
+//   track->SetErrorY2(track->GetErrorY2()*1.3);
+//   track->SetErrorY2(track->GetErrorY2()+0.01);    
+//   track->SetErrorZ2(track->GetErrorZ2()*1.3);   
+//   track->SetErrorZ2(track->GetErrorZ2()+0.005);      
     //}
   if (accept>0) return 0;
   if (track->GetNumberOfClusters()%20==0){
@@ -163,112 +298,208 @@ Int_t AliTPCtrackerMI::UpdateTrack(AliTPCseed * track, Int_t accept){
     //  new(larr[ihelix]) AliHelix(*track) ;    
     //}
   }
-  track->fNoCluster =0;
+  track->SetNoCluster(0);
   return track->Update(c,chi2,i);
 }
 
 
 
-Int_t AliTPCtrackerMI::AcceptCluster(AliTPCseed * seed, AliTPCclusterMI * cluster, Float_t factor, 
-                                      Float_t cory, Float_t corz)
+Int_t AliTPCtrackerMI::AcceptCluster(AliTPCseed * seed, AliTPCclusterMI * cluster)
 {
   //
   // decide according desired precision to accept given 
   // cluster for tracking
-  Double_t sy2=ErrY2(seed,cluster)*cory;
-  Double_t sz2=ErrZ2(seed,cluster)*corz;
-  //sy2=ErrY2(seed,cluster)*cory;
-  //sz2=ErrZ2(seed,cluster)*cory;
+  Double_t  yt=0,zt=0;
+  seed->GetProlongation(cluster->GetX(),yt,zt);
+  Double_t sy2=ErrY2(seed,cluster);
+  Double_t sz2=ErrZ2(seed,cluster);
   
   Double_t sdistancey2 = sy2+seed->GetSigmaY2();
   Double_t sdistancez2 = sz2+seed->GetSigmaZ2();
-  
-  Double_t rdistancey2 = (seed->fCurrentCluster->GetY()-seed->GetY())*
-    (seed->fCurrentCluster->GetY()-seed->GetY())/sdistancey2;
-  Double_t rdistancez2 = (seed->fCurrentCluster->GetZ()-seed->GetZ())*
-    (seed->fCurrentCluster->GetZ()-seed->GetZ())/sdistancez2;
+  Double_t dy=seed->GetCurrentCluster()->GetY()-yt;
+  Double_t dz=seed->GetCurrentCluster()->GetZ()-zt;
+  Double_t rdistancey2 = (seed->GetCurrentCluster()->GetY()-yt)*
+    (seed->GetCurrentCluster()->GetY()-yt)/sdistancey2;
+  Double_t rdistancez2 = (seed->GetCurrentCluster()->GetZ()-zt)*
+    (seed->GetCurrentCluster()->GetZ()-zt)/sdistancez2;
   
   Double_t rdistance2  = rdistancey2+rdistancez2;
   //Int_t  accept =0;
   
-  if (rdistance2>16) return 3;
+  if (AliTPCReconstructor::StreamLevel()>2 && seed->GetNumberOfClusters()>20) {
+    Float_t rmsy2 = seed->GetCurrentSigmaY2();
+    Float_t rmsz2 = seed->GetCurrentSigmaZ2();
+    Float_t rmsy2p30 = seed->GetCMeanSigmaY2p30();
+    Float_t rmsz2p30 = seed->GetCMeanSigmaZ2p30();
+    Float_t rmsy2p30R  = seed->GetCMeanSigmaY2p30R();
+    Float_t rmsz2p30R  = seed->GetCMeanSigmaZ2p30R();
+    AliExternalTrackParam param(*seed);
+    static TVectorD gcl(3),gtr(3);
+    Float_t gclf[3];
+    param.GetXYZ(gcl.GetMatrixArray());
+    cluster->GetGlobalXYZ(gclf);
+    gcl[0]=gclf[0];    gcl[1]=gclf[1];    gcl[2]=gclf[2];
+
+    
+    if (AliTPCReconstructor::StreamLevel()>2) {
+    (*fDebugStreamer)<<"ErrParam"<<
+      "Cl.="<<cluster<<
+      "T.="<<&param<<
+      "dy="<<dy<<
+      "dz="<<dz<<
+      "yt="<<yt<<
+      "zt="<<zt<<
+      "gcl.="<<&gcl<<
+      "gtr.="<<&gtr<<
+      "erry2="<<sy2<<
+      "errz2="<<sz2<<
+      "rmsy2="<<rmsy2<<
+      "rmsz2="<<rmsz2<<        
+      "rmsy2p30="<<rmsy2p30<<
+      "rmsz2p30="<<rmsz2p30<<  
+      "rmsy2p30R="<<rmsy2p30R<<
+      "rmsz2p30R="<<rmsz2p30R<<        
+      // normalize distance - 
+      "rdisty="<<rdistancey2<<
+      "rdistz="<<rdistancez2<<
+      "rdist="<<rdistance2<< //       
+      "\n";
+    }
+  }
+  //return 0;  // temporary
+  if (rdistance2>32) return 3;
   
   
-  if ((rdistancey2>9.*factor || rdistancez2>9.*factor) && cluster->GetType()==0)  
+  if ((rdistancey2>9. || rdistancez2>9.) && cluster->GetType()==0)  
     return 2;  //suspisiouce - will be changed
   
-  if ((rdistancey2>6.25*factor || rdistancez2>6.25*factor) && cluster->GetType()>0)  
+  if ((rdistancey2>6.25 || rdistancez2>6.25) && cluster->GetType()>0)  
     // strict cut on overlaped cluster
     return  2;  //suspisiouce - will be changed
   
-  if ( (rdistancey2>1.*factor || rdistancez2>6.25*factor ) 
+  if ( (rdistancey2>1. || rdistancez2>6.25 ) 
        && cluster->GetType()<0){
-    seed->fNFoundable--;
+    seed->SetNFoundable(seed->GetNFoundable()-1);
     return 2;    
   }
+
+  if (fUseHLTClusters == 3 || fUseHLTClusters == 4) {
+    if (fIteration==2){
+      if(!AliTPCReconstructor::GetRecoParam()->GetUseHLTOnePadCluster()) {
+       if (TMath::Abs(cluster->GetSigmaY2()) < kAlmost0)
+         return 2;
+      }
+    }
+  }
+
   return 0;
 }
 
 
 
 
+
 //_____________________________________________________________________________
 AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCParam *par): 
-AliTracker(), fkNIS(par->GetNInnerSector()/2), fkNOS(par->GetNOuterSector()/2)
+AliTracker(), 
+                fkNIS(par->GetNInnerSector()/2),
+                fInnerSec(0),
+                fkNOS(par->GetNOuterSector()/2),
+                fOuterSec(0),
+                fN(0),
+                fSectors(0),
+                fInput(0),
+                fOutput(0),
+                fSeedTree(0),
+                fTreeDebug(0),
+                fEvent(0),
+                fDebug(0),
+                fNewIO(0),
+                fNtracks(0),
+                fSeeds(0),
+                fIteration(0),
+                fkParam(0),
+                 fDebugStreamer(0),
+                 fUseHLTClusters(4),
+                 fSeedsPool(0),
+                fFreeSeedsID(500),
+                fNFreeSeeds(0),
+                fLastSeedID(-1)
 {
   //---------------------------------------------------------------------
   // The main TPC tracker constructor
   //---------------------------------------------------------------------
-  fInnerSec=new AliTPCSector[fkNIS];         
-  fOuterSec=new AliTPCSector[fkNOS];
+  fInnerSec=new AliTPCtrackerSector[fkNIS];         
+  fOuterSec=new AliTPCtrackerSector[fkNOS];
  
   Int_t i;
   for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
   for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
 
-  fN=0;  fSectors=0;
-
-  fSeeds=0;
-  fNtracks = 0;
-  fParam = par;  
+  fkParam = par;  
   Int_t nrowlow = par->GetNRowLow();
   Int_t nrowup = par->GetNRowUp();
 
   
-  for (Int_t i=0;i<nrowlow;i++){
+  for (i=0;i<nrowlow;i++){
     fXRow[i]     = par->GetPadRowRadiiLow(i);
     fPadLength[i]= par->GetPadPitchLength(0,i);
     fYMax[i]     = fXRow[i]*TMath::Tan(0.5*par->GetInnerAngle());
   }
 
   
-  for (Int_t i=0;i<nrowup;i++){
+  for (i=0;i<nrowup;i++){
     fXRow[i+nrowlow]      = par->GetPadRowRadiiUp(i);
     fPadLength[i+nrowlow] = par->GetPadPitchLength(60,i);
     fYMax[i+nrowlow]      = fXRow[i+nrowlow]*TMath::Tan(0.5*par->GetOuterAngle());
   }
-  fSeeds=0;
+
+  if (AliTPCReconstructor::StreamLevel()>0) {
+    fDebugStreamer = new TTreeSRedirector("TPCdebug.root");
+  }
   //
-  fInput    = 0;
-  fOutput   = 0;
-  fSeedTree = 0;
-  fTreeDebug =0;
-  fNewIO     =0;
-  fDebug     =0;
-  fEvent     =0;
-  fDebugStreamer = new TTreeSRedirector("TPCdebug.root");
+  fSeedsPool = new TClonesArray("AliTPCseed",1000);
 }
 //________________________________________________________________________
 AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCtrackerMI &t):
   AliTracker(t),
-  fkNIS(t.fkNIS),
-  fkNOS(t.fkNOS)
+                fkNIS(t.fkNIS),
+                fInnerSec(0),
+                fkNOS(t.fkNOS),
+                fOuterSec(0),
+                fN(0),
+                fSectors(0),
+                fInput(0),
+                fOutput(0),
+                fSeedTree(0),
+                fTreeDebug(0),
+                fEvent(0),
+                fDebug(0),
+                fNewIO(kFALSE),
+                fNtracks(0),
+                fSeeds(0),
+                fIteration(0),
+                fkParam(0),
+                 fDebugStreamer(0),
+                 fUseHLTClusters(4),
+                 fSeedsPool(0),
+                fFreeSeedsID(500),
+                fNFreeSeeds(0),
+                fLastSeedID(-1)
 {
   //------------------------------------
   // dummy copy constructor
   //------------------------------------------------------------------
+  fOutput=t.fOutput;
+  for (Int_t irow=0; irow<200; irow++){
+    fXRow[irow]=0;
+    fYMax[irow]=0;
+    fPadLength[irow]=0;
+  }
+
 }
-AliTPCtrackerMI & AliTPCtrackerMI::operator=(const AliTPCtrackerMI& /*r*/){
+AliTPCtrackerMI & AliTPCtrackerMI::operator=(const AliTPCtrackerMI& /*r*/)
+{
   //------------------------------
   // dummy 
   //--------------------------------------------------------------
@@ -282,81 +513,21 @@ AliTPCtrackerMI::~AliTPCtrackerMI() {
   delete[] fInnerSec;
   delete[] fOuterSec;
   if (fSeeds) {
-    fSeeds->Delete(); 
+    fSeeds->Clear(); 
     delete fSeeds;
   }
   if (fDebugStreamer) delete fDebugStreamer;
+  if (fSeedsPool) delete fSeedsPool;
 }
 
-void AliTPCtrackerMI::SetIO()
-{
-  //
-  fNewIO   =  kTRUE;
-  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)
-{
-
-  // set input
-  fNewIO = kFALSE;
-  fInput    = 0;
-  fOutput   = 0;
-  fSeedTree = 0;
-  fTreeDebug =0;
-  fInput = input;
-  if (input==0){
-    return;
-  }  
-  //set output
-  fOutput = output;
-  if (output){
-    AliTPCtrack *iotrack= new AliTPCtrack;
-    //    iotrack->fHelixIn   = new TClonesArray("AliHelix");
-    //iotrack->fHelixOut  = new TClonesArray("AliHelix");    
-    fOutput->Branch("tracks","AliTPCtrack",&iotrack,32000,100);
-    delete iotrack;
-  }
-  if (output && (fDebug&2)){
-    //write the full seed information if specified in debug mode
-    //
-    fSeedTree =  new TTree("Seeds","Seeds");
-    AliTPCseed * vseed = new AliTPCseed;
-    //
-    TClonesArray * arrtr = new TClonesArray("AliTPCTrackPoint",160);
-    arrtr->ExpandCreateFast(160);
-    TClonesArray * arre = new TClonesArray("AliTPCExactPoint",160);
-    //
-    vseed->fPoints = arrtr;
-    vseed->fEPoints = arre;
-    //    vseed->fClusterPoints = arrcl;
-    fSeedTree->Branch("seeds","AliTPCseed",&vseed,32000,99);
-    delete arrtr;
-    delete arre;    
-    fTreeDebug = new TTree("trackDebug","trackDebug");
-    TClonesArray * arrd = new TClonesArray("AliTPCTrackPoint2",0);
-    fTreeDebug->Branch("debug",&arrd,32000,99);
-  }
-
 
-  //set ESD event  
-  fEvent  = event;  
-}
-
-void AliTPCtrackerMI::FillESD(TObjArray* arr)
+void AliTPCtrackerMI::FillESD(const TObjArray* arr)
 {
   //
   //
   //fill esds using updated tracks
-  if (fEvent){
+  if (!fEvent) return;
+  
     // write tracks to the event
     // store index of the track
     Int_t nseed=arr->GetEntriesFast();
@@ -365,9 +536,15 @@ void AliTPCtrackerMI::FillESD(TObjArray* arr)
       AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
       if (!pt) continue; 
       pt->UpdatePoints();
-      //      pt->PropagateTo(fParam->GetInnerRadiusLow());
+      AddCovariance(pt);
+      if (AliTPCReconstructor::StreamLevel()>1) {
+       (*fDebugStreamer)<<"Track0"<<
+         "Tr0.="<<pt<<
+         "\n";       
+      }
+      //      pt->PropagateTo(fkParam->GetInnerRadiusLow());
       if (pt->GetKinkIndex(0)<=0){  //don't propagate daughter tracks 
-       pt->PropagateTo(fParam->GetInnerRadiusLow());
+       pt->PropagateTo(fkParam->GetInnerRadiusLow());
       }
  
       if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
@@ -382,7 +559,7 @@ void AliTPCtrackerMI::FillESD(TObjArray* arr)
        continue;
       }
        
-      if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->fNFoundable))>0.55) {
+      if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.55) {
        AliESDtrack iotrack;
        iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
        iotrack.SetTPCPoints(pt->GetPoints());
@@ -396,10 +573,10 @@ void AliTPCtrackerMI::FillESD(TObjArray* arr)
       //
       // short tracks  - maybe decays
 
-      if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->fNFoundable))>0.70) {
+      if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>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)){
+       if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2)){
          AliESDtrack iotrack;
          iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);    
          //iotrack.SetTPCindex(i);
@@ -412,11 +589,11 @@ void AliTPCtrackerMI::FillESD(TObjArray* arr)
        }
       }       
       
-      if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->fNFoundable))>0.8) {
+      if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>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;
+       if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
        //
        AliESDtrack iotrack;
        iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);      
@@ -433,7 +610,7 @@ void AliTPCtrackerMI::FillESD(TObjArray* arr)
       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){
+       if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
          AliESDtrack iotrack;
          iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);    
          iotrack.SetTPCPoints(pt->GetPoints());
@@ -450,7 +627,8 @@ void AliTPCtrackerMI::FillESD(TObjArray* arr)
        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 (foundable<=0) continue;
+       if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
        if (float(found)/float(foundable)<0.8) continue;
        //
        AliESDtrack iotrack;
@@ -464,449 +642,338 @@ void AliTPCtrackerMI::FillESD(TObjArray* arr)
        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();
+    // >> account for suppressed tracks in the kink indices (RS)
+    int nESDtracks = fEvent->GetNumberOfTracks();
+    for (int it=nESDtracks;it--;) {
+      AliESDtrack* esdTr = fEvent->GetTrack(it);
+      if (!esdTr || !esdTr->GetKinkIndex(0)) continue;
+      for (int ik=0;ik<3;ik++) {
+       int knkId=0;
+       if (!(knkId=esdTr->GetKinkIndex(ik))) break; // no more kinks for this track
+       AliESDkink* kink = fEvent->GetKink(TMath::Abs(knkId)-1);
+       if (!kink) {
+         AliError(Form("ESDTrack%d refers to non-existing kink %d",it,TMath::Abs(knkId)-1));
+         continue;
+       }
+       kink->SetIndex(it, knkId<0 ? 0:1); // update track index of the kink: mother at 0, daughter at 1
+      }
+    }
+    // << account for suppressed tracks in the kink indices (RS)  
+    AliInfo(Form("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks()));
+  
 }
 
-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;      
-    //}    
-    //TBranch * br = fOutput->Branch("tracks","AliTPCtrack",&iotrack,32000,100);
-    TBranch * br = fOutput->GetBranch("tracks");
-    br->SetAddress(&iotrack);
-    //
-    for (Int_t i=0; i<nseed; i++) {
-      AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i);    
-      if (!pt) continue;    
-      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;
-  //
-  if (fSeedTree){
-    //write the full seed information if specified in debug mode
-      
-    AliTPCseed * vseed = new AliTPCseed;
-    //
-    TClonesArray * arrtr = new TClonesArray("AliTPCTrackPoint",160);
-    arrtr->ExpandCreateFast(160);
-    //TClonesArray * arrcl = new TClonesArray("AliTPCclusterMI",160);
-    //arrcl->ExpandCreateFast(160);
-    TClonesArray * arre = new TClonesArray("AliTPCExactPoint",160);
-    //
-    vseed->fPoints = arrtr;
-    vseed->fEPoints = arre;
-    //    vseed->fClusterPoints = arrcl;
-    //TBranch * brseed = seedtree->Branch("seeds","AliTPCseed",&vseed,32000,99);
-    TBranch * brseed = fSeedTree->GetBranch("seeds");
-    
-    Int_t nseed=fSeeds->GetEntriesFast();
-    
-    for (Int_t i=0; i<nseed; i++) {
-      AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i);    
-      if (!pt) continue;     
-      pt->fPoints = arrtr;
-      //      pt->fClusterPoints = arrcl;
-      pt->fEPoints       = arre;
-      pt->RebuildSeed();
-      vseed = pt;
-      brseed->SetAddress(&vseed);
-      fSeedTree->Fill();
-      pt->fPoints  = 0;
-      pt->fEPoints = 0;
-      //      pt->fClusterPoints = 0;
-    }
-    fSeedTree->Write();
-    if (fTreeDebug) fTreeDebug->Write();
-  }
 
-}
-  
 
 
 
-Double_t AliTPCtrackerMI::ErrY2(AliTPCseed* seed, AliTPCclusterMI * cl){
+Double_t AliTPCtrackerMI::ErrY2(AliTPCseed* seed, const AliTPCclusterMI * cl){
   //
   //
-  //seed->SetErrorY2(0.1);
-  //return 0.1;
-  //calculate look-up table at the beginning
-  static Bool_t  ginit = kFALSE;
-  static Float_t gnoise1,gnoise2,gnoise3;
-  static Float_t ggg1[10000];
-  static Float_t ggg2[10000];
-  static Float_t ggg3[10000];
-  static Float_t glandau1[10000];
-  static Float_t glandau2[10000];
-  static Float_t glandau3[10000];
+  // Use calibrated cluster error from OCDB
   //
-  static Float_t gcor01[500];
-  static Float_t gcor02[500];
-  static Float_t gcorp[500];
+  AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
   //
+  Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
+  Int_t ctype = cl->GetType();  
+  Int_t    type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
+  Double_t angle = seed->GetSnp()*seed->GetSnp();
+  angle = TMath::Sqrt(TMath::Abs(angle/(1.-angle)));
+  Double_t erry2 = clparam->GetError0Par(0,type, z,angle);
+  if (ctype<0) {
+    erry2+=0.5;  // edge cluster
+  }
+  erry2*=erry2;
+  seed->SetErrorY2(erry2);
+  //
+  return erry2;
+
+//calculate look-up table at the beginning
+//   static Bool_t  ginit = kFALSE;
+//   static Float_t gnoise1,gnoise2,gnoise3;
+//   static Float_t ggg1[10000];
+//   static Float_t ggg2[10000];
+//   static Float_t ggg3[10000];
+//   static Float_t glandau1[10000];
+//   static Float_t glandau2[10000];
+//   static Float_t glandau3[10000];
+//   //
+//   static Float_t gcor01[500];
+//   static Float_t gcor02[500];
+//   static Float_t gcorp[500];
+//   //
 
-  //
-  if (ginit==kFALSE){
-    for (Int_t i=1;i<500;i++){
-      Float_t rsigma = float(i)/100.;
-      gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
-      gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
-      gcorp[i]  = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
-    }
+//   //
+//   if (ginit==kFALSE){
+//     for (Int_t i=1;i<500;i++){
+//       Float_t rsigma = float(i)/100.;
+//       gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
+//       gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
+//       gcorp[i]  = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
+//     }
 
-    //
-    for (Int_t i=3;i<10000;i++){
-      //
-      //
-      // inner sector
-      Float_t amp = float(i);
-      Float_t padlength =0.75;
-      gnoise1 = 0.0004/padlength;
-      Float_t nel     = 0.268*amp;
-      Float_t nprim   = 0.155*amp;
-      ggg1[i]          = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
-      glandau1[i]      = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
-      if (glandau1[i]>1) glandau1[i]=1;
-      glandau1[i]*=padlength*padlength/12.;      
-      //
-      // outer short
-      padlength =1.;
-      gnoise2   = 0.0004/padlength;
-      nel       = 0.3*amp;
-      nprim     = 0.133*amp;
-      ggg2[i]      = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
-      glandau2[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
-      if (glandau2[i]>1) glandau2[i]=1;
-      glandau2[i]*=padlength*padlength/12.;
-      //
-      //
-      // outer long
-      padlength =1.5;
-      gnoise3   = 0.0004/padlength;
-      nel       = 0.3*amp;
-      nprim     = 0.133*amp;
-      ggg3[i]      = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
-      glandau3[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
-      if (glandau3[i]>1) glandau3[i]=1;
-      glandau3[i]*=padlength*padlength/12.;
-      //
-    }
-    ginit = kTRUE;
-  }
-  //
-  //
-  //
-  Int_t amp = int(TMath::Abs(cl->GetQ()));  
-  if (amp>9999) {
-    seed->SetErrorY2(1.);
-    return 1.;
-  }
-  Float_t snoise2;
-  Float_t z = TMath::Abs(fParam->GetZLength()-TMath::Abs(seed->GetZ()));
-  Int_t ctype = cl->GetType();  
-  Float_t padlength= GetPadPitchLength(seed->fRow);
-  Double_t angle2 = seed->GetSnp()*seed->GetSnp();
-  angle2 = angle2/(1-angle2); 
-  //
-  //cluster "quality"
-  Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->fCurrentSigmaY2));
-  Float_t res;
-  //
-  if (fSectors==fInnerSec){
-    snoise2 = gnoise1;
-    res     = ggg1[amp]*z+glandau1[amp]*angle2;     
-    if (ctype==0) res *= gcor01[rsigmay];
-    if ((ctype>0)){
-      res+=0.002;
-      res*= gcorp[rsigmay];
-    }
-  }
-  else {
-    if (padlength<1.1){
-      snoise2 = gnoise2;
-      res     = ggg2[amp]*z+glandau2[amp]*angle2; 
-      if (ctype==0) res *= gcor02[rsigmay];      
-      if ((ctype>0)){
-       res+=0.002;
-       res*= gcorp[rsigmay];
-      }
-    }
-    else{
-      snoise2 = gnoise3;      
-      res     = ggg3[amp]*z+glandau3[amp]*angle2; 
-      if (ctype==0) res *= gcor02[rsigmay];
-      if ((ctype>0)){
-       res+=0.002;
-       res*= gcorp[rsigmay];
-      }
-    }
-  }  
+//     //
+//     for (Int_t i=3;i<10000;i++){
+//       //
+//       //
+//       // inner sector
+//       Float_t amp = float(i);
+//       Float_t padlength =0.75;
+//       gnoise1 = 0.0004/padlength;
+//       Float_t nel     = 0.268*amp;
+//       Float_t nprim   = 0.155*amp;
+//       ggg1[i]          = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
+//       glandau1[i]      = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
+//       if (glandau1[i]>1) glandau1[i]=1;
+//       glandau1[i]*=padlength*padlength/12.;      
+//       //
+//       // outer short
+//       padlength =1.;
+//       gnoise2   = 0.0004/padlength;
+//       nel       = 0.3*amp;
+//       nprim     = 0.133*amp;
+//       ggg2[i]      = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
+//       glandau2[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
+//       if (glandau2[i]>1) glandau2[i]=1;
+//       glandau2[i]*=padlength*padlength/12.;
+//       //
+//       //
+//       // outer long
+//       padlength =1.5;
+//       gnoise3   = 0.0004/padlength;
+//       nel       = 0.3*amp;
+//       nprim     = 0.133*amp;
+//       ggg3[i]      = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
+//       glandau3[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
+//       if (glandau3[i]>1) glandau3[i]=1;
+//       glandau3[i]*=padlength*padlength/12.;
+//       //
+//     }
+//     ginit = kTRUE;
+//   }
+//   //
+//   //
+//   //
+//   Int_t amp = int(TMath::Abs(cl->GetQ()));  
+//   if (amp>9999) {
+//     seed->SetErrorY2(1.);
+//     return 1.;
+//   }
+//   Float_t snoise2;
+//   Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
+//   Int_t ctype = cl->GetType();  
+//   Float_t padlength= GetPadPitchLength(seed->GetRow());
+//   Double_t angle2 = seed->GetSnp()*seed->GetSnp();
+//   angle2 = angle2/(1-angle2); 
+//   //
+//   //cluster "quality"
+//   Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->GetCurrentSigmaY2()));
+//   Float_t res;
+//   //
+//   if (fSectors==fInnerSec){
+//     snoise2 = gnoise1;
+//     res     = ggg1[amp]*z+glandau1[amp]*angle2;     
+//     if (ctype==0) res *= gcor01[rsigmay];
+//     if ((ctype>0)){
+//       res+=0.002;
+//       res*= gcorp[rsigmay];
+//     }
+//   }
+//   else {
+//     if (padlength<1.1){
+//       snoise2 = gnoise2;
+//       res     = ggg2[amp]*z+glandau2[amp]*angle2; 
+//       if (ctype==0) res *= gcor02[rsigmay];      
+//       if ((ctype>0)){
+//     res+=0.002;
+//     res*= gcorp[rsigmay];
+//       }
+//     }
+//     else{
+//       snoise2 = gnoise3;      
+//       res     = ggg3[amp]*z+glandau3[amp]*angle2; 
+//       if (ctype==0) res *= gcor02[rsigmay];
+//       if ((ctype>0)){
+//     res+=0.002;
+//     res*= gcorp[rsigmay];
+//       }
+//     }
+//   }  
 
-  if (ctype<0){
-    res+=0.005;
-    res*=2.4;  // overestimate error 2 times
-  }
-  res+= snoise2;
+//   if (ctype<0){
+//     res+=0.005;
+//     res*=2.4;  // overestimate error 2 times
+//   }
+//   res+= snoise2;
  
-  if (res<2*snoise2)
-    res = 2*snoise2;
+//   if (res<2*snoise2)
+//     res = 2*snoise2;
   
-  seed->SetErrorY2(res);
-  return res;
+//   seed->SetErrorY2(res);
+//   return res;
 
 
 }
 
 
 
-Double_t AliTPCtrackerMI::ErrZ2(AliTPCseed* seed, AliTPCclusterMI * cl){
-  //
-  //
-  //seed->SetErrorY2(0.1);
-  //return 0.1;
-  //calculate look-up table at the beginning
-  static Bool_t  ginit = kFALSE;
-  static Float_t gnoise1,gnoise2,gnoise3;
-  static Float_t ggg1[10000];
-  static Float_t ggg2[10000];
-  static Float_t ggg3[10000];
-  static Float_t glandau1[10000];
-  static Float_t glandau2[10000];
-  static Float_t glandau3[10000];
-  //
-  static Float_t gcor01[1000];
-  static Float_t gcor02[1000];
-  static Float_t gcorp[1000];
-  //
-
+Double_t AliTPCtrackerMI::ErrZ2(AliTPCseed* seed, const AliTPCclusterMI * cl){
   //
-  if (ginit==kFALSE){
-    for (Int_t i=1;i<1000;i++){
-      Float_t rsigma = float(i)/100.;
-      gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
-      gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
-      gcorp[i]  = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
-    }
-
-    //
-    for (Int_t i=3;i<10000;i++){
-      //
-      //
-      // inner sector
-      Float_t amp = float(i);
-      Float_t padlength =0.75;
-      gnoise1 = 0.0004/padlength;
-      Float_t nel     = 0.268*amp;
-      Float_t nprim   = 0.155*amp;
-      ggg1[i]          = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
-      glandau1[i]      = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
-      if (glandau1[i]>1) glandau1[i]=1;
-      glandau1[i]*=padlength*padlength/12.;      
-      //
-      // outer short
-      padlength =1.;
-      gnoise2   = 0.0004/padlength;
-      nel       = 0.3*amp;
-      nprim     = 0.133*amp;
-      ggg2[i]      = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
-      glandau2[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
-      if (glandau2[i]>1) glandau2[i]=1;
-      glandau2[i]*=padlength*padlength/12.;
-      //
-      //
-      // outer long
-      padlength =1.5;
-      gnoise3   = 0.0004/padlength;
-      nel       = 0.3*amp;
-      nprim     = 0.133*amp;
-      ggg3[i]      = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
-      glandau3[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
-      if (glandau3[i]>1) glandau3[i]=1;
-      glandau3[i]*=padlength*padlength/12.;
-      //
-    }
-    ginit = kTRUE;
-  }
   //
+  // Use calibrated cluster error from OCDB
   //
+  AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
   //
-  Int_t amp = int(TMath::Abs(cl->GetQ()));  
-  if (amp>9999) {
-    seed->SetErrorY2(1.);
-    return 1.;
-  }
-  Float_t snoise2;
-  Float_t z = TMath::Abs(fParam->GetZLength()-TMath::Abs(seed->GetZ()));
+  Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
   Int_t ctype = cl->GetType();  
-  Float_t padlength= GetPadPitchLength(seed->fRow);
+  Int_t    type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
   //
   Double_t angle2 = seed->GetSnp()*seed->GetSnp();
-  //  if (angle2<0.6) angle2 = 0.6;
   angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2)); 
-  //
-  //cluster "quality"
-  Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->fCurrentSigmaZ2));
-  Float_t res;
-  //
-  if (fSectors==fInnerSec){
-    snoise2 = gnoise1;
-    res     = ggg1[amp]*z+glandau1[amp]*angle2;     
-    if (ctype==0) res *= gcor01[rsigmaz];
-    if ((ctype>0)){
-      res+=0.002;
-      res*= gcorp[rsigmaz];
-    }
-  }
-  else {
-    if (padlength<1.1){
-      snoise2 = gnoise2;
-      res     = ggg2[amp]*z+glandau2[amp]*angle2; 
-      if (ctype==0) res *= gcor02[rsigmaz];      
-      if ((ctype>0)){
-       res+=0.002;
-       res*= gcorp[rsigmaz];
-      }
-    }
-    else{
-      snoise2 = gnoise3;      
-      res     = ggg3[amp]*z+glandau3[amp]*angle2; 
-      if (ctype==0) res *= gcor02[rsigmaz];
-      if ((ctype>0)){
-       res+=0.002;
-       res*= gcorp[rsigmaz];
-      }
-    }
-  }  
-
-  if (ctype<0){
-    res+=0.002;
-    res*=1.3;
-  }
-  if ((ctype<0) &&amp<70){
-    res+=0.002;
-    res*=1.3;  
+  Double_t angle = TMath::Sqrt(TMath::Abs(angle2));
+  Double_t errz2 = clparam->GetError0Par(1,type, z,angle);
+  if (ctype<0) {
+    errz2+=0.5;  // edge cluster
   }
-  res += snoise2;
-  if (res<2*snoise2)
-     res = 2*snoise2;
-  if (res>3) res =3;
-  seed->SetErrorZ2(res);
-  return res;
-}
-
-
-
-/*
-Double_t AliTPCtrackerMI::ErrZ2(AliTPCseed* seed, AliTPCclusterMI * cl){
-  //
+  errz2*=errz2;
+  seed->SetErrorZ2(errz2);
   //
-  //seed->SetErrorZ2(0.1);
-  //return 0.1;
+  return errz2;
 
-  Float_t snoise2;
-  Float_t z = TMath::Abs(fParam->GetZLength()-TMath::Abs(seed->GetZ()));
-  //
-  Float_t rsigmaz = cl->GetSigmaZ2()/(seed->fCurrentSigmaZ2);
-  Int_t ctype = cl->GetType();
-  Float_t amp = TMath::Abs(cl->GetQ());
-  
-  Float_t nel;
-  Float_t nprim;
-  //
-  Float_t landau=2 ;    //landau fluctuation part
-  Float_t gg=2;         // gg fluctuation part
-  Float_t padlength= GetPadPitchLength(seed->GetX());
-  if (fSectors==fInnerSec){
-    snoise2 = 0.0004/padlength;
-    nel     = 0.268*amp;
-    nprim   = 0.155*amp;
-    gg      = (2+0.001*nel/(padlength*padlength))/nel;
-    landau  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
-    if (landau>1) landau=1;
-  }
-  else {
-    snoise2 = 0.0004/padlength;
-    nel     = 0.3*amp;
-    nprim   = 0.133*amp;
-    gg      = (2+0.0008*nel/(padlength*padlength))/nel;
-    landau  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
-    if (landau>1) landau=1;
-  }
-  Float_t sdiff = gg*fParam->GetDiffT()*fParam->GetDiffT()*z;
 
-  //
-  Float_t angle2 = seed->GetSnp()*seed->GetSnp();
-  angle2 = TMath::Sqrt((1-angle2));
-  if (angle2<0.6) angle2 = 0.6;
-  //angle2 = 1;
 
-  Float_t angle = seed->GetTgl()/angle2;
-  Float_t angular = landau*angle*angle*padlength*padlength/12.;
-  Float_t res = sdiff + angular;
+//   //seed->SetErrorY2(0.1);
+//   //return 0.1;
+//   //calculate look-up table at the beginning
+//   static Bool_t  ginit = kFALSE;
+//   static Float_t gnoise1,gnoise2,gnoise3;
+//   static Float_t ggg1[10000];
+//   static Float_t ggg2[10000];
+//   static Float_t ggg3[10000];
+//   static Float_t glandau1[10000];
+//   static Float_t glandau2[10000];
+//   static Float_t glandau3[10000];
+//   //
+//   static Float_t gcor01[1000];
+//   static Float_t gcor02[1000];
+//   static Float_t gcorp[1000];
+//   //
 
-  
-  if ((ctype==0) && (fSectors ==fOuterSec))
-    res *= 0.81 +TMath::Exp(6.8*(rsigmaz-1.2));
+//   //
+//   if (ginit==kFALSE){
+//     for (Int_t i=1;i<1000;i++){
+//       Float_t rsigma = float(i)/100.;
+//       gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
+//       gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
+//       gcorp[i]  = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
+//     }
 
-  if ((ctype==0) && (fSectors ==fInnerSec))
-    res *= 0.72 +TMath::Exp(2.04*(rsigmaz-1.2));
-  
-  if ((ctype>0)){
-    res+=0.005;
-    res*= TMath::Power(rsigmaz+0.5,1.5);  //0.31+0.147*ctype;
-  }
-  if (ctype<0){
-    res+=0.002;
-    res*=1.3;
-  }
-  if ((ctype<0) &&amp<70){
-    res+=0.002;
-    res*=1.3;  
-  }
-  res += snoise2;
-  if (res<2*snoise2)
-     res = 2*snoise2;
+//     //
+//     for (Int_t i=3;i<10000;i++){
+//       //
+//       //
+//       // inner sector
+//       Float_t amp = float(i);
+//       Float_t padlength =0.75;
+//       gnoise1 = 0.0004/padlength;
+//       Float_t nel     = 0.268*amp;
+//       Float_t nprim   = 0.155*amp;
+//       ggg1[i]          = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
+//       glandau1[i]      = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
+//       if (glandau1[i]>1) glandau1[i]=1;
+//       glandau1[i]*=padlength*padlength/12.;      
+//       //
+//       // outer short
+//       padlength =1.;
+//       gnoise2   = 0.0004/padlength;
+//       nel       = 0.3*amp;
+//       nprim     = 0.133*amp;
+//       ggg2[i]      = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
+//       glandau2[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
+//       if (glandau2[i]>1) glandau2[i]=1;
+//       glandau2[i]*=padlength*padlength/12.;
+//       //
+//       //
+//       // outer long
+//       padlength =1.5;
+//       gnoise3   = 0.0004/padlength;
+//       nel       = 0.3*amp;
+//       nprim     = 0.133*amp;
+//       ggg3[i]      = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
+//       glandau3[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
+//       if (glandau3[i]>1) glandau3[i]=1;
+//       glandau3[i]*=padlength*padlength/12.;
+//       //
+//     }
+//     ginit = kTRUE;
+//   }
+//   //
+//   //
+//   //
+//   Int_t amp = int(TMath::Abs(cl->GetQ()));  
+//   if (amp>9999) {
+//     seed->SetErrorY2(1.);
+//     return 1.;
+//   }
+//   Float_t snoise2;
+//   Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
+//   Int_t ctype = cl->GetType();  
+//   Float_t padlength= GetPadPitchLength(seed->GetRow());
+//   //
+//   Double_t angle2 = seed->GetSnp()*seed->GetSnp();
+//   //  if (angle2<0.6) angle2 = 0.6;
+//   angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2)); 
+//   //
+//   //cluster "quality"
+//   Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->GetCurrentSigmaZ2()));
+//   Float_t res;
+//   //
+//   if (fSectors==fInnerSec){
+//     snoise2 = gnoise1;
+//     res     = ggg1[amp]*z+glandau1[amp]*angle2;     
+//     if (ctype==0) res *= gcor01[rsigmaz];
+//     if ((ctype>0)){
+//       res+=0.002;
+//       res*= gcorp[rsigmaz];
+//     }
+//   }
+//   else {
+//     if (padlength<1.1){
+//       snoise2 = gnoise2;
+//       res     = ggg2[amp]*z+glandau2[amp]*angle2; 
+//       if (ctype==0) res *= gcor02[rsigmaz];      
+//       if ((ctype>0)){
+//     res+=0.002;
+//     res*= gcorp[rsigmaz];
+//       }
+//     }
+//     else{
+//       snoise2 = gnoise3;      
+//       res     = ggg3[amp]*z+glandau3[amp]*angle2; 
+//       if (ctype==0) res *= gcor02[rsigmaz];
+//       if ((ctype>0)){
+//     res+=0.002;
+//     res*= gcorp[rsigmaz];
+//       }
+//     }
+//   }  
 
-  seed->SetErrorZ2(res);
-  return res;
+//   if (ctype<0){
+//     res+=0.002;
+//     res*=1.3;
+//   }
+//   if ((ctype<0) &&amp<70){
+//     res+=0.002;
+//     res*=1.3;  
+//   }
+//   res += snoise2;
+//   if (res<2*snoise2)
+//      res = 2*snoise2;
+//   if (res>3) res =3;
+//   seed->SetErrorZ2(res);
+//   return res;
 }
-*/
+
 
 
 
@@ -919,11 +986,11 @@ void AliTPCtrackerMI::RotateToLocal(AliTPCseed *seed)
   Float_t ymax = x*TMath::Tan(0.5*fSectors->GetAlpha());
   
   if (y > ymax) {
-    seed->fRelativeSector= (seed->fRelativeSector+1) % fN;
+    seed->SetRelativeSector((seed->GetRelativeSector()+1) % fN);
     if (!seed->Rotate(fSectors->GetAlpha())) 
       return;
   } else if (y <-ymax) {
-    seed->fRelativeSector= (seed->fRelativeSector-1+fN) % fN;
+    seed->SetRelativeSector((seed->GetRelativeSector()-1+fN) % fN);
     if (!seed->Rotate(-fSectors->GetAlpha())) 
       return;
   }   
@@ -935,7 +1002,7 @@ void AliTPCtrackerMI::RotateToLocal(AliTPCseed *seed)
 //_____________________________________________________________________________
 Double_t AliTPCtrackerMI::F1old(Double_t x1,Double_t y1,
                    Double_t x2,Double_t y2,
-                   Double_t x3,Double_t y3) 
+                   Double_t x3,Double_t y3) const
 {
   //-----------------------------------------------------------------
   // Initial approximation of the track curvature
@@ -956,7 +1023,7 @@ Double_t AliTPCtrackerMI::F1old(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) 
+                   Double_t x3,Double_t y3) const
 {
   //-----------------------------------------------------------------
   // Initial approximation of the track curvature
@@ -967,7 +1034,7 @@ Double_t AliTPCtrackerMI::F1(Double_t x1,Double_t y1,
   y2 -=y1;
   //  
   Double_t det = x3*y2-x2*y3;
-  if (det==0) {
+  if (TMath::Abs(det)<1e-10){
     return 100;
   }
   //
@@ -982,7 +1049,7 @@ Double_t AliTPCtrackerMI::F1(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) 
+                   Double_t x3,Double_t y3) const 
 {
   //-----------------------------------------------------------------
   // Initial approximation of the track curvature
@@ -993,7 +1060,7 @@ Double_t AliTPCtrackerMI::F2(Double_t x1,Double_t y1,
   y2 -=y1;
   //  
   Double_t det = x3*y2-x2*y3;
-  if (det==0) {
+  if (TMath::Abs(det)<1e-10) {
     return 100;
   }
   //
@@ -1012,7 +1079,7 @@ Double_t AliTPCtrackerMI::F2(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) 
+                   Double_t x3,Double_t y3) const
 {
   //-----------------------------------------------------------------
   // Initial approximation of the track curvature times center of curvature
@@ -1031,7 +1098,7 @@ Double_t AliTPCtrackerMI::F2old(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) 
+                   Double_t z1,Double_t z2) const
 {
   //-----------------------------------------------------------------
   // Initial approximation of the tangent of the track dip angle
@@ -1042,7 +1109,7 @@ Double_t AliTPCtrackerMI::F3(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) 
+                   Double_t z1,Double_t z2, Double_t c) const
 {
   //-----------------------------------------------------------------
   // Initial approximation of the tangent of the track dip angle
@@ -1062,7 +1129,7 @@ Double_t AliTPCtrackerMI::F3n(Double_t x1,Double_t y1,
   return angle2;
 }
 
-Bool_t   AliTPCtrackerMI::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z)
+Bool_t   AliTPCtrackerMI::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z) const
 {//-----------------------------------------------------------------
   // This function find proloncation of a track to a reference plane x=x2.
   //-----------------------------------------------------------------
@@ -1073,8 +1140,8 @@ Bool_t   AliTPCtrackerMI::GetProlongation(Double_t x1, Double_t x2, Double_t x[5
     return kFALSE;
   }
 
-  Double_t c1=x[4]*x1 - x[2], r1=sqrt(1.- c1*c1);
-  Double_t c2=x[4]*x2 - x[2], r2=sqrt(1.- c2*c2);  
+  Double_t c1=x[4]*x1 - x[2], r1=TMath::Sqrt((1.-c1)*(1.+c1));
+  Double_t c2=x[4]*x2 - x[2], r2=TMath::Sqrt((1.-c2)*(1.+c2));  
   y = x[0];
   z = x[1];
   
@@ -1097,40 +1164,38 @@ Bool_t   AliTPCtrackerMI::GetProlongation(Double_t x1, Double_t x2, Double_t x[5
   return kTRUE;  
 }
 
-Int_t  AliTPCtrackerMI::LoadClusters (TTree *tree)
+Int_t  AliTPCtrackerMI::LoadClusters (TTree *const tree)
 {
-  //
+  // load clusters
   //
   fInput = tree;
   return LoadClusters();
 }
 
-Int_t  AliTPCtrackerMI::LoadClusters()
+
+Int_t  AliTPCtrackerMI::LoadClusters(const TObjArray *arr)
 {
   //
   // load clusters to the memory
-  AliTPCClustersRow *clrow= new AliTPCClustersRow;
-  clrow->SetClass("AliTPCclusterMI");
-  clrow->SetArray(0);
-  clrow->GetArray()->ExpandCreateFast(10000);
-  //
-  //  TTree * tree = fClustersArray.GetTree();
-
-  TTree * tree = fInput;
-  TBranch * br = tree->GetBranch("Segment");
-  br->SetAddress(&clrow);
-  //
-  Int_t j=Int_t(tree->GetEntries());
-  for (Int_t i=0; i<j; i++) {
-    br->GetEntry(i);
+  AliTPCClustersRow *clrow = new AliTPCClustersRow("AliTPCclusterMI");
+  Int_t lower   = arr->LowerBound();
+  Int_t entries = arr->GetEntriesFast();
+  
+  for (Int_t i=lower; i<entries; i++) {
+    clrow = (AliTPCClustersRow*) arr->At(i);
+    if(!clrow) continue;
+    if(!clrow->GetArray()) continue;
+    
     //  
     Int_t sec,row;
-    fParam->AdjustSectorRow(clrow->GetID(),sec,row);
+    fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
+    
     for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
-      Transform((AliCluster*)(clrow->GetArray()->At(icl)));
+      Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
     }
     //
-    AliTPCRow * tpcrow=0;
+    if (clrow->GetArray()->GetEntriesFast()<=0) continue;
+    AliTPCtrackerRow * tpcrow=0;
     Int_t left=0;
     if (sec<fkNIS*2){
       tpcrow = &(fInnerSec[sec%fkNIS][row]);    
@@ -1141,17 +1206,16 @@ Int_t  AliTPCtrackerMI::LoadClusters()
       left = (sec-fkNIS*2)/fkNOS;
     }
     if (left ==0){
-      tpcrow->fN1 = clrow->GetArray()->GetEntriesFast();
-      tpcrow->fClusters1 = new AliTPCclusterMI[tpcrow->fN1];
-      for (Int_t i=0;i<tpcrow->fN1;i++) 
-       tpcrow->fClusters1[i] = *(AliTPCclusterMI*)(clrow->GetArray()->At(i));
+      tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
+      for (Int_t j=0;j<tpcrow->GetN1();++j) 
+       tpcrow->SetCluster1(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
     }
     if (left ==1){
-      tpcrow->fN2 = clrow->GetArray()->GetEntriesFast();
-      tpcrow->fClusters2 = new AliTPCclusterMI[tpcrow->fN2];
-      for (Int_t i=0;i<tpcrow->fN2;i++) 
-       tpcrow->fClusters2[i] = *(AliTPCclusterMI*)(clrow->GetArray()->At(i));
+      tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
+      for (Int_t j=0;j<tpcrow->GetN2();++j) 
+       tpcrow->SetCluster2(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
     }
+    clrow->GetArray()->Clear("C");
   }
   //
   delete clrow;
@@ -1160,50 +1224,233 @@ Int_t  AliTPCtrackerMI::LoadClusters()
   return 0;
 }
 
-
-void AliTPCtrackerMI::UnloadClusters()
+Int_t  AliTPCtrackerMI::LoadClusters(const TClonesArray *arr)
 {
   //
-  // unload clusters from the memory
+  // load clusters to the memory from one 
+  // TClonesArray
   //
-  Int_t nrows = fOuterSec->GetNRows();
-  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; 
-      //}
-      tpcrow->ResetClusters();
+  AliTPCclusterMI *clust=0;
+  Int_t count[72][96] = { {0} , {0} }; 
+
+  // loop over clusters
+  for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
+    clust = (AliTPCclusterMI*)arr->At(icl);
+    if(!clust) continue;
+    //printf("cluster: det %d, row %d \n", clust->GetDetector(),clust->GetRow());
+
+    // transform clusters
+    Transform(clust);
+
+    // count clusters per pad row
+    count[clust->GetDetector()][clust->GetRow()]++;
+  }
+
+  // insert clusters to sectors
+  for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
+    clust = (AliTPCclusterMI*)arr->At(icl);
+    if(!clust) continue;
+
+    Int_t sec = clust->GetDetector();
+    Int_t row = clust->GetRow();
+
+    // filter overlapping pad rows needed by HLT
+    if(sec<fkNIS*2) { //IROCs
+     if(row == 30) continue;
     }
-  //
-  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; 
-      //}
-      tpcrow->ResetClusters();
+    else { // OROCs
+      if(row == 27 || row == 76) continue;
     }
 
-  return ;
-}
+    //    Int_t left=0;
+    if (sec<fkNIS*2){
+      //      left = sec/fkNIS;
+      fInnerSec[sec%fkNIS].InsertCluster(clust, count[sec][row], fkParam);    
+    }
+    else{
+      //      left = (sec-fkNIS*2)/fkNOS;
+      fOuterSec[(sec-fkNIS*2)%fkNOS].InsertCluster(clust, count[sec][row], fkParam);
+    }
+  }
 
-void   AliTPCtrackerMI::Transform(AliCluster * cluster){
-  //
-  // 
-  //
-  //if (!fParam->IsGeoRead()) fParam->ReadGeoMatrices();
-  TGeoHMatrix  *mat = fParam->GetClusterMatrix(cluster->GetDetector());
-  Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
-  Double_t posC[3];
-  mat->LocalToMaster(pos,posC);
-  cluster->SetX(posC[0]);
-  cluster->SetY(posC[1]);
-  cluster->SetZ(posC[2]);
-}
+  // Load functions must be called behind LoadCluster(TClonesArray*)
+  // needed by HLT
+  //LoadOuterSectors();
+  //LoadInnerSectors();
+
+  return 0;
+}
+
+
+Int_t  AliTPCtrackerMI::LoadClusters()
+{
+  //
+  // load clusters to the memory
+  static AliTPCClustersRow *clrow= new AliTPCClustersRow("AliTPCclusterMI");
+  //
+  //  TTree * tree = fClustersArray.GetTree();
+
+  TTree * tree = fInput;
+  TBranch * br = tree->GetBranch("Segment");
+  br->SetAddress(&clrow);
+
+  // Conversion of pad, row coordinates in local tracking coords.
+  // Could be skipped here; is already done in clusterfinder
+
+  Int_t j=Int_t(tree->GetEntries());
+  for (Int_t i=0; i<j; i++) {
+    br->GetEntry(i);
+    //  
+    Int_t sec,row;
+    fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
+    for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
+      Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
+    }
+    //
+    AliTPCtrackerRow * tpcrow=0;
+    Int_t left=0;
+    if (sec<fkNIS*2){
+      tpcrow = &(fInnerSec[sec%fkNIS][row]);    
+      left = sec/fkNIS;
+    }
+    else{
+      tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
+      left = (sec-fkNIS*2)/fkNOS;
+    }
+    if (left ==0){
+      tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
+      for (Int_t k=0;k<tpcrow->GetN1();++k) 
+       tpcrow->SetCluster1(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
+    }
+    if (left ==1){
+      tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
+      for (Int_t k=0;k<tpcrow->GetN2();++k) 
+       tpcrow->SetCluster2(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
+    }
+  }
+  //
+  clrow->Clear("C");
+  LoadOuterSectors();
+  LoadInnerSectors();
+  return 0;
+}
+
+
+void AliTPCtrackerMI::UnloadClusters()
+{
+  //
+  // unload clusters from the memory
+  //
+  Int_t nrows = fOuterSec->GetNRows();
+  for (Int_t sec = 0;sec<fkNOS;sec++)
+    for (Int_t row = 0;row<nrows;row++){
+      AliTPCtrackerRow*  tpcrow = &(fOuterSec[sec%fkNOS][row]);
+      //      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++){
+      AliTPCtrackerRow*  tpcrow = &(fInnerSec[sec%fkNIS][row]);
+      //if (tpcrow){
+      //       if (tpcrow->fClusters1) delete []tpcrow->fClusters1; 
+      //if (tpcrow->fClusters2) delete []tpcrow->fClusters2; 
+      //}
+      tpcrow->ResetClusters();
+    }
+
+  return ;
+}
+
+void AliTPCtrackerMI::FillClusterArray(TObjArray* array) const{
+  //
+  // Filling cluster to the array - For visualization purposes
+  //
+  Int_t nrows=0;
+  nrows = fOuterSec->GetNRows();
+  for (Int_t sec = 0;sec<fkNOS;sec++)
+    for (Int_t row = 0;row<nrows;row++){
+      AliTPCtrackerRow*  tpcrow = &(fOuterSec[sec%fkNOS][row]);
+      if (!tpcrow) continue;
+      for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
+       array->AddLast((TObject*)((*tpcrow)[icl]));
+      }
+    } 
+  nrows = fInnerSec->GetNRows();
+  for (Int_t sec = 0;sec<fkNIS;sec++)
+    for (Int_t row = 0;row<nrows;row++){
+      AliTPCtrackerRow*  tpcrow = &(fInnerSec[sec%fkNIS][row]);
+      if (!tpcrow) continue;
+      for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
+       array->AddLast((TObject*)(*tpcrow)[icl]);
+      }
+    }
+}
+
+
+void   AliTPCtrackerMI::Transform(AliTPCclusterMI * cluster){
+  //
+  // transformation
+  //
+  AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
+  AliTPCTransform *transform = calibDB->GetTransform() ;
+  if (!transform) {
+    AliFatal("Tranformations not in calibDB");
+    return;
+  }
+  transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
+  Double_t x[3]={cluster->GetRow(),cluster->GetPad(),cluster->GetTimeBin()};
+  Int_t i[1]={cluster->GetDetector()};
+  transform->Transform(x,i,0,1);  
+  //  if (cluster->GetDetector()%36>17){
+  //  x[1]*=-1;
+  //}
+
+  //
+  // in debug mode  check the transformation
+  //
+  if (AliTPCReconstructor::StreamLevel()>2) {
+    Float_t gx[3];
+    cluster->GetGlobalXYZ(gx);
+    Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
+    TTreeSRedirector &cstream = *fDebugStreamer;
+    cstream<<"Transform"<<
+      "event="<<event<<
+      "x0="<<x[0]<<
+      "x1="<<x[1]<<
+      "x2="<<x[2]<<
+      "gx0="<<gx[0]<<
+      "gx1="<<gx[1]<<
+      "gx2="<<gx[2]<<
+      "Cl.="<<cluster<<
+      "\n"; 
+  }
+  cluster->SetX(x[0]);
+  cluster->SetY(x[1]);
+  cluster->SetZ(x[2]);
+  // The old stuff:
+  //
+  // 
+  //
+  //if (!fkParam->IsGeoRead()) fkParam->ReadGeoMatrices();
+  if (AliTPCReconstructor::GetRecoParam()->GetUseSectorAlignment() && (!calibDB->HasAlignmentOCDB())){
+    TGeoHMatrix  *mat = fkParam->GetClusterMatrix(cluster->GetDetector());
+    //TGeoHMatrix  mat;
+    Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
+    Double_t posC[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
+    if (mat) mat->LocalToMaster(pos,posC);
+    else{
+      // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
+    }
+    cluster->SetX(posC[0]);
+    cluster->SetY(posC[1]);
+    cluster->SetZ(posC[2]);
+  }
+}
 
 //_____________________________________________________________________________
 Int_t AliTPCtrackerMI::LoadOuterSectors() {
@@ -1214,19 +1461,19 @@ Int_t AliTPCtrackerMI::LoadOuterSectors() {
   UInt_t index=0;
   for (Int_t sec = 0;sec<fkNOS;sec++)
     for (Int_t row = 0;row<nrows;row++){
-      AliTPCRow*  tpcrow = &(fOuterSec[sec%fkNOS][row]);  
+      AliTPCtrackerRow*  tpcrow = &(fOuterSec[sec%fkNOS][row]);  
       Int_t sec2 = sec+2*fkNIS;
       //left
-      Int_t ncl = tpcrow->fN1;
+      Int_t ncl = tpcrow->GetN1();
       while (ncl--) {
-       AliTPCclusterMI *c= &(tpcrow->fClusters1[ncl]);
+       AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
        index=(((sec2<<8)+row)<<16)+ncl;
        tpcrow->InsertCluster(c,index);
       }
       //right
-      ncl = tpcrow->fN2;
+      ncl = tpcrow->GetN2();
       while (ncl--) {
-       AliTPCclusterMI *c= &(tpcrow->fClusters2[ncl]);
+       AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
        index=((((sec2+fkNOS)<<8)+row)<<16)+ncl;
        tpcrow->InsertCluster(c,index);
       }
@@ -1234,17 +1481,17 @@ Int_t AliTPCtrackerMI::LoadOuterSectors() {
       // write indexes for fast acces
       //
       for (Int_t i=0;i<510;i++)
-       tpcrow->fFastCluster[i]=-1;
+       tpcrow->SetFastCluster(i,-1);
       for (Int_t i=0;i<tpcrow->GetN();i++){
         Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
-       tpcrow->fFastCluster[zi]=i;  // write index
+       tpcrow->SetFastCluster(zi,i);  // write index
       }
       Int_t last = 0;
       for (Int_t i=0;i<510;i++){
-       if (tpcrow->fFastCluster[i]<0)
-         tpcrow->fFastCluster[i] = last;
+       if (tpcrow->GetFastCluster(i)<0)
+         tpcrow->SetFastCluster(i,last);
        else
-         last = tpcrow->fFastCluster[i];
+         last = tpcrow->GetFastCluster(i);
       }
     }  
   fN=fkNOS;
@@ -1262,19 +1509,19 @@ Int_t  AliTPCtrackerMI::LoadInnerSectors() {
   UInt_t index=0;
   for (Int_t sec = 0;sec<fkNIS;sec++)
     for (Int_t row = 0;row<nrows;row++){
-      AliTPCRow*  tpcrow = &(fInnerSec[sec%fkNIS][row]);
+      AliTPCtrackerRow*  tpcrow = &(fInnerSec[sec%fkNIS][row]);
       //
       //left
-      Int_t ncl = tpcrow->fN1;
+      Int_t ncl = tpcrow->GetN1();
       while (ncl--) {
-       AliTPCclusterMI *c= &(tpcrow->fClusters1[ncl]);
+       AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
        index=(((sec<<8)+row)<<16)+ncl;
        tpcrow->InsertCluster(c,index);
       }
       //right
-      ncl = tpcrow->fN2;
+      ncl = tpcrow->GetN2();
       while (ncl--) {
-       AliTPCclusterMI *c= &(tpcrow->fClusters2[ncl]);
+       AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
        index=((((sec+fkNIS)<<8)+row)<<16)+ncl;
        tpcrow->InsertCluster(c,index);
       }
@@ -1282,17 +1529,17 @@ Int_t  AliTPCtrackerMI::LoadInnerSectors() {
       // write indexes for fast acces
       //
       for (Int_t i=0;i<510;i++)
-       tpcrow->fFastCluster[i]=-1;
+       tpcrow->SetFastCluster(i,-1);
       for (Int_t i=0;i<tpcrow->GetN();i++){
         Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
-       tpcrow->fFastCluster[zi]=i;  // write index
+       tpcrow->SetFastCluster(zi,i);  // write index
       }
       Int_t last = 0;
       for (Int_t i=0;i<510;i++){
-       if (tpcrow->fFastCluster[i]<0)
-         tpcrow->fFastCluster[i] = last;
+       if (tpcrow->GetFastCluster(i)<0)
+         tpcrow->SetFastCluster(i,last);
        else
-         last = tpcrow->fFastCluster[i];
+         last = tpcrow->GetFastCluster(i);
       }
 
     }  
@@ -1309,41 +1556,51 @@ AliTPCclusterMI *AliTPCtrackerMI::GetClusterMI(Int_t index) const {
   //--------------------------------------------------------------------
   //       Return pointer to a given cluster
   //--------------------------------------------------------------------
+  if (index<0) return 0; // no cluster
   Int_t sec=(index&0xff000000)>>24; 
   Int_t row=(index&0x00ff0000)>>16; 
   Int_t ncl=(index&0x00007fff)>>00;
 
-  const AliTPCRow * tpcrow=0;
-  AliTPCclusterMI * clrow =0;
+  const AliTPCtrackerRow * tpcrow=0;
+  TClonesArray * clrow =0;
+
+  if (sec<0 || sec>=fkNIS*4) {
+    AliWarning(Form("Wrong sector %d",sec));
+    return 0x0;
+  }
 
   if (sec<fkNIS*2){
-    tpcrow = &(fInnerSec[sec%fkNIS][row]);
+    AliTPCtrackerSector& tracksec = fInnerSec[sec%fkNIS];
+    if (tracksec.GetNRows()<=row) return 0;
+    tpcrow = &(tracksec[row]);
     if (tpcrow==0) return 0;
 
     if (sec<fkNIS) {
-      if (tpcrow->fN1<=ncl) return 0;
-      clrow = tpcrow->fClusters1;
+      if (tpcrow->GetN1()<=ncl) return 0;
+      clrow = tpcrow->GetClusters1();
     }
     else {
-      if (tpcrow->fN2<=ncl) return 0;
-      clrow = tpcrow->fClusters2;
+      if (tpcrow->GetN2()<=ncl) return 0;
+      clrow = tpcrow->GetClusters2();
     }
   }
   else {
-    tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
+    AliTPCtrackerSector& tracksec = fOuterSec[(sec-fkNIS*2)%fkNOS];
+    if (tracksec.GetNRows()<=row) return 0;
+    tpcrow = &(tracksec[row]);
     if (tpcrow==0) return 0;
 
     if (sec-2*fkNIS<fkNOS) {
-      if (tpcrow->fN1<=ncl) return 0;
-      clrow = tpcrow->fClusters1;
+      if (tpcrow->GetN1()<=ncl) return 0;
+      clrow = tpcrow->GetClusters1();
     }
     else {
-      if (tpcrow->fN2<=ncl) return 0;
-      clrow = tpcrow->fClusters2;
+      if (tpcrow->GetN2()<=ncl) return 0;
+      clrow = tpcrow->GetClusters2();
     }
   }
 
-  return &(clrow[ncl]);      
+  return (AliTPCclusterMI*)clrow->At(ncl);
   
 }
 
@@ -1355,6 +1612,8 @@ Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
   //-----------------------------------------------------------------
   //
   Double_t  x= GetXrow(nr), ymax=GetMaxY(nr);
+  //
+  //
   AliTPCclusterMI *cl=0;
   Int_t tpcindex= t.GetClusterIndex2(nr);
   //
@@ -1366,10 +1625,11 @@ Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_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 (tpcindex >= 0){     //
+      cl = t.GetClusterPointer(nr);
+      //if (cl==0) cl = GetClusterMI(tpcindex);
+      if (!cl) cl = GetClusterMI(tpcindex);
+      t.SetCurrentClusterIndex1(tpcindex); 
     }
     if (cl){      
       Int_t relativesector = ((tpcindex&0xff000000)>>24)%18;  // if previously accepted cluster in different sector
@@ -1380,73 +1640,99 @@ Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
       
       if (TMath::Abs(angle-t.GetAlpha())>0.001){
        Double_t rotation = angle-t.GetAlpha();
-       t.fRelativeSector= relativesector;
-       if (!t.Rotate(rotation)) return 0;      
+       t.SetRelativeSector(relativesector);
+       if (!t.Rotate(rotation)) {
+          t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
+          return 0;
+        }      
+      }
+      if (!t.PropagateTo(x)) {
+        t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
+        return 0;
       }
-      if (!t.PropagateTo(x)) return 0;
       //
-      t.fCurrentCluster = cl
-      t.fRow = nr;
-      Int_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);
+      t.SetCurrentCluster(cl)
+      t.SetRow(nr);
+      Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
       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.SetErrorY2(t.GetErrorY2()+0.03);
+         t.SetErrorZ2(t.GetErrorZ2()+0.03)
+         t.SetErrorY2(t.GetErrorY2()*3);
+         t.SetErrorZ2(t.GetErrorZ2()*3)
        }
-       t.fNFoundable++;
+       t.SetNFoundable(t.GetNFoundable()+1);
        UpdateTrack(&t,accept);
        return 1;
-      }    
+      }
+      else { // Remove old cluster from track
+       t.SetClusterIndex(nr, -3);
+       t.SetClusterPointer(nr, 0);
+      }
     }
   }
   if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;  // cut on angle
-  if (fIteration>1){
+  if (fIteration>1 && IsFindable(t)){
     // not look for new cluster during refitting    
-    t.fNFoundable++; 
+    t.SetNFoundable(t.GetNFoundable()+1);
     return 0;
   }
   //
   UInt_t index=0;
   //  if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
-  Double_t  y=t.GetYat(x);
+  if (!t.PropagateTo(x)) {
+    if (fIteration==0) t.SetRemoval(10);
+    return 0;
+  }
+  Double_t y = t.GetY(); 
   if (TMath::Abs(y)>ymax){
     if (y > ymax) {
-      t.fRelativeSector= (t.fRelativeSector+1) % fN;
+      t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
       if (!t.Rotate(fSectors->GetAlpha())) 
        return 0;
     } else if (y <-ymax) {
-      t.fRelativeSector= (t.fRelativeSector-1+fN) % fN;
+      t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
       if (!t.Rotate(-fSectors->GetAlpha())) 
        return 0;
     }
-    //return 1;
+    if (!t.PropagateTo(x)) {
+      if (fIteration==0) t.SetRemoval(10);
+      return 0;
+    }
+    y = t.GetY();
   }
   //
-  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 (!IsActive(t.GetRelativeSector(),nr)) {
+    t.SetInDead(kTRUE);
+    t.SetClusterIndex2(nr,-1); 
+    return 0;
+  }
+  //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
+  Bool_t isActive  = IsActive(t.GetRelativeSector(),nr);
+  Bool_t isActive2 = (nr>=fInnerSec->GetNRows()) ? fOuterSec[t.GetRelativeSector()][nr-fInnerSec->GetNRows()].GetN()>0:fInnerSec[t.GetRelativeSector()][nr].GetN()>0;
+  
+  if (!isActive || !isActive2) return 0;
+
+  const AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
   if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
   Double_t  roady  =1.;
   Double_t  roadz = 1.;
   //
-  if (TMath::Abs(TMath::Abs(y)-ymax)<krow.fDeadZone){
-    t.fInDead = kTRUE;
+  if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
+    t.SetInDead(kTRUE);
     t.SetClusterIndex2(nr,-1); 
     return 0;
   } 
   else
     {
-      if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fParam->GetZLength() && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker())) 
-       t.fNFoundable++;
+      if (IsFindable(t))
+         //      if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fkParam->GetZLength(0) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker())) 
+       t.SetNFoundable(t.GetNFoundable()+1);
       else
        return 0;
     }   
@@ -1454,18 +1740,18 @@ Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
   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);       
+    if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));       
   }  
   if (cl) {
-    t.fCurrentCluster = cl
-    t.fRow = nr;
+    t.SetCurrentCluster(cl)
+    t.SetRow(nr);
     if (fIteration==2&&cl->IsUsed(10)) return 0; 
-    Int_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);
+    Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
     if (fIteration==2&&cl->IsUsed(11)) {
-      t.fErrorY2 += 0.03;
-      t.fErrorZ2 += 0.03
-      t.fErrorY2 *= 3;
-      t.fErrorZ2 *= 3
+      t.SetErrorY2(t.GetErrorY2()+0.03);
+      t.SetErrorZ2(t.GetErrorZ2()+0.03)
+      t.SetErrorY2(t.GetErrorY2()*3);
+      t.SetErrorZ2(t.GetErrorZ2()*3)
     }
     /*    
     if (t.fCurrentCluster->IsUsed(10)){
@@ -1482,85 +1768,8 @@ Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
     if (accept<3) UpdateTrack(&t,accept);
 
   } else {  
-    if ( fIteration==0 && t.fNFoundable*0.5 > t.GetNumberOfClusters()) t.fRemoval=10;
-    
-  }
-  return 1;
-}
-
-Int_t AliTPCtrackerMI::FollowToNextFast(AliTPCseed& t, Int_t nr) {
-  //-----------------------------------------------------------------
-  // This function tries to find a track prolongation to next pad row
-  //-----------------------------------------------------------------
-  //
-  Double_t  x= GetXrow(nr), ymax=GetMaxY(nr);
-  Double_t y,z; 
-  if (!t.GetProlongation(x,y,z)) {
-    t.fRemoval = 10;
-    return 0;
-  }
-  //
-  //
-  if (TMath::Abs(y)>ymax){
+    if ( fIteration==0 && t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) t.SetRemoval(10);
     
-    if (y > ymax) {
-      t.fRelativeSector= (t.fRelativeSector+1) % fN;
-      if (!t.Rotate(fSectors->GetAlpha())) 
-       return 0;
-    } else if (y <-ymax) {
-      t.fRelativeSector= (t.fRelativeSector-1+fN) % fN;
-      if (!t.Rotate(-fSectors->GetAlpha())) 
-       return 0;
-    }
-    if (!t.PropagateTo(x)) {
-      return 0;
-    } 
-    t.GetProlongation(x,y,z);
-  }
-  //
-  // update current shape info every 3 pad-row
-  if ( (nr%6==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;
-  const AliTPCRow &krow=GetRow(t.fRelativeSector,nr);
-  if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
-  Double_t  roady  =1.;
-  Double_t  roadz = 1.;
-  //
-  Int_t row = nr;
-  if (TMath::Abs(TMath::Abs(y)-ymax)<krow.fDeadZone){
-    t.fInDead = kTRUE;
-    t.SetClusterIndex2(row,-1); 
-    return 0;
-  } 
-  else
-    {
-      if (TMath::Abs(z)>(AliTPCReconstructor::GetCtgRange()*x+10)) t.SetClusterIndex2(row,-1);
-    }   
-  //calculate 
-  
-  if ((cl==0)&&(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);       
-  }  
-
-  if (cl) {
-    t.fCurrentCluster = cl; 
-    //    Int_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);        
-    //if (accept<3){
-      t.SetClusterIndex2(row,index);
-      t.fClusterPointer[row] = cl;
-      //}
   }
   return 1;
 }
@@ -1577,19 +1786,19 @@ Bool_t AliTPCtrackerMI::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
   Int_t sector = (index&0xff000000)>>24;
   //  Int_t row = (index&0x00ff0000)>>16;
   Float_t xyz[3];
-  //  xyz[0] = fParam->GetPadRowRadii(sector,row);
+  //  xyz[0] = fkParam->GetPadRowRadii(sector,row);
   xyz[0] = cl->GetX();
   xyz[1] = cl->GetY();
   xyz[2] = cl->GetZ();
   Float_t sin,cos;
-  fParam->AdjustCosSin(sector,cos,sin);
+  fkParam->AdjustCosSin(sector,cos,sin);
   Float_t x = cos*xyz[0]-sin*xyz[1];
   Float_t y = cos*xyz[1]+sin*xyz[0];
   Float_t cov[6];
   Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
-  if (sector < fParam->GetNInnerSector()) sigmaY2 *= 2.07;
+  if (sector < fkParam->GetNInnerSector()) sigmaY2 *= 2.07;
   Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
-  if (sector < fParam->GetNInnerSector()) sigmaZ2 *= 1.77;
+  if (sector < fkParam->GetNInnerSector()) sigmaZ2 *= 1.77;
   cov[0] = sin*sin*sigmaY2;
   cov[1] = -sin*cos*sigmaY2;
   cov[2] = 0.;
@@ -1597,17 +1806,17 @@ Bool_t AliTPCtrackerMI::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
   cov[4] = 0.;
   cov[5] = sigmaZ2;
   p.SetXYZ(x,y,xyz[2],cov);
-  AliAlignObj::ELayerID iLayer;
+  AliGeomManager::ELayerID iLayer;
   Int_t idet;
-  if (sector < fParam->GetNInnerSector()) {
-    iLayer = AliAlignObj::kTPC1;
+  if (sector < fkParam->GetNInnerSector()) {
+    iLayer = AliGeomManager::kTPC1;
     idet = sector;
   }
   else {
-    iLayer = AliAlignObj::kTPC2;
-    idet = sector - fParam->GetNInnerSector();
+    iLayer = AliGeomManager::kTPC2;
+    idet = sector - fkParam->GetNInnerSector();
   }
-  UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,idet);
+  UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
   p.SetVolumeID(volid);
   return kTRUE;
 }
@@ -1618,8 +1827,8 @@ Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t,  Int_t nr) {
   //-----------------------------------------------------------------
   // This function tries to find a track prolongation to next pad row
   //-----------------------------------------------------------------
-  t.fCurrentCluster  = 0;
-  t.fCurrentClusterIndex1 = 0;   
+  t.SetCurrentCluster(0);
+  t.SetCurrentClusterIndex1(-3);   
    
   Double_t xt=t.GetX();
   Int_t     row = GetRowNumber(xt)-1; 
@@ -1648,11 +1857,11 @@ Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t,  Int_t nr) {
 
   if (TMath::Abs(y)>ymax){
     if (y > ymax) {
-      t.fRelativeSector= (t.fRelativeSector+1) % fN;
+      t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
       if (!t.Rotate(fSectors->GetAlpha())) 
        return 0;
     } else if (y <-ymax) {
-      t.fRelativeSector= (t.fRelativeSector-1+fN) % fN;
+      t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
       if (!t.Rotate(-fSectors->GetAlpha())) 
        return 0;
     }
@@ -1664,22 +1873,32 @@ Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t,  Int_t nr) {
   }
   //
   if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
-  AliTPCRow &krow=GetRow(t.fRelativeSector,nr);
 
-  if (TMath::Abs(TMath::Abs(y)-ymax)<krow.fDeadZone){
-    t.fInDead = kTRUE;
+  if (!IsActive(t.GetRelativeSector(),nr)) {
+    t.SetInDead(kTRUE);
+    t.SetClusterIndex2(nr,-1); 
+    return 0;
+  }
+  //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
+
+  AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
+
+  if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
+    t.SetInDead(kTRUE);
     t.SetClusterIndex2(nr,-1); 
     return 0;
   } 
   else
     {
-      if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker())) t.fNFoundable++;
+
+      //      if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker())) 
+      if (IsFindable(t)) t.SetNFoundable(t.GetNFoundable()+1);
       else
        return 0;      
     }
 
   // update current
-  if ( (nr%6==0) || t.GetNumberOfClusters()<2){
+  if ( (nr%2==0) || t.GetNumberOfClusters()<2){
     //    t.fCurrentSigmaY = GetSigmaY(&t);
     //t.fCurrentSigmaZ = GetSigmaZ(&t);
     GetShape(&t,nr);
@@ -1694,12 +1913,12 @@ Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t,  Int_t nr) {
 
   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 ( (index >= 0) && (index&0x8000)==0){
+      cl = t.GetClusterPointer(nr);
+      if ( (cl==0) && (index >= 0)) cl = GetClusterMI(index);
+      t.SetCurrentClusterIndex1(index);
       if (cl) {
-       t.fCurrentCluster  = cl;
+       t.SetCurrentCluster(cl);
        return 1;
       }
     }
@@ -1713,8 +1932,8 @@ Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t,  Int_t nr) {
     cl = krow.FindNearest2(y,z,roady,roadz,uindex);      
   }
 
-  if (cl) t.fCurrentClusterIndex1 = krow.GetIndex(uindex);   
-  t.fCurrentCluster  = cl;
+  if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(uindex));   
+  t.SetCurrentCluster(cl);
 
   return 1;
 }
@@ -1727,18 +1946,18 @@ Int_t AliTPCtrackerMI::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
 
   //update error according neighborhoud
 
-  if (t.fCurrentCluster) {
-    t.fRow = nr
-    Int_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);
+  if (t.GetCurrentCluster()) {
+    t.SetRow(nr)
+    Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
     
-    if (t.fCurrentCluster->IsUsed(10)){
+    if (t.GetCurrentCluster()->IsUsed(10)){
       //
       //
       //  t.fErrorZ2*=2;
       //  t.fErrorY2*=2;
-      t.fNShared++;
-      if (t.fNShared>0.7*t.GetNumberOfClusters()) {
-       t.fRemoval =10;
+      t.SetNShared(t.GetNShared()+1);
+      if (t.GetNShared()>0.7*t.GetNumberOfClusters()) {
+       t.SetRemoval(10);
        return 0;
       }
     }   
@@ -1747,10 +1966,10 @@ Int_t AliTPCtrackerMI::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
  
   } else {
     if (fIteration==0){
-      if ( ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16)&& t.GetNumberOfClusters()>18) t.fRemoval=10;      
-      if (  t.GetChi2()/t.GetNumberOfClusters()>6 &&t.GetNumberOfClusters()>18) t.fRemoval=10;      
+      if ( t.GetNumberOfClusters()>18 && ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16)) t.SetRemoval(10);      
+      if ( t.GetNumberOfClusters()>18 && t.GetChi2()/t.GetNumberOfClusters()>6 ) t.SetRemoval(10);      
 
-      if (( (t.fNFoundable*0.5 > t.GetNumberOfClusters()) || t.fNoCluster>15)) t.fRemoval=10;
+      if (( (t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) || t.GetNoCluster()>15)) t.SetRemoval(10);
     }
   }
   return 1;
@@ -1759,19 +1978,23 @@ Int_t AliTPCtrackerMI::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
 
 
 //_____________________________________________________________________________
-Int_t AliTPCtrackerMI::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step) {
+Int_t AliTPCtrackerMI::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step, Bool_t fromSeeds) {
   //-----------------------------------------------------------------
   // This function tries to find a track prolongation.
   //-----------------------------------------------------------------
   Double_t xt=t.GetX();
   //
-  Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
+  Double_t alpha=t.GetAlpha();
   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;
+  t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
     
-  Int_t first = GetRowNumber(xt)-1;
+  Int_t first = GetRowNumber(xt);
+  if (!fromSeeds)
+    first -= step;
+  if (first < 0)
+    first = 0;
   for (Int_t nr= first; nr>=rf; nr-=step) {
     // update kink info
     if (t.GetKinkIndexes()[0]>0){
@@ -1780,7 +2003,7 @@ Int_t AliTPCtrackerMI::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step) {
        if (index==0) break;
        if (index<0) continue;
        //
-       AliESDkink * kink = fEvent->GetKink(index-1);
+       AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
        if (!kink){
          printf("PROBLEM\n");
        }
@@ -1810,44 +2033,27 @@ Int_t AliTPCtrackerMI::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step) {
 }
 
 
-//_____________________________________________________________________________
-Int_t AliTPCtrackerMI::FollowProlongationFast(AliTPCseed& t, Int_t rf, Int_t step) {
-  //-----------------------------------------------------------------
-  // This function tries to find a track prolongation.
-  //-----------------------------------------------------------------
-  Double_t xt=t.GetX();
-  //
-  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;
-    
-  for (Int_t nr=GetRowNumber(xt)-1; nr>=rf; nr-=step) {
-    
-    if (FollowToNextFast(t,nr)==0) 
-      if (!t.IsActive()) return 0;
-    
-  }   
-  return 1;
-}
-
 
 
 
 
-Int_t AliTPCtrackerMI::FollowBackProlongation(AliTPCseed& t, Int_t rf) {
+Int_t AliTPCtrackerMI::FollowBackProlongation(AliTPCseed& t, Int_t rf, Bool_t fromSeeds) {
   //-----------------------------------------------------------------
   // This function tries to find a track prolongation.
   //-----------------------------------------------------------------
   //
   Double_t xt=t.GetX();  
-  Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
+  Double_t alpha=t.GetAlpha();
   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;
+  t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
     
-  Int_t first = t.fFirstPoint;
-  if (first<GetRowNumber(xt)+1) first = GetRowNumber(xt)+1;
+  Int_t first = t.GetFirstPoint();
+  Int_t ri = GetRowNumber(xt); 
+  if (!fromSeeds)
+    ri += 1;
+
+  if (first<ri) first = ri;
   //
   if (first<0) first=0;
   for (Int_t nr=first; nr<=rf; nr++) {
@@ -1858,7 +2064,7 @@ Int_t AliTPCtrackerMI::FollowBackProlongation(AliTPCseed& t, Int_t rf) {
        if (index==0) break;
        if (index>0) continue;
        index = TMath::Abs(index);
-       AliESDkink * kink = fEvent->GetKink(index-1);
+       AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
        if (!kink){
          printf("PROBLEM\n");
        }
@@ -1878,6 +2084,7 @@ Int_t AliTPCtrackerMI::FollowBackProlongation(AliTPCseed& t, Int_t rf) {
       fSectors = fInnerSec;
     else
       fSectors = fOuterSec;
+
     FollowToNext(t,nr);                                                             
   }   
   return 1;
@@ -1889,7 +2096,7 @@ Int_t AliTPCtrackerMI::FollowBackProlongation(AliTPCseed& t, Int_t rf) {
    
 Float_t AliTPCtrackerMI::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t & sum2)
 {
-  //
+  // overlapping factor
   //
   sum1=0;
   sum2=0;
@@ -1904,8 +2111,8 @@ Float_t AliTPCtrackerMI::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &
   if (distance>4.) return 0; // if there are far away  - not overlap - to reduce combinatorics
  
   //  Int_t offset =0;
-  Int_t firstpoint = TMath::Min(s1->fFirstPoint,s2->fFirstPoint);
-  Int_t lastpoint = TMath::Max(s1->fLastPoint,s2->fLastPoint);
+  Int_t firstpoint = TMath::Min(s1->GetFirstPoint(),s2->GetFirstPoint());
+  Int_t lastpoint = TMath::Max(s1->GetLastPoint(),s2->GetLastPoint());
   if (lastpoint>160) 
     lastpoint =160;
   if (firstpoint<0) 
@@ -1932,25 +2139,22 @@ Float_t AliTPCtrackerMI::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &
 
 void  AliTPCtrackerMI::SignShared(AliTPCseed * s1, AliTPCseed * s2)
 {
+  // shared clusters
   //
-  //
-  if (TMath::Abs(s1->GetC()-s2->GetC())>0.004) return;
-  if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>0.6) return;
-
-  Float_t dz2 =(s1->GetZ() - s2->GetZ());
-  dz2*=dz2;
-  Float_t dy2 =(s1->GetY() - s2->GetY());
-  dy2*=dy2;
-  Float_t distance = dz2+dy2;
-  if (distance>325.) return ; // if there are far away  - not overlap - to reduce combinatorics
+  Float_t thetaCut = 0.2;//+10.*TMath::Sqrt(s1->GetSigmaTglZ()+ s2->GetSigmaTglZ());
+  if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>thetaCut) return;
+  Float_t minCl = TMath::Min(s1->GetNumberOfClusters(),s2->GetNumberOfClusters());
+  Int_t cutN0 = TMath::Max(5,TMath::Nint(0.1*minCl));
   
   //
   Int_t sumshared=0;
   //
-  Int_t firstpoint = TMath::Max(s1->fFirstPoint,s2->fFirstPoint);
-  Int_t lastpoint = TMath::Min(s1->fLastPoint,s2->fLastPoint);
+  //Int_t firstpoint = TMath::Max(s1->GetFirstPoint(),s2->GetFirstPoint());
+  //Int_t lastpoint = TMath::Min(s1->GetLastPoint(),s2->GetLastPoint());
+  Int_t firstpoint = 0;
+  Int_t lastpoint = 160;
   //
-  if (firstpoint>=lastpoint-5) return;;
+  //  if (firstpoint>=lastpoint-5) return;;
 
   for (Int_t i=firstpoint;i<lastpoint;i++){
     //    if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
@@ -1958,7 +2162,7 @@ void  AliTPCtrackerMI::SignShared(AliTPCseed * s1, AliTPCseed * s2)
       sumshared++;
     }
   }
-  if (sumshared>4){
+  if (sumshared>cutN0){
     // sign clusters
     //
     for (Int_t i=firstpoint;i<lastpoint;i++){
@@ -1967,32 +2171,31 @@ void  AliTPCtrackerMI::SignShared(AliTPCseed * s1, AliTPCseed * s2)
        AliTPCTrackerPoint *p1  = s1->GetTrackPoint(i);
        AliTPCTrackerPoint *p2  = s2->GetTrackPoint(i);; 
        if (s1->IsActive()&&s2->IsActive()){
-         p1->fIsShared = kTRUE;
-         p2->fIsShared = kTRUE;
+         p1->SetShared(kTRUE);
+         p2->SetShared(kTRUE);
        }       
       }
     }
   }
   //  
-  if (sumshared>10){
+  if (sumshared>cutN0){
     for (Int_t i=0;i<4;i++){
-      if (s1->fOverlapLabels[3*i]==0){
-       s1->fOverlapLabels[3*i] = s2->GetLabel();
-       s1->fOverlapLabels[3*i+1] = sumshared;
-       s1->fOverlapLabels[3*i+2] = s2->GetUniqueID();
+      if (s1->GetOverlapLabel(3*i)==0){
+       s1->SetOverlapLabel(3*i,  s2->GetLabel());
+       s1->SetOverlapLabel(3*i+1,sumshared);
+       s1->SetOverlapLabel(3*i+2,s2->GetUniqueID());
        break;
       }        
     }
     for (Int_t i=0;i<4;i++){
-      if (s2->fOverlapLabels[3*i]==0){
-       s2->fOverlapLabels[3*i] = s1->GetLabel();
-       s2->fOverlapLabels[3*i+1] = sumshared;
-       s2->fOverlapLabels[3*i+2] = s1->GetUniqueID();
+      if (s2->GetOverlapLabel(3*i)==0){
+       s2->SetOverlapLabel(3*i,  s1->GetLabel());
+       s2->SetOverlapLabel(3*i+1,sumshared);
+       s2->SetOverlapLabel(3*i+2,s1->GetUniqueID());
        break;
       }        
     }    
   }
-  
 }
 
 void  AliTPCtrackerMI::SignShared(TObjArray * arr)
@@ -2004,10 +2207,10 @@ void  AliTPCtrackerMI::SignShared(TObjArray * arr)
     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
     if (!pt) continue;
     //if (pt) RotateToLocal(pt);
-    pt->fSort = 0;
+    pt->SetSort(0);
   }
   arr->UnSort();
-  arr->Sort();  // sorting according z
+  arr->Sort();  // sorting according relative sectors
   arr->Expand(arr->GetEntries());
   //
   //
@@ -2015,271 +2218,153 @@ void  AliTPCtrackerMI::SignShared(TObjArray * arr)
   for (Int_t i=0; i<nseed; i++) {
     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
     if (!pt) continue;
-    for (Int_t j=0;j<=12;j++){
-      pt->fOverlapLabels[j] =0;
+    for (Int_t j=0;j<12;j++){
+      pt->SetOverlapLabel(j,0);
     }
   }
   for (Int_t i=0; i<nseed; i++) {
     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
     if (!pt) continue;
-    if (pt->fRemoval>10) continue;
+    if (pt->GetRemoval()>10) continue;
     for (Int_t j=i+1; j<nseed; j++){
       AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
+      if (TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>1) continue;
       //      if (pt2){
-      if (pt2->fRemoval<=10) {
-       if ( TMath::Abs(pt->fRelativeSector-pt2->fRelativeSector)>0) break;
+      if (pt2->GetRemoval()<=10) {
+       //if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
        SignShared(pt,pt2);
       }
     }  
   }
 }
 
-void  AliTPCtrackerMI::RemoveDouble(TObjArray * arr, Float_t factor1, Float_t factor2,  Int_t removalindex)
+
+void AliTPCtrackerMI::SortTracks(TObjArray * arr, Int_t mode) const
 {
   //
-  //sort trackss according sectors
-  //
-  if (fDebug&1) {
-    Info("RemoveDouble","Number of tracks before double removal- %d\n",arr->GetEntries());
-  }
-  //
-  for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
+  //sort tracks in array according mode criteria
+  Int_t nseed = arr->GetEntriesFast();    
+  for (Int_t i=0; i<nseed; i++) {
     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
-    if (!pt) continue;
-    pt->fSort = 0;
+    if (!pt) {
+      continue;
+    }
+    pt->SetSort(mode);
   }
   arr->UnSort();
-  arr->Sort();  // sorting according z
-  arr->Expand(arr->GetEntries());
+  arr->Sort();
+}
+
+
+void AliTPCtrackerMI::RemoveUsed2(TObjArray * arr, Float_t factor1,  Float_t factor2, Int_t minimal)
+{
+  //
+  // Loop over all tracks and remove overlaped tracks (with lower quality)
+  // Algorithm:
+  //    1. Unsign clusters
+  //    2. Sort tracks according quality
+  //       Quality is defined by the number of cluster between first and last points 
+  //       
+  //    3. Loop over tracks - decreasing quality order
+  //       a.) remove - If the fraction of shared cluster less than factor (1- n or 2) 
+  //       b.) remove - If the minimal number of clusters less than minimal and not ITS
+  //       c.) if track accepted - sign clusters
+  //
+  //Called in - AliTPCtrackerMI::Clusters2Tracks()
+  //          - AliTPCtrackerMI::PropagateBack()
+  //          - AliTPCtrackerMI::RefitInward()
+  //
+  // Arguments:
+  //   factor1 - factor for constrained
+  //   factor2 -        for non constrained tracks 
+  //            if (Float_t(shared+1)/Float_t(found+1)>factor) - DELETE
+  //
+  UnsignClusters();
+  //
+  Int_t nseed = arr->GetEntriesFast();  
+  Float_t * quality = new Float_t[nseed];
+  Int_t   * indexes = new Int_t[nseed];
+  Int_t good =0;
   //
-  //reset overlap labels
   //
-  Int_t nseed=arr->GetEntriesFast();
   for (Int_t i=0; i<nseed; i++) {
     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
-    if (!pt) continue;
-    pt->SetUniqueID(i);
-    for (Int_t j=0;j<=12;j++){
-      pt->fOverlapLabels[j] =0;
+    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();
+    //prefer high momenta tracks if overlaps
+    quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5); 
   }
+  TMath::Sort(nseed,quality,indexes);
   //
-  //sign shared tracks
-  for (Int_t i=0; i<nseed; i++) {
-    AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
+  //
+  for (Int_t itrack=0; itrack<nseed; itrack++) {
+    Int_t trackindex = indexes[itrack];
+    AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);   
     if (!pt) continue;
-    if (pt->fRemoval>10) continue;
-    Float_t deltac = pt->GetC()*0.1;
-    for (Int_t j=i+1; j<nseed; j++){
-      AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
-      //      if (pt2){
-      if (pt2->fRemoval<=10) {
-       if ( TMath::Abs(pt->fRelativeSector-pt2->fRelativeSector)>0) break;
-       if (TMath::Abs(pt->GetC()  -pt2->GetC())>deltac) continue;
-       if (TMath::Abs(pt->GetTgl()-pt2->GetTgl())>0.05) continue;
-       //
-       SignShared(pt,pt2);
-      }
-    }
-  }
-  //
-  // remove highly shared tracks
-  for (Int_t i=0; i<nseed; i++) {
-    AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
-    if (!pt) continue;
-    if (pt->fRemoval>10) continue;
-    //
-    Int_t sumshared =0;
-    for (Int_t j=0;j<4;j++){
-      sumshared = pt->fOverlapLabels[j*3+1];      
-    }
-    Float_t factor = factor1;
-    if (pt->fRemoval>0) factor = factor2;
-    if (sumshared/pt->GetNumberOfClusters()>factor){
-      for (Int_t j=0;j<4;j++){
-       if (pt->fOverlapLabels[3*j]==0) continue;
-       if (pt->fOverlapLabels[3*j+1]<5) continue; 
-       if (pt->fRemoval==removalindex) continue;      
-       AliTPCseed * pt2 = (AliTPCseed*)arr->UncheckedAt(pt->fOverlapLabels[3*j+2]);
-       if (!pt2) continue;
-       if (pt2->GetSigma2C()<pt->GetSigma2C()){
-         //      pt->fRemoval = removalindex;
-         delete arr->RemoveAt(i);        
-         break;
-       }
-      }      
-    }
-  }
-  arr->Compress();
-  if (fDebug&1) {
-    Info("RemoveDouble","Number of tracks after double removal- %d\n",arr->GetEntries());
-  }
-}
-
-
-
-
-
-
-void AliTPCtrackerMI::SortTracks(TObjArray * arr, Int_t mode) const
-{
-  //
-  //sort tracks in array according mode criteria
-  Int_t nseed = arr->GetEntriesFast();    
-  for (Int_t i=0; i<nseed; i++) {
-    AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
-    if (!pt) {
-      continue;
-    }
-    pt->fSort = mode;
-  }
-  arr->UnSort();
-  arr->Sort();
-}
-
-void AliTPCtrackerMI::RemoveUsed(TObjArray * arr, Float_t factor1,  Float_t factor2, Int_t removalindex)
-{
-
-  //Loop over all tracks and remove "overlaps"
-  //
-  //
-  Int_t nseed = arr->GetEntriesFast();  
-  Int_t good =0;
-
-  for (Int_t i=0; i<nseed; i++) {
-    AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
-    if (!pt) {
-      delete arr->RemoveAt(i);
-    }
-    else{
-      pt->fSort =1;
-      pt->fBSigned = kFALSE;
-    }
-  }
-  arr->Compress();
-  nseed = arr->GetEntriesFast();
-  arr->UnSort();
-  arr->Sort();
-  //
-  //unsign used
-  UnsignClusters();
-  //
-  for (Int_t i=0; i<nseed; i++) {
-    AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
-    if (!pt) {
-      continue;
-    }    
-    Int_t found,foundable,shared;
-    if (pt->IsActive()) 
-      pt->GetClusterStatistic(0,160,found, foundable,shared,kFALSE);
-    else
-      pt->GetClusterStatistic(0,160,found, foundable,shared,kTRUE); 
-    //
-    Double_t factor = factor2;
-    if (pt->fBConstrain) factor = factor1;
-
-    if ((Float_t(shared)/Float_t(found))>factor){
-      pt->Desactivate(removalindex);
-      continue;
-    }
-
-    good++;
-    for (Int_t i=0; i<160; i++) {
-      Int_t index=pt->GetClusterIndex2(i);
-      if (index<0 || index&0x8000 ) continue;
-      AliTPCclusterMI *c= pt->fClusterPointer[i];        
-      if (!c) continue;
-      //      if (!c->IsUsed(10)) c->Use(10);
-      //if (pt->IsActive()) 
-      c->Use(10);  
-      //else
-      //       c->Use(5);
-    }
-    
-  }
-  fNtracks = good;
-  if (fDebug>0){
-    Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
-  }
-}
-
-
-void AliTPCtrackerMI::RemoveUsed2(TObjArray * arr, Float_t factor1,  Float_t factor2, Int_t minimal)
-{
-
-  //Loop over all tracks and remove "overlaps"
-  //
-  //
-  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();
-  }
-  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);
-      }
+      MarkSeedFree( 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;
+    Double_t factor = (pt->GetBConstrain()) ? factor1: factor2;
     //
     Int_t found,foundable,shared;
-    pt->GetClusterStatistic(first,last, found, foundable,shared,kFALSE);
-    Float_t sharedfactor = Float_t(shared+1)/Float_t(found+1);
+    pt->GetClusterStatistic(first,last, found, foundable,shared,kFALSE); // better to get statistic in "high-dens"  region do't use full track as in line bellow
+    //    pt->GetClusterStatistic(0,160, found, foundable,shared,kFALSE);
     Bool_t itsgold =kFALSE;
-    if (pt->fEsd){
+    if (pt->GetESD()){
       Int_t dummy[12];
-      if (pt->fEsd->GetITSclusters(dummy)>4) itsgold= kTRUE;
+      if (pt->GetESD()->GetITSclusters(dummy)>4) itsgold= kTRUE;
     }
     if (!itsgold){
       //
       if (Float_t(shared+1)/Float_t(found+1)>factor){
        if (pt->GetKinkIndexes()[0]!=0) continue;  //don't remove tracks  - part of the kinks
-       delete arr->RemoveAt(trackindex);
+       if( AliTPCReconstructor::StreamLevel()>3){
+         TTreeSRedirector &cstream = *fDebugStreamer;
+         cstream<<"RemoveUsed"<<
+           "iter="<<fIteration<<
+           "pt.="<<pt<<
+           "\n";
+       }
+       MarkSeedFree( 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);
+       if( AliTPCReconstructor::StreamLevel()>3){
+         TTreeSRedirector &cstream = *fDebugStreamer;
+         cstream<<"RemoveShort"<<
+           "iter="<<fIteration<<
+           "pt.="<<pt<<
+           "\n";
+       }
+       MarkSeedFree( arr->RemoveAt(trackindex) );
        continue;
       }
     }
 
     good++;
-    if (sharedfactor>0.4) continue;
+    //if (sharedfactor>0.4) continue;
     if (pt->GetKinkIndexes()[0]>0) continue;
+    //Remove tracks with undefined properties - seems
+    if (pt->GetSigmaY2()<kAlmost0) continue; // ? what is the origin ? 
+    //
     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];        
+      AliTPCclusterMI *c= pt->GetClusterPointer(i);        
       if (!c) continue;
       c->Use(10);  
     }    
@@ -2292,6 +2377,94 @@ void AliTPCtrackerMI::RemoveUsed2(TObjArray * arr, Float_t factor1,  Float_t fac
   delete []indexes;
 }
 
+void AliTPCtrackerMI::DumpClusters(Int_t iter, TObjArray *trackArray) 
+{
+  //
+  // Dump clusters after reco
+  // signed and unsigned cluster can be visualized   
+  // 1. Unsign all cluster
+  // 2. Sign all used clusters
+  // 3. Dump clusters
+  UnsignClusters();
+  Int_t nseed = trackArray->GetEntries();
+  for (Int_t i=0; i<nseed; i++){
+    AliTPCseed *pt=(AliTPCseed*)trackArray->UncheckedAt(i);    
+    if (!pt) {
+      continue;
+    }    
+    Bool_t isKink=pt->GetKinkIndex(0)!=0;
+    for (Int_t j=0; j<160; ++j) {
+      Int_t index=pt->GetClusterIndex2(j);
+      if (index<0) continue;
+      AliTPCclusterMI *c= pt->GetClusterPointer(j);
+      if (!c) continue;
+      if (isKink) c->Use(100);   // kink
+      c->Use(10);                // by default usage 10
+    }
+  }
+  //
+
+  for (Int_t sec=0;sec<fkNIS;sec++){
+    for (Int_t row=0;row<fInnerSec->GetNRows();row++){
+      TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
+      for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++){    
+       AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
+       Float_t gx[3];  cl->GetGlobalXYZ(gx);
+       (*fDebugStreamer)<<"clDump"<< 
+         "iter="<<iter<<
+         "cl.="<<cl<<      
+         "gx0="<<gx[0]<<
+         "gx1="<<gx[1]<<
+         "gx2="<<gx[2]<<
+         "\n";
+      }
+      cla = fInnerSec[sec][row].GetClusters2();
+      for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++){
+       AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
+       Float_t gx[3];  cl->GetGlobalXYZ(gx);
+       (*fDebugStreamer)<<"clDump"<< 
+         "iter="<<iter<<
+         "cl.="<<cl<<
+         "gx0="<<gx[0]<<
+         "gx1="<<gx[1]<<
+         "gx2="<<gx[2]<<
+         "\n";
+      }
+    }
+  }
+  
+  for (Int_t sec=0;sec<fkNOS;sec++){
+    for (Int_t row=0;row<fOuterSec->GetNRows();row++){
+      TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
+      for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++){
+       Float_t gx[3];  
+       AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
+       cl->GetGlobalXYZ(gx);
+       (*fDebugStreamer)<<"clDump"<< 
+         "iter="<<iter<<
+         "cl.="<<cl<<
+         "gx0="<<gx[0]<<
+         "gx1="<<gx[1]<<
+         "gx2="<<gx[2]<<
+         "\n";      
+      }
+      cla = fOuterSec[sec][row].GetClusters2();
+      for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++){
+       Float_t gx[3];  
+       AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
+       cl->GetGlobalXYZ(gx);
+       (*fDebugStreamer)<<"clDump"<< 
+         "iter="<<iter<<
+         "cl.="<<cl<<
+         "gx0="<<gx[0]<<
+         "gx1="<<gx[1]<<
+         "gx2="<<gx[2]<<
+         "\n";      
+      }
+    }
+  }
+  
+}
 void AliTPCtrackerMI::UnsignClusters() 
 {
   //
@@ -2300,27 +2473,27 @@ void AliTPCtrackerMI::UnsignClusters()
   
   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++)
+      TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
+      for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();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++)
+       ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
+      cla = fInnerSec[sec][row].GetClusters2();
+      for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++)
        //if (cl[icl].IsUsed(10))       
-         cl[icl].Use(-1);      
+       ((AliTPCclusterMI*) cla->At(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++)
+      TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
+      for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();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++)
+       ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
+      cla = fOuterSec[sec][row].GetClusters2();
+      for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++)
        //if (cl[icl].IsUsed(10))       
-       cl[icl].Use(-1);      
+       ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
     }
   }
   
@@ -2328,7 +2501,7 @@ void AliTPCtrackerMI::UnsignClusters()
 
 
 
-void AliTPCtrackerMI::SignClusters(TObjArray * arr, Float_t fnumber, Float_t fdensity)
+void AliTPCtrackerMI::SignClusters(const TObjArray * arr, Float_t fnumber, Float_t fdensity)
 {
   //
   //sign clusters to be "used"
@@ -2355,7 +2528,7 @@ void AliTPCtrackerMI::SignClusters(TObjArray * arr, Float_t fnumber, Float_t fde
       continue;
     }    
     if (!(pt->IsActive())) continue;
-    Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->fNFoundable);
+    Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
     if ( (dens>0.7) && (pt->GetNumberOfClusters()>70)){
       sumdens += dens;
       sumdens2+= dens*dens;
@@ -2383,13 +2556,22 @@ void AliTPCtrackerMI::SignClusters(TObjArray * arr, Float_t fnumber, Float_t fde
     meanchi  = sumchi/sum;
     //
     sdensity = sumdens2/sum-mdensity*mdensity;
-    sdensity = TMath::Sqrt(sdensity);
+    if (sdensity >= 0)
+       sdensity = TMath::Sqrt(sdensity);
+    else
+       sdensity = 0.1;
     //
     smeann   = sumn2/sum-meann*meann;
-    smeann   = TMath::Sqrt(smeann);
+    if (smeann >= 0)
+      smeann   = TMath::Sqrt(smeann);
+    else 
+      smeann   = 10;
     //
     smeanchi = sumchi2/sum - meanchi*meanchi;
-    smeanchi = TMath::Sqrt(smeanchi);
+    if (smeanchi >= 0)
+      smeanchi = TMath::Sqrt(smeanchi);
+    else
+      smeanchi = 0.4;
   }
 
 
@@ -2400,23 +2582,23 @@ void AliTPCtrackerMI::SignClusters(TObjArray * arr, Float_t fnumber, Float_t fde
     if (!pt) {
       continue;
     }
-    if (pt->fBSigned) continue;
-    if (pt->fBConstrain) continue;    
+    if (pt->GetBSigned()) continue;
+    if (pt->GetBConstrain()) continue;    
     //if (!(pt->IsActive())) continue;
     /*
     Int_t found,foundable,shared;    
     pt->GetClusterStatistic(0,160,found, foundable,shared);
     if (shared/float(found)>0.3) {
       if (shared/float(found)>0.9 ){
-       //delete arr->RemoveAt(i);
+       //MarkSeedFree( arr->RemoveAt(i) );
       }
       continue;
     }
     */
     Bool_t isok =kFALSE;
-    if ( (pt->fNShared/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
+    if ( (pt->GetNShared()/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
       isok = kTRUE;
-    if ((TMath::Abs(1/pt->GetC())<100.) && (pt->fNShared/pt->GetNumberOfClusters()<0.7))
+    if ((TMath::Abs(1/pt->GetC())<100.) && (pt->GetNShared()/pt->GetNumberOfClusters()<0.7))
       isok =kTRUE;
     if  (TMath::Abs(pt->GetZ()/pt->GetX())>1.1)
       isok =kTRUE;
@@ -2424,10 +2606,10 @@ void AliTPCtrackerMI::SignClusters(TObjArray * arr, Float_t fnumber, Float_t fde
       isok =kTRUE;
     
     if (isok)     
-      for (Int_t i=0; i<160; i++) {    
-       Int_t index=pt->GetClusterIndex2(i);
+      for (Int_t j=0; j<160; ++j) {    
+       Int_t index=pt->GetClusterIndex2(j);
        if (index<0) continue;
-       AliTPCclusterMI *c= pt->fClusterPointer[i];
+       AliTPCclusterMI *c= pt->GetClusterPointer(j);
        if (!c) continue;
        //if (!(c->IsUsed(10))) c->Use();  
        c->Use(10);  
@@ -2444,12 +2626,12 @@ void AliTPCtrackerMI::SignClusters(TObjArray * arr, Float_t fnumber, Float_t fde
       continue;
     }    
     //if (!(pt->IsActive())) continue;
-    if (pt->fBSigned) continue;
+    if (pt->GetBSigned()) continue;
     Double_t chi     = pt->GetChi2()/pt->GetNumberOfClusters();
     if (chi>maxchi) continue;
 
     Float_t bfactor=1;
-    Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->fNFoundable);
+    Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
    
     //sign only tracks with enoug big density at the beginning
     
@@ -2460,17 +2642,17 @@ void AliTPCtrackerMI::SignClusters(TObjArray * arr, Float_t fnumber, Float_t fde
     Double_t minn    = TMath::Max(Int_t(meann-fnumber*smeann*bfactor),50);
    
     //    if (pt->fBConstrain) mindens = TMath::Max(mdensity-sdensity*fdensity*bfactor,0.65);
-    if ( (pt->fRemoval==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
+    if ( (pt->GetRemoval()==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
       minn=0;
 
     if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
       //Int_t noc=pt->GetNumberOfClusters();
-      pt->fBSigned = kTRUE;
-      for (Int_t i=0; i<160; i++) {
+      pt->SetBSigned(kTRUE);
+      for (Int_t j=0; j<160; ++j) {
 
-       Int_t index=pt->GetClusterIndex2(i);
+       Int_t index=pt->GetClusterIndex2(j);
        if (index<0) continue;
-       AliTPCclusterMI *c= pt->fClusterPointer[i];
+       AliTPCclusterMI *c= pt->GetClusterPointer(j);
        if (!c) continue;
        //      if (!(c->IsUsed(10))) c->Use();  
        c->Use(10);  
@@ -2485,71 +2667,50 @@ 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) const
-{
-  // stop not active tracks
-  // take th1 as threshold for number of founded to number of foundable on last 10 active rows
-  // take th2 as threshold for number of founded to number of foundable on last 20 active rows 
-  Int_t nseed = arr->GetEntriesFast();  
-  //
-  for (Int_t i=0; i<nseed; i++) {
-    AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
-    if (!pt) {
-      continue;
-    }
-    if (!(pt->IsActive())) continue;
-    StopNotActive(pt,row0,th0, th1,th2);
-  }
-}
-
-
-
-void  AliTPCtrackerMI::StopNotActive(AliTPCseed * seed, 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
-  // take th2 as threshold for number of founded to number of foundable on last 20 active rows 
-  Int_t sumgood1  = 0;
-  Int_t sumgood2  = 0;
-  Int_t foundable = 0;
-  Int_t maxindex = seed->fLastPoint;  //last foundable row
-  if (seed->fNFoundable*th0 > seed->GetNumberOfClusters()) {
-    seed->Desactivate(10) ;
-    return;
-  }
-
-  for (Int_t i=row0; i<maxindex; i++){
-    Int_t index = seed->GetClusterIndex2(i);
-    if (index!=-1) foundable++;
-    //if (!c) continue;
-    if (foundable<=30) sumgood1++;
-    if (foundable<=50) {
-      sumgood2++;
-    }
-    else{ 
-      break;
-    }        
-  }
-  if (foundable>=30.){ 
-     if (sumgood1<(th1*30.)) seed->Desactivate(10);
-  }
-  if (foundable>=50)
-    if (sumgood2<(th2*50.)) seed->Desactivate(10);
-}
-
 
-Int_t AliTPCtrackerMI::RefitInward(AliESD *event)
+Int_t AliTPCtrackerMI::RefitInward(AliESDEvent *event)
 {
   //
   // back propagation of ESD tracks
   //
   //return 0;
+  if (!event) return 0;
+  const Int_t kMaxFriendTracks=2000;
   fEvent = event;
+  // extract correction object for multiplicity dependence of dEdx
+  TObjArray * gainCalibArray = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(event->GetRunNumber());
+
+  AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
+  if (!transform) {
+    AliFatal("Tranformations not in RefitInward");
+    return 0;
+  }
+  transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
+  const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
+  Int_t nContribut = event->GetNumberOfTracks();
+  TGraphErrors * graphMultDependenceDeDx = 0x0;
+  if (recoParam && recoParam->GetUseMultiplicityCorrectionDedx() && gainCalibArray) {
+    if (recoParam->GetUseTotCharge()) {
+      graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL");
+    } else {
+      graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL");
+    }
+  }
+  //
   ReadSeeds(event,2);
   fIteration=2;
   //PrepareForProlongation(fSeeds,1);
   PropagateForward2(fSeeds);
+  RemoveUsed2(fSeeds,0.4,0.4,20);
+
+  TObjArray arraySeed(fSeeds->GetEntries());
+  for (Int_t i=0;i<fSeeds->GetEntries();i++) {
+    arraySeed.AddAt(fSeeds->At(i),i);    
+  }
+  SignShared(&arraySeed);
+  //  FindCurling(fSeeds, event,2); // find multi found tracks
+  FindSplitted(fSeeds, event,2); // find multi found tracks
+  if (AliTPCReconstructor::StreamLevel()>5)  FindMultiMC(fSeeds, fEvent,2); // find multi found tracks
 
   Int_t ntracks=0;
   Int_t nseed = fSeeds->GetEntriesFast();
@@ -2557,28 +2718,82 @@ Int_t AliTPCtrackerMI::RefitInward(AliESD *event)
     AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
     if (!seed) continue;
     if (seed->GetKinkIndex(0)>0)  UpdateKinkQualityD(seed);  // update quality informations for kinks
+    AliESDtrack *esd=event->GetTrack(i);
+
+    if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
+      AliExternalTrackParam paramIn;
+      AliExternalTrackParam paramOut;
+      Int_t ncl = seed->RefitTrack(seed,&paramIn,&paramOut);
+      if (AliTPCReconstructor::StreamLevel()>2) {
+       (*fDebugStreamer)<<"RecoverIn"<<
+         "seed.="<<seed<<
+         "esd.="<<esd<<
+         "pin.="<<&paramIn<<
+         "pout.="<<&paramOut<<
+         "ncl="<<ncl<<
+         "\n";
+      }
+      if (ncl>15) {
+       seed->Set(paramIn.GetX(),paramIn.GetAlpha(),paramIn.GetParameter(),paramIn.GetCovariance());
+       seed->SetNumberOfClusters(ncl);
+      }
+    }
 
-    seed->PropagateTo(fParam->GetInnerRadiusLow());
+    seed->PropagateTo(fkParam->GetInnerRadiusLow());
     seed->UpdatePoints();
-    AliESDtrack *esd=event->GetTrack(i);
+    AddCovariance(seed);
+    MakeESDBitmaps(seed, esd);
     seed->CookdEdx(0.02,0.6);
     CookLabel(seed,0.1); //For comparison only
     //
-    if (AliTPCReconstructor::StreamLevel()>0 && seed!=0&&esd!=0) {
+    if (AliTPCReconstructor::StreamLevel()>1 && seed!=0) {
       TTreeSRedirector &cstream = *fDebugStreamer;
       cstream<<"Crefit"<<
        "Esd.="<<esd<<
        "Track.="<<seed<<
        "\n"; 
     }
+
     if (seed->GetNumberOfClusters()>15){
       esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit); 
       esd->SetTPCPoints(seed->GetPoints());
-      esd->SetTPCPointsF(seed->fNFoundable);
-      Int_t ndedx   = seed->fNCDEDX[0]+seed->fNCDEDX[1]+seed->fNCDEDX[2]+seed->fNCDEDX[3];
-      Float_t sdedx = (seed->fSDEDX[0]+seed->fSDEDX[1]+seed->fSDEDX[2]+seed->fSDEDX[3])*0.25;
+      esd->SetTPCPointsF(seed->GetNFoundable());
+      Int_t   ndedx = seed->GetNCDEDX(0);
+      Float_t sdedx = seed->GetSDEDX(0);
       Float_t dedx  = seed->GetdEdx();
+      // apply mutliplicity dependent dEdx correction if available
+      if (graphMultDependenceDeDx) {
+       Double_t corrGain =  AliTPCcalibDButil::EvalGraphConst(graphMultDependenceDeDx, nContribut);
+       dedx += (1 - corrGain)*50.; // MIP is normalized to 50
+      }
       esd->SetTPCsignal(dedx, sdedx, ndedx);
+      //
+      // fill new dEdx information
+      //
+      Double32_t signal[4]; 
+      Char_t ncl[3]; 
+      Char_t nrows[3];
+      //
+      for(Int_t iarr=0;iarr<3;iarr++) {
+       signal[iarr] = seed->GetDEDXregion(iarr+1);
+       ncl[iarr] = seed->GetNCDEDX(iarr+1);
+       nrows[iarr] = seed->GetNCDEDXInclThres(iarr+1);
+      }
+      signal[3] = seed->GetDEDXregion(4);
+      //
+      AliTPCdEdxInfo * infoTpcPid = new AliTPCdEdxInfo();
+      infoTpcPid->SetTPCSignalRegionInfo(signal, ncl, nrows);
+      esd->SetTPCdEdxInfo(infoTpcPid);
+      //
+      // add seed to the esd track in Calib level
+      //
+      Bool_t storeFriend = gRandom->Rndm()<(kMaxFriendTracks)/Float_t(nseed);
+      if (AliTPCReconstructor::StreamLevel()>0 &&storeFriend){
+       // RS: this is the only place where the seed is created not in the pool, 
+       // since it should belong to ESDevent
+       AliTPCseed * seedCopy = new AliTPCseed(*seed, kTRUE); 
+       esd->AddCalibObject(seedCopy);
+      }
       ntracks++;
     }
     else{
@@ -2586,24 +2801,30 @@ Int_t AliTPCtrackerMI::RefitInward(AliESD *event)
     }
   }
   //FindKinks(fSeeds,event);
+  if (AliTPCReconstructor::StreamLevel()>3)  DumpClusters(2,fSeeds);
   Info("RefitInward","Number of refitted tracks %d",ntracks);
-  fEvent =0;
-  //WriteTracks();
+
+  AliCosmicTracker::FindCosmic(event, kTRUE);
+
   return 0;
 }
 
 
-Int_t AliTPCtrackerMI::PropagateBack(AliESD *event)
+Int_t AliTPCtrackerMI::PropagateBack(AliESDEvent *event)
 {
   //
   // back propagation of ESD tracks
   //
-
+  if (!event) return 0;
   fEvent = event;
   fIteration = 1;
   ReadSeeds(event,1);
   PropagateBack(fSeeds); 
   RemoveUsed2(fSeeds,0.4,0.4,20);
+  //FindCurling(fSeeds, fEvent,1);  
+  FindSplitted(fSeeds, event,1); // find multi found tracks
+  if (AliTPCReconstructor::StreamLevel()>5)  FindMultiMC(fSeeds, fEvent,1); // find multi found tracks
+
   //
   Int_t nseed = fSeeds->GetEntriesFast();
   Int_t ntracks=0;
@@ -2612,47 +2833,91 @@ Int_t AliTPCtrackerMI::PropagateBack(AliESD *event)
     if (!seed) continue;
     if (seed->GetKinkIndex(0)<0)  UpdateKinkQualityM(seed);  // update quality informations for kinks
     seed->UpdatePoints();
+    AddCovariance(seed);
     AliESDtrack *esd=event->GetTrack(i);
+    if (!esd) continue; //never happen
+    if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
+      AliExternalTrackParam paramIn;
+      AliExternalTrackParam paramOut;
+      Int_t ncl = seed->RefitTrack(seed,&paramIn,&paramOut);
+      if (AliTPCReconstructor::StreamLevel()>2) {
+       (*fDebugStreamer)<<"RecoverBack"<<
+         "seed.="<<seed<<
+         "esd.="<<esd<<
+         "pin.="<<&paramIn<<
+         "pout.="<<&paramOut<<
+         "ncl="<<ncl<<
+         "\n";
+      }
+      if (ncl>15) {
+       seed->Set(paramOut.GetX(),paramOut.GetAlpha(),paramOut.GetParameter(),paramOut.GetCovariance());
+       seed->SetNumberOfClusters(ncl);
+      }
+    }
     seed->CookdEdx(0.02,0.6);
     CookLabel(seed,0.1); //For comparison only
     if (seed->GetNumberOfClusters()>15){
       esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
       esd->SetTPCPoints(seed->GetPoints());
-      esd->SetTPCPointsF(seed->fNFoundable);
-      Int_t ndedx   = seed->fNCDEDX[0]+seed->fNCDEDX[1]+seed->fNCDEDX[2]+seed->fNCDEDX[3];
-      Float_t sdedx = (seed->fSDEDX[0]+seed->fSDEDX[1]+seed->fSDEDX[2]+seed->fSDEDX[3])*0.25;
+      esd->SetTPCPointsF(seed->GetNFoundable());
+      Int_t   ndedx = seed->GetNCDEDX(0);
+      Float_t sdedx = seed->GetSDEDX(0);
       Float_t dedx  = seed->GetdEdx();
       esd->SetTPCsignal(dedx, sdedx, ndedx);
       ntracks++;
-      Int_t eventnumber = event->GetEventNumber();// patch 28 fev 06
-      (*fDebugStreamer)<<"Cback"<<
-       "Tr0.="<<seed<<
-       "EventNr="<<eventnumber<<
-       "\n"; // patch 28 fev 06   
+      Int_t eventnumber = event->GetEventNumberInFile();// patch 28 fev 06
+      // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number      
+      if (AliTPCReconstructor::StreamLevel()>1 && esd) {
+       (*fDebugStreamer)<<"Cback"<<
+         "Tr0.="<<seed<<
+         "esd.="<<esd<<
+         "EventNrInFile="<<eventnumber<<
+         "\n";       
+      }
     }
   }
+  if (AliTPCReconstructor::StreamLevel()>3)  DumpClusters(1,fSeeds);
   //FindKinks(fSeeds,event);
   Info("PropagateBack","Number of back propagated tracks %d",ntracks);
   fEvent =0;
-  //WriteTracks();
+  
   return 0;
 }
 
 
-void AliTPCtrackerMI::DeleteSeeds()
+Int_t AliTPCtrackerMI::PostProcess(AliESDEvent *event)
 {
   //
-  //delete Seeds
-  Int_t nseed = fSeeds->GetEntriesFast();
-  for (Int_t i=0;i<nseed;i++){
-    AliTPCseed * seed = (AliTPCseed*)fSeeds->At(i);
-    if (seed) delete fSeeds->RemoveAt(i);
+  // Post process events 
+  //
+  if (!event) return 0;
+
+  //
+  // Set TPC event status
+  // 
+
+  // event affected by HV dip
+  // reset TPC status
+  if(IsTPCHVDipEvent(event)) { 
+    event->ResetDetectorStatus(AliDAQ::kTPC);
   }
+  //printf("Status %d \n", event->IsDetectorOn(AliDAQ::kTPC));
+
+  return 0;
+}
+
+
+ void AliTPCtrackerMI::DeleteSeeds()
+{
+  //
+  fSeeds->Clear();
+  ResetSeedsPool();
   delete fSeeds;
   fSeeds =0;
 }
 
-void AliTPCtrackerMI::ReadSeeds(AliESD *event, Int_t direction)
+void AliTPCtrackerMI::ReadSeeds(const AliESDEvent *const event, Int_t direction)
 {
   //
   //read seeds from the event
@@ -2675,7 +2940,10 @@ void AliTPCtrackerMI::ReadSeeds(AliESD *event, Int_t direction)
     AliTPCtrack t(*esd);
     t.SetNumberOfClusters(0);
     //    AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
-    AliTPCseed *seed = new AliTPCseed(t/*,t.GetAlpha()*/);
+    AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(t/*,t.GetAlpha()*/);
+    seed->SetPoolID(fLastSeedID);
+    seed->SetUniqueID(esd->GetID());
+    AddCovariance(seed);   //add systematic ucertainty
     for (Int_t ikink=0;ikink<3;ikink++) {
       Int_t index = esd->GetKinkIndex(ikink);
       seed->GetKinkIndexes()[ikink] = index;
@@ -2692,13 +2960,13 @@ void AliTPCtrackerMI::ReadSeeds(AliESD *event, Int_t direction)
       }
 
     }
-    if (((status&AliESDtrack::kITSout)==0)&&(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 (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.); 
+    if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
+    //if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
+    //  fSeeds->AddAt(0,i);
+    //  MarkSeedFree( seed );
+    //  continue;    
+    //}
     if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) > 0 )  {
       Double_t par0[5],par1[5],alpha,x;
       esd->GetInnerExternalParameters(alpha,x,par0);
@@ -2709,7 +2977,7 @@ void AliTPCtrackerMI::ReadSeeds(AliESD *event, Int_t direction)
       if (esd->GetTRDncls()>0) trdchi2 = esd->GetTRDchi2()/esd->GetTRDncls();
       //reset covariance if suspicious 
       if ( (delta1>0.1) || (delta2>0.006) ||trdchi2>7.)
-       seed->ResetCovariance();
+       seed->ResetCovariance(10.);
     }
 
     //
@@ -2717,27 +2985,30 @@ void AliTPCtrackerMI::ReadSeeds(AliESD *event, Int_t direction)
     // rotate to the local coordinate system
     //   
     fSectors=fInnerSec; fN=fkNIS;    
-    Double_t alpha=seed->GetAlpha() - fSectors->GetAlphaShift();
+    Double_t alpha=seed->GetAlpha();
     if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
     if (alpha < 0.            ) alpha += 2.*TMath::Pi();
-    Int_t ns=Int_t(alpha/fSectors->GetAlpha())%fN;
+    Int_t ns=Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
     alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
+    alpha-=seed->GetAlpha();  
     if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
     if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
-    alpha-=seed->GetAlpha();  
-    if (!seed->Rotate(alpha)) {
-      delete seed;
-      continue;
+    if (TMath::Abs(alpha) > 0.001) { // This should not happen normally
+      AliWarning(Form("Rotating track over %f",alpha));
+      if (!seed->Rotate(alpha)) {
+       MarkSeedFree( seed );
+       continue;
+      }
     }
-    seed->fEsd = esd;
+    seed->SetESD(esd);
     // sign clusters
     if (esd->GetKinkIndex(0)<=0){
       for (Int_t irow=0;irow<160;irow++){
        Int_t index = seed->GetClusterIndex2(irow);    
-       if (index>0){ 
+       if (index >= 0){ 
          //
          AliTPCclusterMI * cl = GetClusterMI(index);
-         seed->fClusterPointer[irow] = cl;
+         seed->SetClusterPointer(irow,cl);
          if (cl){
            if ((index & 0x8000)==0){
              cl->Use(10);  // accepted cluster   
@@ -2777,7 +3048,8 @@ void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
   Double_t x[5], c[15];
   //  Int_t di = i1-i2;
   //
-  AliTPCseed * seed = new AliTPCseed;
+  AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed();
+  seed->SetPoolID(fLastSeedID);
   Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
   Double_t cs=cos(alpha), sn=sin(alpha);
   //
@@ -2791,13 +3063,13 @@ void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
 
   Int_t imiddle = (i2+i1)/2;    //middle pad row index
   Double_t xm = GetXrow(imiddle); // radius of middle pad-row
-  const AliTPCRow& krm=GetRow(sec,imiddle); //middle pad -row
+  const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
   //
   Int_t ns =sec;   
 
-  const AliTPCRow& kr1=GetRow(ns,i1);
-  Double_t ymax  = GetMaxY(i1)-kr1.fDeadZone-1.5;  
-  Double_t ymaxm = GetMaxY(imiddle)-kr1.fDeadZone-1.5;  
+  const AliTPCtrackerRow& kr1=GetRow(ns,i1);
+  Double_t ymax  = GetMaxY(i1)-kr1.GetDeadZone()-1.5;  
+  Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;  
 
   //
   // change cut on curvature if it can't reach this layer
@@ -2847,10 +3119,10 @@ void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
     for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
       Int_t sec2 = sec + dsec;
       // 
-      //      AliTPCRow&  kr2  = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
-      //AliTPCRow&  kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
-      AliTPCRow&  kr2  = GetRow((sec2+fkNOS)%fkNOS,i2);
-      AliTPCRow&  kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
+      //      AliTPCtrackerRow&  kr2  = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
+      //AliTPCtrackerRow&  kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
+      AliTPCtrackerRow&  kr2  = GetRow((sec2+fkNOS)%fkNOS,i2);
+      AliTPCtrackerRow&  kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
       Int_t  index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
       Int_t  index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
 
@@ -2946,12 +3218,12 @@ void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
        }
        
 
-       Double_t dym = 0;
-       Double_t dzm = 0;
-       if (cm){
-         dym = ym - cm->GetY();
-         dzm = zm - cm->GetZ();
-       }
+       // Double_t dym = 0;
+       // Double_t dzm = 0;
+       // if (cm){
+       //   dym = ym - cm->GetY();
+       //   dzm = zm - cm->GetZ();
+       // }
        nin2++;
 
 
@@ -2987,12 +3259,13 @@ void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
        //      if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
        
         UInt_t index=kr1.GetIndex(is);
-       AliTPCseed *track=new(seed) AliTPCseed(index, x, c, x1, ns*alpha+shift);
-       
-       track->fIsSeeding = kTRUE;
-       track->fSeed1 = i1;
-       track->fSeed2 = i2;
-       track->fSeedType=3;
+       if (seed) {MarkSeedFree(seed); seed = 0;}
+       AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, ns*alpha+shift, x, c, index);
+       seed->SetPoolID(fLastSeedID);
+       track->SetIsSeeding(kTRUE);
+       track->SetSeed1(i1);
+       track->SetSeed2(i2);
+       track->SetSeedType(3);
 
        
        //if (dsec==0) {
@@ -3000,8 +3273,7 @@ void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
          Int_t foundable,found,shared;
          track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
          if ((found<0.55*foundable)  || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
-           seed->Reset();
-           seed->~AliTPCseed();
+           MarkSeedFree(seed); seed = 0;
            continue;
          }
          //}
@@ -3011,57 +3283,52 @@ void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
        
        
        //Int_t rc = 1;
-       track->fBConstrain =1;
+       track->SetBConstrain(1);
        //      track->fLastPoint = i1+fInnerSec->GetNRows();  // first cluster in track position
-       track->fLastPoint = i1;  // first cluster in track position
-       track->fFirstPoint = track->fLastPoint;
+       track->SetLastPoint(i1);  // first cluster in track position
+       track->SetFirstPoint(track->GetLastPoint());
        
        if (track->GetNumberOfClusters()<(i1-i2)*0.5 || 
-           track->GetNumberOfClusters() < track->fNFoundable*0.6 || 
-           track->fNShared>0.4*track->GetNumberOfClusters() ) {
-         seed->Reset();
-         seed->~AliTPCseed();
+           track->GetNumberOfClusters() < track->GetNFoundable()*0.6 || 
+           track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
+         MarkSeedFree(seed); seed = 0;
          continue;
        }
        nout1++;
         // Z VERTEX CONDITION
-       Double_t zv;
-        zv = track->GetZ()+track->GetTgl()/track->GetC()*
-         ( asin(-track->GetEta()) - asin(track->GetX()*track->GetC()-track->GetEta()));
+       Double_t zv, bz=GetBz();
+        if ( !track->GetZAt(0.,bz,zv) ) continue;
        if (TMath::Abs(zv-z3)>cuts[2]) {
          FollowProlongation(*track, TMath::Max(i2-20,0));
-         zv = track->GetZ()+track->GetTgl()/track->GetC()*
-           ( asin(-track->GetEta()) - asin(track->GetX()*track->GetC()-track->GetEta()));
+          if ( !track->GetZAt(0.,bz,zv) ) continue;
          if (TMath::Abs(zv-z3)>cuts[2]){
            FollowProlongation(*track, TMath::Max(i2-40,0));
-           zv = track->GetZ()+track->GetTgl()/track->GetC()*
-             ( asin(-track->GetEta()) - asin(track->GetX()*track->GetC()-track->GetEta()));
-           if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->fNFoundable*0.7)){
+            if ( !track->GetZAt(0.,bz,zv) ) continue;
+           if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
              // make seed without constrain
              AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
              FollowProlongation(*track2, i2,1);
-             track2->fBConstrain = kFALSE;
-             track2->fSeedType = 1;
+             track2->SetBConstrain(kFALSE);
+             track2->SetSeedType(1);
              arr->AddLast(track2); 
-             seed->Reset();
-             seed->~AliTPCseed();
+             MarkSeedFree( seed ); seed = 0;
              continue;         
            }
            else{
-             seed->Reset();
-             seed->~AliTPCseed();
+             MarkSeedFree( seed ); seed = 0;
              continue;
            
            }
          }
        }
-       
-       track->fSeedType =0;
-       arr->AddLast(track); 
-       seed = new AliTPCseed;  
+      
+       track->SetSeedType(0);
+       arr->AddLast(track); // note, track is seed, don't free the seed
+       seed = new( NextFreeSeed() ) AliTPCseed;        
+       seed->SetPoolID(fLastSeedID);
        nout2++;
        // don't consider other combinations
-       if (track->GetNumberOfClusters() > track->fNFoundable*0.8)
+       if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
          break;
       }
     }
@@ -3069,7 +3336,7 @@ void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
   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;
+  if (seed) MarkSeedFree( seed );
 }
 
 
@@ -3097,7 +3364,8 @@ void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
   Double_t x[5], c[15];
   //
   // make temporary seed
-  AliTPCseed * seed = new AliTPCseed;
+  AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
+  seed->SetPoolID(fLastSeedID);
   Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
   //  Double_t cs=cos(alpha), sn=sin(alpha);
   //
@@ -3105,25 +3373,25 @@ void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
 
   // first 3 padrows
   Double_t x1 = GetXrow(i1-1);
-  const    AliTPCRow& kr1=GetRow(sec,i1-1);
-  Double_t y1max  = GetMaxY(i1-1)-kr1.fDeadZone-1.5;  
+  const    AliTPCtrackerRow& kr1=GetRow(sec,i1-1);
+  Double_t y1max  = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;  
   //
   Double_t x1p = GetXrow(i1);
-  const    AliTPCRow& kr1p=GetRow(sec,i1);
+  const    AliTPCtrackerRow& kr1p=GetRow(sec,i1);
   //
   Double_t x1m = GetXrow(i1-2);
-  const    AliTPCRow& kr1m=GetRow(sec,i1-2);
+  const    AliTPCtrackerRow& kr1m=GetRow(sec,i1-2);
 
   //
   //last 3 padrow for seeding
-  AliTPCRow&  kr3  = GetRow((sec+fkNOS)%fkNOS,i1-7);
+  AliTPCtrackerRow&  kr3  = GetRow((sec+fkNOS)%fkNOS,i1-7);
   Double_t    x3   =  GetXrow(i1-7);
   //  Double_t    y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;  
   //
-  AliTPCRow&  kr3p  = GetRow((sec+fkNOS)%fkNOS,i1-6);
+  AliTPCtrackerRow&  kr3p  = GetRow((sec+fkNOS)%fkNOS,i1-6);
   Double_t    x3p   = GetXrow(i1-6);
   //
-  AliTPCRow&  kr3m  = GetRow((sec+fkNOS)%fkNOS,i1-8);
+  AliTPCtrackerRow&  kr3m  = GetRow((sec+fkNOS)%fkNOS,i1-8);
   Double_t    x3m   = GetXrow(i1-8);
 
   //
@@ -3131,7 +3399,7 @@ void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
   // middle padrow
   Int_t im = i1-4;                           //middle pad row index
   Double_t xm         = GetXrow(im);         // radius of middle pad-row
-  const AliTPCRow& krm=GetRow(sec,im);   //middle pad -row
+  const AliTPCtrackerRow& krm=GetRow(sec,im);   //middle pad -row
   //  Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;  
   //
   //
@@ -3160,7 +3428,7 @@ void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
       y3 = kcl->GetY(); 
       // apply angular cuts
       if (TMath::Abs(y1-y3)>dymax) continue;
-      x3 = x3; 
+      //x3 = x3; 
       z3 = kcl->GetZ();        
       if (TMath::Abs(z1-z3)>dzmax) continue;
       //
@@ -3277,32 +3545,32 @@ void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
       
       //       if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
       
-      UInt_t index=kr1.GetIndex(is);
-      AliTPCseed *track=new(seed) AliTPCseed(index, x, c, x1, sec*alpha+shift);
+      index=kr1.GetIndex(is);
+      if (seed) {MarkSeedFree( seed ); seed = 0;}
+      AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, sec*alpha+shift, x, c, index);
+      seed->SetPoolID(fLastSeedID);
       
-      track->fIsSeeding = kTRUE;
+      track->SetIsSeeding(kTRUE);
 
       nin++;      
       FollowProlongation(*track, i1-7,1);
-      if (track->GetNumberOfClusters() < track->fNFoundable*0.75 || 
-         track->fNShared>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
-       seed->Reset();
-       seed->~AliTPCseed();
+      if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 || 
+         track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
+       MarkSeedFree( seed ); seed = 0;
        continue;
       }
       nout1++;
       nout2++; 
       //Int_t rc = 1;
       FollowProlongation(*track, i2,1);
-      track->fBConstrain =0;
-      track->fLastPoint = i1+fInnerSec->GetNRows();  // first cluster in track position
-      track->fFirstPoint = track->fLastPoint;
+      track->SetBConstrain(0);
+      track->SetLastPoint(i1+fInnerSec->GetNRows());  // first cluster in track position
+      track->SetFirstPoint(track->GetLastPoint());
       
       if (track->GetNumberOfClusters()<(i1-i2)*0.5 || 
-         track->GetNumberOfClusters()<track->fNFoundable*0.7 || 
-         track->fNShared>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
-       seed->Reset();
-       seed->~AliTPCseed();
+         track->GetNumberOfClusters()<track->GetNFoundable()*0.7 || 
+         track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
+       MarkSeedFree( seed ); seed = 0;
        continue;
       }
    
@@ -3310,11 +3578,10 @@ void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
        FollowProlongation(*track, TMath::Max(i2-10,0),1);
        AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
        FollowProlongation(*track2, i2,1);
-       track2->fBConstrain = kFALSE;
-       track2->fSeedType = 4;
-       arr->AddLast(track2); 
-       seed->Reset();
-       seed->~AliTPCseed();
+       track2->SetBConstrain(kFALSE);
+       track2->SetSeedType(4);
+       arr->AddLast(track2);
+       MarkSeedFree( seed ); seed = 0;
       }
       
    
@@ -3325,9 +3592,9 @@ void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
   }
   
   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);
+    Info("MakeSeeds5","\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2,nout3);
   }
-  delete seed;
+  if (seed) MarkSeedFree(seed);
 }
 
 
@@ -3354,12 +3621,13 @@ void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
   //  Double_t cs=cos(alpha), sn=sin(alpha);
   Int_t row0 = (i1+i2)/2;
   Int_t drow = (i1-i2)/2;
-  const AliTPCRow& kr0=fSectors[sec][row0];
-  AliTPCRow * kr=0;
+  const AliTPCtrackerRow& kr0=fSectors[sec][row0];
+  AliTPCtrackerRow * kr=0;
 
   AliTPCpolyTrack polytrack;
   Int_t nclusters=fSectors[sec][row0];
-  AliTPCseed * seed = new AliTPCseed;
+  AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
+  seed->SetPoolID(fLastSeedID);
 
   Int_t sumused=0;
   Int_t cused=0;
@@ -3368,8 +3636,8 @@ void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
     Int_t nfound =0;
     Int_t nfoundable =0;
     for (Int_t iter =1; iter<2; iter++){   //iterations
-      const AliTPCRow& krm=fSectors[sec][row0-iter];
-      const AliTPCRow& krp=fSectors[sec][row0+iter];      
+      const AliTPCtrackerRow& krm=fSectors[sec][row0-iter];
+      const AliTPCtrackerRow& krp=fSectors[sec][row0+iter];      
       const AliTPCclusterMI * cl= kr0[is];
       
       if (cl->IsUsed(10)) {
@@ -3389,7 +3657,7 @@ void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
       Float_t erry = 0;
       Float_t errz = 0;
       
-      Double_t ymax = fSectors->GetMaxY(row0)-kr0.fDeadZone-1.5;
+      Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
       if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue;  // seed only at the edge
       
       erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;     
@@ -3438,9 +3706,9 @@ void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
          Int_t row = row0+ddrow*delta;
          kr = &(fSectors[sec][row]);
          Double_t xn = kr->GetX();
-         Double_t ymax = fSectors->GetMaxY(row)-kr->fDeadZone-1.5;
+         Double_t ymax1 = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
          polytrack.GetFitPoint(xn,yn,zn);
-         if (TMath::Abs(yn)>ymax) continue;
+         if (TMath::Abs(yn)>ymax1) continue;
          nfoundable++;
          AliTPCclusterMI * cln = kr->FindNearest(yn,zn,roady,roadz);
          if (cln) {
@@ -3557,25 +3825,26 @@ void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
 
        UInt_t index=0;
        //kr0.GetIndex(is);
-       AliTPCseed *track=new (seed) AliTPCseed(index, x, c, x1, sec*alpha+shift);
-       track->fIsSeeding = kTRUE;
+       if (seed) {MarkSeedFree( seed ); seed = 0;}
+       AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1,sec*alpha+shift,x,c,index);
+       seed->SetPoolID(fLastSeedID);
+       track->SetIsSeeding(kTRUE);
        Int_t rc=FollowProlongation(*track, i2);        
-       if (constrain) track->fBConstrain =1;
+       if (constrain) track->SetBConstrain(1);
        else
-         track->fBConstrain =0;
-       track->fLastPoint = row1+fInnerSec->GetNRows();  // first cluster in track position
-       track->fFirstPoint = track->fLastPoint;
+         track->SetBConstrain(0);
+       track->SetLastPoint(row1+fInnerSec->GetNRows());  // first cluster in track position
+       track->SetFirstPoint(track->GetLastPoint());
 
        if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 || 
-           track->GetNumberOfClusters() < track->fNFoundable*0.6 || 
-           track->fNShared>0.4*track->GetNumberOfClusters()) {
-         //delete track;
-         seed->Reset();
-         seed->~AliTPCseed();
+           track->GetNumberOfClusters() < track->GetNFoundable()*0.6 || 
+           track->GetNShared()>0.4*track->GetNumberOfClusters()) {
+         MarkSeedFree( seed ); seed = 0;
        }
        else {
-         arr->AddLast(track);
-         seed = new AliTPCseed;
+         arr->AddLast(track); // track IS seed, don't free seed
+         seed = new( NextFreeSeed() ) AliTPCseed;
+         seed->SetPoolID(fLastSeedID);
        }
        nin3++;
       }
@@ -3584,11 +3853,11 @@ void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,
   if (fDebug>3){
     Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
   }
-  delete seed;
+  if (seed) MarkSeedFree( seed );
 }
 
 
-AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
+AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *const track, Float_t r0, Float_t r1, Float_t r2)
 {
   //
   //
@@ -3609,13 +3878,13 @@ AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *track, Float_t r0, Float_t r1,
   Int_t index=-1;
   Int_t clindex;
   for (Int_t i=0;i<160;i++){
-    if (track->fClusterPointer[i]){
+    if (track->GetClusterPointer(i)){
       index++;
       AliTPCTrackerPoint   *trpoint =track->GetTrackPoint(i);
       if ( (index<p0) || x0[0]<0 ){
        if (trpoint->GetX()>1){
          clindex = track->GetClusterIndex2(i);
-         if (clindex>0){       
+         if (clindex >= 0){    
            x0[0] = trpoint->GetX();
            x0[1] = trpoint->GetY();
            x0[2] = trpoint->GetZ();
@@ -3626,7 +3895,7 @@ AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *track, Float_t r0, Float_t r1,
 
       if ( (index<p1) &&(trpoint->GetX()>1)){
        clindex = track->GetClusterIndex2(i);
-       if (clindex>0){
+       if (clindex >= 0){
          x1[0] = trpoint->GetX();
          x1[1] = trpoint->GetY();
          x1[2] = trpoint->GetZ();
@@ -3635,7 +3904,7 @@ AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *track, Float_t r0, Float_t r1,
       }
       if ( (index<p2) &&(trpoint->GetX()>1)){
        clindex = track->GetClusterIndex2(i);
-       if (clindex>0){
+       if (clindex >= 0){
          x2[0] = trpoint->GetX();
          x2[1] = trpoint->GetY();
          x2[2] = trpoint->GetZ(); 
@@ -3706,21 +3975,22 @@ AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *track, Float_t r0, Float_t r1,
   c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
   
   //  Int_t row1 = fSectors->GetRowNumber(x2[0]);
-  AliTPCseed *seed=new  AliTPCseed(0, x, c, x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift());
+  AliTPCseed *seed = new( NextFreeSeed() )  AliTPCseed(x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
+  seed->SetPoolID(fLastSeedID);
   //  Double_t y0,z0,y1,z1, y2,z2;
   //seed->GetProlongation(x0[0],y0,z0);
   // seed->GetProlongation(x1[0],y1,z1);
   //seed->GetProlongation(x2[0],y2,z2);
   //  seed =0;
-  seed->fLastPoint  = pp2;
-  seed->fFirstPoint = pp2;
+  seed->SetLastPoint(pp2);
+  seed->SetFirstPoint(pp2);
   
 
   return seed;
 }
 
 
-AliTPCseed *AliTPCtrackerMI::ReSeed(AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
+AliTPCseed *AliTPCtrackerMI::ReSeed(const AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
 {
   //
   //
@@ -3738,8 +4008,8 @@ AliTPCseed *AliTPCtrackerMI::ReSeed(AliTPCseed *track, Float_t r0, Float_t r1, F
   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};
+  Double_t  xyz[3][3]={{0}};
+  Int_t     row[3]={0},sec[3]={0,0,0};
   //
   // find track row position at given ratio of the length
   Int_t index=-1;
@@ -3826,9 +4096,10 @@ AliTPCseed *AliTPCtrackerMI::ReSeed(AliTPCseed *track, Float_t r0, Float_t r1, F
   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];  
+  AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
+  seed->SetPoolID(fLastSeedID);
+  seed->SetLastPoint(row[2]);
+  seed->SetFirstPoint(row[2]);  
   return seed;
 }
 
@@ -3975,31 +4246,574 @@ AliTPCseed *AliTPCtrackerMI::ReSeed(AliTPCseed *track,Int_t r0, Bool_t forward)
   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];  
+  AliTPCseed *seed=new( NextFreeSeed() )  AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
+  seed->SetPoolID(fLastSeedID);
+  seed->SetLastPoint(row[2]);
+  seed->SetFirstPoint(row[2]);  
   for (Int_t i=row[0];i<row[2];i++){
-    seed->fIndex[i] = track->fIndex[i];
+    seed->SetClusterIndex(i, track->GetClusterIndex(i));
   }
 
   return seed;
 }
 
-void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
+
+
+void  AliTPCtrackerMI::FindMultiMC(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
 {
   //
-  //  find kinks
+  //  find multi tracks - THIS FUNCTION IS ONLY FOR DEBUG PURPOSES
+  //                      USES MC LABELS
+  //  Use AliTPCReconstructor::StreamLevel()>2 if you want to tune parameters - cuts
+  //
+  //  Two reasons to have multiple find tracks
+  //  1. Curling tracks can be find more than once
+  //  2. Splitted tracks 
+  //     a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)        
+  //     b.) Edge effect on the sector boundaries
   //
   //
+  //  Algorithm done in 2 phases - because of CPU consumption
+  //  it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated                           
+  //
+  //  Algorihm for curling tracks sign:
+  //    1 phase -makes a very rough fast cuts to minimize combinatorics
+  //                 a.) opposite sign
+  //                 b.) one of the tracks - not pointing to the primary vertex - 
+  //                 c.) delta tan(theta)
+  //                 d.) delta phi
+  //    2 phase - calculates DCA between tracks  - time consument
 
-  TObjArray *kinks= new TObjArray(10000);
-  //  TObjArray *v0s= new TObjArray(10000);
-  Int_t nentries = array->GetEntriesFast();
+  //
+  //    fast cuts 
+  //
+  //    General cuts    - for splitted tracks and for curling tracks
+  //
+  const Float_t kMaxdPhi      = 0.2;  // maximal distance in phi
+  //
+  //    Curling tracks cuts
+  //
+  //
+  //
+  //
+  Int_t nentries = array->GetEntriesFast();  
+  AliHelix *helixes      = new AliHelix[nentries];
+  Float_t  *xm           = new Float_t[nentries];
+  Float_t  *dz0           = new Float_t[nentries];
+  Float_t  *dz1           = new Float_t[nentries];
+  //
+  //
+  TStopwatch timer;
+  timer.Start();
+  //
+  // Find track COG in x direction - point with best defined parameters
+  //
+  for (Int_t i=0;i<nentries;i++){
+    AliTPCseed* track = (AliTPCseed*)array->At(i);    
+    if (!track) continue;
+    track->SetCircular(0);
+    new (&helixes[i]) AliHelix(*track);
+    Int_t ncl=0;
+    xm[i]=0;
+    Float_t dz[2];
+    track->GetDZ(GetX(),GetY(),GetZ(),GetBz(),dz);
+    dz0[i]=dz[0];
+    dz1[i]=dz[1];
+    for (Int_t icl=0; icl<160; icl++){
+      AliTPCclusterMI * cl =  track->GetClusterPointer(icl);
+      if (cl) {
+       xm[i]+=cl->GetX();
+       ncl++;
+      }
+    }
+    if (ncl>0) xm[i]/=Float_t(ncl);
+  }  
+  //
+  for (Int_t i0=0;i0<nentries;i0++){
+    AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
+    if (!track0) continue;    
+    Float_t xc0 = helixes[i0].GetHelix(6);
+    Float_t yc0 = helixes[i0].GetHelix(7);
+    Float_t r0  = helixes[i0].GetHelix(8);
+    Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
+    Float_t fi0 = TMath::ATan2(yc0,xc0);
+    
+    for (Int_t i1=i0+1;i1<nentries;i1++){
+      AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
+      if (!track1) continue;      
+      Int_t lab0=track0->GetLabel();
+      Int_t lab1=track1->GetLabel();
+      if (TMath::Abs(lab0)!=TMath::Abs(lab1)) continue;
+      //
+      Float_t xc1 = helixes[i1].GetHelix(6);
+      Float_t yc1 = helixes[i1].GetHelix(7);
+      Float_t r1  = helixes[i1].GetHelix(8);
+      Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
+      Float_t fi1 = TMath::ATan2(yc1,xc1);
+      //
+      Float_t dfi = fi0-fi1;
+      //
+      //
+      if (dfi>1.5*TMath::Pi())  dfi-=TMath::Pi();  // take care about edge effect 
+      if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi();  // 
+      if (TMath::Abs(dfi)>kMaxdPhi&&helixes[i0].GetHelix(4)*helixes[i1].GetHelix(4)<0){
+       //
+       // if short tracks with undefined sign 
+       fi1 =  -TMath::ATan2(yc1,-xc1);
+       dfi = fi0-fi1;
+      }
+      Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
+      
+      //
+      // debug stream to tune "fast cuts" 
+      //
+      Double_t dist[3];   // distance at X 
+      Double_t mdist[3]={0,0,0};  // mean distance X+-40cm
+      track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])-40.,dist,AliTracker::GetBz());
+      for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
+      track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])+40.,dist,AliTracker::GetBz());
+      for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
+      track0->GetDistance(track1,0.5*(xm[i0]+xm[i1]),dist,AliTracker::GetBz());
+      for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
+      for (Int_t i=0;i<3;i++) mdist[i]*=0.33333;
+      
+      Float_t sum =0;
+      Float_t sums=0;
+      for (Int_t icl=0; icl<160; icl++){
+       AliTPCclusterMI * cl0 =  track0->GetClusterPointer(icl);
+       AliTPCclusterMI * cl1 =  track1->GetClusterPointer(icl);
+       if (cl0&&cl1) {
+         sum++;
+         if (cl0==cl1) sums++;
+       }
+      }
+      //
+      if (AliTPCReconstructor::StreamLevel()>5) {
+      TTreeSRedirector &cstream = *fDebugStreamer;
+      cstream<<"Multi"<<
+       "iter="<<iter<<
+       "lab0="<<lab0<<
+       "lab1="<<lab1<<   
+       "Tr0.="<<track0<<       // seed0
+       "Tr1.="<<track1<<       // seed1
+       "h0.="<<&helixes[i0]<<
+       "h1.="<<&helixes[i1]<<
+       //
+       "sum="<<sum<<           //the sum of rows with cl in both
+       "sums="<<sums<<         //the sum of shared clusters
+       "xm0="<<xm[i0]<<        // the center of track
+       "xm1="<<xm[i1]<<        // the x center of track
+       // General cut variables                   
+       "dfi="<<dfi<<           // distance in fi angle
+       "dtheta="<<dtheta<<     // distance int theta angle
+       //
+       "dz00="<<dz0[i0]<<
+       "dz01="<<dz0[i1]<<
+       "dz10="<<dz1[i1]<<
+       "dz11="<<dz1[i1]<<
+       "dist0="<<dist[0]<<     //distance x
+       "dist1="<<dist[1]<<     //distance y
+       "dist2="<<dist[2]<<     //distance z
+       "mdist0="<<mdist[0]<<   //distance x
+       "mdist1="<<mdist[1]<<   //distance y
+       "mdist2="<<mdist[2]<<   //distance z
+       //
+       "r0="<<r0<<
+       "rc0="<<rc0<<
+       "fi0="<<fi0<<
+       "fi1="<<fi1<<
+       "r1="<<r1<<
+       "rc1="<<rc1<<
+       "\n";
+       }
+    }
+  }    
+  delete [] helixes;
+  delete [] xm;
+  delete [] dz0;
+  delete [] dz1;
+  if (AliTPCReconstructor::StreamLevel()>1) {
+    AliInfo("Time for curling tracks removal DEBUGGING MC");
+    timer.Print();
+  }
+}
+
+
+
+void  AliTPCtrackerMI::FindSplitted(TObjArray * array, AliESDEvent */*esd*/, Int_t /*iter*/){
+  //
+  // Find Splitted tracks and remove the one with worst quality  
+  // Corresponding debug streamer to tune selections - "Splitted2"
+  // Algorithm:
+  // 0. Sort tracks according quility
+  // 1. Propagate the tracks to the reference radius
+  // 2. Double_t loop to select close tracks (only to speed up process)
+  // 3. Calculate cluster overlap ratio - and remove the track if bigger than a threshold
+  // 4. Delete temporary parameters
+  // 
+  const Double_t xref=GetXrow(63);  // reference radius -IROC/OROC boundary
+  //    rough cuts
+  const Double_t kCutP1=10;       // delta Z cut 10 cm 
+  const Double_t kCutP2=0.15;     // delta snp(fi) cut 0.15 
+  const Double_t kCutP3=0.15;     // delta tgl(theta) cut 0.15
+  const Double_t kCutAlpha=0.15;  // delta alpha cut
+  Int_t firstpoint = 0;
+  Int_t lastpoint = 160;
+  //
+  Int_t nentries = array->GetEntriesFast();  
+  AliExternalTrackParam *params      = new AliExternalTrackParam[nentries];
+  //
+  //
+  TStopwatch timer;
+  timer.Start();
+  //
+  //0.  Sort tracks according quality
+  //1.  Propagate the ext. param to reference radius
+  Int_t nseed = array->GetEntriesFast();  
+  if (nseed<=0) return;
+  Float_t * quality = new Float_t[nseed];
+  Int_t   * indexes = new Int_t[nseed];
+  for (Int_t i=0; i<nseed; i++) {
+    AliTPCseed *pt=(AliTPCseed*)array->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();
+    //prefer high momenta tracks if overlaps
+    quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
+    params[i]=(*pt);
+    AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),5.,kTRUE);
+    AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),1.,kTRUE);
+  }
+  TMath::Sort(nseed,quality,indexes);
+  //
+  // 3. Loop over pair of tracks
+  //
+  for (Int_t i0=0; i0<nseed; i0++) {
+    Int_t index0=indexes[i0];
+    if (!(array->UncheckedAt(index0))) continue;
+    AliTPCseed *s1 = (AliTPCseed*)array->UncheckedAt(index0);  
+    if (!s1->IsActive()) continue;
+    AliExternalTrackParam &par0=params[index0];
+    for (Int_t i1=i0+1; i1<nseed; i1++) {
+      Int_t index1=indexes[i1];
+      if (!(array->UncheckedAt(index1))) continue;
+      AliTPCseed *s2 = (AliTPCseed*)array->UncheckedAt(index1);  
+      if (!s2->IsActive()) continue;
+      if (s2->GetKinkIndexes()[0]!=0)
+       if (s2->GetKinkIndexes()[0] == -s1->GetKinkIndexes()[0]) continue;
+      AliExternalTrackParam &par1=params[index1];
+      if (TMath::Abs(par0.GetParameter()[3]-par1.GetParameter()[3])>kCutP3) continue;
+      if (TMath::Abs(par0.GetParameter()[1]-par1.GetParameter()[1])>kCutP1) continue;
+      if (TMath::Abs(par0.GetParameter()[2]-par1.GetParameter()[2])>kCutP2) continue;
+      Double_t dAlpha= TMath::Abs(par0.GetAlpha()-par1.GetAlpha());
+      if (dAlpha>TMath::Pi()) dAlpha-=TMath::Pi();
+      if (TMath::Abs(dAlpha)>kCutAlpha) continue;
+      //
+      Int_t sumShared=0;
+      Int_t nall0=0;
+      Int_t nall1=0;
+      Int_t firstShared=lastpoint, lastShared=firstpoint;
+      Int_t firstRow=lastpoint, lastRow=firstpoint;
+      //
+      for (Int_t i=firstpoint;i<lastpoint;i++){
+       if (s1->GetClusterIndex2(i)>0) nall0++;
+       if (s2->GetClusterIndex2(i)>0) nall1++;
+       if  (s1->GetClusterIndex2(i)>0 && s2->GetClusterIndex2(i)>0) {
+         if (i<firstRow) firstRow=i;
+         if (i>lastRow)  lastRow=i;
+       }
+       if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
+         if (i<firstShared) firstShared=i;
+         if (i>lastShared)  lastShared=i;
+         sumShared++;
+       }
+      }
+      Double_t ratio0 = Float_t(sumShared)/Float_t(TMath::Min(nall0+1,nall1+1));
+      Double_t ratio1 = Float_t(sumShared)/Float_t(TMath::Max(nall0+1,nall1+1));
+      
+      if( AliTPCReconstructor::StreamLevel()>1){
+       TTreeSRedirector &cstream = *fDebugStreamer;
+       Int_t n0=s1->GetNumberOfClusters();
+       Int_t n1=s2->GetNumberOfClusters();
+       Int_t n0F=s1->GetNFoundable();
+       Int_t n1F=s2->GetNFoundable();
+       Int_t lab0=s1->GetLabel();
+       Int_t lab1=s2->GetLabel();
+
+       cstream<<"Splitted2"<<
+         "iter="<<fIteration<<
+         "lab0="<<lab0<<        // MC label if exist
+         "lab1="<<lab1<<        // MC label if exist
+         "index0="<<index0<<
+         "index1="<<index1<<
+         "ratio0="<<ratio0<<      // shared ratio
+         "ratio1="<<ratio1<<      // shared ratio
+         "p0.="<<&par0<<        // track parameters
+         "p1.="<<&par1<<
+         "s0.="<<s1<<           // full seed
+         "s1.="<<s2<<
+         "n0="<<n0<<     // number of clusters track 0
+         "n1="<<n1<<     // number of clusters track 1
+         "nall0="<<nall0<<     // number of clusters track 0
+         "nall1="<<nall1<<     // number of clusters track 1
+         "n0F="<<n0F<<   // number of findable
+         "n1F="<<n1F<<   // number of findable
+         "shared="<<sumShared<<    // number of shared clusters
+         "firstS="<<firstShared<<  // first and the last shared row
+         "lastS="<<lastShared<<
+         "firstRow="<<firstRow<<   // first and the last row with cluster
+         "lastRow="<<lastRow<<     //
+         "\n";
+      }
+      //
+      // remove track with lower quality
+      //
+      if (ratio0>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(0) ||
+         ratio1>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(1)){
+       //
+       //
+       //
+       MarkSeedFree( array->RemoveAt(index1) );
+      }
+    }
+  }
+  //
+  // 4. Delete temporary array
+  //
+  delete [] params; 
+  delete [] quality;
+  delete [] indexes;
+
+}
+
+
+
+void  AliTPCtrackerMI::FindCurling(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
+{
+  //
+  //  find Curling tracks
+  //  Use AliTPCReconstructor::StreamLevel()>1 if you want to tune parameters - cuts
+  //
+  //
+  //  Algorithm done in 2 phases - because of CPU consumption
+  //  it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated                           
+  //  see detal in MC part what can be used to cut
+  //
+  //    
+  //
+  const Float_t kMaxC         = 400;  // maximal curvature to of the track
+  const Float_t kMaxdTheta    = 0.15;  // maximal distance in theta
+  const Float_t kMaxdPhi      = 0.15;  // maximal distance in phi
+  const Float_t kPtRatio      = 0.3; // ratio between pt
+  const Float_t kMinDCAR      = 2.;   // distance to the primary vertex in r - see cpipe cut      
+
+  //
+  //    Curling tracks cuts
+  //
+  //
+  const Float_t kMaxDeltaRMax = 40;   // distance in outer radius
+  const Float_t kMaxDeltaRMin = 5.;   // distance in lower radius - see cpipe cut
+  const Float_t kMinAngle     = 2.9;  // angle between tracks
+  const Float_t kMaxDist      = 5;    // biggest distance 
+  //
+  // The cuts can be tuned using the "MC information stored in Multi tree ==> see FindMultiMC
+  /* 
+     Fast cuts:
+     TCut csign("csign","Tr0.fP[4]*Tr1.fP[4]<0"); //opposite sign
+     TCut cmax("cmax","abs(Tr0.GetC())>1/400");
+     TCut cda("cda","sqrt(dtheta^2+dfi^2)<0.15");
+     TCut ccratio("ccratio","abs((Tr0.fP[4]+Tr1.fP[4])/(abs(Tr0.fP[4])+abs(Tr1.fP[4])))<0.3");
+     TCut cpipe("cpipe", "min(abs(r0-rc0),abs(r1-rc1))>5");    
+     //
+     TCut cdrmax("cdrmax","abs(abs(rc0+r0)-abs(rc1+r1))<40")
+     TCut cdrmin("cdrmin","abs(abs(rc0+r0)-abs(rc1+r1))<10")
+     //
+     Multi->Draw("dfi","iter==0"+csign+cmax+cda+ccratio); ~94% of curling tracks fulfill 
+     Multi->Draw("min(abs(r0-rc0),abs(r1-rc1))","iter==0&&abs(lab1)==abs(lab0)"+csign+cmax+cda+ccratio+cpipe+cdrmin+cdrmax); //80%
+     //
+     Curling2->Draw("dfi","iter==0&&abs(lab0)==abs(lab1)"+csign+cmax+cdtheta+cdfi+ccratio)
+
+  */
+  //  
+  //
+  //
+  Int_t nentries = array->GetEntriesFast();  
+  AliHelix *helixes      = new AliHelix[nentries];
+  for (Int_t i=0;i<nentries;i++){
+    AliTPCseed* track = (AliTPCseed*)array->At(i);    
+    if (!track) continue;
+    track->SetCircular(0);
+    new (&helixes[i]) AliHelix(*track);
+  }
+  //
+  //
+  TStopwatch timer;
+  timer.Start();
+  Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
+
+  //
+  // Find tracks
+  //
+  //
+  for (Int_t i0=0;i0<nentries;i0++){
+    AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
+    if (!track0) continue;    
+    if (TMath::Abs(track0->GetC())<1/kMaxC) continue;
+    Float_t xc0 = helixes[i0].GetHelix(6);
+    Float_t yc0 = helixes[i0].GetHelix(7);
+    Float_t r0  = helixes[i0].GetHelix(8);
+    Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
+    Float_t fi0 = TMath::ATan2(yc0,xc0);
+    
+    for (Int_t i1=i0+1;i1<nentries;i1++){
+      AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
+      if (!track1) continue;      
+      if (TMath::Abs(track1->GetC())<1/kMaxC) continue;    
+      Float_t xc1 = helixes[i1].GetHelix(6);
+      Float_t yc1 = helixes[i1].GetHelix(7);
+      Float_t r1  = helixes[i1].GetHelix(8);
+      Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
+      Float_t fi1 = TMath::ATan2(yc1,xc1);
+      //
+      Float_t dfi = fi0-fi1;
+      //
+      //
+      if (dfi>1.5*TMath::Pi())  dfi-=TMath::Pi();  // take care about edge effect 
+      if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi();  // 
+      Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
+      //
+      //
+      // FIRST fast cuts
+      if (track0->GetBConstrain()&&track1->GetBConstrain())  continue;  // not constrained
+      if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0)   continue; // not the same sign
+      if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>kMaxdTheta) continue; //distance in the Theta
+      if ( TMath::Abs(dfi)>kMaxdPhi) continue;  //distance in phi
+      if ( TMath::Sqrt(dfi*dfi+dtheta*dtheta)>kMaxdPhi) continue; //common angular offset
+      //
+      Float_t pt0 = track0->GetSignedPt();
+      Float_t pt1 = track1->GetSignedPt();
+      if ((TMath::Abs(pt0+pt1)/(TMath::Abs(pt0)+TMath::Abs(pt1)))>kPtRatio) continue;      
+      if ((iter==1) && TMath::Abs(TMath::Abs(rc0+r0)-TMath::Abs(rc1+r1))>kMaxDeltaRMax) continue;
+      if ((iter!=1) &&TMath::Abs(TMath::Abs(rc0-r0)-TMath::Abs(rc1-r1))>kMaxDeltaRMin) continue;
+      if (TMath::Min(TMath::Abs(rc0-r0),TMath::Abs(rc1-r1))<kMinDCAR) continue;
+      //
+      //
+      // Now find closest approach
+      //
+      //
+      //
+      Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
+      if (npoints==0) continue;
+      helixes[i0].GetClosestPhases(helixes[i1], phase);
+      //
+      Double_t xyz0[3];
+      Double_t xyz1[3];
+      Double_t hangles[3];
+      helixes[i0].Evaluate(phase[0][0],xyz0);
+      helixes[i1].Evaluate(phase[0][1],xyz1);
+
+      helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
+      Double_t deltah[2],deltabest;
+      if (TMath::Abs(hangles[2])<kMinAngle) continue;
+
+      if (npoints>0){
+       Int_t ibest=0;
+       helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
+       if (npoints==2){
+         helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
+         if (deltah[1]<deltah[0]) ibest=1;
+       }
+       deltabest  = TMath::Sqrt(deltah[ibest]);
+       helixes[i0].Evaluate(phase[ibest][0],xyz0);
+       helixes[i1].Evaluate(phase[ibest][1],xyz1);
+       helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
+       Double_t radiusbest = TMath::Sqrt(radius[ibest]);
+       //
+       if (deltabest>kMaxDist) continue;
+       //      if (mindcar+mindcaz<40 && (TMath::Abs(hangles[2])<kMinAngle ||deltabest>3)) continue;
+       Bool_t sign =kFALSE;
+       if (hangles[2]>kMinAngle) sign =kTRUE;
+       //
+       if (sign){
+         //      circular[i0] = kTRUE;
+         //      circular[i1] = kTRUE;
+         if (track0->OneOverPt()<track1->OneOverPt()){
+           track0->SetCircular(track0->GetCircular()+1);
+           track1->SetCircular(track1->GetCircular()+2);
+         }
+         else{
+           track1->SetCircular(track1->GetCircular()+1);
+           track0->SetCircular(track0->GetCircular()+2);
+         }
+       }               
+       if (AliTPCReconstructor::StreamLevel()>2){        
+         //
+         //debug stream to tune "fine" cuts      
+         Int_t lab0=track0->GetLabel();
+         Int_t lab1=track1->GetLabel();
+          TTreeSRedirector &cstream = *fDebugStreamer;
+         cstream<<"Curling2"<<
+           "iter="<<iter<<
+           "lab0="<<lab0<<
+           "lab1="<<lab1<<   
+           "Tr0.="<<track0<<
+           "Tr1.="<<track1<<
+           //
+           "r0="<<r0<<
+           "rc0="<<rc0<<
+           "fi0="<<fi0<<
+           "r1="<<r1<<
+           "rc1="<<rc1<<
+           "fi1="<<fi1<<
+           "dfi="<<dfi<<
+           "dtheta="<<dtheta<<
+           //
+           "npoints="<<npoints<<                      
+           "hangles0="<<hangles[0]<<
+           "hangles1="<<hangles[1]<<
+           "hangles2="<<hangles[2]<<                    
+           "xyz0="<<xyz0[2]<<
+           "xyzz1="<<xyz1[2]<<
+           "radius="<<radiusbest<<
+           "deltabest="<<deltabest<< 
+           "phase0="<<phase[ibest][0]<<
+           "phase1="<<phase[ibest][1]<<
+           "\n";                 
+
+       }
+      }
+    }
+  }
+  delete [] helixes;
+  if (AliTPCReconstructor::StreamLevel()>1) {
+    AliInfo("Time for curling tracks removal");
+    timer.Print();
+  }
+}
+
+
+void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESDEvent *esd)
+{
+  //
+  //  find kinks
+  //
+  //
+  // RS something is wrong in this routine: not all seeds are assigned to daughters and mothers array, but they all are queried
+  // to check later
+
+  TObjArray *kinks= new TObjArray(10000);
+  //  TObjArray *v0s= 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();
+  AliKink  *kink         = new AliKink();
   Int_t      * usage     = new Int_t[nentries];
   Float_t  *zm           = new Float_t[nentries];
   Float_t  *z0           = new Float_t[nentries]; 
@@ -4019,7 +4833,7 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
     usage[i]=0;
     AliTPCseed* track = (AliTPCseed*)array->At(i);    
     if (!track) continue;
-    track->fCircular =0;
+    track->SetCircular(0);
     shared[i] = kFALSE;
     track->UpdatePoints();
     if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
@@ -4052,29 +4866,28 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
   Int_t ncandidates =0;
   Int_t nall =0;
   Int_t ntracks=0; 
-  Double_t phase[2][2],radius[2];
+  Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
 
   //
   // Find circling track
-  TTreeSRedirector &cstream = *fDebugStreamer;
   //
   for (Int_t i0=0;i0<nentries;i0++){
     AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
     if (!track0) continue;    
-    if (track0->fN<40) continue;
-    if (TMath::Abs(1./track0->fP4)>200) continue;
+    if (track0->GetNumberOfClusters()<40) continue;
+    if (TMath::Abs(1./track0->GetC())>200) continue;
     for (Int_t i1=i0+1;i1<nentries;i1++){
       AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
       if (!track1) continue;
-      if (track1->fN<40)                  continue;
-      if ( TMath::Abs(track1->fP3+track0->fP3)>0.1) continue;
-      if (track0->fBConstrain&&track1->fBConstrain) continue;
-      if (TMath::Abs(1./track1->fP4)>200) continue;
-      if (track1->fP4*track0->fP4>0)      continue;
-      if (track1->fP3*track0->fP3>0)      continue;
-      if (max(TMath::Abs(1./track0->fP4),TMath::Abs(1./track1->fP4))>190) continue;
-      if (track0->fBConstrain&&TMath::Abs(track1->fP4)<TMath::Abs(track0->fP4)) continue; //returning - lower momenta
-      if (track1->fBConstrain&&TMath::Abs(track0->fP4)<TMath::Abs(track1->fP4)) continue; //returning - lower momenta
+      if (track1->GetNumberOfClusters()<40)                  continue;
+      if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
+      if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
+      if (TMath::Abs(1./track1->GetC())>200) continue;
+      if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0)      continue;
+      if (track1->GetTgl()*track0->GetTgl()>0)      continue;
+      if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
+      if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
+      if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
       //
       Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
       if (mindcar<5)   continue;
@@ -4109,14 +4922,6 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
       helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
       Double_t deltah[2],deltabest;
       if (hangles[2]<2.8) continue;
-      /*
-      cstream<<"C"<<track0->fLab<<track1->fLab<<
-       track0->fP3<<track1->fP3<<
-       track0->fP4<<track1->fP4<<
-       delta<<rmean<<npoints<<
-       hangles[0]<<hangles[2]<<
-       xyz0[2]<<xyz1[2]<<radius[0]<<"\n"; 
-      */
       if (npoints>0){
        Int_t ibest=0;
        helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
@@ -4132,26 +4937,29 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
        //
        if (deltabest>6) continue;
        if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
-       Bool_t sign =kFALSE;
-       if (hangles[2]>3.06) sign =kTRUE;
+       Bool_t lsign =kFALSE;
+       if (hangles[2]>3.06) lsign =kTRUE;
        //
-       if (sign){
+       if (lsign){
          circular[i0] = kTRUE;
          circular[i1] = kTRUE;
-         if (TMath::Abs(track0->fP4)<TMath::Abs(track1->fP4)){
-           track0->fCircular += 1;
-           track1->fCircular += 2;
+         if (track0->OneOverPt()<track1->OneOverPt()){
+           track0->SetCircular(track0->GetCircular()+1);
+           track1->SetCircular(track1->GetCircular()+2);
          }
          else{
-           track1->fCircular += 1;
-           track0->fCircular += 2;
+           track1->SetCircular(track1->GetCircular()+1);
+           track0->SetCircular(track0->GetCircular()+2);
          }
        }               
-       if (sign&&AliTPCReconstructor::StreamLevel()>1){          
+       if (lsign&&AliTPCReconstructor::StreamLevel()>1){         
          //debug stream          
+         Int_t lab0=track0->GetLabel();
+         Int_t lab1=track1->GetLabel();
+          TTreeSRedirector &cstream = *fDebugStreamer;
          cstream<<"Curling"<<
-           "lab0="<<track0->fLab<<
-           "lab1="<<track1->fLab<<   
+           "lab0="<<lab0<<
+           "lab1="<<lab1<<   
            "Tr0.="<<track0<<
            "Tr1.="<<track1<<      
            "dca0="<<dca[i0]<<
@@ -4183,6 +4991,10 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
   for (Int_t i =0;i<nentries;i++){
     if (sign[i]==0) continue;
     AliTPCseed * track0 = (AliTPCseed*)array->At(i);
+    if (track0==0) {
+      AliInfo("seed==0");
+      continue;
+    }
     ntracks++;
     //
     Double_t cradius0 = 40*40;
@@ -4254,15 +5066,15 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
       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);
+      Int_t found,foundable,ishared;
+      track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
       if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
-      track0->GetClusterStatistic(row0+5,155, found, foundable,shared,kFALSE);
+      track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
       if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
       //
-      track1->GetClusterStatistic(0,row0-5, found, foundable,shared,kFALSE);
+      track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
       if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
-      track1->GetClusterStatistic(row0+5,155, found, foundable,shared,kFALSE);
+      track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
       if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
       //     
       if (dens00<dens10 && dens01<dens11) continue;
@@ -4286,7 +5098,7 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
       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().GetX()>90.) new (&paramd) AliExternalTrackParam(ktrack1->GetReference()); 
+      if (row0>60&&ktrack1->GetReference().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference()); 
       //
       //
       kink->SetMother(paramm);
@@ -4295,8 +5107,8 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
 
       Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
       Int_t index[4];
-      fParam->Transform0to1(x,index);
-      fParam->Transform1to2(x,index);
+      fkParam->Transform0to1(x,index);
+      fkParam->Transform1to2(x,index);
       row0 = GetRowNumber(x[0]); 
 
       if (kink->GetR()<100) continue;
@@ -4313,7 +5125,7 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
 
       if (mpt<1){
        //for high momenta momentum not defined well in first iteration
-       Double_t qt   =  TMath::Sin(kink->GetAngle(2))*ktrack1->P();
+       Double_t qt   =  TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
        if (qt>0.35) continue; 
       }
       
@@ -4340,12 +5152,12 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
        //      angle and densities  not defined yet
        if (kink->GetTPCDensityFactor()<0.8) continue;
        if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
-       if (kink->GetAngle(2)*ktrack0->P()<0.003) continue; //too small angle
+       if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
        if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
        if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
 
-       Float_t criticalangle = track0->fC22+track0->fC33;
-       criticalangle+= track1->fC22+track1->fC33;
+       Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
+       criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
        criticalangle= 3*TMath::Sqrt(criticalangle);
        if (criticalangle>0.02) criticalangle=0.02;
        if (kink->GetAngle(2)<criticalangle) continue;
@@ -4357,12 +5169,12 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
       for ( Int_t row = row0-drow; row<row0+drow;row++){
        if (row<0) continue;
        if (row>155) continue;
-       if (ktrack0->fClusterPointer[row]){
+       if (ktrack0->GetClusterPointer(row)){
          AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
          shapesum+=point->GetSigmaY()+point->GetSigmaZ();
          sum++;
        }
-       if (ktrack1->fClusterPointer[row]){
+       if (ktrack1->GetClusterPointer(row)){
          AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
          shapesum+=point->GetSigmaY()+point->GetSigmaZ();
          sum++;
@@ -4375,8 +5187,32 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
        kink->SetShapeFactor(shapesum/sum);
       }      
       //      esd->AddKink(kink);
+      //
+      //      kink->SetMother(paramm);
+      //kink->SetDaughter(paramd);
+      Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
+      chi2P2*=chi2P2;
+      chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
+      Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
+      chi2P3*=chi2P3;
+      chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
+      //
+      if (AliTPCReconstructor::StreamLevel()>1) {
+       (*fDebugStreamer)<<"kinkLpt"<<
+         "chi2P2="<<chi2P2<<
+         "chi2P3="<<chi2P3<<
+         "p0.="<<&paramm<<
+         "p1.="<<&paramd<<
+         "k.="<<kink<<
+         "\n";
+      }
+      if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
+       continue;
+      }
+      //
       kinks->AddLast(kink);
-      kink = new AliESDkink;
+      kink = new AliKink;
       ncandidates++;
     }
   }
@@ -4392,74 +5228,75 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
   //
   for (Int_t i=0;i<nkinks;i++){
     quality[i] =100000;
-    AliESDkink *kink = (AliESDkink*)kinks->At(i);
+    AliKink *kinkl = (AliKink*)kinks->At(i);
     //
     // refit kinks towards vertex
     // 
-    Int_t index0 = kink->GetIndex(0);
-    Int_t index1 = kink->GetIndex(1);
+    Int_t index0 = kinkl->GetIndex(0);
+    Int_t index1 = kinkl->GetIndex(1);
     AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
     AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
     //
-    Int_t sumn=ktrack0->fN+ktrack1->fN;
+    Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
     //
     // Refit Kink under if too small angle
     //
-    if (kink->GetAngle(2)<0.05){
-      kink->SetTPCRow0(GetRowNumber(kink->GetR()));
-      Int_t row0 = kink->GetTPCRow0();
-      Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2)));
+    if (kinkl->GetAngle(2)<0.05){
+      kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
+      Int_t row0 = kinkl->GetTPCRow0();
+      Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
       //
       //
       Int_t last  = row0-drow;
       if (last<40) last=40;
-      if (last<ktrack0->fFirstPoint+25) last = ktrack0->fFirstPoint+25;
+      if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
       AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
       //
       //
       Int_t first = row0+drow;
       if (first>130) first=130;
-      if (first>ktrack1->fLastPoint-25) first = TMath::Max(ktrack1->fLastPoint-25,30);
+      if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
       AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
       //
       if (seed0 && seed1){
-       kink->SetStatus(1,8);
-       if (RefitKink(*seed0,*seed1,*kink)) kink->SetStatus(1,9);
-       row0 = GetRowNumber(kink->GetR());
-       sumn = seed0->fN+seed1->fN;
-       new (&mothers[i])   AliTPCseed(*seed0);
-       new (&daughters[i]) AliTPCseed(*seed1); 
+       kinkl->SetStatus(1,8);
+       if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
+       row0 = GetRowNumber(kinkl->GetR());
+       sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
+       mothers[i] = *seed0;
+       daughters[i] = *seed1;
       }
       else{
        delete kinks->RemoveAt(i);
-       if (seed0) delete seed0;
-       if (seed1) delete seed1;
+       if (seed0) MarkSeedFree( seed0 );
+       if (seed1) MarkSeedFree( seed1 );
        continue;
       }
-      if (kink->GetDistance()>0.5 || kink->GetR()<110 || kink->GetR()>240) {
+      if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
        delete kinks->RemoveAt(i);
-       if (seed0) delete seed0;
-       if (seed1) delete seed1;
+       if (seed0) MarkSeedFree( seed0 );
+       if (seed1) MarkSeedFree( seed1 );
        continue;
       }
       //
-      delete seed0;
-      delete seed1;            
+      MarkSeedFree( seed0 );
+      MarkSeedFree( seed1 );
     }
     //
-    if (kink) quality[i] = 160*((0.1+kink->GetDistance())*(2.-kink->GetTPCDensityFactor()))/(sumn+40.);  //the longest -clossest will win
+    if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.);  //the longest -clossest will win
   }
   TMath::Sort(nkinks,quality,indexes,kFALSE);
   //
   //remove double find kinks
   //
   for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
-    AliESDkink * kink0 = (AliESDkink*) kinks->At(indexes[ikink0]);
+    AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
     if (!kink0) continue;
     //
-    for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
+    for (Int_t ikink1=0;ikink1<ikink0;ikink1++){ 
+      kink0 = (AliKink*) kinks->At(indexes[ikink0]);
       if (!kink0) continue;
-      AliESDkink * kink1 = (AliESDkink*) kinks->At(indexes[ikink1]);
+      AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
       if (!kink1) continue;
       // if not close kink continue
       if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
@@ -4480,10 +5317,10 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
       Int_t bothd = 0;
       //
       for (Int_t i=0;i<row0;i++){
-       if (mother0.fIndex[i]>0 && mother1.fIndex[i]>0){
+       if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
          both++;
          bothm++;
-         if (mother0.fIndex[i]==mother1.fIndex[i]){
+         if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
            same++;
            samem++;
          }
@@ -4491,10 +5328,11 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
       }
 
       for (Int_t i=row0;i<158;i++){
-       if (daughter0.fIndex[i]>0 && daughter0.fIndex[i]>0){
+       //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug? 
+       if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
          both++;
          bothd++;
-         if (mother0.fIndex[i]==mother1.fIndex[i]){
+         if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
            same++;
            samed++;
          }
@@ -4504,12 +5342,13 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
       Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
       Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
       if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
-       Int_t sum0 = mother0.fN+daughter0.fN;
-       Int_t sum1 = mother1.fN+daughter1.fN;
+       Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
+       Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
        if (sum1>sum0){
          shared[kink0->GetIndex(0)]= kTRUE;
          shared[kink0->GetIndex(1)]= kTRUE;      
          delete kinks->RemoveAt(indexes[ikink0]);
+         break;
        }
        else{
          shared[kink1->GetIndex(0)]= kTRUE;
@@ -4522,34 +5361,34 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
 
 
   for (Int_t i=0;i<nkinks;i++){
-    AliESDkink * kink = (AliESDkink*) kinks->At(indexes[i]);
-    if (!kink) continue;
-    kink->SetTPCRow0(GetRowNumber(kink->GetR()));
-    Int_t index0 = kink->GetIndex(0);
-    Int_t index1 = kink->GetIndex(1);
-    if (circular[index0]||circular[index1]&&kink->GetDistance()>0.2) continue;
-    kink->SetMultiple(usage[index0],0);
-    kink->SetMultiple(usage[index1],1);
-    if (kink->GetMultiple()[0]+kink->GetMultiple()[1]>2) continue;
-    if (kink->GetMultiple()[0]+kink->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
-    if (kink->GetMultiple()[0]+kink->GetMultiple()[1]>0 && kink->GetDistance()>0.2) continue;
-    if (circular[index0]||circular[index1]&&kink->GetDistance()>0.1) continue;
+    AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
+    if (!kinkl) continue;
+    kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
+    Int_t index0 = kinkl->GetIndex(0);
+    Int_t index1 = kinkl->GetIndex(1);
+    if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
+    kinkl->SetMultiple(usage[index0],0);
+    kinkl->SetMultiple(usage[index1],1);
+    if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
+    if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
+    if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
+    if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
 
     AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
     AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
     if (!ktrack0 || !ktrack1) continue;
-    Int_t index = esd->AddKink(kink);
+    Int_t index = esd->AddKink(kinkl);
     //
     //
-    if ( ktrack0->fKinkIndexes[0]==0 && ktrack1->fKinkIndexes[0]==0) {  //best kink
-      if (mothers[indexes[i]].fN>20 && daughters[indexes[i]].fN>20 && (mothers[indexes[i]].fN+daughters[indexes[i]].fN)>100){
-       new (ktrack0) AliTPCseed(mothers[indexes[i]]);
-       new (ktrack1) AliTPCseed(daughters[indexes[i]]);
+    if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) {  //best kink
+      if (mothers[indexes[i]].GetNumberOfClusters()>20 && daughters[indexes[i]].GetNumberOfClusters()>20 && (mothers[indexes[i]].GetNumberOfClusters()+daughters[indexes[i]].GetNumberOfClusters())>100){
+       *ktrack0 = mothers[indexes[i]];
+       *ktrack1 = daughters[indexes[i]];
       }
     }
     //
-    ktrack0->fKinkIndexes[usage[index0]] = -(index+1);
-    ktrack1->fKinkIndexes[usage[index1]] =  (index+1);
+    ktrack0->SetKinkIndex(usage[index0],-(index+1));
+    ktrack1->SetKinkIndex(usage[index1], (index+1));
     usage[index0]++;
     usage[index1]++;
   }
@@ -4559,8 +5398,8 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
   for (Int_t i=0;i<nentries;i++){
     AliTPCseed * track0 = (AliTPCseed*)array->At(i);
     if (!track0) continue;
-    if (track0->fKinkIndexes[0]!=0) continue;
-    if (shared[i]) delete array->RemoveAt(i);
+    if (track0->GetKinkIndex(0)!=0) continue;
+    if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
   }
 
   //
@@ -4579,30 +5418,31 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
     if (!track0) continue;
     if (track0->Pt()<1.4) continue;
     //remove double high momenta tracks - overlapped with kink candidates
-    Int_t shared=0;
+    Int_t ishared=0;
     Int_t all   =0;
-    for (Int_t icl=track0->fFirstPoint;icl<track0->fLastPoint; icl++){
-      if (track0->fClusterPointer[icl]!=0){
+    for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
+      if (track0->GetClusterPointer(icl)!=0){
        all++;
-       if (track0->fClusterPointer[icl]->IsUsed(10)) shared++;
+       if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
       }
     }
-    if (Float_t(shared+1)/Float_t(nall+1)>0.5) {
-      delete array->RemoveAt(i);
+    if (Float_t(ishared+1)/Float_t(all+1)>0.5) {  
+      MarkSeedFree( array->RemoveAt(i) );
+      continue;
     }
     //
-    if (track0->fKinkIndexes[0]!=0) continue;
+    if (track0->GetKinkIndex(0)!=0) continue;
     if (track0->GetNumberOfClusters()<80) continue;
 
     AliTPCseed *pmother = new AliTPCseed();
     AliTPCseed *pdaughter = new AliTPCseed();
-    AliESDkink *pkink = new AliESDkink;
+    AliKink *pkink = new AliKink;
 
     AliTPCseed & mother = *pmother;
     AliTPCseed & daughter = *pdaughter;
-    AliESDkink & kink = *pkink;
-    if (CheckKinkPoint(track0,mother,daughter, kink)){
-      if (mother.fN<30||daughter.fN<20) {
+    AliKink & kinkl = *pkink;
+    if (CheckKinkPoint(track0,mother,daughter, kinkl)){
+      if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
        delete pmother;
        delete pdaughter;
        delete pkink;
@@ -4614,31 +5454,37 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
        delete pkink;
        continue;
       }
-      Int_t row0= kink.GetTPCRow0();
-      if (kink.GetDistance()>0.5 || kink.GetR()<110. || kink.GetR()>240.) {
+      Int_t row0= kinkl.GetTPCRow0();
+      if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
        delete pmother;
        delete pdaughter;
        delete pkink;
        continue;
       }
       //
-      Int_t index = esd->AddKink(&kink);      
-      mother.fKinkIndexes[0] = -(index+1);
-      daughter.fKinkIndexes[0] = index+1;
-      if (mother.fN>50) {
-       delete array->RemoveAt(i);
-       array->AddAt(new AliTPCseed(mother),i);
+      Int_t index = esd->AddKink(&kinkl);      
+      mother.SetKinkIndex(0,-(index+1));
+      daughter.SetKinkIndex(0,index+1);
+      if (mother.GetNumberOfClusters()>50) {
+       MarkSeedFree( array->RemoveAt(i) );
+       AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
+       mtc->SetPoolID(fLastSeedID);
+       array->AddAt(mtc,i);
       }
       else{
-       array->AddLast(new AliTPCseed(mother));
+       AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
+       mtc->SetPoolID(fLastSeedID);
+       array->AddLast(mtc);
       }
-      array->AddLast(new AliTPCseed(daughter));      
+      AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
+      dtc->SetPoolID(fLastSeedID);
+      array->AddLast(dtc);      
       for (Int_t icl=0;icl<row0;icl++) {
-       if (mother.fClusterPointer[icl]) mother.fClusterPointer[icl]->Use(20);
+       if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
       }
       //
       for (Int_t icl=row0;icl<158;icl++) {
-       if (daughter.fClusterPointer[icl]) daughter.fClusterPointer[icl]->Use(20);
+       if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
       }
       //
     }
@@ -4669,43 +5515,52 @@ void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
   kinks->Delete();
   delete kinks;
 
-  printf("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall);
+  AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
   timer.Print();
 }
 
-void  AliTPCtrackerMI::FindV0s(TObjArray * array, AliESD *esd)
+
+/*
+void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESDEvent *esd)
 {
   //
-  //  find V0s
+  //  find kinks
   //
   //
-  TObjArray *tpcv0s      = new TObjArray(100000);
-  Int_t     nentries     = array->GetEntriesFast();
+
+  TObjArray *kinks= new TObjArray(10000);
+  //  TObjArray *v0s= 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];
+  AliKink  *kink         = new AliKink();
+  Int_t      * usage     = new Int_t[nentries];
+  Float_t  *zm           = new Float_t[nentries];
   Float_t  *z0           = new Float_t[nentries]; 
-  Float_t  *dca          = new Float_t[nentries];
-  Float_t  *sdcar        = new Float_t[nentries];
-  Float_t  *cdcar        = new Float_t[nentries];
-  Float_t  *pulldcar     = new Float_t[nentries];
-  Float_t  *pulldcaz     = new Float_t[nentries];
-  Float_t  *pulldca      = new Float_t[nentries];
-  Bool_t   *isPrim       = new Bool_t[nentries];  
-  const AliESDVertex * primvertex = esd->GetVertex();
-  Double_t             zvertex = primvertex->GetZv(); 
+  Float_t  *fim          = new Float_t[nentries];
+  Float_t  *shared       = new Float_t[nentries];
+  Bool_t   *circular     = new Bool_t[nentries];
+  Float_t *dca          = new Float_t[nentries];
+  //const AliESDVertex * primvertex = esd->GetVertex();
   //
   //  nentries = array->GetEntriesFast();
   //
+  
+  //
+  //
   for (Int_t i=0;i<nentries;i++){
     sign[i]=0;
-    isPrim[i]=0;
+    usage[i]=0;
     AliTPCseed* track = (AliTPCseed*)array->At(i);    
     if (!track) continue;
-    track->GetV0Indexes()[0] = 0;  //rest v0 indexes
-    track->GetV0Indexes()[1] = 0;  //rest v0 indexes
-    track->GetV0Indexes()[2] = 0;  //rest v0 indexes
-    //
+    track->SetCircular(0);
+    shared[i] = kFALSE;
+    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);
     Double_t xyz[3];
@@ -4713,27 +5568,18 @@ void  AliTPCtrackerMI::FindV0s(TObjArray * array, AliESD *esd)
     sign[i] = (track->GetC()>0) ? -1:1;
     Double_t x,y,z;
     x=160;
-    z0[i]=1000;
-    if (track->GetProlongation(0,y,z))  z0[i] = z;
-    dca[i] = track->GetD(0,0);
-    // 
-    // dca error parrameterezation + pulls
-    //
-    sdcar[i]      = TMath::Sqrt(0.150*0.150+(100*track->fP4)*(100*track->fP4));
-    if (TMath::Abs(track->fP3)>1) sdcar[i]*=2.5;
-    cdcar[i]      = TMath::Exp((TMath::Abs(track->fP4)-0.0106)*525.3);
-    pulldcar[i]   = (dca[i]-cdcar[i])/sdcar[i];
-    pulldcaz[i]   = (z0[i]-zvertex)/sdcar[i];
-    pulldca[i]    = TMath::Sqrt(pulldcar[i]*pulldcar[i]+pulldcaz[i]*pulldcaz[i]);
-    if (track->fTPCr[1]+track->fTPCr[2]+track->fTPCr[3]>0.5) {
-      if (pulldca[i]<3.) isPrim[i]=kTRUE;  //pion, muon and Kaon  3 sigma cut
-    }
-    if (track->fTPCr[4]>0.5) {
-      if (pulldca[i]<0.5) isPrim[i]=kTRUE;  //proton 0.5 sigma cut
-    }
-    if (track->fTPCr[0]>0.4) {
-      isPrim[i]=kFALSE;  //electron no  sigma cut
+    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];
+    }   
+    z0[i]=1000;
+    circular[i]= kFALSE;
+    if (track->GetProlongation(0,y,z))  z0[i] = z;
+    dca[i] = track->GetD(0,0);    
   }
   //
   //
@@ -4742,283 +5588,673 @@ void  AliTPCtrackerMI::FindV0s(TObjArray * array, AliESD *esd)
   Int_t ncandidates =0;
   Int_t nall =0;
   Int_t ntracks=0; 
-  Double_t phase[2][2],radius[2];
+  Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
+
+  //
+  // Find circling track
+  //
+  for (Int_t i0=0;i0<nentries;i0++){
+    AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
+    if (!track0) continue;    
+    if (track0->GetNumberOfClusters()<40) continue;
+    if (TMath::Abs(1./track0->GetC())>200) continue;
+    for (Int_t i1=i0+1;i1<nentries;i1++){
+      AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
+      if (!track1) continue;
+      if (track1->GetNumberOfClusters()<40)                  continue;
+      if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
+      if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
+      if (TMath::Abs(1./track1->GetC())>200) continue;
+      if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0)      continue;
+      if (track1->GetTgl()*track0->GetTgl()>0)      continue;
+      if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
+      if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
+      if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
+      //
+      Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
+      if (mindcar<5)   continue;
+      Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
+      if (mindcaz<5) continue;
+      if (mindcar+mindcaz<20) continue;
+      //
+      //
+      Float_t xc0 = helixes[i0].GetHelix(6);
+      Float_t yc0 = helixes[i0].GetHelix(7);
+      Float_t r0  = helixes[i0].GetHelix(8);
+      Float_t xc1 = helixes[i1].GetHelix(6);
+      Float_t yc1 = helixes[i1].GetHelix(7);
+      Float_t r1  = helixes[i1].GetHelix(8);
+       
+      Float_t rmean = (r0+r1)*0.5;
+      Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
+      //if (delta>30) continue;
+      if (delta>rmean*0.25) continue;
+      if (TMath::Abs(r0-r1)/rmean>0.3) continue; 
+      //
+      Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
+      if (npoints==0) continue;
+      helixes[i0].GetClosestPhases(helixes[i1], phase);
+      //
+      Double_t xyz0[3];
+      Double_t xyz1[3];
+      Double_t hangles[3];
+      helixes[i0].Evaluate(phase[0][0],xyz0);
+      helixes[i1].Evaluate(phase[0][1],xyz1);
+
+      helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
+      Double_t deltah[2],deltabest;
+      if (hangles[2]<2.8) continue;
+      if (npoints>0){
+       Int_t ibest=0;
+       helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
+       if (npoints==2){
+         helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
+         if (deltah[1]<deltah[0]) ibest=1;
+       }
+       deltabest  = TMath::Sqrt(deltah[ibest]);
+       helixes[i0].Evaluate(phase[ibest][0],xyz0);
+       helixes[i1].Evaluate(phase[ibest][1],xyz1);
+       helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
+       Double_t radiusbest = TMath::Sqrt(radius[ibest]);
+       //
+       if (deltabest>6) continue;
+       if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
+       Bool_t lsign =kFALSE;
+       if (hangles[2]>3.06) lsign =kTRUE;
+       //
+       if (lsign){
+         circular[i0] = kTRUE;
+         circular[i1] = kTRUE;
+         if (track0->OneOverPt()<track1->OneOverPt()){
+           track0->SetCircular(track0->GetCircular()+1);
+           track1->SetCircular(track1->GetCircular()+2);
+         }
+         else{
+           track1->SetCircular(track1->GetCircular()+1);
+           track0->SetCircular(track0->GetCircular()+2);
+         }
+       }               
+       if (lsign&&AliTPCReconstructor::StreamLevel()>1){         
+         //debug stream          
+         Int_t lab0=track0->GetLabel();
+         Int_t lab1=track1->GetLabel();
+          TTreeSRedirector &cstream = *fDebugStreamer;
+         cstream<<"Curling"<<
+           "lab0="<<lab0<<
+           "lab1="<<lab1<<   
+           "Tr0.="<<track0<<
+           "Tr1.="<<track1<<      
+           "dca0="<<dca[i0]<<
+           "dca1="<<dca[i1]<<
+           "mindcar="<<mindcar<<
+           "mindcaz="<<mindcaz<<
+           "delta="<<delta<<
+           "rmean="<<rmean<<
+           "npoints="<<npoints<<                      
+           "hangles0="<<hangles[0]<<
+           "hangles2="<<hangles[2]<<                    
+           "xyz0="<<xyz0[2]<<
+           "xyzz1="<<xyz1[2]<<
+           "z0="<<z0[i0]<<
+           "z1="<<z0[i1]<<
+           "radius="<<radiusbest<<
+           "deltabest="<<deltabest<< 
+           "phase0="<<phase[ibest][0]<<
+           "phase1="<<phase[ibest][1]<<
+           "\n";                 
+       }
+      }
+    }
+  }
+  //
+  //  Finf kinks loop
+  // 
+  //
+  for (Int_t i =0;i<nentries;i++){
+    if (sign[i]==0) continue;
+    AliTPCseed * track0 = (AliTPCseed*)array->At(i);
+    if (track0==0) {
+      AliInfo("seed==0");
+      continue;
+    }
+    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,ishared;
+      track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
+      if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
+      track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
+      if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
+      //
+      track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
+      if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
+      track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,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().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference()); 
+      //
+      //
+      kink->SetMother(paramm);
+      kink->SetDaughter(paramd);
+      kink->Update();
+
+      Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
+      Int_t index[4];
+      fkParam->Transform0to1(x,index);
+      fkParam->Transform1to2(x,index);
+      row0 = GetRowNumber(x[0]); 
+
+      if (kink->GetR()<100) continue;
+      if (kink->GetR()>240) continue;
+      if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue;  //out of fiducial volume
+      if (kink->GetDistance()>cdist3) continue;
+      Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1];  // rough direction estimate
+      if (dird<0) continue;
+
+      Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1];  // rough direction estimate
+      if (dirm<0) continue;
+      Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
+      if (mpt<0.2) continue;
+
+      if (mpt<1){
+       //for high momenta momentum not defined well in first iteration
+       Double_t qt   =  TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
+       if (qt>0.35) continue; 
+      }
+      
+      kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
+      kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
+      if (dens00>dens10){
+       kink->SetTPCDensity(dens00,0,0);
+       kink->SetTPCDensity(dens01,0,1);
+       kink->SetTPCDensity(dens10,1,0);
+       kink->SetTPCDensity(dens11,1,1);
+       kink->SetIndex(i,0);
+       kink->SetIndex(j,1);
+      }
+      else{
+       kink->SetTPCDensity(dens10,0,0);
+       kink->SetTPCDensity(dens11,0,1);
+       kink->SetTPCDensity(dens00,1,0);
+       kink->SetTPCDensity(dens01,1,1);
+       kink->SetIndex(j,0);
+       kink->SetIndex(i,1);
+      }
+
+      if (mpt<1||kink->GetAngle(2)>0.1){
+       //      angle and densities  not defined yet
+       if (kink->GetTPCDensityFactor()<0.8) continue;
+       if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
+       if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
+       if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
+       if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
+
+       Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
+       criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
+       criticalangle= 3*TMath::Sqrt(criticalangle);
+       if (criticalangle>0.02) criticalangle=0.02;
+       if (kink->GetAngle(2)<criticalangle) continue;
+      }
+      //
+      Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2)));  // overlap region defined
+      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->GetClusterPointer(row)){
+         AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
+         shapesum+=point->GetSigmaY()+point->GetSigmaZ();
+         sum++;
+       }
+       if (ktrack1->GetClusterPointer(row)){
+         AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
+         shapesum+=point->GetSigmaY()+point->GetSigmaZ();
+         sum++;
+       }       
+      }
+      if (sum<4){
+       kink->SetShapeFactor(-1.);
+      }
+      else{
+       kink->SetShapeFactor(shapesum/sum);
+      }      
+      //      esd->AddKink(kink);
+      //
+      //      kink->SetMother(paramm);
+      //kink->SetDaughter(paramd);
+      Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
+      chi2P2*=chi2P2;
+      chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
+      Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
+      chi2P3*=chi2P3;
+      chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
+      //
+      if (AliTPCReconstructor::StreamLevel()>1) {
+       (*fDebugStreamer)<<"kinkLpt"<<
+         "chi2P2="<<chi2P2<<
+         "chi2P3="<<chi2P3<<
+         "p0.="<<&paramm<<
+         "p1.="<<&paramd<<
+         "k.="<<kink<<
+         "\n";
+      }
+      if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
+       continue;
+      }
+      //
+      kinks->AddLast(kink);
+      kink = new AliKink;
+      ncandidates++;
+    }
+  }
+  //
+  // sort the kinks according quality - and refit them towards vertex
+  //
+  Int_t       nkinks    = kinks->GetEntriesFast();
+  Float_t    *quality   = new Float_t[nkinks];
+  Int_t      *indexes   = new Int_t[nkinks];
+  AliTPCseed **mothers   = new AliTPCseed*[nkinks]; memset(mothers,   0, nkinks*sizeof(AliTPCseed*));
+  AliTPCseed **daughters = new AliTPCseed*[nkinks]; memset(daughters, 0, nkinks*sizeof(AliTPCseed*));
+  //
+  //
+  for (Int_t i=0;i<nkinks;i++){
+    quality[i] =100000;
+    AliKink *kinkl = (AliKink*)kinks->At(i);
+    //
+    // refit kinks towards vertex
+    // 
+    Int_t index0 = kinkl->GetIndex(0);
+    Int_t index1 = kinkl->GetIndex(1);
+    AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
+    AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
+    //
+    Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
+    //
+    // Refit Kink under if too small angle
+    //
+    if (kinkl->GetAngle(2)<0.05){
+      kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
+      Int_t row0 = kinkl->GetTPCRow0();
+      Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
+      //
+      //
+      Int_t last  = row0-drow;
+      if (last<40) last=40;
+      if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
+      AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
+      //
+      //
+      Int_t first = row0+drow;
+      if (first>130) first=130;
+      if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
+      AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
+      //
+      if (seed0 && seed1){
+       kinkl->SetStatus(1,8);
+       if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
+       row0 = GetRowNumber(kinkl->GetR());
+       sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
+       mothers[i] = new ( NextFreeSeed() ) AliTPCseed(*seed0);
+       mothers[i]->SetPoolID(fLastSeedID);
+       daughters[i] = new (NextFreeSeed() ) AliTPCseed(*seed1);
+       daughters[i]->SetPoolID(fLastSeedID);
+      }
+      else{
+       delete kinks->RemoveAt(i);
+       if (seed0) MarkSeedFree( seed0 );
+       if (seed1) MarkSeedFree( seed1 );
+       continue;
+      }
+      if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
+       delete kinks->RemoveAt(i);
+       if (seed0) MarkSeedFree( seed0 );
+       if (seed1) MarkSeedFree( seed1 );
+       continue;
+      }
+      //
+      MarkSeedFree( seed0 );
+      MarkSeedFree( seed1 );
+    }
+    //
+    if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.);  //the longest -clossest will win
+  }
+  TMath::Sort(nkinks,quality,indexes,kFALSE);
+  //
+  //remove double find kinks
+  //
+  for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
+    AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
+    if (!kink0) continue;
+    //
+    for (Int_t ikink1=0;ikink1<ikink0;ikink1++){ 
+      kink0 = (AliKink*) kinks->At(indexes[ikink0]);
+      if (!kink0) continue;
+      AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
+      if (!kink1) continue;
+      // if not close kink continue
+      if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
+      if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
+      if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
+      //
+      AliTPCseed &mother0   = *mothers[indexes[ikink0]];
+      AliTPCseed &daughter0 = *daughters[indexes[ikink0]];
+      AliTPCseed &mother1   = *mothers[indexes[ikink1]];
+      AliTPCseed &daughter1 = *daughters[indexes[ikink1]];
+      Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
+      //
+      Int_t same  = 0;
+      Int_t both  = 0;
+      Int_t samem = 0;
+      Int_t bothm = 0;
+      Int_t samed = 0;
+      Int_t bothd = 0;
+      //
+      for (Int_t i=0;i<row0;i++){
+       if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
+         both++;
+         bothm++;
+         if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
+           same++;
+           samem++;
+         }
+       }
+      }
+
+      for (Int_t i=row0;i<158;i++){
+       //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug? 
+       if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
+         both++;
+         bothd++;
+         if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
+           same++;
+           samed++;
+         }
+       }
+      }
+      Float_t ratio = Float_t(same+1)/Float_t(both+1);
+      Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
+      Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
+      if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
+       Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
+       Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
+       if (sum1>sum0){
+         shared[kink0->GetIndex(0)]= kTRUE;
+         shared[kink0->GetIndex(1)]= kTRUE;      
+         delete kinks->RemoveAt(indexes[ikink0]);
+         break;
+       }
+       else{
+         shared[kink1->GetIndex(0)]= kTRUE;
+         shared[kink1->GetIndex(1)]= kTRUE;      
+         delete kinks->RemoveAt(indexes[ikink1]);
+       }
+      }
+    }
+  }
+
+
+  for (Int_t i=0;i<nkinks;i++){
+    AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
+    if (!kinkl) continue;
+    kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
+    Int_t index0 = kinkl->GetIndex(0);
+    Int_t index1 = kinkl->GetIndex(1);
+    if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
+    kinkl->SetMultiple(usage[index0],0);
+    kinkl->SetMultiple(usage[index1],1);
+    if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
+    if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
+    if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
+    if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
+
+    AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
+    AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
+    if (!ktrack0 || !ktrack1) continue;
+    Int_t index = esd->AddKink(kinkl);
+    //
+    //
+    if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) {  //best kink
+      if (mothers[indexes[i]]->GetNumberOfClusters()>20 && daughters[indexes[i]]->GetNumberOfClusters()>20 && 
+         (mothers[indexes[i]]->GetNumberOfClusters()+daughters[indexes[i]]->GetNumberOfClusters())>100){
+       *ktrack0 = *mothers[indexes[i]];
+       *ktrack1 = *daughters[indexes[i]];
+      }
+    }
+    //
+    ktrack0->SetKinkIndex(usage[index0],-(index+1));
+    ktrack1->SetKinkIndex(usage[index1], (index+1));
+    usage[index0]++;
+    usage[index1]++;
+  }
+  //
+  // Remove tracks corresponding to shared kink's
+  //
+  for (Int_t i=0;i<nentries;i++){
+    AliTPCseed * track0 = (AliTPCseed*)array->At(i);
+    if (!track0) continue;
+    if (track0->GetKinkIndex(0)!=0) continue;
+    if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
+  }
+
+  //
   //
-  //  Finf V0s loop
-  // 
+  RemoveUsed2(array,0.5,0.4,30);
+  UnsignClusters();
+  for (Int_t i=0;i<nentries;i++){
+    AliTPCseed * track0 = (AliTPCseed*)array->At(i);
+    if (!track0) continue;
+    track0->CookdEdx(0.02,0.6);
+    track0->CookPID();
+  }
   //
-  // //  
-  TTreeSRedirector &cstream = *fDebugStreamer; 
-  Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
-  AliESDV0MI vertex; 
-  Double_t cradius0 = 10*10;
-  Double_t cradius1 = 200*200;
-  Double_t cdist1=3.;
-  Double_t cdist2=4.;
-  Double_t cpointAngle = 0.95;
-  //
-  Double_t delta[2]={10000,10000};
-  for (Int_t i =0;i<nentries;i++){
-    if (sign[i]==0) continue;
+  for (Int_t i=0;i<nentries;i++){
     AliTPCseed * track0 = (AliTPCseed*)array->At(i);
     if (!track0) continue;
-    if (AliTPCReconstructor::StreamLevel()>0){
-      cstream<<"Tracks"<<
-       "Tr0.="<<track0<<
-       "dca="<<dca[i]<<
-       "z0="<<z0[i]<<
-       "zvertex="<<zvertex<<
-       "sdcar0="<<sdcar[i]<<
-       "cdcar0="<<cdcar[i]<<
-       "pulldcar0="<<pulldcar[i]<<
-       "pulldcaz0="<<pulldcaz[i]<<
-       "pulldca0="<<pulldca[i]<<
-       "isPrim="<<isPrim[i]<<
-       "\n";
+    if (track0->Pt()<1.4) continue;
+    //remove double high momenta tracks - overlapped with kink candidates
+    Int_t ishared=0;
+    Int_t all   =0;
+    for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
+      if (track0->GetClusterPointer(icl)!=0){
+       all++;
+       if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
+      }
+    }
+    if (Float_t(ishared+1)/Float_t(all+1)>0.5) {  
+      MarkSeedFree( array->RemoveAt(i) );
+      continue;
     }
     //
-    if (track0->fP4<0) continue;
-    if (track0->GetKinkIndex(0)>0||isPrim[i]) continue;   //daughter kink
-    //
-    if (TMath::Abs(helixes[i].GetHelix(4))<0.000000001) continue;
-    ntracks++;
-    // debug output
-    
-    
-    for (Int_t j =0;j<nentries;j++){
-      AliTPCseed * track1 = (AliTPCseed*)array->At(j);
-      if (!track1) continue;
-      if (track1->GetKinkIndex(0)>0 || isPrim[j]) continue; //daughter kink
-      if (sign[j]*sign[i]>0) continue; 
-      if (TMath::Abs(helixes[j].GetHelix(4))<0.000001) continue;
-      if (track0->fCircular+track1->fCircular>1) continue;    //circling -returning track
-      nall++;
-      //
-      // DCA to prim vertex cut
-      //
-      //
-      delta[0]=10000;
-      delta[1]=10000;
+    if (track0->GetKinkIndex(0)!=0) continue;
+    if (track0->GetNumberOfClusters()<80) continue;
 
-      Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,cdist2);
-      if (npoints<1) continue;
-      Int_t iclosest=0;
-      // cuts on radius      
-      if (npoints==1){
-       if (radius[0]<cradius0||radius[0]>cradius1) continue;
-       helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta[0]);
-       if (delta[0]>cdist1) continue;
+    AliTPCseed *pmother = new( NextFreeSeed() ) AliTPCseed();
+    pmother->SetPoolID(fLastSeedID);
+    AliTPCseed *pdaughter = new( NextFreeSeed() ) AliTPCseed();
+    pdaughter->SetPoolID(fLastSeedID);
+    AliKink *pkink = new AliKink;
+
+    AliTPCseed & mother = *pmother;
+    AliTPCseed & daughter = *pdaughter;
+    AliKink & kinkl = *pkink;
+    if (CheckKinkPoint(track0,mother,daughter, kinkl)){
+      if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
+       MarkSeedFree( pmother );
+       MarkSeedFree( pdaughter );
+       delete pkink;
+       continue;  //too short tracks
       }
-      else{
-       if (TMath::Max(radius[0],radius[1])<cradius0|| TMath::Min(radius[0],radius[1])>cradius1) continue;      
-       helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta[0]);    
-       helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta[1]);
-       if (delta[1]<delta[0]) iclosest=1;
-       if (delta[iclosest]>cdist1) continue;
-      }
-      helixes[i].ParabolicDCA(helixes[j],phase[iclosest][0],phase[iclosest][1],radius[iclosest],delta[iclosest]);
-      if (radius[iclosest]<cradius0 || radius[iclosest]>cradius1 || delta[iclosest]>cdist1) continue;
-      //
-      Double_t pointAngle = helixes[i].GetPointAngle(helixes[j],phase[iclosest],fprimvertex);
-      if (pointAngle<cpointAngle) continue;
-      //
-      Bool_t isGamma = kFALSE;
-      vertex.SetP(*track0); //track0 - plus
-      vertex.SetM(*track1); //track1 - minus
-      vertex.Update(fprimvertex);
-      if (track0->fTPCr[0]>0.3&&track1->fTPCr[0]>0.3&&vertex.GetAnglep()[2]<0.15) isGamma=kTRUE;              // gamma conversion candidate
-      Double_t pointAngle2 = vertex.GetPointAngle();
-      //continue;
-      if (vertex.GetPointAngle()<cpointAngle && (!isGamma)) continue; // point angle cut
-      if (vertex.GetDist2()>2&&(!isGamma)) continue;         // point angle cut
-      Float_t sigmae     = 0.15*0.15;
-      if (vertex.GetRr()<80) 
-       sigmae += (sdcar[i]*sdcar[i]+sdcar[j]*sdcar[j])*(1.-vertex.GetRr()/80.)*(1.-vertex.GetRr()/80.);
-      sigmae+= TMath::Sqrt(sigmae);
-      if (vertex.GetDist2()/sigmae>3.&&(!isGamma)) continue; 
-      Float_t densb0=0,densb1=0,densa0=0,densa1=0;
-      Int_t row0 = GetRowNumber(vertex.GetRr());
-      if (row0>15){
-       if (vertex.GetDist2()>0.2) continue;             
-       densb0     = track0->Density2(0,row0-5);          
-       densb1     = track1->Density2(0,row0-5);         
-       if (densb0>0.3|| densb1>0.3) continue;            //clusters before vertex
-       densa0     = track0->Density2(row0+5,row0+40);    
-       densa1     = track1->Density2(row0+5,row0+40);    
-       if ((densa0<0.4|| densa1<0.4)&&(!isGamma)) continue;            //missing clusters after vertex
+      if (mother.Pt()<1.4) {
+       MarkSeedFree( pmother );
+       MarkSeedFree( pdaughter );
+       delete pkink;
+       continue;
+      }
+      Int_t row0= kinkl.GetTPCRow0();
+      if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
+       MarkSeedFree( pmother );
+       MarkSeedFree( pdaughter );
+       delete pkink;
+       continue;
+      }
+      //
+      Int_t index = esd->AddKink(&kinkl);      
+      mother.SetKinkIndex(0,-(index+1));
+      daughter.SetKinkIndex(0,index+1);
+      if (mother.GetNumberOfClusters()>50) {
+       MarkSeedFree( array->RemoveAt(i) );
+       AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
+       mtc->SetPoolID(fLastSeedID);
+       array->AddAt(mtc,i);
       }
       else{
-       densa0     = track0->Density2(0,40);  //cluster density
-       densa1     = track1->Density2(0,40);  //cluster density
-       if ((vertex.GetRr()<80&&densa0+densa1<1.)&&(!isGamma)) continue;
-      }
-      vertex.SetLab(0,track0->GetLabel());
-      vertex.SetLab(1,track1->GetLabel());
-      vertex.SetChi2After((densa0+densa1)*0.5);
-      vertex.SetChi2Before((densb0+densb1)*0.5);
-      vertex.SetIndex(0,i);
-      vertex.SetIndex(1,j);
-      vertex.SetStatus(1); // TPC v0 candidate
-      vertex.SetRp(track0->fTPCr);
-      vertex.SetRm(track1->fTPCr);
-      tpcv0s->AddLast(new AliESDV0MI(vertex));      
-      ncandidates++;
-      {
-       Int_t eventNr = esd->GetEventNumber();
-       Double_t radiusm= (delta[0]<delta[1])? TMath::Sqrt(radius[0]):TMath::Sqrt(radius[1]);  
-       Double_t deltam= (delta[0]<delta[1])? TMath::Sqrt(delta[0]):TMath::Sqrt(delta[1]);  
-       if (AliTPCReconstructor::StreamLevel()>0)
-         cstream<<"V0"<<
-         "Event="<<eventNr<<
-         "vertex.="<<&vertex<<
-         "Tr0.="<<track0<<
-         "lab0="<<track0->fLab<<
-         "Helix0.="<<&helixes[i]<<     
-         "Tr1.="<<track1<<
-         "lab1="<<track1->fLab<<
-         "Helix1.="<<&helixes[j]<<
-         "pointAngle="<<pointAngle<<
-         "pointAngle2="<<pointAngle2<<
-         "dca0="<<dca[i]<<
-         "dca1="<<dca[j]<<
-         "z0="<<z0[i]<<
-         "z1="<<z0[j]<<
-         "zvertex="<<zvertex<<
-         "circular0="<<track0->fCircular<<
-         "circular1="<<track1->fCircular<<
-         "npoints="<<npoints<<
-         "radius0="<<radius[0]<<
-         "delta0="<<delta[0]<<
-         "radius1="<<radius[1]<<
-         "delta1="<<delta[1]<<
-         "radiusm="<<radiusm<<
-         "deltam="<<deltam<<
-         "sdcar0="<<sdcar[i]<<
-         "sdcar1="<<sdcar[j]<<
-         "cdcar0="<<cdcar[i]<<
-         "cdcar1="<<cdcar[j]<<
-         "pulldcar0="<<pulldcar[i]<<
-         "pulldcar1="<<pulldcar[j]<<
-         "pulldcaz0="<<pulldcaz[i]<<
-         "pulldcaz1="<<pulldcaz[j]<<
-         "pulldca0="<<pulldca[i]<<
-         "pulldca1="<<pulldca[j]<<
-         "densb0="<<densb0<<
-         "densb1="<<densb1<<
-         "densa0="<<densa0<<
-         "densa1="<<densa1<<
-         "sigmae="<<sigmae<<
-         "\n";
+       AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
+       mtc->SetPoolID(fLastSeedID);
+       array->AddLast(mtc);
       }
+      AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
+      dtc->SetPoolID(fLastSeedID);
+      array->AddLast(dtc);
+      for (Int_t icl=0;icl<row0;icl++) {
+       if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
+      }
+      //
+      for (Int_t icl=row0;icl<158;icl++) {
+       if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
+      }
+      //
     }
-  }    
-  Float_t *quality = new Float_t[ncandidates];
-  Int_t *indexes = new Int_t[ncandidates];
-  Int_t naccepted =0;
-  for (Int_t i=0;i<ncandidates;i++){
-    quality[i]     = 0; 
-    AliESDV0MI *v0 = (AliESDV0MI*)tpcv0s->At(i);
-    quality[i]     = 1./(1.00001-v0->GetPointAngle());   //base point angle
-    // quality[i]    /= (0.5+v0->GetDist2());  
-    // quality[i]    *= v0->GetChi2After();               //density factor
-    Double_t minpulldca = TMath::Min(2.+pulldca[v0->GetIndex(0)],(2.+pulldca[v0->GetIndex(1)]) );     //pull
-    Int_t index0 = v0->GetIndex(0);
-    Int_t index1 = v0->GetIndex(1);
-    AliTPCseed * track0 = (AliTPCseed*)array->At(index0);
-    AliTPCseed * track1 = (AliTPCseed*)array->At(index1);
-    if (track0->fTPCr[0]>0.3&&track1->fTPCr[0]>0.3&&v0->GetAnglep()[2]<0.15) quality[i]+=1000000;              // gamma conversion candidate
-    if (track0->fTPCr[4]>0.9||track1->fTPCr[4]>0.9&&minpulldca>4) quality[i]*=10;    // lambda candidate candidate
-  }
-
-  TMath::Sort(ncandidates,quality,indexes,kTRUE);
-  //
-  //
-  for (Int_t i=0;i<ncandidates;i++){
-    AliESDV0MI * v0 = (AliESDV0MI*)tpcv0s->At(indexes[i]);
-    if (!v0) continue;
-    Int_t index0 = v0->GetIndex(0);
-    Int_t index1 = v0->GetIndex(1);
-    AliTPCseed * track0 = (AliTPCseed*)array->At(index0);
-    AliTPCseed * track1 = (AliTPCseed*)array->At(index1);
-    if (!track0||!track1) {
-      printf("Bug\n");
-      continue;
-    }
-    Bool_t accept =kTRUE;  //default accept
-    Int_t *v0indexes0 = track0->GetV0Indexes();
-    Int_t *v0indexes1 = track1->GetV0Indexes();
-    //
-    Int_t order0 = (v0indexes0[0]!=0) ? 1:0;
-    Int_t order1 = (v0indexes1[0]!=0) ? 1:0;    
-    if (v0indexes0[1]!=0) order0 =2;
-    if (v0indexes1[1]!=0) order1 =2;      
-    //
-    if (v0indexes0[2]!=0) {order0=3; accept=kFALSE;}
-    if (v0indexes0[2]!=0) {order1=3; accept=kFALSE;}
-    //
-    AliESDV0MI * v02 = v0;
-    if (accept){
-      v0->SetOrder(0,order0);
-      v0->SetOrder(1,order1);
-      v0->SetOrder(1,order0+order1);     
-      Int_t index = esd->AddV0MI(v0);
-      v02 = esd->GetV0MI(index);
-      v0indexes0[order0]=index;
-      v0indexes1[order1]=index;
-      naccepted++;
-    }
-    {
-      Int_t eventNr = esd->GetEventNumber();
-      if (AliTPCReconstructor::StreamLevel()>0)
-       cstream<<"V02"<<
-       "Event="<<eventNr<<
-       "vertex.="<<v0<<        
-       "vertex2.="<<v02<<
-       "Tr0.="<<track0<<
-       "lab0="<<track0->fLab<<
-       "Tr1.="<<track1<<
-       "lab1="<<track1->fLab<<
-       "dca0="<<dca[index0]<<
-       "dca1="<<dca[index1]<<
-       "order0="<<order0<<
-       "order1="<<order1<<
-       "accept="<<accept<<
-       "quality="<<quality[i]<<
-       "pulldca0="<<pulldca[index0]<<
-       "pulldca1="<<pulldca[index1]<<
-       "index="<<i<<
-       "\n";
-    }
-  }    
-
+    MarkSeedFree( pmother );
+    MarkSeedFree( pdaughter );
+    delete pkink;
+  }
 
+  delete [] daughters;
+  delete [] mothers;
   //
   //
+  delete [] dca;
+  delete []circular;
+  delete []shared;
   delete []quality;
   delete []indexes;
-//
-  delete [] isPrim;
-  delete [] pulldca;
-  delete [] pulldcaz;
-  delete [] pulldcar;
-  delete [] cdcar;
-  delete [] sdcar;
-  delete [] dca;
   //
+  delete kink;
+  delete[]fim;
+  delete[] zm;
   delete[] z0;
+  delete [] usage;
   delete[] alpha;
+  delete[] nclusters;
   delete[] sign;
   delete[] helixes;
-  printf("TPC V0 finder : naccepted\t%d\tncandidates\t%d\tntracks\t%d\tnall\t%d\n",naccepted,ncandidates,ntracks,nall);
+  kinks->Delete();
+  delete kinks;
+
+  AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
   timer.Print();
 }
+*/
 
-Int_t AliTPCtrackerMI::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, AliESDkink &kink)
+Int_t AliTPCtrackerMI::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
 {
   //
   // refit kink towards to the vertex
   //
   //
+  AliKink &kink=(AliKink &)knk;
+
   Int_t row0 = GetRowNumber(kink.GetR());
   FollowProlongation(mother,0);
   mother.Reset(kFALSE);
@@ -5033,7 +6269,7 @@ Int_t AliTPCtrackerMI::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, AliES
   const Int_t kNdiv =5;
   AliTPCseed  param0[kNdiv];  // parameters along the track
   AliTPCseed  param1[kNdiv];  // parameters along the track
-  AliESDkink   kinks[kNdiv];   // corresponding kink parameters
+  AliKink     kinks[kNdiv];   // corresponding kink parameters
   //
   Int_t rows[kNdiv];
   for (Int_t irow=0; irow<kNdiv;irow++){
@@ -5044,13 +6280,13 @@ Int_t AliTPCtrackerMI::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, AliES
   for (Int_t irow=0;irow<kNdiv;irow++){
     FollowBackProlongation(mother, rows[irow]);
     FollowProlongation(daughter,rows[kNdiv-1-irow]);       
-    new(&param0[irow])     AliTPCseed(mother);
-    new(&param1[kNdiv-1-irow])   AliTPCseed(daughter);
+    param0[irow] = mother;
+    param1[kNdiv-1-irow] = daughter;
   }
   //
   // define kinks 
   for (Int_t irow=0; irow<kNdiv-1;irow++){
-    if (param0[irow].fN<kNdiv||param1[irow].fN<kNdiv) continue;
+    if (param0[irow].GetNumberOfClusters()<kNdiv||param1[irow].GetNumberOfClusters()<kNdiv) continue;
     kinks[irow].SetMother(param0[irow]);
     kinks[irow].SetDaughter(param1[irow]);
     kinks[irow].Update();
@@ -5060,12 +6296,12 @@ Int_t AliTPCtrackerMI::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, AliES
   Int_t index =-1;
   Double_t mindist = 10000;
   for (Int_t irow=0;irow<kNdiv;irow++){
-    if (param0[irow].fN<20||param1[irow].fN<20) continue;
+    if (param0[irow].GetNumberOfClusters()<20||param1[irow].GetNumberOfClusters()<20) continue;
     if (TMath::Abs(kinks[irow].GetR())>240.) continue;
     if (TMath::Abs(kinks[irow].GetR())<100.) continue;
     //
-    Float_t normdist = TMath::Abs(param0[irow].fX-kinks[irow].GetR())*(0.1+kink.GetDistance());
-    normdist/= (param0[irow].fN+param1[irow].fN+40.);
+    Float_t normdist = TMath::Abs(param0[irow].GetX()-kinks[irow].GetR())*(0.1+kink.GetDistance());
+    normdist/= (param0[irow].GetNumberOfClusters()+param1[irow].GetNumberOfClusters()+40.);
     if (normdist < mindist){
       mindist = normdist;
       index = irow;
@@ -5078,15 +6314,15 @@ Int_t AliTPCtrackerMI::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, AliES
   param0[index].Reset(kTRUE);
   FollowProlongation(param0[index],0);
   //
-  new (&mother) AliTPCseed(param0[index]);
-  new (&daughter) AliTPCseed(param1[index]);  // daughter in vertex
+  mother = param0[index];
+  daughter = param1[index];  // daughter in vertex
   //
   kink.SetMother(mother);
   kink.SetDaughter(daughter);
   kink.Update();
   kink.SetTPCRow0(GetRowNumber(kink.GetR()));
-  kink.SetTPCncls(param0[index].fN,0);
-  kink.SetTPCncls(param1[index].fN,1);
+  kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
+  kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
   kink.SetLabel(CookLabel(&mother,0.4, 0,kink.GetTPCRow0()),0);
   kink.SetLabel(CookLabel(&daughter,0.4, kink.GetTPCRow0(),160),1);
   mother.SetLabel(kink.GetLabel(0));
@@ -5106,10 +6342,8 @@ void AliTPCtrackerMI::UpdateKinkQualityM(AliTPCseed * seed){
     if (index>=0) break;
     index = TMath::Abs(index)-1;
     AliESDkink * kink = fEvent->GetKink(index);
-    //kink->fTPCdensity2[0][0]=-1;
-    //kink->fTPCdensity2[0][1]=-1;
-    kink->SetTPCDensity2(-1,0,0);
-    kink->SetTPCDensity2(1,0,1);
+    kink->SetTPCDensity(-1,0,0);
+    kink->SetTPCDensity(1,0,1);
     //
     Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
     if (row0<15) row0=15;
@@ -5119,9 +6353,9 @@ void AliTPCtrackerMI::UpdateKinkQualityM(AliTPCseed * seed){
     //
     Int_t found,foundable,shared;
     seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
-    if (foundable>5)   kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),0,0);
+    if (foundable>5)   kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,0);
     seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
-    if (foundable>5)   kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),0,1);
+    if (foundable>5)   kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,1);
   }
     
 }
@@ -5136,8 +6370,8 @@ void AliTPCtrackerMI::UpdateKinkQualityD(AliTPCseed * seed){
     if (index<=0) break;
     index = TMath::Abs(index)-1;
     AliESDkink * kink = fEvent->GetKink(index);
-    kink->SetTPCDensity2(-1,1,0);
-    kink->SetTPCDensity2(-1,1,1);
+    kink->SetTPCDensity(-1,1,0);
+    kink->SetTPCDensity(-1,1,1);
     //
     Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
     if (row0<15) row0=15;
@@ -5147,15 +6381,15 @@ void AliTPCtrackerMI::UpdateKinkQualityD(AliTPCseed * seed){
     //
     Int_t found,foundable,shared;
     seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
-    if (foundable>5)   kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),1,0);
+    if (foundable>5)   kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,0);
     seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
-    if (foundable>5)   kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),1,1);
+    if (foundable>5)   kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,1);
   }
     
 }
 
 
-Int_t  AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, AliESDkink &kink)
+Int_t  AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
 {
   //
   // check kink point for given track
@@ -5163,28 +6397,30 @@ Int_t  AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTP
   // otherwise seed0 correspond to mother particle
   //           seed1 correspond to daughter particle
   //           kink  parameter of kink point
+  AliKink &kink=(AliKink &)knk;
 
-  Int_t middlerow = (seed->fFirstPoint+seed->fLastPoint)/2;
-  Int_t first = seed->fFirstPoint
-  Int_t last  = seed->fLastPoint;
+  Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
+  Int_t first = seed->GetFirstPoint()
+  Int_t last  = seed->GetLastPoint();
   if (last-first<20) return 0;          // shortest length - 2*30 = 60 pad-rows
 
   
   AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE);  //middle of chamber
   if (!seed1) return 0;
-  FollowProlongation(*seed1,seed->fLastPoint-20);
+  FollowProlongation(*seed1,seed->GetLastPoint()-20);
   seed1->Reset(kTRUE);
   FollowProlongation(*seed1,158);
   seed1->Reset(kTRUE);  
-  last = seed1->fLastPoint;
+  last = seed1->GetLastPoint();
   //
-  AliTPCseed *seed0 = new AliTPCseed(*seed);
+  AliTPCseed *seed0 = new( NextFreeSeed() ) AliTPCseed(*seed);
+  seed0->SetPoolID(fLastSeedID);
   seed0->Reset(kFALSE);
   seed0->Reset();
   //
   AliTPCseed  param0[20];  // parameters along the track
   AliTPCseed  param1[20];  // parameters along the track
-  AliESDkink            kinks[20];   // corresponding kink parameters
+  AliKink     kinks[20];   // corresponding kink parameters
   Int_t rows[20];
   for (Int_t irow=0; irow<20;irow++){
     rows[irow] = first +((last-first)*irow)/19;
@@ -5194,8 +6430,8 @@ Int_t  AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTP
   for (Int_t irow=0;irow<20;irow++){
     FollowBackProlongation(*seed0, rows[irow]);
     FollowProlongation(*seed1,rows[19-irow]);       
-    new(&param0[irow])     AliTPCseed(*seed0);
-    new(&param1[19-irow])   AliTPCseed(*seed1);
+    param0[irow] = *seed0;
+    param1[19-irow] = *seed1;
   }
   //
   // define kinks 
@@ -5211,31 +6447,33 @@ Int_t  AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTP
   for (Int_t irow=1;irow<19;irow++){
     if (TMath::Abs(kinks[irow].GetR())>240.) continue;
     if (TMath::Abs(kinks[irow].GetR())<110.) continue;
-    Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].fX));
+    Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
     if ( quality > maxchange){
       maxchange = quality;
       index = irow;
       //
     }
   }
-  delete seed0;
-  delete seed1;
+  MarkSeedFree( seed0 );
+  MarkSeedFree( seed1 );
   if (index<0) return 0;
   //
   Int_t row0    = GetRowNumber(kinks[index].GetR());   //row 0 estimate
-  seed0 = new AliTPCseed(param0[index]);
-  seed1 = new AliTPCseed(param1[index]);
+  seed0 = new( NextFreeSeed() ) AliTPCseed(param0[index]);
+  seed0->SetPoolID(fLastSeedID);
+  seed1 = new( NextFreeSeed() ) AliTPCseed(param1[index]);
+  seed1->SetPoolID(fLastSeedID);
   seed0->Reset(kFALSE);
   seed1->Reset(kFALSE);
-  seed0->ResetCovariance();
-  seed1->ResetCovariance();
+  seed0->ResetCovariance(10.);
+  seed1->ResetCovariance(10.);
   FollowProlongation(*seed0,0);
   FollowBackProlongation(*seed1,158);
-  new (&mother) AliTPCseed(*seed0);  // backup mother at position 0
+  mother = *seed0; // backup mother at position 0
   seed0->Reset(kFALSE);  
   seed1->Reset(kFALSE);
-  seed0->ResetCovariance();
-  seed1->ResetCovariance();
+  seed0->ResetCovariance(10.);
+  seed1->ResetCovariance(10.);
   //
   first = TMath::Max(row0-20,0);
   last  = TMath::Min(row0+20,158);
@@ -5248,8 +6486,8 @@ Int_t  AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTP
   for (Int_t irow=0;irow<20;irow++){
     FollowBackProlongation(*seed0, rows[irow]);
     FollowProlongation(*seed1,rows[19-irow]);       
-    new(&param0[irow])     AliTPCseed(*seed0);
-    new(&param1[19-irow])   AliTPCseed(*seed1);
+    param0[irow] = *seed0;
+    param1[19-irow] = *seed1;
   }
   //
   // define kinks 
@@ -5267,7 +6505,7 @@ Int_t  AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTP
   for (Int_t irow=0;irow<20;irow++){
     if (TMath::Abs(kinks[irow].GetR())>250.) continue;
     if (TMath::Abs(kinks[irow].GetR())<90.) continue;
-    Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].fX));
+    Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
     if ( quality > maxchange){
       maxchange = quality;
       index = irow;
@@ -5276,35 +6514,63 @@ Int_t  AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTP
   }
   //
   //
-  if (index==-1 || param0[index].fN+param1[index].fN<100){
-    delete seed0;
-    delete seed1;
+  if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
+    MarkSeedFree( seed0 );
+    MarkSeedFree( seed1 );
     return 0;
   }
+
   //  Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
   
   kink.SetMother(param0[index]);
   kink.SetDaughter(param1[index]);
   kink.Update();
+
+  Double_t chi2P2 = param0[index].GetParameter()[2]-param1[index].GetParameter()[2];
+  chi2P2*=chi2P2;
+  chi2P2/=param0[index].GetCovariance()[5]+param1[index].GetCovariance()[5];
+  Double_t chi2P3 = param0[index].GetParameter()[3]-param1[index].GetParameter()[3];
+  chi2P3*=chi2P3;
+  chi2P3/=param0[index].GetCovariance()[9]+param1[index].GetCovariance()[9];
+  //
+  if (AliTPCReconstructor::StreamLevel()>1) {
+    (*fDebugStreamer)<<"kinkHpt"<<
+      "chi2P2="<<chi2P2<<
+      "chi2P3="<<chi2P3<<
+      "p0.="<<&param0[index]<<
+      "p1.="<<&param1[index]<<
+      "k.="<<&kink<<
+      "\n";
+  }
+  if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
+    MarkSeedFree( seed0 );
+    MarkSeedFree( seed1 );
+    return 0; 
+  }
+
+
   row0    = GetRowNumber(kink.GetR());   
   kink.SetTPCRow0(row0);
   kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
   kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
   kink.SetIndex(-10,0);
-  kink.SetIndex(int(param0[index].fN+param1[index].fN),1);
-  kink.SetTPCncls(param0[index].fN,0);
-  kink.SetTPCncls(param1[index].fN,1);
+  kink.SetIndex(int(param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()),1);
+  kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
+  kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
   //
   //
   //  new (&mother) AliTPCseed(param0[index]);
-  new (&daughter) AliTPCseed(param1[index]);
+  daughter = param1[index];
   daughter.SetLabel(kink.GetLabel(1));  
   param0[index].Reset(kTRUE);
-  FollowProlongation(param0[index],0);  
-  new (&mother) AliTPCseed(param0[index]);
+  FollowProlongation(param0[index],0);    
+  mother = param0[index];
   mother.SetLabel(kink.GetLabel(0));
-  delete seed0;
-  delete seed1;
+  if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(1)){
+    mother=*seed;
+  }
+  MarkSeedFree( seed0 );
+  MarkSeedFree( seed1 );
   //
   return 1;
 }
@@ -5321,11 +6587,11 @@ AliTPCseed*  AliTPCtrackerMI::ReSeed(AliTPCseed *t)
   //  Int_t last  = fSectors->GetNRows()-1;
   //
   if (fSectors == fOuterSec){
-    first = TMath::Max(first, t->fFirstPoint-fInnerSec->GetNRows());
+    first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
     //last  = 
   }
   else
-    first = t->fFirstPoint;
+    first = t->GetFirstPoint();
   //
   AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
   FollowBackProlongation(*t,fSectors->GetNRows()-1);
@@ -5368,23 +6634,33 @@ 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()*/));
+     AliTPCseed* sdc = new( NextFreeSeed() ) AliTPCseed(*seed/*,seed->GetAlpha()*/);
+     sdc->SetPoolID(fLastSeedID);
+     fSeeds->AddLast(sdc);
   }
   
-  delete seed;
+  delete seed; // RS: this seed is not from the pool, delete it !!!
   delete seedTree; 
   savedir->cd();
   return 0;
 }
 
-Int_t AliTPCtrackerMI::Clusters2Tracks (AliESD *esd)
+Int_t AliTPCtrackerMI::Clusters2Tracks (AliESDEvent *const esd)
 {
   //
+  // clusters to tracks
   if (fSeeds) DeleteSeeds();
-  fEvent = esd;
+  else ResetSeedsPool();
+  fEvent = esd; 
+
+  AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;  
+  transform->SetCurrentTimeStamp( esd->GetTimeStamp());
+  transform->SetCurrentRun(esd->GetRunNumber());
+
   Clusters2Tracks();
   if (!fSeeds) return 1;
   FillESD(fSeeds);
+  if (AliTPCReconstructor::StreamLevel()>3)  DumpClusters(0,fSeeds);
   return 0;
   //
 }
@@ -5410,62 +6686,32 @@ Int_t AliTPCtrackerMI::Clusters2Tracks() {
     if (!pt) continue;    
     Int_t nc=t.GetNumberOfClusters();
     if (nc<20) {
-      delete fSeeds->RemoveAt(i);
+      MarkSeedFree( fSeeds->RemoveAt(i) );
       continue;
     } 
     CookLabel(pt,0.1); 
-    if (pt->fRemoval==10) {
+    if (pt->GetRemoval()==10) {
       if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
-       pt->Desactivate(10);  // make track again active
+       pt->Desactivate(10);  // make track again active  // MvL: should be 0 ?
       else{
        pt->Desactivate(20);    
-       delete fSeeds->RemoveAt(i);
+       MarkSeedFree( fSeeds->RemoveAt(i) );
       }
     } 
   }
   //
   RemoveUsed2(fSeeds,0.85,0.85,0);
-  FindKinks(fSeeds,fEvent);
+  if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
+  //FindCurling(fSeeds, fEvent,0);  
+  if (AliTPCReconstructor::StreamLevel()>5)  FindMultiMC(fSeeds, fEvent,-1); // find multi found tracks
   RemoveUsed2(fSeeds,0.5,0.4,20);
+  FindSplitted(fSeeds, fEvent,0); // find multi found tracks
+  if (AliTPCReconstructor::StreamLevel()>5)  FindMultiMC(fSeeds, fEvent,0); // find multi found tracks
+
  //  //
 //   // refit short tracks
 //   //
   Int_t nseed=fSeeds->GetEntriesFast();
-//   for (Int_t i=0; i<nseed; i++) {
-//     AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;    
-//     if (!pt) continue;    
-//     Int_t nc=t.GetNumberOfClusters();
-//     if (nc<15) {
-//       delete fSeeds->RemoveAt(i);
-//       continue;
-//     }
-//     if (pt->GetKinkIndexes()[0]!=0) continue; // ignore kink candidates
-//     if (nc>100) continue;                     // hopefully, enough for ITS
-//     AliTPCseed *seed2 = new AliTPCseed(*pt);
-//     //seed2->Reset(kFALSE);
-//     //pt->ResetCovariance();
-//     seed2->Modify(1);
-//     FollowBackProlongation(*seed2,158);
-//     //seed2->Reset(kFALSE);
-//     seed2->Modify(10);
-//     FollowProlongation(*seed2,0);
-//     TTreeSRedirector &cstream = *fDebugStreamer;
-//     cstream<<"Crefit"<<
-//       "Tr0.="<<pt<<
-//       "Tr1.="<<seed2<<
-//       "\n";     
-//     if (seed2->fN>pt->fN){
-//       delete fSeeds->RemoveAt(i);
-//       fSeeds->AddAt(seed2,i);
-//     }else{
-//       delete seed2;
-//     }
-//   }
-//   RemoveUsed2(fSeeds,0.6,0.6,50);
-
-//  FindV0s(fSeeds,fEvent);  
-  //RemoveDouble(fSeeds,0.2,0.6,11);
-
   //
   Int_t found = 0;
   for (Int_t i=0; i<nseed; i++) {
@@ -5473,18 +6719,18 @@ Int_t AliTPCtrackerMI::Clusters2Tracks() {
     if (!pt) continue;    
     Int_t nc=t.GetNumberOfClusters();
     if (nc<15) {
-      delete fSeeds->RemoveAt(i);
+      MarkSeedFree( fSeeds->RemoveAt(i) );
       continue;
     }
     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) )){
+    if ((pt->IsActive() || (pt->GetRemoval()==10) )){
       found++;      
       if (fDebug>0) cerr<<found<<'\r';      
-      pt->fLab2 = i;
+      pt->SetLab2(i);
     }
     else
-      delete fSeeds->RemoveAt(i);
+      MarkSeedFree( fSeeds->RemoveAt(i) );
   }
 
   
@@ -5499,22 +6745,22 @@ Int_t AliTPCtrackerMI::Clusters2Tracks() {
     if (!pt) continue;    
     Int_t nc=t.GetNumberOfClusters();
     if (nc<15) {
-      delete fSeeds->RemoveAt(i);
+      MarkSeedFree( fSeeds->RemoveAt(i) );
       continue;
     }
     t.SetUniqueID(i);
     t.CookdEdx(0.02,0.6);
     //    CheckKinkPoint(&t,0.05);
     //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
-    if ((pt->IsActive() || (pt->fRemoval==10) )){
+    if ((pt->IsActive() || (pt->GetRemoval()==10) )){
       found++;
       if (fDebug>0){
        cerr<<found<<'\r';      
       }
-      pt->fLab2 = i;
+      pt->SetLab2(i);
     }
     else
-      delete fSeeds->RemoveAt(i);
+      MarkSeedFree( fSeeds->RemoveAt(i) );
     //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
     //if (seed1){
     //  FollowProlongation(*seed1,0);
@@ -5538,7 +6784,7 @@ Int_t AliTPCtrackerMI::Clusters2Tracks() {
   fIteration = 2;
   
   PrepareForProlongation(fSeeds,5.);
-  PropagateForward2(fSeeds);
+  PropagateForard2(fSeeds);
    
   printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
   // RemoveUsed(fSeeds,0.7,0.7,6);
@@ -5551,7 +6797,7 @@ Int_t AliTPCtrackerMI::Clusters2Tracks() {
     if (!pt) continue;    
     Int_t nc=t.GetNumberOfClusters();
     if (nc<15) {
-      delete fSeeds->RemoveAt(i);
+      MarkSeedFree( fSeeds->RemoveAt(i) );
       continue;
     }
     t.CookdEdx(0.02,0.6);
@@ -5561,7 +6807,7 @@ Int_t AliTPCtrackerMI::Clusters2Tracks() {
       cerr<<found++<<'\r';      
     }
     else
-      delete fSeeds->RemoveAt(i);
+      MarkSeedFree( fSeeds->RemoveAt(i) );
     pt->fLab2 = i;
   }
   */
@@ -5596,7 +6842,8 @@ TObjArray * AliTPCtrackerMI::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_
   //
   //
   //tracking routine
-  TObjArray * arr = new TObjArray;
+  static TObjArray arrTracks;
+  TObjArray * arr = &arrTracks;
   // 
   fSectors = fOuterSec;
   TStopwatch timer;
@@ -5621,14 +6868,18 @@ TObjArray * AliTPCtrackerMI::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_
 
 TObjArray * AliTPCtrackerMI::Tracking()
 {
+  // tracking
   //
-  //
+  if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
   TStopwatch timer;
   timer.Start();
   Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
 
   TObjArray * seeds = new TObjArray;
   TObjArray * arr=0;
+  Int_t fLastSeedRowSec=AliTPCReconstructor::GetRecoParam()->GetLastSeedRowSec();
+  Int_t gapPrim = AliTPCReconstructor::GetRecoParam()->GetSeedGapPrim();
+  Int_t gapSec = AliTPCReconstructor::GetRecoParam()->GetSeedGapSec();
   
   Int_t gap =20;
   Float_t cuts[4];
@@ -5642,7 +6893,7 @@ TObjArray * AliTPCtrackerMI::Tracking()
   //  
   //find primaries  
   cuts[0]=0.0066;
-  for (Int_t delta = 0; delta<18; delta+=6){
+  for (Int_t delta = 0; delta<18; delta+=gapPrim){
     //
     cuts[0]=0.0070;
     cuts[1] = 1.5;
@@ -5667,7 +6918,7 @@ TObjArray * AliTPCtrackerMI::Tracking()
 
   //find primaries  
   cuts[0]=0.0077;
-  for (Int_t delta = 20; delta<120; delta+=10){
+  for (Int_t delta = 20; delta<120; delta+=gapPrim){
     //
     // seed high pt tracks
     cuts[0]=0.0060;
@@ -5720,9 +6971,22 @@ TObjArray * AliTPCtrackerMI::Tracking()
   SumTracks(seeds,arr);   
   SignClusters(seeds,fnumber,fdensity);   
   //
+  arr = Tracking(4,nup-5,nup-5-gap,cuts,-1);
+  SumTracks(seeds,arr);   
+  SignClusters(seeds,fnumber,fdensity);   
+  //
+  arr = Tracking(4,nup-7,nup-7-gap,cuts,-1);
+  SumTracks(seeds,arr);   
+  SignClusters(seeds,fnumber,fdensity);   
+  //
+  //
+  arr = Tracking(4,nup-9,nup-9-gap,cuts,-1);
+  SumTracks(seeds,arr);   
+  SignClusters(seeds,fnumber,fdensity);   
+  //
 
 
-  for (Int_t delta = 3; delta<30; delta+=5){
+  for (Int_t delta = 9; delta<30; delta+=gapSec){
     //
     cuts[0] = 0.3;
     cuts[1] = 1.5;
@@ -5745,8 +7009,9 @@ TObjArray * AliTPCtrackerMI::Tracking()
   fdensity = 2.;
   cuts[0]=0.0080;
 
+
   // find secondaries
-  for (Int_t delta = 30; delta<90; delta+=10){
+  for (Int_t delta = 30; delta<fLastSeedRowSec; delta+=gapSec){
     //
     cuts[0] = 0.3;
     cuts[1] = 3.5;
@@ -5773,18 +7038,69 @@ TObjArray * AliTPCtrackerMI::Tracking()
 }
 
 
-void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *arr2) const
+TObjArray * AliTPCtrackerMI::TrackingSpecial()
+{
+  //
+  // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
+  // no primary vertex seeding tried
+  //
+  TStopwatch timer;
+  timer.Start();
+  Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
+
+  TObjArray * seeds = new TObjArray;
+  TObjArray * arr=0;
+  
+  Int_t   gap  = 15;
+  Float_t cuts[4];
+  Float_t fnumber  = 3.0;
+  Float_t fdensity = 3.0;
+  
+  // find secondaries
+  cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC();   // max curvature
+  cuts[1] = 3.5;    // max tan(phi) angle for seeding
+  cuts[2] = 3.;     // not used (cut on z primary vertex)     
+  cuts[3] = 3.5;    // max tan(theta) angle for seeding
+
+  for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
+    //
+    arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
+    SumTracks(seeds,arr);   
+    SignClusters(seeds,fnumber,fdensity);   
+  } 
+  if (fDebug>0){
+    Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
+    timer.Print();
+    timer.Start();
+  }
+
+  return seeds;
+  //
+      
+}
+
+
+void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *&arr2)
 {
   //
   //sum tracks to common container
   //remove suspicious tracks
+  // RS: Attention: supplied tracks come in the static array, don't delete them
   Int_t nseed = arr2->GetEntriesFast();
   for (Int_t i=0;i<nseed;i++){
     AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);    
     if (pt){
+      //
+      // remove tracks with too big curvature
+      //
+      if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
+       MarkSeedFree( arr2->RemoveAt(i) );
+       continue;
+      }
        // REMOVE VERY SHORT  TRACKS
       if (pt->GetNumberOfClusters()<20){ 
-       delete arr2->RemoveAt(i);
+       MarkSeedFree( arr2->RemoveAt(i) );
        continue;
       }// patch 28 fev06
       // NORMAL ACTIVE TRACK
@@ -5793,8 +7109,8 @@ void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *arr2) const
        continue;
       }
       //remove not usable tracks
-      if (pt->fRemoval!=10){
-       delete arr2->RemoveAt(i);
+      if (pt->GetRemoval()!=10){
+       MarkSeedFree( arr2->RemoveAt(i) );
        continue;
       }
      
@@ -5802,16 +7118,16 @@ void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *arr2) const
       if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
        arr1->AddLast(arr2->RemoveAt(i));
       else{      
-       delete arr2->RemoveAt(i);
+       MarkSeedFree( arr2->RemoveAt(i) );
       }
     }
   }
-  delete arr2;  
+  // delete arr2;  arr2 = 0; // RS: this is static array, don't delete it
 }
 
 
 
-void  AliTPCtrackerMI::ParallelTracking(TObjArray * arr, Int_t rfirst, Int_t rlast)
+void  AliTPCtrackerMI::ParallelTracking(TObjArray *const arr, Int_t rfirst, Int_t rlast)
 {
   //
   // try to track in parralel
@@ -5823,7 +7139,7 @@ void  AliTPCtrackerMI::ParallelTracking(TObjArray * arr, Int_t rfirst, Int_t rla
     if (!pt) continue;
     if (!t.IsActive()) continue;
     // follow prolongation to the first layer
-    if ( (fSectors ==fInnerSec) || (t.fFirstPoint-fParam->GetNRowLow()>rfirst+1) )  
+    if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fkParam->GetNRowLow()>rfirst+1) )  
       FollowProlongation(t, rfirst+1);
   }
 
@@ -5842,8 +7158,8 @@ void  AliTPCtrackerMI::ParallelTracking(TObjArray * arr, Int_t rfirst, Int_t rla
       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) {
+      //      if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
+      if (pt->GetRelativeSector()>17) {
        continue;
       }
       UpdateClusters(t,nr);
@@ -5853,8 +7169,8 @@ void  AliTPCtrackerMI::ParallelTracking(TObjArray * arr, Int_t rfirst, Int_t rla
       AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i); 
       if (!pt) continue;
       if (!pt->IsActive()) continue; 
-      // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fParam->GetNRowLow())<nr) continue;
-      if (pt->fRelativeSector>17) {
+      // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
+      if (pt->GetRelativeSector()>17) {
        continue;
       }
       FollowToNextCluster(*pt,nr);
@@ -5862,7 +7178,7 @@ void  AliTPCtrackerMI::ParallelTracking(TObjArray * arr, Int_t rfirst, Int_t rla
   }    
 }
 
-void AliTPCtrackerMI::PrepareForBackProlongation(TObjArray * arr,Float_t fac) const
+void AliTPCtrackerMI::PrepareForBackProlongation(const TObjArray *const arr,Float_t fac) const
 {
   //
   //
@@ -5875,7 +7191,7 @@ void AliTPCtrackerMI::PrepareForBackProlongation(TObjArray * arr,Float_t fac) co
       pt->Modify(fac);
       //
       //rotate to current local system at first accepted  point    
-      Int_t index  = pt->GetClusterIndex2(pt->fFirstPoint); 
+      Int_t index  = pt->GetClusterIndex2(pt->GetFirstPoint()); 
       Int_t sec    = (index&0xff000000)>>24;
       sec = sec%18;
       Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
@@ -5884,7 +7200,7 @@ void AliTPCtrackerMI::PrepareForBackProlongation(TObjArray * arr,Float_t fac) co
       Float_t angle2 = pt->GetAlpha();
       
       if (TMath::Abs(angle1-angle2)>0.001){
-       pt->Rotate(angle1-angle2);
+       if (!pt->Rotate(angle1-angle2)) return;
        //angle2 = pt->GetAlpha();
        //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
        //if (pt->GetAlpha()<0) 
@@ -5898,7 +7214,7 @@ void AliTPCtrackerMI::PrepareForBackProlongation(TObjArray * arr,Float_t fac) co
 
 
 }
-void AliTPCtrackerMI::PrepareForProlongation(TObjArray * arr, Float_t fac) const
+void AliTPCtrackerMI::PrepareForProlongation(TObjArray *const arr, Float_t fac) const
 {
   //
   //
@@ -5909,7 +7225,7 @@ void AliTPCtrackerMI::PrepareForProlongation(TObjArray * arr, Float_t fac) const
     AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
     if (pt) {
       pt->Modify(fac);
-      pt->fFirstPoint = pt->fLastPoint
+      pt->SetFirstPoint(pt->GetLastPoint())
     }
     
   }
@@ -5917,7 +7233,7 @@ void AliTPCtrackerMI::PrepareForProlongation(TObjArray * arr, Float_t fac) const
 
 }
 
-Int_t AliTPCtrackerMI::PropagateBack(TObjArray * arr)
+Int_t AliTPCtrackerMI::PropagateBack(const TObjArray *const arr)
 {
   //
   // make back propagation
@@ -5930,7 +7246,7 @@ Int_t AliTPCtrackerMI::PropagateBack(TObjArray * arr)
       fSectors = fInnerSec;
       //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
       //fSectors = fOuterSec;
-      FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);     
+      FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);     
       //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
       //       Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
       //       FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
@@ -5938,17 +7254,17 @@ Int_t AliTPCtrackerMI::PropagateBack(TObjArray * arr)
     }
     if (pt&& pt->GetKinkIndex(0)>0) {
       AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
-      pt->fFirstPoint = kink->GetTPCRow0();
+      pt->SetFirstPoint(kink->GetTPCRow0());
       fSectors = fInnerSec;
-      FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);  
+      FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);  
     }
-    
+    CookLabel(pt,0.3);
   }
   return 0;
 }
 
 
-Int_t AliTPCtrackerMI::PropagateForward2(TObjArray * arr)
+Int_t AliTPCtrackerMI::PropagateForward2(const TObjArray *const arr)
 {
   //
   // make forward propagation
@@ -5958,10 +7274,12 @@ Int_t AliTPCtrackerMI::PropagateForward2(TObjArray * arr)
   for (Int_t i=0;i<nseed;i++){
     AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
     if (pt) { 
-      FollowProlongation(*pt,0);
+      FollowProlongation(*pt,0,1,1);
+      CookLabel(pt,0.3);
     }
+    
   }
 return 0;
+ return 0;
 }
 
 
@@ -5978,7 +7296,7 @@ Int_t AliTPCtrackerMI::PropagateForward()
       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;
+      t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
     }
   }
   
@@ -5986,7 +7304,6 @@ Int_t AliTPCtrackerMI::PropagateForward()
   ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
   fSectors = fInnerSec;
   ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
-  //WriteTracks();
   return 1;
 }
 
@@ -5995,7 +7312,7 @@ Int_t AliTPCtrackerMI::PropagateForward()
 
 
 
-Int_t AliTPCtrackerMI::PropagateBack(AliTPCseed * pt, Int_t row0, Int_t row1)
+Int_t AliTPCtrackerMI::PropagateBack(AliTPCseed *const pt, Int_t row0, Int_t row1)
 {
   //
   // make back propagation, in between row0 and row1
@@ -6029,20 +7346,33 @@ Int_t AliTPCtrackerMI::PropagateBack(AliTPCseed * pt, Int_t row0, Int_t row1)
 
 void  AliTPCtrackerMI::GetShape(AliTPCseed * seed, Int_t row)
 {
-  //
-  //
-  Float_t sd2 = TMath::Abs((fParam->GetZLength()-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
-  //  Float_t padlength =  fParam->GetPadPitchLength(seed->fSector);
-  Float_t padlength =  GetPadPitchLength(row);
-  //
-  Float_t sresy = (seed->fSector < fParam->GetNSector()/2) ? 0.2 :0.3;
+  // gets cluster shape
+  // 
+  AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
+  Float_t zdrift = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())));
+  Int_t type = (seed->GetSector() < fkParam->GetNSector()/2) ? 0: (row>126) ? 1:2;
   Double_t angulary  = seed->GetSnp();
-  angulary = angulary*angulary/(1-angulary*angulary);
-  seed->fCurrentSigmaY2 = sd2+padlength*padlength*angulary/12.+sresy*sresy;  
-  //
-  Float_t sresz = fParam->GetZSigma();
-  Float_t angularz  = seed->GetTgl();
-  seed->fCurrentSigmaZ2 = sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz;
+
+  if (TMath::Abs(angulary)>AliTPCReconstructor::GetMaxSnpTracker()) {
+    angulary = TMath::Sign(AliTPCReconstructor::GetMaxSnpTracker(),angulary);
+  }
+
+  angulary = angulary*angulary/((1.-angulary)*(1.+angulary));
+  Double_t angularz  = seed->GetTgl()*seed->GetTgl()*(1.+angulary);
+  
+  Double_t sigmay =  clparam->GetRMS0(0,type,zdrift,TMath::Sqrt(TMath::Abs(angulary)));
+  Double_t sigmaz =  clparam->GetRMS0(1,type,zdrift,TMath::Sqrt(TMath::Abs(angularz)));
+  seed->SetCurrentSigmaY2(sigmay*sigmay);
+  seed->SetCurrentSigmaZ2(sigmaz*sigmaz);
+  // Float_t sd2 = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fkParam->GetDiffL()*fkParam->GetDiffL();
+//   //  Float_t padlength =  fkParam->GetPadPitchLength(seed->fSector);
+//   Float_t padlength =  GetPadPitchLength(row);
+//   //
+//   Float_t sresy = (seed->GetSector() < fkParam->GetNSector()/2) ? 0.2 :0.3;
+//   seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);  
+//   //
+//   Float_t sresz = fkParam->GetZSigma();
+//   seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
   /*
   Float_t wy = GetSigmaY(seed);
   Float_t wz = GetSigmaZ(seed);
@@ -6055,39 +7385,18 @@ void  AliTPCtrackerMI::GetShape(AliTPCseed * seed, Int_t row)
 }
 
 
-Float_t  AliTPCtrackerMI::GetSigmaY(AliTPCseed * seed)
-{
-  //
-  //  
-  Float_t sd2 = TMath::Abs((fParam->GetZLength()-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
-  Float_t padlength =  fParam->GetPadPitchLength(seed->fSector);
-  Float_t sres = (seed->fSector < fParam->GetNSector()/2) ? 0.2 :0.3;
-  Float_t angular  = seed->GetSnp();
-  angular = angular*angular/(1-angular*angular);
-  //  angular*=angular;
-  //angular  = TMath::Sqrt(angular/(1-angular));
-  Float_t res = TMath::Sqrt(sd2+padlength*padlength*angular/12.+sres*sres);
-  return res;
-}
-Float_t  AliTPCtrackerMI::GetSigmaZ(AliTPCseed * seed)
-{
-  //
-  //
-  Float_t sd2 = TMath::Abs((fParam->GetZLength()-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
-  Float_t padlength =  fParam->GetPadPitchLength(seed->fSector);
-  Float_t sres = fParam->GetZSigma();
-  Float_t angular  = seed->GetTgl();
-  Float_t res = TMath::Sqrt(sd2+padlength*padlength*angular*angular/12.+sres*sres);
-  return res;
-}
-
 
 //__________________________________________________________________________
 void AliTPCtrackerMI::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
   //--------------------------------------------------------------------
   //This function "cooks" a track label. If label<0, this track is fake.
   //--------------------------------------------------------------------
-  AliTPCseed * t = (AliTPCseed*)tk;
+  AliTPCseed * t = dynamic_cast<AliTPCseed*>(tk);
+  if(!t){
+    printf("%s:%d wrong type \n",(char*)__FILE__,__LINE__);
+    return;
+  }
+
   Int_t noc=t->GetNumberOfClusters();
   if (noc<10){
     //printf("\nnot founded prolongation\n\n\n");
@@ -6112,8 +7421,8 @@ void AliTPCtrackerMI::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
      if (index&0x8000) continue;
      //     
      //clusters[current]=GetClusterMI(index);
-     if (t->fClusterPointer[i]){
-       clusters[current]=t->fClusterPointer[i];     
+     if (t->GetClusterPointer(i)){
+       clusters[current]=t->GetClusterPointer(i);     
        current++;
      }
   }
@@ -6139,14 +7448,14 @@ void AliTPCtrackerMI::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
     if (TMath::Abs(c->GetLabel(1)) == lab ||
         TMath::Abs(c->GetLabel(2)) == lab ) max++;
   }
-
-  if ((1.- Float_t(max)/noc) > wrong) lab=-lab;
+  if (noc<=0) { lab=-1; return;}
+  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++) {
+     for (i=1; i<160&&ind<tail; i++) {
        //       AliTPCclusterMI *c=clusters[noc-i];
        AliTPCclusterMI *c=clusters[i];
        if (!c) continue;
@@ -6167,7 +7476,7 @@ void AliTPCtrackerMI::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
 
 
 //__________________________________________________________________________
-Int_t AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong,Int_t first, Int_t last) const {
+Int_t AliTPCtrackerMI::CookLabel(AliTPCseed *const t, Float_t wrong,Int_t first, Int_t last) const {
   //--------------------------------------------------------------------
   //This function "cooks" a track label. If label<0, this track is fake.
   //--------------------------------------------------------------------
@@ -6196,13 +7505,13 @@ Int_t AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong,Int_t first, Int_t
      if (index&0x8000) continue;
      //     
      //clusters[current]=GetClusterMI(index);
-     if (t->fClusterPointer[i]){
-       clusters[current]=t->fClusterPointer[i];     
+     if (t->GetClusterPointer(i)){
+       clusters[current]=t->GetClusterPointer(i);     
        current++;
      }
   }
   noc = current;
-  if (noc<5) return -1;
+  //if (noc<5) return -1;
   Int_t lab=123456789;
   for (i=0; i<noc; i++) {
     AliTPCclusterMI *c=clusters[i];
@@ -6223,14 +7532,14 @@ Int_t AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong,Int_t first, Int_t
     if (TMath::Abs(c->GetLabel(1)) == lab ||
         TMath::Abs(c->GetLabel(2)) == lab ) max++;
   }
-
-  if ((1.- Float_t(max)/noc) > wrong) lab=-lab;
+  if (noc<=0) { lab=-1; return -1;}
+  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++) {
+     for (i=1; i<160&&ind<tail; i++) {
        //       AliTPCclusterMI *c=clusters[noc-i];
        AliTPCclusterMI *c=clusters[i];
        if (!c) continue;
@@ -6250,29 +7559,6 @@ Int_t AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong,Int_t first, Int_t
 }
 
 
-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);} 
-  }
-}
-
 Int_t  AliTPCtrackerMI::GetRowNumber(Double_t x[3]) const 
 {
   //return pad row number for given x vector
@@ -6285,196 +7571,216 @@ Int_t  AliTPCtrackerMI::GetRowNumber(Double_t x[3]) const
   return GetRowNumber(localx);
 }
 
-//_________________________________________________________________________
-void AliTPCtrackerMI::AliTPCSector::Setup(const AliTPCParam *par, Int_t f) {
+
+
+void AliTPCtrackerMI::MakeESDBitmaps(AliTPCseed *t, AliESDtrack *esd)
+{
   //-----------------------------------------------------------------------
-  // Setup inner sector
+  // Fill the cluster and sharing bitmaps of the track
   //-----------------------------------------------------------------------
-  if (f==0) {
-     fAlpha=par->GetInnerAngle();
-     fAlphaShift=par->GetInnerAngleShift();
-     fPadPitchWidth=par->GetInnerPadPitchWidth();
-     fPadPitchLength=par->GetInnerPadPitchLength();
-     fN=par->GetNRowLow();
-     fRow=new AliTPCRow[fN];
-     for (Int_t i=0; i<fN; i++) {
-       fRow[i].SetX(par->GetPadRowRadiiLow(i));
-       fRow[i].fDeadZone =1.5;  //1.5 cm of dead zone
-     }
-  } else {
-     fAlpha=par->GetOuterAngle();
-     fAlphaShift=par->GetOuterAngleShift();
-     fPadPitchWidth  = par->GetOuterPadPitchWidth();
-     fPadPitchLength = par->GetOuter1PadPitchLength();
-     f1PadPitchLength = par->GetOuter1PadPitchLength();
-     f2PadPitchLength = par->GetOuter2PadPitchLength();
-
-     fN=par->GetNRowUp();
-     fRow=new AliTPCRow[fN];
-     for (Int_t i=0; i<fN; i++) {
-       fRow[i].SetX(par->GetPadRowRadiiUp(i)); 
-       fRow[i].fDeadZone =1.5;  // 1.5 cm of dead zone
-     }
-  } 
+
+  Int_t firstpoint = 0;
+  Int_t lastpoint = 159;
+  AliTPCTrackerPoint *point;
+  AliTPCclusterMI    *cluster;
+  
+  Int_t nclsf = 0;
+  TBits clusterMap(159);
+  TBits sharedMap(159);
+  TBits fitMap(159);
+  for (int iter=firstpoint; iter<lastpoint; iter++) {
+    // Change to cluster pointers to see if we have a cluster at given padrow
+
+    cluster = t->GetClusterPointer(iter);
+    if (cluster) {
+      clusterMap.SetBitNumber(iter, kTRUE);
+      point = t->GetTrackPoint(iter);
+      if (point->IsShared())
+       sharedMap.SetBitNumber(iter,kTRUE);
+    }
+    if (t->GetClusterIndex(iter) >= 0 && (t->GetClusterIndex(iter) & 0x8000) == 0) {
+      fitMap.SetBitNumber(iter, kTRUE);
+      nclsf++;
+    }
+  }
+  esd->SetTPCClusterMap(clusterMap);
+  esd->SetTPCSharedMap(sharedMap);
+  esd->SetTPCFitMap(fitMap);
+  if (nclsf != t->GetNumberOfClusters())
+    AliWarning(Form("Inconsistency between ncls %d and indices %d (found %d)",t->GetNumberOfClusters(),nclsf,esd->GetTPCClusterMap().CountBits()));
 }
 
-AliTPCtrackerMI::AliTPCRow::AliTPCRow() {
+Bool_t AliTPCtrackerMI::IsFindable(AliTPCseed & track){
   //
-  // default constructor
-  fN=0;
-  fN1=0;
-  fN2=0;
-  fClusters1=0;
-  fClusters2=0;
+  // return flag if there is findable cluster at given position
+  //
+  Float_t kDeltaZ=10;
+  Float_t z = track.GetZ();
+  
+  if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*track.GetX()+kDeltaZ) && 
+      TMath::Abs(z)<fkParam->GetZLength(0) && 
+      (TMath::Abs(track.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
+    return kTRUE;
+  return kFALSE;      
 }
 
-AliTPCtrackerMI::AliTPCRow::~AliTPCRow(){
-  //
 
+void AliTPCtrackerMI::AddCovariance(AliTPCseed * seed){
+  //
+  // Adding systematic error estimate to the covariance matrix
+  //                !!!! the systematic error for element 4 is in 1/GeV 
+  // 03.03.2012     MI changed in respect to the previous versions
+  const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
+  //
+  // use only the diagonal part if not specified otherwise
+  if (!AliTPCReconstructor::GetRecoParam()->GetUseSystematicCorrelation()) return AddCovarianceAdd(seed);
+  //
+  Double_t *covarS= (Double_t*)seed->GetCovariance();
+  Double_t factor[5]={1,1,1,1,1};
+  factor[0]= TMath::Sqrt(TMath::Abs((covarS[0] + param[0]*param[0])/covarS[0]));
+  factor[1]= TMath::Sqrt(TMath::Abs((covarS[2] + param[1]*param[1])/covarS[2]));
+  factor[2]= TMath::Sqrt(TMath::Abs((covarS[5] + param[2]*param[2])/covarS[5]));
+  factor[3]= TMath::Sqrt(TMath::Abs((covarS[9] + param[3]*param[3])/covarS[9]));
+  factor[4]= TMath::Sqrt(TMath::Abs((covarS[14] +param[4]*param[4])/covarS[14]));
+  //
+  factor[0]=factor[2];
+  factor[4]=factor[2];
+  // 0
+  // 1    2
+  // 3    4    5
+  // 6    7    8    9 
+  // 10   11   12   13   14
+  for (Int_t i=0; i<5; i++){
+    for (Int_t j=i; j<5; j++){
+      Int_t index=seed->GetIndex(i,j);
+      covarS[index]*=factor[i]*factor[j];
+    }
+  }
 }
 
 
+void AliTPCtrackerMI::AddCovarianceAdd(AliTPCseed * seed){
+  //
+  // Adding systematic error - as additive factor without correlation
+  //
+  //                !!!! the systematic error for element 4 is in 1/GeV 
+  // 03.03.2012     MI changed in respect to the previous versions
 
-//_________________________________________________________________________
-void 
-AliTPCtrackerMI::AliTPCRow::InsertCluster(const AliTPCclusterMI* c, UInt_t index) {
-  //-----------------------------------------------------------------------
-  // Insert a cluster into this pad row in accordence with its y-coordinate
-  //-----------------------------------------------------------------------
-  if (fN==kMaxClusterPerRow) {
-    cerr<<"AliTPCRow::InsertCluster(): Too many clusters !\n"; return;
-  }
-  if (fN==0) {fIndex[0]=index; fClusters[fN++]=c; return;}
-  Int_t i=Find(c->GetZ());
-  memmove(fClusters+i+1 ,fClusters+i,(fN-i)*sizeof(AliTPCclusterMI*));
-  memmove(fIndex   +i+1 ,fIndex   +i,(fN-i)*sizeof(UInt_t));
-  fIndex[i]=index; fClusters[i]=c; fN++;
+  const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
+  Double_t *covarIn= (Double_t*)seed->GetCovariance();
+  Double_t covar[15];
+  for (Int_t i=0;i<15;i++) covar[i]=0;
+  // 0
+  // 1    2
+  // 3    4    5
+  // 6    7    8    9 
+  // 10   11   12   13   14
+  covar[0] = param[0]*param[0];
+  covar[2] = param[1]*param[1];
+  covar[5] = param[2]*param[2];
+  covar[9] = param[3]*param[3];
+  covar[14]= param[4]*param[4];
+  //
+  covar[1]=TMath::Sqrt((covar[0]*covar[2]))*covarIn[1]/TMath::Sqrt((covarIn[0]*covarIn[2]));
+  //
+  covar[3]=TMath::Sqrt((covar[0]*covar[5]))*covarIn[3]/TMath::Sqrt((covarIn[0]*covarIn[5]));
+  covar[4]=TMath::Sqrt((covar[2]*covar[5]))*covarIn[4]/TMath::Sqrt((covarIn[2]*covarIn[5]));
+  //
+  covar[6]=TMath::Sqrt((covar[0]*covar[9]))*covarIn[6]/TMath::Sqrt((covarIn[0]*covarIn[9]));
+  covar[7]=TMath::Sqrt((covar[2]*covar[9]))*covarIn[7]/TMath::Sqrt((covarIn[2]*covarIn[9]));
+  covar[8]=TMath::Sqrt((covar[5]*covar[9]))*covarIn[8]/TMath::Sqrt((covarIn[5]*covarIn[9]));
+  //
+  covar[10]=TMath::Sqrt((covar[0]*covar[14]))*covarIn[10]/TMath::Sqrt((covarIn[0]*covarIn[14]));
+  covar[11]=TMath::Sqrt((covar[2]*covar[14]))*covarIn[11]/TMath::Sqrt((covarIn[2]*covarIn[14]));
+  covar[12]=TMath::Sqrt((covar[5]*covar[14]))*covarIn[12]/TMath::Sqrt((covarIn[5]*covarIn[14]));
+  covar[13]=TMath::Sqrt((covar[9]*covar[14]))*covarIn[13]/TMath::Sqrt((covarIn[9]*covarIn[14]));
+  //
+  seed->AddCovariance(covar);
 }
 
-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;
-}
+//_____________________________________________________________________________
+Bool_t  AliTPCtrackerMI::IsTPCHVDipEvent(AliESDEvent const *esdEvent) {
+//
+// check events affected by TPC HV dip
+//
+if(!esdEvent) return kFALSE;
 
+// Init TPC OCDB
+if(!AliTPCcalibDB::Instance()) return kFALSE;
+AliTPCcalibDB::Instance()->SetRun(esdEvent->GetRunNumber());
 
-//___________________________________________________________________
-Int_t AliTPCtrackerMI::AliTPCRow::Find(Double_t z) const {
-  //-----------------------------------------------------------------------
-  // Return the index of the nearest cluster 
-  //-----------------------------------------------------------------------
-  if (fN==0) return 0;
-  if (z <= fClusters[0]->GetZ()) return 0;
-  if (z > fClusters[fN-1]->GetZ()) return fN;
-  Int_t b=0, e=fN-1, m=(b+e)/2;
-  for (; b<e; m=(b+e)/2) {
-    if (z > fClusters[m]->GetZ()) b=m+1;
-    else e=m; 
-  }
-  return m;
-}
+// Get HV TPC chamber sensors and calculate the median
+AliDCSSensorArray *voltageArray= AliTPCcalibDB::Instance()->GetVoltageSensors(esdEvent->GetRunNumber());
+if(!voltageArray) return kFALSE;
 
+TString sensorName="";
+Double_t kTPCHVdip = 2.0; // allow for 2V dip as compared to median from given sensor
 
 
-//___________________________________________________________________
-AliTPCclusterMI * AliTPCtrackerMI::AliTPCRow::FindNearest(Double_t y, Double_t z, Double_t roady, Double_t roadz) const {
-  //-----------------------------------------------------------------------
-  // Return the index of the nearest cluster in z y 
-  //-----------------------------------------------------------------------
-  Float_t maxdistance = roady*roady + roadz*roadz;
+  for(Int_t sector=0; sector<72; sector++)
+  {
+    Char_t sideName='A';
+    if ((sector/18)%2==1) sideName='C';
+    if (sector<36){
+      //IROC
+      sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,sector%18);
+    } else {
+      //OROC
+      sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,sector%18);
+    }
+    
+    AliDCSSensor* sensor = voltageArray->GetSensor(sensorName.Data());
+    if(!sensor) continue;
+    TGraph *graph = sensor->GetGraph();
+    if(!graph) continue;
+    Double_t median = TMath::Median(graph->GetN(), graph->GetY());
+    if(median == 0) continue;
+
+    //printf("chamber %d, sensor %s, HV %f, median %f\n", sector, sensorName.Data(), sensor->GetValue(esdEvent->GetTimeStamp()), median);
+    
+    if(TMath::Abs(sensor->GetValue(esdEvent->GetTimeStamp())-median)>kTPCHVdip) {
+      return kTRUE; 
+    }
+  } 
+  return kFALSE; 
+} 
 
-  AliTPCclusterMI *cl =0;
-  for (Int_t i=Find(z-roadz); i<fN; i++) {
-      AliTPCclusterMI *c=(AliTPCclusterMI*)(fClusters[i]);
-      if (c->GetZ() > z+roadz) break;
-      if ( (c->GetY()-y) >  roady ) continue;
-      Float_t distance = (c->GetZ()-z)*(c->GetZ()-z)+(c->GetY()-y)*(c->GetY()-y);
-      if (maxdistance>distance) {
-       maxdistance = distance;
-       cl=c;       
-      }
+//________________________________________
+void AliTPCtrackerMI::MarkSeedFree(TObject *sd) 
+{
+  // account that this seed is "deleted" 
+  AliTPCseed* seed = dynamic_cast<AliTPCseed*>(sd);
+  if (!seed) {
+    AliError(Form("Freeing of non-AliTPCseed %p from the pool is requested",sd)); 
+    return;
+  }
+  int id = seed->GetPoolID();
+  if (id<0) {
+    AliError(Form("Freeing of seed %p NOT from the pool is requested",sd)); 
+    return;
   }
-  return cl;      
+  //  AliInfo(Form("%d %p",id, seed));
+  fSeedsPool->RemoveAt(id);
+  if (fFreeSeedsID.GetSize()<=fNFreeSeeds) fFreeSeedsID.Set( 2*fNFreeSeeds + 100 );
+  fFreeSeedsID.GetArray()[fNFreeSeeds++] = id;
 }
 
-AliTPCclusterMI * AliTPCtrackerMI::AliTPCRow::FindNearest2(Double_t y, Double_t z, Double_t roady, Double_t roadz,UInt_t & index) const 
+//________________________________________
+TObject *&AliTPCtrackerMI::NextFreeSeed()
 {
-  //-----------------------------------------------------------------------
-  // Return the index of the nearest cluster in z y 
-  //-----------------------------------------------------------------------
-  Float_t maxdistance = roady*roady + roadz*roadz;
-  AliTPCclusterMI *cl =0;
-
-  //PH Check boundaries. 510 is the size of fFastCluster
-  Int_t iz1 = Int_t(z-roadz+254.5);
-  if (iz1<0 || iz1>=510) return cl;
-  iz1 = TMath::Max(fFastCluster[iz1]-1,0);
-  Int_t iz2 = Int_t(z+roadz+255.5);
-  if (iz2<0 || iz2>=510) return cl;
-  iz2 = TMath::Min(fFastCluster[iz2]+1,fN);
-
-  //FindNearest3(y,z,roady,roadz,index);
-  //  for (Int_t i=Find(z-roadz); i<fN; i++) {
-  for (Int_t i=iz1; i<iz2; i++) {
-      AliTPCclusterMI *c=(AliTPCclusterMI*)(fClusters[i]);
-      if (c->GetZ() > z+roadz) break;
-      if ( c->GetY()-y >  roady ) continue;
-      if ( y-c->GetY() >  roady ) continue;
-      Float_t distance = (c->GetZ()-z)*(c->GetZ()-z)+(c->GetY()-y)*(c->GetY()-y);
-      if (maxdistance>distance) {
-       maxdistance = distance;
-       cl=c;       
-       index =i;
-       //roady = TMath::Sqrt(maxdistance);
-      }
-  }
-  return cl;      
+  // return next free slot where the seed can be created
+  fLastSeedID = fNFreeSeeds ? fFreeSeedsID.GetArray()[--fNFreeSeeds] : fSeedsPool->GetEntriesFast();
+  //  AliInfo(Form("%d",fLastSeedID));
+  return (*fSeedsPool)[ fLastSeedID ];
+  //
 }
 
-
-
-AliTPCclusterMI * AliTPCtrackerMI::AliTPCRow::FindNearest3(Double_t y, Double_t z, Double_t roady, Double_t roadz,UInt_t & index) const 
+//________________________________________
+void AliTPCtrackerMI::ResetSeedsPool()
 {
-  //-----------------------------------------------------------------------
-  // Return the index of the nearest cluster in z y 
-  //-----------------------------------------------------------------------
-  Float_t maxdistance = roady*roady + roadz*roadz;
-  //  Int_t iz = Int_t(z+255.);
-  AliTPCclusterMI *cl =0;
-  for (Int_t i=Find(z-roadz); i<fN; i++) {
-    //for (Int_t i=fFastCluster[iz-2]; i<fFastCluster[iz+2]; i++) {
-      AliTPCclusterMI *c=(AliTPCclusterMI*)(fClusters[i]);
-      if (c->GetZ() > z+roadz) break;
-      if ( c->GetY()-y >  roady ) continue;
-      if ( y-c->GetY() >  roady ) continue;
-      Float_t distance = (c->GetZ()-z)*(c->GetZ()-z)+(c->GetY()-y)*(c->GetY()-y);
-      if (maxdistance>distance) {
-       maxdistance = distance;
-       cl=c;       
-       index =i;
-       //roady = TMath::Sqrt(maxdistance);
-      }
-  }
-  return cl;      
+  // mark all seeds in the pool as unused
+  AliInfo(Form("CurrentSize: %d, BookedUpTo: %d, free: %d",fSeedsPool->GetSize(),fSeedsPool->GetEntriesFast(),fNFreeSeeds));
+  fNFreeSeeds = 0;
+  fSeedsPool->Clear("C"); // RS: nominally the seeds may allocate memory...
 }
-
-
-
-
-
-// AliTPCTrackerPoint * AliTPCseed::GetTrackPoint(Int_t i)
-// {
-//   //
-//   // 
-//   return &fTrackPoints[i];
-// }
-
-