1 /**************************************************************************
2 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 #include "TObjArray.h"
17 #include "Riostream.h"
20 #include "AliTPCCompression.h"
21 #include "AliTPCBuffer160.h"
22 #include "AliTPCDDLRawData.h"
28 ClassImp(AliTPCDDLRawData)
29 ////////////////////////////////////////////////////////////////////////////////////////
31 AliTPCDDLRawData::AliTPCDDLRawData(const AliTPCDDLRawData &source){
36 AliTPCDDLRawData& AliTPCDDLRawData::operator=(const AliTPCDDLRawData &source){
42 ////////////////////////////////////////////////////////////////////////////
43 void AliTPCDDLRawData::RawData(Int_t LDCsNumber){
44 //Number of DDL=2*36+4*36=216
45 //2 DDL for each inner sector
46 //4 DDL for each outer sector
47 Int_t DDLPerFile=216/LDCsNumber;
49 if (216%LDCsNumber) DDLPerFile++;
50 cout<<"Number of DDL per slide: "<<DDLPerFile<<endl;
52 f.open("AliTPCDDL.dat",ios::binary);
53 if(!f){cout<<"File doesn't exist !!"<<endl;return;}
64 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
67 sprintf(filename,"TPCslice%d",SliceNumber);
68 cout<<" Creating "<<filename<<endl;
69 AliTPCBuffer160 *Buffer=new AliTPCBuffer160(filename,1);
72 Int_t PSecNumber=-1; //Previous Sector number
73 Int_t PRowNumber=-1; //Previous Row number
74 Int_t PPadNumber=-1; //Previous Pad number
75 Int_t PTimeBin=-1; //Previous Time-Bin
76 Int_t PSubSector=-1; //Previous Sub Sector
81 while (f.read((char*)(&data),sizeof(data))){
88 PSubSector=data.SubSec;
89 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
90 Buffer->WriteMiniHeader(0,PSecNumber,PSubSector,0,0);//Dummy;
92 Buffer->FillBuffer(data.Dig-offset);
96 if ( (data.Time==(PTimeBin+1)) &&
97 (PPadNumber==data.Pad) &&
98 (PRowNumber==data.Row) &&
99 (PSecNumber==data.Sec)){
103 Buffer->FillBuffer(PTimeBin);
104 Buffer->FillBuffer(BunchLength+2);
106 if ((PPadNumber!=data.Pad)||(PRowNumber!=data.Row)||(PSecNumber!=data.Sec)){
107 //Trailer is formatted and inserted!!
108 Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
112 if(PSubSector!=data.SubSec){
114 if(CountDDL==(DDLPerFile+1)){
115 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
117 Buffer->WriteMiniHeader(1,PSecNumber,PSubSector,0,0);
118 //cout<<"Mini header for DDL:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
121 sprintf(filename,"TPCslice%d",SliceNumber);
122 cout<<" Creating "<<filename<<endl;
123 Buffer=new AliTPCBuffer160(filename,1);
124 Buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
129 Buffer->WriteMiniHeader(1,PSecNumber,PSubSector,0,0);
130 Buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
132 PSubSector=data.SubSec;
143 Buffer->FillBuffer(data.Dig-offset);
147 Buffer->FillBuffer(PTimeBin);
148 Buffer->FillBuffer(BunchLength+2);
150 Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
153 Buffer->WriteMiniHeader(1,PSecNumber,PSubSector,0,0);
154 //cout<<"Mini header for D D L:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
156 cout<<"Number of digits: "<<Count<<endl;
160 ////////////////////////////////////////////////////////////////////////////
161 ////////////////////////////////////////////////////////////////////////////
162 //This method is used to Compress and decompress the slides
164 Int_t AliTPCDDLRawData::RawDataCompDecompress(Int_t LDCsNumber,Int_t Comp){
165 static const Int_t NumTable=5;
170 //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector;
172 for(Int_t i=1;i<=LDCsNumber;i++){
174 sprintf(filename,"TPCslice%d",i);
175 sprintf(dest,"TPCslice%d.comp",i);
178 sprintf(filename,"TPCslice%d.comp",i);
179 sprintf(dest,"TPCslice%d.decomp",i);
181 f.open(filename,ios::binary|ios::in);
182 if(!f){cout<<"File doesn't exist \n";exit(1);}
183 cout<<filename<<" "<<dest<<endl;
185 fdest.open(dest,ios::binary);
186 //loop over the DDL block
187 //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
188 //The number of block is ceil(216/LDCsNumber)
189 ULong_t MiniHeader[3];
190 //here the Mini Header is read
191 while( (f.read((char*)(MiniHeader),sizeof(ULong_t)*3)) ){
193 //Int_t dim=sizeof(ULong_t)+sizeof(Int_t)*5;
194 //cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" Size "<<Size<<endl;
195 //open the temporay File
197 char temp[15]="TempFile";
198 fo.open(temp,ios::binary);
200 for(ULong_t j=0;j<Size;j++){
201 f.read((char*)(&car),1);
202 fo.write((char*)(&car),1);
205 //The temp file is compressed or decompressed
206 AliTPCCompression *util = new AliTPCCompression();
208 util->CompressDataOptTables(NumTable,temp,"TempCompDecomp");
210 util->DecompressDataOptTables(NumTable,temp,"TempCompDecomp");
212 //the temp compressed file is open and copied to the final file fdest
214 fi.open("TempCompDecomp",ios::binary);
215 fi.seekg(0,ios::end);
218 //The Mini Header is updated (Size and Compressed flag)
219 //and written into the output file
229 MiniHeader[2]=MiniHeader[2]&aux;
230 fdest.write((char*)(MiniHeader),sizeof(ULong_t)*3);
231 //The compressem temp file is copied into the output file fdest
232 for(ULong_t j=0;j<Size;j++){
233 fi.read((char*)(&car),1);
234 fdest.write((char*)(&car),1);
241 remove("TempCompDecomp");
246 /////////////////////////////////////////////////////////////////////////////////
247 //This method is used to build the Altro format from AliTPCDDL.dat
248 //It is used to debug the code and create the tables used in the compresseion phase
249 void AliTPCDDLRawData::RawDataAltro(){
252 f.open("AliTPCDDL.dat",ios::binary);
253 if(!f){cout<<"File doesn't exist !!"<<endl;return;}
264 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
265 char filename[30]="AltroFormatDDL.dat";
266 cout<<" Creating "<<filename<<endl;
267 AliTPCBuffer160 *Buffer=new AliTPCBuffer160(filename,1);
270 Int_t PSecNumber=-1; //Previous Sector number
271 Int_t PRowNumber=-1; //Previous Row number
272 Int_t PPadNumber=-1; //Previous Pad number
273 Int_t PTimeBin=-1; //Previous Time-Bin
276 ULong_t numPackets=0;
277 while (f.read((char*)(&data),sizeof(data))){
285 Buffer->FillBuffer(data.Dig-offset);
289 if ( (data.Time==(PTimeBin+1)) &&
290 (PPadNumber==data.Pad) &&
291 (PRowNumber==data.Row) &&
292 (PSecNumber==data.Sec)){
296 Buffer->FillBuffer(PTimeBin);
297 Buffer->FillBuffer(BunchLength+2);
299 if ((PPadNumber!=data.Pad)||(PRowNumber!=data.Row)||(PSecNumber!=data.Sec)){
300 //Trailer is formatted and inserted!!
301 Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
312 Buffer->FillBuffer(data.Dig-offset);
316 Buffer->FillBuffer(PTimeBin);
317 Buffer->FillBuffer(BunchLength+2);
319 Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
321 cout<<"Number of digits: "<<Count<<endl;
327 void AliTPCDDLRawData::RawDataAltroDecode(Int_t LDCsNumber,Int_t Comp){
332 sprintf(dest,"AltroDDLRecomposed.dat");
334 sprintf(dest,"AltroDDLRecomposedDec.dat");
336 fdest.open(dest,ios::binary);
339 //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector,Flag=0;
340 for(Int_t i=1;i<=LDCsNumber;i++){
342 sprintf(filename,"TPCslice%d",i);
344 sprintf(filename,"TPCslice%d.decomp",i);
346 f.open(filename,ios::binary|ios::in);
348 //loop over the DDL block
349 //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
350 //The number of block is ceil(216/LDCsNumber)
351 ULong_t MiniHeader[3];
352 //here the Mini Header is read
353 // for(Int_t j=0;j<3;j++)MiniHeader[j]=0;
354 while( (f.read((char*)(MiniHeader),sizeof(ULong_t)*3)) ){
355 //cout<<"Mini header dimension "<<MiniHeader[0]<<endl;
358 for(ULong_t j=0;j<Size;j++){
359 f.read((char*)(&car),1);
360 fdest.write((char*)(&car),1);