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