]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/comp/AliL3Compress.cxx
Coding conventions
[u/mrichter/AliRoot.git] / HLT / comp / AliL3Compress.cxx
index f7142b743534819498db53b39df3067e6de4107a..e40742e4c3549cba422e7cd36d97d2f09e7e6ebd 100644 (file)
@@ -2,6 +2,11 @@
 
 // Author: Anders Vestbo <mailto:vestbo$fi.uib.no>
 //*-- Copyright &copy ALICE HLT Group
+//_____________________________________________________________
+//
+//  AliL3Compress
+//
+// Class for compressing and uncompressing data.
 
 #include "AliL3StandardIncludes.h"
 
@@ -14,7 +19,9 @@
 #include "AliL3ModelTrack.h"
 #include "AliL3Transform.h"
 #include "AliL3MemHandler.h"
+#include "AliL3DataCompressorHelper.h"
 #include "AliL3DataCompressor.h"
+#include "AliL3SpacePointData.h"
 
 #if 0
 #ifdef use_root
 
 #include "AliL3Compress.h"
 
-#if GCCVERSION == 3
+#if __GNUC__ == 3
 using namespace std;
 #endif
 
-//_____________________________________________________________
-//
-//  AliL3Compress
-//
-// Class for compressing and uncompressing data.
 
 ClassImp(AliL3Compress)
 
 AliL3Compress::AliL3Compress()
 {
+  // default constructor
   fTracks=0;
   fSlice =0;
   fPatch=0;
@@ -52,6 +55,7 @@ AliL3Compress::AliL3Compress()
 
 AliL3Compress::AliL3Compress(Int_t slice,Int_t patch,Char_t *path,Bool_t writeshape,Int_t event)
 {
+  // constructor
   fEvent=event;
   fSlice=slice;
   fPatch=patch;
@@ -62,12 +66,14 @@ AliL3Compress::AliL3Compress(Int_t slice,Int_t patch,Char_t *path,Bool_t writesh
 
 AliL3Compress::~AliL3Compress()
 {
+  // destructor
   if(fTracks)
     delete fTracks;
 }
 
 Bool_t AliL3Compress::WriteFile(AliL3TrackArray *tracks,Char_t *filename)
 {
+  // writes file
   Char_t fname[1024];
   if(filename)
     sprintf(fname,"%s/comp/%s",fPath,filename);
@@ -98,10 +104,11 @@ Bool_t AliL3Compress::WriteFile(AliL3TrackArray *tracks,Char_t *filename)
       
       track->FillModel();
       model = track->GetModel();
-      if(model->fNClusters==0) continue;
+      //if(model->fNClusters==0) continue;
       clusters = track->GetClusters();
       if(fwrite(model,sizeof(AliL3TrackModel),1,file)!=1) break;
-      if(fwrite(clusters,model->fNClusters*sizeof(AliL3ClusterModel),1,file)!=1) break;
+      //if(fwrite(clusters,model->fNClusters*sizeof(AliL3ClusterModel),1,file)!=1) break;
+      if(fwrite(clusters,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel),1,file)!=1) break;
       count++;
       
     }
@@ -157,7 +164,8 @@ Bool_t AliL3Compress::ReadFile(Char_t which,Char_t *filename)
       AliL3TrackModel *model = track->GetModel();
       AliL3ClusterModel *clusters = track->GetClusters();
       if(fread(model,sizeof(AliL3TrackModel),1,file)!=1) break;
-      if(fread(clusters,model->fNClusters*sizeof(AliL3ClusterModel),1,file)!=1) break;
+      //if(fread(clusters,model->fNClusters*sizeof(AliL3ClusterModel),1,file)!=1) break;
+      if(fread(clusters,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel),1,file)!=1) break;
       track->FillTrack();
     }
 
@@ -168,6 +176,7 @@ Bool_t AliL3Compress::ReadFile(Char_t which,Char_t *filename)
 
 Bool_t AliL3Compress::CompressFile()
 {
+  // compresses file
   Char_t fname[100];
   if(fEvent<0)
     sprintf(fname,"%s/comp/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
@@ -192,8 +201,8 @@ Bool_t AliL3Compress::CompressFile()
   Int_t temp;
   Int_t power;
   
-  Int_t timeo,pado,chargeo,shapeo;
-  timeo=pado=chargeo=shapeo=0;
+  Int_t timeo,pado,chargeo,padshapeo,timeshapeo;
+  timeo=pado=chargeo=padshapeo=timeshapeo=0;
   while(!feof(input))
     {
       if(fread(&track,sizeof(AliL3TrackModel),1,input)!=1) break;
@@ -211,7 +220,7 @@ Bool_t AliL3Compress::CompressFile()
       fwrite(&track,sizeof(AliL3TrackModel),1,output->file);
       
       Int_t origslice=-1,slice,clustercount=0;
-      for(Int_t i=0; i<track.fNClusters; i++)
+      for(Int_t i=0; i<AliL3Transform::GetNRows(fPatch); i++)
        {
          if(fread(&cluster,sizeof(AliL3ClusterModel),1,input)!=1) break;
          
@@ -236,7 +245,7 @@ Bool_t AliL3Compress::CompressFile()
            {
              slice = cluster.fSlice;
              if(slice == origslice)
-               OutputBit(output,0);
+               OutputBit(output,0);  //No change of slice
              else
                {
                  OutputBit(output,1);
@@ -251,13 +260,14 @@ Bool_t AliL3Compress::CompressFile()
            OutputBit(output,0);
          else
            OutputBit(output,1);
-         power = 1<<(AliL3DataCompressor::GetNTimeBits()-1);
+         power = 1<<(AliL3DataCompressorHelper::GetNTimeBits()-1);
          if(abs(temp)>=power)
            {
+             //cout<<abs(temp)<<" "<<power<<endl;
              timeo++;
              temp=power - 1;
            }
-         OutputBits(output,abs(temp),(AliL3DataCompressor::GetNTimeBits()-1));
+         OutputBits(output,abs(temp),(AliL3DataCompressorHelper::GetNTimeBits()-1));
          
          //Write pad information:
          temp = (Int_t)rint(cluster.fDPad);
@@ -265,52 +275,52 @@ Bool_t AliL3Compress::CompressFile()
            OutputBit(output,0);
          else
            OutputBit(output,1);
-         power = 1<<(AliL3DataCompressor::GetNPadBits()-1);
+         power = 1<<(AliL3DataCompressorHelper::GetNPadBits()-1);
          if(abs(temp)>=power)
            {
              pado++;
              temp=power - 1;
            }
-         OutputBits(output,abs(temp),(AliL3DataCompressor::GetNPadBits()-1));
+         OutputBits(output,abs(temp),(AliL3DataCompressorHelper::GetNPadBits()-1));
          
          //Write charge information:
          temp = (Int_t)cluster.fDCharge;
-         power = 1<<(AliL3DataCompressor::GetNChargeBits());
+         power = 1<<(AliL3DataCompressorHelper::GetNChargeBits());
          if(abs(temp)>=power)
            {
              chargeo++;
              temp=power - 1;
            }
-         OutputBits(output,abs(temp),(AliL3DataCompressor::GetNChargeBits()));
+         OutputBits(output,abs(temp),(AliL3DataCompressorHelper::GetNChargeBits()));
          
          if(fWriteShape)
            {
              //Write shape information:
-             temp = (Int_t)cluster.fDSigmaY2;
+             temp = (Int_t)rint(cluster.fDSigmaY);
              if(temp<0)
                OutputBit(output,0);
              else
                OutputBit(output,1);
-             power = 1<<(AliL3DataCompressor::GetNShapeBits()-1);
+             power = 1<<(AliL3DataCompressorHelper::GetNShapeBits()-1);
              if(abs(temp) >= power)
                {
-                 shapeo++;
+                 padshapeo++;
                  temp = power - 1;
                }
-             OutputBits(output,abs(temp),(AliL3DataCompressor::GetNShapeBits()-1));
+             OutputBits(output,abs(temp),(AliL3DataCompressorHelper::GetNShapeBits()-1));
              
-             temp = (Int_t)cluster.fDSigmaZ2;
+             temp = (Int_t)rint(cluster.fDSigmaZ);
              if(temp<0)
                OutputBit(output,0);
              else
                OutputBit(output,1);
-             power = 1<<(AliL3DataCompressor::GetNShapeBits()-1);
+             power = 1<<(AliL3DataCompressorHelper::GetNShapeBits()-1);
              if(abs(temp) >= power)
                {
-                 shapeo++;
+                 timeshapeo++;
                  temp=power - 1;
                }
-             OutputBits(output,abs(temp),(AliL3DataCompressor::GetNShapeBits()-1));
+             OutputBits(output,abs(temp),(AliL3DataCompressorHelper::GetNShapeBits()-1));
            }
          
          clustercount++;
@@ -319,19 +329,21 @@ Bool_t AliL3Compress::CompressFile()
   
   fclose(input);
   CloseOutputBitFile(output);
-  if(pado || timeo || chargeo || shapeo)
+  if(pado || timeo || chargeo || padshapeo || timeshapeo)
     {
       cout<<endl<<"Saturations: "<<endl
          <<"Pad "<<pado<<endl
          <<"Time "<<timeo<<endl
          <<"Charge "<<chargeo<<endl
-         <<"Shape "<<shapeo<<endl<<endl;
+         <<"Padshape "<<padshapeo<<endl
+         <<"Timeshape "<<timeshapeo<<endl<<endl;
     }
   return kTRUE;
 }
 
 Bool_t AliL3Compress::ExpandFile()
 {
+  // expands file
   Char_t fname[100];
   if(fEvent<0)
     sprintf(fname,"%s/comp/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
@@ -365,7 +377,7 @@ Bool_t AliL3Compress::ExpandFile()
 
       memset(clusters,0,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel));
       Int_t origslice=-1,clustercount=0;
-      for(Int_t i=0; i<trackmodel.fNClusters; i++)
+      for(Int_t i=0; i<AliL3Transform::GetNRows(fPatch); i++)
        {
          Int_t temp,sign;
          
@@ -400,42 +412,42 @@ Bool_t AliL3Compress::ExpandFile()
          
          //Read time information:
          sign=InputBit(input);
-         temp = InputBits(input,(AliL3DataCompressor::GetNTimeBits()-1));
+         temp = InputBits(input,(AliL3DataCompressorHelper::GetNTimeBits()-1));
          if(!sign)
            temp*=-1;
          clusters[i].fDTime = temp;
          
          //Read pad information:
          sign=InputBit(input);
-         temp = InputBits(input,(AliL3DataCompressor::GetNPadBits()-1));
+         temp = InputBits(input,(AliL3DataCompressorHelper::GetNPadBits()-1));
          if(!sign)
            temp*=-1;
          clusters[i].fDPad = temp;
          
          //Read charge information:
-         temp=InputBits(input,(AliL3DataCompressor::GetNChargeBits()));
+         temp=InputBits(input,(AliL3DataCompressorHelper::GetNChargeBits()));
          clusters[i].fDCharge = temp;
          
          if(fWriteShape)
            {
              //Read shape information:
              sign = InputBit(input);
-             temp = InputBits(input,(AliL3DataCompressor::GetNShapeBits()-1));
+             temp = InputBits(input,(AliL3DataCompressorHelper::GetNShapeBits()-1));
              if(!sign)
                temp*=-1;
-             clusters[i].fDSigmaY2 = temp;
+             clusters[i].fDSigmaY = temp;
              
              sign = InputBit(input);
-             temp = InputBits(input,(AliL3DataCompressor::GetNShapeBits()-1));
+             temp = InputBits(input,(AliL3DataCompressorHelper::GetNShapeBits()-1));
              if(!sign)
                temp*=-1;
-             clusters[i].fDSigmaZ2 = temp;
+             clusters[i].fDSigmaZ = temp;
            }
          clustercount++;
        }
       count++;
-      fwrite(clusters,(trackmodel.fNClusters)*sizeof(AliL3ClusterModel),1,output);
-      
+      //fwrite(clusters,(trackmodel.fNClusters)*sizeof(AliL3ClusterModel),1,output);
+      fwrite(clusters,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel),1,output);
     }
   
   delete [] clusters;
@@ -444,11 +456,177 @@ Bool_t AliL3Compress::ExpandFile()
   return kTRUE;
 }
 
+void AliL3Compress::CompressRemaining(AliL3SpacePointData *clusters[36][6],UInt_t nclusters[36][6])
+{
+  //Write the remaining clusters in a compressed format.
+
+  Char_t filename[1024];
+  Int_t nrows = AliL3Transform::GetNRows();
+  Int_t *npoints = new Int_t[nrows];
+  for(Int_t slice=0; slice<=35; slice++)
+    {
+      for(Int_t patch=0; patch < 1; patch++)
+       {
+         sprintf(filename,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,slice,-1);
+         BIT_FILE *output = OpenOutputBitFile(filename);
+         if(!output)
+           {
+             cerr<<"AliL3Compress::CompressRemaining : Cannot open file "<<filename<<endl;
+             exit(5);
+           }
+         AliL3SpacePointData *cl = clusters[slice][patch];
+         memset(npoints,0,nrows*sizeof(Int_t));
+         
+         UInt_t i;
+         for(i=0; i<nclusters[slice][patch]; i++)
+           {
+             if(cl[i].fCharge == 0) continue; //has been used
+             npoints[cl[i].fPadRow]++;
+           }
+         Int_t rowspresent=0;
+         for(Int_t j=0; j<nrows; j++)
+           {
+             if(!npoints[j]) continue;
+             rowspresent++;
+           }
+         
+         //Write number of padrows with clusters
+         OutputBits(output,rowspresent,8);
+         
+         Int_t lastPadrow=-1;
+         for(i=0; i<nclusters[slice][patch]; i++)
+           {
+             if(cl[i].fCharge == 0) continue; //has been used
+             Int_t padrow = cl[i].fPadRow;
+             if(padrow != lastPadrow)
+               {
+                 OutputBits(output,padrow,8);//Write padrow #
+                 if(npoints[padrow] >= 1<<10)
+                   {
+                     cerr<<"AliL3Compress::CompressRemaining : Too many remaining clusters "<<npoints[padrow]<<endl;
+                     exit(5);
+                   }
+                 OutputBits(output,npoints[padrow],10);//Write number of clusters on this padrow
+                 lastPadrow = padrow;
+               }
+             
+             Float_t xyz[3] = {cl[i].fX,cl[i].fY,cl[i].fZ};
+             Int_t sector,row,buff;
+             AliL3Transform::Slice2Sector(slice,padrow,sector,row);
+             AliL3Transform::Global2Raw(xyz,sector,row);
+             
+             Float_t padw = sqrt(cl[i].fSigmaY2) / AliL3Transform::GetPadPitchWidth(AliL3Transform::GetPatch(padrow));
+             Float_t timew = sqrt(cl[i].fSigmaZ2) / AliL3Transform::GetZWidth();
+             
+             //Check for saturation in the widths.
+             //Basically only store a certain number of decimals here, and cut the widths which is higher:
+             if(padw >= (1<<AliL3DataCompressorHelper::GetNShapeBitsRemaining()) / AliL3DataCompressorHelper::GetPadPrecisionFactor())
+               padw = (1<<AliL3DataCompressorHelper::GetNShapeBitsRemaining()) / AliL3DataCompressorHelper::GetPadPrecisionFactor() - 1/AliL3DataCompressorHelper::GetPadPrecisionFactor();
+             if(timew >= (1<<AliL3DataCompressorHelper::GetNShapeBitsRemaining()) / AliL3DataCompressorHelper::GetTimePrecisionFactor())
+               timew = (1<<AliL3DataCompressorHelper::GetNShapeBitsRemaining()) / AliL3DataCompressorHelper::GetTimePrecisionFactor() - 1/AliL3DataCompressorHelper::GetTimePrecisionFactor();;
+             
+             //Write pad
+             buff = (Int_t)rint(xyz[1]*AliL3DataCompressorHelper::GetPadPrecisionFactor());
+             if(buff<0)
+               {
+                 cerr<<"AliL3Compress:CompressRemaining : Wrong pad value "<<buff<<endl;
+                 exit(5);
+               }
+             OutputBits(output,buff,AliL3DataCompressorHelper::GetNPadBitsRemaining());
+             
+             //Write time
+             buff = (Int_t)rint(xyz[2]*AliL3DataCompressorHelper::GetTimePrecisionFactor());
+             if(buff<0)
+               {
+                 cerr<<"AliL3Compress:CompressRemaining : Wrong time value "<<buff<<endl;
+                 exit(5);
+               }
+             OutputBits(output,buff,AliL3DataCompressorHelper::GetNTimeBitsRemaining());
+             
+             //Write widths
+             buff = (Int_t)rint(padw*AliL3DataCompressorHelper::GetPadPrecisionFactor());
+             OutputBits(output,buff,AliL3DataCompressorHelper::GetNShapeBitsRemaining());
+             buff = (Int_t)rint(timew*AliL3DataCompressorHelper::GetTimePrecisionFactor());
+             OutputBits(output,buff,AliL3DataCompressorHelper::GetNShapeBitsRemaining());
+             
+             //Write charge 
+             buff = cl[i].fCharge;
+             if(buff >= 1<<(AliL3DataCompressorHelper::GetNChargeBits()))
+               buff = (1<<(AliL3DataCompressorHelper::GetNChargeBits()))-1;
+             OutputBits(output,buff,AliL3DataCompressorHelper::GetNChargeBits());
+           }
+         
+         CloseOutputBitFile(output);
+       }
+      
+    }
+  delete [] npoints;
+}
+
+void AliL3Compress::ExpandRemaining(TempCluster **clusters,Int_t *ncl,const Int_t /*maxpoints*/)
+{
+  //Expand the remaining clusters stored using function CompressRemaining
+  
+  Char_t filename[1024];
+  Int_t buff;
+  for(Int_t slice=0; slice<=35; slice++)
+    {
+      for(Int_t p=0; p<1; p++)
+       {
+         sprintf(filename,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,slice,-1);
+         BIT_FILE *input = OpenInputBitFile(filename);
+         
+         //Read number of padrows 
+         buff = InputBits(input,8);
+         Int_t nrows = buff;
+         
+         for(Int_t i=0; i<nrows; i++)
+           {
+             //Read padrow
+             buff = InputBits(input,8);
+             Int_t padrow = buff;
+             
+             //Read nclusters;
+             buff = InputBits(input,10);
+             Int_t npoints = buff;
+             
+             for(Int_t i=0; i<npoints; i++)
+               {
+                 clusters[slice][ncl[slice]].fPadrow = padrow;
+
+                 //Read pad
+                 buff = InputBits(input,AliL3DataCompressorHelper::GetNPadBitsRemaining());
+                 clusters[slice][ncl[slice]].fPad = (Float_t)buff/AliL3DataCompressorHelper::GetPadPrecisionFactor();
+                 
+                 //Read time
+                 buff = InputBits(input,AliL3DataCompressorHelper::GetNTimeBitsRemaining());
+                 clusters[slice][ncl[slice]].fTime = (Float_t)buff/AliL3DataCompressorHelper::GetTimePrecisionFactor();
+                 
+                 //Read widths 
+                 buff = InputBits(input,AliL3DataCompressorHelper::GetNShapeBitsRemaining());
+                 clusters[slice][ncl[slice]].fSigmaY2 = pow((Float_t)buff/AliL3DataCompressorHelper::GetPadPrecisionFactor(),2);
+                 buff = InputBits(input,AliL3DataCompressorHelper::GetNShapeBitsRemaining());
+                 clusters[slice][ncl[slice]].fSigmaZ2 = pow((Float_t)buff/AliL3DataCompressorHelper::GetPadPrecisionFactor(),2);
+                 
+                 //Read charge
+                 buff = InputBits(input,AliL3DataCompressorHelper::GetNChargeBits());
+                 clusters[slice][ncl[slice]].fCharge = buff;
+                 
+                 ncl[slice]++;
+               }
+             
+           }
+         CloseInputBitFile(input);
+       }
+    }
+}
+
 void AliL3Compress::PrintCompRatio(ofstream *outfile)
 {
+  // prints the compression ratio
   AliL3MemHandler *mem = new AliL3MemHandler();
   Char_t fname[1024];
-  UInt_t remain_size=0,digit_size=0;
+  UInt_t remainSize=0,digitSize=0;
   for(Int_t i=0; i<36; i++)
     {
       if(fEvent<0)
@@ -456,12 +634,12 @@ void AliL3Compress::PrintCompRatio(ofstream *outfile)
       else
        sprintf(fname,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,i,-1);
       mem->SetBinaryInput(fname);
-      remain_size += mem->GetFileSize();
+      remainSize += mem->GetFileSize();
       mem->CloseBinaryInput();
 
       sprintf(fname,"%s/binaries/digits_c8_%d_%d_%d.raw",fPath,fEvent,i,-1);
       mem->SetBinaryInput(fname);
-      digit_size += mem->GetFileSize();
+      digitSize += mem->GetFileSize();
       mem->CloseBinaryInput();
     }
   
@@ -472,27 +650,85 @@ void AliL3Compress::PrintCompRatio(ofstream *outfile)
     sprintf(fname,"%s/comp/tracks_c_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
 
   mem->SetBinaryInput(fname);
-  UInt_t compress_size = mem->GetFileSize();
+  UInt_t compressSize = mem->GetFileSize();
   mem->CloseBinaryInput();
   
-  if(digit_size==0)
+  if(digitSize==0)
     {
-      cerr<<"AliL3Compress::PrintCompRatio : Zero digit size "<<endl;
-      exit(5);
+      cerr<<"AliL3Compress::PrintCompRatio : Zero digit size, not able to obtain comp. ratios!"<<endl;
+      return;
     }
   
-  Float_t compratio = (Float_t)(compress_size + remain_size)/(Float_t)digit_size;
+  Float_t compratio = (Float_t)(compressSize + remainSize)/(Float_t)digitSize;
+  Float_t entropy[3];
+  Int_t trackSize = GetEntropy(entropy[0],entropy[1],entropy[2])*sizeof(AliL3TrackModel);
   if(outfile)
     {
       ofstream &out = *outfile;
-      out<<compress_size<<' '<<remain_size<<' '<<digit_size<<endl;
+      out<<compressSize<<' '<<remainSize<<' '<<digitSize<<' '<<trackSize<<' '<<entropy[0]<<' '<<entropy[1]<<endl;
     }
-
+  
   cout<<"=========================================="<<endl;
-  cout<<"Original digits size : "<<digit_size/1000<<" kByte ( 100 % )"<<endl;
-  cout<<"Compressed file size : "<<compress_size/1000<<" kByte ( "<<(Float_t)compress_size*100/(Float_t)digit_size<<" % )"<<endl;
-  cout<<"Remainig file size   : "<<remain_size/1000<<" kByte ( "<<(Float_t)remain_size*100/(Float_t)digit_size<<" % )"<<endl;
+  cout<<"Original digits size : "<<digitSize/1000<<" kByte ( 100 % )"<<endl;
+  cout<<"Compressed file size : "<<compressSize/1000<<" kByte ( "<<(Float_t)compressSize*100/(Float_t)digitSize<<" % )"<<endl;
+  cout<<"Remaining file size  : "<<remainSize/1000<<" kByte ( "<<(Float_t)remainSize*100/(Float_t)digitSize<<" % )"<<endl;
+  cout<<"Relative track size  : "<<trackSize/1000<<" kByte ( "<<(Float_t)trackSize*100/(Float_t)digitSize<<" % )"<<endl;
+  cout<<"Relative cluster size: "<<(compressSize-trackSize)/1000<<" kByte ( "<<(Float_t)(compressSize-trackSize)*100/(Float_t)digitSize<<" % )"<<endl;
   cout<<"---------------------- "<<endl;
   cout<<"Compression ratio    : "<<compratio*100<<" %"<<endl;
   cout<<"=========================================="<<endl;
+  cout<<"Entropy of residuals : "<<entropy[0]<<" "<<entropy[1]<<endl;
+}
+
+Int_t AliL3Compress::GetEntropy(Float_t &padEntropy,Float_t &timeEntropy,Float_t &chargeEntropy)
+{
+  //Calculate the entropy of the quantized residuals in both directions
+  
+  if(!ReadFile('m'))
+    return 0;
+  const Int_t knmax=100000;
+  Float_t pads[knmax];
+  Float_t times[knmax];
+  Float_t charge[knmax];
+  memset(&pads[0],0,knmax*sizeof(Float_t));
+  memset(&times[0],0,knmax*sizeof(Float_t));
+  memset(&charge[0],0,knmax*sizeof(Float_t));
+  Float_t counter=0;
+
+  for(Int_t i=0; i<fTracks->GetNTracks(); i++)
+    {
+      AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
+      if(!track) continue;
+      for(Int_t padrow=0; padrow<AliL3Transform::GetNRows(); padrow++)
+       {
+         if(!track->IsPresent(padrow)) continue;
+         Int_t dpad = abs((Int_t)rint(track->GetClusterModel(padrow)->fDPad));
+         Int_t dtime = abs((Int_t)rint(track->GetClusterModel(padrow)->fDTime));
+         Int_t dcharge = (Int_t)track->GetClusterModel(padrow)->fDCharge;
+         if(dpad >= knmax || dtime >= knmax || dcharge >= knmax)
+           {
+             cerr<<"AliL3Compress::GetEntropy : Quantization out of range: "<<dpad<<" "<<dtime<<" "<<dcharge<<endl;
+             break;
+           }
+         pads[dpad]++;
+         times[dtime]++;
+         charge[dcharge]++;
+         counter++;
+       }
+    }
+  padEntropy=timeEntropy=chargeEntropy=0;
+  for(Int_t i=0; i<knmax; i++)
+    {
+      if(pads[i]>0)
+       padEntropy += (pads[i]/counter)*(log(pads[i]/counter)/log(2.0));
+      if(times[i]>0)
+       timeEntropy += (times[i]/counter)*(log(times[i]/counter)/log(2.0));
+      if(charge[i]>0)
+       chargeEntropy += (charge[i]/counter)*(log(charge[i]/counter)/log(2.0));
+    }
+  
+  padEntropy*=-1;
+  timeEntropy*=-1;
+  chargeEntropy*=-1;
+  return fTracks->GetNTracks();
 }