Fit mathematics improved, obsollete GBTracker cleaned up
[u/mrichter/AliRoot.git] / HLT / TPCLib / tracking-ca / AliHLTTPCCAGBTracker.cxx
index 84cd47c..b93889c 100644 (file)
@@ -1,5 +1,5 @@
 // $Id$
-//***************************************************************************
+// **************************************************************************
 // This file is property of and copyright by the ALICE HLT Project          * 
 // ALICE Experiment at CERN, All rights reserved.                           *
 //                                                                          *
 // appear in the supporting documentation. The authors make no claims       *
 // about the suitability of this software for any purpose. It is            *
 // provided "as is" without express or implied warranty.                    *
+//                                                                          *
 //***************************************************************************
 
+
 #include "AliHLTTPCCAGBTracker.h"
 #include "AliHLTTPCCAGBHit.h"
 #include "AliHLTTPCCAOutTrack.h"
 #include "AliHLTTPCCATracker.h"
 #include "AliHLTTPCCAGBTrack.h"
-
-#include "TMath.h"
+#include "AliHLTTPCCATrackParam.h"
+#include "AliHLTTPCCAMerger.h"
+#include "AliHLTTPCCAMergerOutput.h"
+#include "AliHLTTPCCADataCompressor.h"
+#include "AliHLTTPCCAMath.h"
+#include "AliHLTTPCCATrackLinearisation.h"
 #include "TStopwatch.h"
-#include "Riostream.h"
 
 //#define DRAW
 
 #ifdef DRAW
 #include "AliHLTTPCCADisplay.h"
-#include "TApplication.h"
 #endif //DRAW
 
-ClassImp(AliHLTTPCCAGBTracker)
 
 AliHLTTPCCAGBTracker::AliHLTTPCCAGBTracker()
-  : TObject(),
+  :
     fSlices(0), 
     fNSlices(0), 
     fHits(0),
+    fExt2IntHitID(0),
     fNHits(0),
     fTrackHits(0), 
     fTracks(0), 
     fNTracks(0),
-    fSliceTrackInfos(0),
+    fMerger(0),    
     fTime(0),
-    fStatNEvents(0)
+    fStatNEvents(0),
+    fSliceTrackerTime(0)
 {
   //* constructor
   for( Int_t i=0; i<20; i++ ) fStatTime[i] = 0;
+  fMerger = new AliHLTTPCCAMerger;
 }
 
 AliHLTTPCCAGBTracker::AliHLTTPCCAGBTracker(const AliHLTTPCCAGBTracker&)
-  : TObject(),
+  : 
     fSlices(0), 
     fNSlices(0), 
     fHits(0),
+    fExt2IntHitID(0),
     fNHits(0),
     fTrackHits(0), 
     fTracks(0), 
     fNTracks(0),
-    fSliceTrackInfos(0),
+    fMerger(0),
     fTime(0),
-    fStatNEvents(0)
+    fStatNEvents(0),
+    fSliceTrackerTime(0)
 {
   //* dummy
 }
 
-AliHLTTPCCAGBTracker &AliHLTTPCCAGBTracker::operator=(const AliHLTTPCCAGBTracker&)
+const AliHLTTPCCAGBTracker &AliHLTTPCCAGBTracker::operator=(const AliHLTTPCCAGBTracker&) const
 {
   //* dummy
   return *this;
@@ -78,10 +86,9 @@ AliHLTTPCCAGBTracker::~AliHLTTPCCAGBTracker()
 {
   //* destructor
   StartEvent();
-  if( fSliceTrackInfos ) delete[] fSliceTrackInfos;
-  fSliceTrackInfos = 0;
   if( fSlices ) delete[] fSlices;
   fSlices=0;
+  delete fMerger;
 }
 
 void AliHLTTPCCAGBTracker::SetNSlices( Int_t N )
@@ -89,36 +96,25 @@ void AliHLTTPCCAGBTracker::SetNSlices( Int_t N )
   //* set N of slices
   StartEvent();
   fNSlices = N;
-  if( fSliceTrackInfos ) delete[] fSliceTrackInfos;
-  fSliceTrackInfos = 0;
   if( fSlices ) delete[] fSlices;
   fSlices=0;
   fSlices = new AliHLTTPCCATracker[N];
-  fSliceTrackInfos = new AliHLTTPCCAGBSliceTrackInfo *[N];
-  for( Int_t iSlice=0; iSlice<fNSlices; iSlice++ ){
-    fSliceTrackInfos[iSlice] = 0;
-  }
 }
 
 void AliHLTTPCCAGBTracker::StartEvent()
 {
   //* clean up track and hit arrays
-
-  if( fSliceTrackInfos ){
-    for( Int_t iSlice=0; iSlice<fNSlices; iSlice++ ){
-      if( fSliceTrackInfos[iSlice] ) delete[] fSliceTrackInfos[iSlice];
-      fSliceTrackInfos[iSlice] = 0;
-    }
-  }
   if( fTrackHits ) delete[] fTrackHits;
   fTrackHits = 0;
   if( fTracks ) delete[] fTracks;
   fTracks = 0;
   if( fHits ) delete[] fHits;
   fHits=0;
+  if( fExt2IntHitID ) delete[] fExt2IntHitID;
+  fExt2IntHitID = 0;
   fNHits = 0;
   fNTracks = 0;
-  for( int i=0; i<fNSlices; i++) fSlices[i].StartEvent();
+  for( Int_t i=0; i<fNSlices; i++) fSlices[i].StartEvent();
 }
 
 
@@ -127,7 +123,10 @@ void AliHLTTPCCAGBTracker::SetNHits( Int_t nHits )
   //* set the number of hits
   if( fHits ) delete[] fHits;
   fHits = 0;
+  if( fExt2IntHitID ) delete[] fExt2IntHitID;
+  fExt2IntHitID = 0;
   fHits = new AliHLTTPCCAGBHit[ nHits ];
+  fExt2IntHitID = new Int_t[ nHits ];
   fNHits = 0;
 }  
 
@@ -137,748 +136,354 @@ void AliHLTTPCCAGBTracker::ReadHit( Float_t x, Float_t y, Float_t z,
 {
   //* read the hit to local array
   AliHLTTPCCAGBHit &hit = fHits[fNHits];
-  hit.X() = x;
-  hit.Y() = y;
-  hit.Z() = z;  
-  hit.ErrX() = 1.e-4;//fSlices[iSlice].Param().ErrX();
-  hit.ErrY() = errY;
-  hit.ErrZ() = errZ;
-  hit.Amp() = amp;
-  hit.ID() = ID;
-  hit.ISlice()=iSlice;
-  hit.IRow() = iRow;
-  hit.IsUsed() = 0;
-
-  hit.SliceHit().Y() = y;
-  hit.SliceHit().Z() = z;
-  hit.SliceHit().ErrY() = errY;
-  hit.SliceHit().ErrZ() = errZ;
-  hit.SliceHit().ID() = 0;
-  fNHits++;
+  hit.SetX( x );
+  hit.SetY( y );
+  hit.SetZ( z );  
+  hit.SetErrX( 1.e-4 );//fSlices[iSlice].Param().ErrX();
+  hit.SetErrY( errY );
+  hit.SetErrZ( errZ );
+  hit.SetAmp( amp );
+  hit.SetID( ID );
+  hit.SetISlice( iSlice );
+  hit.SetIRow( iRow );
+  hit.SetIsUsed( 0 );
+  fNHits++;  
 }
 
 void AliHLTTPCCAGBTracker::FindTracks()
 {
   //* main tracking routine
   fTime = 0;
-  fStatNEvents++;
+  fStatNEvents++;  
 
 #ifdef DRAW
-  if( fStatNEvents<=1 ){
-    if( !gApplication ){
-      TApplication *myapp = new TApplication("myapp",0,0);
-    }    
-    AliHLTTPCCADisplay::Instance().Init();
-  }
-  AliHLTTPCCADisplay::Instance().SetSliceView();
-  //AliHLTTPCCADisplay::Instance().SetTPCView();
-  //AliHLTTPCCADisplay::Instance().DrawTPC();
-#endif //DRAW
+  AliHLTTPCCADisplay::Instance().SetGB(this);
+  AliHLTTPCCADisplay::Instance().SetTPCView();
+  AliHLTTPCCADisplay::Instance().DrawTPC();
+  AliHLTTPCCADisplay::Instance().Ask();
+#endif //DRAW  
 
-  if( fNHits<=0 ) return;
   
-  sort(fHits,fHits+fNHits, AliHLTTPCCAGBHit::Compare );
+  std::sort(fHits,fHits+fNHits, AliHLTTPCCAGBHit::Compare );  
+
+  for( Int_t i=0; i<fNHits; i++ )  fExt2IntHitID[fHits[i].ID()] = i;
 
   // Read hits, row by row
 
-  Int_t oldRow = -1;
-  Int_t oldSlice = -1;
-  Int_t nRowHits = 0;
-  Int_t firstRowHit = 0;
-  int nHitsTotal = fNHits;
-  AliHLTTPCCAHit *vHits = new AliHLTTPCCAHit[nHitsTotal]; // CA hit array
+  Int_t nHitsTotal = fNHits;
+  Float_t *hitX = new Float_t [nHitsTotal];
+  Float_t *hitY = new Float_t [nHitsTotal];
+  Float_t *hitZ = new Float_t [nHitsTotal];
+
+  Int_t *sliceNHits = new Int_t[ fNSlices ];
+  Int_t **rowNHits = new Int_t* [fNSlices];
+  for( Int_t i=0; i<fNSlices; i++ ) rowNHits[i] = new Int_t[200];
+
+  for( Int_t is=0; is<fNSlices; is++ ){
+    sliceNHits[is] = 0;
+    for( Int_t ir=0; ir<200; ir++ ) rowNHits[is][ir] = 0;    
+  }
+
+  for( Int_t ih=0; ih<nHitsTotal; ih++){
+    AliHLTTPCCAGBHit &h = fHits[ih];    
+    sliceNHits[h.ISlice()]++;
+    rowNHits[h.ISlice()][h.IRow()]++;
+  }
   
-  for( int ih=0; ih<nHitsTotal; ih++){
-    AliHLTTPCCAGBHit &h = fHits[ih];
-    h.SliceHit().ID() = ih;
-    vHits[ih] = h.SliceHit();
-    if( h.IRow() != oldRow || h.ISlice() != oldSlice ){
-      if( oldRow>=0 && oldSlice>=0 ){  
-       fSlices[oldSlice].ReadHitRow( oldRow, vHits+firstRowHit, nRowHits );
+  Int_t firstSliceHit = 0;
+  for( Int_t is=0; is<fNSlices; is++ ){
+    fFirstSliceHit[is] = firstSliceHit;
+    Int_t rowFirstHits[200];
+    Int_t firstRowHit = 0;
+    for( Int_t ir=0; ir<200; ir++ ){
+      rowFirstHits[ir] = firstRowHit;
+      for( Int_t ih=0; ih<rowNHits[is][ir]; ih++){
+       AliHLTTPCCAGBHit &h = fHits[firstSliceHit + firstRowHit + ih];    
+       hitX[firstRowHit + ih] = h.X();
+       hitY[firstRowHit + ih] = h.Y();
+       hitZ[firstRowHit + ih] = h.Z(); 
       }
-      oldRow = h.IRow();
-      oldSlice = h.ISlice();
-      firstRowHit = ih;
-      nRowHits = 0;
-    }
-    nRowHits++;    
-  }    
-  if( oldRow>=0 && oldSlice>=0 ){
-    fSlices[oldSlice].ReadHitRow( oldRow, vHits+firstRowHit, nRowHits );
+      firstRowHit+=rowNHits[is][ir];
+    }    
+    fSlices[is].ReadEvent( rowFirstHits, &*rowNHits[is], hitX, hitY, hitZ, sliceNHits[is] );
+   
+    //Int_t data[ rowNHits[is]]
+    //AliHLTTPCCAEventHeader event;
+
+    firstSliceHit+=sliceNHits[is];
+  }
+
+  if( sliceNHits ) delete[] sliceNHits;
+  if( rowNHits ){
+    for( Int_t i=0; i<fNSlices; i++ ) delete[] rowNHits[i];
+    delete[] rowNHits;
   }
-  delete[] vHits;
-  
-  //cout<<"Start CA reconstruction"<<endl;
 
-  for( int iSlice=0; iSlice<fNSlices; iSlice++ ){
+  delete[] hitX;
+  hitX = 0;
+  if( hitY ) delete[] hitY;
+  hitY=0;
+  if( hitZ ) delete[] hitZ;
+  hitZ=0;
+  if( fNHits<=0 ) return;
+
+  TStopwatch timer1;
+  TStopwatch timer2;
+  //std::cout<<"Start CA reconstruction"<<std::endl;
+  for( Int_t iSlice=0; iSlice<fNSlices; iSlice++ ){
+    //std::cout<<"Reconstruct slice "<<iSlice<<std::endl;
     TStopwatch timer;
     AliHLTTPCCATracker &slice = fSlices[iSlice];
     slice.Reconstruct();
     timer.Stop();
-    fTime = timer.CpuTime();
+    //fTime+= timer.CpuTime();
+    //blaTime+= timer.CpuTime();
     fStatTime[0] += timer.CpuTime();
-    fStatTime[1]+=slice.Timers()[0];
-    fStatTime[2]+=slice.Timers()[1];
-    fStatTime[3]+=slice.Timers()[2];
-    fStatTime[4]+=slice.Timers()[3];
-    fStatTime[5]+=slice.Timers()[4];
-    fStatTime[6]+=slice.Timers()[5];
-    fStatTime[7]+=slice.Timers()[6];
-    fStatTime[8]+=slice.Timers()[7];
-  }
-  //cout<<"End CA reconstruction"<<endl;
-  
-  for( Int_t iSlice=0; iSlice<fNSlices; iSlice++ ){
-    AliHLTTPCCATracker &iS = fSlices[iSlice];
-    if( fSliceTrackInfos[iSlice] ) delete[] fSliceTrackInfos[iSlice];
-    fSliceTrackInfos[iSlice]=0;
-    int iNTracks = iS.NOutTracks();
-    fSliceTrackInfos[iSlice] = new AliHLTTPCCAGBSliceTrackInfo[iNTracks];
-    for( Int_t itr=0; itr<iNTracks; itr++ ){
-      fSliceTrackInfos[iSlice][itr].fPrevNeighbour = -1;
-      fSliceTrackInfos[iSlice][itr].fNextNeighbour = -1; 
-      fSliceTrackInfos[iSlice][itr].fUsed = 0;
-    }
+    fStatTime[1]+=slice.Timer(0);
+    fStatTime[2]+=slice.Timer(1);
+    fStatTime[3]+=slice.Timer(2);
+    fStatTime[4]+=slice.Timer(3);
+    fStatTime[5]+=slice.Timer(4);
+    fStatTime[6]+=slice.Timer(5);
+    fStatTime[7]+=slice.Timer(6);
+    fStatTime[8]+=slice.Timer(7);
   }
+
+  timer2.Stop();
+  //std::cout<<"blaTime = "<<timer2.CpuTime()*1.e3<<std::endl;
+  fSliceTrackerTime = timer2.CpuTime();
   
-  //cout<<"Start CA merging"<<endl;
+  //std::cout<<"Start CA merging"<<std::endl;
+
   TStopwatch timerMerge;
-  Merging();
+  Merge(); 
   timerMerge.Stop();
   fStatTime[9]+=timerMerge.CpuTime();  
-  fTime+=timerMerge.CpuTime();
-  //cout<<"End CA merging"<<endl;
+  //fTime+=timerMerge.CpuTime();
+  //std::cout<<"Merge time = "<<timerMerge.CpuTime()*1.e3<<"ms"<<std::endl;
+  //std::cout<<"End CA merging"<<std::endl;
+  timer1.Stop();
+  fTime+= timer1.CpuTime();
 
 #ifdef DRAW
   AliHLTTPCCADisplay::Instance().Ask();
 #endif //DRAW
 }
 
-void AliHLTTPCCAGBTracker::Merging()
+void AliHLTTPCCAGBTracker::Merge()
 {
-  //* track merging between slices
+  // test 
 
-  Float_t dalpha = fSlices[1].Param().Alpha() - fSlices[0].Param().Alpha();
-  Int_t nextSlice[100], prevSlice[100];
-  for( Int_t iSlice=0; iSlice<fNSlices; iSlice++ ){
-    nextSlice[iSlice] = iSlice + 1;
-    prevSlice[iSlice] = iSlice - 1;
-  }
-  nextSlice[ fNSlices/2 - 1 ] = 0;
-  prevSlice[ 0 ] = fNSlices/2 - 1;
-  nextSlice[ fNSlices - 1 ] = fNSlices/2;
-  prevSlice[ fNSlices/2 ] = fNSlices - 1;
-  
-  TStopwatch timerMerge1;
-
-  Int_t maxNSliceTracks = 0;
+#ifdef DRAW
+  AliHLTTPCCADisplay &disp = AliHLTTPCCADisplay::Instance();
+  AliHLTTPCCADisplay::Instance().SetTPCView();
+  AliHLTTPCCADisplay::Instance().DrawTPC();
+  AliHLTTPCCADisplay::Instance().DrawGBHits( *this );
+  disp.Ask(); 
+  std::cout<<"Slice tracks:"<<std::endl;
   for( Int_t iSlice=0; iSlice<fNSlices; iSlice++ ){
-    AliHLTTPCCATracker &iS = fSlices[iSlice];
-    if( maxNSliceTracks < iS.NOutTracks() ) maxNSliceTracks = iS.NOutTracks();
+    AliHLTTPCCATracker &slice = fSlices[iSlice];
+    disp.SetCurrentSlice(&slice);    
+    for( Int_t itr=0; itr<*slice.NOutTracks(); itr++ ){
+      disp.DrawSliceOutTrack( itr, kBlue, 2. );
+    }
   }
+  //AliHLTTPCCADisplay::Instance().DrawGBHits( *this );
+  disp.Ask(); 
+#endif //DRAW  
 
-  //* arrays for rotated track parameters
 
-  AliHLTTPCCATrackParam *iTrParams[2], *jTrParams[2];
-  Bool_t *iOK[2], *jOK[2];
-  for( int i=0; i<2; i++ ){
-    iTrParams[i] = new AliHLTTPCCATrackParam[maxNSliceTracks];
-    jTrParams[i] = new AliHLTTPCCATrackParam[maxNSliceTracks];
-    iOK[i] = new Bool_t [maxNSliceTracks];
-    jOK[i] = new Bool_t [maxNSliceTracks];
-  }
-  
-  for( Int_t iSlice=0; iSlice<fNSlices; iSlice++ ){
-    //cout<<"\nMerge slice "<<iSlice<<endl<<endl;
-    AliHLTTPCCATracker &iS = fSlices[iSlice];
-    Int_t jSlice = nextSlice[iSlice];
-    AliHLTTPCCATracker &jS = fSlices[jSlice];    
-    int iNTracks = iS.NOutTracks();
-    int jNTracks = jS.NOutTracks();
-    if( iNTracks<=0 || jNTracks<=0 ) continue;
-    
-    //* prepare slice tracks for merging
-    
-    for (Int_t itr=0; itr<iNTracks; itr++) {      
-      iOK[0][itr] = 0;
-      iOK[1][itr] = 0;
-      if( iS.OutTracks()[itr].NHits()<10 ) continue;
-      AliHLTTPCCATrackParam &iT1 = iTrParams[0][itr];
-      AliHLTTPCCATrackParam &iT2 = iTrParams[1][itr];
-      iT1 = iS.OutTracks()[itr].StartPoint();
-      iT2 = iS.OutTracks()[itr].EndPoint();
-      iOK[0][itr] = iT1.Rotate( dalpha/2 - TMath::Pi()/2 );
-      iOK[1][itr] = iT2.Rotate( dalpha/2 - TMath::Pi()/2 );
-
-      if( iOK[0][itr] ){
-       iOK[0][itr] = iT1.TransportToX( 0 );
-       if( iS.Param().RMin() > iT1.Y() || iS.Param().RMax() < iT1.Y() ) iOK[0][itr]=0;
-      }
-      if( iOK[1][itr] ){
-       iOK[1][itr] = iT2.TransportToX( 0 );
-       if( iS.Param().RMin() > iT2.Y() || iS.Param().RMax() < iT2.Y() ) iOK[1][itr]=0;
-      }
-    }
+  AliHLTTPCCAMerger &merger = *fMerger;
 
-    for (Int_t jtr=0; jtr<jNTracks; jtr++) {      
-      jOK[0][jtr] = 0;
-      jOK[1][jtr] = 0;
-      if( jS.OutTracks()[jtr].NHits()<10 ) continue;
-      AliHLTTPCCATrackParam &jT1 = jTrParams[0][jtr];
-      AliHLTTPCCATrackParam &jT2 = jTrParams[1][jtr];
-      jT1 = jS.OutTracks()[jtr].StartPoint();
-      jT2 = jS.OutTracks()[jtr].EndPoint();
-      jOK[0][jtr] = jT1.Rotate( -dalpha/2 - TMath::Pi()/2 );
-      jOK[1][jtr] = jT2.Rotate( -dalpha/2 - TMath::Pi()/2 );
-      if( jOK[0][jtr] ){
-       jOK[0][jtr] = jT1.TransportToX( 0 );
-       if( jS.Param().RMin() > jT1.Y() || jS.Param().RMax() < jT1.Y() ) jOK[0][jtr]=0;
-      }
-      if( jOK[1][jtr] ){
-       jOK[1][jtr] = jT2.TransportToX( 0 );
-       if( jS.Param().RMin() > jT2.Y() || jS.Param().RMax() < jT2.Y() ) jOK[1][jtr]=0;
-      }
-    }
+  merger.Clear();
+  merger.SetSliceParam( fSlices[0].Param() );
 
-    //* start merging
-    //cout<<"Start slice merging.."<<endl;
-    for (Int_t itr=0; itr<iNTracks; itr++) {      
-      if( !iOK[0][itr] && !iOK[1][itr] ) continue;
-      Int_t jBest = -1;
-      Int_t lBest = 0;
-      for (Int_t jtr=0; jtr<jNTracks; jtr++) {
-       if( jS.OutTracks()[jtr].NHits() < lBest ) continue;     
-       if( !jOK[0][jtr] && !jOK[1][jtr] ) continue;
-       for( Int_t ip=0; ip<2 && (jBest!=jtr) ; ip++ ){
-         if( !iOK[ip][itr] ) continue;
-         for( Int_t jp=0; jp<2 && (jBest!=jtr) ; jp++ ){
-           if( !jOK[jp][jtr] ) continue;         
-           AliHLTTPCCATrackParam &iT = iTrParams[ip][itr];
-           AliHLTTPCCATrackParam &jT = jTrParams[jp][jtr];
-           // check for neighbouring   
-           {
-             Float_t factor2 = 3.5*3.5;
-             float d = jT.GetY() - iT.GetY();
-             float s2 = jT.GetErr2Y() + iT.GetErr2Y();
-             if( d*d>factor2*s2 ){
-               continue;
-             }
-             d = jT.GetZ() - iT.GetZ();
-             s2 = jT.GetErr2Z() + iT.GetErr2Z();
-             if( d*d>factor2*s2 ){         
-               continue;
-             }
-             Bool_t ok = 1;
-             { // phi, kappa, DsDz signs are the same 
-               d = jT.GetSinPhi() - iT.GetSinPhi();
-               s2 = jT.GetErr2SinPhi() + iT.GetErr2SinPhi();
-               if( d*d>factor2*s2 ) ok = 0;
-               d = jT.GetKappa() - iT.GetKappa(); 
-               s2 = jT.GetErr2Kappa() + iT.GetErr2Kappa();
-               if( d*d>factor2*s2 ) ok = 0;
-               d = jT.GetDzDs() - iT.GetDzDs();
-               s2 = jT.GetErr2DzDs() + iT.GetErr2DzDs();
-               if( d*d>factor2*s2 ) ok = 0;
-             }
-             if( !ok ){ // phi, kappa, DsDz signs are the different
-               d = jT.GetSinPhi() + iT.GetSinPhi();
-               s2 = jT.GetErr2SinPhi() + iT.GetErr2SinPhi();
-               if( d*d>factor2*s2 ) continue;
-               d = jT.GetKappa() + iT.GetKappa(); 
-               s2 = jT.GetErr2Kappa() + iT.GetErr2Kappa();
-               if( d*d>factor2*s2 ) continue;
-               d = jT.GetDzDs() + iT.GetDzDs();
-               s2 = jT.GetErr2DzDs() + iT.GetErr2DzDs();
-               if( d*d>factor2*s2 ) continue;
-             }
-             // tracks can be matched
-
-             lBest = jS.OutTracks()[jtr].NHits();
-             jBest = jtr;
-           }
-         }
-       }
-      }
-      if( jBest>=0 ){
-       Int_t oldi = fSliceTrackInfos[jSlice][jBest].fPrevNeighbour;
-       if( oldi >= 0 ){
-         if( iS.OutTracks()[ oldi ].NHits() < iS.OutTracks()[ itr ].NHits() ){
-           fSliceTrackInfos[jSlice][jBest].fPrevNeighbour = -1;
-           fSliceTrackInfos[iSlice][oldi].fNextNeighbour = -1;
-         } else continue;
-       }
-       //SG!!!
-       fSliceTrackInfos[iSlice][itr].fNextNeighbour = jBest;
-       fSliceTrackInfos[jSlice][jBest].fPrevNeighbour = itr;   
-      }    
-    }
-  }
-
-  for( Int_t i=0; i<2; i++){
-    if( iTrParams[i] ) delete[] iTrParams[i];
-    if( jTrParams[i] ) delete[] jTrParams[i];
-    if( iOK[i] ) delete[] iOK[i];
-    if( jOK[i] ) delete[] jOK[i];
+  for( Int_t i=0; i<fNSlices; i++ ) {
+    merger.SetSliceData( i, fSlices[i].Output() );
   }
-  timerMerge1.Stop();
-  fStatTime[10]+=timerMerge1.CpuTime();
 
-  TStopwatch timerMerge2;
+  merger.Reconstruct();
 
-  Int_t nTracksTot = 0;
-  for( Int_t iSlice = 0; iSlice<fNSlices; iSlice++ ){    
-    AliHLTTPCCATracker &slice = fSlices[iSlice];
-    nTracksTot+= slice.NOutTracks();
-  }
+  const AliHLTTPCCAMergerOutput &out = *(merger.Output());
+  
   
   if( fTrackHits ) delete[] fTrackHits;
   fTrackHits = 0;
   if(fTracks ) delete[] fTracks;
   fTracks = 0;
-  fTrackHits = new Int_t [fNHits*10];
-  fTracks = new AliHLTTPCCAGBTrack[nTracksTot];
+  fTrackHits = new Int_t [out.NTrackClusters()];
+  fTracks = new AliHLTTPCCAGBTrack[out.NTracks()];  
   fNTracks = 0;
 
   Int_t nTrackHits = 0;
+  
+  for( Int_t itr=0; itr<out.NTracks(); itr++ ){
+    const AliHLTTPCCAMergedTrack &track = out.Track( itr );
+
+    AliHLTTPCCAGBTrack &trackGB = fTracks[fNTracks];
+    trackGB.SetFirstHitRef( nTrackHits );
+    trackGB.SetNHits( track.NClusters() );
+    trackGB.SetParam( track.InnerParam() );
+    trackGB.SetAlpha( track.InnerAlpha() );
+    trackGB.SetDeDx( 0 );
+
+    for( Int_t icl=0; icl<track.NClusters(); icl++ ){
+      UInt_t  iDsrc = out.ClusterIDsrc( track.FirstClusterRef() + icl );
+      UInt_t iSlice = AliHLTTPCCADataCompressor::IDsrc2ISlice( iDsrc );
+      UInt_t iRow   = AliHLTTPCCADataCompressor::IDsrc2IRow( iDsrc );
+      UInt_t iClu   = AliHLTTPCCADataCompressor::IDsrc2IClu( iDsrc );    
+      fTrackHits[nTrackHits+icl] = fFirstSliceHit[iSlice] + fSlices[iSlice].Row(iRow).FirstHit() + iClu;
+    }              
+    nTrackHits+= track.NClusters();
+    fNTracks++;
+  }
+
+#ifdef DRAW
+  std::cout<<"Global tracks: "<<std::endl;
+  AliHLTTPCCADisplay::Instance().ClearView();
+  AliHLTTPCCADisplay::Instance().SetTPCView();
+  AliHLTTPCCADisplay::Instance().DrawTPC();
+  AliHLTTPCCADisplay::Instance().DrawGBHits( *this );
+  for( Int_t itr=0; itr<fNTracks; itr++ ){
+    std::cout<<itr<<" nhits= "<<fTracks[itr].NHits()<<std::endl;
+    AliHLTTPCCADisplay::Instance().DrawGBTrack( itr, kBlue, 2. );    
+    //AliHLTTPCCADisplay::Instance().Ask();
+  }
+  AliHLTTPCCADisplay::Instance().Ask();
+#endif
+
+}
 
-  //cout<<"\nStart global track creation...\n"<<endl;  
 
-         static int nRejected = 0;
 
-  Int_t maxNRows = fSlices[0].Param().NRows();
+Bool_t AliHLTTPCCAGBTracker::FitTrack( AliHLTTPCCATrackParam &T, AliHLTTPCCATrackParam t0, 
+                                      Float_t &Alpha, Int_t hits[], Int_t &NTrackHits,
+                                      Bool_t dir )
+{
+  // Fit the track
   
-  for( Int_t iSlice = 0; iSlice<fNSlices; iSlice++ ){
+  //return fMerger->FitTrack( T, Alpha, t0, Alpha, hits, NTrackHits, dir );
+
+  Float_t alpha0 = Alpha;
+
+  AliHLTTPCCATrackParam::AliHLTTPCCATrackFitParam fitPar;
+  AliHLTTPCCATrackParam t = t0;
+  AliHLTTPCCATrackLinearisation l(t0);
+
+  Bool_t first = 1;
+  t.CalculateFitParameters( fitPar );
+
+  Int_t hitsNew[1000];
+  Int_t nHitsNew = 0;
+
+  for( Int_t ihit=0; ihit<NTrackHits; ihit++){
     
-    AliHLTTPCCATracker &slice = fSlices[iSlice];
-    for( Int_t itr=0; itr<slice.NOutTracks(); itr++ ){
-      if( fSliceTrackInfos[iSlice][itr].fUsed ) continue;
-      //cout<<"\n slice "<<iSlice<<", track "<<itr<<"\n"<<endl;
-      //AliHLTTPCCAOutTrack &tCA = slice.OutTracks()[itr];
-      AliHLTTPCCAGBTrack &t = fTracks[fNTracks];
-      //t.Param() = tCA.StartPoint();
-       //t.Alpha() = slice.Param().Alpha();
-      t.NHits() = 0;
-      t.FirstHitRef() = nTrackHits;
-
-      struct FitPoint{    
-       Int_t fISlice;
-       Int_t fHitID;
-       Float_t fX, fY, fZ, fErr2Y, fErr2Z, fAmp;
-      } fitPoints[300];
-      for( Int_t i=0; i<maxNRows; i++ ) fitPoints[i].fISlice = -1;
-     
-      Int_t nHits = 0;
-      Int_t jSlice = iSlice;
-      Int_t jtr = itr;
-      do{ 
-       if( fSliceTrackInfos[jSlice][jtr].fUsed ) break;
-       fSliceTrackInfos[jSlice][jtr].fUsed = 1;
-       AliHLTTPCCATracker &jslice = fSlices[jSlice];
-       AliHLTTPCCAOutTrack &jTr = jslice.OutTracks()[jtr];
-       for( int jhit=0; jhit<jTr.NHits(); jhit++){
-         int id = jslice.OutTrackHits()[jTr.FirstHitRef()+jhit];         
-         AliHLTTPCCAGBHit &h = fHits[id];
-         FitPoint &p =  fitPoints[h.IRow()];
-         if( p.fISlice >=0 ) continue;
-         p.fISlice = h.ISlice();
-         p.fHitID = id;
-         p.fX = jslice.Rows()[h.IRow()].X();
-         p.fY = h.Y();
-         p.fZ = h.Z();
-         p.fErr2Y = h.ErrY()*h.ErrY();
-         p.fErr2Z = h.ErrZ()*h.ErrZ();
-         p.fAmp = h.Amp();
-         nHits++;          
-       }
-       jtr = fSliceTrackInfos[jSlice][jtr].fNextNeighbour;
-       jSlice = nextSlice[jSlice];     
-      } while( jtr >=0 ); 
-
-      if( nHits < 30 ) continue;     //SG!!!
-
-
-      Int_t firstRow = 0, lastRow = maxNRows-1;
-      for( firstRow=0; firstRow<maxNRows; firstRow++ ){
-       if( fitPoints[firstRow].fISlice>=0 ) break;
-      }
-      for( lastRow=maxNRows-1; lastRow>=0; lastRow-- ){
-       if( fitPoints[lastRow].fISlice>=0 ) break;
-      }
-      Int_t mmidRow = (firstRow + lastRow )/2;
-      Int_t midRow = firstRow;
-      for( Int_t i=firstRow+1; i<=lastRow; i++ ){
-       if( fitPoints[i].fISlice<0 ) continue;  
-       if( TMath::Abs(i-mmidRow)>=TMath::Abs(midRow-mmidRow) ) continue;
-       midRow = i;
-      }
-      if( midRow==firstRow || midRow==lastRow ) continue;
-  
-      Int_t searchRows[300];
-      Int_t nSearchRows = 0;
-
-      for( Int_t i=firstRow; i<=lastRow; i++ ) searchRows[nSearchRows++] = i;
-      for( Int_t i=lastRow+1; i<maxNRows; i++ ) searchRows[nSearchRows++] = i;
-      for( Int_t i=firstRow-1; i>=0; i-- ) searchRows[nSearchRows++] = i;
-      
-      // refit 
-
-      AliHLTTPCCATrackParam t0;
-
-      {        
-
-       {         
-         FitPoint &p0 =  fitPoints[firstRow];
-         FitPoint &p1 =  fitPoints[midRow];
-         FitPoint &p2 =  fitPoints[lastRow];
-         Float_t x0=p0.fX, y0=p0.fY, z0=p0.fZ;
-         Float_t x1=p1.fX, y1=p1.fY, z1=p1.fZ;
-         Float_t x2=p2.fX, y2=p2.fY, z2=p2.fZ;
-         if( p1.fISlice!=p0.fISlice ){
-           Float_t dAlpha = fSlices[p0.fISlice].Param().Alpha() - fSlices[p1.fISlice].Param().Alpha();
-           Float_t c = TMath::Cos(dAlpha);
-           Float_t s = TMath::Sin(dAlpha);
-           x1 = p1.fX*c + p1.fY*s;
-           y1 = p1.fY*c - p1.fX*s;
-         }
-         if( p2.fISlice!=p0.fISlice ){
-           Float_t dAlpha = fSlices[p0.fISlice].Param().Alpha() - fSlices[p2.fISlice].Param().Alpha();
-           Float_t c = TMath::Cos(dAlpha);
-           Float_t s = TMath::Sin(dAlpha);
-           x2 = p2.fX*c + p2.fY*s;
-           y2 = p2.fY*c - p2.fX*s;
-         }
-
-         Float_t sp0[5] = {x0, y0, z0, .5, .5 };       
-         Float_t sp1[5] = {x1, y1, z1, .5, .5 };
-         Float_t sp2[5] = {x2, y2, z2, .5, .5 };
-         t0.ConstructXYZ3(sp0,sp1,sp2,1., 0);
-       }
-       
-       Int_t currslice = fitPoints[firstRow].fISlice;
-
-       for( Int_t rowID=0; rowID<nSearchRows; rowID++ ){
-         Int_t iRow = searchRows[rowID];         
-         FitPoint &p =  fitPoints[iRow];
-
-         if( p.fISlice>=0 ){ 
-
-           //* Existing hit
-
-           //* Rotate to the new slice
-
-           if( p.fISlice!=currslice ){ 
-             if( !t0.Rotate( fSlices[p.fISlice].Param().Alpha() - fSlices[currslice].Param().Alpha() ) ) continue;     
-             currslice = p.fISlice;
-           }
-           //* Transport to the new row
-           
-           if( !t0.TransportToX( p.fX ) ) continue;
-
-           //* Calculate hit errors
-           
-           GetErrors2( p.fISlice, iRow, t0, p.fErr2Y, p.fErr2Z );
-
-         } else { 
-           //continue; //SG!!
-           //* Search for the missed hit
-
-           Float_t factor2 = 3.5*3.5;
-
-           AliHLTTPCCATracker *cslice = &(fSlices[currslice]);
-           AliHLTTPCCARow *row = &(cslice->Rows()[iRow]);
-           if( !t0.TransportToX( row->X() ) ) continue;
-
-           if( t0.GetY() > row->MaxY() ){ //next slice
-
-             Int_t j = nextSlice[currslice];
-
-             //* Rotate to the new slice
-             
-             if( !t0.Rotate( -fSlices[currslice].Param().Alpha() +fSlices[j].Param().Alpha() ) ) continue;           
-             currslice = j;
-             cslice = &(fSlices[currslice]);
-             row = &(cslice->Rows()[iRow]);
-             if( !t0.TransportToX( row->X() ) ) continue;
-             if( TMath::Abs(t0.GetY()) > row->MaxY() ) continue;
-
-           }else if( t0.GetY() < -row->MaxY() ){ //prev slice
-             Int_t j = prevSlice[currslice];
-             //* Rotate to the new slice
-             if( !t0.Rotate( -fSlices[currslice].Param().Alpha() +fSlices[j].Param().Alpha() ) ) break;
-             currslice = j;
-             cslice = &(fSlices[currslice]);
-             row = &(cslice->Rows()[iRow]);
-             if( !t0.TransportToX( row->X() ) ) continue;              
-             if( TMath::Abs(t0.GetY()) > row->MaxY() ) continue;
-           }
-           
-           Int_t bestsh = -1;
-           Float_t ds = 1.e10;
-           for( Int_t ish=0; ish<row->NHits(); ish++ ){
-             AliHLTTPCCAHit &sh = row->Hits()[ish];
-             Float_t dy = sh.Y() - t0.GetY();
-             Float_t dz = sh.Z() - t0.GetZ();
-             Float_t dds = dy*dy+dz*dz;
-             if( dds<ds ){
-               ds = dds;
-               bestsh = ish;
-             }
-           }
-           if( bestsh<0 ) continue;
-
-           //* Calculate hit errors
-           
-           GetErrors2( currslice, iRow, t0, p.fErr2Y, p.fErr2Z );
-
-           AliHLTTPCCAHit &sh = row->Hits()[bestsh];
-           Float_t dy = sh.Y() - t0.GetY();
-           Float_t dz = sh.Z() - t0.GetZ();
-           Float_t s2z = /*t0.GetErr2Z() + */ p.fErr2Z;
-           if( dz*dz>factor2*s2z ) continue;           
-           Float_t s2y = /*t0.GetErr2Y() + */ p.fErr2Y;
-           if( dy*dy>factor2*s2y ) continue;
-
-           p.fISlice = currslice;
-           p.fHitID = sh.ID();
-           p.fX = row->X();
-           p.fY = sh.Y();
-           p.fZ = sh.Z();
-           p.fAmp = fHits[p.fHitID].Amp();
-         }
-
-         //* Update the track
-         
-         t0.Filter2( p.fY, p.fZ, p.fErr2Y, p.fErr2Z );   
-       }
-
-       //* final refit, dE/dx calculation
-       //cout<<"\n\nstart refit..\n"<<endl;
-       {
-         Double_t sumDeDx = 0;
-         Int_t nDeDx = 0;
-         t.NHits() = 0;
-       
-         AliHLTTPCCATrackFitParam fitPar;
-         t0.CalculateFitParameters( fitPar, fSlices[0].Param().Bz() );
-
-         t0.Cov()[ 0] = .1;
-         t0.Cov()[ 1] = 0;
-         t0.Cov()[ 2] = .1;
-         t0.Cov()[ 3] = 0;
-         t0.Cov()[ 4] = 0;
-         t0.Cov()[ 5] = .1;
-         t0.Cov()[ 6] = 0;
-         t0.Cov()[ 7] = 0;
-         t0.Cov()[ 8] = 0;
-         t0.Cov()[ 9] = .1;
-         t0.Cov()[10] = 0;
-         t0.Cov()[11] = 0;
-         t0.Cov()[12] = 0;
-         t0.Cov()[13] = 0;
-         t0.Cov()[14] = .1;
-         t0.Chi2() = 0;
-         t0.NDF() = -5;        
-         bool first = 1;
-         for( Int_t iRow = maxNRows-1; iRow>=0; iRow-- ){
-           FitPoint &p =  fitPoints[iRow];
-           if( p.fISlice<0 ) continue;
-           fTrackHits[nTrackHits+t.NHits()] = p.fHitID;
-           t.NHits()++;
-           
-           //* Rotate to the new slice
-
-           if( p.fISlice!=currslice ){ 
-             //cout<<"rotate..."<<endl;
-             //cout<<" before rotation:"<<endl;
-             //t0.Print();
-             if( !t0.Rotate( fSlices[p.fISlice].Param().Alpha() - fSlices[currslice].Param().Alpha() ) ) continue;     
-             //cout<<" after rotation:"<<endl;
-             //t0.Print();
-             currslice = p.fISlice;
-           }
-           //* Transport to the new row
-           
-           //cout<<" before transport:"<<endl;
-           //t0.Print();
-           
-           //if( !t0.TransportToX( p.fX ) ) continue;      
-           if( !t0.TransportToXWithMaterial( p.fX, fitPar ) ) continue;            
-           //if( !t0.TransportToX( p.fX ) ) continue;      
-           //cout<<" after transport:"<<endl;
-           //t0.Print();
-
-           //* Update the track
-           
-           if( first ){
-             t0.Cov()[ 0] = .5*.5;
-             t0.Cov()[ 1] = 0;
-             t0.Cov()[ 2] = .5*.5;
-             t0.Cov()[ 3] = 0;
-             t0.Cov()[ 4] = 0;
-             t0.Cov()[ 5] = .2*.2;
-             t0.Cov()[ 6] = 0;
-             t0.Cov()[ 7] = 0;
-             t0.Cov()[ 8] = 0;
-             t0.Cov()[ 9] = .2*.2;
-             t0.Cov()[10] = 0;
-             t0.Cov()[11] = 0;
-             t0.Cov()[12] = 0;
-             t0.Cov()[13] = 0;
-             t0.Cov()[14] = .5*.5;
-             t0.Chi2() = 0;
-             t0.NDF() = -5;
-           }
-
-           //cout<<" before filtration:"<<endl;
-           //t0.Print();
-
-           if( !t0.Filter2( p.fY, p.fZ, p.fErr2Y, p.fErr2Z ) ) continue;         
-           //cout<<" after filtration:"<<endl;
-           //t0.Print();
-             first = 0;
-           
-           if( TMath::Abs( t0.CosPhi() )>1.e-4 ){
-             Float_t dLdX = TMath::Sqrt(1.+t0.DzDs()*t0.DzDs())/TMath::Abs(t0.CosPhi());
-             sumDeDx+=p.fAmp/dLdX;
-             nDeDx++;
-           } 
-         }
-         t.DeDx() = 0;
-         if( nDeDx >0 ) t.DeDx() = sumDeDx/nDeDx;
-         if( t0.GetErr2Y()<=0 ){
-           cout<<"nhits = "<<t.NHits()<<", t0.GetErr2Y() = "<<t0.GetErr2Y()<<endl;
-           t0.Print();
-           //exit(1);
-         }
-       }
-
-       if( t.NHits()<30 ) continue;//SG!!
-
-       {
-         Bool_t ok=1;
-         
-         Float_t *c = t0.Cov();
-         for( int i=0; i<15; i++ ) ok = ok && finite(c[i]);
-         for( int i=0; i<5; i++ ) ok = ok && finite(t0.Par()[i]);
-         ok = ok && (t0.GetX()>50);
-         
-         if( c[0]<=0 || c[2]<=0 || c[5]<=0 || c[9]<=0 || c[14]<=0 ) ok = 0;
-         //if( c[0]>5. || c[2]>5. || c[5]>2. || c[9]>2 || c[14]>2 ) ok = 0;
-         if(!ok){
-           nRejected++;
-           //cout<<"\n\nRejected: "<<nRejected<<"\n"<<endl;
-           continue;
-         }
-       }
-
-       if( TMath::Abs(t0.Kappa())<1.e-8 ) t0.Kappa() = 1.e-8;  
-       t.Param() = t0;
-       t.Alpha() = fSlices[currslice].Param().Alpha();
-       nTrackHits+= t.NHits();
-       fNTracks++;   
-      }
-    }
-  }
-  cout<<"\n\nRejected: "<<nRejected<<"\n"<<endl;
-  timerMerge2.Stop();
-  fStatTime[11]+=timerMerge2.CpuTime();
+    Int_t jhit = dir ?(NTrackHits-1-ihit) :ihit;
+    AliHLTTPCCAGBHit &h = fHits[hits[jhit]];
 
-  TStopwatch timerMerge3;
+    Int_t iSlice = h.ISlice();
 
-  //* selection  
-  //cout<<"Selection..."<<endl;
-  {
-    AliHLTTPCCAGBTrack *vtracks = new AliHLTTPCCAGBTrack [fNTracks];
-    Int_t *vhits = new Int_t [fNHits];
-    AliHLTTPCCAGBTrack **vptracks = new AliHLTTPCCAGBTrack* [fNTracks];
+    Float_t sliceAlpha =  fSlices[0].Param().Alpha( iSlice );
 
-    for( Int_t itr=0; itr<fNTracks; itr++ ){
-      vptracks[itr] = &(fTracks[itr]);
+    if( CAMath::Abs( sliceAlpha - alpha0)>1.e-4 ){
+      if( ! t.Rotate(  sliceAlpha - alpha0, l, .999 ) ) continue;
+      alpha0 = sliceAlpha;
     }
-    Int_t nTracks = 0;
-    Int_t nHits = 0;
-    sort(vptracks, vptracks+fNTracks, AliHLTTPCCAGBTrack::ComparePNClusters );
-    for( Int_t itr=0; itr<fNTracks; itr++ ){
-      AliHLTTPCCAGBTrack &t = *(vptracks[itr]);
-      AliHLTTPCCAGBTrack &to = vtracks[nTracks];
-      to=*(vptracks[itr]);
-      to.FirstHitRef() = nHits;
-      to.NHits() = 0;
-      for( Int_t ih=0; ih<t.NHits(); ih++ ){
-       Int_t jh = fTrackHits[t.FirstHitRef()+ih];
-       AliHLTTPCCAGBHit &h = fHits[jh];
-       if( h.IsUsed() ) continue;
-       vhits[to.FirstHitRef() + to.NHits()] = jh;
-       to.NHits()++;
-       h.IsUsed() = 1;
-      }
-      if( to.NHits()<30 ) continue;//SG!!!
-      nHits+=to.NHits();
-      nTracks++;
-      //cout<<to.Param().GetErr2Y()<<" "<<to.Param().GetErr2Z()<<endl;
+
+    //Float_t x = fSliceParam.RowX( h.IRow() );
+    Float_t x = h.X();
+    
+    if( !t.TransportToXWithMaterial( x, l, fitPar, fSlices[0].Param().GetBz(t) ) ) continue;
+    
+    if( first ){
+      t.SetCov( 0, 10 );
+      t.SetCov( 1,  0 );
+      t.SetCov( 2, 10 );
+      t.SetCov( 3,  0 );
+      t.SetCov( 4,  0 );
+      t.SetCov( 5,  1 );
+      t.SetCov( 6,  0 );
+      t.SetCov( 7,  0 );
+      t.SetCov( 8,  0 );
+      t.SetCov( 9,  1 );
+      t.SetCov(10,  0 );
+      t.SetCov(11,  0 );
+      t.SetCov(12,  0 );
+      t.SetCov(13,  0 );
+      t.SetCov(14,  10 );
+      t.SetChi2( 0 );
+      t.SetNDF( -5 );
+      t.CalculateFitParameters( fitPar );
     }
-    fNTracks = nTracks;
-    if( fTrackHits ) delete[] fTrackHits;
-    if( fTracks ) delete[] fTracks;
-    fTrackHits = vhits;
-    fTracks = vtracks;
-    delete[] vptracks;
-  }
-  timerMerge3.Stop();
-  fStatTime[12]+=timerMerge3.CpuTime();
-}
 
-void AliHLTTPCCAGBTracker::GetErrors2( Int_t iSlice, Int_t iRow, AliHLTTPCCATrackParam &t, Float_t &Err2Y, Float_t &Err2Z )
-{
-  //
-  // Use calibrated cluster error from OCDB
-  //
     
-  Float_t z = TMath::Abs((250.-0.275)-TMath::Abs(t.GetZ()));
-  Int_t    type = (iRow<63) ? 0: (iRow>126) ? 1:2;
-  Float_t cosPhiInv = TMath::Abs(t.GetCosPhi())>1.e-2 ?1./t.GetCosPhi() :0;
-  Float_t angleY = t.GetSinPhi()*cosPhiInv ;
-  Float_t angleZ = t.GetDzDs()*cosPhiInv ;
+    Float_t err2Y, err2Z;
+    fSlices[0].Param().GetClusterErrors2( h.IRow(), h.Z(), l.SinPhi(), l.CosPhi(), l.DzDs(), err2Y, err2Z );
+    if( !t.Filter( h.Y(), h.Z(), err2Y, err2Z ) ) continue;                
 
-  AliHLTTPCCATracker &slice = fSlices[iSlice];
+    first = 0;
 
-  Err2Y = slice.Param().GetClusterError2(0,type, z,angleY);  
-  Err2Z = slice.Param().GetClusterError2(1,type, z,angleZ);
+    hitsNew[nHitsNew++] = hits[jhit];
+  }
+  
+  if( CAMath::Abs(t.QPt())<1.e-8 ) t.SetQPt( 1.e-8 );
+  
+  Bool_t ok=1;
+  
+  const Float_t *c = t.Cov();
+  for( Int_t i=0; i<15; i++ ) ok = ok && finite(c[i]);
+  for( Int_t i=0; i<5; i++ ) ok = ok && finite(t.Par()[i]);
+  ok = ok && (t.GetX()>50);
+  
+  if( c[0]<=0 || c[2]<=0 || c[5]<=0 || c[9]<=0 || c[14]<=0 ) ok = 0;
+  if( c[0]>5. || c[2]>5. || c[5]>2. || c[9]>2 || c[14]>2. ) ok = 0;
+  
+  if( CAMath::Abs(t.SinPhi())>.99 ) ok = 0;
+  else if( l.CosPhi()>=0 ) t.SetSignCosPhi( 1 );
+  else t.SetSignCosPhi( -1 );
+  
+  if( ok ){
+    T = t;
+    Alpha = alpha0;
+    NTrackHits = nHitsNew;
+    for( Int_t i=0; i<NTrackHits; i++ ){
+      hits[dir ?(NTrackHits-1-i) :i] = hitsNew[i];
+    }
+  }
+  return ok;
 }
 
 
-void AliHLTTPCCAGBTracker::GetErrors2( AliHLTTPCCAGBHit &h, AliHLTTPCCATrackParam &t, Float_t &Err2Y, Float_t &Err2Z )
-{
-  //
-  // Use calibrated cluster error from OCDB
-  //
 
-  GetErrors2( h.ISlice(), h.IRow(), t, Err2Y, Err2Z );
-}
-
-void AliHLTTPCCAGBTracker::WriteSettings( ostream &out )
+void AliHLTTPCCAGBTracker::WriteSettings( std::ostream &out ) const
 {
-  out<< NSlices()<<endl;  
-  for( int iSlice=0; iSlice<NSlices(); iSlice++ ){    
+  //* write settings to the file
+  out<< NSlices()<<std::endl;  
+  for( Int_t iSlice=0; iSlice<NSlices(); iSlice++ ){    
     fSlices[iSlice].Param().WriteSettings( out );
   }
 }
 
-void AliHLTTPCCAGBTracker::ReadSettings( istream &in )
+void AliHLTTPCCAGBTracker::ReadSettings( std::istream &in )
 {
+  //* Read settings from the file
   Int_t nSlices=0;
   in >> nSlices;
   SetNSlices( nSlices );
-  for( int iSlice=0; iSlice<NSlices(); iSlice++ ){    
+  for( Int_t iSlice=0; iSlice<NSlices(); iSlice++ ){    
     AliHLTTPCCAParam param;
     param.ReadSettings ( in );
     fSlices[iSlice].Initialize( param ); 
   }
 }
 
-void AliHLTTPCCAGBTracker::WriteEvent( ostream &out )
+void AliHLTTPCCAGBTracker::WriteEvent( std::ostream &out ) const
 {
-  out<<NHits()<<endl;
+  // write event to the file
+
+  out<<NHits()<<std::endl;
   for (Int_t ih=0; ih<NHits(); ih++) {
     AliHLTTPCCAGBHit &h = fHits[ih];
     out<<h.X()<<" ";
@@ -889,12 +494,14 @@ void AliHLTTPCCAGBTracker::WriteEvent( ostream &out )
     out<<h.Amp()<<" ";
     out<<h.ID()<<" ";
     out<<h.ISlice()<<" ";
-    out<<h.IRow()<<endl;
+    out<<h.IRow()<<std::endl;
   }
 }
 
-void AliHLTTPCCAGBTracker::ReadEvent( istream &in )
+void AliHLTTPCCAGBTracker::ReadEvent( std::istream &in ) 
 {
+  //* Read event from file 
+
   StartEvent();
   Int_t nHits;
   in >> nHits;
@@ -908,42 +515,46 @@ void AliHLTTPCCAGBTracker::ReadEvent( istream &in )
   }
 }
 
-void AliHLTTPCCAGBTracker::WriteTracks( ostream &out )
+void AliHLTTPCCAGBTracker::WriteTracks( std::ostream &out ) const 
 {
-  out<<fTime<<endl;
+  //* Write tracks to file 
+
+  out<<fSliceTrackerTime<<std::endl;
   Int_t nTrackHits = 0;
-  for( Int_t itr=0; itr<NTracks(); itr++ ){
-    AliHLTTPCCAGBTrack &t = Tracks()[itr];    
-    nTrackHits+=t.NHits();
+  for( Int_t itr=0; itr<fNTracks; itr++ ){
+    nTrackHits+=fTracks[itr].NHits();
   }
-  out<<nTrackHits<<endl;
+  out<<nTrackHits<<std::endl;
   for( Int_t ih=0; ih<nTrackHits; ih++ ){
-    out<< TrackHits()[ih]<<" ";
+    out<< fTrackHits[ih]<<" ";
   }
-  out<<endl;
+  out<<std::endl;
   
-  out<<NTracks()<<endl;
-  for( Int_t itr=0; itr<NTracks(); itr++ ){
-    AliHLTTPCCAGBTrack &t = Tracks()[itr];    
-    AliHLTTPCCATrackParam &p = t.Param();      
+  out<<NTracks()<<std::endl;
+  for( Int_t itr=0; itr<fNTracks; itr++ ){
+    AliHLTTPCCAGBTrack &t = fTracks[itr];    
+    const AliHLTTPCCATrackParam &p = t.Param();        
     out<< t.NHits()<<" ";
     out<< t.FirstHitRef()<<" ";
     out<< t.Alpha()<<" ";
-    out<< t.DeDx()<<endl;
-    out<< p.X()<<" ";
-    out<< p.CosPhi()<<" ";
-    out<< p.Chi2()<<" ";
-    out<< p.NDF()<<endl;
-    for( Int_t i=0; i<5; i++ ) out<<p.Par()[i]<<" ";
-    out<<endl;
-    for( Int_t i=0; i<15; i++ ) out<<p.Cov()[i]<<" ";
-    out<<endl;
+    out<< t.DeDx()<<std::endl;
+    out<< p.GetX()<<" ";
+    out<< p.GetCosPhi()<<" ";
+    out<< p.GetChi2()<<" ";
+    out<< p.GetNDF()<<std::endl;
+    for( Int_t i=0; i<5; i++ ) out<<p.GetPar()[i]<<" ";
+    out<<std::endl;
+    for( Int_t i=0; i<15; i++ ) out<<p.GetCov()[i]<<" ";
+    out<<std::endl;
   }
 }
 
-void AliHLTTPCCAGBTracker::ReadTracks( istream &in )
+void AliHLTTPCCAGBTracker::ReadTracks( std::istream &in )
 {
+  //* Read tracks  from file 
+
   in>>fTime;
+  fSliceTrackerTime = fTime;
   fStatTime[0]+=fTime;
   fStatNEvents++;
   if( fTrackHits ) delete[] fTrackHits;
@@ -960,16 +571,27 @@ void AliHLTTPCCAGBTracker::ReadTracks( istream &in )
   fTracks = new AliHLTTPCCAGBTrack[fNTracks];
   for( Int_t itr=0; itr<NTracks(); itr++ ){
     AliHLTTPCCAGBTrack &t = Tracks()[itr];    
-    AliHLTTPCCATrackParam &p = t.Param();      
-    in>> t.NHits();
-    in>> t.FirstHitRef();
-    in>> t.Alpha();
-    in>> t.DeDx();
-    in>> p.X();
-    in>> p.CosPhi();
-    in>> p.Chi2();
-    in>> p.NDF();
-    for( Int_t i=0; i<5; i++ ) in>>p.Par()[i];
-    for( Int_t i=0; i<15; i++ ) in>>p.Cov()[i];
+    AliHLTTPCCATrackParam p;
+    Int_t i;
+    Float_t f;
+    in>>i;
+    t.SetNHits(i);
+    in>>i;
+    t.SetFirstHitRef( i );
+    in>>f;
+    t.SetAlpha(f);
+    in>>f;
+    t.SetDeDx( f );
+    in>>f;
+    p.SetX( f );
+    in>>f;
+    p.SetSignCosPhi( f );
+    in>>f;
+    p.SetChi2( f );
+    in>>i;
+    p.SetNDF( i );
+    for( Int_t j=0; j<5; j++ ){ in>>f; p.SetPar( j, f); }
+    for( Int_t j=0; j<15; j++ ){ in>>f; p.SetCov(j,f); }
+    t.SetParam(p);     
   }
 }