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