Updated version of raw data code (D.Favretto)
[u/mrichter/AliRoot.git] / TPC / AliTPCDDLRawData.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15 /* $Id$ */
16
17
18 //This class conteins all the methods to create raw data 
19 //as par a given DDL.
20 //It produces DDL with both compressed and uncompressed format.
21 //For compression we use the optimized table wich needs 
22 //to be provided.
23
24
25 #include "TObjArray.h"
26 #include "Riostream.h"
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include "AliTPCCompression.h"
30 #include "AliTPCBuffer160.h"
31 #include "AliTPCDDLRawData.h"
32
33 ClassImp(AliTPCDDLRawData)
34 ////////////////////////////////////////////////////////////////////////////////////////
35
36 AliTPCDDLRawData::AliTPCDDLRawData(const AliTPCDDLRawData &source){
37   // Copy Constructor
38   fVerbose=source.fVerbose;
39   return;
40 }
41
42 AliTPCDDLRawData& AliTPCDDLRawData::operator=(const AliTPCDDLRawData &source){
43   //Assigment operator
44   fVerbose=source.fVerbose;
45   return *this;
46 }
47
48
49 ////////////////////////////////////////////////////////////////////////////
50 void AliTPCDDLRawData::RawData(Int_t LDCsNumber){
51   //Raw data slides generation
52   //Number of DDL=2*36+4*36=216
53   //2 DDL for each inner sector
54   //4 DDL for each outer sector
55   Int_t ddlPerFile=216/LDCsNumber;
56   Int_t offset=1;
57   if (216%LDCsNumber) ddlPerFile++;
58   cout<<"Number of DDL per slide: "<<ddlPerFile<<endl;
59   ifstream f;
60 #ifndef __DECCXX
61   f.open("AliTPCDDL.dat",ios::binary);
62 #else
63   f.open("AliTPCDDL.dat");
64 #endif
65   if(!f){cout<<"File doesn't exist !!"<<endl;return;}
66   struct DataPad{
67     Int_t Sec;
68     Int_t SubSec;
69     Int_t Row;
70     Int_t Pad;
71     Int_t Dig;
72     Int_t Time;
73   };
74   DataPad data;
75
76   //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
77   Int_t sliceNumber=1;
78   char  filename[15];
79   sprintf(filename,"TPCslice%d",sliceNumber); 
80   cout<<"   Creating "<<filename<<endl;
81   AliTPCBuffer160 *buffer=new AliTPCBuffer160(filename,1);
82
83   ULong_t count=0;
84   Int_t pSecNumber=-1;  //Previous Sector number
85   Int_t pRowNumber=-1;  //Previous Row number  
86   Int_t pPadNumber=-1;  //Previous Pad number
87   Int_t pTimeBin=-1;    //Previous Time-Bin
88   Int_t pSubSector=-1;  //Previous Sub Sector
89   Int_t bunchLength=0;
90   Int_t countDDL=0;
91   Int_t nwords=0;
92   ULong_t numPackets=0;
93   while (f.read((char*)(&data),sizeof(data))){
94     count++;
95     if (pPadNumber==-1){
96       pSecNumber=data.Sec;
97       pRowNumber=data.Row;
98       pPadNumber=data.Pad;
99       pTimeBin=data.Time;
100       pSubSector=data.SubSec;
101       //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
102       buffer->WriteMiniHeader(0,pSecNumber,pSubSector,0,0);//Dummy;
103       bunchLength=1;
104       buffer->FillBuffer(data.Dig-offset);
105       nwords++;
106     }//end if
107     else{
108       if ( (data.Time==(pTimeBin+1)) &&
109            (pPadNumber==data.Pad) &&
110            (pRowNumber==data.Row) &&
111            (pSecNumber==data.Sec)){
112         bunchLength++;
113       }//end if
114       else{
115         buffer->FillBuffer(pTimeBin);
116         buffer->FillBuffer(bunchLength+2);
117         nwords+=2;
118         if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
119           //Trailer is formatted and inserted!!
120           buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
121           numPackets++;
122           nwords=0;
123
124           if(pSubSector!=data.SubSec){
125             countDDL++;
126             if(countDDL==ddlPerFile){
127               //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
128               buffer->Flush();
129               buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
130               //cout<<"Mini header for DDL:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
131               delete buffer;
132               sliceNumber++;
133               sprintf(filename,"TPCslice%d",sliceNumber);
134               cout<<"   Creating "<<filename<<endl;
135               buffer=new AliTPCBuffer160(filename,1);
136               buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
137               countDDL=0;
138             }//end if
139             else{
140               buffer->Flush();
141               buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
142               buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
143             }
144             pSubSector=data.SubSec;
145           }//end if
146         }//end if
147         
148         bunchLength=1;
149         pPadNumber=data.Pad;
150         pRowNumber=data.Row;
151         pSecNumber=data.Sec;
152       }//end else
153       pTimeBin=data.Time;
154       buffer->FillBuffer(data.Dig-offset);
155       nwords++;
156     }//end else
157   }//end while
158   buffer->FillBuffer(pTimeBin);
159   buffer->FillBuffer(bunchLength+2);
160   nwords+=2;
161   buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
162   //write the  M.H.
163   buffer->Flush();
164   buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
165   //cout<<"Mini header for D D L:"<<pSecNumber<<" Sub-sec:"<<pSubSector<<endl;
166   delete buffer;
167   cout<<"Number of digits: "<<count<<endl;
168   f.close();
169   return;
170 }
171 ////////////////////////////////////////////////////////////////////////////
172 ////////////////////////////////////////////////////////////////////////////
173
174
175 Int_t AliTPCDDLRawData::RawDataCompDecompress(Int_t LDCsNumber,Int_t Comp){
176   //This method is used to compress and decompress the slides
177   static const Int_t kNumTables=5;
178   char filename[20];
179   char dest[20];
180   fstream f;
181   ULong_t size=0;
182   //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector;
183   Int_t flag=0;
184   for(Int_t i=1;i<=LDCsNumber;i++){
185     if(!Comp){
186       sprintf(filename,"TPCslice%d",i);
187       sprintf(dest,"TPCslice%d.comp",i);
188     }
189     else{
190       sprintf(filename,"TPCslice%d.comp",i);
191       sprintf(dest,"TPCslice%d.decomp",i);
192     }
193 #ifndef __DECCXX
194     f.open(filename,ios::binary|ios::in);
195 #else
196     f.open(filename,ios::in);
197 #endif
198     if(!f){cout<<"BE CAREFUL!! There isn't enough data to generate "<<LDCsNumber<<" slices"<<endl;break;}
199     cout<<filename<<"  "<<dest<<endl;
200     ofstream fdest;
201 #ifndef __DECCXX
202     fdest.open(dest,ios::binary);
203 #else
204     fdest.open(dest);
205 #endif
206     //loop over the DDL block 
207     //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
208     //The number of block is ceil(216/LDCsNumber)
209     ULong_t miniHeader[3];
210     //here the Mini Header is read
211     while( (f.read((char*)(miniHeader),sizeof(ULong_t)*3)) ){
212       size=miniHeader[0];
213       // cout<<"Data size:"<<size<<endl;
214       //Int_t dim=sizeof(ULong_t)+sizeof(Int_t)*5;
215       //cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" size "<<size<<endl;
216       //open the temporay File
217       ofstream fo;
218       char temp[15]="TempFile";
219 #ifndef __DECCXX
220       fo.open(temp,ios::binary);
221 #else
222       fo.open(temp);
223 #endif
224       Int_t car=0;
225       for(ULong_t j=0;j<size;j++){
226         f.read((char*)(&car),1);
227         fo.write((char*)(&car),1);
228       }//end for
229       fo.close();
230       //The temp file is compressed or decompressed
231       AliTPCCompression *util = new AliTPCCompression();
232       util->SetVerbose(0);
233       if(!Comp){
234         util->CompressDataOptTables(kNumTables,temp,"TempCompDecomp");
235       }
236       else
237         util->DecompressDataOptTables(kNumTables,temp,"TempCompDecomp");
238       delete util;
239       //the temp compressed file is open and copied to the final file fdest
240       ifstream fi;
241 #ifndef __DECCXX
242       fi.open("TempCompDecomp",ios::binary);
243 #else
244       fi.open("TempCompDecomp");
245 #endif
246       fi.seekg(0,ios::end);
247       size=fi.tellg();
248       fi.seekg(0);
249       //The Mini Header is updated (size and Compressed flag) 
250       //and written into the output file
251       miniHeader[0]=size;
252       if(!Comp)
253         flag=1;
254       else
255         flag=0;
256       ULong_t aux=0x0;
257       flag<<=8;
258       aux|=flag;
259       miniHeader[2]=miniHeader[2]|aux;
260       fdest.write((char*)(miniHeader),sizeof(ULong_t)*3);
261       //The compressem temp file is copied into the output file fdest
262       for(ULong_t j=0;j<size;j++){
263         fi.read((char*)(&car),1);
264         fdest.write((char*)(&car),1);
265       }//end for
266       fi.close();
267     }//end while
268     f.clear();
269     f.close();
270     fdest.close();
271     remove("TempFile");
272     remove("TempCompDecomp");
273   }//end for
274   return 0;
275 }
276
277 /////////////////////////////////////////////////////////////////////////////////
278 void AliTPCDDLRawData::RawDataAltro()const{
279   //This method is used to build the Altro format from AliTPCDDL.dat
280   //It is used to debug the code and creates the tables used in the compresseion phase
281   Int_t offset=1;
282   ifstream f;
283 #ifndef __DECCXX
284   f.open("AliTPCDDL.dat",ios::binary);
285 #else
286   f.open("AliTPCDDL.dat");
287 #endif
288   if(!f){cout<<"File doesn't exist !!"<<endl;return;}
289   struct DataPad{
290     Int_t Sec;
291     Int_t SubSec;
292     Int_t Row;
293     Int_t Pad;
294     Int_t Dig;
295     Int_t Time;
296   };
297   DataPad data;
298
299   //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
300   char  filename[30]="AltroFormatDDL.dat";
301   cout<<"   Creating "<<filename<<endl;
302   AliTPCBuffer160 *buffer=new AliTPCBuffer160(filename,1);
303
304   ULong_t count=0;
305   Int_t pSecNumber=-1;  //Previous Sector number
306   Int_t pRowNumber=-1;  //Previous Row number  
307   Int_t pPadNumber=-1;  //Previous Pad number
308   Int_t pTimeBin=-1;    //Previous Time-Bin
309   Int_t bunchLength=0;
310   Int_t nwords=0;
311   ULong_t numPackets=0;
312   while (f.read((char*)(&data),sizeof(data))){
313     count++;
314     if (pPadNumber==-1){
315       pSecNumber=data.Sec;
316       pRowNumber=data.Row;
317       pPadNumber=data.Pad;
318       pTimeBin=data.Time;
319       bunchLength=1;
320       buffer->FillBuffer(data.Dig-offset);
321       nwords++;
322     }//end if
323     else{
324       if ( (data.Time==(pTimeBin+1)) &&
325            (pPadNumber==data.Pad) &&
326            (pRowNumber==data.Row) &&
327            (pSecNumber==data.Sec)){
328         bunchLength++;
329       }//end if
330       else{
331         buffer->FillBuffer(pTimeBin);
332         buffer->FillBuffer(bunchLength+2);
333         nwords+=2;
334         if ((pPadNumber!=data.Pad)||(pRowNumber!=data.Row)||(pSecNumber!=data.Sec)){
335           //Trailer is formatted and inserted!!
336           buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
337           numPackets++;
338           nwords=0;
339         }//end if
340         
341         bunchLength=1;
342         pPadNumber=data.Pad;
343         pRowNumber=data.Row;
344         pSecNumber=data.Sec;
345       }//end else
346       pTimeBin=data.Time;
347       buffer->FillBuffer(data.Dig-offset);
348       nwords++;
349     }//end else
350   }//end while
351   buffer->FillBuffer(pTimeBin);
352   buffer->FillBuffer(bunchLength+2);
353   nwords+=2;
354   buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
355   delete buffer;
356   cout<<"Number of digits: "<<count<<endl;
357   f.close(); 
358   return;
359 }
360
361 /////////////////////////////////////////////////////////////////////////
362 void AliTPCDDLRawData::RawDataAltroDecode(Int_t LDCsNumber,Int_t Comp){
363   //This method merges the slides in only one file removing at the same 
364   //time all the mini headers. The file so obtained must be Altro format
365   //complaiant.
366   //It is used mainly in the debugging phase 
367   char filename[15];
368   char dest[30];
369   fstream f;
370   if(!Comp)
371     sprintf(dest,"AltroDDLRecomposed.dat");
372   else
373     sprintf(dest,"AltroDDLRecomposedDec.dat");
374   ofstream fdest;
375
376 #ifndef __DECCXX
377   fdest.open(dest,ios::binary);
378 #else
379   fdest.open(dest);
380 #endif
381   ULong_t size=0;
382   //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector,flag=0;
383   for(Int_t i=1;i<=LDCsNumber;i++){
384     if(!Comp)
385       sprintf(filename,"TPCslice%d",i);  
386     else
387       sprintf(filename,"TPCslice%d.decomp",i);  
388 #ifndef __DECCXX
389     f.open(filename,ios::binary|ios::in);
390 #else
391     f.open(filename,ios::in);
392 #endif
393     if(!f){cout<<"BE CAREFUL!! There isn't enough data to generate "<<LDCsNumber<<" slices"<<endl;break;}
394     //loop over the DDL block 
395     //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
396     //The number of block is ceil(216/LDCsNumber)
397     ULong_t miniHeader[3];
398     //here the Mini Header is read
399     //cout<<filename<<endl;
400     while( (f.read((char*)(miniHeader),sizeof(ULong_t)*3)) ){
401       Int_t car=0;
402       size=miniHeader[0];
403       for(ULong_t j=0;j<size;j++){
404         f.read((char*)(&car),1);
405         fdest.write((char*)(&car),1);
406       }//end for
407     }//end while
408     f.clear();
409     f.close();
410   }//end for
411   fdest.close();
412   return;
413 }
414