--- /dev/null
+#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;
+}
--- /dev/null
+/**************************************************************************
+ * 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;
+}
--- /dev/null
+/* 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
#pragma link C++ class AliITSDigitizer+;
#pragma link C++ class AliITSFDigitizer+;
#pragma link C++ class AliITSFindClustersV2+;
+// Raw data
+#pragma link C++ class AliITSDDLRawData+;
#endif
AliITSreconstruction.cxx \
AliITSFindClustersV2.cxx \
AliITSRiemannFit.cxx \
- AliITSFDigitizer.cxx
+ AliITSFDigitizer.cxx AliITSDDLRawData.cxx
# AliITSAlignmentTrack.cxx AliITSAlignmentModule.cxx \
HDRS:= $(SRCS:.cxx=.h)
--- /dev/null
+#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
--- /dev/null
+/**************************************************************************
+ * 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;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
--- /dev/null
+#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
--- /dev/null
+/**************************************************************************
+ * 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;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
--- /dev/null
+/* 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
--- /dev/null
+/**************************************************************************
+ * 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;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
--- /dev/null
+/* 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
--- /dev/null
+#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
--- /dev/null
+#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;
+}
--- /dev/null
+/**************************************************************************
+ * 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;
+}
+
--- /dev/null
+/* 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
--- /dev/null
+#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;
+}
--- /dev/null
+/**************************************************************************
+ * 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;
+}
+
+//////////////////////////////////////////////////////////////////////////////
--- /dev/null
+/* 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
#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
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)