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 **************************************************************************/
18 //This class conteins all the methods to create raw data
20 //It produces DDL with both compressed and uncompressed format.
21 //For compression we use the optimized table wich needs
25 #include "TObjArray.h"
26 #include "Riostream.h"
29 #include "AliTPCCompression.h"
30 #include "AliTPCBuffer160.h"
31 #include "AliTPCDDLRawData.h"
33 ClassImp(AliTPCDDLRawData)
34 ////////////////////////////////////////////////////////////////////////////////////////
36 AliTPCDDLRawData::AliTPCDDLRawData(const AliTPCDDLRawData &source){
41 AliTPCDDLRawData& AliTPCDDLRawData::operator=(const AliTPCDDLRawData &source){
47 ////////////////////////////////////////////////////////////////////////////
48 void AliTPCDDLRawData::RawData(Int_t LDCsNumber){
49 //Raw data slides generation
50 //Number of DDL=2*36+4*36=216
51 //2 DDL for each inner sector
52 //4 DDL for each outer sector
53 Int_t ddlPerFile=216/LDCsNumber;
55 if (216%LDCsNumber) ddlPerFile++;
56 cout<<"Number of DDL per slide: "<<ddlPerFile<<endl;
59 f.open("AliTPCDDL.dat",ios::binary);
61 f.open("AliTPCDDL.dat");
63 if(!f){cout<<"File doesn't exist !!"<<endl;return;}
74 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
77 sprintf(filename,"TPCslice%d",sliceNumber);
78 cout<<" Creating "<<filename<<endl;
79 AliTPCBuffer160 *buffer=new AliTPCBuffer160(filename,1);
82 Int_t pSecNumber=-1; //Previous Sector number
83 Int_t pRowNumber=-1; //Previous Row number
84 Int_t pPadNumber=-1; //Previous Pad number
85 Int_t pTimeBin=-1; //Previous Time-Bin
86 Int_t pSubSector=-1; //Previous Sub Sector
91 while (f.read((char*)(&data),sizeof(data))){
98 pSubSector=data.SubSec;
99 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
100 buffer->WriteMiniHeader(0,pSecNumber,pSubSector,0,0);//Dummy;
102 buffer->FillBuffer(data.Dig-offset);
106 if ( (data.Time==(pTimeBin+1)) &&
107 (pPadNumber==data.Pad) &&
108 (pRowNumber==data.Row) &&
109 (pSecNumber==data.Sec)){
113 buffer->FillBuffer(pTimeBin);
114 buffer->FillBuffer(bunchLength+2);
116 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
117 //Trailer is formatted and inserted!!
118 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
122 if(pSubSector!=data.SubSec){
124 if(countDDL==ddlPerFile){
125 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
127 buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
128 //cout<<"Mini header for DDL:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
131 sprintf(filename,"TPCslice%d",sliceNumber);
132 cout<<" Creating "<<filename<<endl;
133 buffer=new AliTPCBuffer160(filename,1);
134 buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
139 buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
140 buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
142 pSubSector=data.SubSec;
152 buffer->FillBuffer(data.Dig-offset);
156 buffer->FillBuffer(pTimeBin);
157 buffer->FillBuffer(bunchLength+2);
159 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
162 buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
163 //cout<<"Mini header for D D L:"<<pSecNumber<<" Sub-sec:"<<pSubSector<<endl;
165 cout<<"Number of digits: "<<count<<endl;
169 ////////////////////////////////////////////////////////////////////////////
170 ////////////////////////////////////////////////////////////////////////////
173 Int_t AliTPCDDLRawData::RawDataCompDecompress(Int_t LDCsNumber,Int_t Comp){
174 //This method is used to compress and decompress the slides
175 static const Int_t kNumTables=5;
180 //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector;
182 for(Int_t i=1;i<=LDCsNumber;i++){
184 sprintf(filename,"TPCslice%d",i);
185 sprintf(dest,"TPCslice%d.comp",i);
188 sprintf(filename,"TPCslice%d.comp",i);
189 sprintf(dest,"TPCslice%d.decomp",i);
192 f.open(filename,ios::binary|ios::in);
194 f.open(filename,ios::in);
196 if(!f){cout<<"File doesn't exist \n";exit(1);}
197 cout<<filename<<" "<<dest<<endl;
200 fdest.open(dest,ios::binary);
204 //loop over the DDL block
205 //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
206 //The number of block is ceil(216/LDCsNumber)
207 ULong_t miniHeader[3];
208 //here the Mini Header is read
209 while( (f.read((char*)(miniHeader),sizeof(ULong_t)*3)) ){
211 //Int_t dim=sizeof(ULong_t)+sizeof(Int_t)*5;
212 //cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" size "<<size<<endl;
213 //open the temporay File
215 char temp[15]="TempFile";
217 fo.open(temp,ios::binary);
222 for(ULong_t j=0;j<size;j++){
223 f.read((char*)(&car),1);
224 fo.write((char*)(&car),1);
227 //The temp file is compressed or decompressed
228 AliTPCCompression *util = new AliTPCCompression();
229 // util->SetVerbose(1);
231 util->CompressDataOptTables(kNumTables,temp,"TempCompDecomp");
233 util->DecompressDataOptTables(kNumTables,temp,"TempCompDecomp");
235 //the temp compressed file is open and copied to the final file fdest
238 fi.open("TempCompDecomp",ios::binary);
240 fi.open("TempCompDecomp");
242 fi.seekg(0,ios::end);
245 //The Mini Header is updated (size and Compressed flag)
246 //and written into the output file
255 miniHeader[2]=miniHeader[2]|aux;
256 fdest.write((char*)(miniHeader),sizeof(ULong_t)*3);
257 //The compressem temp file is copied into the output file fdest
258 for(ULong_t j=0;j<size;j++){
259 fi.read((char*)(&car),1);
260 fdest.write((char*)(&car),1);
268 remove("TempCompDecomp");
273 /////////////////////////////////////////////////////////////////////////////////
274 void AliTPCDDLRawData::RawDataAltro()const{
275 //This method is used to build the Altro format from AliTPCDDL.dat
276 //It is used to debug the code and create the tables used in the compresseion phase
280 f.open("AliTPCDDL.dat",ios::binary);
282 f.open("AliTPCDDL.dat");
284 if(!f){cout<<"File doesn't exist !!"<<endl;return;}
295 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
296 char filename[30]="AltroFormatDDL.dat";
297 cout<<" Creating "<<filename<<endl;
298 AliTPCBuffer160 *buffer=new AliTPCBuffer160(filename,1);
301 Int_t pSecNumber=-1; //Previous Sector number
302 Int_t pRowNumber=-1; //Previous Row number
303 Int_t pPadNumber=-1; //Previous Pad number
304 Int_t pTimeBin=-1; //Previous Time-Bin
307 ULong_t numPackets=0;
308 while (f.read((char*)(&data),sizeof(data))){
316 buffer->FillBuffer(data.Dig-offset);
320 if ( (data.Time==(pTimeBin+1)) &&
321 (pPadNumber==data.Pad) &&
322 (pRowNumber==data.Row) &&
323 (pSecNumber==data.Sec)){
327 buffer->FillBuffer(pTimeBin);
328 buffer->FillBuffer(bunchLength+2);
330 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
331 //Trailer is formatted and inserted!!
332 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
343 buffer->FillBuffer(data.Dig-offset);
347 buffer->FillBuffer(pTimeBin);
348 buffer->FillBuffer(bunchLength+2);
350 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
352 cout<<"Number of digits: "<<count<<endl;
357 /////////////////////////////////////////////////////////////////////////
358 void AliTPCDDLRawData::RawDataAltroDecode(Int_t LDCsNumber,Int_t Comp){
359 //This method merges the slides in only one file removing at the same
360 //time all the mini headers. The file so obtained must be Altro format
362 //It is used mainly in the debugging phase
367 sprintf(dest,"AltroDDLRecomposed.dat");
369 sprintf(dest,"AltroDDLRecomposedDec.dat");
373 fdest.open(dest,ios::binary);
378 //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector,flag=0;
379 for(Int_t i=1;i<=LDCsNumber;i++){
381 sprintf(filename,"TPCslice%d",i);
383 sprintf(filename,"TPCslice%d.decomp",i);
385 f.open(filename,ios::binary|ios::in);
387 f.open(filename,ios::in);
389 if(!f){cout<<"The file doesn't exist"<<endl;exit(1);}
390 //loop over the DDL block
391 //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
392 //The number of block is ceil(216/LDCsNumber)
393 ULong_t miniHeader[3];
394 //here the Mini Header is read
395 while( (f.read((char*)(miniHeader),sizeof(ULong_t)*3)) ){
396 //cout<<"Mini header dimension "<<miniHeader[0]<<endl;
399 for(ULong_t j=0;j<size;j++){
400 f.read((char*)(&car),1);
401 fdest.write((char*)(&car),1);