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 **************************************************************************/
17 //This class conteins all the methods to create raw data
19 //It produces DDL with both compressed and uncompressed format.
20 //For compression we use the optimized table wich needs
24 #include "TObjArray.h"
25 #include "Riostream.h"
28 #include "AliTPCCompression.h"
29 #include "AliTPCBuffer160.h"
30 #include "AliTPCDDLRawData.h"
32 ClassImp(AliTPCDDLRawData)
33 ////////////////////////////////////////////////////////////////////////////////////////
35 AliTPCDDLRawData::AliTPCDDLRawData(const AliTPCDDLRawData &source){
40 AliTPCDDLRawData& AliTPCDDLRawData::operator=(const AliTPCDDLRawData &source){
46 ////////////////////////////////////////////////////////////////////////////
47 void AliTPCDDLRawData::RawData(Int_t LDCsNumber){
48 //Raw data slides generation
49 //Number of DDL=2*36+4*36=216
50 //2 DDL for each inner sector
51 //4 DDL for each outer sector
52 Int_t ddlPerFile=216/LDCsNumber;
54 if (216%LDCsNumber) ddlPerFile++;
55 cout<<"Number of DDL per slide: "<<ddlPerFile<<endl;
57 f.open("AliTPCDDL.dat",ios::binary);
58 if(!f){cout<<"File doesn't exist !!"<<endl;return;}
69 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
72 sprintf(filename,"TPCslice%d",sliceNumber);
73 cout<<" Creating "<<filename<<endl;
74 AliTPCBuffer160 *buffer=new AliTPCBuffer160(filename,1);
77 Int_t pSecNumber=-1; //Previous Sector number
78 Int_t pRowNumber=-1; //Previous Row number
79 Int_t pPadNumber=-1; //Previous Pad number
80 Int_t pTimeBin=-1; //Previous Time-Bin
81 Int_t pSubSector=-1; //Previous Sub Sector
86 while (f.read((char*)(&data),sizeof(data))){
93 pSubSector=data.SubSec;
94 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
95 buffer->WriteMiniHeader(0,pSecNumber,pSubSector,0,0);//Dummy;
97 buffer->FillBuffer(data.Dig-offset);
101 if ( (data.Time==(pTimeBin+1)) &&
102 (pPadNumber==data.Pad) &&
103 (pRowNumber==data.Row) &&
104 (pSecNumber==data.Sec)){
108 buffer->FillBuffer(pTimeBin);
109 buffer->FillBuffer(bunchLength+2);
111 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
112 //Trailer is formatted and inserted!!
113 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
117 if(pSubSector!=data.SubSec){
119 if(countDDL==ddlPerFile){
120 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
122 buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
123 //cout<<"Mini header for DDL:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
126 sprintf(filename,"TPCslice%d",sliceNumber);
127 cout<<" Creating "<<filename<<endl;
128 buffer=new AliTPCBuffer160(filename,1);
129 buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
134 buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
135 buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
137 pSubSector=data.SubSec;
147 buffer->FillBuffer(data.Dig-offset);
151 buffer->FillBuffer(pTimeBin);
152 buffer->FillBuffer(bunchLength+2);
154 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
157 buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
158 //cout<<"Mini header for D D L:"<<pSecNumber<<" Sub-sec:"<<pSubSector<<endl;
160 cout<<"Number of digits: "<<count<<endl;
164 ////////////////////////////////////////////////////////////////////////////
165 ////////////////////////////////////////////////////////////////////////////
168 Int_t AliTPCDDLRawData::RawDataCompDecompress(Int_t LDCsNumber,Int_t Comp){
169 //This method is used to compress and decompress the slides
170 static const Int_t kNumTables=5;
175 //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector;
177 for(Int_t i=1;i<=LDCsNumber;i++){
179 sprintf(filename,"TPCslice%d",i);
180 sprintf(dest,"TPCslice%d.comp",i);
183 sprintf(filename,"TPCslice%d.comp",i);
184 sprintf(dest,"TPCslice%d.decomp",i);
186 f.open(filename,ios::binary|ios::in);
187 if(!f){cout<<"File doesn't exist \n";exit(1);}
188 cout<<filename<<" "<<dest<<endl;
190 fdest.open(dest,ios::binary);
191 //loop over the DDL block
192 //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
193 //The number of block is ceil(216/LDCsNumber)
194 ULong_t miniHeader[3];
195 //here the Mini Header is read
196 while( (f.read((char*)(miniHeader),sizeof(ULong_t)*3)) ){
198 //Int_t dim=sizeof(ULong_t)+sizeof(Int_t)*5;
199 //cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" size "<<size<<endl;
200 //open the temporay File
202 char temp[15]="TempFile";
203 fo.open(temp,ios::binary);
205 for(ULong_t j=0;j<size;j++){
206 f.read((char*)(&car),1);
207 fo.write((char*)(&car),1);
210 //The temp file is compressed or decompressed
211 AliTPCCompression *util = new AliTPCCompression();
213 util->CompressDataOptTables(kNumTables,temp,"TempCompDecomp");
215 util->DecompressDataOptTables(kNumTables,temp,"TempCompDecomp");
217 //the temp compressed file is open and copied to the final file fdest
219 fi.open("TempCompDecomp",ios::binary);
220 fi.seekg(0,ios::end);
223 //The Mini Header is updated (size and Compressed flag)
224 //and written into the output file
234 miniHeader[2]=miniHeader[2]&aux;
235 fdest.write((char*)(miniHeader),sizeof(ULong_t)*3);
236 //The compressem temp file is copied into the output file fdest
237 for(ULong_t j=0;j<size;j++){
238 fi.read((char*)(&car),1);
239 fdest.write((char*)(&car),1);
247 remove("TempCompDecomp");
252 /////////////////////////////////////////////////////////////////////////////////
253 void AliTPCDDLRawData::RawDataAltro()const{
254 //This method is used to build the Altro format from AliTPCDDL.dat
255 //It is used to debug the code and create the tables used in the compresseion phase
258 f.open("AliTPCDDL.dat",ios::binary);
259 if(!f){cout<<"File doesn't exist !!"<<endl;return;}
270 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
271 char filename[30]="AltroFormatDDL.dat";
272 cout<<" Creating "<<filename<<endl;
273 AliTPCBuffer160 *buffer=new AliTPCBuffer160(filename,1);
276 Int_t pSecNumber=-1; //Previous Sector number
277 Int_t pRowNumber=-1; //Previous Row number
278 Int_t pPadNumber=-1; //Previous Pad number
279 Int_t pTimeBin=-1; //Previous Time-Bin
282 ULong_t numPackets=0;
283 while (f.read((char*)(&data),sizeof(data))){
291 buffer->FillBuffer(data.Dig-offset);
295 if ( (data.Time==(pTimeBin+1)) &&
296 (pPadNumber==data.Pad) &&
297 (pRowNumber==data.Row) &&
298 (pSecNumber==data.Sec)){
302 buffer->FillBuffer(pTimeBin);
303 buffer->FillBuffer(bunchLength+2);
305 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
306 //Trailer is formatted and inserted!!
307 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
318 buffer->FillBuffer(data.Dig-offset);
322 buffer->FillBuffer(pTimeBin);
323 buffer->FillBuffer(bunchLength+2);
325 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
327 cout<<"Number of digits: "<<count<<endl;
332 /////////////////////////////////////////////////////////////////////////
333 void AliTPCDDLRawData::RawDataAltroDecode(Int_t LDCsNumber,Int_t Comp){
334 //This method merges the slides in only one file removing at the same
335 //time all the mini headers. The file so obtained must be Altro format
337 //It is used mainly in the debugging phase
342 sprintf(dest,"AltroDDLRecomposed.dat");
344 sprintf(dest,"AltroDDLRecomposedDec.dat");
347 fdest.open(dest,ios::binary);
349 //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector,flag=0;
350 for(Int_t i=1;i<=LDCsNumber;i++){
352 sprintf(filename,"TPCslice%d",i);
354 sprintf(filename,"TPCslice%d.decomp",i);
355 f.open(filename,ios::binary|ios::in);
356 if(!f){cout<<"The file doesn't exist"<<endl;exit(1);}
357 //loop over the DDL block
358 //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
359 //The number of block is ceil(216/LDCsNumber)
360 ULong_t miniHeader[3];
361 //here the Mini Header is read
362 while( (f.read((char*)(miniHeader),sizeof(ULong_t)*3)) ){
363 //cout<<"Mini header dimension "<<miniHeader[0]<<endl;
366 for(ULong_t j=0;j<size;j++){
367 f.read((char*)(&car),1);
368 fdest.write((char*)(&car),1);