]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/TPCLib/tracking-ca/AliHLTTPCCAGBTracker.cxx
Fit mathematics improved, obsollete GBTracker cleaned up
[u/mrichter/AliRoot.git] / HLT / TPCLib / tracking-ca / AliHLTTPCCAGBTracker.cxx
index a371623b8f6af4d60dede8e11ef0ee1a7494a249..b93889c8e7157d4c8fe6ff1f5a7b4dd7de248f1a 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"
-#include "TROOT.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),
-    fStatNEvents(0)
+    fMerger(0),    
+    fTime(0),
+    fStatNEvents(0),
+    fSliceTrackerTime(0)
 {
   //* constructor
-  fStatTime[0] = 0;
-  fStatTime[1] = 0;
-  fStatTime[2] = 0;
-  fStatTime[3] = 0;
-  fStatTime[4] = 0;
-  fStatTime[5] = 0;
-  fStatTime[6] = 0;
-  fStatTime[7] = 0;
-  fStatTime[8] = 0;
-  fStatTime[9] = 0;
+  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),
-    fStatNEvents(0)
+    fMerger(0),
+    fTime(0),
+    fStatNEvents(0),
+    fSliceTrackerTime(0)
 {
   //* dummy
 }
 
-AliHLTTPCCAGBTracker &AliHLTTPCCAGBTracker::operator=(const AliHLTTPCCAGBTracker&)
+const AliHLTTPCCAGBTracker &AliHLTTPCCAGBTracker::operator=(const AliHLTTPCCAGBTracker&) const
 {
   //* dummy
   return *this;
@@ -86,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 )
@@ -97,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();
 }
 
 
@@ -135,637 +123,475 @@ 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;
 }  
 
-void AliHLTTPCCAGBTracker::ReadHit( Double_t x, Double_t y, Double_t z, 
-                                   Double_t errY, Double_t errZ,
+void AliHLTTPCCAGBTracker::ReadHit( Float_t x, Float_t y, Float_t z, 
+                                   Float_t errY, Float_t errZ, Float_t amp,
                                    Int_t ID, Int_t iSlice, Int_t iRow )
 {
   //* 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.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
-
-  fStatNEvents++;
+  fTime = 0;
+  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];
   }
-  delete[] vHits;
-  
-  //cout<<"Start CA reconstruction"<<endl;
 
-  for( int iSlice=0; iSlice<fNSlices; iSlice++ ){
+  if( sliceNHits ) delete[] sliceNHits;
+  if( rowNHits ){
+    for( Int_t i=0; i<fNSlices; i++ ) delete[] rowNHits[i];
+    delete[] rowNHits;
+  }
+
+  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();
+    //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];
-#ifdef DRAW
-    //SlicePerformance( iSlice );
-    //if( slice.NTracks()>0 ) AliHLTTPCCADisplay::Instance().Ask();
-#endif 
-  }
-  //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[8]+=timerMerge.CpuTime();
-  //cout<<"End CA merging"<<endl;
+  fStatTime[9]+=timerMerge.CpuTime();  
+  //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 
 
-  Double_t dalpha = fSlices[1].Param().Alpha() - fSlices[0].Param().Alpha();
-  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++ ){
-    AliHLTTPCCATracker &iS = fSlices[iSlice];
-    Int_t jSlice = iSlice+1;
-    if( iSlice==fNSlices/2-1 ) jSlice = 0;
-    else if( iSlice==fNSlices-1 ) jSlice = fNSlices/2;
-    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()<30 ) 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()<30 ) 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
-
-    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;
-       }
-       
-       fSliceTrackInfos[iSlice][itr].fNextNeighbour = jBest;
-       fSliceTrackInfos[jSlice][jBest].fPrevNeighbour = itr;   
-      }    
-    }
+  for( Int_t i=0; i<fNSlices; i++ ) {
+    merger.SetSliceData( i, fSlices[i].Output() );
   }
 
-  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];
-  }
+  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++;
+  }
 
-  for( Int_t iSlice = 0; iSlice<fNSlices; iSlice++ ){
-    
-    AliHLTTPCCATracker &slice = fSlices[iSlice];
-    for( Int_t itr=0; itr<slice.NOutTracks(); itr++ ){
-      if( fSliceTrackInfos[iSlice][itr].fUsed ) continue;
-      fSliceTrackInfos[iSlice][itr].fUsed = 1;
-      AliHLTTPCCAOutTrack &tCA = slice.OutTracks()[itr];
-      AliHLTTPCCAGBTrack &t = fTracks[fNTracks];
-      t.Param() = tCA.StartPoint();
-      t.NHits() = 0;
-      t.FirstHitRef() = nTrackHits;
-      t.Alpha() = slice.Param().Alpha();
-            
-      Int_t ihit = 0;
-      Int_t jSlice = iSlice;
-      Int_t jtr = itr;
-      for( int jhit=0; jhit<tCA.NHits(); jhit++){
-       int index = slice.OutTrackHits()[tCA.FirstHitRef()+jhit];
-       fTrackHits[nTrackHits+ihit] = index;
-       ihit++;     
-      }
-      while( fSliceTrackInfos[jSlice][jtr].fNextNeighbour >=0 ){
-       jtr = fSliceTrackInfos[jSlice][jtr].fNextNeighbour;
-       if( jSlice==fNSlices/2-1 ) jSlice = 0;
-       else if( jSlice==fNSlices-1 ) jSlice = fNSlices/2;
-       else jSlice = jSlice + 1;
-       if( fSliceTrackInfos[jSlice][jtr].fUsed ) break;
-       fSliceTrackInfos[jSlice][jtr].fUsed = 1;
-       AliHLTTPCCAOutTrack &jTr = fSlices[jSlice].OutTracks()[jtr];
-       for( int jhit=0; jhit<jTr.NHits(); jhit++){
-         int index = fSlices[jSlice].OutTrackHits()[jTr.FirstHitRef()+jhit];     
-         fTrackHits[nTrackHits+ihit] = index;
-         ihit++;
-       }
-      }
-      t.NHits() = ihit;
-      if( t.NHits()<50 ) continue;
-      Int_t nHitsOld = t.NHits();
-
-      // refit 
-      {
-       if( t.NHits()<10 ) continue;
-
-
-       AliHLTTPCCAGBHit* *vhits = new AliHLTTPCCAGBHit*[nHitsOld];
-       
-       for( Int_t ih=0; ih<nHitsOld; ih++ ){
-         vhits[ih] = &(fHits[fTrackHits[t.FirstHitRef() + ih]]);
-       }       
-       
-       sort(vhits, vhits+nHitsOld, AliHLTTPCCAGBHit::ComparePRowDown );
-
-       AliHLTTPCCATrackParam t0;
-       
-       {         
-         AliHLTTPCCAGBHit &h0 = *(vhits[0]);
-         AliHLTTPCCAGBHit &h1 = *(vhits[nHitsOld/2]);
-         AliHLTTPCCAGBHit &h2 = *(vhits[nHitsOld-1]);
-         if( h0.IRow()==h1.IRow() || h0.IRow()==h2.IRow() || h1.IRow()==h2.IRow() ) continue;
-         Double_t x1,y1,z1, x2, y2, z2, x3, y3, z3;
-         fSlices[h0.ISlice()].Param().Slice2Global(h0.X(), h0.Y(), h0.Z(), &x1,&y1,&z1);
-         fSlices[h1.ISlice()].Param().Slice2Global(h1.X(), h1.Y(), h1.Z(), &x2,&y2,&z2);
-         fSlices[h2.ISlice()].Param().Slice2Global(h2.X(), h2.Y(), h2.Z(), &x3,&y3,&z3);
-         fSlices[h0.ISlice()].Param().Global2Slice(x1, y1, z1, &x1,&y1,&z1);
-         fSlices[h0.ISlice()].Param().Global2Slice(x2, y2, z2, &x2,&y2,&z2);
-         fSlices[h0.ISlice()].Param().Global2Slice(x3, y3, z3, &x3,&y3,&z3);
-         Float_t sp0[5] = {x1, y1, z1, .5, .5 };       
-         Float_t sp1[5] = {x2, y2, z2, .5, .5 };
-         Float_t sp2[5] = {x3, y3, z3, .5, .5 };
-         t0.ConstructXYZ3(sp0,sp1,sp2,1., 0);
-       }             
-
-       Int_t currslice = vhits[0]->ISlice();
-       Int_t currrow = fSlices[currslice].Param().NRows()-1;
-       Double_t currd2 = 1.e10;
-       AliHLTTPCCAGBHit *currhit = 0;
-
-       for( Int_t ih=0; ih<nHitsOld; ih++ ){
-         Double_t y0 = t0.GetY();
-         Double_t z0 = t0.GetZ();      
-         AliHLTTPCCAGBHit &h = *(vhits[ih]);
-         //cout<<"hit,slice,row="<<ih<<" "<<h.slice<<" "<<h.row<<endl;
-         if( h.ISlice() == currslice && h.IRow() == currrow ){
-           //* select the best hit in the row
-           Double_t dy = h.Y() - y0;
-           Double_t dz = h.Z() - z0;
-           Double_t d2 = dy*dy + dz*dz;
-           if( d2<currd2 ){
-             currhit = &h;
-             currd2 = d2;
-           }
-           continue;
-         }else{
-           if( currhit != 0 ){ 
-             //* update track  
-             t0.Filter(currhit->Y(), currhit->Z(), currhit->ErrY(), currhit->ErrZ());
-             currhit = 0;
-           }
-           if( h.ISlice() != currslice ){
-             //* Rotate to the new slice
-             currhit = 0;
-             if( !t0.Rotate( -fSlices[currslice].Param().Alpha() +fSlices[h.ISlice()].Param().Alpha() ) ) break;       
-             currslice = h.ISlice();
-             //currrow = 300;
-             currd2 = 1.e10;
-           }
-           //* search for missed hits in rows
-           {
-             Double_t factor2 = 3.5*3.5;
-             AliHLTTPCCATracker &cslice = fSlices[currslice];        
-             for( Int_t srow=currrow-1; srow>h.IRow(); srow--){
-               AliHLTTPCCARow &row = cslice.Rows()[srow];
-               if( !t0.TransportToX( row.X() ) ) continue;
-               Int_t bestsh = -1;
-               Double_t ds = 1.e10;
-               for( Int_t ish=0; ish<row.NHits(); ish++ ){
-                 AliHLTTPCCAHit &sh = row.Hits()[ish];
-                 Double_t dy = sh.Y() - t0.GetY();
-                 Double_t dz = sh.Z() - t0.GetZ();
-                 Double_t dds = dy*dy+dz*dz;
-                 if( dds<ds ){
-                   ds = dds;
-                   bestsh = ish;
-                 }
-               }
-               if( bestsh<0 ) continue;
-               AliHLTTPCCAHit &sh = row.Hits()[bestsh];
-               Double_t dy = sh.Y() - t0.GetY();
-               Double_t dz = sh.Z() - t0.GetZ();
-               Double_t s2z = /*t0.GetErr2Z() + */ sh.ErrZ()*sh.ErrZ();
-               if( dz*dz>factor2*s2z ) continue;               
-               Double_t s2y = /*t0.GetErr2Y() + */ sh.ErrY()*sh.ErrY();
-               if( dy*dy>factor2*s2y ) continue;
-               //* update track          
-               t0.Filter(sh.Y(), sh.Z(), sh.ErrY()/.33, sh.ErrZ()/.33);
-               fTrackHits[nTrackHits+t.NHits()] = sh.ID();
-               t.NHits()++;
-             }
-           }
-           //* transport to the new row
-           currrow = h.IRow();  
-           Bool_t ok = t0.TransportToX( h.X() );       
-           if( ok ){
-             currrow = h.IRow();
-             Double_t dy = h.Y() - t0.GetY();
-             Double_t dz = h.Z() - t0.GetZ();
-             currd2 = dy*dy + dz*dz;
-             currhit = &h;
-           }
-         }
-       }
-       if( currhit != 0 ){ // update track
-         
-         t0.Filter(currhit->Y(), currhit->Z(), currhit->ErrY(), currhit->ErrZ());
-       }
-       
-       //* search for missed hits in rows
-       {
-         Double_t factor2 = 3.5*3.5;
-         for( Int_t srow=currrow-1; srow>=0; srow--){
-           AliHLTTPCCATracker *cslice = &(fSlices[currslice]);
-           AliHLTTPCCARow *row = &(cslice->Rows()[srow]);
-           if( !t0.TransportToX( row->X() ) ) continue;
-           if( t0.GetY() > row->MaxY() ){ //next slice
-             Int_t j = currslice+1;
-             if( currslice==fNSlices/2-1 ) j = 0;
-             else if( currslice==fNSlices-1 ) j = fNSlices/2;
-             //* 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()[srow]);
-             if( !t0.TransportToX( row->X() ) ) continue;              
-           }else if( t0.GetY() < -row->MaxY() ){ //prev slice
-             Int_t j = currslice-1;
-             if( currslice==0 ) j = fNSlices/2-1;
-             else if( currslice==fNSlices/2 ) j = fNSlices-1;
-             //* 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()[srow]);
-             if( !t0.TransportToX( row->X() ) ) continue;              
-           }
-           Int_t bestsh = -1;
-           Double_t ds = 1.e10;
-           for( Int_t ish=0; ish<row->NHits(); ish++ ){
-             AliHLTTPCCAHit &sh = row->Hits()[ish];
-             Double_t dy = sh.Y() - t0.GetY();
-             Double_t dz = sh.Z() - t0.GetZ();
-             Double_t dds = dy*dy+dz*dz;
-             if( dds<ds ){
-               ds = dds;
-               bestsh = ish;
-             }
-           }
-           if( bestsh<0 ) continue;
-           AliHLTTPCCAHit &sh = row->Hits()[bestsh];
-           Double_t dy = sh.Y() - t0.GetY();
-           Double_t dz = sh.Z() - t0.GetZ();
-           Double_t s2z = /*t0.GetErr2Z() + */ sh.ErrZ()*sh.ErrZ();
-           if( dz*dz>factor2*s2z ) continue;           
-           Double_t s2y = /*t0.GetErr2Y() + */ sh.ErrY()*sh.ErrY();
-           if( dy*dy>factor2*s2y ) continue;
-           //* update track      
-           t0.Filter(sh.Y(), sh.Z(), sh.ErrY()/.33, sh.ErrZ()/.33);
-           fTrackHits[nTrackHits+t.NHits()] = sh.ID();
-           t.NHits()++;
-         }     
-       }
-       if( vhits ) delete[] vhits;
-
-       //* search for missed hits in rows
-       {
-         Double_t factor2 = 3.5*3.5;   
-         AliHLTTPCCAGBHit &h0 = fHits[fTrackHits[t.FirstHitRef()]];
-         
-         Bool_t ok = t0.Rotate( -fSlices[currslice].Param().Alpha() +fSlices[h0.ISlice()].Param().Alpha() );
-         
-         currslice = h0.ISlice();
-         currrow = h0.IRow();
-         
-         for( Int_t srow=currrow+1; srow<fSlices[0].Param().NRows()&&ok; srow++){
-           AliHLTTPCCATracker *cslice = &(fSlices[currslice]);
-           AliHLTTPCCARow *row = &(cslice->Rows()[srow]);
-           if( !t0.TransportToX( row->X() ) ) continue;
-           if( t0.GetY() > row->MaxY() ){ //next slice
-             Int_t j = currslice+1;
-             if( currslice==fNSlices/2-1 ) j = 0;
-             else if( currslice==fNSlices-1 ) j = fNSlices/2;
-             //* 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()[srow]);
-             if( !t0.TransportToX( row->X() ) ) continue;              
-           }else if( t0.GetY() < -row->MaxY() ){ //prev slice
-             Int_t j = currslice-1;
-             if( currslice==0 ) j = fNSlices/2-1;
-             else if( currslice==fNSlices/2 ) j = fNSlices-1;
-             //* 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()[srow]);
-             if( !t0.TransportToX( row->X() ) ) continue;              
-           }
-           Int_t bestsh = -1;
-           Double_t ds = 1.e10;
-           for( Int_t ish=0; ish<row->NHits(); ish++ ){
-             AliHLTTPCCAHit &sh = row->Hits()[ish];
-             Double_t dy = sh.Y() - t0.GetY();
-             Double_t dz = sh.Z() - t0.GetZ();
-             Double_t dds = dy*dy+dz*dz;
-             if( dds<ds ){
-               ds = dds;
-               bestsh = ish;
-             }
-           }
-           if( bestsh<0 ) continue;
-           AliHLTTPCCAHit &sh = row->Hits()[bestsh];
-           Double_t dy = sh.Y() - t0.GetY();
-           Double_t dz = sh.Z() - t0.GetZ();
-           Double_t s2z = /*t0.GetErr2Z() + */ sh.ErrZ()*sh.ErrZ();
-           if( dz*dz>factor2*s2z ) continue;           
-           Double_t s2y = /*t0.GetErr2Y() + */ sh.ErrY()*sh.ErrY();
-           if( dy*dy>factor2*s2y ) continue;
-           //* update track      
-           t0.Filter(sh.Y(), sh.Z(), sh.ErrY()/.33, sh.ErrZ()/.33);
-           fTrackHits[nTrackHits+t.NHits()] = sh.ID();
-           t.NHits()++;
-         }     
-       }
-       
-       Bool_t ok=1;
-       {
-         for( int i=0; i<15; i++ ) ok = ok && finite(t0.Cov()[i]);
-         for( int i=0; i<5; i++ ) ok = ok && finite(t0.Par()[i]);
-         ok = ok && (t0.GetX()>50);
-       }
-       if(!ok) continue;
-       if( TMath::Abs(t0.Kappa())<1.e-8 ) t0.Kappa() = 1.e-8;
-       if( nHitsOld != t.NHits() ){
-         //cout<<"N matched hits = "<<(t.NHits() - nHitsOld )<<" / "<<nHitsOld<<endl;
-       }
-
-       t.Param() = t0;
-       t.Alpha() = fSlices[currslice].Param().Alpha();
-       if( t.NHits()<50 ) continue;
-       nTrackHits+= t.NHits();
-       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
+
+}
+
+
+
+Bool_t AliHLTTPCCAGBTracker::FitTrack( AliHLTTPCCATrackParam &T, AliHLTTPCCATrackParam t0, 
+                                      Float_t &Alpha, Int_t hits[], Int_t &NTrackHits,
+                                      Bool_t dir )
+{
+  // Fit the track
   
-  //* selection  
+  //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 );
 
-  {
-    AliHLTTPCCAGBTrack *vtracks = new AliHLTTPCCAGBTrack [fNTracks];
-    Int_t *vhits = new Int_t [fNHits];
-    AliHLTTPCCAGBTrack **vptracks = new AliHLTTPCCAGBTrack* [fNTracks];
+  Int_t hitsNew[1000];
+  Int_t nHitsNew = 0;
 
-    for( Int_t itr=0; itr<fNTracks; itr++ ){
-      vptracks[itr] = &(fTracks[itr]);
+  for( Int_t ihit=0; ihit<NTrackHits; ihit++){
+    
+    Int_t jhit = dir ?(NTrackHits-1-ihit) :ihit;
+    AliHLTTPCCAGBHit &h = fHits[hits[jhit]];
+
+    Int_t iSlice = h.ISlice();
+
+    Float_t sliceAlpha =  fSlices[0].Param().Alpha( iSlice );
+
+    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()<50 ) continue;
-      nHits+=to.NHits();
-      nTracks++;
+
+    //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;
+
+    
+    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;                
+
+    first = 0;
+
+    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::WriteSettings( std::ostream &out ) const
+{
+  //* 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( std::istream &in )
+{
+  //* Read settings from the file
+  Int_t nSlices=0;
+  in >> nSlices;
+  SetNSlices( nSlices );
+  for( Int_t iSlice=0; iSlice<NSlices(); iSlice++ ){    
+    AliHLTTPCCAParam param;
+    param.ReadSettings ( in );
+    fSlices[iSlice].Initialize( param ); 
+  }
+}
+
+void AliHLTTPCCAGBTracker::WriteEvent( std::ostream &out ) const
+{
+  // write event to the file
+
+  out<<NHits()<<std::endl;
+  for (Int_t ih=0; ih<NHits(); ih++) {
+    AliHLTTPCCAGBHit &h = fHits[ih];
+    out<<h.X()<<" ";
+    out<<h.Y()<<" ";
+    out<<h.Z()<<" ";
+    out<<h.ErrY()<<" ";
+    out<<h.ErrZ()<<" ";
+    out<<h.Amp()<<" ";
+    out<<h.ID()<<" ";
+    out<<h.ISlice()<<" ";
+    out<<h.IRow()<<std::endl;
+  }
+}
+
+void AliHLTTPCCAGBTracker::ReadEvent( std::istream &in ) 
+{
+  //* Read event from file 
+
+  StartEvent();
+  Int_t nHits;
+  in >> nHits;
+  SetNHits(nHits);
+  for (Int_t i=0; i<nHits; i++) {
+    Float_t x, y, z, errY, errZ;
+    Float_t amp;
+    Int_t id, iSlice, iRow;
+    in>>x>>y>>z>>errY>>errZ>>amp>>id>>iSlice>>iRow;
+    ReadHit( x, y, z, errY, errZ, amp, id, iSlice, iRow );
+  }
+}
+
+void AliHLTTPCCAGBTracker::WriteTracks( std::ostream &out ) const 
+{
+  //* Write tracks to file 
+
+  out<<fSliceTrackerTime<<std::endl;
+  Int_t nTrackHits = 0;
+  for( Int_t itr=0; itr<fNTracks; itr++ ){
+    nTrackHits+=fTracks[itr].NHits();
+  }
+  out<<nTrackHits<<std::endl;
+  for( Int_t ih=0; ih<nTrackHits; ih++ ){
+    out<< fTrackHits[ih]<<" ";
+  }
+  out<<std::endl;
+  
+  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()<<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( std::istream &in )
+{
+  //* Read tracks  from file 
+
+  in>>fTime;
+  fSliceTrackerTime = fTime;
+  fStatTime[0]+=fTime;
+  fStatNEvents++;
+  if( fTrackHits ) delete[] fTrackHits;
+  fTrackHits = 0;  
+  Int_t nTrackHits = 0;
+  in >> nTrackHits;
+  fTrackHits = new Int_t [nTrackHits];
+  for( Int_t ih=0; ih<nTrackHits; ih++ ){
+    in >> TrackHits()[ih];
+  }
+  if( fTracks ) delete[] fTracks;
+  fTracks = 0;  
+  in >> fNTracks;
+  fTracks = new AliHLTTPCCAGBTrack[fNTracks];
+  for( Int_t itr=0; itr<NTracks(); itr++ ){
+    AliHLTTPCCAGBTrack &t = Tracks()[itr];    
+    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);     
+  }
 }