#include <Riostream.h>
#include <TMath.h>
#include <TSystem.h>
-#include "AliTPCBuffer160.h"
-#include "AliTPCHuffman.h"
+#include "AliAltroBuffer.h"
+#include "AliTPCHNode.h"
+#include "AliTPCHTable.h"
#include "AliTPCCompression.h"
ClassImp(AliTPCCompression)
+
//////////////////////////////////////////////////////////////////////////////////////////////////
AliTPCCompression::AliTPCCompression(){
//Defaul constructor
fDimBuffer=sizeof(UInt_t)*8;
fFreeBitsBuffer=fDimBuffer;
- fReadBits=0;
+ fBitsToRead=32;
fPos=0;
fBuffer=0;
fVerbose=0;
//Constructor
this->fDimBuffer=source.fDimBuffer;
this->fFreeBitsBuffer=source.fFreeBitsBuffer;
- this->fReadBits=source.fReadBits;
+ this->fBitsToRead=source.fBitsToRead;
this->fPos=source.fPos;
this->fBuffer=source.fBuffer;
this->fVerbose=source.fVerbose;
//Redefinition of the assignment operator
this->fDimBuffer=source.fDimBuffer;
this->fFreeBitsBuffer=source.fFreeBitsBuffer;
- this->fReadBits=source.fReadBits;
+ this->fBitsToRead=source.fBitsToRead;
this->fPos=source.fPos;
this->fBuffer=source.fBuffer;
this->fVerbose=source.fVerbose;
Int_t AliTPCCompression::FillTables(const char* fSource,AliTPCHTable* table[],Int_t /*NumTables*/){
//This method is used to compute the frequencies of the symbols in the source file
- AliTPCBuffer160 buff(fSource,0);
+ AliAltroBuffer buff(fSource,0);
UInt_t countWords=0;
UInt_t countTrailer=0;
Int_t numWords,padNum,rowNum,secNum=0;
UInt_t stat[5]={0,0,0,0,0};
Int_t endFill=0;
Int_t end=1;
- while(buff.ReadTrailerBackward(numWords,padNum,rowNum,secNum) !=-1 ){
+ while(buff.ReadTrailerBackward(numWords,padNum,rowNum,secNum)){
if(end){
endFill=buff.GetFillWordsNum();
end=0;
Double_t sum=0;
Double_t min=10;
Double_t alpha=0;
- Double_t A=0;
- AliTPCHTable *Table=new AliTPCHTable(dim);
+ Double_t a=0;
+ AliTPCHTable *table=new AliTPCHTable(dim);
freq=1;
- Double_t FreqArray[1024];
+ Double_t freqArray[1024];
for(Int_t i=0;i<1024;i++){
- FreqArray[i]=0;
+ freqArray[i]=0;
}
alpha=M*0.000000602+0.0104;
if (fVerbose)
cout<<"alpha "<<alpha<<endl;
for(Int_t x=0;x<dim;x++){
if (Type==1)
- FreqArray[x]=TMath::Power((x+1),-beta)*TMath::Exp(-alpha*(x+1));
+ freqArray[x]=TMath::Power((x+1),-beta)*TMath::Exp(-alpha*(x+1));
else
- FreqArray[x]=TMath::Power((x+1),-beta);
- sum+=FreqArray[x];
- if (FreqArray[x]<min)min=FreqArray[x];
+ freqArray[x]=TMath::Power((x+1),-beta);
+ sum+=freqArray[x];
+ if (freqArray[x]<min)min=freqArray[x];
}//end for
if (fVerbose)
cout<<"Minimun Value "<<min<<endl;
- A=1/sum;
+ a=1/sum;
if (fVerbose)
- cout<<"A Value: "<<A<<endl;
+ cout<<"a Value: "<<a<<endl;
for(Int_t x=0;x<dim;x++){
if (Type==0)//Bunch length
if (x>=3)//minimum bunch length
- Table->SetValFrequency(x,A*FreqArray[x]*1000);
+ table->SetValFrequency(x,a*freqArray[x]*1000);
else
- Table->SetValFrequency(x,0);
+ table->SetValFrequency(x,0);
else //Time table
- Table->SetValFrequency(x,A*FreqArray[x]);
+ table->SetValFrequency(x,a*freqArray[x]);
}
- Table->BuildHTable();
+ table->BuildHTable();
ofstream fTable;
char filename[15];
sprintf(filename,"Table%d.dat",Type);
#else
fTable.open(filename);
#endif
- Int_t dimTable=Table->Size();
+ Int_t dimTable=table->Size();
//Table dimension is written into a file
fTable.write((char*)(&dimTable),sizeof(Int_t));
//One table is written into a file
for(Int_t i=0;i<dimTable;i++){
- UChar_t CodeLen=Table->CodeLen()[i];
- Double_t Code=Table->Code()[i];
- fTable.write((char*)(&CodeLen),sizeof(UChar_t));
- fTable.write((char*)(&Code),sizeof(Double_t));
+ UChar_t codeLen=table->CodeLen()[i];
+ Double_t code=table->Code()[i];
+ fTable.write((char*)(&codeLen),sizeof(UChar_t));
+ fTable.write((char*)(&code),sizeof(Double_t));
} //end for
fTable.close();
- delete Table;
+ delete table;
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////
f.open(fDest,ios::out);
#endif
// Source file is open
- AliTPCBuffer160 buff(fSource,0);
+ AliAltroBuffer buff(fSource,0);
//coded words are written into a file
Int_t numWords,padNum,rowNum,secNum=0;
UInt_t storedWords=0;
fStat<<endl;
fStat<<"-------------------COMPRESSION STATISTICS----------"<<endl;
Int_t end=1;
- while(buff.ReadTrailerBackward(numWords,padNum,rowNum,secNum) !=-1 ){
+ while(buff.ReadTrailerBackward(numWords,padNum,rowNum,secNum)){
if(end){
fillWords=buff.GetFillWordsNum();
end=0;
node=RootNode[k];
for(Int_t j=1;j<=codeLen;j++){
UInt_t bit,val=0;
- val=(UInt_t)TMath::Power(2,codeLen-j);
+ // val=(UInt_t)TMath::Power(2,codeLen-j);
+ val=(UInt_t)(1<<(codeLen-j));
bit=(UInt_t)code&val;
AliTPCHNode *temp=node;
if(bit){
//At this point the trees are been built
return 0;
}
+
+Int_t AliTPCCompression::CreateLUTsFromTrees(AliTPCHNode *RootNode[],Int_t NumTables,UInt_t *LUTDimension[],AliTPCHNode **LUTNode[]){
+ //For each Huffman tree this method builds the associate look-up-table for fast
+ //decoding of compressed data.
+ //Should be called after CreateTreesFromFile.
+ if(fVerbose)
+ cout<<"Creating the LUTs \n";
+ AliTPCHNode *node=0;
+
+ //loop over the tables
+ for(Int_t k=0;k<NumTables;k++){
+ UInt_t dim = 1<<fgkTableDimension;
+ LUTDimension[k] = new UInt_t[dim];
+ LUTNode[k] = new AliTPCHNode*[dim];
+ //loop over the words of one LUT
+ for(UInt_t i=0;i<dim;i++){
+ UInt_t buffer = i;
+ node=RootNode[k];
+ LUTDimension[k][i] = GetDecodedLUTBuffer(&node,&buffer);
+ LUTNode[k][i] = node;
+ // cout<<"LUT "<<k<<" "<<i<<" "<<LUTDimension[k][i]<<" "<<LUTNode[k][i]<<" "<<LUTNode[k][i]->GetSymbol()<<endl;
+ }
+ }
+ if (fVerbose)
+ cout<<"LUTs generated \n";
+ //At this point the LUTs are built
+ return 0;
+}
//////////////////////////////////////////////////////////////////////////////////////////////////
void AliTPCCompression::DeleteHuffmanTree(AliTPCHNode* node){
//This function deletes all the nodes of an Huffman tree
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////
-UInt_t AliTPCCompression::ReadWord(Int_t NumberOfBit){
+UInt_t AliTPCCompression::ReadWord(UInt_t NumberOfBit){
//This method retrieves a word of a specific number of bits from the file through the internal buffer
UInt_t result=0;
UInt_t bit=0;
- for (Int_t i=0;i<NumberOfBit;i++){
- if (fReadBits==32){
+ for (UInt_t i=0;i<NumberOfBit;i++){
+ if (fBitsToRead==0){
fPos-=sizeof(UInt_t);
f.seekg(fPos);
f.read((char*)(&fBuffer),sizeof(UInt_t));
- fReadBits=0;
+ fBitsToRead=32;
}//end if
- UInt_t mask=0;
- mask=(UInt_t)TMath::Power(2,fReadBits);
+ UInt_t mask=(UInt_t)(1<<(32-fBitsToRead));
bit=fBuffer&mask;
- bit=bit>>fReadBits;
- fReadBits++;
+ bit=bit>>(32-fBitsToRead);
+ fBitsToRead--;
bit=bit<<i;
result=result|bit;
}//end for
return result;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
-UInt_t AliTPCCompression::ReadWordBuffer(Int_t NumberOfBit){
+UInt_t AliTPCCompression::ReadWordBuffer(UInt_t NumberOfBit){
//This method retrieves a word of a specific number of bits from the file through the buffer
UInt_t result=0;
- UInt_t bit=0;
- for (Int_t i=0;i<NumberOfBit;i++){
- if (fReadBits==32){
- fPointBuffer-=8;
- fBuffer=0;
- for(Int_t i=0;i<4;i++){
- UInt_t val=0;
- val=*fPointBuffer;
- val&=0xFF;
- fPointBuffer++;
- val<<=8*i;
- fBuffer=fBuffer|val;
- }//end for
- fReadBits=0;
- }//end if
- UInt_t mask=0;
- mask=(UInt_t)TMath::Power(2,fReadBits);
- bit=fBuffer&mask;
- bit=bit>>fReadBits;
- fReadBits++;
- bit=bit<<i;
- result=result|bit;
- }//end for
+
+ if(NumberOfBit<=fBitsToRead) {
+ result = fBuffer&((1<<NumberOfBit)-1);
+ fBuffer=fBuffer>>NumberOfBit;
+ fBitsToRead-=NumberOfBit;
+ }
+ else {
+ fPointBuffer--;
+ UInt_t tempbuffer = *fPointBuffer;
+ if((NumberOfBit-fBitsToRead) != 32)
+ tempbuffer=tempbuffer&((1<<(NumberOfBit-fBitsToRead))-1);
+ tempbuffer=tempbuffer<<fBitsToRead;
+ result = fBuffer|tempbuffer;
+ fBuffer=*fPointBuffer;
+ fBitsToRead=(32+fBitsToRead)-NumberOfBit;
+ fBuffer=fBuffer>>(32-fBitsToRead);
+ }
+
+ return result;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+inline void AliTPCCompression::AdjustWordBuffer(UInt_t NumberOfBit){
+ //This method retrieves a word of a specific number of bits from the file through the buffer
+ //The method is used together with LUTs for fast decoding
+ if(NumberOfBit<=fBitsToRead) {
+ fBuffer=fBuffer>>NumberOfBit;
+ fBitsToRead-=NumberOfBit;
+ }
+ else {
+ fPointBuffer--;
+ fBuffer=*fPointBuffer;
+ fBitsToRead=(32+fBitsToRead)-NumberOfBit;
+ fBuffer=fBuffer>>(32-fBitsToRead);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+inline UInt_t AliTPCCompression::ReadWordBufferWithLUTs(){
+ //This method retrieves a word of a specific number of bits from the file through the buffer
+ //The method is used together with LUTs for fast decoding
+ if(fgkTableDimension<=fBitsToRead)
+ return fBuffer&((1<<fgkTableDimension)-1);
+ else {
+ UInt_t tempbuffer = *(fPointBuffer-1);
+ tempbuffer=tempbuffer&((1<<(fgkTableDimension-fBitsToRead))-1);
+ tempbuffer=tempbuffer<<fBitsToRead;
+ return fBuffer|tempbuffer;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+inline UInt_t AliTPCCompression::ReadBitFromWordBuffer(){
+ //This method retrieves a bit from the file through the buffer
+ UInt_t result=0;
+
+ if (fBitsToRead==0){
+ fPointBuffer--;
+ fBuffer=*fPointBuffer;
+ fBitsToRead=32;
+ }//end if
+ result=fBuffer&0x1;
+ fBitsToRead--;
+ fBuffer=fBuffer>>1;
+ return result;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+inline UInt_t AliTPCCompression::ReadBitFromLUTBuffer(UInt_t *buffer){
+ //This method retrieves a word of a bit out of the LUT buffer
+ UInt_t result=0;
+
+ result=*buffer&0x1;
+ *buffer=*buffer>>1;
return result;
}
void AliTPCCompression::ReadTrailer(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber,Bool_t Memory){
//It retrieves a trailer
if(Memory){
- ReadWordBuffer(1);
+ ReadBitFromWordBuffer();
SecNumber=ReadWordBuffer(9);
RowNumber=ReadWordBuffer(10);
PadNumber=ReadWordBuffer(10);
return;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
-UInt_t AliTPCCompression::GetDecodedWord(AliTPCHNode* root,Bool_t Memory){
+inline UInt_t AliTPCCompression::GetDecodedWordBuffer(AliTPCHNode* root){
//This method retrieves a decoded word.
AliTPCHNode *node=root;
UInt_t symbol=0;
Bool_t decoded=0;
+
+ while(!decoded){
+ UInt_t bit=ReadBitFromWordBuffer();
+ if(bit)
+ node=node->GetRight();
+ else
+ node=node->GetLeft();
+ if (!(node->GetLeft())){
+ symbol=node->GetSymbol();
+ decoded=1;
+ }
+ }//end while
+ return symbol;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+inline UInt_t AliTPCCompression::GetDecodedWordBufferWithLUTs(UInt_t* LUTDimension,AliTPCHNode** LUTNode){
+ //This method retrieves a decoded word.
+ UInt_t symbol=0;
+ UInt_t buffer=0;
+ Bool_t decoded=0;
+
+ buffer = ReadWordBufferWithLUTs();
+ AliTPCHNode *node=LUTNode[buffer];
+ if (!(node->GetLeft())){
+ symbol=node->GetSymbol();
+ decoded=1;
+ }
+ AdjustWordBuffer(LUTDimension[buffer]);
while(!decoded){
- UInt_t bit=0;
- if(Memory)
- bit=ReadWordBuffer(1);
+ UInt_t bit=ReadBitFromWordBuffer();
+ if(bit)
+ node=node->GetRight();
else
- bit=ReadWord(1);
+ node=node->GetLeft();
+ if (!(node->GetLeft())){
+ symbol=node->GetSymbol();
+ decoded=1;
+ }
+ }//end while
+ return symbol;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+inline UInt_t AliTPCCompression::GetDecodedLUTBuffer(AliTPCHNode** node,UInt_t *buffer){
+ //This method retrieves a decoded word for the LUTs.
+ Bool_t decoded=0;
+ UInt_t counter=0;
+
+ while(!decoded && counter<fgkTableDimension){
+ UInt_t bit=ReadBitFromLUTBuffer(buffer);
+ counter++;
+ if(bit)
+ *node=(*node)->GetRight();
+ else
+ *node=(*node)->GetLeft();
+ if (!((*node)->GetLeft())){
+ decoded=1;
+ }
+ }//end while
+ return counter;
+}
+
+inline UInt_t AliTPCCompression::GetDecodedWord(AliTPCHNode* root){
+ //This method retrieves a decoded word.
+ AliTPCHNode *node=root;
+ UInt_t symbol=0;
+ Bool_t decoded=0;
+
+ while(!decoded){
+ UInt_t bit=ReadWord(1);
if(bit)
node=node->GetRight();
else
decoded=1;
}
}//end while
+
return symbol;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
fPos=f.tellg();
fPos-=sizeof(UInt_t);
f.seekg(fPos);
- fReadBits=0;
+ fBitsToRead=32;
fBuffer=0;
f.read((char*)(&fBuffer),sizeof(UInt_t));
Int_t bit=0;
while(!bit){
bit=fBuffer&mask;
mask=mask<<1;
- fReadBits++;
+ fBitsToRead--;
}
UInt_t packetNumber=ReadWord(sizeof(UInt_t)*8);
if(fVerbose){
cout<<"Number of Packect: "<<packetNumber<<endl;
}
- AliTPCBuffer160 bufferFile(fDest,1);
+ AliAltroBuffer bufferFile(fDest,1);
UInt_t k=0;
UInt_t wordsRead=0; //number of read coded words
while(k<packetNumber){
Int_t bunchLen=0;
Int_t count=0;
for(Int_t i=0;i<numWords;i++){
- UInt_t symbol=GetDecodedWord(rootNode[nextTableType],kFALSE);
+ UInt_t symbol=GetDecodedWord(rootNode[nextTableType]);
wordsRead++;
//Time reconstruction
if (nextTableType==1){
Int_t AliTPCCompression::Decompress(AliTPCHNode *RootNode[],Int_t /*NumTables*/,char* PointBuffer,UInt_t BufferSize,UShort_t out[],UInt_t &dim){
//This method decompress a file using separate Huffman tables
- fPointBuffer=PointBuffer+BufferSize-4;
- fReadBits=0;
+ // fPointBuffer=((UInt_t *)PointBuffer)+(UInt_t)(BufferSize/4)-1;
+ fPointBuffer=(UInt_t *)(PointBuffer+BufferSize-4);
+ fBitsToRead=32;
fBuffer=0;
- for(Int_t i=0;i<4;i++){
- UInt_t val=0;
- val=*fPointBuffer;
- val&=0xFF;
- fPointBuffer++;
- val<<=8*i;
- fBuffer=fBuffer|val;
- }//end for
+ fBuffer=*fPointBuffer;
Int_t bit=0;
- UInt_t mask=0x1;
while(!bit){
- bit=fBuffer&mask;
- mask=mask<<1;
- fReadBits++;
+ bit=fBuffer&0x1;
+ fBuffer=fBuffer>>1;
+ fBitsToRead--;
}//end while
UInt_t packetNumber=ReadWordBuffer(sizeof(UInt_t)*8); //32 bits
if (fVerbose){
Int_t count=0;
Int_t timeDigit=0;
for(Int_t i=0;i<numWords;i++){
- UInt_t symbol=GetDecodedWord(RootNode[nextTableType],kTRUE);
+ UInt_t symbol=GetDecodedWordBuffer(RootNode[nextTableType]);
+ wordsRead++;
+ //Time reconstruction
+ if (nextTableType==1){
+ if (previousTime!=-1){
+ previousTime=symbol+previousTime+bunchLen;
+ }
+ else previousTime=symbol;
+ time=previousTime;
+ out[dim]=bunchLen+2;
+ dim++;
+ out[dim]=time;
+ dim++;
+ timeDigit=time-bunchLen;
+ }
+ if(nextTableType>1){
+ //
+ //ftxt<<symbol<<endl;
+ out[dim]=symbol;
+ dim++;
+ timeDigit++;
+ //padDigits->SetDigits(symbol,timeDigit);
+ }
+ NextTable(symbol,nextTableType,bunchLen,count);
+ if(nextTableType==0){
+ //
+ //ftxt<<time<<endl;
+ // ftxt<<(bunchLen+2)<<endl;
+ bunchLen=0;
+ }
+ }//end for
+ }//end while
+ return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+Int_t AliTPCCompression::DecompressWithLUTs(AliTPCHNode *RootNode[],UInt_t *LUTDimension[],AliTPCHNode **LUTNode[],Int_t /*NumTables*/,char* PointBuffer,UInt_t BufferSize,UShort_t out[],UInt_t &dim){
+ //This method decompress a file using separate Huffman tables and already prepared LUTs for fast decoding
+
+ // fPointBuffer=((UInt_t *)PointBuffer)+(UInt_t)(BufferSize/4)-1;
+ fPointBuffer=(UInt_t *)(PointBuffer+BufferSize-4);
+ fBitsToRead=32;
+ fBuffer=0;
+
+ fBuffer=*fPointBuffer;
+ Int_t bit=0;
+ while(!bit){
+ bit=fBuffer&0x1;
+ fBuffer=fBuffer>>1;
+ fBitsToRead--;
+ }//end while
+ UInt_t packetNumber=ReadWordBuffer(sizeof(UInt_t)*8); //32 bits
+ if (fVerbose){
+ cout<<"First one has been found "<<endl;
+ cout<<"Number of packets:"<<packetNumber<<endl;
+ }//end if
+ UInt_t k=0;
+ UInt_t wordsRead=0; //number of read coded words
+ while(k<packetNumber){
+ Int_t numWords,padNumber,rowNumber,secNumber=0;
+ ReadTrailer(numWords,padNumber,rowNumber,secNumber,kTRUE);
+ out[dim]=numWords;
+ dim++;
+ out[dim]=padNumber;
+ dim++;
+ out[dim]=rowNumber;
+ dim++;
+ out[dim]=secNumber;
+ dim++;
+ //ftxt<<"S:"<<secNumber<<" R:"<<rowNumber<<" P:"<<padNumber<<" W:"<<numWords<<endl;
+ // padDigits->SetPadID(padNumber,rowNumber,secNumber,DDL);
+ k++;
+ wordsRead+=4;
+ Int_t previousTime=-1;
+ Int_t time=0;
+ Int_t nextTableType=0;
+ Int_t bunchLen=0;
+ Int_t count=0;
+ Int_t timeDigit=0;
+ for(Int_t i=0;i<numWords;i++){
+ UInt_t symbol;
+ if(i == (numWords-1))
+ symbol = GetDecodedWordBuffer(RootNode[nextTableType]);
+ else
+ symbol=GetDecodedWordBufferWithLUTs(LUTDimension[nextTableType],LUTNode[nextTableType]);
wordsRead++;
//Time reconstruction
if (nextTableType==1){
//Time bin of the last amplitude sample in the bunch, amplitude values)
//It is used mainly for debugging
ofstream ftxt(fileOut);
- AliTPCBuffer160 buff(fileIn,0);
+ AliAltroBuffer buff(fileIn,0);
Int_t numWords,padNum,rowNum,secNum=0;
Int_t value=0;
if (fVerbose) cout<<"Creating a txt file from an Altro Format file"<<endl;
- while(buff.ReadTrailerBackward(numWords,padNum,rowNum,secNum) !=-1 ){
+ while(buff.ReadTrailerBackward(numWords,padNum,rowNum,secNum)){
ftxt<<"S:"<<secNum<<" R:"<<rowNum<<" P:"<<padNum<<" W:"<<numWords<<endl;
if (numWords%4){
for(Int_t j=0;j<(4-numWords%4);j++){