//if( fResponse->Do10to8() ) signal = Convert8to10( signal );
In this way the amplitude value for signal coming from SDD takes only 8 bits and not 10.
*/
+//DigitsFile is the input file that contains digits
-void AliITSDDLRawData(char* DigitsFile="galice.root"){
- #ifdef __NOCOMPILED__
+void AliITSDDLRawData(char* DigitsFile="galiceD.root"){
+#ifdef __NOCOMPILED__
if (gClassTable->GetID("AliRun") < 0) {
gROOT->LoadMacro("loadlibs.C");
loadlibs();
#ifdef __NOCOMPILED__
}
#endif
- // Connect the Root input file containing Geometry, Kine and Hits
- // galice.root file by default
- char* filename="galice.root";
- // TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(DigitsFile);
if (!file){
- // file = new TFile(filename);
file = new TFile(DigitsFile);
- cout<<"NEW FILE CREATED !!!"<<endl;
}//end if
file->ls();
- // Get AliRun object from file
- if (!gAlice) {
- gAlice = (AliRun*)file->Get("gAlice");
- if (gAlice)cout<<"AliRun object found on file "<<filename<<endl;
- if(!gAlice){
- cout<<"Can't access AliRun object on file "<<filename<<endl;
- cout<<"Macro execution stopped!!!"<<endl;
- }
- }
- // gAlice->SetTreeDFileName("digits.root");
- gAlice->SetTreeDFileName(DigitsFile);
- Int_t nparticles = gAlice->GetEvent(0);
- //
- // ITS
- AliITS *ITS = (AliITS*)gAlice->GetModule("ITS");
- Int_t nmodules;
- ITS->InitModules(-1,nmodules);
- cout<<"Number of ITS modules= "<<nmodules<<endl;
- //cout<<"Filling modules... It takes a while, now. Please be patient"<<endl;
- //ITS->FillModules(0,0,nmodules," "," ");
- //cout<<"ITS modules .... DONE!"<<endl;
- // DIGITS
- TTree *TD = gAlice->TreeD();
-
- AliITSDDLRawData *util=new AliITSDDLRawData();
- TStopwatch timer;
+ // Get AliRun object from file
+ if (!gAlice){
+ gAlice = (AliRun*)file->Get("gAlice");
+ if (gAlice)cout<<"AliRun object found on file "<<DigitsFile<<endl;
+ if(!gAlice){
+ cout<<"Can't access AliRun object on file "<<DigitsFile<<endl;
+ cout<<"Macro execution stopped!!!"<<endl;
+ exit(1);
+ }//end if
+ }//end if
+ gAlice->SetTreeDFileName(DigitsFile);
+ // Long_t nparticles = gAlice->GetEvent(0);
- //SILICON PIXEL DETECTOR
- cout<<"Formatting data for SPD"<<endl;
- timer.Start();
- util->RawDataSPD(ITS,TD);
- timer.Stop();
- timer.Print();
- //util->TestFormat();
+ //Int_t nparticles = gAlice->GetEvent(0);
+ //
+ // ITS
+ AliITS *ITS = (AliITS*)gAlice->GetModule("ITS");
+ Int_t nmodules;
+ ITS->InitModules(-1,nmodules);
+ cout<<"Number of ITS modules= "<<nmodules<<endl;
+ //cout<<"Filling modules... It takes a while, now. Please be patient"<<endl;
+ //ITS->FillModules(0,0,nmodules," "," ");
+ //cout<<"ITS modules .... DONE!"<<endl;
+ // DIGITS
- //SILICON DRIFT DETECTOR
- cout<<"Formatting data for SDD"<<endl;
- timer.Start();
- util->RawDataSDD(ITS,TD);
- timer.Stop();
- timer.Print();
-
- //SILICON STRIP DETECTOR
- cout<<"Formatting data for SSD"<<endl;
- timer.Start();
- util->RawDataSSD(ITS,TD);
- timer.Stop();
- timer.Print();
-
- delete util;
- return;
+
+ TTree* TD = (TTree*)file->Get("TreeD0");
+ if (TD == 0x0){
+ ::Error("DDLRawData","Can not find tree with ITS digits");
+ return;
+ }//end if
+ ITS->SetTreeAddressD(TD);
+
+
+ //TTree *TD = gAlice->TreeD();
+
+ AliITSDDLRawData *util=new AliITSDDLRawData();
+ //Verbose level
+ // 0: Silent
+ // 1: cout messages
+ // 2: txt files with digits
+ //BE CAREFUL, verbose level 2 MUST be used only for debugging and
+ //it is highly suggested to use this mode only for debugging digits files
+ //reasonably small, because otherwise the size of the txt files can reach
+ //quickly several MB wasting time and disk space.
+ util->SetVerbose(0);
+ TStopwatch timer;
+
+ //SILICON PIXEL DETECTOR
+ cout<<"Formatting data for SPD"<<endl;
+ timer.Start();
+ util->RawDataSPD(ITS,TD);
+ // util->RawDataSPD(ITS,TD,20);
+ timer.Stop();
+ timer.Print();
+ //ONLY FOR DEBUGGING
+ util->TestFormat();
+
+ //SILICON DRIFT DETECTOR
+ cout<<"Formatting data for SDD"<<endl;
+ timer.Start();
+ //util->RawDataSDD(ITS,TD,12);
+ util->RawDataSDD(ITS,TD);
+ timer.Stop();
+ timer.Print();
+
+ //SILICON STRIP DETECTOR
+ cout<<"Formatting data for SSD"<<endl;
+ timer.Start();
+ //util->RawDataSSD(ITS,TD,16);
+ util->RawDataSSD(ITS,TD);
+ timer.Stop();
+ timer.Print();
+
+ delete util;
+ return;
}
* about the suitability of this software for any purpose. It is *
* provided "as is" without express or implied warranty. *
**************************************************************************/
+
/* $Id$ */
+
//This class contains all the necessary methods to create the Raw Data
//files (slides) for the ITS data challenges for:
//SPD
//Default constructor
fIndex=-1;
fHalfStaveModule=-1;
+ fVerbose=0;
}
////////////////////////////////////////////////////////////////////////////////////////
//Copy Constructor
this->fIndex=source.fIndex;
this->fHalfStaveModule=source.fHalfStaveModule;
+ this->fVerbose=source.fVerbose;
return;
}
//Assigment operator
this->fIndex=source.fIndex;
this->fHalfStaveModule=source.fHalfStaveModule;
+ this->fVerbose=source.fVerbose;
return *this;
}
//STRIP
//
-void AliITSDDLRawData::GetDigitsSSD(TClonesArray *ITSdigits,Int_t mod, ULong_t *buf){
+void AliITSDDLRawData::GetDigitsSSD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,ULong_t *buf){
//This method packs the SSD digits in a proper 32 bits structure
Int_t ix;
Int_t iz;
ULong_t baseWord;
Int_t ndigits = ITSdigits->GetEntries();
AliITSdigit *digs;
+ ofstream ftxt;
if(ndigits){
+ if (fVerbose==2){
+ ftxt.open("SSDdigits.txt",ios::app);
+ }
for (Int_t digit=0;digit<ndigits;digit++) {
digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
iz=digs->fCoord1; // If iz==0, N side and if iz=1 P side
ix=digs->fCoord2; // Strip Numbar
is=digs->fSignal; // ADC Signal
// cout<<" Module:"<<mod-500<<" N/P side:"<<iz<<" Strip Number:"<<ix<<" Amplidute:"<<is-1<<endl;
+ if (fVerbose==2)
+ ftxt<<"DDL:"<<ddl<<" Mod: "<<modR<<" N/P: "<<iz<<" Strip: "<<ix<<" Value: "<<is-1<<endl;
baseWord=0;
word=is-1;
PackWord(baseWord,word,0,9);//ADC data
buf[fIndex]=baseWord;
}//end for
}//end if
+ if (fVerbose==2)
+ ftxt.close();
return;
}//end GetDigitsSSD
//Silicon Drift Detector
//
-void AliITSDDLRawData::GetDigitsSDD(TClonesArray *ITSdigits,Int_t mod, ULong_t *buf){
+void AliITSDDLRawData::GetDigitsSDD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,ULong_t *buf){
//This method packs the SSD digits in a proper 32 bits structure
Int_t ix;
Int_t iz;
ULong_t baseWord;
Int_t ndigits = ITSdigits->GetEntries();
AliITSdigit *digs;
+ ofstream ftxt;
if(ndigits){
//cout<<"Mudule "<<mod<<" number of digits "<<ndigits<<endl;
+ if (fVerbose==2)
+ ftxt.open("SDDdigits.txt",ios::app);
for (Int_t digit=0;digit<ndigits;digit++) {
digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
iz=digs->fCoord1; // Anode
ix=digs->fCoord2; // Time
is=digs->fSignal; // ADC Signal
+ if (fVerbose==2)
+ ftxt<<"DDL:"<<ddl<<" MID:"<<modR<<" An:"<<iz<<" T:"<<ix<<" A:"<<is<<endl;
// cout<<"Amplitude value:"<<is<<" Time Bucket:"<<ix<<" Anode:"<<iz<<endl;
if (is>255){cout<<"WARNING (!) bits words is needed)!!!\n";}
baseWord=0;
buf[fIndex]=baseWord;
}//end for
}//end if
+ if(fVerbose==2)
+ ftxt.close();
return;
}//end GetDigitsSDD
//PIXEL
//
-void AliITSDDLRawData::GetDigitsSPD(TClonesArray *ITSdigits,Int_t mod, ULong_t *buf){
- //This method packs the SPD digits in a proper 32 strucure
+void AliITSDDLRawData::GetDigitsSPD(TClonesArray *ITSdigits,Int_t mod,Int_t ddl, ULong_t *buf){
+ //This method packs the SPD digits in a proper 32 structure
+ //Since data is zero suppressed,the coordinates for the chip having zero digits
+ //doesn't get listed in the galice.root file. However the SPD format requires
+ //the empty chip to be written with chip header and chip trailer.
Int_t ix;
Int_t iz;
Int_t chipNo=0;
AliITSdigit *digs;
fHalfStaveModule++; //It's a private variable used to distinguish between the firs
//and the second module of an Half Stave Module
+ ofstream ftxt;
if(ndigits){
//loop over digits
+ if (fVerbose==2)
+ ftxt.open("SPDdigits.txt",ios::app);
for (Int_t digit=0;digit<ndigits;digit++){
digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit);
/*---------------------------------------------------------------------------
* Each module contains 5 read out chips of 256 rows and 32 columns.
- * So, the cell number in Z direction varies from 1 to 160. Therefore,
+ * So, the cell number in Z direction varies from 0 to 159. Therefore,
* to get the chip address (0 to 4), we need to divide column number by 32.
* ---------------------------------------------------------------------*/
iz=digs->fCoord1; // Cell number in Z direction
ix=digs->fCoord2; // Cell number in X direction
chipNo=iz/32;
+ if(fVerbose==2)
+ ftxt<<"DDL:"<<ddl<<" Mod:"<<mod<<" Row:"<<ix<<" Col:"<<iz<<endl;
hitRow=iz-chipNo*32;
if(fHalfStaveModule){
chipNo+=5;
fHalfStaveModule=-1;
}//end if
- //cout<<"Chip number of the current digit:"<<chipNo<<" Row:"<<hitRow<<" Column:"<<ix<<endl;
if(previousChip==-1){
//loop over chip without digits
//Even if there aren't digits for a given chip
else
WriteChipHeader(i,(mod/2),baseWord);
WriteChipTrailer(buf,chipHitCount,baseWord);
+ chipHitCount=0;
}//end for
- previousChip=chipNo;
WriteChipHeader(chipNo,(mod/2),baseWord);
chipHitCount++;
WriteHit(buf,ix,hitRow,baseWord);
+ previousChip=chipNo;
}//end if
else{
- chipHitCount++;
if(previousChip!=chipNo){
- WriteChipTrailer(buf,chipHitCount-1,baseWord);
+ WriteChipTrailer(buf,chipHitCount,baseWord);
+ chipHitCount=0;
for(Int_t i=previousChip+1;i<chipNo;i++){
WriteChipHeader(i,(mod/2),baseWord);
WriteChipTrailer(buf,0,baseWord);
+ chipHitCount=0;
}//end for
WriteChipHeader(chipNo,(mod/2),baseWord);
previousChip=chipNo;
}//end if
+ chipHitCount++;
WriteHit(buf,ix,hitRow,baseWord);
}//end else
}//end for
Int_t end=4;
if(chipNo>4)end+=5;
WriteChipTrailer(buf,chipHitCount,baseWord);
+ chipHitCount=0;
for(Int_t i=chipNo+1;i<=end;i++){
WriteChipHeader(i,(mod/2),baseWord);
WriteChipTrailer(buf,0,baseWord);
+ chipHitCount=0;
}//end for
}//end if
else{
for(Int_t i=0;i<5;i++){
WriteChipHeader(chipNo+i,(mod/2),baseWord);
WriteChipTrailer(buf,chipHitCount,baseWord);
+ chipHitCount=0;
}//end for
}//end else
+ if(fVerbose==2)
+ ftxt.close();
return;
}//end GetDigitsSPD
{74,75,78,79,226,227,230,231,234,235,238,239}};
Int_t ddlsPerFile=kDDLsNumber/LDCsNumber;
if(kDDLsNumber%LDCsNumber)ddlsPerFile++;
- cout<<"Number of DDL per File: "<<ddlsPerFile<<endl;
+ if(fVerbose)
+ cout<<"Number of DDL per File: "<<ddlsPerFile<<endl;
Int_t subd=0;
Int_t countDDL=0;
Int_t sliceNumber=1;
nbytes += TD->GetEvent(mapSPD[i][mod]);
//For each Module, buf contains the array of data words in Binary format
//fIndex gives the number of 32 bits words in the buffer for each module
- GetDigitsSPD(digitsInITS,mapSPD[i][mod],buf);
+ GetDigitsSPD(digitsInITS,mapSPD[i][mod],i,buf);
outfile.write((char *)buf,((fIndex+1)*sizeof(ULong_t)));
for(Int_t i=0;i<(fIndex+1);i++){
buf[i]=0;
Int_t ddlsPerFile=kDDLsNumber/LDCsNumber;
- if(20%LDCsNumber)ddlsPerFile++;
- cout<<"Number of DDL per File: "<<ddlsPerFile<<endl;
+ if(kDDLsNumber%LDCsNumber)ddlsPerFile++;
+ if(fVerbose)
+ cout<<"Number of DDL per File: "<<ddlsPerFile<<endl;
Int_t subd=2; //SSD
Int_t countDDL=0;
Int_t sliceNumber=1;
nbytes += TD->GetEvent(mapSSD[i][mod]);
//For each Module, buf contains the array of data words in Binary format
//fIndex gives the number of 32 bits words in the buffer for each module
- GetDigitsSSD(digitsInITS,mod,buf);
+ GetDigitsSSD(digitsInITS,mod,mapSSD[i][mod],i,buf);
outfile.write((char *)buf,((fIndex+1)*sizeof(ULong_t)));
for(Int_t i=0;i<(fIndex+1);i++){
buf[i]=0;
Int_t ddlsPerFile=kDDLsNumber/LDCsNumber;
if(kDDLsNumber%LDCsNumber)ddlsPerFile++;
- cout<<"Number of DDL per File: "<<ddlsPerFile<<endl;
+ if(fVerbose)
+ cout<<"Number of DDL per File: "<<ddlsPerFile<<endl;
Int_t subd=1;
Int_t countDDL=0;
Int_t sliceNumber=1;
//For each Module, buf contains the array of data words in Binary format
//fIndex gives the number of 32 bits words in the buffer for each module
// cout<<"MODULE NUMBER:"<<mapSDD[i][mod]<<endl;
- GetDigitsSDD(digitsInITS,mod,buf);
+ GetDigitsSDD(digitsInITS,mod,mapSDD[i][mod],i,buf);
outfile.write((char *)buf,((fIndex+1)*sizeof(ULong_t)));
for(Int_t i=0;i<(fIndex+1);i++){
buf[i]=0;
ChipAddr=(Int_t)temp;
UnpackWord(BaseWord,4,10,temp);
EventCnt=(Int_t)temp;
- cout<<"Chip: "<<ChipAddr<<" Half Stave module:"<<EventCnt<<endl;
+ if(fVerbose)
+ cout<<"Chip: "<<ChipAddr<<" Half Stave module:"<<EventCnt<<endl;
return;
}//end ReadChipHeader
//This method writes a chip trailer
//pixel fill word
if((ChipHitCount%2)!=0){
- PackWord(BaseWord,0xFECD,0,15);
+ PackWord(BaseWord,0xFEDC,0,15);
}
PackWord(BaseWord,ChipHitCount,16,28);
PackWord(BaseWord,0x0,30,31);
//cout<<"Block Size: "<<size<<endl;
size=miniHeader[0];
UnpackWord(miniHeader[2],16,31,ddlsNumber);
- ftxt<<"DDL NUMBER:"<<ddlsNumber<<endl;
+ //ftxt<<"DDL NUMBER:"<<ddlsNumber<<endl;
ULong_t word=0;
- ULong_t code=0;
- ULong_t decoded1,decoded2=0;
+ ULong_t codeH,codeL=0;
+ ULong_t chip=0;
+ ULong_t half=0;
+ ULong_t col=0;
+ ULong_t row=0;
+ Int_t moduleID=0;
+ ULong_t hitscount=0;
+ Int_t previous=-1;
for(ULong_t j=0;j<(size/4);j++){
f.read((char*)(&word),sizeof(word)); //32 bits word
- code=0;
- UnpackWord(word,14,15,code);
- DecodeWord(code,word,0,decoded1,decoded2);
- switch (code){
- case 0://trailer
- ftxt<<"Number of Hit:"<<decoded1<<endl;
- break;
- case 1://header
- ftxt<<"Half Stave Number:"<<decoded1<<" Chip Number:"<<decoded2<<endl;
- break;
- case 2://hit
- ftxt<<"Row:"<<decoded1<<" Column:"<<decoded2<<endl;
- break;
- case 3://fill word
- break;
- }//end switch
- code=0;
- UnpackWord(word,30,31,code);
- DecodeWord(code,word,1,decoded1,decoded2);
- switch (code){
- case 0://trailer
- ftxt<<"Number of Hit:"<<decoded1<<endl;
- break;
- case 1://header
- ftxt<<"Half Stave Number:"<<decoded1<<" Chip Number:"<<decoded2<<endl;
- break;
- case 2://hit
- ftxt<<"Row:"<<decoded1<<" Column:"<<decoded2<<endl;
- break;
- case 3://fill word
- break;
- }//end switch
+ UnpackWord(word,30,31,codeH);
+ UnpackWord(word,14,15,codeL);
+ if ((codeH==2)&&(codeL==1)){
+ UnpackWord(word,0,3,chip);
+ UnpackWord(word,4,10,half);
+ moduleID=half*2+chip/5;
+ if (moduleID!=previous){
+ if (hitscount){
+ previous=moduleID;
+ hitscount=0;
+ }
+ }
+ chip=chip%5;
+ row=col=0;
+ UnpackWord(word,21,28,row);
+ UnpackWord(word,16,20,col);
+ col=col+32*chip;
+ hitscount++;
+ ftxt<<"DDL:"<<ddlsNumber<<" Mod:"<<moduleID<<" Row:"<<row<<" Col:"<<col<<endl;
+ }//end if
+ else if ((codeH==2)&&(codeL==2)){
+ row=col=0;
+ UnpackWord(word,5,12,row);
+ UnpackWord(word,0,4,col);
+ col=col+32*chip;
+ ftxt<<"DDL:"<<ddlsNumber<<" Mod:"<<moduleID<<" Row:"<<row<<" Col:"<<col<<endl;
+ row=col=0;
+ UnpackWord(word,21,28,row);
+ UnpackWord(word,16,20,col);
+ col=col+32*chip;
+ ftxt<<"DDL:"<<ddlsNumber<<" Mod:"<<moduleID<<" Row:"<<row<<" Col:"<<col<<endl;
+ hitscount++;
+ hitscount++;
+ }//end else if
+ else if ((codeH==0)&&(codeL==2)){
+ row=col=0;
+ UnpackWord(word,5,12,row);
+ UnpackWord(word,0,4,col);
+ col=col+32*chip;
+ hitscount++;
+ ftxt<<"DDL:"<<ddlsNumber<<" Mod:"<<moduleID<<" Row:"<<row<<" Col:"<<col<<endl;
+ }//end else if
}//end for
}//end while
f.clear();
ftxt.close();
return;
}
-
-void AliITSDDLRawData::DecodeWord(ULong_t Code,ULong_t BaseWord,Int_t FirstHalf,ULong_t &Decoded1,ULong_t &Decoded2){
- //FirstHalf=0 ==>bits from 0 to 15
- //FirstHalf=1 ==>bits from 16 to 31
- if(!FirstHalf){
- switch (Code){
- case 0://trailer
- UnpackWord(BaseWord,0,12,Decoded1);
- break;
- case 1://header
- UnpackWord(BaseWord,4,10,Decoded1);
- UnpackWord(BaseWord,0,3,Decoded2);
- break;
- case 2://hit
- UnpackWord(BaseWord,5,12,Decoded1);
- UnpackWord(BaseWord,0,4,Decoded2);
- break;//fill word
- case 3:
- UnpackWord(BaseWord,0,13,Decoded1);
- break;
- }//end switch
- }
- else{
- switch (Code){
- case 0://trailer
- UnpackWord(BaseWord,16,28,Decoded1);
- break;
- case 1://header
- UnpackWord(BaseWord,20,26,Decoded1);
- UnpackWord(BaseWord,16,19,Decoded2);
- break;
- case 2://hit
- UnpackWord(BaseWord,21,28,Decoded1);
- UnpackWord(BaseWord,16,20,Decoded2);
- break;
- case 3://fill word
- UnpackWord(BaseWord,16,29,Decoded1);
- break;
- }//end switch
- }
- return;
-}
Int_t RawDataSSD(AliITS *ITS,TTree *TD ,Int_t LDCsNumber=2);
// This method generates the files with the Silicon pixel detector data
void TestFormat();
- //A debugging method used to test the files generated for the SPD.
+ // A debugging method used to test the files generated for the SPD.
+ void SetVerbose(Int_t Verbose){fVerbose=Verbose;}
+ // To set the verbose level
private:
- void GetDigitsSPD(TClonesArray *ITSdigits, Int_t mod, ULong_t *buf);
+ void GetDigitsSPD(TClonesArray *ITSdigits, Int_t mod,Int_t ddl,ULong_t *buf);
//This method formats and stores in buf all the digits of a SPD module
- void GetDigitsSDD(TClonesArray *ITSdigits, Int_t mod, ULong_t *buf);
+ void GetDigitsSDD(TClonesArray *ITSdigits, Int_t mod,Int_t modR,Int_t ddl,ULong_t *buf);
//This method formats and stores in buf all the digits of a SDD module
- void GetDigitsSSD(TClonesArray *ITSdigits, Int_t mod, ULong_t *buf);
+ void GetDigitsSSD(TClonesArray *ITSdigits, Int_t mod,Int_t modR,Int_t ddl,ULong_t *buf);
//This method formats and stores in buf all the digits of a SSD module
void PackWord(ULong_t &BaseWord, ULong_t Word, Int_t StartBit, Int_t StopBit);
//This method stores the value of the variable Word of StopBit-StartBit+1 bits
//Silicon pixel detector data format
void ReadChipHeader(Int_t &ChipAddr,Int_t &EventCnt,ULong_t BaseWord);
void ReadChipTrailer(Int_t &ChipHitCount,ULong_t BaseWord);
- void DecodeWord(ULong_t Code,ULong_t BaseWord,Int_t FirstHalf,ULong_t &Decoded1,ULong_t &Decoded2);
//Methods used for reading and dubugging SPD data files
-
+ Int_t fVerbose; //Verbose level (0:no msg, 1:msg, 2:digits in txt files)
Long_t fIndex; //number of 32 words to be stored into the output file
Int_t fHalfStaveModule; //first or second half of an Half Stave module
ClassDef(AliITSDDLRawData,1)
// tree=new TTree("tree","Values");
fNumberOfDigits=0;
fVerbose=0;
+ remove("TPCdigits.txt");
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
data.SubSec=SubSec;
data.Row=row;
digrow->First();
+ Int_t padID=-1;
+ Int_t ddlNumber=0;
+ ofstream ftxt;
+ if (fVerbose==2){
+ ftxt.open("TPCdigits.txt",ios::app);
+ if(sec<36)
+ ddlNumber=sec*2+SubSec;
+ else
+ ddlNumber=72+(sec-36)*4+SubSec;
+ }//end if
do{
- data.Dig=digrow->CurrentDigit(); //adc
- data.Time=digrow->CurrentRow(); //time
- data.Pad =digrow->CurrentColumn(); // pad
+ data.Dig=digrow->CurrentDigit(); //adc
+ data.Time=digrow->CurrentRow(); //time
+ data.Pad =digrow->CurrentColumn(); // pad
+ if(fVerbose==2)
+ if (padID!=data.Pad){
+ ftxt<<"S:"<<data.Sec<<" DDL:"<<ddlNumber<<" R:"<<data.Row<<" P:"<<data.Pad<<endl;
+ padID=data.Pad;
+ }//end if
if(data.Dig>eth){
switch (flag){
case 0:{
fNumberOfDigits++;
f.write((char*)(&data),sizeof(data));
+ if(fVerbose==2)
+ ftxt<<"A:"<<data.Dig<<" T:"<<data.Time<<endl;
break;
}//end case 0
case 1:{
if((data.Pad>=minPad)&&(data.Pad<=maxPad)){
f.write((char*)(&data),sizeof(data));
+ if(fVerbose==2)
+ ftxt<<"A:"<<data.Dig<<" T:"<<data.Time<<endl;
fNumberOfDigits++;
}
break;
case 2:{
if((data.Pad<minPad)||(data.Pad>maxPad)){
f.write((char*)(&data),sizeof(data));
+ if(fVerbose==2)
+ ftxt<<"A:"<<data.Dig<<" T:"<<data.Time<<endl;
fNumberOfDigits++;
}
break;
};//end switch
}//end if
}while (digrow->Next());
+ if (fVerbose==2)
+ ftxt.close();
return;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
ULong_t GetDigNumber()const{return fNumberOfDigits;}
void SetVerbose(Int_t val){fVerbose=val;}
private:
- Int_t fVerbose; //Verbosity level: 0-silent, not 0-all printout
+ Int_t fVerbose; //Verbosity level: 0-silent, 1:cout msg, 2: txt files for checking
fstream f; //The IO file name
//TFile *fout;
//TTree *tree;
#else
f.open(fileName,ios::in);
#endif
- if(!f){cout<<"File doesn't exist\n";exit(-1);}
+ if(!f){cout<<"File doesn't exist:"<<fileName<<endl;;exit(-1);}
fShift=0;
//To get the file dimension (position of the last element in term of bytes)
f.seekg(0, ios::end);
fFilePosition-=sizeof(ULong_t)*5;
f.seekg(fFilePosition);
f.read((char*)fBuffer,sizeof(ULong_t)*5);
+
+ //cout<<"Buffer letto"<<endl;
+ /*
+ char* tt=(char*)fBuffer;
+ for(Int_t ii=0;ii<20;ii++){
+ cout<<hex;
+ cout<<ii<<"==> "<<(Int_t)*tt<<endl;
+ cout<<dec;
+ tt++;
+ }
+ cout<<0<<" --- "<<hex<<fBuffer[0]<<dec<<endl;
+ cout<<1<<" --- "<<hex<<fBuffer[1]<<dec<<endl;
+ cout<<2<<" --- "<<hex<<fBuffer[2]<<dec<<endl;
+ cout<<3<<" --- "<<hex<<fBuffer[3]<<dec<<endl;
+ cout<<4<<" --- "<<hex<<fBuffer[4]<<dec<<endl;
+ cout<<"Fine ULong_t"<<endl;
+ */
fCurrentCell=4;
fShift=22;
fMaskBackward=0xFF;
* about the suitability of this software for any purpose. It is *
* provided "as is" without express or implied warranty. *
**************************************************************************/
+
/* $Id$ */
+
// This class contains the implementation of the
// compression and decompression algorithms
// Compression is performed reading the Altro data block (called packet) backward.
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////
+Int_t AliTPCCompression::CreateTableFormula(Double_t beta,ULong_t M,Int_t dim,Int_t Type){
+ // Type = 0 for Bunch length
+ // Type = 1 for Time Gap
+ ULong_t freq;
+ Double_t sum=0;
+ Double_t min=10;
+ Double_t alpha=0;
+ Double_t A=0;
+ AliTPCHTable *Table=new AliTPCHTable(dim);
+
+ freq=1;
+ Double_t FreqArray[1024];
+ for(Int_t i=0;i<1024;i++){
+ 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));
+ else
+ 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;
+ if (fVerbose)
+ 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);
+ else
+ Table->SetValFrequency(x,0);
+ else //Time table
+ Table->SetValFrequency(x,A*FreqArray[x]);
+ }
+ Table->BuildHTable();
+ ofstream fTable;
+ char filename[15];
+ sprintf(filename,"Table%d.dat",Type);
+ fTable.open(filename,ios::binary);
+ 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));
+ } //end for
+ fTable.close();
+ delete Table;
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////
Int_t AliTPCCompression::CreateTables(const char* fSource,const Int_t NumTables){
//Tables manager
/*
Int_t n=10;// 10 bits per symbol
AliTPCHTable ** table = new AliTPCHTable*[NumTables];
//The table is inizialized with the rigth number of rows
- for(Int_t i=0;i<NumTables;i++){table[i]=new AliTPCHTable((Int_t)(TMath::Power(2,n)));}
+ for(Int_t i=0;i<NumTables;i++){
+ table[i]=new AliTPCHTable((Int_t)(TMath::Power(2,n)));
+ table[i]->SetVerbose(fVerbose);
+ }
//The frequencies are calculated and the tables are filled
if (fVerbose)
cout<<"Filling tables...\n";
if (fVerbose)
cout<<"Tables filled \n";
+
+ //Frequencies normalization
+ table[0]->NormalizeFrequencies();
+ table[1]->NormalizeFrequencies();
+ table[2]->NormalizeFrequencies();
+ table[3]->NormalizeFrequencies();
+ table[4]->NormalizeFrequencies();
+
//Tables are saved in a sequence of text file and using the macro Histo.C is it possible to get
//a series of histograms rappresenting the frequency distribution
table[0]->StoreFrequencies("BunchLenFreq.txt");
#else
fTable.open(filename);
#endif
+ if(!fTable){cout<<"File doesn't exist:"<<filename<<endl; exit(1);}
fTable.read((char*)(&dim),sizeof(Int_t));
if (fVerbose)
cout<<"Table dimension: "<<dim<<endl;
//At this point the trees are been built
return 0;
}
+
+Int_t AliTPCCompression::CreateTablesFromTxtFiles(Int_t NumTable){
+ //This method creates a set of binary tables, needed by the Huffman
+ //algorith, starting from a set of frequencies tables stored in form of
+ //txt files
+ if (fVerbose)
+ cout<<"Retrieving frequencies from txt files \n";
+ ifstream fTable;
+ char filename[15];
+ //Tables are read from the files (Each codeword has been "Mirrored")
+ AliTPCHTable **table = new AliTPCHTable*[NumTable];
+ for(Int_t k=0;k<NumTable;k++){
+ sprintf(filename,"Table%d.txt",k);
+ cout<<filename<<endl;
+ fTable.open(filename);
+ if(!fTable){cout<<"File doesn't exist: "<<filename<<endl; exit(1);}
+ Int_t symbol=0;
+ Double_t freq=0;
+ table[k]=new AliTPCHTable(1024);
+ while(!fTable.eof()){
+ fTable>>freq;
+ if (fTable.good()){
+ if (freq<0){
+ cout<<"Frequency cannot be negative !!!\n";
+ exit(1);
+ }
+ table[k]->SetValFrequency(symbol,freq);
+ }
+ symbol++;
+ }//end while
+ fTable.clear();
+ fTable.close();
+ }//end for
+ fStat.open("Statistics",ios::app);
+ fStat<<endl;
+ fStat<<"----------------- ENTROPY for external txt tables --------------------------"<<endl;
+ fStat<<"Entropy of Bunch length table......."<<table[0]->GetEntropy()<<endl;
+ fStat<<"Entropy of Time bin table..........."<<table[1]->GetEntropy()<<endl;
+ fStat<<"Entropy of one Sample bunch table..."<<table[2]->GetEntropy()<<endl;
+ fStat<<"Entropy of Central Sample table....."<<table[3]->GetEntropy()<<endl;
+ fStat<<"Entropy Border Samples table........"<<table[4]->GetEntropy()<<endl;
+ fStat.close();
+ for(Int_t k=0;k<NumTable;k++){
+ table[k]->BuildHTable();
+ }//end for
+ //The tables are saved ad binary files
+ StoreTables(table,NumTable);
+ //The tables stored in memory are deleted;
+ for(Int_t i=0;i<NumTable;i++)delete table[i];
+ delete [] table;
+ return 0;
+}
+
////////////////////////////////////////////////////////////////////////////////////////
/* COMPRESSION */
////////////////////////////////////////////////////////////////////////////////////////
Double_t ratio=(dimension/fillWords)*100;
fStat<<"Compression ratio (Compressed/Uncompressed)..."<<ratio<<"%"<<endl;
fStat<<endl;
- fStat<<"Bunch length size in bytes......"<<(ULong_t)TMath::Ceil(stat[0]/8)<<" Comppression.."<<(stat[0]/numElem[0])*10<<"%"<<endl;
-
- fStat<<"Time gap size in bytes.........."<<(ULong_t)TMath::Ceil(stat[1]/8)<<" Comppression.."<<(stat[1]/numElem[1])*10<<"%"<<endl;
- fStat<<"Amplitude values in bytes......."<<(ULong_t)TMath::Ceil((stat[2]+stat[3]+stat[4])/8)<<" Comppression.."<<
- ((stat[2]+stat[3]+stat[4])/(numElem[2]+numElem[3]+numElem[4]))*10<<"%"<<endl;
+ if (numElem[0])
+ fStat<<"Bunch length size in bytes......"<<(ULong_t)TMath::Ceil(stat[0]/8)<<" Comppression.."<<(stat[0]/numElem[0])*10<<"%"<<endl;
+ if (numElem[1])
+ fStat<<"Time gap size in bytes.........."<<(ULong_t)TMath::Ceil(stat[1]/8)<<" Comppression.."<<(stat[1]/numElem[1])*10<<"%"<<endl;
+ if (numElem[2]+numElem[3]+numElem[4])
+ fStat<<"Amplitude values in bytes......."<<(ULong_t)TMath::Ceil((stat[2]+stat[3]+stat[4])/8)<<" Comppression.."<<
+ ((stat[2]+stat[3]+stat[4])/(numElem[2]+numElem[3]+numElem[4]))*10<<"%"<<endl;
+ if (numElem[2])
fStat<<" One Samples in bytes............"<<(ULong_t)TMath::Ceil(stat[2]/8)<<" Comppression.."<<(stat[2]/numElem[2])*10<<"%"<<endl;
+ if (numElem[3])
fStat<<" Central Samples size in bytes..."<<(ULong_t)TMath::Ceil(stat[3]/8)<<" Comppression.."<<(stat[3]/numElem[3])*10<<"%"<<endl;
+ if (numElem[4])
fStat<<" Border Samples size in bytes...."<<(ULong_t)TMath::Ceil(stat[4]/8)<<" Comppression.."<<(stat[4]/numElem[4])*10<<"%"<<endl;
fStat<<endl;
fStat<<"Average number of bits per word"<<endl;
- fStat<<"Bunch length ......"<<stat[0]/numElem[0]<<endl;
- fStat<<"Time gap .........."<<stat[1]/numElem[1]<<endl;
- fStat<<"One Samples........"<<stat[2]/numElem[2]<<endl;
- fStat<<"Central Samples ..."<<stat[3]/numElem[3]<<endl;
- fStat<<"Border Samples....."<<stat[4]/numElem[4]<<endl;
+ if (numElem[0])
+ fStat<<"Bunch length ......"<<stat[0]/numElem[0]<<endl;
+ if (numElem[1])
+ fStat<<"Time gap .........."<<stat[1]/numElem[1]<<endl;
+ if (numElem[2])
+ fStat<<"One Samples........"<<stat[2]/numElem[2]<<endl;
+ if (numElem[3])
+ fStat<<"Central Samples ..."<<stat[3]/numElem[3]<<endl;
+ if (numElem[4])
+ fStat<<"Border Samples....."<<stat[4]/numElem[4]<<endl;
fStat.close();
return 0;
}
#else
f.open(fname,ios::in);
#endif
- if(!f){cout<<"File doesn't exist\n";return -1;}
+ if(!f){cout<<"File doesn't exist:"<<fname<<endl;;return -1;}
AliTPCHNode ** rootNode = new AliTPCHNode*[NumTables];
//Creation of the Huffman trees
CreateTrees(rootNode,NumTables);
#else
f.open(fname,ios::in);
#endif
- if(!f){cout<<"File doesn't exist\n";return -1;}
+ if(!f){cout<<"File doesn't exist:"<<fname<<endl;;return -1;}
//to go to the end of the file
f.seekg(0,ios::end);
//to get the file dimension in byte
AliTPCBuffer160 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 ){
- ftxt<<"W:"<<numWords<<" P:"<<padNum<<" R:"<<rowNum<<" S:"<<secNum<<endl;
+ ftxt<<"S:"<<secNum<<" R:"<<rowNum<<" P:"<<padNum<<" W:"<<numWords<<endl;
if (numWords%4){
for(Int_t j=0;j<(4-numWords%4);j++){
value=buff.GetNextBackWord();
//This method is used to compute the frequencies of the symbols in the source file
Int_t CreateTables(const char* fSource,const Int_t NumTables);
//This method is used to create and store the tables
+ Int_t CreateTableFormula(Double_t beta,ULong_t M,Int_t dim,Int_t Type);
+ //This method is used to create and store the Bunch length or Time Gap Table using a formula
void SetVerbose(Int_t val){fVerbose=val;}
//This method is used to set up the verbose level
// 0 ==> No output messages are displayed
void ReadAltroFormat(char* fileOut,char* fileIn)const;
//This method is used to read an Altro file and generate a text file containing the same information
//It's is useful for debugging
-
+ Int_t CreateTablesFromTxtFiles(Int_t NumTable);
+ //This method creates a set of binary tables starting from a set of txt tables
private:
Int_t StoreTables(AliTPCHTable* table[],const Int_t NumTable);
//This method is used to store an array of tables in a sequence of binary files
sprintf(cname,"TreeD_75x40_100x60_150x60_%d",eventn);
digarr->ConnectTree(cname);
AliTPCBuffer *b=new AliTPCBuffer("AliTPCDDL.dat");
+
+ //Verbose level
+ // 0: Silent
+ // 1: cout messages
+ // 2: txt files with digits
+ //BE CAREFUL, verbose level 2 MUST be used only for debugging and
+ //it is highly suggested to use this mode only for debugging digits files
+ //reasonably small, because otherwise the size of the txt files can reach
+ //quickly several MB wasting time and disk space.
+ b->SetVerbose(0);
+
+
Int_t nrows=Int_t(digarr->GetTree()->GetEntries());
cout<<"Number of entries "<<nrows<<endl;
Int_t PSector=-1;
//TABLES CREATION
//The Altro File "AltroFormatDDL.dat" is built from "AliTPCDDL.dat"
util->RawDataAltro();
- u->SetVerbose(1);
+ //u->SetVerbose(1);
//The file "AltroFormatDDL.dat" is converted in a txt file "AltroFormatDDL.txt"
//that is used for debugging
+ /*
+ cout<<"Creating a txt file from an Altro format file"<<endl;
u->ReadAltroFormat("AltroFormatDDL.txt","AltroFormatDDL.dat");
+ */
//Tables are created and stored in as sequence of binary files
u->CreateTables("AltroFormatDDL.dat",NumTable);
util->RawDataAltroDecode(LDCsNumber,0);
///The Altro file AltroDDLRecomposed.dat is converted in a txt file AltroDDLRecomposed.txt
//This file must be equal to the ones created above.
+ cout<<"Creating a txt file from an Altro format file"<<endl;
u->ReadAltroFormat("AltroDDLRecomposed.txt","AltroDDLRecomposed.dat");
*/
-
+
//SLICE COMPRESSION
cout<<"Slice Compression"<<endl;
timer.Stop();
timer.Print();
-
/*
//SLICE DECOMPRESSION
timer.Start();
timer.Stop();
timer.Print();
*/
-
+
/*
//SLICE DECOMPRESSED CHECKING
//A new Altro file is created from the decompressed slides
util->RawDataAltroDecode(LDCsNumber,1);
//Convertion of the Altro file AltroDDLRecomposedDec.dat in a txt file AltroDDLRecomposedDec.txt
//Useful for debugging
+ cout<<"Creating a txt file from an Altro format file"<<endl;
u->ReadAltroFormat("AltroDDLRecomposedDec.txt","AltroDDLRecomposedDec.dat");
*/
delete util;
AliTPCDDLRawData::AliTPCDDLRawData(const AliTPCDDLRawData &source){
// Copy Constructor
+ fVerbose=source.fVerbose;
return;
}
AliTPCDDLRawData& AliTPCDDLRawData::operator=(const AliTPCDDLRawData &source){
//Assigment operator
+ fVerbose=source.fVerbose;
return *this;
}
#else
f.open(filename,ios::in);
#endif
- if(!f){cout<<"File doesn't exist \n";exit(1);}
+ if(!f){cout<<"BE CAREFUL!! There isn't enough data to generate "<<LDCsNumber<<" slices"<<endl;break;}
cout<<filename<<" "<<dest<<endl;
ofstream fdest;
#ifndef __DECCXX
//here the Mini Header is read
while( (f.read((char*)(miniHeader),sizeof(ULong_t)*3)) ){
size=miniHeader[0];
+ // cout<<"Data size:"<<size<<endl;
//Int_t dim=sizeof(ULong_t)+sizeof(Int_t)*5;
//cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" size "<<size<<endl;
//open the temporay File
fo.close();
//The temp file is compressed or decompressed
AliTPCCompression *util = new AliTPCCompression();
- // util->SetVerbose(1);
- if(!Comp)
+ util->SetVerbose(0);
+ if(!Comp){
util->CompressDataOptTables(kNumTables,temp,"TempCompDecomp");
+ }
else
util->DecompressDataOptTables(kNumTables,temp,"TempCompDecomp");
delete util;
/////////////////////////////////////////////////////////////////////////////////
void AliTPCDDLRawData::RawDataAltro()const{
//This method is used to build the Altro format from AliTPCDDL.dat
- //It is used to debug the code and create the tables used in the compresseion phase
+ //It is used to debug the code and creates the tables used in the compresseion phase
Int_t offset=1;
ifstream f;
#ifndef __DECCXX
#else
f.open(filename,ios::in);
#endif
- if(!f){cout<<"The file doesn't exist"<<endl;exit(1);}
+ if(!f){cout<<"BE CAREFUL!! There isn't enough data to generate "<<LDCsNumber<<" slices"<<endl;break;}
//loop over the DDL block
//Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
//The number of block is ceil(216/LDCsNumber)
ULong_t miniHeader[3];
//here the Mini Header is read
+ //cout<<filename<<endl;
while( (f.read((char*)(miniHeader),sizeof(ULong_t)*3)) ){
- //cout<<"Mini header dimension "<<miniHeader[0]<<endl;
Int_t car=0;
size=miniHeader[0];
for(ULong_t j=0;j<size;j++){
class AliTPCDDLRawData:public TObject{
public:
- AliTPCDDLRawData(){;}//default constructor
+ AliTPCDDLRawData(){fVerbose=0;}//default constructor
virtual ~AliTPCDDLRawData(){;}//destructor
AliTPCDDLRawData(const AliTPCDDLRawData &source); // copy constructor
AliTPCDDLRawData& operator=(const AliTPCDDLRawData &source); // ass. op.
void RawDataAltroDecode(Int_t LDCsNumber,Int_t Comp=0);
//This method is used to construct an Altro format file starting from
//the slices compressed or uncompressed
+ void SetVerbose(Int_t Verbose){fVerbose=Verbose;}
private:
+ Int_t fVerbose; //Verbose level 0:Silent, 1: cout msg, 2:txt files for debugging
ClassDef(AliTPCDDLRawData,1)
};
#if !defined(__CINT__) || defined(__MAKECINT__)
-#include <fstream.h>
+#include <Riotream.h>
#include <alles.h>
#include "AliTPCCompression.h"
#endif
AliTPCCompression *util = new AliTPCCompression();
TStopwatch timer;
//verbose level can be: 0=silent 1=few messages 2=pedantic output
- util->SetVerbose(2);
- //Tables are created
- util->CreateTables(fSource,NumTable);
- //util->ReadAltroFormat("File1.txt","AltroFormat.dat");
- //The source file is compressed
+ util->SetVerbose(1);
+ Int_t choice;
+ do{
+ cout<<"**** Chose the tables set **** "<<endl;
+ cout<<"1==> Create tables from the input file "<<endl;
+ cout<<"2==> Use external optimized tables (txt format)"<<endl;
+ cout<<"3==> Time gap and Bunch length tables generated using formulas "<<endl;
+ cout<<"Insert the corresponding number: ";
+ cin>>choice;
+ cout<<endl;
+ }while((choice<1)||(choice>3));
+ switch(choice){
+ case 1:{
+ //Tables are created
+ util->CreateTables(fSource,NumTable);
+ cout<<"Tables have been created"<<endl;
+ break;
+ }
+ case 2:{
+ util->CreateTablesFromTxtFiles(NumTable);
+ break;
+ }
+ case 3:{
+ Double_t beta,gamma=0;
+ ULong_t mul=0;
+ cout<<"Multiplicity (suggested 20000) ==> ";
+ cin>>mul;
+ cout<<"Gamma (suggested 4.77) ==> ";
+ cin>>gamma;
+ cout<<"Beta (suggested 0.37) ==> ";
+ cin>>beta;
+ util->CreateTables(fSource,NumTable);
+ util->CreateTableFormula(gamma,mul,300,0);
+ util->CreateTableFormula(beta,mul,445,1);
+ break;
+ }
+ };
+
+ //BE CAREFUL, the following method must be used only for debugging and
+ //it is highly suggested to use it only for debugging files
+ //reasonably small, because otherwise the size of the txt files can reach
+ //quickly several MB wasting time and disk space.
+
+ // util->ReadAltroFormat("File1.txt",fSource);
+ //The source file is compressed
timer.Start();
util->CompressDataOptTables(NumTable,fSource,fDest);
timer.Stop();
timer.Print();
- /*
+
+ /*
//The Compressed file is decompressed
timer.Start();
util->DecompressDataOptTables(NumTable,fDest);
timer.Stop();
timer.Print();
- //util->ReadAltroFormat("File2.txt","SourceDecompressed.dat");
+ util->ReadAltroFormat("File2.txt","SourceDecompressed.dat");
*/
delete util;
}
//////////////////////////////////////////////////////////////////////////////
+Int_t AliTPCHTable::NormalizeFrequencies(){
+ //This method normalized the frequencies
+ //Frequencies normalization
+ Double_t sum=0.;
+ for (Int_t i=0; i< fSize; i++) {
+ sum+=fCode[i];
+ }//end for
+ if (fVerbose){
+ cout<<"Frequency sum: "<<sum<<endl;
+ }//end if
+ if(sum!=0.){
+ for (Int_t i=0; i< fSize; i++) {
+ fCode[i]/=sum;
+ if ((fCode[i]!=0.) && (fCode[i]<10e-20))cout<<"Frequency value very small !!! "<<fCode[i]<<endl;
+ }//end for
+ }
+ return 0;
+}
+//////////////////////////////////////////////////////////////////////////////
Int_t AliTPCHTable::StoreFrequencies(const char *fname)const{
//It stores the frequencies in a text file
ofstream ftxt(fname);
for (Int_t i=0;i<fSize;i++){
- ftxt<<(ULong_t)fCode[i]<<endl;
+ ftxt<<fCode[i]<<endl;
}
ftxt.close();
return 0;
void SetVerbose(Int_t val){fVerbose=val;}
//Method to set directly a frequency
Int_t SetValFrequency(const Int_t Val,Double_t Value);
+ Int_t NormalizeFrequencies();
private:
//This method executes the pre-order visit of an Huffman tree and calculates the
//codeword for each leaf