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;
58 f.open("AliTPCDDL.dat",ios::binary);
60 f.open("AliTPCDDL.dat");
62 if(!f){cout<<"File doesn't exist !!"<<endl;return;}
73 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
76 sprintf(filename,"TPCslice%d",sliceNumber);
77 cout<<" Creating "<<filename<<endl;
78 AliTPCBuffer160 *buffer=new AliTPCBuffer160(filename,1);
81 Int_t pSecNumber=-1; //Previous Sector number
82 Int_t pRowNumber=-1; //Previous Row number
83 Int_t pPadNumber=-1; //Previous Pad number
84 Int_t pTimeBin=-1; //Previous Time-Bin
85 Int_t pSubSector=-1; //Previous Sub Sector
90 while (f.read((char*)(&data),sizeof(data))){
97 pSubSector=data.SubSec;
98 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
99 buffer->WriteMiniHeader(0,pSecNumber,pSubSector,0,0);//Dummy;
101 buffer->FillBuffer(data.Dig-offset);
105 if ( (data.Time==(pTimeBin+1)) &&
106 (pPadNumber==data.Pad) &&
107 (pRowNumber==data.Row) &&
108 (pSecNumber==data.Sec)){
112 buffer->FillBuffer(pTimeBin);
113 buffer->FillBuffer(bunchLength+2);
115 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
116 //Trailer is formatted and inserted!!
117 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
121 if(pSubSector!=data.SubSec){
123 if(countDDL==ddlPerFile){
124 //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
126 buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
127 //cout<<"Mini header for DDL:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
130 sprintf(filename,"TPCslice%d",sliceNumber);
131 cout<<" Creating "<<filename<<endl;
132 buffer=new AliTPCBuffer160(filename,1);
133 buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
138 buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
139 buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
141 pSubSector=data.SubSec;
151 buffer->FillBuffer(data.Dig-offset);
155 buffer->FillBuffer(pTimeBin);
156 buffer->FillBuffer(bunchLength+2);
158 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
161 buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
162 //cout<<"Mini header for D D L:"<<pSecNumber<<" Sub-sec:"<<pSubSector<<endl;
164 cout<<"Number of digits: "<<count<<endl;
168 ////////////////////////////////////////////////////////////////////////////
169 ////////////////////////////////////////////////////////////////////////////
172 Int_t AliTPCDDLRawData::RawDataCompDecompress(Int_t LDCsNumber,Int_t Comp){
173 //This method is used to compress and decompress the slides
174 static const Int_t kNumTables=5;
179 //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector;
181 for(Int_t i=1;i<=LDCsNumber;i++){
183 sprintf(filename,"TPCslice%d",i);
184 sprintf(dest,"TPCslice%d.comp",i);
187 sprintf(filename,"TPCslice%d.comp",i);
188 sprintf(dest,"TPCslice%d.decomp",i);
191 f.open(filename,ios::binary|ios::in);
193 f.open(filename,ios::in);
195 if(!f){cout<<"File doesn't exist \n";exit(1);}
196 cout<<filename<<" "<<dest<<endl;
199 fdest.open(dest,ios::binary);
203 //loop over the DDL block
204 //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
205 //The number of block is ceil(216/LDCsNumber)
206 ULong_t miniHeader[3];
207 //here the Mini Header is read
208 while( (f.read((char*)(miniHeader),sizeof(ULong_t)*3)) ){
210 //Int_t dim=sizeof(ULong_t)+sizeof(Int_t)*5;
211 //cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" size "<<size<<endl;
212 //open the temporay File
214 char temp[15]="TempFile";
216 fo.open(temp,ios::binary);
221 for(ULong_t j=0;j<size;j++){
222 f.read((char*)(&car),1);
223 fo.write((char*)(&car),1);
226 //The temp file is compressed or decompressed
227 AliTPCCompression *util = new AliTPCCompression();
229 util->CompressDataOptTables(kNumTables,temp,"TempCompDecomp");
231 util->DecompressDataOptTables(kNumTables,temp,"TempCompDecomp");
233 //the temp compressed file is open and copied to the final file fdest
236 fi.open("TempCompDecomp",ios::binary);
238 fi.open("TempCompDecomp");
240 fi.seekg(0,ios::end);
243 //The Mini Header is updated (size and Compressed flag)
244 //and written into the output file
254 miniHeader[2]=miniHeader[2]&aux;
255 fdest.write((char*)(miniHeader),sizeof(ULong_t)*3);
256 //The compressem temp file is copied into the output file fdest
257 for(ULong_t j=0;j<size;j++){
258 fi.read((char*)(&car),1);
259 fdest.write((char*)(&car),1);
267 remove("TempCompDecomp");
272 /////////////////////////////////////////////////////////////////////////////////
273 void AliTPCDDLRawData::RawDataAltro()const{
274 //This method is used to build the Altro format from AliTPCDDL.dat
275 //It is used to debug the code and create the tables used in the compresseion phase
279 f.open("AliTPCDDL.dat",ios::binary);
281 f.open("AliTPCDDL.dat");
283 if(!f){cout<<"File doesn't exist !!"<<endl;return;}
294 //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
295 char filename[30]="AltroFormatDDL.dat";
296 cout<<" Creating "<<filename<<endl;
297 AliTPCBuffer160 *buffer=new AliTPCBuffer160(filename,1);
300 Int_t pSecNumber=-1; //Previous Sector number
301 Int_t pRowNumber=-1; //Previous Row number
302 Int_t pPadNumber=-1; //Previous Pad number
303 Int_t pTimeBin=-1; //Previous Time-Bin
306 ULong_t numPackets=0;
307 while (f.read((char*)(&data),sizeof(data))){
315 buffer->FillBuffer(data.Dig-offset);
319 if ( (data.Time==(pTimeBin+1)) &&
320 (pPadNumber==data.Pad) &&
321 (pRowNumber==data.Row) &&
322 (pSecNumber==data.Sec)){
326 buffer->FillBuffer(pTimeBin);
327 buffer->FillBuffer(bunchLength+2);
329 if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
330 //Trailer is formatted and inserted!!
331 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
342 buffer->FillBuffer(data.Dig-offset);
346 buffer->FillBuffer(pTimeBin);
347 buffer->FillBuffer(bunchLength+2);
349 buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
351 cout<<"Number of digits: "<<count<<endl;
356 /////////////////////////////////////////////////////////////////////////
357 void AliTPCDDLRawData::RawDataAltroDecode(Int_t LDCsNumber,Int_t Comp){
358 //This method merges the slides in only one file removing at the same
359 //time all the mini headers. The file so obtained must be Altro format
361 //It is used mainly in the debugging phase
366 sprintf(dest,"AltroDDLRecomposed.dat");
368 sprintf(dest,"AltroDDLRecomposedDec.dat");
372 fdest.open(dest,ios::binary);
377 //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector,flag=0;
378 for(Int_t i=1;i<=LDCsNumber;i++){
380 sprintf(filename,"TPCslice%d",i);
382 sprintf(filename,"TPCslice%d.decomp",i);
384 f.open(filename,ios::binary|ios::in);
386 f.open(filename,ios::in);
388 if(!f){cout<<"The file doesn't exist"<<endl;exit(1);}
389 //loop over the DDL block
390 //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
391 //The number of block is ceil(216/LDCsNumber)
392 ULong_t miniHeader[3];
393 //here the Mini Header is read
394 while( (f.read((char*)(miniHeader),sizeof(ULong_t)*3)) ){
395 //cout<<"Mini header dimension "<<miniHeader[0]<<endl;
398 for(ULong_t j=0;j<size;j++){
399 f.read((char*)(&car),1);
400 fdest.write((char*)(&car),1);