// Author: Anders Vestbo <mailto:vestbo$fi.uib.no>
//*-- Copyright © ALICE HLT Group
+//_____________________________________________________________
+//
+// AliL3Compress
+//
+// Class for compressing and uncompressing data.
#include "AliL3StandardIncludes.h"
#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;
AliL3Compress::AliL3Compress(Int_t slice,Int_t patch,Char_t *path,Bool_t writeshape,Int_t event)
{
+ // constructor
fEvent=event;
fSlice=slice;
fPatch=patch;
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);
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++;
}
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();
}
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);
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;
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;
{
slice = cluster.fSlice;
if(slice == origslice)
- OutputBit(output,0);
+ OutputBit(output,0); //No change of slice
else
{
OutputBit(output,1);
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);
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++;
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);
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;
//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;
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)
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();
}
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(×[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();
}