]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/comp/AliL3DataCompressor.cxx
New version of TOF tracker which uses TOF clusters as an input (A. De Caro)
[u/mrichter/AliRoot.git] / HLT / comp / AliL3DataCompressor.cxx
index 372074c9be257bb4c063a9ac5d0f4159fb2573bf..cebd9e81b7cea7e9f63cca94d58145e18301d8ac 100644 (file)
@@ -2,6 +2,13 @@
 
 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
 //*-- Copyright &copy ALICE HLT Group
+//_____________________________________________________________
+//
+//  AliL3DataCompression
+//
+// Interface class; binary <-> AliROOT handling of TPC data compression classes.
+//
+
 
 #include "AliL3StandardIncludes.h"
 
@@ -10,7 +17,7 @@
 #include "AliL3Transform.h"
 #include "AliL3MemHandler.h"
 #include "AliL3SpacePointData.h"
-#include "AliL3Compress.h"
+#include "AliL3CompressAC.h"
 #include "AliL3TrackArray.h"
 #include "AliL3ModelTrack.h"
 #include "AliL3Benchmark.h"
 
 #ifdef use_aliroot
 #include "AliL3FileHandler.h"
-
-#include <AliKalmanTrack.h>
-#include <AliTPCtracker.h>
 #include <AliTPCcluster.h>
 #include <AliTPCParamSR.h>
 #include <AliTPCDigitsArray.h>
 #include <AliTPCClustersArray.h>
-#include <AliTPCcluster.h>
 #include <AliTPCClustersRow.h>
 #include <AliSimDigits.h>
 #include <AliTPC.h>
 
 #ifdef use_root
 #include <TFile.h>
-#include <TMath.h>
 #include <TDirectory.h>
 #include <TSystem.h>
 #include <TH2F.h>
 #endif
 
+#include "AliL3DataCompressorHelper.h"
 #include "AliL3DataCompressor.h"
+#include <math.h>
 
-#if GCCVERSION == 3
+#if __GNUC__ == 3
 using namespace std;
 #endif
 
-//_____________________________________________________________
-//
-//  AliL3DataCompression
-//
-// Interface class; binary <-> AliROOT handling of TPC data compression classes.
-//
-
 
 ClassImp(AliL3DataCompressor)
 
-Int_t AliL3DataCompressor::fNumTimeBits = 12;
-Int_t AliL3DataCompressor::fNumPadBits = 12;
-Int_t AliL3DataCompressor::fNumChargeBits = 14;
-Int_t AliL3DataCompressor::fNumShapeBits = 14;
-Float_t AliL3DataCompressor::fXYResidualStep = 0.03;
-Float_t AliL3DataCompressor::fZResidualStep = 0.05;
-Float_t AliL3DataCompressor::fXYWidthStep = 0.005;
-Float_t AliL3DataCompressor::fZWidthStep = 0.005;
-Int_t AliL3DataCompressor::fClusterCharge = 100;
-
 AliL3DataCompressor::AliL3DataCompressor()
 {
+  // default constructor
   fBenchmark=0;
   fInputTracks=0;
   fKeepRemaining=kTRUE;
+  fNoCompression=kFALSE;
   fEvent=0;
   fWriteClusterShape=kFALSE;
   fOutputFile=0;
   fCompRatioFile=0;
+  fNusedClusters=0;
+  fNunusedClusters=0;
   memset(fClusters,0,36*6*sizeof(AliL3SpacePointData*));
 }
 
 AliL3DataCompressor::AliL3DataCompressor(Char_t *path,Bool_t keep,Bool_t writeshape)
 {
+  // constructor
   strcpy(fPath,path);
   fBenchmark = new AliL3Benchmark();
   fInputTracks=0;
@@ -88,6 +80,9 @@ AliL3DataCompressor::AliL3DataCompressor(Char_t *path,Bool_t keep,Bool_t writesh
   fWriteClusterShape = writeshape;
   fEvent=0;
   fOutputFile=0;
+  fNusedClusters=0;
+  fNunusedClusters=0;
+  fNoCompression=kFALSE;
   memset(fClusters,0,36*6*sizeof(AliL3SpacePointData*));
 #ifdef use_root
   Char_t name[1024];
@@ -99,6 +94,7 @@ AliL3DataCompressor::AliL3DataCompressor(Char_t *path,Bool_t keep,Bool_t writesh
 
 AliL3DataCompressor::~AliL3DataCompressor()
 {
+  // destructor
   if(fInputTracks)
     delete fInputTracks;
   if(fBenchmark)
@@ -115,28 +111,13 @@ AliL3DataCompressor::~AliL3DataCompressor()
 
 void AliL3DataCompressor::DoBench(Char_t *fname)
 {
+  // does benchmarking
   fBenchmark->Analyze(fname);
 }
 
-void AliL3DataCompressor::SetBitNumbers(Int_t pad,Int_t time,Int_t charge,Int_t shape)
-{
-  fNumPadBits = pad;
-  fNumTimeBits = time;
-  fNumChargeBits = charge;
-  fNumShapeBits = shape;
-}
-
-void AliL3DataCompressor::SetResolutions(Float_t xyresidual,Float_t zresidual,Int_t clustercharge,Float_t xywidth,Float_t zwidth)
-{
-  fXYResidualStep = xyresidual;
-  fZResidualStep = zresidual;
-  fXYWidthStep = xywidth;
-  fZWidthStep = zwidth;
-  fClusterCharge = clustercharge;
-}
-
 void AliL3DataCompressor::OpenOutputFile()
 {
+  // opens the output file
 #ifndef use_aliroot
    LOG(AliL3Log::kError,"AliL3DataCompressor::OpenOutputFile","Version")
      <<"You have to compile with use_aliroot flag in order to use this function"<<ENDLOG;
@@ -162,6 +143,7 @@ void AliL3DataCompressor::OpenOutputFile()
 
 void AliL3DataCompressor::CloseOutputFile()
 {
+  // closes the output file
   if(fCompRatioFile)
     {
       fCompRatioFile->close();
@@ -182,6 +164,7 @@ void AliL3DataCompressor::CloseOutputFile()
 
 void AliL3DataCompressor::LoadData(Int_t event,Bool_t sp)
 {
+  // Loads data
   fSinglePatch=sp;
   fEvent=event;
   AliL3MemHandler *clusterfile[36][6];
@@ -209,6 +192,7 @@ void AliL3DataCompressor::LoadData(Int_t event,Bool_t sp)
        }
     }
   
+  //cout<<endl<<"Reading from offlinecf"<<endl<<endl;
   sprintf(fname,"%s/cf/tracks_%d.raw",fPath,fEvent);
   AliL3MemHandler *tfile = new AliL3MemHandler();
   tfile->SetBinaryInput(fname);
@@ -221,7 +205,7 @@ void AliL3DataCompressor::LoadData(Int_t event,Bool_t sp)
   delete tfile;
 }
 
-void AliL3DataCompressor::FillData(Int_t min_hits,Bool_t expand)
+void AliL3DataCompressor::FillData(Int_t minHits,Bool_t expand)
 {
   
   //Fill the track data into track and cluster structures, and write to file.
@@ -235,8 +219,9 @@ void AliL3DataCompressor::FillData(Int_t min_hits,Bool_t expand)
       AliL3Track *intrack = fInputTracks->GetCheckedTrack(i);
       if(!intrack) continue;
 
-      if(intrack->GetNHits()<min_hits) break;
-
+      if(intrack->GetNHits()<minHits) break;
+      if(intrack->GetPt()<0.1) continue;
+      
       intrack->CalculateHelix();
       
       AliL3ModelTrack *outtrack = (AliL3ModelTrack*)comptracks->NextTrack();
@@ -253,6 +238,7 @@ void AliL3DataCompressor::FillData(Int_t min_hits,Bool_t expand)
       UInt_t *hitids = intrack->GetHitNumbers();
       Int_t origslice = (hitids[nhits-1]>>25)&0x7f;
       outtrack->Init(origslice,-1);
+      
       for(Int_t j=nhits-1; j>=0; j--)
        {
          UInt_t id=hitids[j];
@@ -271,25 +257,26 @@ void AliL3DataCompressor::FillData(Int_t min_hits,Bool_t expand)
          if(!intrack->CalculateReferencePoint(angle,AliL3Transform::Row2X(padrow)))
            {
              cerr<<"AliL3DataCompressor::FillData : Error in crossing point calc on slice "<<slice<<" row "<<padrow<<endl;
-             outtrack->Print(kFALSE);
-             exit(5);
+             break;
+             //outtrack->Print(kFALSE);
+             //exit(5);
            }
          
-         Float_t xyz_cross[3] = {intrack->GetPointX(),intrack->GetPointY(),intrack->GetPointZ()};
-         
+         Float_t xyzCross[3] = {intrack->GetPointX(),intrack->GetPointY(),intrack->GetPointZ()};
+
          Int_t sector,row;
          AliL3Transform::Slice2Sector(slice,padrow,sector,row);
-         AliL3Transform::Global2Raw(xyz_cross,sector,row);
+         AliL3Transform::Global2Raw(xyzCross,sector,row);
          AliL3Transform::Global2Raw(xyz,sector,row);
          
-         outtrack->SetPadHit(padrow,xyz_cross[1]);
-         outtrack->SetTimeHit(padrow,xyz_cross[2]);
+         outtrack->SetPadHit(padrow,xyzCross[1]);
+         outtrack->SetTimeHit(padrow,xyzCross[2]);
+
+         outtrack->SetCrossingAngleLUT(padrow,intrack->GetCrossingAngle(padrow,slice));
+         outtrack->CalculateClusterWidths(padrow,kTRUE);
 
          if(fWriteClusterShape)
            {
-             Float_t angle = intrack->GetCrossingAngle(padrow,slice);
-             outtrack->SetCrossingAngleLUT(padrow,angle);
-             outtrack->CalculateClusterWidths(padrow,kTRUE);
              Int_t patch = AliL3Transform::GetPatch(padrow);
              Float_t sigmaY2 = points[pos].fSigmaY2 / pow(AliL3Transform::GetPadPitchWidth(patch),2);
              Float_t sigmaZ2 = points[pos].fSigmaZ2 / pow(AliL3Transform::GetZWidth(),2);
@@ -301,11 +288,11 @@ void AliL3DataCompressor::FillData(Int_t min_hits,Bool_t expand)
          //IMPORTANT: Set the slice in which cluster is, you need it in AliL3ModelTrack::FillTrack!
          outtrack->GetClusterModel(padrow)->fSlice=slice;
          points[pos].fCharge = 0;//Mark this cluster as used.
+         fNusedClusters++;
        }
       if(!expand)
        outtrack->SetNClusters(AliL3Transform::GetNRows(-1));
     }
-  
   if(expand)
     ExpandTrackData(comptracks);
   
@@ -332,63 +319,63 @@ void AliL3DataCompressor::ExpandTrackData(AliL3TrackArray *tracks)
       Int_t nhits = track->GetNHits();
       //cout<<"Expanding track with "<<nhits<<" clusters"<<endl;
       
-      Int_t last_slice=-1;
+      Int_t lastSlice=-1;
       for(Int_t padrow=AliL3Transform::GetNRows()-1; padrow>=0; padrow--)
        {
          if(track->IsPresent(padrow))
            {
-             last_slice = track->GetClusterModel(padrow)->fSlice;
+             lastSlice = track->GetClusterModel(padrow)->fSlice;
              continue;
            }
          
-         if(last_slice < 0) //the outer cluster is missing, so skip it - it will be written anyhow.
+         if(lastSlice < 0) //the outer cluster is missing, so skip it - it will be written anyhow.
            continue;
          
          //Check the slice of the next padrow:
-         Int_t next_padrow = padrow-1;
-         Int_t next_slice = -1;
-         while(next_padrow >=0)
+         Int_t nextPadrow = padrow-1;
+         Int_t nextSlice = -1;
+         while(nextPadrow >=0)
            {
-             if(track->IsPresent(next_padrow))
+             if(track->IsPresent(nextPadrow))
                {
-                 next_slice = track->GetClusterModel(next_padrow)->fSlice;
+                 nextSlice = track->GetClusterModel(nextPadrow)->fSlice;
                  break;
                }
-             next_padrow--;
+             nextPadrow--;
            }
-         if(next_slice>=0)
-           if(next_slice != last_slice)//The track crosses a slice boundary here
+         if(nextSlice>=0)
+           if(nextSlice != lastSlice)//The track crosses a slice boundary here
              continue;
          
          //UInt_t size;
-         AliL3SpacePointData *points = fClusters[last_slice][0];//->GetDataPointer(size);
+         AliL3SpacePointData *points = fClusters[lastSlice][0];//->GetDataPointer(size);
          
          Float_t angle = 0;
-         AliL3Transform::Local2GlobalAngle(&angle,last_slice);
+         AliL3Transform::Local2GlobalAngle(&angle,lastSlice);
          if(!track->CalculateReferencePoint(angle,AliL3Transform::Row2X(padrow)))
            continue;
-         Float_t xyz_cross[3] = {track->GetPointX(),track->GetPointY(),track->GetPointZ()};
-         AliL3Transform::Global2Local(xyz_cross,last_slice,kTRUE);
+         Float_t xyzCross[3] = {track->GetPointX(),track->GetPointY(),track->GetPointZ()};
+         AliL3Transform::Global2LocHLT(xyzCross,lastSlice);
          Float_t mindist = 123456789;
          AliL3SpacePointData *closest=0;
-         for(UInt_t j=0; j<fNcl[last_slice][0]; j++)
+         for(UInt_t j=0; j<fNcl[lastSlice][0]; j++)
            {
              if(points[j].fCharge == 0) continue;// || points[j].fPadRow != padrow) continue;
              if(points[j].fPadRow < padrow) continue;
              if(points[j].fPadRow > padrow) break;
              Float_t xyz[3] = {points[j].fX,points[j].fY,points[j].fZ};
-             AliL3Transform::Global2Local(xyz,last_slice,kTRUE);
+             AliL3Transform::Global2LocHLT(xyz,lastSlice);
              
              //Check for overflow:
-             Int_t temp = (Int_t)rint((xyz_cross[1]-xyz[1])/GetXYResidualStep());
-             if( abs(temp) > 1<<(GetNPadBits()-1))
+             Int_t temp = (Int_t)rint((xyzCross[1]-xyz[1])/AliL3DataCompressorHelper::GetXYResidualStep(padrow));
+             if( abs(temp) > 1<<(AliL3DataCompressorHelper::GetNPadBits()-1))
                continue;
              
-             temp = (Int_t)rint((xyz_cross[2]-xyz[2])/GetZResidualStep());
-             if( abs(temp) > 1<<(GetNTimeBits()-1))
+             temp = (Int_t)rint((xyzCross[2]-xyz[2])/AliL3DataCompressorHelper::GetZResidualStep(padrow));
+             if( abs(temp) > 1<<(AliL3DataCompressorHelper::GetNTimeBits()-1))
                continue;
              
-             Float_t dist = sqrt( pow(xyz_cross[1]-xyz[1],2) + pow(xyz_cross[2]-xyz[2],2) );
+             Float_t dist = sqrt( pow(xyzCross[1]-xyz[1],2) + pow(xyzCross[2]-xyz[2],2) );
              if(dist < mindist)
                {
                  closest = &points[j];
@@ -399,16 +386,16 @@ void AliL3DataCompressor::ExpandTrackData(AliL3TrackArray *tracks)
            {
              Int_t sector,row;
              Float_t xyz[3] = {closest->fX,closest->fY,closest->fZ};
-             AliL3Transform::Slice2Sector(last_slice,padrow,sector,row);
-             AliL3Transform::Local2Raw(xyz_cross,sector,row);
+             AliL3Transform::Slice2Sector(lastSlice,padrow,sector,row);
+             AliL3Transform::Local2Raw(xyzCross,sector,row);
              AliL3Transform::Global2Raw(xyz,sector,row);
              
-             track->SetPadHit(padrow,xyz_cross[1]);
-             track->SetTimeHit(padrow,xyz_cross[2]);
+             track->SetPadHit(padrow,xyzCross[1]);
+             track->SetTimeHit(padrow,xyzCross[2]);
              
              if(fWriteClusterShape)
                {
-                 Float_t angle = track->GetCrossingAngle(padrow,last_slice);
+                 Float_t angle = track->GetCrossingAngle(padrow,lastSlice);
                  track->SetCrossingAngleLUT(padrow,angle);
                  track->CalculateClusterWidths(padrow,kTRUE);
                  Int_t patch = AliL3Transform::GetPatch(padrow);
@@ -421,7 +408,7 @@ void AliL3DataCompressor::ExpandTrackData(AliL3TrackArray *tracks)
              nhits++;
              
              //IMPORTANT: Set the slice in which cluster is, you need it in AliL3ModelTrack::FillTrack!
-             track->GetClusterModel(padrow)->fSlice=last_slice;
+             track->GetClusterModel(padrow)->fSlice=lastSlice;
              closest->fCharge = 0;//Mark this cluster as used.
            }
        }
@@ -431,6 +418,60 @@ void AliL3DataCompressor::ExpandTrackData(AliL3TrackArray *tracks)
   
 }
 
+
+
+void AliL3DataCompressor::DetermineMinBits()
+{
+  //Make a pass through the modelled data (after FillData has been done) to determine
+  //how many bits is needed to encode the residuals _without_ overflows.
+  
+  AliL3Compress *comp = new AliL3Compress(-1,-1,fPath,fWriteClusterShape,fEvent);
+  comp->ReadFile('m');
+  AliL3TrackArray *tracks = comp->GetTracks();
+  if(tracks->GetNTracks()==0)
+    {
+      delete comp;
+      return;
+    }
+  
+  Int_t maxtime=0,maxpad=0,maxsigma=0,maxcharge=0;
+  Int_t dpad,dtime,charge,dsigmaY,dsigmaZ,npadbits,ntimebits,nchargebits,nshapebits=0;
+  for(Int_t i=0; i<tracks->GetNTracks(); i++)
+    {
+      AliL3ModelTrack *track = (AliL3ModelTrack*)tracks->GetCheckedTrack(i);
+      if(!track) continue;
+      for(Int_t padrow=0; padrow<AliL3Transform::GetNRows(); padrow++)
+       {
+         if(!track->IsPresent(padrow)) continue;
+         dpad = AliL3DataCompressorHelper::Abs(AliL3DataCompressorHelper::Nint(track->GetClusterModel(padrow)->fDPad));
+         dtime = AliL3DataCompressorHelper::Abs(AliL3DataCompressorHelper::Nint(track->GetClusterModel(padrow)->fDTime));
+         charge = AliL3DataCompressorHelper::Abs((Int_t)track->GetClusterModel(padrow)->fDCharge);
+         dsigmaY = AliL3DataCompressorHelper::Abs(AliL3DataCompressorHelper::Nint(track->GetClusterModel(padrow)->fDSigmaY));
+         dsigmaZ = AliL3DataCompressorHelper::Abs(AliL3DataCompressorHelper::Nint(track->GetClusterModel(padrow)->fDSigmaZ));
+         if(dpad > maxpad)
+           maxpad=dpad;
+         if(dtime > maxtime)
+           maxtime=dtime;
+         if(charge > maxcharge)
+           maxcharge=charge;
+         if(dsigmaY > maxsigma)
+           maxsigma=dsigmaY;
+         if(dsigmaZ > maxsigma)
+           maxsigma=dsigmaZ;
+       }
+    }
+  cout<<"maxpad "<<maxpad<<" maxtime "<<maxtime<<" maxcharge "<<maxcharge<<endl;
+  npadbits = (Int_t)ceil(log(Double_t(maxpad))/log(2.)) + 1; //need 1 extra bit to encode the sign
+  ntimebits = (Int_t)ceil(log(Double_t(maxtime))/log(2.)) + 1;
+  nchargebits = (Int_t)ceil(log(Double_t(maxcharge))/log(2.)); //Store as a absolute value
+  if(fWriteClusterShape)
+    nshapebits = (Int_t)ceil(log(Double_t(maxsigma))/log(2.)) + 1;
+  
+  nchargebits = AliL3DataCompressorHelper::GetNChargeBits();
+  cout<<"Updating bitnumbers; pad "<<npadbits<<" time "<<ntimebits<<" charge "<<nchargebits<<" shape "<<nshapebits<<endl;
+  AliL3DataCompressorHelper::SetBitNumbers(npadbits,ntimebits,nchargebits,nshapebits);
+}
+
 void AliL3DataCompressor::WriteRemaining(Bool_t select)
 {
   //Write remaining clusters (not assigned to any tracks) to file
@@ -442,135 +483,168 @@ void AliL3DataCompressor::WriteRemaining(Bool_t select)
   if(select)
     SelectRemainingClusters();
   
-  Char_t filename[1024];
-  
   if(!fSinglePatch)
     {
       cerr<<"AliL3Compressor::WriteRemaining : You have to modify this function when not running singlepatch"<<endl;
       return;
     }
-
-  cout<<"Writing remaining clusters "<<endl;
-  Int_t nrows = AliL3Transform::GetNRows();
-  Int_t *npoints = new Int_t[nrows];
-  for(Int_t i=0; i<=35; i++)
+  if(!fNoCompression)
     {
-      for(Int_t patch=0; patch < 1; patch++)
+      cout<<"Compressing remaining clusters "<<endl;
+      AliL3Compress *comp = new AliL3Compress(-1,-1,fPath,fWriteClusterShape,fEvent);
+      comp->CompressRemaining(fClusters,fNcl);
+      delete comp;
+      return;
+    }
+  else
+    {
+      cout<<"Writing remaining clusters"<<endl;
+      Int_t nrows = AliL3Transform::GetNRows();
+      Int_t *npoints = new Int_t[nrows];
+      Char_t filename[1024];
+      for(Int_t i=0; i<=35; i++)
        {
-         sprintf(filename,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,i,-1);
-         FILE *outfile = fopen(filename,"w");
-         if(!outfile)
+         for(Int_t patch=0; patch < 1; patch++)
            {
-             cerr<<"AliL3DataCompressor::WriteRemaining : Cannot open file "<<filename<<endl;
-             exit(5);
-           }
-         //UInt_t dummy;
-         AliL3SpacePointData *points = fClusters[i][patch];//->GetDataPointer(dummy);
+             sprintf(filename,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,i,-1);
+             FILE *outfile = fopen(filename,"w");
+             if(!outfile)
+               {
+                 cerr<<"AliL3DataCompressor::WriteRemaining : Cannot open file "<<filename<<endl;
+                 exit(5);
+               }
+
+             AliL3SpacePointData *points = fClusters[i][patch];
          
-         memset(npoints,0,nrows*sizeof(Int_t));
+             memset(npoints,0,nrows*sizeof(Int_t));
          
-         for(UInt_t j=0; j<fNcl[i][patch]; j++)
-           {
-             if(points[j].fCharge == 0) continue; //has been used
-             npoints[points[j].fPadRow]++;
-           }
-         Int_t size =0;
-         Byte_t *data = 0;
-         AliL3RemainingRow *tempPt=0;
+             for(UInt_t j=0; j<fNcl[i][patch]; j++)
+               {
+                 if(points[j].fCharge == 0) continue; //has been used
+                 npoints[points[j].fPadRow]++;
+               }
+             Int_t size =0;
+             Byte_t *data = 0;
+             AliL3RemainingRow *tempPt=0;
          
-         Int_t last_row = -2;
-         Int_t localcounter=0;
+             Int_t lastRow = -2;
+             Int_t localcounter=0;
          
-         for(UInt_t j=0; j<fNcl[i][patch]; j++)
-           {
-             if(points[j].fCharge == 0) continue; //has been used
-             
-             Int_t padrow = points[j].fPadRow;
-             if(padrow != last_row)
+             for(UInt_t j=0; j<fNcl[i][patch]; j++)
                {
-                 if(last_row != -2)
+                 if(points[j].fCharge == 0) continue; //has been used
+             
+                 Int_t padrow = points[j].fPadRow;
+                 if(padrow != lastRow)
                    {
-                     if(!tempPt)
+                     if(lastRow != -2)
                        {
-                         cerr<<"AliL3DataCompressor::WriteRemaining : Zero row pointer "<<endl;
-                         exit(5);
+                         if(!tempPt)
+                           {
+                             cerr<<"AliL3DataCompressor::WriteRemaining : Zero row pointer "<<endl;
+                             exit(5);
+                           }
+                         if(localcounter != tempPt->fNClusters)
+                           {
+                             cerr<<"AliL3DataCompressor::WriteRemaining : Mismatching clustercounter "<<localcounter<<" "
+                                 <<(Int_t)tempPt->fNClusters<<endl;
+                             exit(5);
+                           }
+                         //cout<<"Writing row "<<(int)tempPt->fPadRow<<" with "<<(int)tempPt->fNClusters<<" clusters"<<endl;
+                         fwrite(tempPt,size,1,outfile);
                        }
-                     if(localcounter != tempPt->fNClusters)
-                       {
-                         cerr<<"AliL3DataCompressor::WriteRemaining : Mismatching clustercounter "<<localcounter<<" "
-                             <<(Int_t)tempPt->fNClusters<<endl;
-                         exit(5);
-                       }
-                     //cout<<"Writing row "<<(int)tempPt->fPadRow<<" with "<<(int)tempPt->fNClusters<<" clusters"<<endl;
-                     fwrite(tempPt,size,1,outfile);
+                     if(data)
+                       delete [] data;
+                     size = sizeof(AliL3RemainingRow) + npoints[padrow]*sizeof(AliL3RemainingCluster);
+                     data = new Byte_t[size];
+                     tempPt = (AliL3RemainingRow*)data;
+                 
+                     localcounter=0;
+                     tempPt->fPadRow = padrow;
+                     tempPt->fNClusters = npoints[padrow];
+                     lastRow = padrow;
+                   }
+                 if(localcounter >= npoints[padrow])
+                   {
+                     cerr<<"AliL3DataCompressor::WriteRemaining : Cluster counter out of range: "
+                         <<localcounter<<" "<<npoints[padrow]<<endl;
+                     exit(5);
                    }
-                 if(data)
-                   delete [] data;
-                 size = sizeof(AliL3RemainingRow) + npoints[padrow]*sizeof(AliL3RemainingCluster);
-                 data = new Byte_t[size];
-                 tempPt = (AliL3RemainingRow*)data;
+             
+                 Float_t xyz[3] = {points[j].fX,points[j].fY,points[j].fZ};
+                 Int_t sector,row;
+                 AliL3Transform::Slice2Sector(i,padrow,sector,row);
+                 AliL3Transform::Global2Raw(xyz,sector,row);
                  
-                 localcounter=0;
-                 tempPt->fPadRow = padrow;
-                 tempPt->fNClusters = npoints[padrow];
-                 last_row = padrow;
+                 Float_t padw = points[j].fSigmaY2 / pow(AliL3Transform::GetPadPitchWidth(AliL3Transform::GetPatch(padrow)),2);
+                 Float_t timew = points[j].fSigmaZ2 / pow(AliL3Transform::GetZWidth(),2);
+                 tempPt->fClusters[localcounter].fPad = xyz[1];
+                 tempPt->fClusters[localcounter].fTime = xyz[2];
+                 tempPt->fClusters[localcounter].fCharge = points[j].fCharge;
+                 tempPt->fClusters[localcounter].fSigmaY2 = padw;
+                 tempPt->fClusters[localcounter].fSigmaZ2 = timew;
+                 localcounter++;
+                 fNunusedClusters++;
                }
-             if(localcounter >= npoints[padrow])
-               {
-                 cerr<<"AliL3DataCompressor::WriteRemaining : Cluster counter out of range: "
-                     <<localcounter<<" "<<npoints[padrow]<<endl;
-                 exit(5);
-               }
-             
-             Float_t xyz[3] = {points[j].fX,points[j].fY,points[j].fZ};
-             AliL3Transform::Global2Local(xyz,i,kTRUE);
              
-             tempPt->fClusters[localcounter].fY = xyz[1];
-             tempPt->fClusters[localcounter].fZ = xyz[2];
-             tempPt->fClusters[localcounter].fCharge = points[j].fCharge;
-             tempPt->fClusters[localcounter].fSigmaY2 = points[j].fSigmaY2;
-             tempPt->fClusters[localcounter].fSigmaZ2 = points[j].fSigmaZ2;
-             localcounter++;
+             //Write the last row:
+             fwrite(tempPt,size,1,outfile);
+             if(data)
+               delete [] data;
+             fclose(outfile);
            }
-         //Write the last row:
-         //cout<<"Writing row "<<(int)tempPt->fPadRow<<" with "<<(int)tempPt->fNClusters<<" clusters"<<endl;
-         fwrite(tempPt,size,1,outfile);
-         if(data)
-           delete [] data;
-         fclose(outfile);
        }
-    }
-  delete [] npoints;
+      delete [] npoints;
+    }  
 }
 
 void AliL3DataCompressor::SelectRemainingClusters()
 {
   //Select which remaining clusters to write in addition to the compressed data.
-
+  //In particular one can here make sure that "important" clusters are not missed:
+  //The offline track finder perform seed finding in the outer padrows;
+  //the first seeding is using pair of points on outermost padrow and 
+  //0.125*nrows more rows towards the vertex. The second seeding uses pair
+  //of points on the outermost padrow-0.5*0.125*nrows and 0.125*nrows + 0.5*0.125*nrows
+  //more rows towards the vertex. In order to evaluate the seeds, the track offline
+  //track finder checks whether a certain amount of possible clusters (padrows) is 
+  //attached to the track, and then the kalman filtering starts.
+  //To ensure a minimal loss off efficiency, all clusters in this region should be
+  //intact.....
+  
   cout<<"Cleaning up clusters"<<endl;
   Int_t nrows = AliL3Transform::GetNRows();
   Int_t gap=(Int_t)(0.125*nrows), shift=(Int_t)(0.5*gap);
   
   for(Int_t slice=0; slice<36; slice++)
     {
-      //UInt_t dummy;
-      AliL3SpacePointData *points = fClusters[slice][0];//->GetDataPointer(dummy);
+      AliL3SpacePointData *points = fClusters[slice][0];
       for(UInt_t i=0; i<fNcl[slice][0]; i++)
        {
          if(points[i].fCharge == 0) continue; //Already removed
          Int_t padrow = (Int_t)points[i].fPadRow;
          
+         //Check the widths (errors) of the cluster, and remove big bastards:
+         Float_t padw = sqrt(points[i].fSigmaY2) / AliL3Transform::GetPadPitchWidth(AliL3Transform::GetPatch(padrow));
+         Float_t timew = sqrt(points[i].fSigmaZ2) / AliL3Transform::GetZWidth();
+         if(padw >= 2.55 || timew >= 2.55)//Because we use 1 byte to store
+           {
+             points[i].fCharge = 0;
+             continue;
+           }
+
          Float_t xyz[3] = {points[i].fX,points[i].fY,points[i].fZ};
          Int_t sector,row;
          AliL3Transform::Slice2Sector(slice,padrow,sector,row);
          AliL3Transform::Global2Raw(xyz,sector,row);
          
-         if(padrow >= nrows-1-gap-shift) continue;
+         if(padrow >= nrows-1-gap-shift) continue;//save all the clusters in this region
+         
          //if(padrow >= nrows-1-shift) continue;
 
          //Save the clusters at the borders:
-         if(xyz[1] < 3 || xyz[1] >= AliL3Transform::GetNPads(padrow)-4)
-           continue;
+         //if(xyz[1] < 3 || xyz[1] >= AliL3Transform::GetNPads(padrow)-4)
+         // continue;
 
          //Save clusters on padrows used for offline seeding:
          if(padrow == nrows - 1 || padrow == nrows - 1 - gap ||                 //First seeding
@@ -584,19 +658,36 @@ void AliL3DataCompressor::SelectRemainingClusters()
   
 }
 
-void AliL3DataCompressor::CompressAndExpand()
+void AliL3DataCompressor::CompressAndExpand(Bool_t arithmeticCoding)
 {
   //Read tracks/clusters from file, compress data and uncompress it. Write compression rates to file.
+  if(fNoCompression)
+    return;
+  
   cout<<"Compressing and expanding data"<<endl;
-  AliL3Compress *comp = new AliL3Compress(-1,-1,fPath,fWriteClusterShape,fEvent);
+  AliL3Compress *comp = 0;
+  if(arithmeticCoding)
+    comp = new AliL3CompressAC(-1,-1,fPath,fWriteClusterShape,fEvent);
+  else
+    comp = new AliL3Compress(-1,-1,fPath,fWriteClusterShape,fEvent);
   comp->CompressFile();
   comp->ExpandFile();
   comp->PrintCompRatio(fCompRatioFile);
   delete comp;
+  
+  ofstream &out = *fCompRatioFile;
+  out<<AliL3DataCompressorHelper::GetNPadBits()<<' '<<AliL3DataCompressorHelper::GetNTimeBits()<<' '
+     <<AliL3DataCompressorHelper::GetNChargeBits()<<' '<<AliL3DataCompressorHelper::GetNShapeBits()<<' '
+     <<AliL3DataCompressorHelper::GetNPadBitsRemaining()<<' '<<AliL3DataCompressorHelper::GetNTimeBitsRemaining()<<' '
+     <<AliL3DataCompressorHelper::GetNShapeBitsRemaining()<<endl;
+  /*
+  //Write the ratio between used and unused clusters to comp file:
+  out<<fNusedClusters<<' '<<fNunusedClusters<<endl;
+  */
 }
 
 
-void AliL3DataCompressor::RestoreData()
+void AliL3DataCompressor::RestoreData(Bool_t remainingOnly)
 {
   //Restore the uncompressed data together with the remaining clusters,
   //and write to a final cluster file which serves as an input to the
@@ -609,19 +700,20 @@ void AliL3DataCompressor::RestoreData()
 
   cout<<"Restoring data"<<endl;
   
-  const Int_t maxpoints=500000;
+  const Int_t kmaxpoints=500000;
   TempCluster **clusters = new TempCluster*[36];
   Int_t *ncl = new Int_t[36];
   for(Int_t i=0; i<36; i++)
     {
       ncl[i]=0;
-      clusters[i] = new TempCluster[maxpoints];
+      clusters[i] = new TempCluster[kmaxpoints];
     }
   
-  ReadUncompressedData(clusters,ncl,maxpoints);
-  
+  if(!remainingOnly)
+    ReadUncompressedData(clusters,ncl,kmaxpoints);
+    
   if(fKeepRemaining)
-    ReadRemaining(clusters,ncl,maxpoints);
+    ReadRemaining(clusters,ncl,kmaxpoints);
   
   Char_t filename[1024];
   sprintf(filename,"%s/digitfile.root",fPath);
@@ -650,14 +742,15 @@ void AliL3DataCompressor::RestoreData()
   Int_t totcounter=0;
   for(Int_t slice=0; slice<=35; slice++)
     {
-      TempCluster **clPt = new TempCluster*[maxpoints];
+      TempCluster **clPt = new TempCluster*[kmaxpoints];
       cout<<"Sorting "<<ncl[slice]<<" clusters in slice "<<slice<<endl;
       for(Int_t i=0; i<ncl[slice]; i++)
        clPt[i] = &clusters[slice][i];
       
-      QSort(clPt,0,ncl[slice]);
+      if(fNusedClusters)
+       QSort(clPt,0,ncl[slice]);
       
-      //cout<<"padrow "<<clPt[i]->padrow<<" pad "<<clPt[i]->pad<<" time "<<clPt[i]->time<<endl;
+      //cout<<"padrow "<<clPt[i]->fPadrow<<" pad "<<clPt[i]->fPad<<" time "<<clPt[i]->fTime<<endl;
 
       Int_t falseid=0;
       Int_t counter=0;
@@ -670,20 +763,20 @@ void AliL3DataCompressor::RestoreData()
          digits->ExpandBuffer();
          digits->ExpandTrackBuffer();
          Int_t patch = AliL3Transform::GetPatch(padrow);
-         while(counter < ncl[slice] && clPt[counter]->padrow == padrow)
+         while(counter < ncl[slice] && clPt[counter]->fPadrow == padrow)
            {
              Float_t temp[3];
-             AliL3Transform::Raw2Local(temp,sec,row,clPt[counter]->pad,clPt[counter]->time);
+             AliL3Transform::Raw2Local(temp,sec,row,clPt[counter]->fPad,clPt[counter]->fTime);
              
              AliTPCcluster *c = new AliTPCcluster();
              c->SetY(temp[1]);
              c->SetZ(temp[2]);
-             c->SetQ(clPt[counter]->charge);
+             c->SetQ(clPt[counter]->fCharge);
              
-             c->SetSigmaY2(clPt[counter]->sigmaY2*pow(AliL3Transform::GetPadPitchWidth(patch),2));
-             c->SetSigmaZ2(clPt[counter]->sigmaZ2*pow(AliL3Transform::GetZWidth(),2));
-             Int_t pad = TMath::Nint(clPt[counter]->pad);
-             Int_t time = TMath::Nint(clPt[counter]->time);
+             c->SetSigmaY2(clPt[counter]->fSigmaY2*pow(AliL3Transform::GetPadPitchWidth(patch),2));
+             c->SetSigmaZ2(clPt[counter]->fSigmaZ2*pow(AliL3Transform::GetZWidth(),2));
+             Int_t pad = AliL3DataCompressorHelper::Nint(clPt[counter]->fPad);
+             Int_t time = AliL3DataCompressorHelper::Nint(clPt[counter]->fTime);
              
              if(pad < 0)
                pad=0;
@@ -708,7 +801,7 @@ void AliL3DataCompressor::RestoreData()
                      //cout<<"slice "<<slice<<" padrow "<<padrow<<" y "<<temp[1]<<" z "<<temp[2]<<" label "<<c->GetLabel(0)<<endl;
                    }
                }
-             //cout<<"row "<<padrow<<" pad "<<clPt[counter]->pad<<" time "<<clPt[counter]->time<<" sigmaY2 "<<c->GetSigmaY2()<<" sigmaZ2 "<<c->GetSigmaZ2()<<endl;
+             //cout<<"row "<<padrow<<" pad "<<clPt[counter]->fPad<<" time "<<clPt[counter]->fTime<<" sigmaY2 "<<c->GetSigmaY2()<<" sigmaZ2 "<<c->GetSigmaZ2()<<endl;
              clrow->InsertCluster(c);
              delete c;
              counter++;
@@ -740,17 +833,24 @@ void AliL3DataCompressor::RestoreData()
 #endif
 }
 
-void AliL3DataCompressor::ReadUncompressedData(TempCluster **clusters,Int_t *ncl,const Int_t maxpoints)
+void AliL3DataCompressor::ReadUncompressedData(TempCluster **clusters,Int_t *ncl,const Int_t kmaxpoints)
 {
-
-  cout<<"Reading uncompressed tracks "<<endl;
+  // Reads uncompressed data  
   AliL3Compress *comp = new AliL3Compress(-1,-1,fPath,fWriteClusterShape,fEvent);
-  
-  if(!comp->ReadFile('u'))
-    return;
+  if(fNoCompression)
+    {
+      cout<<endl<<"Reading unmodified data, no compression has been done here!!!!"<<endl<<endl;
+      comp->ReadFile('m');//Read the unmodified data (no compression has been done).
+    }
+  else
+    {
+      cout<<"Reading uncompressed tracks "<<endl;
+      comp->ReadFile('u');
+    }
   
   AliL3TrackArray *tracks = comp->GetTracks();
   
+  //Float_t totcounter=0,pcounter=0,tcounter=0;
   Int_t charge;
   Float_t pad,time,sigmaY2,sigmaZ2;
   for(Int_t i=0; i<tracks->GetNTracks(); i++)
@@ -763,8 +863,8 @@ void AliL3DataCompressor::ReadUncompressedData(TempCluster **clusters,Int_t *ncl
          track->GetPad(padrow,pad);
          track->GetTime(padrow,time);
          track->GetClusterCharge(padrow,charge);
-         track->GetXYWidth(padrow,sigmaY2);
-         track->GetZWidth(padrow,sigmaZ2);
+         track->GetSigmaY2(padrow,sigmaY2);
+         track->GetSigmaZ2(padrow,sigmaZ2);
          Int_t slice = track->GetClusterModel(padrow)->fSlice;
          /*
            if(pad < -1 || pad > AliL3Transform::GetNPads(padrow) || time < -1 || time > AliL3Transform::GetNTimeBins())
@@ -774,104 +874,112 @@ void AliL3DataCompressor::ReadUncompressedData(TempCluster **clusters,Int_t *ncl
            exit(5);
            }
          */
-         if(ncl[slice] >= maxpoints)
+         if(ncl[slice] >= kmaxpoints)
            {
              cerr<<"AliL3DataCompressor::ReadUncompressedData : Too many clusters"<<endl;
              exit(5);
            }
-         clusters[slice][ncl[slice]].pad = pad;
-         clusters[slice][ncl[slice]].time = time;
-         clusters[slice][ncl[slice]].charge = charge;
-         clusters[slice][ncl[slice]].sigmaY2 = sigmaY2;
-         clusters[slice][ncl[slice]].sigmaZ2 = sigmaZ2;
-         clusters[slice][ncl[slice]].padrow = padrow;
+         clusters[slice][ncl[slice]].fPad = pad;
+         clusters[slice][ncl[slice]].fTime = time;
+         clusters[slice][ncl[slice]].fCharge = charge;
+         clusters[slice][ncl[slice]].fSigmaY2 = sigmaY2;
+         clusters[slice][ncl[slice]].fSigmaZ2 = sigmaZ2;
+         clusters[slice][ncl[slice]].fPadrow = padrow;
          //cout<<"row "<<padrow<<" pad "<<pad<<" time "<<time<<" charge "<<charge<<" sigmas "<<sigmaY2<<" "<<sigmaZ2<<endl;
          ncl[slice]++;
        }
     }
-
   delete comp;
 }
 
-void AliL3DataCompressor::ReadRemaining(TempCluster **clusters,Int_t *ncl,const Int_t maxpoints)
+void AliL3DataCompressor::ReadRemaining(TempCluster **clusters,Int_t *ncl,const Int_t kmaxpoints)
 {
-  
-  Char_t filename[1024];
+  // reads remaining clusters  
   cout<<"Reading remaining clusters "<<endl;
-  AliL3MemHandler mem;
-  
-  for(Int_t slice=0; slice<=35; slice++)
+  if(!fNoCompression)
+    {
+      AliL3Compress *comp = new AliL3Compress(-1,-1,fPath,fWriteClusterShape,fEvent);
+      comp->ExpandRemaining(clusters,ncl,kmaxpoints);
+      delete comp;
+      return;
+    }
+  else
     {
-      for(Int_t p=0; p<1; p++)
+      AliL3MemHandler mem;
+      Char_t filename[1024];
+      for(Int_t slice=0; slice<=35; slice++)
        {
-         sprintf(filename,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,slice,-1);
+         for(Int_t p=0; p<1; p++)
+           {
+             sprintf(filename,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,slice,-1);
          
-         mem.SetBinaryInput(filename);
-         AliL3RemainingRow *tempPt = (AliL3RemainingRow*)mem.Allocate();
+             mem.SetBinaryInput(filename);
+             AliL3RemainingRow *tempPt = (AliL3RemainingRow*)mem.Allocate();
          
-         Int_t nrows=0;
-         FILE *infile = mem.GetFilePointer();
-         while(!feof(infile))
-           {
-             Byte_t *dPt = (Byte_t*)tempPt;
-             if(fread(tempPt,sizeof(AliL3RemainingRow),1,infile)!=1) break;
+             Int_t nrows=0;
+             FILE *infile = mem.GetFilePointer();
+             while(!feof(infile))
+               {
+                 Byte_t *dPt = (Byte_t*)tempPt;
+                 if(fread(tempPt,sizeof(AliL3RemainingRow),1,infile)!=1) break;
              
-             dPt += sizeof(AliL3RemainingRow);
+                 dPt += sizeof(AliL3RemainingRow);
              
-             Int_t size = sizeof(AliL3RemainingCluster)*tempPt->fNClusters;
+                 Int_t size = sizeof(AliL3RemainingCluster)*tempPt->fNClusters;
              
-             fread(dPt,size,1,infile);
-             dPt += size;
-             tempPt = (AliL3RemainingRow*)dPt;
-             nrows++;
-           }
+                 fread(dPt,size,1,infile);
+                 dPt += size;
+                 tempPt = (AliL3RemainingRow*)dPt;
+                 nrows++;
+               }
          
-         mem.CloseBinaryInput();
-         UInt_t dummy;
-         tempPt = (AliL3RemainingRow*)mem.GetDataPointer(dummy);
+             mem.CloseBinaryInput();
+             UInt_t dummy;
+             tempPt = (AliL3RemainingRow*)mem.GetDataPointer(dummy);
          
-         for(Int_t i=0; i<nrows; i++)
-           {
-             AliL3RemainingCluster *points = tempPt->fClusters;
-             Int_t padrow = (Int_t)tempPt->fPadRow;
-             Int_t patch = AliL3Transform::GetPatch(padrow);
-             Int_t sector,row;
-             AliL3Transform::Slice2Sector(slice,padrow,sector,row);
-             //cout<<"Loading slice "<<slice<<" row "<<padrow<<" with "<<(Int_t)tempPt->fNClusters<<" clusters "<<endl;
-             for(Int_t j=0; j<tempPt->fNClusters; j++)
+             for(Int_t i=0; i<nrows; i++)
                {
+                 AliL3RemainingCluster *points = tempPt->fClusters;
+                 Int_t padrow = (Int_t)tempPt->fPadRow;
+                 //Int_t sector,row;
+                 //AliL3Transform::Slice2Sector(slice,padrow,sector,row);
+                 //cout<<"Loading slice "<<slice<<" row "<<padrow<<" with "<<(Int_t)tempPt->fNClusters<<" clusters "<<endl;
+                 for(Int_t j=0; j<tempPt->fNClusters; j++)
+                   {
                  
-                 Float_t xyz[3] = {AliL3Transform::Row2X(padrow),points[j].fY,points[j].fZ};
-                 
-                 AliL3Transform::Local2Raw(xyz,sector,row);
+                     //Float_t xyz[3] = {AliL3Transform::Row2X(padrow),points[j].fY,points[j].fZ};
+                     //AliL3Transform::Local2Raw(xyz,sector,row);
                  
-                 if(ncl[slice] >= maxpoints)
-                   {
-                     cerr<<"AliL3DataCompressor::ReadRemaining : Too many clusters"<<endl;
-                     exit(5);
+                     if(ncl[slice] >= kmaxpoints)
+                       {
+                         cerr<<"AliL3DataCompressor::ReadRemaining : Too many clusters"<<endl;
+                         exit(5);
+                       }
+                     //cout<<"slice "<<slice<<" padrow "<<padrow<<" pad "<<xyz[1]<<" time "<<xyz[2]<<endl;
+                     clusters[slice][ncl[slice]].fPad = points[j].fPad;
+                     clusters[slice][ncl[slice]].fTime = points[j].fTime;
+                     clusters[slice][ncl[slice]].fCharge = points[j].fCharge;
+                     clusters[slice][ncl[slice]].fSigmaY2 = points[j].fSigmaY2;
+                     clusters[slice][ncl[slice]].fSigmaZ2 = points[j].fSigmaZ2;
+                     clusters[slice][ncl[slice]].fPadrow = padrow;
+                     //cout<<"padrow "<<padrow<<" pad "<<clusters[slice][ncl[slice]].fPad<<" time "<<clusters[slice][ncl[slice]].fTime<<" charge "<<clusters[slice][ncl[slice]].fCharge<<" widths "<<clusters[slice][ncl[slice]].fSigmaY2<<" "<<clusters[slice][ncl[slice]].fSigmaZ2<<endl;
+                     ncl[slice]++;
                    }
-                 //cout<<"slice "<<slice<<" padrow "<<padrow<<" pad "<<xyz[1]<<" time "<<xyz[2]<<endl;
-                 clusters[slice][ncl[slice]].pad = xyz[1];
-                 clusters[slice][ncl[slice]].time = xyz[2];
-                 clusters[slice][ncl[slice]].charge = points[j].fCharge;
-                 clusters[slice][ncl[slice]].sigmaY2 = points[j].fSigmaY2/pow(AliL3Transform::GetPadPitchWidth(patch),2);
-                 clusters[slice][ncl[slice]].sigmaZ2 = points[j].fSigmaZ2/pow(AliL3Transform::GetZWidth(),2);
-                 clusters[slice][ncl[slice]].padrow = padrow;
-                 ncl[slice]++;
+                 Byte_t *dPt = (Byte_t*)tempPt;
+                 Int_t size = sizeof(AliL3RemainingRow) + tempPt->fNClusters*sizeof(AliL3RemainingCluster);
+                 dPt += size;
+                 tempPt = (AliL3RemainingRow*)dPt;
                }
-             Byte_t *dPt = (Byte_t*)tempPt;
-             Int_t size = sizeof(AliL3RemainingRow) + tempPt->fNClusters*sizeof(AliL3RemainingCluster);
-             dPt += size;
-             tempPt = (AliL3RemainingRow*)dPt;
-           }
          
-         mem.Free();
+             mem.Free();
+           }
        }
     }
 }
 
 void AliL3DataCompressor::QSort(TempCluster **a, Int_t first, Int_t last)
 {
+  // Implementation of quick sort
   static TempCluster *tmp;
    static int i;           // "static" to save stack space
    int j;
@@ -910,224 +1018,15 @@ void AliL3DataCompressor::QSort(TempCluster **a, Int_t first, Int_t last)
 
 Int_t AliL3DataCompressor::Compare(TempCluster *a,TempCluster *b)
 {
-  /*
-  if(a->padrow < 0 || a->padrow > AliL3Transform::GetNRows(-1) ||
-     b->padrow < 0 || b->padrow > AliL3Transform::GetNRows(-1))
-    {
-      cerr<<"AliL3Compressor::Compare : Wrong padrows "<<a->padrow<<" "<<b->padrow<<endl;
-      exit(5);
-    }
-  else if(a->pad < 0 || a->pad > AliL3Transform::GetNPads(a->padrow) || 
-         b->pad < 0 || b->pad > AliL3Transform::GetNPads(b->padrow))
-    {
-      cerr<<"AliL3Compressor::Compare : Wrong pads "<<a->pad<<" "<<b->pad<<endl;
-      exit(5);
-    }
-  else if(a->time < 0 || a->time > AliL3Transform::GetNTimeBins() || 
-         b->time < 0 || b->time > AliL3Transform::GetNTimeBins())
-    {
-      cerr<<"AliL3Compressor::Compare : Wrong timebins "<<a->time<<" "<<b->time<<endl;
-      exit(5);
-    }
-  */
-  if(a->padrow < b->padrow) return -1;
-  if(a->padrow > b->padrow) return 1;
+  // compares two clusters
+  if(a->fPadrow < b->fPadrow) return -1;
+  if(a->fPadrow > b->fPadrow) return 1;
 
-  if(rint(a->pad) == rint(b->pad) && rint(a->time) == rint(b->time)) return 0;
+  if(rint(a->fPad) == rint(b->fPad) && rint(a->fTime) == rint(b->fTime)) return 0;
   
-  if(rint(a->pad) < rint(b->pad)) return -1;
-  if(rint(a->pad) == rint(b->pad) && rint(a->time) < rint(b->time)) return -1;
+  if(rint(a->fPad) < rint(b->fPad)) return -1;
+  if(rint(a->fPad) == rint(b->fPad) && rint(a->fTime) < rint(b->fTime)) return -1;
   
   return 1;
 }
 
-void AliL3DataCompressor::LoadOfflineData(Int_t event)
-{
-  //Take offline reconstructed tracks as an input.
-  //In this case, no remaining clusters are written.
-  
-#ifndef use_aliroot
-   LOG(AliL3Log::kError,"AliL3DataCompressor::LoadOfflineData","Version")
-     <<"You have to compile with use_aliroot flag in order to use this function"<<ENDLOG;
-#else
-
-  char filename[1024];
-  
-  AliKalmanTrack::SetConvConst(1000/0.299792458/AliL3Transform::GetSolenoidField());
-  sprintf(filename,"%s/offline/AliTPCclusters.root",fPath);
-
-  TFile *in = TFile::Open(filename);
-  AliTPCParam *param=(AliTPCParam*)in->Get("75x40_100x60_150x60");
-  
-  AliTPCtracker *tracker = new AliTPCtracker(param);
-  tracker->SetEventNumber(event);
-  tracker->LoadClusters();
-  
-  const Int_t MAX=20000;
-  Int_t nentr=0,i=0; TObjArray tarray(MAX);
-  sprintf(filename,"%s/offline/AliTPCtracks.root",fPath);
-  TFile *tf=TFile::Open(filename);
-  
-  char tname[100]; sprintf(tname,"TreeT_TPC_%d",event);
-  TTree *tracktree=(TTree*)tf->Get(tname);
-  
-  TBranch *tbranch=tracktree->GetBranch("tracks");
-  nentr=(Int_t)tracktree->GetEntries();
-  AliTPCtrack *iotrack=0;
-
-  for (i=0; i<nentr; i++) {
-    iotrack=new AliTPCtrack;
-    tbranch->SetAddress(&iotrack);
-    tracktree->GetEvent(i);
-    tarray.AddLast(iotrack);
-  }   
-  delete tracktree; 
-  tf->Close();
-  
-  AliL3TrackArray *comptracks = new AliL3TrackArray("AliL3ModelTrack");
-  cout<<"Loaded "<<nentr<<" offline tracks"<<endl;
-  Int_t slice,padrow;
-  Int_t totcounter=0;
-  for(i=0; i<nentr; i++)
-    {
-      
-      AliTPCtrack *track=(AliTPCtrack*)tarray.UncheckedAt(i);
-      Int_t nhits = track->GetNumberOfClusters();
-      Int_t idx = track->GetClusterIndex(nhits-1);
-      Int_t sec=(idx&0xff000000)>>24, row=(idx&0x00ff0000)>>16;
-      
-      if(sec >= 18)
-       sec += 18;
-      
-      AliL3Transform::Sector2Slice(slice,padrow,sec,row);
-      Double_t par[5],xk=AliL3Transform::Row2X(padrow);
-      track->PropagateTo(xk);
-      track->GetExternalParameters(xk,par);
-      Double_t psi = TMath::ASin(par[2]) + track->GetAlpha();
-      if (psi<-TMath::Pi()) psi+=2*TMath::Pi();
-      if (psi>=TMath::Pi()) psi-=2*TMath::Pi();
-      Float_t pt_1=TMath::Abs(par[4]);
-      Int_t charge = 1;
-      if(par[4] > 0)
-       charge=-1;
-
-      Float_t first[3];
-      AliCluster *fcl = tracker->GetCluster(idx);
-      first[0] = xk;
-      first[1] = fcl->GetY();
-      first[2] = fcl->GetZ();
-
-      AliL3Transform::Local2Global(first,slice);
-      
-      AliL3ModelTrack *outtrack = (AliL3ModelTrack*)comptracks->NextTrack();
-      outtrack->SetNHits(nhits);
-      outtrack->SetFirstPoint(first[0],first[1],first[2]);
-      outtrack->SetPt(1/pt_1);
-      outtrack->SetPsi(psi);
-      outtrack->SetTgl(par[3]);
-      outtrack->SetCharge(charge);
-      outtrack->CalculateHelix();
-      outtrack->Init(0,-1);
-
-      //for(int j=0; j<nhits; j++)
-      for(int j=nhits-1; j>=0; j--)
-       {
-         Int_t index = track->GetClusterIndex(j);
-         
-         Float_t xyz[3];
-         Int_t clustercharge =0;
-         
-         AliTPCcluster *cluster = (AliTPCcluster*)tracker->GetCluster(index);
-         xyz[1] = cluster->GetY();
-         xyz[2] = cluster->GetZ();
-         clustercharge = (Int_t)cluster->GetQ();
-         
-         cluster->SetQ(-clustercharge);//Set as used
-         
-         sec=(index&0xff000000)>>24; row=(index&0x00ff0000)>>16;
-         
-         //This we do because the sector numbering of course are different internally
-         //in the fucked up AliTPCtracker class. 
-         if(sec >= 18)
-           sec += 18;
-         
-         if(xyz[2] < 0)
-           sec += 18;
-
-         //cout<<"sector "<<sec<<" row "<<row<<endl;
-         if(!AliL3Transform::Sector2Slice(slice,padrow,sec,row))
-           exit(5);
-         xyz[0] = AliL3Transform::Row2X(padrow);
-         
-         //cout<<"Hit in slice "<<slice<<" padrow "<<padrow<<" y "<<cluster->GetY()<<" z "<<cluster->GetZ()<<endl;
-         AliL3Transform::Local2Raw(xyz,sec,row);
-         //cout<<"slice "<<slice<<" padrow "<<padrow<<" pad "<<xyz[1]<<" time "<<xyz[2]<<endl;
-         
-         if(xyz[1] < -1 || xyz[1] > AliL3Transform::GetNPads(padrow) ||
-            xyz[2] < -1 || xyz[2] > AliL3Transform::GetNTimeBins())
-           {
-             cerr<<"AliL3DataCompressor::FillOfflineData : Wrong time "<<xyz[2]<<" in slice "
-                 <<slice<<" padrow "<<padrow<<endl;
-             cout<<"sector "<<sec<<" row "<<row<<endl;
-             //cout<<"Hit in slice "<<slice<<" padrow "<<padrow<<" y "<<cluster->GetY()<<" z "<<cluster->GetZ()<<endl;
-             cout<<"Track hit "<<xyz[0]<<" "<<xyz[1]<<" "<<xyz[2]<<endl;
-             exit(5);
-           }
-         
-         Float_t angle = 0;
-         AliL3Transform::Local2GlobalAngle(&angle,slice);
-         if(!outtrack->CalculateReferencePoint(angle,AliL3Transform::Row2X(padrow)))
-           {
-             cerr<<"AliL3DataCompressor::FillOfflineData : Error in crossing point calc on slice "
-                 <<slice<<" row "<<padrow<<endl;
-             exit(5);
-           }
-         Float_t xyz_cross[3] = {outtrack->GetPointX(),outtrack->GetPointY(),outtrack->GetPointZ()};
-         AliL3Transform::Global2Raw(xyz_cross,sec,row);
-         /*
-           if(fabs(xyz_cross[1] - xyz[1]) > 10 ||
-           fabs(xyz_cross[2] - xyz[2]) > 10)
-           {
-           cout<<"AliL3DataCompressor::FillOfflineData : Wrong crossing slice "<<slice<<" padrow "
-           <<padrow<<" pad "<<xyz[1]<<" padhit "<<xyz_cross[1]<<" time "<<xyz[2]<<" timehit "<<xyz_cross[2]<<endl;
-           outtrack->Print();
-           exit(5);
-           }
-         */
-         //cout<<" crossing "<<xyz_cross[0]<<" "<<xyz_cross[1]<<" "<<xyz_cross[2]<<endl;
-         outtrack->SetPadHit(padrow,xyz_cross[1]);
-         outtrack->SetTimeHit(padrow,xyz_cross[2]);
-         
-         if(fWriteClusterShape)
-           {
-             Float_t angle = outtrack->GetCrossingAngle(padrow,slice);
-             outtrack->SetCrossingAngleLUT(padrow,angle);
-             outtrack->CalculateClusterWidths(padrow,kTRUE);
-             Int_t patch = AliL3Transform::GetPatch(padrow);
-             Float_t sigmaY2 = cluster->GetSigmaY2() / pow(AliL3Transform::GetPadPitchWidth(patch),2);
-             Float_t sigmaZ2 = cluster->GetSigmaZ2() / pow(AliL3Transform::GetZWidth(),2);
-             outtrack->SetCluster(padrow,xyz[1],xyz[2],clustercharge,sigmaY2,sigmaZ2,3);
-           }
-         else
-           outtrack->SetCluster(padrow,xyz[1],xyz[2],clustercharge,0,0,3);
-         totcounter++;
-         outtrack->GetClusterModel(padrow)->fSlice = slice;
-       }
-      /*
-      int label = track->GetLabel();
-      if(label == 10019 || label==6281 || label== 5326 || label==3054 || label==1366 || label==1005)
-       outtrack->Print();
-      */
-    }
-  
-  tracker->UnloadClusters();
-  
-  cout<<"AliL3DataCompressor::FillOfflineData : Wrote "<<totcounter<<" clusters"<<endl;
-  //Write tracks to file
-  AliL3Compress *comp = new AliL3Compress(-1,-1,fPath,fWriteClusterShape,fEvent);
-  comp->WriteFile(comptracks);
-  delete comp;
-  delete comptracks;
-  delete tracker;
-#endif
-}