New classes and macros for raw data compression and ADC (D.Favretto)
authorhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 12 Feb 2003 11:23:23 +0000 (11:23 +0000)
committerhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 12 Feb 2003 11:23:23 +0000 (11:23 +0000)
21 files changed:
ITS/AliITSDDLRawData.C [new file with mode: 0644]
ITS/AliITSDDLRawData.cxx [new file with mode: 0644]
ITS/AliITSDDLRawData.h [new file with mode: 0644]
ITS/ITSLinkDef.h
ITS/libITS.pkg
TPC/AliTPCAltro.C [new file with mode: 0644]
TPC/AliTPCBuffer.cxx [new file with mode: 0644]
TPC/AliTPCBuffer.h [new file with mode: 0644]
TPC/AliTPCBuffer160.cxx [new file with mode: 0644]
TPC/AliTPCBuffer160.h [new file with mode: 0644]
TPC/AliTPCCompression.cxx [new file with mode: 0644]
TPC/AliTPCCompression.h [new file with mode: 0644]
TPC/AliTPCDDL.C [new file with mode: 0644]
TPC/AliTPCDDLRawData.C [new file with mode: 0644]
TPC/AliTPCDDLRawData.cxx [new file with mode: 0644]
TPC/AliTPCDDLRawData.h [new file with mode: 0644]
TPC/AliTPCH5OptimizedTables.C [new file with mode: 0644]
TPC/AliTPCHuffman.cxx [new file with mode: 0644]
TPC/AliTPCHuffman.h [new file with mode: 0644]
TPC/TPCLinkDef.h
TPC/libTPC.pkg

diff --git a/ITS/AliITSDDLRawData.C b/ITS/AliITSDDLRawData.C
new file mode 100644 (file)
index 0000000..ede2ebb
--- /dev/null
@@ -0,0 +1,91 @@
+#if !defined(__CINT__) || defined(__MAKECINT__)
+
+#include <iostream.h>
+#include "AliITSDDLRawData.h"
+#endif
+
+/*
+Before running this macro it is necessary comment the following line of the method
+AddDigit in the class AliITSsimulationSDD
+//if( fResponse->Do10to8() ) signal = Convert8to10( signal ); 
+In this way the amplitude value for signal coming from SDD takes only 8 bits and not 10.
+*/
+
+void AliITSDDLRawData(char* DigitsFile="galice.root"){
+  #ifdef __NOCOMPILED__
+  if (gClassTable->GetID("AliRun") < 0) {
+    gROOT->LoadMacro("loadlibs.C");
+    loadlibs();
+  }
+  else {
+#endif
+    if(gAlice){
+      delete gAlice;
+      gAlice=0;
+    }
+#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;
+  
+  //SILICON PIXEL DETECTOR
+  cout<<"Formatting data for SPD"<<endl;
+  timer.Start();
+  util->RawDataSPD(ITS,TD);
+  timer.Stop();
+  timer.Print();
+    
+  //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;
+}
diff --git a/ITS/AliITSDDLRawData.cxx b/ITS/AliITSDDLRawData.cxx
new file mode 100644 (file)
index 0000000..a3c429c
--- /dev/null
@@ -0,0 +1,897 @@
+/**************************************************************************
+ * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+#include <stdlib.h>
+#include <iostream.h>
+#include <TClonesArray.h>
+#include <TTree.h>
+#include <AliITS.h>
+#include <AliITSgeom.h>
+#include <AliITSdigit.h>
+#include "AliITSDDLRawData.h"
+
+ClassImp(AliITSDDLRawData)
+
+////////////////////////////////////////////////////////////////////////////////////////
+AliITSDDLRawData::AliITSDDLRawData(){
+  fIndex=-1;
+  fHalfStaveModule=-1;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+AliITSDDLRawData::AliITSDDLRawData(const AliITSDDLRawData &source){
+  // Copy Constructor
+  this->fIndex=source.fIndex;
+  this->fHalfStaveModule=source.fHalfStaveModule;
+  return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+AliITSDDLRawData& AliITSDDLRawData::operator=(const AliITSDDLRawData &source){
+  //Assigment operator
+  this->fIndex=source.fIndex;
+  this->fHalfStaveModule=source.fHalfStaveModule;
+  return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+//STRIP 
+//
+
+void AliITSDDLRawData::GetDigitsSSD(TClonesArray *ITSdigits,Int_t mod, ULong_t *buf){
+  Int_t ix;
+  Int_t iz;
+  Int_t is;
+  ULong_t Word;
+  ULong_t BaseWord;
+  Int_t ndigits = ITSdigits->GetEntries();
+  AliITSdigit *digs;
+  if(ndigits){
+    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;
+      BaseWord=0;
+      Word=is-1;
+      PackWord(BaseWord,Word,0,9);//ADC data
+      Word=ix;
+      PackWord(BaseWord,Word,10,19);//Strip Number
+      Word=iz;      
+      PackWord(BaseWord,Word,20,20);//ADC Channel ID (N or P side)
+      Word=mod;
+      PackWord(BaseWord,Word,21,31);//ADC module ID
+      fIndex++;
+      buf[fIndex]=BaseWord;
+    }//end for
+  }//end if
+  return;
+}//end GetDigitsSSD
+
+////////////////////////////////////////////////////////////////////////////////////////
+//Silicon Drift Detector
+//
+
+void AliITSDDLRawData::GetDigitsSDD(TClonesArray *ITSdigits,Int_t mod, ULong_t *buf){  
+  Int_t ix;
+  Int_t iz;
+  Int_t is;
+  ULong_t Word;
+  ULong_t BaseWord;
+  Int_t ndigits = ITSdigits->GetEntries();
+  AliITSdigit *digs;
+  if(ndigits){
+    //cout<<"Mudule "<<mod<<" number of digits "<<ndigits<<endl;
+    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
+      //      cout<<"Amplitude value:"<<is<<" Time Bucket:"<<ix<<" Anode:"<<iz<<endl;
+      if (is>255){cout<<"WARNING (!) bits words is needed)!!!\n";}
+      BaseWord=0;
+      /*
+      //10 bits words for amplitude value
+      Word=is;
+      PackWord(BaseWord,Word,0,9);//ADC data
+      Word=ix;
+      PackWord(BaseWord,Word,10,17);//Time bucket
+      Word=iz;
+      PackWord(BaseWord,Word,18,26);//Anode Number
+      Word=mod;
+      PackWord(BaseWord,Word,27,31);//Module number
+      */
+      
+      //8bits words for amplitude value
+      Word=is;
+      PackWord(BaseWord,Word,0,7);//ADC data
+      Word=ix;
+      PackWord(BaseWord,Word,8,15);//Time bucket
+      Word=iz;
+      PackWord(BaseWord,Word,16,24);//Anode Number
+      Word=mod;
+      PackWord(BaseWord,Word,25,31);//Module number
+     
+      fIndex++;
+      buf[fIndex]=BaseWord;
+    }//end for
+  }//end if
+  return;
+}//end GetDigitsSDD
+
+////////////////////////////////////////////////////////////////////////////////////////
+//PIXEL 
+//
+
+void AliITSDDLRawData::GetDigitsSPD(TClonesArray *ITSdigits,Int_t mod, ULong_t *buf){
+  Int_t ix;
+  Int_t iz;
+  Int_t ChipNo=0;
+  ULong_t BaseWord=0;
+  ULong_t HitRow=0;
+  Int_t ChipHitCount=0;  //Number of Hit in the current chip
+  Int_t PreviousChip=-1; //Previuos chip respect to the actual aone
+  Int_t ndigits = ITSdigits->GetEntries(); //number of digits in the current module
+  //cout<<"      Number of digits in the current module:"<<ndigits<<" module:"<<mod<<endl;
+  AliITSdigit *digs;
+  fHalfStaveModule++;    //It's a private variable used to distinguish between the firs  
+                         //and the second module of an Half Stave Module
+  if(ndigits){
+    //loop over digits
+    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,
+       *     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;
+      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 
+       //the chip header and the chip trailer are stored
+       for(Int_t i=0;i<(iz/32);i++){
+         if(ChipNo>4)
+           WriteChipHeader(i+5,(mod/2),BaseWord);
+         else
+           WriteChipHeader(i,(mod/2),BaseWord);
+         WriteChipTrailer(buf,ChipHitCount,BaseWord);
+       }//end for
+       PreviousChip=ChipNo;
+       WriteChipHeader(ChipNo,(mod/2),BaseWord);
+       ChipHitCount++;
+       WriteHit(buf,ix,HitRow,BaseWord);
+      }//end if
+      else{
+       ChipHitCount++;
+       if(PreviousChip!=ChipNo){
+         WriteChipTrailer(buf,ChipHitCount-1,BaseWord);
+         for(Int_t i=PreviousChip+1;i<ChipNo;i++){
+           WriteChipHeader(i,(mod/2),BaseWord);
+           WriteChipTrailer(buf,0,BaseWord);
+         }//end for
+         WriteChipHeader(ChipNo,(mod/2),BaseWord);
+         PreviousChip=ChipNo;
+       }//end if
+       WriteHit(buf,ix,HitRow,BaseWord);
+      }//end else
+    }//end for
+    //Even if there aren't digits for a given chip 
+    //the chip header and the chip trailer are stored
+    Int_t End=4;
+    if(ChipNo>4)End+=5;
+    WriteChipTrailer(buf,ChipHitCount,BaseWord);
+    for(Int_t i=ChipNo+1;i<=End;i++){
+      WriteChipHeader(i,(mod/2),BaseWord);
+      WriteChipTrailer(buf,0,BaseWord);
+    }//end for
+  }//end if
+  else{
+    //In this module there aren't digits but
+    //the chip header and chip trailer are store anyway
+    if(fHalfStaveModule){
+      ChipNo=5;
+      fHalfStaveModule=-1;
+    }//end if
+    for(Int_t i=0;i<5;i++){
+      WriteChipHeader(ChipNo+i,(mod/2),BaseWord);
+      WriteChipTrailer(buf,ChipHitCount,BaseWord);
+    }//end for
+  }//end else 
+  return;
+}//end GetDigitsSPD
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void AliITSDDLRawData::PackWord(ULong_t &BaseWord, ULong_t Word, Int_t StartBit, Int_t StopBit){
+  ULong_t DummyWord,OffSet;
+  Int_t   Length;
+  ULong_t Sum;
+  //The BaseWord is being filled with 1 from StartBit to StopBit
+  Length=StopBit-StartBit+1;
+  Sum=(ULong_t)pow(2,Length)-1;
+  if(Word > Sum){
+    cout<<"WARNING::Word to be filled is not within desired length"<<endl;
+    cout<<"Word:"<<Word<<" Start bit:"<<StartBit<<" Stop Bit:"<<StopBit<<endl;
+    exit(-1);
+  }
+  OffSet=Sum;
+  OffSet<<=StartBit;
+  BaseWord=BaseWord|OffSet;
+  //The Word to be filled is shifted to the position StartBit
+  //and the remaining  Left and Right bits are filled with 1
+  Sum=(ULong_t)pow(2,StartBit)-1;
+  DummyWord=0xFFFFFFFF<<Length;
+  DummyWord +=Word;
+  DummyWord<<=StartBit;
+  DummyWord+=Sum;
+  BaseWord=BaseWord&DummyWord;
+  return;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void AliITSDDLRawData::UnpackWord(ULong_t PackedWord, Int_t StartBit, Int_t StopBit, ULong_t &Word){   
+  ULong_t OffSet;
+  Int_t Length;
+  Length=StopBit-StartBit+1;
+  OffSet=(ULong_t)pow(2,Length)-1;
+  OffSet<<=StartBit;
+  Word=PackedWord&OffSet;
+  Word>>=StartBit;
+  return;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Int_t AliITSDDLRawData::RawDataSPD(AliITS *ITS,TTree *TD ,Int_t LDCsNumber){
+
+  //Silicon Pixel Detector
+  const Int_t DDLNumber=20;       // Number of DDL in SPD
+  const Int_t ModulePerDDL=12;    // Number of modules in each DDL 
+  //Row    ==> DDLs
+  //Column ==> Modules
+  Int_t SPDMap[DDLNumber][ModulePerDDL]={{ 0, 1, 4, 5, 80, 81, 84, 85, 88, 89, 92, 93},
+                                        { 2, 3, 6, 7, 82, 83, 86, 87, 90, 91, 94, 95},
+                                        { 8, 9,12,13, 96, 97,100,101,104,105,108,109},
+                                        {10,11,14,15, 98, 99,102,103,106,107,110,111},
+                                        {16,17,20,21,112,113,116,117,120,121,124,125},
+                                        {18,19,22,23,114,115,118,119,122,123,126,127},
+                                        {24,25,28,29,128,129,132,133,136,137,140,141},
+                                        {26,27,30,31,130,131,134,135,138,139,142,143},
+                                        {32,33,36,37,144,145,148,149,152,153,156,157},
+                                        {34,35,38,39,146,147,150,151,154,155,158,159},
+                                        {40,41,44,45,160,161,164,165,168,169,172,173},
+                                        {42,43,46,47,162,163,166,167,170,171,174,175},
+                                        {48,47,50,51,176,177,180,181,184,185,188,189},
+                                        {50,51,54,55,178,179,182,183,186,187,190,191},
+                                        {56,57,60,61,192,193,196,197,200,201,204,205},
+                                        {58,59,62,63,194,195,198,199,202,203,206,207},
+                                        {64,65,68,69,208,209,212,213,216,217,220,221},
+                                        {66,67,70,71,210,211,214,215,218,219,222,223},
+                                        {72,73,76,77,224,225,228,229,232,233,236,237},
+                                        {74,75,78,79,226,227,230,231,234,235,238,239}};
+  Int_t DDLPerFile=DDLNumber/LDCsNumber;
+  if(DDLNumber%LDCsNumber)DDLPerFile++;
+  cout<<"Number of DDL per File: "<<DDLPerFile<<endl;
+  Int_t subd=0;
+  Int_t CountDDL=0;
+  Int_t SliceNumber=1;
+  const Int_t size=21000; //256*32*5=40960 max number of digits per module
+  ULong_t buf[size];      //One buffer cell can contain 2 digits 
+  fIndex=-1;
+  TClonesArray *ITSdigits  = ITS->DigitsAddress(subd);
+
+  Int_t nbytes = 0; 
+  char fileName[15];
+
+  ULong_t MiniHeaderPosition=0; //variable used to store the position of the Mini Header inside a file
+  ofstream outfile;         // logical name of the output file 
+  Int_t Flag=0;             // 0==> Uncompressed data 1==>Compressed Data
+  Int_t Detector=1;         // 1==>ITS (Pixel) 2==>ITS (Drift) 3==>ITS (Strip) 0==>TPC ......
+  ULong_t Size=0;           // Size of the data block that follows the mini header
+  Int_t MagicWord=0x123456;  // Magic word used to distinguish between data and garbage
+  sprintf(fileName,"SPDslice%d",SliceNumber); //The name of  the output file. There are as many slides as the number of LDC
+  outfile.open(fileName,ios::binary);
+  ULong_t MiniHeader[3];
+  Int_t MiniHeaderSize=sizeof(ULong_t)*3;
+  Int_t Version=1;          //Version of the mini header 
+  //loop over DDLs
+  for(Int_t i=0;i<DDLNumber;i++){
+    CountDDL++;
+    //write Dummy MINI HEADER
+    MiniHeader[0]=Size;
+    PackWord(MiniHeader[1],MagicWord,8,31);
+    PackWord(MiniHeader[1],Detector,0,7);
+    PackWord(MiniHeader[2],i,16,31);
+    PackWord(MiniHeader[2],Flag,8,15);
+    PackWord(MiniHeader[2],Version,0,7);
+    MiniHeaderPosition=outfile.tellp();
+    outfile.write((char*)(MiniHeader),MiniHeaderSize);
+    //Loops over Modules of a particular DDL
+    for (Int_t mod=0; mod<ModulePerDDL; mod++){
+      ITS->ResetDigits();
+      nbytes += TD->GetEvent(SPDMap[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(ITSdigits,SPDMap[i][mod],buf);
+      outfile.write((char *)buf,((fIndex+1)*sizeof(ULong_t)));
+      for(Int_t i=0;i<(fIndex+1);i++){
+       buf[i]=0;
+      }//end for
+      fIndex=-1;
+    }//end for
+    
+    //Write REAL MINI HEADER
+    ULong_t CurrentFilePosition=outfile.tellp();
+    outfile.seekp(MiniHeaderPosition);
+    Size=CurrentFilePosition-MiniHeaderPosition-MiniHeaderSize;
+    
+    outfile.write((char*)(&Size),sizeof(ULong_t));
+    outfile.seekp(CurrentFilePosition);
+    if(CountDDL==DDLPerFile){
+      outfile.close();
+      SliceNumber++;
+      sprintf(fileName,"SPDslice%d",SliceNumber); 
+      if(i!=(DDLNumber-1))
+       outfile.open(fileName,ios::binary);
+      CountDDL=0;
+    }//end if
+  }//end for
+  outfile.close();
+  return 0;  
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Int_t AliITSDDLRawData::RawDataSSD(AliITS *ITS,TTree *TD ,Int_t LDCsNumber){
+  //Strip detector
+  const Int_t DDLNumber=16;        // Number of DDL in SSD
+  const Int_t ModulePerDDL=109;    // Number of modules in each DDL 
+  //DDL from 32 to 47 (16 DDL)
+  //Row    ==> DDLs
+  //Column ==> Modules
+  Int_t SSDMap[DDLNumber][ModulePerDDL]={
+    //104
+    //DDL[32][]=
+    { 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510,
+      522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532,
+      1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,
+      1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,
+      1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,
+      2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108,2109,
+      2123,2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,
+      2148,2149,2150,2151,2152,2153,2154,2155,2156,2157,2158,2159,
+      2173,2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,2184,-1,-1,-1,-1,-1},    
+    //93
+    //DDL[33][]=
+    { 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576,
+      588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598,
+      610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620,
+      1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,
+      1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,
+      1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,
+      1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,
+      1373,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,
+      -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,-1,-1,-1,-1},
+    //103
+    //DDL[34][]=
+    { 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642,
+      654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664,
+      676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686,
+      698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708,
+      720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730,
+      1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,
+      1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,
+      1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,
+      1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,-1,-1,-1,-1,-1,-1},
+    //104
+    //DDL[35][]=
+    { 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752,
+      764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774,
+      786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796,
+      808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818,
+      1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,
+      1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,
+      1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,
+      1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,
+      1598,1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,-1,-1,-1,-1,-1},
+    //104
+    //DDL[36[]=
+    { 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840,
+      852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862,
+      874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884,
+      896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906,
+      1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,
+      1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,
+      1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1682,1684,
+      1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,
+      1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,-1,-1,-1,-1,-1},
+    //104
+    //DDL[37][]=
+    { 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928,
+      940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950,
+      962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972,
+      984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994,
+      1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,
+      1773,1774,1775,1776,1777,1778,1779,1780,1781,1782,1783,1784,
+      1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,1809,
+      1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,
+      1848,1849,1850,1851,1852,1853,1854,1855,1856,1857,1858,1859,-1,-1,-1,-1,-1},
+    //103
+    //DDL[38][]=
+    {1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,
+     1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,
+     1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,
+     1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,
+     1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,
+     1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,
+     1898,1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,
+     1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,
+     1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,-1,-1,-1,-1,-1,-1},
+    //104
+    //DDL[39][]=
+    {1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,
+     1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,
+     1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,
+     1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,
+     1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,
+     1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,
+     2023,2024,2025,2026,2027,2028,2029,2030,2031,2032,2033,2034,
+     2048,2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,
+     2073,2074,2075,2076,2077,2078,2079,2080,2081,2082,2083,2084,-1,-1,-1,-1,-1},
+    //109
+    //DDL[40][]=
+    { 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521,
+      533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543,
+      1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,
+      1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,
+      1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,
+      2110,2111,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,
+      2135,2136,2137,2138,2139,2140,2141,2142,2143,2144,2145,2146,2147,
+      2160,2161,2162,2163,2164,2165,2166,2167,2168,2169,2170,2171,2172,
+      2185,2186,2187,2188,2189,2190,2191,2192,2193,2194,2195,2196,2197},
+    //109
+    //DDL[41][]=
+    { 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565,
+      577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587,
+      599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609,
+      621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631,
+      1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,
+      1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,
+      1335,1336,1337,1338,1339,1340,1341,1342,1443,1344,1345,1346,1347,
+      1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,
+      1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397},
+    //107
+    //DDL[42][]=
+    { 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653,
+      665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675,
+      687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697,
+      709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719,
+      731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741,
+      1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,
+      1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,
+      1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,
+      1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,-1,-1},
+    //109
+    //DDL[43][]=
+    { 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763,
+      775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785,
+      797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807,
+      819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829,
+      1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,
+      1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,
+      1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,
+      1585,1586,1587,1588,1589,1590,1591,1592,1593,1584,1595,1596,1597,
+      1610,1611,1612,1613,1614,1615,1616,1617,1618,1619,1620,1621,1622},
+    //109
+    //DDL[44][]=
+    { 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851,
+      863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873,
+      885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895,
+      907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917,
+      1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647,
+      1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,
+      1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,
+      1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,1722,
+      1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747},
+    //109
+    //DDL[45][]=
+    {929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939,
+     951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961,
+     973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983,
+     995, 996, 997, 998, 999,1000,1001,1002,1003,1004,1005,
+     1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1770,1771,1772,
+     1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796,1797,
+     1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,
+     1835,1836,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847,
+     1860,1861,1862,1863,1864,1865,1866,1867,1868,1869,1870,1871,1872},
+    //109
+    //DDL[46][]=
+    {1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,
+     1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,
+     1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,
+     1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,
+     1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,
+     1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,
+     1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,
+     1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,
+     1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972},
+    //109
+    //DDL[47][]=
+    {1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,
+     1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,
+     1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,
+     1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,
+     1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,
+     2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,
+     2035,2036,2037,2038,2039,2040,2041,2042,2043,2044,2045,2046,2047,
+     2060,2061,2062,2063,2064,2065,2066,2067,2068,2069,2070,2071,2072,
+     2085,2086,2087,2088,2089,2090,2091,2092,2093,2094,2095,2096,2097} };
+
+
+  Int_t DDLPerFile=DDLNumber/LDCsNumber;
+  if(20%LDCsNumber)DDLPerFile++;
+  cout<<"Number of DDL per File: "<<DDLPerFile<<endl;
+  Int_t subd=2;          //SSD
+  Int_t CountDDL=0;
+  Int_t SliceNumber=1;
+  const Int_t size=1536;//768*2 Number of stripe * number of sides(N and P)
+  ULong_t buf[size];      
+  fIndex=-1;
+  Int_t nbytes = 0; 
+  TClonesArray *ITSdigits  = ITS->DigitsAddress(subd);
+  char fileName[15];
+
+  ULong_t MiniHeaderPosition=0; //variable used to store the position of the Mini Header inside the file
+  ofstream outfile;             // logical name of the output file 
+  Int_t Flag=0;                 // 0==> Uncompressed data 1==>Compressed Data
+  Int_t Detector=3;             // 1==>ITS (Pixel) 2==>ITS (Drift) 3==>ITS (Strip) 0==>TPC ......
+  ULong_t Size=0;               // Size of the data block that follows the mini header
+  Int_t MagicWord=0x123456;     // Magic word used to distinguish between data and garbage
+  sprintf(fileName,"SSDslice%d",SliceNumber); //The name of  the output file. There are as many slides as the number of LDC
+  outfile.open(fileName,ios::binary);
+  ULong_t MiniHeader[3];
+  Int_t MiniHeaderSize=sizeof(ULong_t)*3;
+  Int_t Version=1;              //Version of the mini header 
+  //loop over DDLs
+  
+  for(Int_t i=0;i<DDLNumber;i++){
+    CountDDL++;
+    //write Dummy MINI HEADER
+    MiniHeader[0]=Size;
+    PackWord(MiniHeader[1],MagicWord,8,31);
+    PackWord(MiniHeader[1],Detector,0,7);
+    PackWord(MiniHeader[2],i,16,31);
+    PackWord(MiniHeader[2],Flag,8,15);
+    PackWord(MiniHeader[2],Version,0,7);
+    MiniHeaderPosition=outfile.tellp();
+    outfile.write((char*)(MiniHeader),MiniHeaderSize);
+    
+    //Loops over Modules of a particular DDL
+    for (Int_t mod=0; mod<ModulePerDDL; mod++){
+      if(SSDMap[i][mod]!=-1){
+       ITS->ResetDigits();
+       nbytes += TD->GetEvent(SSDMap[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(ITSdigits,mod,buf);
+       outfile.write((char *)buf,((fIndex+1)*sizeof(ULong_t)));
+       for(Int_t i=0;i<(fIndex+1);i++){
+         buf[i]=0;
+       }//end for
+       fIndex=-1;
+      }//end if
+    }//end for
+    //Write REAL MINI HEADER
+    ULong_t CurrentFilePosition=outfile.tellp();
+    outfile.seekp(MiniHeaderPosition);
+    Size=CurrentFilePosition-MiniHeaderPosition-MiniHeaderSize;
+    
+    outfile.write((char*)(&Size),sizeof(ULong_t));
+    outfile.seekp(CurrentFilePosition);
+    if(CountDDL==DDLPerFile){
+      outfile.close();
+      SliceNumber++;
+      sprintf(fileName,"SSDslice%d",SliceNumber); 
+      if(i!=(DDLNumber-1))
+       outfile.open(fileName,ios::binary);
+      CountDDL=0;
+    }//end if
+  }//end for
+  outfile.close();
+  return 0;  
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Int_t AliITSDDLRawData::RawDataSDD(AliITS *ITS,TTree *TD ,Int_t LDCsNumber){
+  //Silicon Drift Detector
+  const Int_t DDLNumber=12;       // Number of DDL in SPD
+  const Int_t ModulePerDDL=22;    // Number of modules in each DDL 
+  //Row    ==> DDLs
+  //Column ==> Modules  
+  Int_t SDDMap[DDLNumber][ModulePerDDL]= {{240,241,242,246,247,248,252,253,254,258,259,260,264,265,266,270,271,272,276,277,278,-1},
+                                         {243,244,245,249,250,251,255,256,257,261,262,263,267,268,269,273,274,275,279,280,281,-1},
+                                         {282,283,284,288,289,290,294,295,296,300,301,302,306,307,308,312,313,314,318,319,320,-1},
+                                         {285,286,287,291,292,293,297,298,299,303,304,305,309,310,311,315,316,317,321,322,323,-1},
+                                         {324,325,326,327,332,333,334,335,340,341,342,343,348,349,350,351,356,357,358,359,364,365},
+                                         {328,329,330,331,336,337,338,339,344,345,346,347,352,353,354,355,360,361,362,363,368,369},
+                                         {366,367,372,373,374,375,380,381,382,383,388,389,390,391,396,397,398,399,404,405,406,407},
+                                         {370,371,376,377,378,379,384,385,386,387,392,393,394,395,400,401,402,403,408,409,410,411},
+                                         {412,413,414,415,420,421,422,423,428,429,430,431,436,436,438,439,444,445,446,447,452,453},
+                                         {416,417,418,419,424,425,426,427,432,433,434,435,440,441,442,443,448,449,450,451,456,457},
+                                         {454,455,460,461,462,463,468,469,470,471,476,477,478,479,484,485,486,487,492,493,494,495},
+                                         {458,459,464,465,466,467,472,473,474,475,480,481,482,483,488,489,490,491,496,497,498,499}};
+  
+  Int_t DDLPerFile=DDLNumber/LDCsNumber;
+  if(DDLNumber%LDCsNumber)DDLPerFile++;
+  cout<<"Number of DDL per File: "<<DDLPerFile<<endl;
+  Int_t subd=1;
+  Int_t CountDDL=0;
+  Int_t SliceNumber=1;
+  const Int_t size=131072; //256*512
+  ULong_t buf[size];      
+  fIndex=-1;
+  Int_t nbytes = 0; 
+  TClonesArray *ITSdigits  = ITS->DigitsAddress(subd);
+  char fileName[15];
+
+  ULong_t MiniHeaderPosition=0; // variable used to store the position of the Mini Header inside a file
+  ofstream outfile;             // logical name of the output file 
+  Int_t Flag=0;                 // 0==> Uncompressed data 1==>Compressed Data
+  Int_t Detector=2;             // 1==>ITS (Pixel) 2==>ITS (Drift) 3==>ITS (Strip) 0==>TPC ......
+  ULong_t Size=0;               // Size of the data block that follows the mini header
+  Int_t MagicWord=0x123456;     // Magic word used to distinguish between data and garbage
+  sprintf(fileName,"SDDslice%d",SliceNumber); //The name of  the output file. There are as many slides as the number of LDC
+  outfile.open(fileName,ios::binary);
+  ULong_t MiniHeader[3];
+  Int_t MiniHeaderSize=sizeof(ULong_t)*3;
+  Int_t Version=1;             //Version of the mini header 
+  //loop over DDLs
+  for(Int_t i=0;i<DDLNumber;i++){
+    CountDDL++;
+    //write Dummy MINI HEADER
+    MiniHeader[0]=Size;
+    PackWord(MiniHeader[1],MagicWord,8,31);
+    PackWord(MiniHeader[1],Detector,0,7);
+    PackWord(MiniHeader[2],i,16,31);
+    PackWord(MiniHeader[2],Flag,8,15);
+    PackWord(MiniHeader[2],Version,0,7);
+    MiniHeaderPosition=outfile.tellp();
+    outfile.write((char*)(MiniHeader),MiniHeaderSize);
+    //Loops over Modules of a particular DDL
+    for (Int_t mod=0; mod<ModulePerDDL; mod++){
+      if(SDDMap[i][mod]!=-1){
+       ITS->ResetDigits();
+       nbytes += TD->GetEvent(SDDMap[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
+       //      cout<<"MODULE NUMBER:"<<SDDMap[i][mod]<<endl;
+       GetDigitsSDD(ITSdigits,mod,buf);
+       outfile.write((char *)buf,((fIndex+1)*sizeof(ULong_t)));
+       for(Int_t i=0;i<(fIndex+1);i++){
+         buf[i]=0;
+       }//end for
+       fIndex=-1;
+      }//end if
+    }//end for
+    
+    //Write REAL MINI HEADER
+    ULong_t CurrentFilePosition=outfile.tellp();
+    outfile.seekp(MiniHeaderPosition);
+    Size=CurrentFilePosition-MiniHeaderPosition-MiniHeaderSize;
+    
+    outfile.write((char*)(&Size),sizeof(ULong_t));
+    outfile.seekp(CurrentFilePosition);
+    if(CountDDL==DDLPerFile){
+      outfile.close();
+      SliceNumber++;
+      sprintf(fileName,"SDDslice%d",SliceNumber); 
+      if(i!=(DDLNumber-1))
+       outfile.open(fileName,ios::binary);
+      CountDDL=0;
+    }//end if
+  }//end for
+  outfile.close();
+  return 0;  
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void AliITSDDLRawData::WriteChipHeader(Int_t ChipAddr,Int_t EventCnt,ULong_t &BaseWord){
+  //cout<<"Chip: "<<ChipAddr<<" Half Stave module:"<<EventCnt<<endl;
+  BaseWord=0;
+  PackWord(BaseWord,ChipAddr,0,3);
+  PackWord(BaseWord,EventCnt,4,10);
+  PackWord(BaseWord,0x7,11,13);
+  PackWord(BaseWord,0x1,14,15);
+  return;
+}//end WriteChipHeader
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void AliITSDDLRawData::ReadChipHeader(Int_t &ChipAddr,Int_t &EventCnt,ULong_t BaseWord){
+  ULong_t temp=0;
+  UnpackWord(BaseWord,0,3,temp);
+  ChipAddr=(Int_t)temp;
+  UnpackWord(BaseWord,4,10,temp);
+  EventCnt=(Int_t)temp;
+  cout<<"Chip: "<<ChipAddr<<" Half Stave module:"<<EventCnt<<endl;
+  return;
+}//end ReadChipHeader
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void  AliITSDDLRawData::WriteChipTrailer(ULong_t *buf,Int_t ChipHitCount,ULong_t &BaseWord){
+  //pixel fill word
+  if((ChipHitCount%2)!=0){
+    PackWord(BaseWord,0xFECD,0,15);
+  }
+  PackWord(BaseWord,ChipHitCount,16,28);
+  PackWord(BaseWord,0x0,30,31);
+  fIndex++;
+  buf[fIndex]=BaseWord;
+  BaseWord=0;
+  return;
+}//end WriteChipTrailer
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void  AliITSDDLRawData::ReadChipTrailer(Int_t &ChipHitCount,ULong_t BaseWord){
+  ULong_t temp=0;
+  UnpackWord(BaseWord,16,28,temp);
+  ChipHitCount=(Int_t)temp;
+  return;
+}//end ReadChipTrailer
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void  AliITSDDLRawData::WriteHit(ULong_t *buf,Int_t RowAddr,Int_t HitAddr,ULong_t &BaseWord){
+  if(!BaseWord){
+    PackWord(BaseWord,HitAddr,0,4);
+    PackWord(BaseWord,RowAddr,5,12);
+    PackWord(BaseWord,2,14,15);
+  }//end if
+  else{
+    PackWord(BaseWord,HitAddr,16,20);
+    PackWord(BaseWord,RowAddr,21,28);
+    PackWord(BaseWord,2,30,31);
+    fIndex++;
+    buf[fIndex]=BaseWord;
+    BaseWord=0;
+  }//end else
+  return;
+}//end WriteHit
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void AliITSDDLRawData::TestFormat(){
+  ifstream f;
+  Int_t  LDCsNumber=2;
+  ofstream ftxt("File2.txt");
+  ULong_t Size=0;
+  char filename[15];
+  ULong_t DDLNumber=0;
+  ULong_t MiniHeader[3];
+  Int_t MiniHeaderSize=sizeof(ULong_t)*3;
+  for(Int_t i=1;i<=LDCsNumber;i++){
+    sprintf(filename,"SPDslice%d",i);  
+    f.open(filename,ios::binary|ios::in);
+    if(!f){exit(1);}
+    //loop over the DDL block 
+    //here the Mini Header is read
+    while( f.read((char*)(MiniHeader),MiniHeaderSize)){
+      //cout<<"Block Size: "<<Size<<endl;
+      Size=MiniHeader[0];
+      UnpackWord(MiniHeader[2],16,31,DDLNumber);
+      ftxt<<"DDL NUMBER:"<<DDLNumber<<endl;
+      ULong_t Word=0;
+      ULong_t Code=0;
+      ULong_t Decoded1,Decoded2=0;
+      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
+      }//end for
+    }//end while
+    f.close();
+  }//end for
+  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;
+}
diff --git a/ITS/AliITSDDLRawData.h b/ITS/AliITSDDLRawData.h
new file mode 100644 (file)
index 0000000..baeabb6
--- /dev/null
@@ -0,0 +1,55 @@
+/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Class used for generating the files containung data, required by the Data Challenge //
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef AliITSDDLRAWDATA_H
+#define AliITSDDLRAWDATA_H
+
+class AliITS;
+class TTree;
+
+class AliITSDDLRawData:public TObject{
+ public:
+  AliITSDDLRawData();//default constructor
+  virtual ~AliITSDDLRawData(){;}//destructor
+  AliITSDDLRawData(const AliITSDDLRawData &source); // copy constructor
+  AliITSDDLRawData& operator=(const AliITSDDLRawData &source); // ass. op.
+  // This method generates the files with the Silicon pixel detector data
+  Int_t RawDataSPD(AliITS *ITS,TTree *TD ,Int_t LDCsNumber=2);
+  // This method generates the files with the Silicon drift detector data
+  Int_t RawDataSDD(AliITS *ITS,TTree *TD ,Int_t LDCsNumber=4);
+  // This method generates the files with the Silicon pixel detector data
+  Int_t RawDataSSD(AliITS *ITS,TTree *TD ,Int_t LDCsNumber=2);
+  //A debugging method used to test the files generated for the SPD.
+  void  TestFormat();
+ private: 
+  //This method formats and stores in buf all the digits of a SPD module
+  void  GetDigitsSPD(TClonesArray *ITSdigits, Int_t mod, ULong_t *buf);
+  //This method formats and stores in buf all the digits of a SDD module
+  void  GetDigitsSDD(TClonesArray *ITSdigits, Int_t mod, ULong_t *buf);
+  //This method formats and stores in buf all the digits of a SSD module
+  void  GetDigitsSSD(TClonesArray *ITSdigits, Int_t mod, ULong_t *buf);
+  //This method stores the value of the variable Word of StopBit-StartBit+1 bits 
+  //in BaseWord, starting from the bit StartBit
+  void  PackWord(ULong_t &BaseWord, ULong_t Word, Int_t StartBit, Int_t StopBit);
+  //This method extracts a group of adiacents bits, specified by StartBit and StopBit, 
+  //from the word PackedWord. The resulting word is saved in the Word variable
+  void  UnpackWord(ULong_t PackedWord, Int_t StartBit, Int_t StopBit, ULong_t &Word);
+  //The following three methods are used to store the data according to the 
+  //Silicon pixel detector data format
+  void  WriteChipHeader(Int_t ChipAddr,Int_t EventCnt,ULong_t &BaseWord);
+  void  WriteChipTrailer(ULong_t *buf,Int_t ChipHitCount,ULong_t &BaseWord);
+  void  WriteHit(ULong_t *buf,Int_t RowAddr,Int_t HitAddr,ULong_t &BaseWord);
+  //Methods used for reading and dubugging SPD data files
+  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);
+  Int_t fIndex;
+  Int_t fHalfStaveModule;
+  ClassDef(AliITSDDLRawData,1)
+};
+    
+#endif
index b51cac1..fca6f0f 100644 (file)
 #pragma link C++ class AliITSDigitizer+;
 #pragma link C++ class AliITSFDigitizer+;
 #pragma link C++ class AliITSFindClustersV2+;
+// Raw data
+#pragma link C++ class AliITSDDLRawData+;
 #endif
index a256914..d52940b 100644 (file)
@@ -39,7 +39,7 @@ SRCS          = AliITS.cxx AliITSv1.cxx AliITSv5.cxx AliITSvSPD02.cxx \
                AliITSreconstruction.cxx \
                AliITSFindClustersV2.cxx \
                AliITSRiemannFit.cxx \
-               AliITSFDigitizer.cxx
+               AliITSFDigitizer.cxx AliITSDDLRawData.cxx
 #              AliITSAlignmentTrack.cxx AliITSAlignmentModule.cxx \
 
 HDRS:=  $(SRCS:.cxx=.h)
diff --git a/TPC/AliTPCAltro.C b/TPC/AliTPCAltro.C
new file mode 100644 (file)
index 0000000..4f3c6bd
--- /dev/null
@@ -0,0 +1,110 @@
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include <fstream.h>
+#include "AliTPCBuffer160.h"
+#include <alles.h>
+#endif
+
+int AliTPCAltro(char* FileName,Int_t eth=0){
+  //eth is a threshold.
+  //Digits stored into a file have an amplitude value greater than eth
+  Int_t offset=1; //this should be equal to the threshold
+  /*
+    NB the amplitude values strored in the ALTRO file are shifted  by offset 
+    because the range for each word goes from 0 to 1023, now due to zero suppression 
+    values lower that the threshold never appear.
+   */
+  TFile *cf=TFile::Open(FileName);
+  // old geometry (3.07)
+  //AliTPCParamSR *param =(AliTPCParamSR *)cf->Get("75x40_100x60");
+  // if new geometry comment out the line above and uncomment the one below
+  AliTPCParamSR *param =(AliTPCParamSR *)cf->Get("75x40_100x60_150x60");
+  AliTPCDigitsArray *digarr=new AliTPCDigitsArray;
+  digarr->Setup(param);
+  
+  char  cname[100];
+  //old geometry
+  //sprintf(cname,"TreeD_75x40_100x60_%d",eventn);
+  // if new geometry comment out the line above and uncomment the one below
+  Int_t eventn=0;
+  sprintf(cname,"TreeD_75x40_100x60_150x60_%d",eventn);
+  digarr->ConnectTree(cname);
+
+  Int_t PSecNumber=-1;  //Previous Sector number
+  Int_t PRowNumber=-1;  //Previous Row number  
+  Int_t PPadNumber=-1;  //Previous Pad number
+  Int_t PTimeBin=-1;    //Previous Time-Bin
+  Int_t BunchLength=0;
+
+  //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
+  AliTPCBuffer160 Buffer("AltroFormat.dat",1); 
+  //number of entries in the tree
+  Int_t nrows=Int_t(digarr->GetTree()->GetEntries());
+  cout<<"Number of entries "<<nrows<<endl;
+  ULong_t Count=0;
+  Int_t nwords=0;
+  Int_t numPackets=0;
+  //ofstream ftxt("Data.txt");
+  for (Int_t n=0; n<nrows; n++) {
+    AliSimDigits *digrow=(AliSimDigits*)digarr->LoadEntry(n);
+    Int_t sec,row; // sector and row number (in the TPC)
+    param->AdjustSectorRow(digrow->GetID(),sec,row);   
+    //cout<<"Sector:"<<sec<<" Row:"<<row<<endl;
+    digrow->First();
+    do{
+      Short_t dig=digrow->CurrentDigit(); //adc
+      Int_t time=digrow->CurrentRow(); //time
+      Int_t pad =digrow->CurrentColumn(); // pad 
+      if(dig>eth){
+       Count++;
+       //ftxt<<"Sec: "<<sec<<" Row: "<<row<<" Pad:"<<pad<<" Time: "<<time<<" ADC:"<<dig<<endl;
+       //cout<<"Sec: "<<sec<<" Row: "<<row<<" Pad:"<<pad<<" Time: "<<time<<" ADC:"<<dig<<endl;
+       if (PPadNumber==-1){
+         PSecNumber=sec;
+         PRowNumber=row;
+         PPadNumber=pad;
+         // PAmplitude=dig;
+         PTimeBin=time;
+         BunchLength=1;
+         Buffer.FillBuffer(dig-offset);
+         nwords++;
+       }//end if
+       else{
+         if ( (time==(PTimeBin+1)) &&
+              (PPadNumber==pad) &&
+              (PRowNumber==row) &&
+              (PSecNumber==sec)){
+           BunchLength++;
+         }//end if
+         else{
+           Buffer.FillBuffer(PTimeBin);
+           Buffer.FillBuffer(BunchLength+2);
+           nwords+=2;
+           if ((PPadNumber!=pad)||(PRowNumber!=row)||(PSecNumber!=sec)){
+             //Trailer is formatted and inserted!!
+             Buffer.WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
+             numPackets++;
+             nwords=0;
+           }//end if
+           
+           BunchLength=1;
+           PPadNumber=pad;
+           PRowNumber=row;
+           PSecNumber=sec;
+         }//end else
+         PTimeBin=time;
+         Buffer.FillBuffer(dig-offset);
+         nwords++;
+       }//end else
+      }//end if
+    } while (digrow->Next());
+  }//end for
+  Buffer.FillBuffer(PTimeBin);
+  Buffer.FillBuffer(BunchLength+2);
+  nwords+=2;
+  Buffer.WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
+  numPackets++;
+  cout<<"There are "<<Count<<" Digits\n";
+  cout<<"Packets "<<numPackets<<"\n";
+  //ftxt.close();
+  return 0;
+}//end macro
diff --git a/TPC/AliTPCBuffer.cxx b/TPC/AliTPCBuffer.cxx
new file mode 100644 (file)
index 0000000..43525a3
--- /dev/null
@@ -0,0 +1,147 @@
+/**************************************************************************
+ * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+#include "Riostream.h"
+#include "TObjArray.h"
+#include "AliTPCBuffer.h"
+#include "AliSimDigits.h"
+
+//#include "TFile.h"
+//#include "TTree.h"
+
+ClassImp(AliTPCBuffer)
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+AliTPCBuffer::AliTPCBuffer(const char* fileName){
+  f.open("AliTPCDDL.dat",ios::binary|ios::out);
+  // fout=new TFile(fileName,"recreate");
+  // tree=new TTree("tree","Values");
+  NumberOfDigits=0;
+  fVerbose=0;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+AliTPCBuffer::~AliTPCBuffer(){
+  f.close();
+  //delete tree;
+  //delete fout;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+AliTPCBuffer::AliTPCBuffer(const AliTPCBuffer &source){
+  // Copy Constructor
+  return;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+AliTPCBuffer& AliTPCBuffer::operator=(const AliTPCBuffer &source){
+  //Assigment operator
+  return *this;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/*
+void AliTPCBuffer::WriteRow(Int_t eth,AliSimDigits *digrow,Int_t minPad,Int_t maxPad,Int_t flag,Int_t sec,Int_t SubSec,Int_t row){
+  //flag=0 the whole row is written to the root file
+  //flag=1 only value in the range [minPad,MaxPasd] are written to the root file
+  //flag=2 complementary case of 1
+  Int_t Pad;
+  Int_t Dig;
+  Int_t Time;
+  tree->Branch("sec",&sec,"sec/I");
+  tree->Branch("SubSec",&SubSec,"SubSec/I");
+  tree->Branch("row",&row,"row/I");
+  tree->Branch("Pad",&Pad,"Pad/I");
+  tree->Branch("Dig",&Dig,"Dig/I");
+  tree->Branch("Time",&Time,"Time/I");
+  digrow->First();
+  do{
+    Dig=digrow->CurrentDigit(); //adc
+    Time=digrow->CurrentRow(); //time
+    Pad =digrow->CurrentColumn(); // pad 
+    //    cout<<"Sec "<<sec<<" row "<<row<<" Pad "<<Pad<<" Dig "<<Dig<<" Time "<<Time<<endl; 
+    if(Dig>eth){
+      switch (flag){
+      case 0:{
+       tree->Fill();
+       NumberOfDigits++;
+       break;
+      }//end case 0
+      case 1:{
+         if((Pad>=minPad)&&(Pad<=maxPad)){
+           tree->Fill();
+           NumberOfDigits++;
+         }
+       break;
+      }//end case 1
+      case 2:{
+       if((Pad<minPad)||(Pad>maxPad)){
+         tree->Fill();
+         NumberOfDigits++;
+       }
+       break;
+      }//end case 2
+      };//end switch
+    }//end if
+  }while (digrow->Next());
+  tree->Write();
+  return;
+}
+*/
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void AliTPCBuffer::WriteRowBinary(Int_t eth,AliSimDigits *digrow,Int_t minPad,Int_t maxPad,Int_t flag,Int_t sec,Int_t SubSec,Int_t row){
+  //flag=0 the whole row is written intto the file
+  //flag=1 only value in the range [minPad,MaxPasd] are written into the file
+  //flag=2 complementary case of 1
+  struct DataPad{
+    Int_t Sec;
+    Int_t SubSec;
+    Int_t Row;
+    Int_t Pad;
+    Int_t Dig;
+    Int_t Time;
+  };
+  DataPad data;
+  data.Sec=sec;
+  data.SubSec=SubSec;
+  data.Row=row;
+  digrow->First();
+  do{
+    data.Dig=digrow->CurrentDigit(); //adc
+    data.Time=digrow->CurrentRow(); //time
+    data.Pad =digrow->CurrentColumn(); // pad 
+    if(data.Dig>eth){
+      switch (flag){
+      case 0:{
+       NumberOfDigits++;
+       f.write((char*)(&data),sizeof(data));
+       break;
+      }//end case 0
+      case 1:{
+       if((data.Pad>=minPad)&&(data.Pad<=maxPad)){
+         f.write((char*)(&data),sizeof(data));
+         NumberOfDigits++;
+       }
+       break;
+      }//end case 1
+      case 2:{
+       if((data.Pad<minPad)||(data.Pad>maxPad)){
+         f.write((char*)(&data),sizeof(data));
+         NumberOfDigits++;
+       }
+       break;
+      }//end case 2
+      };//end switch
+    }//end if
+  }while (digrow->Next());
+  return;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/TPC/AliTPCBuffer.h b/TPC/AliTPCBuffer.h
new file mode 100644 (file)
index 0000000..3b40c77
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef AliTPCBUFFER_H
+#define AliTPCBUFFER_H
+/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/////////////////////////////////////////////////////
+// Class used for                                  //
+/////////////////////////////////////////////////////
+
+class fstream;
+
+class AliSimDigits;
+//class TTree;
+//class TFile;
+class AliTPCBuffer:public TObject{
+public:
+  AliTPCBuffer(){}//default constructor
+  AliTPCBuffer(const char* fileName);//constructor
+  virtual ~AliTPCBuffer();//destructor
+  AliTPCBuffer(const AliTPCBuffer &source); // copy constructor
+  AliTPCBuffer& operator=(const AliTPCBuffer &source); // ass. op.
+  void    WriteRowBinary(Int_t eth,AliSimDigits *digrow,Int_t minPad,Int_t maxPad,Int_t flag,Int_t sec,Int_t SubSec,Int_t row);
+  //  void    WriteRow(Int_t eth,AliSimDigits *digrow,Int_t minPad,Int_t maxPad,Int_t flag,Int_t sec,Int_t SubSec,Int_t row);
+  ULong_t GetDigNumber()const{return NumberOfDigits;}
+  void    SetVerbose(Int_t val){fVerbose=val;}
+private:
+  Int_t fVerbose;
+  fstream f;
+  //TFile *fout;
+  //TTree *tree;
+  ULong_t NumberOfDigits;
+  ClassDef(AliTPCBuffer,1)
+};
+
+#endif
diff --git a/TPC/AliTPCBuffer160.cxx b/TPC/AliTPCBuffer160.cxx
new file mode 100644 (file)
index 0000000..26ff2c2
--- /dev/null
@@ -0,0 +1,329 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+#include "TObjArray.h"
+#include "Riostream.h"
+#include <stdlib.h>
+#include "AliTPCBuffer160.h"
+
+ClassImp(AliTPCBuffer160)
+
+AliTPCBuffer160::AliTPCBuffer160(const char* fileName,Int_t flag){
+  //if flag = 1 the actual object is used in the write mode
+  //if flag = 0 the actual object is used in the read mode
+  fFlag=flag;
+  fCurrentCell=0;
+  fMiniHeaderPos=0;
+  fMaskBackward=0xFF;
+  fVerbose=0;
+  if (flag){
+    fFreeCellBuffer=16;
+    fShift=32; 
+    //the buffer is cleaned 
+    for (Int_t i=0;i<5;i++)fBuffer[i]=0;
+    //open the output file
+    f.open(fileName,ios::binary|ios::out);
+  }
+  else{
+    //open the input file
+    f.open(fileName,ios::binary|ios::in);
+    if(!f){cout<<"File doesn't exist\n";exit(-1);}
+    fShift=0;
+    //To get the file dimension (position of the last element in term of bytes)
+    f.seekg(0, ios::end);
+    fFilePosition= f.tellg();
+    fFileEnd=fFilePosition;
+    f.seekg(0);
+  }
+}
+
+AliTPCBuffer160::~AliTPCBuffer160(){
+  if (fFlag){
+    //Last Buffer filled couldn't be full
+    Flush();
+    if(fVerbose)
+      cout<<"File Created\n";
+  }//end if
+  f.close();
+}
+
+
+AliTPCBuffer160::AliTPCBuffer160(const AliTPCBuffer160 &source){
+  // Copy Constructor
+  if(&source==this)return;
+  this->fShift=source.fShift;
+  this->fCurrentCell=source.fCurrentCell;
+  this->fFreeCellBuffer=source.fFreeCellBuffer;
+  this->fFlag=source.fFlag;
+  this->fMaskBackward=source.fMaskBackward;
+  this->fFilePosition=source.fFilePosition;
+  this->fMiniHeaderPos=source.fMiniHeaderPos;
+  this->fVerbose=source.fVerbose;
+  for (Int_t i=0;i<5;i++)this->fBuffer[i]=source.fBuffer[i];
+  return;
+}
+
+AliTPCBuffer160& AliTPCBuffer160::operator=(const AliTPCBuffer160 &source){
+  //Assigment operator
+  if(&source==this)return *this;
+  this->fShift=source.fShift;
+  this->fCurrentCell=source.fCurrentCell;
+  this->fFreeCellBuffer=source.fFreeCellBuffer;
+  this->fFlag=source.fFlag;
+  this->fMaskBackward=source.fMaskBackward;
+  this->fFilePosition=source.fFilePosition;
+  this->fMiniHeaderPos=source.fMiniHeaderPos;
+  this->fVerbose=source.fVerbose;
+  for (Int_t i=0;i<5;i++)this->fBuffer[i]=source.fBuffer[i];
+  return *this;
+}
+
+Int_t AliTPCBuffer160::GetNext(){
+  //If there aren't elements anymore -1 is returned otherwise 
+  //the next element is returned
+  ULong_t Mask=0xFFC00000;
+  ULong_t temp;
+  ULong_t Value;
+  if (!fShift){
+    if ( f.read((char*)fBuffer,sizeof(ULong_t)*5) ){
+      fCurrentCell=0;
+      fShift=22;
+      Value=fBuffer[fCurrentCell]&Mask;
+      Value=Value>>22;
+      fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<10;
+      return Value;      
+    }
+    else return -1;
+  }//end if
+  else{
+    if (fShift>=10){
+      Value=fBuffer[fCurrentCell]&Mask;
+      Value=Value>>22;
+      fShift-=10;
+      fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<10;
+    }
+    else{
+      Value=fBuffer[fCurrentCell]&Mask;
+      fCurrentCell++;
+      temp=fBuffer[fCurrentCell];
+      temp=temp>>fShift;
+      temp=temp&Mask;
+      Value=Value|temp;
+      Value=Value>>22;
+      fBuffer[fCurrentCell]=fBuffer[fCurrentCell]<<(10-fShift);
+      fShift=22+fShift;
+    }
+    return Value;
+  }//end else
+}
+
+Int_t AliTPCBuffer160::GetNextBackWord(){
+  //If there aren't elements anymore -1 is returned otherwise 
+  //the next element is returned
+  ULong_t Mask=0x3FF;
+  ULong_t temp;
+  ULong_t Value;
+  if (!fShift){
+    if (fFilePosition){
+      fFilePosition-=sizeof(ULong_t)*5;
+      f.seekg(fFilePosition);
+      f.read((char*)fBuffer,sizeof(ULong_t)*5);
+      fCurrentCell=4;
+      fShift=22;
+      fMaskBackward=0xFF;
+      Value=fBuffer[fCurrentCell]&Mask;
+      fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>10;
+      return Value;      
+    }
+    else return -1;
+  }//end if
+  else{
+    if (fShift>=10){
+      Value=fBuffer[fCurrentCell]&Mask;
+      fShift-=10;
+      fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>10;
+    }
+    else{
+      Value=fBuffer[fCurrentCell];
+      fCurrentCell--;
+      temp=fBuffer[fCurrentCell]&Mask;
+      temp=temp&fMaskBackward;
+      fMaskBackward=fMaskBackward>>2;
+      temp=temp<<fShift;
+      Value=Value|temp;
+      fBuffer[fCurrentCell]=fBuffer[fCurrentCell]>>(10-fShift);
+      fShift=22+fShift;
+    }
+    return Value;
+  }//end else
+}
+
+void AliTPCBuffer160::Flush(){
+  if(fFreeCellBuffer!=16){
+    Int_t temp=fFreeCellBuffer;
+    for(Int_t i=0;i<temp;i++){
+      FillBuffer(0x2AA);
+    }//end for
+  }//end if
+}
+
+void AliTPCBuffer160::FillBuffer(Int_t Val){
+  //each value takes 10 bits
+  fFreeCellBuffer--;
+  if (fShift<10){
+    Int_t temp=Val;
+    Val=Val>>(10-fShift);
+    fBuffer[fCurrentCell]|=Val;
+    fCurrentCell++;
+    fShift+=32;
+    Val=temp;
+  }
+  fShift-=10;
+  Val=Val<<fShift;
+  fBuffer[fCurrentCell]|=Val;
+  if(!fShift){
+    //Buffer is written into a file
+    f.write((char*)fBuffer,sizeof(ULong_t)*5);
+   //Buffer is empty
+    for(Int_t j=0;j<5;j++)fBuffer[j]=0;
+    fShift=32;
+    fCurrentCell=0;
+    fFreeCellBuffer=16;
+  }
+  /*
+    for(Int_t jj=0;jj<5;jj++){
+    cout.flags(ios::hex);
+    cout<<fBuffer[jj]<<endl;
+    cout.flags(ios::dec);
+    }
+    
+  */
+  return;
+}
+
+void   AliTPCBuffer160::WriteTrailer(Int_t WordsNumber,Int_t PadNumber,Int_t RowNumber,Int_t SecNumber){
+  Int_t num=fFreeCellBuffer%4;
+  for(Int_t i=0;i<num;i++){
+    FillBuffer(0x2AA);
+  }//end for
+  FillBuffer(WordsNumber);
+  FillBuffer(PadNumber);
+  FillBuffer(RowNumber);
+  FillBuffer(SecNumber);
+}
+
+void AliTPCBuffer160::ReadTrailer(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber){
+  WordsNumber=GetNext();
+  PadNumber=GetNext();
+  RowNumber=GetNext();
+  SecNumber=GetNext();
+}
+
+
+Int_t AliTPCBuffer160::ReadTrailerBackward(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber){
+  Int_t temp;
+  EndingFillWords=0;
+  do{
+    temp=GetNextBackWord();
+    EndingFillWords++;
+    if (temp==-1)return -1;
+  }while (temp==0x2AA);  
+  EndingFillWords--;
+  SecNumber=temp;
+  RowNumber=GetNextBackWord();
+  PadNumber=GetNextBackWord();
+  WordsNumber=GetNextBackWord();
+  return 0;
+} 
+
+void AliTPCBuffer160::WriteMiniHeader(ULong_t Size,Int_t SecNumber,Int_t SubSector,Int_t Detector,Int_t Flag ){
+  //size msg errore sector number sub-sector number 0 for TPC 0 for uncompressed
+  Int_t DDLNumber;
+  ULong_t MiniHeader[3];
+  Int_t Version=1;
+  if(SecNumber<36)
+    DDLNumber=SecNumber*2+SubSector;
+  else
+    DDLNumber=72+(SecNumber-36)*4+SubSector;
+  //  cout<<"DDL number "<<DDLNumber<<endl;
+  for(Int_t i=0;i<3;i++)MiniHeader[i]=0;
+  Int_t MiniHeaderSize=(sizeof(ULong_t))*3;
+  PackWord(MiniHeader[1],Detector,0,7);
+  PackWord(MiniHeader[1],0x123456,8,31);
+  PackWord(MiniHeader[2],Version,0,7);
+  PackWord(MiniHeader[2],Flag,8,15);
+  PackWord(MiniHeader[2],DDLNumber,16,31);
+  if (!Size){
+    //if size=0 it means that this mini header is a dummi mini header
+    fMiniHeaderPos=f.tellp();
+    //cout<<" Position of the DUMMY MH:"<<fMiniHeaderPos<<" Size:"<<Size<<endl;
+    MiniHeader[0]=Size;
+    f.write((char*)(MiniHeader),MiniHeaderSize);
+  }//end if
+  else{
+    ULong_t CurrentFilePos=f.tellp();
+    f.seekp(fMiniHeaderPos);
+    Size=CurrentFilePos-fMiniHeaderPos-MiniHeaderSize;
+    //cout<<"Current Position (Next MH) "<<CurrentFilePos<<" Position of the MH:"<<fMiniHeaderPos<<" Size:"<<Size<<endl;
+    MiniHeader[0]=Size;
+    //cout<<"Mini Header Size:"<<MiniHeader[0]<<endl;
+    f.write((char*)(MiniHeader),MiniHeaderSize);
+    f.seekp(CurrentFilePos);
+  }
+  return;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void AliTPCBuffer160::PackWord(ULong_t &BaseWord, ULong_t Word, Int_t StartBit, Int_t StopBit){
+  ULong_t DummyWord,OffSet;
+  Int_t   Length;
+  ULong_t Sum;
+  //The BaseWord is being filled with 1 from StartBit to StopBit
+  Length=StopBit-StartBit+1;
+  Sum=(ULong_t)pow(2,Length)-1;
+  if(Word > Sum){
+    cout<<"WARNING::Word to be filled is not within desired length"<<endl;
+    exit(-1);
+  }
+  OffSet=Sum;
+  OffSet<<=StartBit;
+  BaseWord=BaseWord|OffSet;
+  //The Word to be filled is shifted to the position StartBit
+  //and the remaining  Left and Right bits are filled with 1
+  Sum=(ULong_t)pow(2,StartBit)-1;
+  DummyWord=0xFFFFFFFF<<Length;
+  DummyWord +=Word;
+  DummyWord<<=StartBit;
+  DummyWord+=Sum;
+  BaseWord=BaseWord&DummyWord;
+  return;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void AliTPCBuffer160::UnpackWord(ULong_t PackedWord, Int_t StartBit, Int_t StopBit, ULong_t &Word){    
+  ULong_t OffSet;
+  Int_t Length;
+  Length=StopBit-StartBit+1;
+  OffSet=(ULong_t)pow(2,Length)-1;
+  OffSet<<=StartBit;
+  Word=PackedWord&OffSet;
+  Word>>=StartBit;
+  return;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/TPC/AliTPCBuffer160.h b/TPC/AliTPCBuffer160.h
new file mode 100644 (file)
index 0000000..3ac3c7a
--- /dev/null
@@ -0,0 +1,76 @@
+/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/////////////////////////////////////////////////////
+// Class used for read-write the ALTRO data format //
+/////////////////////////////////////////////////////
+
+/*This class is an interface between the altro format file and the 
+  user, and can be used in write or read mode
+  In the write mode a new altro file is created and filled using the method FillBuffer().
+  The name of the file is specified as parameter in the constructor as well as the type mode.
+  In the Read mode the specified file is open and the values can be read using the
+  methods GetNext() and GetNextBackWord().
+  The first method is used to read the file forward while the second is used to read backward 
+*/
+
+#ifndef AliTPCBUFFER160_H
+#define AliTPCBUFFER160_H
+
+class AliTPCBuffer160:public TObject{
+public:
+  AliTPCBuffer160(){}//default constructor
+  AliTPCBuffer160(const char* fileName,Int_t flag);//constructor
+  virtual ~AliTPCBuffer160();//destructor
+  AliTPCBuffer160(const AliTPCBuffer160 &source); // copy constructor
+  AliTPCBuffer160& operator=(const AliTPCBuffer160 &source); // ass. op.
+  void  FillBuffer(Int_t Val);
+  //this method returmn the number of free cells of the internal buffer
+  Int_t GetFreeCellNumber()const{return fFreeCellBuffer;}
+  //this method return the next word of 10 bit (reading the file backward) if it exists -1 otherwise
+  Int_t GetNextBackWord();
+  //this method return the next word of 10 bit (reading the file forward) if it exists -1 otherwise
+  Int_t GetNext();
+  //this method is used to write tha trailer
+  void  WriteTrailer(Int_t WordsNumber,Int_t PadNumber,Int_t RowNumber,Int_t SecNumber);
+  //this method is used to read the trailer when the file is read forward
+  void  ReadTrailer(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber);
+  //this method is used to read the trailer when the file is read backward
+  Int_t ReadTrailerBackward(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber);
+  //this methos is used to write the Mini header
+  void  WriteMiniHeader(ULong_t Size,Int_t SecNumber,Int_t SubSector,Int_t Detector,Int_t Flag );
+  //this methos is used to set the verbose level 
+  //level  0 no output messages
+  //level !=0 some messages are displayed during the run
+  void  SetVerbose(Int_t val){fVerbose=val;}
+  //this method is used to fill the buffer with 2AA hexadecimal value and save it into the output file
+  void  Flush();
+  Int_t GetFillWordsNum(){return EndingFillWords;}
+private:
+  //this method is used to pack bits into a word of 32 bits
+  void  PackWord(ULong_t &BaseWord, ULong_t Word, Int_t StartBit, Int_t StopBit);
+  //this method is used to read a precise number of bits from a word of 32 bits
+  void  UnpackWord(ULong_t PackedWord, Int_t StartBit, Int_t StopBit, ULong_t &Word);
+
+  ULong_t fBuffer[5];   //Buffer dimension is 32*5=160 bits and it contains 16 values
+                        //A value is never splitted in two Buffer
+
+
+  Int_t fShift;         //This variable contains the number of free bits in the current cel of
+                        //the Buffer after that the value Val is been inserted.
+                        //size of Int_t is 32 bit that is the same size of a cell of Buffer so 
+                        //the shift operation are perfomend only on value Val.
+  Int_t fCurrentCell;   //This variable contains the cell number of the cell currently used 
+  Int_t fFreeCellBuffer;//number of free cells of the buffer
+  Int_t fFlag;          //0 read  1 write
+  Int_t fVerbose;       //verbose level
+  fstream f;            //logical name of the I/O file
+  Int_t fMaskBackward;  
+  ULong_t fFilePosition;//'pointer' to the actual position in the file
+  ULong_t fFileEnd;     //position of the last element of the file (File dimension)
+  ULong_t fMiniHeaderPos;//Mini header position
+  Int_t  EndingFillWords;
+  ClassDef(AliTPCBuffer160,1)
+};
+
+#endif
diff --git a/TPC/AliTPCCompression.cxx b/TPC/AliTPCCompression.cxx
new file mode 100644 (file)
index 0000000..7bd5e0f
--- /dev/null
@@ -0,0 +1,1047 @@
+/**************************************************************************
+ * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+#include <TObjArray.h>
+#include "Riostream.h"
+#include <math.h>
+#include "AliTPCCompression.h"
+#include "AliTPCBuffer160.h"
+#include "AliTPCHuffman.h"
+
+ClassImp(AliTPCCompression)
+//////////////////////////////////////////////////////////////////////////////////////////////////
+AliTPCCompression::AliTPCCompression(){
+  fDimBuffer=sizeof(ULong_t)*8;
+  fFreeBitsBuffer=fDimBuffer;
+  fReadBits=0;
+  fPos=0;
+  fBuffer=0;
+  fVerbose=0;
+  fFillWords=0;
+  return;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////
+AliTPCCompression::AliTPCCompression(const AliTPCCompression &source){
+  this->fDimBuffer=source.fDimBuffer;
+  this->fFreeBitsBuffer=source.fFreeBitsBuffer;
+  this->fReadBits=source.fReadBits;
+  this->fPos=source.fPos;
+  this->fBuffer=source.fBuffer;
+  this->fVerbose=source.fVerbose;
+  this->fFillWords=source.fFillWords;
+  return;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////
+AliTPCCompression&  AliTPCCompression::operator=(const AliTPCCompression &source){
+  this->fDimBuffer=source.fDimBuffer;
+  this->fFreeBitsBuffer=source.fFreeBitsBuffer;
+  this->fReadBits=source.fReadBits;
+  this->fPos=source.fPos;
+  this->fBuffer=source.fBuffer;
+  this->fVerbose=source.fVerbose;
+  this->fFillWords=source.fFillWords;
+  return *this;
+} 
+//////////////////////////////////////////////////////////////////////////////////////////////////
+void AliTPCCompression::NextTable(Int_t Val,Int_t &NextTableType,Int_t &BunchLen,Int_t &Count){
+  /*
+    Table index:
+    0==> Bunch length value     
+    1==> Time Bin value 
+    2==> 1-samples bunch
+    3==> Central samples
+    4==> Border samples
+  */  
+  switch (NextTableType){
+  case 0:{
+    BunchLen=Val-2;
+    NextTableType=1;
+    break;
+  }//end case 0
+  case 1:{
+    if (BunchLen==1)NextTableType=2;
+    else{
+      NextTableType=4;
+      Count=1;
+    }
+    break;
+  }//end case 1
+  case 2:{
+    NextTableType=0;
+    break;
+  }//end case 2
+  case 3:{
+    Count++;
+    if (Count==(BunchLen-1)){
+      NextTableType=4;
+    }
+    break;
+  }//end case 3
+  case 4:{
+    if (Count==1){
+      if (BunchLen>2)
+       NextTableType=3;
+      else
+       Count++;
+    }
+    else
+      NextTableType=0;
+    break;
+  }//end case 4
+  }//end switch
+  return;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Int_t AliTPCCompression::FillTables(const char* fSource,AliTPCHTable* table[],const Int_t NumTables){
+  //This method is used to compute the frequencies of the symbols in the source file
+  AliTPCBuffer160 Buff(fSource,0);
+  ULong_t CountWords=0;
+  ULong_t CountTrailer=0;
+  Int_t NumWords,PadNum,RowNum,SecNum=0;
+  Int_t Value=0;
+  ULong_t Stat[5]={0,0,0,0,0};
+  Int_t EndFill=0;
+  Int_t End=1;
+  while(Buff.ReadTrailerBackward(NumWords,PadNum,RowNum,SecNum) !=-1 ){
+    if(End){
+      EndFill=Buff.GetFillWordsNum();
+      End=0;
+    }//endif
+    CountTrailer++;
+    if (NumWords%4){
+      fFillWords+=4-NumWords%4;
+      for(Int_t j=0;j<(4-NumWords%4);j++){
+       Value=Buff.GetNextBackWord();
+      }//end for
+    }//end if
+    
+    Int_t Packet[1024];
+    Int_t TimePos[345];
+    Int_t Tp=0;
+    for(Int_t i=0;i<345;i++)TimePos[i]=0;
+    for(Int_t i=0;i<1024;i++)Packet[i]=0;
+    
+    Int_t NextTableType=0;
+    Int_t BunchLen=0;
+    Int_t Count=0;
+    for(Int_t i=0;i<NumWords;i++){
+      Value=Buff.GetNextBackWord();
+      Packet[i]=Value;
+      if(NextTableType==1){
+       TimePos[Tp]=i;
+       Tp++;
+      }
+      NextTable(Value,NextTableType,BunchLen,Count);
+    }//end for
+    //computing the Time gap between two bunches
+    Int_t temp=0;
+    Tp--;
+    Int_t PreviousTime=Packet[TimePos[Tp]];
+    for(Int_t i=Tp-1;i>=0;i--){
+      Int_t TimPos=TimePos[i];
+      Int_t BunchLen=Packet[TimPos-1]-2;
+      temp=Packet[TimPos];
+      Packet[TimPos]=Packet[TimPos]-PreviousTime-BunchLen;
+      PreviousTime=temp;
+    }
+    NextTableType=0;
+    Count=0;
+    BunchLen=0;
+    for(Int_t i=0;i<NumWords;i++){
+      Value=Packet[i];
+      table[NextTableType]->SetFrequency(Value);
+      Stat[NextTableType]++;
+      NextTable(Value,NextTableType,BunchLen,Count);
+      CountWords++;
+    }//end for
+  }//end while
+  cout<<"Number of words:       "<<CountWords<<endl;
+  cout<<"Number of trailers:    "<<CountTrailer<<endl;
+  cout<<"Number of fill words   "<<fFillWords+EndFill<<endl;
+  cout<<"Total number of words: "<<CountWords+CountTrailer*4+fFillWords<<endl;
+  //STATISTICS  
+  stat.open("Statistics");
+  stat<<"Number of words:..........................................."<<CountWords<<endl;
+  stat<<"Number of trailers (4 10 bits words in each one)..........."<<CountTrailer<<endl;
+  stat<<"Number of fill words:......................................"<<fFillWords+EndFill<<endl;
+  stat<<"Total number of words:....................................."<<CountWords+CountTrailer*4+fFillWords+EndFill<<endl;
+  stat<<"-----------------------------------------"<<endl;
+  stat<<"Number of Bunches............."<<Stat[0]<<endl;
+  stat<<"Number of Time bin............"<<Stat[1]<<endl;
+  stat<<"Number of One Samples Bunch..."<<Stat[2]<<endl;
+  stat<<"Number of Central Samples....."<<Stat[3]<<endl;
+  stat<<"Number of Border Samples......"<<Stat[4]<<endl;
+  stat<<"-----------------------------------------"<<endl;
+  ULong_t FileDimension=(ULong_t)ceil(double((CountTrailer*4+CountWords+fFillWords+EndFill)*10/8));
+  stat<<"Total file Size in bytes.."<<FileDimension<<endl;
+  Double_t Percentage=ceil((fFillWords+EndFill)*125)/FileDimension;
+  stat<<"Fill Words................"<<(ULong_t)ceil((fFillWords+EndFill)*10/8)<<" bytes   "<<Percentage<<"%"<<endl;  
+  Percentage=(Double_t)CountTrailer*500/FileDimension;
+  stat<<"Trailer..................."<<CountTrailer*5<<" bytes   "<<Percentage<<"%"<<endl;
+
+  Percentage=(Double_t)((Stat[0]+Stat[1]+Stat[2]+Stat[3]+Stat[4])) *125/FileDimension;
+  stat<<"Data......................"<<(ULong_t)ceil((Stat[0]+Stat[1]+Stat[2]+Stat[3]+Stat[4])*10/8)<<" bytes   "<<Percentage<<"%"<<endl;
+
+  Percentage=(Double_t)(Stat[0]*125)/FileDimension;
+  stat<<"Bunch....................."<<(ULong_t)ceil(Stat[0]*10/8)<<" bytes  "<<Percentage<<"%"<<endl;  //  
+  Percentage=(Double_t)(Stat[1]*125)/FileDimension;
+  stat<<"Time......................"<<(ULong_t)ceil(Stat[1]*10/8)<<" bytes  "<<Percentage<<"%"<<endl;  //  
+
+
+  Percentage=(Double_t)((Stat[2]+Stat[3]+Stat[4])) *125/FileDimension;
+  stat<<"Amplitude values.........."<<(ULong_t)ceil((Stat[2]+Stat[3]+Stat[4])*10/8)<<" bytes  "<<Percentage<<"%"<<endl;
+  Percentage=(Double_t)(Stat[2]*125)/FileDimension;
+  stat<<"     One Samples..............."<<(ULong_t)ceil(Stat[2]*10/8)<<" bytes  "<<Percentage<<"%"<<endl;  //  
+  Percentage=(Double_t)(Stat[3]*125)/FileDimension;
+  stat<<"     Central Samples..........."<<(ULong_t)ceil(Stat[3]*10/8)<<" bytes  "<<Percentage<<"%"<<endl;  //  
+  Percentage=(Double_t)(Stat[4]*125)/FileDimension;
+  stat<<"     Border Samples............"<<(ULong_t)ceil(Stat[4]*10/8)<<" bytes  "<<Percentage<<"%"<<endl;  //  
+  stat.close();
+  return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////
+Int_t AliTPCCompression::StoreTables(AliTPCHTable* table[],const Int_t NumTable){
+  char filename[15];
+  ofstream fTable;
+  for(Int_t k=0;k<NumTable;k++){
+    sprintf(filename,"Table%d.dat",k); 
+    fTable.open(filename,ios::binary);
+    Int_t dim=table[k]->Size();
+    //Table dimension is written into a file
+    fTable.write((char*)(&dim),sizeof(Int_t));
+    //One table is written into a file
+    for(Int_t i=0;i<dim;i++){
+      UChar_t CodeLen=table[k]->CodeLen()[i];
+      //      ULong_t Code=(ULong_t)table[k]->Code()[i];
+      Double_t Code=table[k]->Code()[i];
+      fTable.write((char*)(&CodeLen),sizeof(UChar_t));
+      //fTable.write((char*)(&Code),sizeof(ULong_t));
+      fTable.write((char*)(&Code),sizeof(Double_t));
+    } //end for
+    fTable.close();
+  }//end for
+  return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////
+Int_t AliTPCCompression::CreateTables(const char* fSource,const Int_t NumTables){
+    Int_t n=10;// 10 bits per symbol 
+  /*
+    Table index:
+    0==> Bunch length values     
+    1==> Time Bin values 
+    2==> 1-samples bunch
+    3==> Central samples
+    4==> Border samples
+  */
+  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)(pow(2,n)));}
+  //The frequencies are calculated and the tables are filled
+  if (fVerbose)
+    cout<<"Filling tables...\n";
+  //The get the frequencies 
+  FillTables(fSource,table,NumTables);
+
+  //This part will be used in the table optimization phase
+  /*
+  for(Int_t i=0;i<NumTables;i++){
+    table[i]->CompleteTable(i);
+  }
+  */
+  if(fVerbose){
+    cout<<"Entropy of Bunch length table........."<<table[0]->GetEntropy()<<endl;
+    cout<<"Entropy of Time bin table............."<<table[1]->GetEntropy()<<endl;
+    cout<<"Entropy of one Sample bunch table....."<<table[2]->GetEntropy()<<endl;
+    cout<<"Entropy of Central Sample table......."<<table[3]->GetEntropy()<<endl;
+    cout<<"Entropy Border Samples table.........."<<table[4]->GetEntropy()<<endl;
+  }
+  stat.open("Statistics",ios::app);
+  stat<<endl;
+  stat<<"----------------- ENTROPY for castomized tables --------------------------"<<endl;
+  stat<<"Entropy of Bunch length table......."<<table[0]->GetEntropy()<<endl;
+  stat<<"Entropy of Time bin table..........."<<table[1]->GetEntropy()<<endl;
+  stat<<"Entropy of one Sample bunch table..."<<table[2]->GetEntropy()<<endl;
+  stat<<"Entropy of Central Sample table....."<<table[3]->GetEntropy()<<endl;
+  stat<<"Entropy Border Samples table........"<<table[4]->GetEntropy()<<endl;
+  stat.close();
+  if (fVerbose)
+    cout<<"Tables filled \n";
+  //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");
+  table[1]->StoreFrequencies("TimeFreq.txt");
+  table[2]->StoreFrequencies("Sample1Freq.txt");
+  table[3]->StoreFrequencies("SCentralFreq.txt");
+  table[4]->StoreFrequencies("SBorderFreq.txt");
+  if (fVerbose)
+    cout<<"Creating Tables..\n";
+  //One Huffman tree is created for each table starting from the frequencies of the symbols
+  for(Int_t i=0;i<NumTables;i++){
+    table[i]->BuildHTable();
+    if (fVerbose==2){
+      cout<<"Number of elements inside the table:"<<table[i]->GetWordsNumber();
+      switch(i){
+      case 0:{
+       cout<<" (Bunch Length)"<<endl;
+       break;
+      }
+      case 1:{
+       cout<<" (Time Bin)"<<endl;
+       break;
+      }
+      case 2:{
+       cout<<" (1 Samples Bunch)"<<endl;
+       break;
+      }
+      case 3:{
+       cout<<" (Central Samples)"<<endl;
+       break;
+      }
+      case 4:{
+       cout<<" (Border Samples)"<<endl;
+       break;
+      }
+      }//end switch
+      table[i]->PrintTable();
+    }
+  }
+  //The tables are saved ad binary files
+  StoreTables(table,NumTables);
+  //The tables stored in memory are deleted; 
+  for(Int_t i=0;i<NumTables;i++)delete table[i];
+  delete [] table;
+  return 0;
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+Int_t AliTPCCompression::RetrieveTables(AliTPCHTable* table[],Int_t NumTable){
+  if (fVerbose)
+    cout<<"Retrieving tables from files \n";
+  //  ULong_t Code;
+  Double_t Code;
+  UChar_t CodeLen;
+  ifstream fTable;  
+  char filename[15];
+  //The following for loop is used to generate the Huffman trees acording to the tables
+  for(Int_t k=0;k<NumTable;k++){
+    Int_t Dim;//this variable contains the table dimension
+    sprintf(filename,"Table%d.dat",k); 
+    fTable.open(filename,ios::binary);
+    fTable.read((char*)(&Dim),sizeof(Int_t));
+    if (fVerbose)
+      cout<<"Table dimension: "<<Dim<<endl;
+    table[k]=new AliTPCHTable(Dim);
+    for(Int_t i=0;i<Dim;i++){
+      fTable.read((char*)(&CodeLen),sizeof(UChar_t));
+      table[k]->SetCodeLen(CodeLen,i);
+      //      fTable.read((char*)(&Code),sizeof(ULong_t));
+      fTable.read((char*)(&Code),sizeof(Double_t));
+      table[k]->SetCode(Mirror((ULong_t)Code,CodeLen),i);
+    }//end for 
+    fTable.close();
+  }//end for 
+  if (fVerbose)
+    cout<<"Trees generated \n";
+  //At this point the trees are been built
+  return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////////
+/*                               COMPRESSION                                          */
+////////////////////////////////////////////////////////////////////////////////////////
+
+void AliTPCCompression::StoreValue(ULong_t val,UChar_t len){
+  if (len<=fFreeBitsBuffer){           // val is not splitted in two buffer
+    fFreeBitsBuffer-=len;
+    fBuffer=fBuffer<<len;
+    fBuffer=fBuffer|val;    
+    if(!fFreeBitsBuffer){              // if the buffer is full it is written into a file 
+      f.write((char*)(&fBuffer),sizeof(ULong_t));      
+      fFreeBitsBuffer=fDimBuffer;
+      fBuffer=0;
+    }
+  }//end if
+  else{                               //val has to be splitted in two buffers
+    fBuffer=fBuffer<<fFreeBitsBuffer;
+    ULong_t temp;
+    temp=val;
+    temp=temp>>(len-fFreeBitsBuffer);
+    fBuffer=fBuffer|temp;
+    f.write((char*)(&fBuffer),sizeof(ULong_t));
+    fFreeBitsBuffer=fDimBuffer-(len-fFreeBitsBuffer);
+    val=val<<fFreeBitsBuffer;
+    val=val>>fFreeBitsBuffer;
+    fBuffer=val;
+  }//end else
+  return;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////
+void AliTPCCompression::Flush(){
+  //The last buffen cannot be completely full
+  if(fFreeBitsBuffer<fDimBuffer){
+    fBuffer=fBuffer<<fFreeBitsBuffer;
+    f.write((char*)(&fBuffer),sizeof(ULong_t));         
+  }//end if
+  return;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////
+ULong_t AliTPCCompression::Mirror(ULong_t val,UChar_t len){
+  ULong_t specular=0;
+  ULong_t Mask=0x1;
+  ULong_t bit;
+  for(Int_t i=0;i<len;i++){
+    bit=val&Mask;
+    bit=bit>>i;
+    specular=specular<<1;
+    specular=specular|bit;
+    Mask=Mask<<1;
+  }
+  return specular;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////
+Int_t AliTPCCompression::CompressData(AliTPCHTable* table[],Int_t NumTable,const char* fSource,const char* fDest){
+  cout<<" COMPRESSION "<<endl;
+  cout<<"compression of the file "<<fSource<<" Output File: "<<fDest<<endl;
+  //the output file is open
+  f.open(fDest,ios::binary|ios::out);
+  //Tables are written into the output file
+  for(Int_t k=0;k<NumTable;k++){
+    Int_t dim=table[k]->Size();
+    //Table dimension is written into a file
+    f.write((char*)(&dim),sizeof(Int_t));
+    //One table is written into a file
+    for(Int_t i=0;i<dim;i++){
+      UChar_t CodeLen=table[k]->CodeLen()[i];
+      ULong_t Code=(ULong_t)table[k]->Code()[i];
+      f.write((char*)(&CodeLen),sizeof(UChar_t));
+      f.write((char*)(&Code),sizeof(ULong_t));
+    } //end for
+  }//end for
+
+  // Source file is open
+  AliTPCBuffer160 Buff(fSource,0);
+  //coded words are written into the output file
+  Int_t NumWords,PadNum,RowNum,SecNum=0;
+  ULong_t StoredWords=0;
+  Int_t Value=0;
+  ULong_t NumPacket=0;
+  while(Buff.ReadTrailerBackward(NumWords,PadNum,RowNum,SecNum) !=-1 ){
+    NumPacket++;
+    if (NumWords%4){
+      for(Int_t j=0;j<(4-NumWords%4);j++){
+       Value=Buff.GetNextBackWord();
+      }//end for
+    }//end if
+
+    Int_t Packet[1024];
+    Int_t TimePos[345];
+    Int_t Tp=0;
+    for(Int_t i=0;i<345;i++)TimePos[i]=0;
+    for(Int_t i=0;i<1024;i++)Packet[i]=0;
+
+    Int_t NextTableType=0;
+    Int_t BunchLen=0;
+    Int_t Count=0;
+    for(Int_t i=0;i<NumWords;i++){
+      Value=Buff.GetNextBackWord();
+      Packet[i]=Value;
+      if(NextTableType==1){
+       TimePos[Tp]=i;
+       Tp++;
+      }
+      NextTable(Value,NextTableType,BunchLen,Count);
+    }//end for
+    //computing the Time gap between two bunches
+    Int_t temp=0;
+    Tp--;
+    Int_t PreviousTime=Packet[TimePos[Tp]];
+    for(Int_t i=Tp-1;i>=0;i--){
+      Int_t TimPos=TimePos[i];
+      Int_t BunchLen=Packet[TimPos-1]-2;
+      temp=Packet[TimPos];
+      Packet[TimPos]=Packet[TimPos]-PreviousTime-BunchLen;
+      PreviousTime=temp;
+    }//end for
+    NextTableType=0;
+    Count=0;
+    BunchLen=0;
+    Int_t TimeBin=0;
+    //All the words for one pad are compressed and stored in the compress file
+    for(Int_t i=0;i<NumWords;i++){
+      Value=Packet[i];
+      if(NextTableType==1)TimeBin=Value;
+      if(NextTableType>1){
+       //      ULong_t val=(ULong_t)table[NextTableType]->Code()[Value];     // val is the code
+       Double_t val=table[NextTableType]->Code()[Value];     // val is the code
+       UChar_t len=table[NextTableType]->CodeLen()[Value];  // len is the length (number of bits)of val
+       StoreValue(Mirror((ULong_t)val,len),len);
+       StoredWords++;
+      }//end if
+      NextTable(Value,NextTableType,BunchLen,Count);
+      if(NextTableType==0){
+       //      ULong_t val=(ULong_t)table[1]->Code()[TimeBin];     // val is the code
+       Double_t val=table[1]->Code()[TimeBin];     // val is the code
+       UChar_t len=table[1]->CodeLen()[TimeBin];  // len is the length (number of bits)of val
+       StoreValue(Mirror((ULong_t)val,len),len);
+       //val=(ULong_t)table[NextTableType]->Code()[(BunchLen+2)];     // val is the code
+       val=table[NextTableType]->Code()[(BunchLen+2)];     // val is the code
+       len=table[NextTableType]->CodeLen()[(BunchLen+2)];  // len is the length (number of bits)of val
+       StoreValue(Mirror((ULong_t)val,len),len);
+       StoredWords+=2;
+      }
+    }//end for
+    //Trailer
+    StoreValue(NumWords,10);
+    StoreValue(PadNum,10);
+    StoreValue(RowNum,10);
+    StoreValue(SecNum,9);
+    StoreValue(1,1);
+    StoredWords+=4;
+  }//end  while
+  StoreValue(NumPacket,32);
+  cout<<"Number of strored packet: "<<NumPacket<<endl;
+  StoreValue(1,1);
+  //The last buffen cannot be completely full
+  Flush();
+  cout<<"Number of stored words: "<<StoredWords<<endl;
+  f.close();
+  return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+Int_t AliTPCCompression::CompressDataOptTables(Int_t NumTable,const char* fSource,const char* fDest){
+  if (fVerbose){
+    cout<<" BackWord COMPRESSION "<<endl;
+    cout<<"compression of the file "<<fSource<<" Output File: "<<fDest<<endl;
+  }
+  //Tables are read from the files (Each codeword has been "Mirrored")
+  AliTPCHTable ** table = new AliTPCHTable*[NumTable];
+  RetrieveTables(table,NumTable);
+  //the output file is open
+  f.open(fDest,ios::binary|ios::out);
+  // Source file is open
+  AliTPCBuffer160 Buff(fSource,0);
+  //coded words are written into a file
+  Int_t NumWords,PadNum,RowNum,SecNum=0;
+  ULong_t  StoredWords=0;
+  Int_t    Value=0;
+  ULong_t  NumPacket=0;
+  Double_t Stat[5]={0.,0.,0.,0.,0.};
+  ULong_t  TrailerNumber=0;
+  Double_t  NumElem[5]={0,0,0,0,0};
+  Double_t FillWords=0.;
+  stat.open("Statistics",ios::app);
+  stat<<endl;
+  stat<<"-------------------COMPRESSION STATISTICS----------"<<endl;
+  Int_t End=1;
+  while(Buff.ReadTrailerBackward(NumWords,PadNum,RowNum,SecNum) !=-1 ){
+    if(End){
+      FillWords=Buff.GetFillWordsNum();
+      End=0;
+    }//endif
+
+    NumPacket++;
+    if (NumWords%4){
+      FillWords+=4-NumWords%4;
+      for(Int_t j=0;j<(4-NumWords%4);j++){
+       Value=Buff.GetNextBackWord();
+      }//end for
+    }//end if
+
+    Int_t Packet[1024];
+    Int_t TimePos[345];
+    Int_t Tp=0;
+    for(Int_t i=0;i<345;i++)TimePos[i]=0;
+    for(Int_t i=0;i<1024;i++)Packet[i]=0;
+
+    Int_t NextTableType=0;
+    Int_t BunchLen=0;
+    Int_t Count=0;
+    for(Int_t i=0;i<NumWords;i++){
+      Value=Buff.GetNextBackWord();
+      Packet[i]=Value;
+      if(NextTableType==1){
+       TimePos[Tp]=i;
+       Tp++;
+      }
+      NextTable(Value,NextTableType,BunchLen,Count);
+    }//end for
+    //computing the Time gap between two bunches
+    Int_t temp=0;
+    Tp--;
+    Int_t PreviousTime=Packet[TimePos[Tp]];
+    for(Int_t i=Tp-1;i>=0;i--){
+      Int_t TimPos=TimePos[i];
+      Int_t BunchLen=Packet[TimPos-1]-2;
+      temp=Packet[TimPos];
+      Packet[TimPos]=Packet[TimPos]-PreviousTime-BunchLen;
+      PreviousTime=temp;
+    }//end for
+
+    NextTableType=0;
+    Count=0;
+    BunchLen=0;
+    Int_t TimeBin=0;
+    for(Int_t i=0;i<NumWords;i++){
+      Value=Packet[i];
+      if(NextTableType==1)TimeBin=Value;
+      if(NextTableType>1){
+       //ULong_t val=(ULong_t)table[NextTableType]->Code()[Value];     // val is the code
+       Double_t val=table[NextTableType]->Code()[Value];     // val is the code
+       UChar_t len=table[NextTableType]->CodeLen()[Value];  // len is the length (number of bits)of val
+       Stat[NextTableType]+=len;
+       NumElem[NextTableType]++;
+       StoreValue((ULong_t)val,len);
+       StoredWords++;
+      }//end if
+      NextTable(Value,NextTableType,BunchLen,Count);
+      if(NextTableType==0){
+       //      ULong_t val=(ULong_t)table[1]->Code()[TimeBin];     // val is the code
+       Double_t val=table[1]->Code()[TimeBin];     // val is the code
+       UChar_t len=table[1]->CodeLen()[TimeBin];  // len is the length (number of bits)of val
+       Stat[1]+=len;
+       NumElem[1]++;
+       StoreValue((ULong_t)val,len);
+       //      val=(ULong_t)table[NextTableType]->Code()[(BunchLen+2)];     // val is the code
+       val=table[NextTableType]->Code()[(BunchLen+2)];     // val is the code
+       len=table[NextTableType]->CodeLen()[(BunchLen+2)];  // len is the length (number of bits)of val
+       StoreValue((ULong_t)val,len);
+       Stat[NextTableType]+=len;
+       NumElem[NextTableType]++;
+       StoredWords+=2;
+      }
+    }//end for
+    //Trailer
+    StoreValue(NumWords,10);
+    StoreValue(PadNum,10);
+    StoreValue(RowNum,10);
+    StoreValue(SecNum,9);
+    StoreValue(1,1);
+    StoredWords+=4;
+    TrailerNumber++;
+  }//end  while
+  StoreValue(NumPacket,32);
+  if(fVerbose)
+    cout<<"Number of strored packet: "<<NumPacket<<endl;
+  StoreValue(1,1);
+  //The last buffen cannot be completely full
+  Flush();
+  if(fVerbose)
+    cout<<"Number of stored words: "<<StoredWords<<endl;
+  f.close();
+  //Tables are deleted
+  for(Int_t i=0;i<NumTable;i++){
+    delete table[i];
+  }//end for
+  delete [] table;
+  Double_t dimension=(ULong_t)ceil((Stat[0]+Stat[1]+Stat[2]+Stat[3]+Stat[4])/8)+TrailerNumber*5;
+  stat<<"Trailer Dimension in bytes......"<<TrailerNumber*5<<endl;
+  stat<<"Data Dimension in bytes........."<<(ULong_t)ceil((Stat[0]+Stat[1]+Stat[2]+Stat[3]+Stat[4])/8)<<endl;
+  stat<<"Compressed file dimension......."<<(ULong_t)dimension<<endl;
+  /*
+  stat<<(ULong_t)TrailerNumber<<endl;
+  stat<<(ULong_t)FillWords<<endl;
+  stat<<(ULong_t)NumElem[0]<<endl;
+  stat<<(ULong_t)NumElem[1]<<endl;
+  stat<<(ULong_t)NumElem[2]<<endl;
+  stat<<(ULong_t)NumElem[3]<<endl;
+  stat<<(ULong_t)NumElem[4]<<endl;
+  */
+  FillWords=(FillWords+NumElem[0]+NumElem[1]+NumElem[2]+NumElem[3]+NumElem[4]+TrailerNumber*4)*10/8;
+  stat<<"Original file dimension........."<<(ULong_t)FillWords<<endl;
+
+  Double_t ratio=(dimension/FillWords)*100;
+  stat<<"Compression ratio (Compressed/Uncompressed)..."<<ratio<<"%"<<endl;
+  stat<<endl;
+  stat<<"Bunch length size in bytes......"<<(ULong_t)ceil(Stat[0]/8)<<" Comppression.."<<(Stat[0]/NumElem[0])*10<<"%"<<endl;
+  
+  stat<<"Time gap size in bytes.........."<<(ULong_t)ceil(Stat[1]/8)<<" Comppression.."<<(Stat[1]/NumElem[1])*10<<"%"<<endl;
+  stat<<"Amplitude values in bytes......."<<(ULong_t)ceil((Stat[2]+Stat[3]+Stat[4])/8)<<" Comppression.."<<
+    ((Stat[2]+Stat[3]+Stat[4])/(NumElem[2]+NumElem[3]+NumElem[4]))*10<<"%"<<endl;
+  stat<<"     One Samples in bytes............"<<(ULong_t)ceil(Stat[2]/8)<<" Comppression.."<<(Stat[2]/NumElem[2])*10<<"%"<<endl;
+  stat<<"     Central Samples size in bytes..."<<(ULong_t)ceil(Stat[3]/8)<<" Comppression.."<<(Stat[3]/NumElem[3])*10<<"%"<<endl;
+  stat<<"     Border Samples size in bytes...."<<(ULong_t)ceil(Stat[4]/8)<<" Comppression.."<<(Stat[4]/NumElem[4])*10<<"%"<<endl;
+  stat<<endl;
+  stat<<"Average number of bits per word"<<endl;
+  stat<<"Bunch length ......"<<Stat[0]/NumElem[0]<<endl;
+  stat<<"Time gap .........."<<Stat[1]/NumElem[1]<<endl;
+  stat<<"One Samples........"<<Stat[2]/NumElem[2]<<endl;
+  stat<<"Central Samples ..."<<Stat[3]/NumElem[3]<<endl;
+  stat<<"Border Samples....."<<Stat[4]/NumElem[4]<<endl;
+  stat.close();
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////////
+/*                               DECOMPRESSION                                        */
+////////////////////////////////////////////////////////////////////////////////////////
+void AliTPCCompression::CreateTrees(AliTPCHNode *RootNode[],const Int_t NumTables){
+  //The first part of the compressed file cotains the tables
+  //The following for loop is used to generate the Huffman trees acording to the tables
+  if(fVerbose)
+    cout<<"Creating the Huffman trees \n";
+  AliTPCHNode *node=0;
+  //  ULong_t Code;
+  Double_t Code;
+  UChar_t CodeLen;
+  //loop over the numbero of tables
+  for(Int_t k=0;k<NumTables;k++){
+    RootNode[k]=new AliTPCHNode(); //RootNode is the root of the tree
+    Int_t Dim;//this variable contains the table dimension
+    f.read((char*)(&Dim),sizeof(Int_t));
+    if (fVerbose)
+      cout<<"Table dimension: "<<Dim<<endl;
+    //loop over the words of a table
+    for(Int_t i=0;i<Dim;i++){
+      f.read((char*)(&CodeLen),sizeof(UChar_t));
+      //f.read((char*)(&Code),sizeof(ULong_t));
+      f.read((char*)(&Code),sizeof(Double_t));
+      node=RootNode[k];
+      for(Int_t j=1;j<=CodeLen;j++){
+       ULong_t bit,val=0;
+       val=(ULong_t)pow(2,CodeLen-j);
+       bit=(ULong_t)Code&val; 
+       AliTPCHNode *temp=node;
+       if(bit){
+         node=node->GetRight();
+         if(!node){
+           node=new AliTPCHNode();
+           temp->SetRight(node);
+         }//end if
+       }//end if
+       else{
+         node=node->GetLeft();
+         if(!node){
+           node=new AliTPCHNode();
+           temp->SetLeft(node);
+         }//end if
+       }//end else
+      }//end for
+      if(CodeLen){
+       node->SetSymbol(i);
+       node->SetFrequency(CodeLen);
+      }//end if
+      //cout<<node->GetSymbol()<<"  "<<(Int_t)node->GetFrequency()<<endl;
+    }//end for 
+  }//end for 
+  if (fVerbose)
+    cout<<"Trees generated \n";
+  //At this point the trees are been built
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////
+void AliTPCCompression::CreateTreesFromFile(AliTPCHNode *RootNode[],const Int_t NumTables){
+  if(fVerbose)
+    cout<<"Creating the Huffman trees \n";
+  AliTPCHNode *node=0;
+  // ULong_t Code;
+  Double_t Code;
+  UChar_t CodeLen;
+  ifstream fTable;  
+  char filename[15];
+  //The following for loop is used to generate the Huffman trees acording to the tables
+  //loop over the tables
+  for(Int_t k=0;k<NumTables;k++){
+    RootNode[k]=new AliTPCHNode(); //RootNode is the root of the tree
+    Int_t Dim=0;//this variable contains the table dimension
+    sprintf(filename,"Table%d.dat",k); 
+    fTable.open(filename,ios::binary);
+    fTable.read((char*)(&Dim),sizeof(Int_t));
+    if (fVerbose)
+      cout<<"Table dimension: "<<Dim<<endl;
+    //loop over the words of one table
+    for(Int_t i=0;i<Dim;i++){
+      fTable.read((char*)(&CodeLen),sizeof(UChar_t));
+      //fTable.read((char*)(&Code),sizeof(ULong_t));
+      fTable.read((char*)(&Code),sizeof(Double_t));
+      node=RootNode[k];
+      for(Int_t j=1;j<=CodeLen;j++){
+       ULong_t bit,val=0;
+       val=(ULong_t)pow(2,CodeLen-j);
+       bit=(ULong_t)Code&val; 
+       AliTPCHNode *temp=node;
+       if(bit){
+         node=node->GetRight();
+         if(!node){
+           node=new AliTPCHNode();
+           temp->SetRight(node);
+         }//end if 
+       }//end if
+       else{
+         node=node->GetLeft();
+         if(!node){
+           node=new AliTPCHNode();
+           temp->SetLeft(node);
+         }//end if
+       }//end else
+      }//end for
+      if(CodeLen){
+       node->SetSymbol(i);
+       node->SetFrequency(CodeLen);
+      }//end if
+    }//end for 
+    fTable.close();
+  }//end for 
+  if (fVerbose)
+    cout<<"Trees generated \n";
+  //At this point the trees are been built
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////
+void AliTPCCompression::DeleteHuffmanTree(AliTPCHNode* node){
+  //This function deletes all the nodes of an Huffman tree
+  //In an Huffman tree any internal node has always two children
+  if (node){
+    DeleteHuffmanTree(node->GetLeft());
+    DeleteHuffmanTree(node->GetRight());
+    //    cout<<node->GetSymbol()<<"  "<<(Int_t)node->GetFrequency()<<endl;
+    delete node;
+  }
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////
+void AliTPCCompression::VisitHuffmanTree(AliTPCHNode* node){
+  //This function realizes an in order visit of a binary tree
+  if (node){
+    cout<<node->GetSymbol()<<" "<<node->GetFrequency()<<endl;
+    VisitHuffmanTree(node->GetLeft());
+    VisitHuffmanTree(node->GetRight());
+  }
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////
+ULong_t AliTPCCompression::ReadWord(Int_t NumberOfBit){
+  ULong_t Result=0;
+  ULong_t bit=0;
+  for (Int_t i=0;i<NumberOfBit;i++){
+    if (fReadBits==32){
+      fPos-=sizeof(ULong_t);
+      f.seekg(fPos);
+      f.read((char*)(&fBuffer),sizeof(ULong_t));
+      fReadBits=0;
+    }//end if
+    ULong_t mask=0;
+    mask=(ULong_t)pow(2,fReadBits);
+    bit=fBuffer&mask;
+    bit=bit>>fReadBits;
+    fReadBits++;
+    bit=bit<<i;
+    Result=Result|bit;
+  }//end for
+  return Result;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////
+void AliTPCCompression::ReadTrailer(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber){
+  ReadWord(1);
+  SecNumber=ReadWord(9);
+  RowNumber=ReadWord(10);
+  PadNumber=ReadWord(10);
+  WordsNumber=ReadWord(10);
+  return;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////
+ULong_t AliTPCCompression::GetDecodedWord(AliTPCHNode* root){
+  AliTPCHNode *node=root;
+  ULong_t symbol=0;
+  Bool_t decoded=0;
+  while(!decoded){
+    ULong_t bit=ReadWord(1);
+    if(bit)
+      node=node->GetRight();
+    else
+      node=node->GetLeft();
+    if (!(node->GetLeft())){
+      symbol=node->GetSymbol();
+      decoded=1;
+    }
+  }//end while
+  return symbol;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////
+Int_t AliTPCCompression::DecompressData(Int_t NumTables,const char* fname,char* fDest){
+  cout<<"   DECOMPRESSION:"<<endl;
+  cout<<"Source File "<<fname<<" Destination File "<<fDest<<endl; 
+  f.open(fname,ios::binary|ios::in);
+  if(!f){cout<<"File doesn't exist\n";return -1;}
+  AliTPCHNode ** RootNode = new AliTPCHNode*[NumTables];
+  //Creation of the Huffman trees
+  CreateTrees(RootNode,NumTables);
+  //to go to the end of the file
+  f.seekg(0,ios::end);
+  //to get the file dimension in byte
+  fPos=f.tellg();
+  fPos-=sizeof(ULong_t);
+  f.seekg(fPos);
+  fReadBits=0;
+  fBuffer=0;
+  f.read((char*)(&fBuffer),sizeof(ULong_t));
+  Int_t bit=0;
+  ULong_t Mask=0x1;
+  while(!bit){
+    bit=fBuffer&Mask;
+    Mask=Mask<<1;
+    fReadBits++;
+  }
+  ULong_t PacketNumber=ReadWord(sizeof(ULong_t)*8);
+  cout<<"Number of Packect: "<<PacketNumber<<endl;
+  AliTPCBuffer160 BufferFile(fDest,1);
+  ULong_t k=0;
+  ULong_t WordsRead=0; //number of read coded words 
+  while(k<PacketNumber){
+    Int_t NumWords,PadNumber,RowNumber,SecNumber=0;
+    ReadTrailer(NumWords,PadNumber,RowNumber,SecNumber);
+    k++;
+    WordsRead+=4;
+    Int_t PreviousTime=-1;
+    Int_t Time=0;
+    Int_t NextTableType=0;
+    Int_t BunchLen=0;
+    Int_t Count=0;
+    for(Int_t i=0;i<NumWords;i++){
+      ULong_t symbol=GetDecodedWord(RootNode[NextTableType]);
+      WordsRead++;
+      //Time reconstruction
+      if (NextTableType==1){
+       if (PreviousTime!=-1){
+         PreviousTime=symbol+PreviousTime+BunchLen;
+       }
+       else PreviousTime=symbol;
+       Time=PreviousTime;
+      }
+      if(NextTableType>1)
+       BufferFile.FillBuffer(symbol);
+      NextTable(symbol,NextTableType,BunchLen,Count); 
+      if(NextTableType==0){
+       BufferFile.FillBuffer(Time);
+       BufferFile.FillBuffer(BunchLen+2);
+       BunchLen=0;
+      }
+    }//end for
+    BufferFile.WriteTrailer(NumWords,PadNumber,RowNumber,SecNumber);
+  }//end while
+  cout<<"Number of decoded words:"<<WordsRead<<endl;
+  f.close();
+  //The trees are deleted 
+  for(Int_t j=0;j<NumTables;j++){
+      DeleteHuffmanTree(RootNode[j]);
+  }//end for
+  delete [] RootNode; 
+  return 0; 
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Int_t AliTPCCompression::DecompressDataOptTables(Int_t NumTables,const char* fname,char* fDest){
+  if(fVerbose){
+    cout<<"   DECOMPRESSION:"<<endl;
+    cout<<"Source File "<<fname<<" Destination File "<<fDest<<endl; 
+  }
+  AliTPCHNode ** RootNode = new AliTPCHNode*[NumTables];
+  //Creation of the Huffman trees
+  CreateTreesFromFile(RootNode,NumTables);
+  f.open(fname,ios::binary|ios::in);
+  if(!f){cout<<"File doesn't exist\n";return -1;}
+  //to go to the end of the file
+  f.seekg(0,ios::end);
+  //to get the file dimension in byte
+  fPos=f.tellg();
+  fPos-=sizeof(ULong_t);
+  f.seekg(fPos);
+  fReadBits=0;
+  fBuffer=0;
+  f.read((char*)(&fBuffer),sizeof(ULong_t));
+  Int_t bit=0;
+  ULong_t Mask=0x1;
+  while(!bit){
+    bit=fBuffer&Mask;
+    Mask=Mask<<1;
+    fReadBits++;
+  }
+  ULong_t PacketNumber=ReadWord(sizeof(ULong_t)*8);
+  if(fVerbose){
+    cout<<"Number of Packect: "<<PacketNumber<<endl;
+  }
+  AliTPCBuffer160 BufferFile(fDest,1);
+  ULong_t k=0;
+  ULong_t WordsRead=0; //number of read coded words 
+  while(k<PacketNumber){
+    Int_t NumWords,PadNumber,RowNumber,SecNumber=0;
+    ReadTrailer(NumWords,PadNumber,RowNumber,SecNumber);
+    k++;
+    WordsRead+=4;
+    Int_t PreviousTime=-1;
+    Int_t Time=0;
+    Int_t NextTableType=0;
+    Int_t BunchLen=0;
+    Int_t Count=0;
+    for(Int_t i=0;i<NumWords;i++){
+      ULong_t symbol=GetDecodedWord(RootNode[NextTableType]);
+      WordsRead++;
+      //Time reconstruction
+      if (NextTableType==1){
+       if (PreviousTime!=-1){
+         PreviousTime=symbol+PreviousTime+BunchLen;
+       }
+       else PreviousTime=symbol;
+       Time=PreviousTime;
+      }
+      if(NextTableType>1)
+       BufferFile.FillBuffer(symbol);
+      NextTable(symbol,NextTableType,BunchLen,Count); 
+      if(NextTableType==0){
+       BufferFile.FillBuffer(Time);
+       BufferFile.FillBuffer(BunchLen+2);
+       BunchLen=0;
+      }
+    }//end for
+    BufferFile.WriteTrailer(NumWords,PadNumber,RowNumber,SecNumber);
+  }//end while
+  if(fVerbose){
+    cout<<"Number of decoded words:"<<WordsRead<<endl;
+  }
+  f.close();
+  //The trees are deleted 
+  for(Int_t j=0;j<NumTables;j++){
+      DeleteHuffmanTree(RootNode[j]);
+  }//end for
+  delete [] RootNode;
+  return 0; 
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+void AliTPCCompression::ReadAltroFormat(char* fileOut,char* fileIn){
+  ofstream ftxt(fileOut);
+  AliTPCBuffer160 Buff(fileIn,0);
+  Int_t NumWords,PadNum,RowNum,SecNum=0;
+  Int_t Value=0;
+  while(Buff.ReadTrailerBackward(NumWords,PadNum,RowNum,SecNum) !=-1 ){
+    ftxt<<"W:"<<NumWords<<" P:"<<PadNum<<" R:"<<RowNum<<" S:"<<SecNum<<endl;
+    if (NumWords%4){
+      for(Int_t j=0;j<(4-NumWords%4);j++){
+       Value=Buff.GetNextBackWord();
+      }//end for
+    }//end if
+    for(Int_t i=0;i<NumWords;i++){
+      Value=Buff.GetNextBackWord();
+      ftxt<<Value<<endl;
+    }//end for
+  }//end while
+  ftxt.close();
+  return;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
diff --git a/TPC/AliTPCCompression.h b/TPC/AliTPCCompression.h
new file mode 100644 (file)
index 0000000..9dd64fb
--- /dev/null
@@ -0,0 +1,91 @@
+/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+//////////////////////////////////////////////////////
+// Utility Class for Compression and Decompression  //
+//////////////////////////////////////////////////////
+
+#ifndef AliTPCCOMPRESSION_H
+#define AliTPCCOMPRESSION_H
+
+class AliTPCHNode;
+class AliTPCHTable;
+
+class AliTPCCompression:public TObject{
+ public:
+  AliTPCCompression();
+  virtual ~AliTPCCompression(){;}
+  AliTPCCompression(const AliTPCCompression &source); // copy constructor
+  AliTPCCompression& operator=(const AliTPCCompression &source); // ass. op.
+  //This method is used to compress the data store in the altro format file using specific tables
+  //calculate on a particular file that has to be compressed
+  //The tables are stored at the beginning of the compressed file
+  Int_t  CompressData(AliTPCHTable* table[],Int_t NumTable,const char* fSource,const char* fDest);
+  //This methos is used to compress an Altro file using a set of general table previously calculated  and
+  //stored as a sequence of txt file. In this case the tables are not stored in the compressed file
+  Int_t  CompressDataOptTables(Int_t NumTable,const char* fSource,const char* fDest);
+  //This method is used tho decompress a file compressed using the CompressData method
+  Int_t  DecompressData(Int_t NumTables,const char* fname,char* fDest="SourceDecompressed.dat");
+  //This methos is used yo decompress a file compressed using the CompressDataOptTable method
+  //It expects a set of table used for compressing the file in the same direcotory of the compressed file
+  Int_t  DecompressDataOptTables(Int_t NumTables,const char* fname,char* fDest="SourceDecompressed.dat");
+  //This method is used to compute the frequencies of the symbols in the source file
+  Int_t  FillTables(const char* fSource,AliTPCHTable* table[],const Int_t NumTables);
+  //This method is used to create and store the tables 
+  Int_t  CreateTables(const char* fSource,const Int_t NumTables);
+  //This method is used to set up the verbose level
+  //   0 ==> No output messages are displayed
+  //   1 ==> Some output messages are displayed during the running
+  //   2 ==> A complete output is displayed
+  void   SetVerbose(Int_t val){fVerbose=val;}
+  //This method is used to read an Altro file and generate a text file containing the same information
+  //It's is useful for debugging
+  void   ReadAltroFormat(char* fileOut,char* fileIn);
+ private:
+  //This method is used to store an array of tables in a sequence of binary files
+  //Each file contains the Size of the table (number of words) and for each word contains the corrispondent 
+  //codeword and codelength
+  Int_t   StoreTables(AliTPCHTable* table[],const Int_t NumTable);
+  //This method is used to retrieve an array of tables from a sequence of binaruy files created using 
+  //the previous method 
+  Int_t   RetrieveTables(AliTPCHTable* table[],Int_t NumTable);
+  //This method is used to delete an Huffamn tree
+  void    DeleteHuffmanTree(AliTPCHNode* node);
+  //This method realizes an in order visit of a binary tree
+  void    VisitHuffmanTree(AliTPCHNode* node);
+  //This methos is used to create one or more Huffman tree strarting from one or more tables 
+  //It is used in the decompression phase (DecompressData())
+  void    CreateTrees(AliTPCHNode *RootNode[],const Int_t NumTables);
+  //This method is like the previous one but the tables are stored in binary files
+  //It is used in the decompression phase (DecompressDataOptTables())
+  void    CreateTreesFromFile(AliTPCHNode *RootNode[],const Int_t NumTables);
+  //This method is used to deduce which is the next table that as to be used to interpret the next value
+  //reading the Altro format
+  void    NextTable(Int_t Val,Int_t &NextTableType,Int_t &BunchLen,Int_t &Count);
+  //This method is used to store a value in the compressed file 
+  void    StoreValue(ULong_t val,UChar_t len);
+  //This methos is used to get the specular value of a given value
+  //for istance the specular value of 12345 is 54321
+  ULong_t Mirror(ULong_t val,UChar_t len);
+  //This method is used to complete and store the buffer in the output file when it isn't completely full 
+  void    Flush();
+  //this method is used to read a specified number of bits from the compressed file
+  ULong_t ReadWord(Int_t NumberOfBit);
+  //This method is used to read the trailer 
+  void    ReadTrailer(Int_t &WordsNumber,Int_t &PadNumber,Int_t &RowNumber,Int_t &SecNumber);
+  //This method is used to get a decoded word from the compressed file
+  ULong_t GetDecodedWord(AliTPCHNode* root);
+
+  fstream f;                  // f is the logical name for the compressed and uncompressed file
+  ofstream stat;              // Statistics 
+  ULong_t fBuffer;            // buffer 
+  Int_t   fDimBuffer;         // buffer dimension (32 bit)
+  Int_t   fFreeBitsBuffer;    // number of free bits inside the buffer
+  Int_t   fReadBits;          // number of bit read
+  ULong_t fPos;               // current file position
+  Int_t   fVerbose;           // verbose level
+  ULong_t fFillWords;
+  ClassDef(AliTPCCompression,1)
+};
+#endif
diff --git a/TPC/AliTPCDDL.C b/TPC/AliTPCDDL.C
new file mode 100644 (file)
index 0000000..3762b6b
--- /dev/null
@@ -0,0 +1,81 @@
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include "TFile.h"
+#include "AliTPCBuffer.h"
+#endif
+
+
+void AliTPCDDL(char* FileName,Int_t eth=0){
+  //eth is a threshold.
+  //Digits stored into a file have an amplitude value greater than eth
+  TFile *cf=TFile::Open(FileName);
+  // old geometry (3.07)
+  //AliTPCParamSR *param =(AliTPCParamSR *)cf->Get("75x40_100x60");
+  // if new geometry comment out the line above and uncomment the one below
+  AliTPCParamSR *param =(AliTPCParamSR *)cf->Get("75x40_100x60_150x60");
+  AliTPCDigitsArray *digarr=new AliTPCDigitsArray;
+  digarr->Setup(param);
+  char  cname[100];
+  //old geometry
+  //sprintf(cname,"TreeD_75x40_100x60_%d",eventn);
+  // if new geometry comment out the line above and uncomment the one below
+  Int_t eventn=0;
+  sprintf(cname,"TreeD_75x40_100x60_150x60_%d",eventn);
+  digarr->ConnectTree(cname);
+  AliTPCBuffer *b=new AliTPCBuffer("AliTPCDDL.dat");
+  Int_t nrows=Int_t(digarr->GetTree()->GetEntries());
+  cout<<"Number of entries "<<nrows<<endl;
+  Int_t PSector=-1;
+  Int_t SubSec=0;
+  for (Int_t n=0; n<nrows; n++) {
+    AliSimDigits *digrow=(AliSimDigits*)digarr->LoadEntry(n);
+
+    Int_t sec,row; // sector and row number (in the TPC)
+    param->AdjustSectorRow(digrow->GetID(),sec,row);   
+    // cout<<sec<<" row "<<row<<endl;
+    if(PSector!=sec){
+      SubSec=0;
+      PSector=sec;
+    }//end if
+
+    if(sec<36){
+      //inner sector [0;35]
+      if(row!=30)
+       //the whole row is written into the output file
+       b->WriteRowBinary(eth,digrow,0,0,0,sec,SubSec,row);
+      else{
+       //only the pads in the range [37;48] are written into the output file
+       b->WriteRowBinary(eth,digrow,37,48,1,sec,SubSec,row);
+       SubSec=1;
+       //only the pads outside the range [37;48] are written into the output file
+       b->WriteRowBinary(eth,digrow,37,48,2,sec,SubSec,row);
+      }//end else
+    }//end if
+    else{
+      //outer sector [36;71]
+      if(row==54)SubSec=2;
+      if((row!=27)&&(row!=76))
+       b->WriteRowBinary(eth,digrow,0,0,0,sec,SubSec,row);
+      else{
+       if(row==27){
+         //only the pads outside the range [43;46] are written into the output file
+         b->WriteRowBinary(eth,digrow,43,46,2,sec,SubSec,row);
+         SubSec=1;
+         //only the pads in the range [43;46] are written into the output file
+         b->WriteRowBinary(eth,digrow,43,46,1,sec,SubSec,row);
+       }
+       if(row==76){
+         //only the pads outside the range [33;88] are written into the output file
+         b->WriteRowBinary(eth,digrow,33,88,2,sec,SubSec,row);
+         SubSec=3;
+         //only the pads in the range [33;88] are written into the output file
+         b->WriteRowBinary(eth,digrow,33,88,1,sec,SubSec,row);
+       }
+      }
+    }//end else
+  }//end for
+  cf->Close();
+  cout<<"File created !"<<endl;
+  cout<<"Total number of digits: "<<b->GetDigNumber()<<endl;
+  delete b;
+  return;
+}//end AliTPCDataChallenge
diff --git a/TPC/AliTPCDDLRawData.C b/TPC/AliTPCDDLRawData.C
new file mode 100644 (file)
index 0000000..666f1bd
--- /dev/null
@@ -0,0 +1,73 @@
+#if !defined(__CINT__) || defined(__MAKECINT__)
+
+#include "AliTPCDDLRawData.h"
+#include "AliTPCCompression.h"
+#include <alles.h>
+#endif
+
+
+void AliTPCDDLRawData(Int_t LDCsNumber=12){
+  AliTPCDDLRawData *util=new AliTPCDDLRawData();
+  AliTPCCompression *u=new AliTPCCompression();
+  TStopwatch timer;
+
+  static const Int_t NumTable=5;
+  
+  //TABLES CREATION
+  //The Altro File "AltroFormatDDL.dat" is built from "AliTPCDDL.dat"
+  util->RawDataAltro();
+  u->SetVerbose(1);
+  //The file "AltroFormatDDL.dat" is converted in a txt file "AltroFormatDDL.txt"
+  //that is used for debugging
+  u->ReadAltroFormat("AltroFormatDDL.txt","AltroFormatDDL.dat");
+  //Tables are created and stored in as sequence of binary files
+  u->CreateTables("AltroFormatDDL.dat",NumTable);
+  
+
+  
+  //SLICE CREATION
+  //Slices are built here
+  timer.Start();
+  util->RawData(LDCsNumber);
+  timer.Stop();
+  timer.Print();
+  
+  
+  /* 
+  //SLICE CHECKING
+  //An Altro File is created from the slides
+  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.
+  u->ReadAltroFormat("AltroDDLRecomposed.txt","AltroDDLRecomposed.dat");
+  */
+
+  
+  //SLICE COMPRESSION
+  //Slices are compressed here using the tables created above or an optimized set of tables (Tables file for Huffman coding are required)
+  timer.Start();
+  util->RawDataCompDecompress(LDCsNumber,0);
+  timer.Stop();
+  timer.Print();
+  
+
+  /*
+  //SLICE DECOMPRESSION
+  timer.Start();
+  util->RawDataCompDecompress(LDCsNumber,1);
+  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
+  u->ReadAltroFormat("AltroDDLRecomposedDec.txt","AltroDDLRecomposedDec.dat");
+  
+  delete util;
+  delete u;
+  return;
+}
diff --git a/TPC/AliTPCDDLRawData.cxx b/TPC/AliTPCDDLRawData.cxx
new file mode 100644 (file)
index 0000000..c362bdf
--- /dev/null
@@ -0,0 +1,368 @@
+/**************************************************************************
+ * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+#include "TObjArray.h"
+#include "Riostream.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "AliTPCCompression.h"
+#include "AliTPCBuffer160.h"
+#include "AliTPCDDLRawData.h"
+#include "TFile.h"
+#include "TTree.h"
+
+
+
+ClassImp(AliTPCDDLRawData)
+////////////////////////////////////////////////////////////////////////////////////////
+
+AliTPCDDLRawData::AliTPCDDLRawData(const AliTPCDDLRawData &source){
+  // Copy Constructor
+  return;
+}
+
+AliTPCDDLRawData& AliTPCDDLRawData::operator=(const AliTPCDDLRawData &source){
+  //Assigment operator
+  return *this;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+void AliTPCDDLRawData::RawData(Int_t LDCsNumber){
+  //Number of DDL=2*36+4*36=216
+  //2 DDL for each inner sector
+  //4 DDL for each outer sector
+  Int_t DDLPerFile=216/LDCsNumber;
+  Int_t offset=1;
+  if (216%LDCsNumber) DDLPerFile++;
+  cout<<"Number of DDL per slide: "<<DDLPerFile<<endl;
+  ifstream f;
+  f.open("AliTPCDDL.dat",ios::binary);
+  if(!f){cout<<"File doesn't exist !!"<<endl;return;}
+  struct DataPad{
+    Int_t Sec;
+    Int_t SubSec;
+    Int_t Row;
+    Int_t Pad;
+    Int_t Dig;
+    Int_t Time;
+  };
+  DataPad data;
+
+  //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
+  Int_t SliceNumber=1;
+  char  filename[15];
+  sprintf(filename,"TPCslice%d",SliceNumber); 
+  cout<<"   Creating "<<filename<<endl;
+  AliTPCBuffer160 *Buffer=new AliTPCBuffer160(filename,1);
+
+  ULong_t Count=0;
+  Int_t PSecNumber=-1;  //Previous Sector number
+  Int_t PRowNumber=-1;  //Previous Row number  
+  Int_t PPadNumber=-1;  //Previous Pad number
+  Int_t PTimeBin=-1;    //Previous Time-Bin
+  Int_t PSubSector=-1;  //Previous Sub Sector
+  Int_t BunchLength=0;
+  Int_t CountDDL=0;
+  Int_t nwords=0;
+  ULong_t numPackets=0;
+  while (f.read((char*)(&data),sizeof(data))){
+    Count++;
+    if (PPadNumber==-1){
+      PSecNumber=data.Sec;
+      PRowNumber=data.Row;
+      PPadNumber=data.Pad;
+      PTimeBin=data.Time;
+      PSubSector=data.SubSec;
+      //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
+      Buffer->WriteMiniHeader(0,PSecNumber,PSubSector,0,0);//Dummy;
+      BunchLength=1;
+      Buffer->FillBuffer(data.Dig-offset);
+      nwords++;
+    }//end if
+    else{
+      if ( (data.Time==(PTimeBin+1)) &&
+          (PPadNumber==data.Pad) &&
+          (PRowNumber==data.Row) &&
+          (PSecNumber==data.Sec)){
+       BunchLength++;
+      }//end if
+      else{
+       Buffer->FillBuffer(PTimeBin);
+       Buffer->FillBuffer(BunchLength+2);
+       nwords+=2;
+       if ((PPadNumber!=data.Pad)||(PRowNumber!=data.Row)||(PSecNumber!=data.Sec)){
+         //Trailer is formatted and inserted!!
+         Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
+         numPackets++;
+         nwords=0;
+
+         if(PSubSector!=data.SubSec){
+           CountDDL++;
+           if(CountDDL==(DDLPerFile+1)){
+             //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
+             Buffer->Flush();
+             Buffer->WriteMiniHeader(1,PSecNumber,PSubSector,0,0);
+             //cout<<"Mini header for DDL:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
+             delete Buffer;
+             SliceNumber++;
+             sprintf(filename,"TPCslice%d",SliceNumber);
+             cout<<"   Creating "<<filename<<endl;
+             Buffer=new AliTPCBuffer160(filename,1);
+             Buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
+             CountDDL=1;
+           }//end if
+           else{
+             Buffer->Flush();
+             Buffer->WriteMiniHeader(1,PSecNumber,PSubSector,0,0);
+             Buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
+           }
+           PSubSector=data.SubSec;
+         }//end if
+         
+       }//end if
+       
+       BunchLength=1;
+       PPadNumber=data.Pad;
+       PRowNumber=data.Row;
+       PSecNumber=data.Sec;
+      }//end else
+      PTimeBin=data.Time;
+      Buffer->FillBuffer(data.Dig-offset);
+      nwords++;
+    }//end else
+  }//end while
+  Buffer->FillBuffer(PTimeBin);
+  Buffer->FillBuffer(BunchLength+2);
+  nwords+=2;
+  Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
+  //write the  M.H.
+  Buffer->Flush();
+  Buffer->WriteMiniHeader(1,PSecNumber,PSubSector,0,0);
+  //cout<<"Mini header for D D L:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
+  delete Buffer;
+  cout<<"Number of digits: "<<Count<<endl;
+  f.close();
+  return;
+}
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+//This method is used to Compress and decompress the slides
+
+Int_t AliTPCDDLRawData::RawDataCompDecompress(Int_t LDCsNumber,Int_t Comp){
+  static const Int_t NumTable=5;
+  char filename[20];
+  char dest[20];
+  fstream f;
+  ULong_t Size=0;
+  //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector;
+  Int_t Flag=0;
+  for(Int_t i=1;i<=LDCsNumber;i++){
+    if(!Comp){
+      sprintf(filename,"TPCslice%d",i);
+      sprintf(dest,"TPCslice%d.comp",i);
+    }
+    else{
+      sprintf(filename,"TPCslice%d.comp",i);
+      sprintf(dest,"TPCslice%d.decomp",i);
+    }
+    f.open(filename,ios::binary|ios::in);
+    if(!f){cout<<"File doesn't exist \n";exit(1);}
+    cout<<filename<<"  "<<dest<<endl;
+    ofstream fdest;
+    fdest.open(dest,ios::binary);
+    //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
+    while( (f.read((char*)(MiniHeader),sizeof(ULong_t)*3)) ){
+      Size=MiniHeader[0];
+      //Int_t dim=sizeof(ULong_t)+sizeof(Int_t)*5;
+      //cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" Size "<<Size<<endl;
+      //open the temporay File
+      ofstream fo;
+      char temp[15]="TempFile";
+      fo.open(temp,ios::binary);
+      Int_t car=0;
+      for(ULong_t j=0;j<Size;j++){
+       f.read((char*)(&car),1);
+       fo.write((char*)(&car),1);
+      }//end for
+      fo.close();
+      //The temp file is compressed or decompressed
+      AliTPCCompression *util = new AliTPCCompression();
+      if(!Comp)
+       util->CompressDataOptTables(NumTable,temp,"TempCompDecomp");
+      else
+       util->DecompressDataOptTables(NumTable,temp,"TempCompDecomp");
+      delete util;
+      //the temp compressed file is open and copied to the final file fdest
+      ifstream fi;
+      fi.open("TempCompDecomp",ios::binary);
+      fi.seekg(0,ios::end);
+      Size=fi.tellg();
+      fi.seekg(0);
+      //The Mini Header is updated (Size and Compressed flag) 
+      //and written into the output file
+      MiniHeader[0]=Size;
+      if(!Comp)
+       Flag=1;
+      else
+       Flag=0;
+      ULong_t aux=0xFFFF;
+      aux<<=16;
+      aux|=Flag;
+      aux|=0xFF;
+      MiniHeader[2]=MiniHeader[2]&aux;
+      fdest.write((char*)(MiniHeader),sizeof(ULong_t)*3);
+      //The compressem temp file is copied into the output file fdest
+      for(ULong_t j=0;j<Size;j++){
+       fi.read((char*)(&car),1);
+       fdest.write((char*)(&car),1);
+      }//end for
+      fi.close();
+    }//end while
+    f.close();
+    fdest.close();
+    remove("TempFile");
+    remove("TempCompDecomp");
+  }//end for
+  return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+//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
+void AliTPCDDLRawData::RawDataAltro(){
+  Int_t offset=1;
+  ifstream f;
+  f.open("AliTPCDDL.dat",ios::binary);
+  if(!f){cout<<"File doesn't exist !!"<<endl;return;}
+  struct DataPad{
+    Int_t Sec;
+    Int_t SubSec;
+    Int_t Row;
+    Int_t Pad;
+    Int_t Dig;
+    Int_t Time;
+  };
+  DataPad data;
+
+  //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
+  char  filename[30]="AltroFormatDDL.dat";
+  cout<<"   Creating "<<filename<<endl;
+  AliTPCBuffer160 *Buffer=new AliTPCBuffer160(filename,1);
+
+  ULong_t Count=0;
+  Int_t PSecNumber=-1;  //Previous Sector number
+  Int_t PRowNumber=-1;  //Previous Row number  
+  Int_t PPadNumber=-1;  //Previous Pad number
+  Int_t PTimeBin=-1;    //Previous Time-Bin
+  Int_t BunchLength=0;
+  Int_t nwords=0;
+  ULong_t numPackets=0;
+  while (f.read((char*)(&data),sizeof(data))){
+    Count++;
+    if (PPadNumber==-1){
+      PSecNumber=data.Sec;
+      PRowNumber=data.Row;
+      PPadNumber=data.Pad;
+      PTimeBin=data.Time;
+      BunchLength=1;
+      Buffer->FillBuffer(data.Dig-offset);
+      nwords++;
+    }//end if
+    else{
+      if ( (data.Time==(PTimeBin+1)) &&
+          (PPadNumber==data.Pad) &&
+          (PRowNumber==data.Row) &&
+          (PSecNumber==data.Sec)){
+       BunchLength++;
+      }//end if
+      else{
+       Buffer->FillBuffer(PTimeBin);
+       Buffer->FillBuffer(BunchLength+2);
+       nwords+=2;
+       if ((PPadNumber!=data.Pad)||(PRowNumber!=data.Row)||(PSecNumber!=data.Sec)){
+         //Trailer is formatted and inserted!!
+         Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
+         numPackets++;
+         nwords=0;
+       }//end if
+       
+       BunchLength=1;
+       PPadNumber=data.Pad;
+       PRowNumber=data.Row;
+       PSecNumber=data.Sec;
+      }//end else
+      PTimeBin=data.Time;
+      Buffer->FillBuffer(data.Dig-offset);
+      nwords++;
+    }//end else
+  }//end while
+  Buffer->FillBuffer(PTimeBin);
+  Buffer->FillBuffer(BunchLength+2);
+  nwords+=2;
+  Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
+  delete Buffer;
+  cout<<"Number of digits: "<<Count<<endl;
+  f.close(); 
+  return;
+}
+
+
+void AliTPCDDLRawData::RawDataAltroDecode(Int_t LDCsNumber,Int_t Comp){
+  char filename[15];
+  char dest[30];
+  fstream f;
+  if(!Comp)
+    sprintf(dest,"AltroDDLRecomposed.dat");
+  else
+    sprintf(dest,"AltroDDLRecomposedDec.dat");
+  ofstream fdest;
+  fdest.open(dest,ios::binary);
+  
+  ULong_t Size=0;
+  //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector,Flag=0;
+  for(Int_t i=1;i<=LDCsNumber;i++){
+     if(!Comp)
+      sprintf(filename,"TPCslice%d",i);  
+    else
+      sprintf(filename,"TPCslice%d.decomp",i);  
+    
+    f.open(filename,ios::binary|ios::in);
+    if(!f){exit(1);}
+    //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
+    //    for(Int_t j=0;j<3;j++)MiniHeader[j]=0;
+    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++){
+       f.read((char*)(&car),1);
+       fdest.write((char*)(&car),1);
+      }//end for
+    }//end while
+    f.close();
+  }//end for
+  fdest.close();
+  return;
+}
+
diff --git a/TPC/AliTPCDDLRawData.h b/TPC/AliTPCDDLRawData.h
new file mode 100644 (file)
index 0000000..164747f
--- /dev/null
@@ -0,0 +1,32 @@
+/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/////////////////////////////////////////////////////
+// Class used for the fifth ALICE data challenge  //
+/////////////////////////////////////////////////////
+
+#ifndef AliTPCDDLRAWDATA_H
+#define AliTPCDDLRAWDATA_H
+
+
+class AliTPCDDLRawData:public TObject{
+ public:
+  AliTPCDDLRawData(){;}//default constructor
+  virtual ~AliTPCDDLRawData(){;}//destructor
+  AliTPCDDLRawData(const AliTPCDDLRawData &source); // copy constructor
+  AliTPCDDLRawData& operator=(const AliTPCDDLRawData &source); // ass. op.
+  //This method is used to create the slides (sequence of files)
+  void  RawData(Int_t LDCsNumber);
+  //This method is used to create the compressed slides starting from the uncompressed ones 
+  //or it can be used to decompress a sequence of compressed slices
+  Int_t RawDataCompDecompress(Int_t LDCsNumber,Int_t Comp=0);
+  //This method is used to create the Altro format file from "AliTPCDDL.dat"
+  void  RawDataAltro();
+  //This method is used to Construct an Altro format file starting from
+  //the slices compressed or uncompressed
+  void RawDataAltroDecode(Int_t LDCsNumber,Int_t Comp=0);
+ private:
+  ClassDef(AliTPCDDLRawData,1)
+};
+    
+#endif
diff --git a/TPC/AliTPCH5OptimizedTables.C b/TPC/AliTPCH5OptimizedTables.C
new file mode 100644 (file)
index 0000000..e465b71
--- /dev/null
@@ -0,0 +1,36 @@
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include <fstream.h>
+#include <alles.h>
+#include "AliTPCCompression.h"
+#endif
+
+/*
+This macro compress and decompress an Altro format file using Huffman technique with 5 tables
+*/
+
+void AliTPCH5OptimizedTables(const char* fSource="AltroFormat.dat",const char* fDest="CompressedData.dat"){
+  cout<<"Source file: "<<fSource<<" Output file: "<<fDest<<endl;
+  static const Int_t NumTable=5;
+  AliTPCCompression *util = new AliTPCCompression();
+  TStopwatch timer;
+  util->SetVerbose(2);
+  //Tables are created
+  util->CreateTables(fSource,NumTable);
+  //util->ReadAltroFormat("File1.txt","AltroFormat.dat");
+  //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");
+  */
+  delete util;
+}
diff --git a/TPC/AliTPCHuffman.cxx b/TPC/AliTPCHuffman.cxx
new file mode 100644 (file)
index 0000000..d20eb0a
--- /dev/null
@@ -0,0 +1,350 @@
+/**************************************************************************
+ * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+////////////////////////////////////////////////
+//  Huffman classes for set:TPC               //
+////////////////////////////////////////////////
+
+#include <TObjArray.h>
+#include <iostream.h>
+#include <fstream.h>
+#include "TMath.h"
+#include "AliTPCHuffman.h"
+#include "AliTPCBuffer160.h"
+
+ClassImp(AliTPCHNode)
+
+AliTPCHNode::AliTPCHNode(){
+  // constructor
+  fLeft=0;
+  fRight=0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+AliTPCHNode::AliTPCHNode(Int_t sym, Double_t freq){
+  // standard constructor
+  fSymbol=sym;
+  fFrequency=freq;
+  fLeft=0;
+  fRight=0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+AliTPCHNode::AliTPCHNode(const AliTPCHNode &source){
+  //     Copy Constructor 
+  if(&source == this) return;
+  this->fSymbol = source.fSymbol;
+  this->fFrequency = source.fFrequency;
+  this->fLeft = source.fLeft;
+  this->fRight = source.fRight;
+  return;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+AliTPCHNode& AliTPCHNode::operator=(const AliTPCHNode &source){
+  //    Assignment operator
+  if(&source == this) return *this;
+  this->fSymbol = source.fSymbol;
+  this->fFrequency = source.fFrequency;
+  this->fLeft = source.fLeft;
+  this->fRight = source.fRight;
+  return *this;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+Int_t AliTPCHNode::Compare(const TObject *obj)const{
+  // function called by Sort method of TObjArray
+  AliTPCHNode *node=(AliTPCHNode *)obj;
+  Double_t f=fFrequency;
+  Double_t fo=node->fFrequency;
+  if (f<fo) return 1;
+  else if (f>fo) return -1;
+  else return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+ClassImp(AliTPCHTable)
+  
+AliTPCHTable::AliTPCHTable(){
+  // constructor
+  fCodeLen=0;
+  fCode=0;
+  fHNodes=0;
+  fNnodes=0;
+  fNum=0;
+  fVerbose=0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+AliTPCHTable::AliTPCHTable(Int_t size){
+  //initialise
+  fSize=size;
+  fCodeLen = new UChar_t[fSize]; 
+  fCode = new Double_t[fSize]; 
+  fHNodes = new TObjArray;
+  fNnodes=0;
+  fNum=0;
+  fVerbose=0;
+  fSym= new Short_t[fSize];
+  for (Short_t i=0;i<fSize;i++) {
+    fSym[i]=i;
+  }//end for
+  ClearTable(); 
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+AliTPCHTable::AliTPCHTable(const AliTPCHTable &source){
+  //     Copy Constructor 
+  if(&source == this) return;
+  this->fSize = source.fSize;
+  this->fCodeLen = source.fCodeLen;
+  this->fCode = source.fCode;
+  this->fSym = source.fSym;
+  this->fHNodes = source.fHNodes;
+  this->fNnodes = source.fNnodes;
+  this->fNum=source.fNum;
+  this->fVerbose=source.fVerbose;
+  return;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+AliTPCHTable& AliTPCHTable::operator=(const AliTPCHTable &source) {
+  //    Assignment operator
+  if(&source == this) return *this;
+  this->fSize = source.fSize;
+  this->fCodeLen = source.fCodeLen;
+  this->fCode = source.fCode;
+  this->fSym = source.fSym;
+  this->fHNodes = source.fHNodes;
+  this->fNnodes = source.fNnodes;
+  this->fNum=source.fNum;
+  this->fVerbose=source.fVerbose;
+  return *this;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+AliTPCHTable::~AliTPCHTable(){
+  // HTable
+  if(fVerbose)
+    cout<<"HTable destructor !\n";
+  if (fCodeLen) delete[] fCodeLen;
+  if (fCode) delete [] fCode;
+  if (fHNodes) {
+    fHNodes->Delete(); //Clear out the collection and deletes the removed objects
+    delete fHNodes;
+  }//end if
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void AliTPCHTable::SetCodeLen(UChar_t len,Int_t val){
+  fCodeLen[val]=len;
+  return;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void AliTPCHTable::SetCode(Double_t code,Int_t val){
+  fCode[val]=code;
+  return;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void AliTPCHTable::PrintTable()const{
+  cout<<"Table for Huffman coding\n";
+  cout<<"  Symbol|   Code   |   Length \n";
+  for (Int_t i=0;i<fSize;i++){
+    if (fCodeLen[i]){
+      cout.width(6);cout<<fSym[i];
+      cout.width(3);cout<<"|";
+      cout.width(6);cout<<hex<<(ULong_t)fCode[i]<<dec;
+      cout.width(5);cout<<"|";
+      cout.width(6);cout<<(ULong_t)fCodeLen[i]<<endl;  
+    }//end if
+  }//end for
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+Bool_t AliTPCHTable::SpanTree(AliTPCHNode *start, ULong_t code, UChar_t len){
+  // span tree
+  //In an Huffman tree any internal node has always two children
+  AliTPCHNode * visited;
+  visited = start;
+  Int_t idx=visited->GetSymbol();
+  if (!visited->GetLeft()) {
+    fCode[idx] = code; 
+    fCodeLen[idx] = len;
+    return kTRUE;
+  }//end if
+  SpanTree(visited->GetLeft(), code << 1, len + 1);
+  SpanTree(visited->GetRight(), code << 1 | 0x0001, len + 1);
+  return kTRUE;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void AliTPCHTable::ResetHNodes(){
+  // Reset number of HNodes and the HNodes array 
+  if (fHNodes)  fHNodes->Clear();
+  if (fNnodes)  fNnodes=0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void AliTPCHTable::ClearTable(){
+  // Clear the table
+  memset(fCodeLen,0,sizeof(UChar_t)*fSize);
+  memset(fCode,0,sizeof(Double_t)*fSize);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+Int_t  AliTPCHTable::GetFrequencies(const char *fname){
+  AliTPCBuffer160 buff(fname,0);
+  ULong_t NumberOfWords=0;
+  Int_t Val;
+  while((Val=buff.GetNext())!=-1){
+    fCode[Val]++;
+    fNum++;
+    NumberOfWords++;
+  }
+  cout<<"Total number of words: "<<NumberOfWords<<endl;
+  //Print out the frequencies 
+  /*
+    for (Int_t i=0;i<fSize;i++){
+    if (fCode[i])cout<<"Symbol: "<<i<<" Freq: "<<fCode[i]<<endl;
+    }
+    cout<<endl;
+  */
+  return 0;
+}
+
+Int_t AliTPCHTable::SetValFrequency(const Int_t Val,Double_t Value){
+  fCode[Val]=Value;
+  fNum=1;
+  return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+Int_t AliTPCHTable::SetFrequency(const Int_t Val){
+  fCode[Val]++;
+  fNum++;
+  return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+Int_t AliTPCHTable::StoreFrequencies(const char *fname){
+  ofstream ftxt(fname);  
+  for (Int_t i=0;i<fSize;i++){
+    ftxt<<(ULong_t)fCode[i]<<endl;
+  }
+  ftxt.close();
+  return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void AliTPCHTable::CompleteTable(Int_t k){
+  Int_t max;
+  ULong_t val;
+  switch(k){
+  case 0:
+    max=700;
+    val=1;
+    break;
+  case 1:
+    max=445;
+    val=1;
+    break;
+  default:
+    max=fSize;
+    val=1;
+    break;
+  }//end switch
+
+  for(Int_t i=0;i<max;i++){
+    if(fCode[i]==0.0)fCode[i]=val;
+  }
+  return;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+Double_t  AliTPCHTable::GetEntropy()const{
+  Double_t entropy=0;
+  Double_t prob=0;
+  for (Int_t i=0;i<fSize;i++){
+    if (fCode[i]){
+      prob=fCode[i]/(Double_t)fNum;
+      entropy+=prob*(TMath::Log2(prob));
+    }
+  }
+  return -entropy;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+Int_t AliTPCHTable::BuildHTable(){
+  // build Htable
+  if(GetWordsNumber()){
+    for (Int_t i=0; i< fSize; i++) {
+      if (fCode[i] > 0.){
+       fNnodes++;
+       //cout<< "Symbol:"<<i<<" Freq:"<<fCode[i]<<endl;
+       fHNodes->Add(new AliTPCHNode(i,fCode[i]));
+      }//end if
+    }//end for
+    Int_t nentries=fHNodes->GetEntriesFast();  
+    //cout<<"Number of symbols: "<<nentries<<endl;
+    Int_t nindex=nentries-1;  
+    while (nindex > 0){
+      fHNodes->Sort(nindex+1);
+      AliTPCHNode *aux = new AliTPCHNode(0,0);
+      AliTPCHNode *node= (AliTPCHNode*)fHNodes->UncheckedAt(nindex-1);
+      AliTPCHNode *node1= (AliTPCHNode*)fHNodes->UncheckedAt(nindex);
+      
+      aux->SetLeft(node);
+      aux->SetRight(node1);
+      aux->SetFrequency(node->GetFrequency() + node1->GetFrequency());
+      fHNodes->RemoveAt(nindex-1);
+      fHNodes->AddAt(aux,nindex-1);
+      nindex--;
+    }//end while
+    ClearTable();  
+    AliTPCHNode *start= (AliTPCHNode*)fHNodes->UncheckedAt(0);
+    SpanTree(start,0,0);
+  }//end if
+  else{
+    cout<<"Table contains 0 elements\n";
+  }//end else
+  return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
diff --git a/TPC/AliTPCHuffman.h b/TPC/AliTPCHuffman.h
new file mode 100644 (file)
index 0000000..c6c6439
--- /dev/null
@@ -0,0 +1,90 @@
+/* Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+///////////////////////////////////////////////////
+//  Huffman Table associated classes for set:TPC //
+///////////////////////////////////////////////////
+
+#ifndef AliTPCHUFFMAN_H
+#define AliTPCHUFFMAN_H
+class AliTPCBuffer160;
+
+class AliTPCHNode: public TObject  {
+ public:
+  AliTPCHNode(); //default constructor
+  AliTPCHNode(Int_t symbol, Double_t freq);
+  virtual ~AliTPCHNode() {}
+  AliTPCHNode(const AliTPCHNode &source); // copy constructor
+  AliTPCHNode& operator=(const AliTPCHNode &source); // ass. op.
+
+  Bool_t  IsSortable() const{return kTRUE;}
+  Int_t   Compare(const TObject *obj) const;
+  void    SetLeft(AliTPCHNode* point){fLeft=point;}
+  void    SetRight(AliTPCHNode* point){fRight=point;}
+  AliTPCHNode* GetRight()const{return fRight;}
+  AliTPCHNode* GetLeft()const{return fLeft;}
+  void    SetSymbol(Int_t sym){fSymbol=sym;}
+  void    SetFrequency(Double_t freq){fFrequency=freq;}
+  Double_t GetFrequency()const{return fFrequency;}
+  Int_t   GetSymbol()const{return fSymbol;}
+
+ private:
+  Int_t         fSymbol;       // Symbols
+  Double_t       fFrequency;    // Frequency of the Symbol
+  AliTPCHNode   *fLeft;        // Pointer to the left son
+  AliTPCHNode   *fRight;       // pointer to the right son
+  ClassDef(AliTPCHNode,1)     
+};
+/////////////////////////////////////////////////////////////////////////////////////////////////
+class AliTPCHTable: public TObject{ 
+ public:
+  AliTPCHTable(); 
+  AliTPCHTable(Int_t size);
+  virtual   ~AliTPCHTable();
+  AliTPCHTable(const AliTPCHTable &source); // copy constructor
+  AliTPCHTable& operator=(const AliTPCHTable &source); // ass. op.
+  
+  Int_t      Size()const {return fSize;}
+  UChar_t*   CodeLen()const {return fCodeLen;}
+  Double_t*  Code()const {return fCode;}
+  Short_t*   Sym()const {return fSym;}
+  void       SetCodeLen(UChar_t len,Int_t val);
+  void       SetCode(Double_t code,Int_t val);
+  TObjArray* HNodes()const {return fHNodes;}
+  void       PrintTable()const;
+  //This method builds the Huffman tree starting from the frequncies that are 
+  //strored temporary in fCode array
+  Int_t      BuildHTable();
+  //This method returns the number of words stored in the fSym array
+  ULong_t    GetWordsNumber()const{return fNum;}
+  //This method increase by one the frequency of each value that is present
+  //in the specified file
+  Int_t      GetFrequencies(const char* fname);
+  //This method increase by one the frequency of a given value
+  Int_t      SetFrequency(const Int_t Val);
+  //This method strores the frequency of the symbol in a text file
+  Int_t      StoreFrequencies(const char *fname);
+  void       CompleteTable(Int_t k);
+  Double_t   GetEntropy()const;
+  void       SetVerbose(Int_t val){fVerbose=val;}
+  //Method to set directly a frequency
+  Int_t      SetValFrequency(const Int_t Val,Double_t Value);
+ private:
+  //This method executes the pre-order visit of an Huffman tree and calculates the 
+  //codeword for each leaf
+  Bool_t     SpanTree(AliTPCHNode*start, ULong_t code, UChar_t len);
+  void       ResetHNodes();  //Reset the array fHNodes but not delete the remuved objects
+  void       ClearTable();   //Reset the table
+  Int_t       fSize;       // size of the arrays
+  UChar_t     *fCodeLen;   //![fSize] number of bits array
+  Double_t    *fCode;     //![fSize] coded symbols array
+  
+  Short_t    *fSym;      //![fSize] array of input symbols
+  TObjArray  *fHNodes;   // array of nodes
+  Int_t       fNnodes;   // number of nodes
+  ULong_t     fNum;      // number of words
+  Int_t       fVerbose;
+  ClassDef(AliTPCHTable,1)  //Huffman Table  object for set:TPC
+};
+#endif
index 4e53723..8dc1832 100644 (file)
 #pragma link C++ class  AliTPCpolyTrack+;
 
 
+#pragma link C++ class  AliTPCBuffer+;
+#pragma link C++ class  AliTPCBuffer160+;
+#pragma link C++ class  AliTPCCompression+;
+#pragma link C++ class  AliTPCDDLRawData+;
+#pragma link C++ class  AliTPCHNode+;
+#pragma link C++ class  AliTPCHTable+;
 
 
 #endif
index b4ad93a..a78ee7c 100644 (file)
@@ -11,7 +11,11 @@ SRCS:=  AliTPC.cxx  AliTPCv0.cxx    AliTPCv1.cxx      AliTPCv2.cxx  \
        AliTPCTrackHits.cxx\
        AliTPCDigitizer.cxx\
        AliTPCTrackHitsV2.cxx AliTPCtrackerParam.cxx AliTPCkineGrid.cxx \
-       AliTPCclustererMI.cxx AliTPCclusterMI.cxx  AliTPCtrackerMI.cxx AliTPCpolyTrack.cxx
+       AliTPCclustererMI.cxx AliTPCclusterMI.cxx  AliTPCtrackerMI.cxx \
+       AliTPCpolyTrack.cxx \
+       AliTPCBuffer.cxx AliTPCBuffer160.cxx \
+       AliTPCCompression.cxx AliTPCDDLRawData.cxx \
+       AliTPCHuffman.cxx
 HDRS:= $(SRCS:.cxx=.h)