No ios::binary on Alpha with cxx
[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 //This class conteins all the methods to create raw data 
18 //as par a given DDL.
19 //It produces DDL with both compressed and uncompressed format.
20 //For compression we use the optimized table wich needs 
21 //to be provided.
22
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   return;
38 }
39
40 AliTPCDDLRawData& AliTPCDDLRawData::operator=(const AliTPCDDLRawData &source){
41   //Assigment operator
42   return *this;
43 }
44
45
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;
53   Int_t offset=1;
54   if (216%LDCsNumber) ddlPerFile++;
55   cout<<"Number of DDL per slide: "<<ddlPerFile<<endl;
56   ifstream f;
57 #ifndef __DECCXX
58   f.open("AliTPCDDL.dat",ios::binary);
59 #else
60   f.open("AliTPCDDL.dat");
61 #endif
62   if(!f){cout<<"File doesn't exist !!"<<endl;return;}
63   struct DataPad{
64     Int_t Sec;
65     Int_t SubSec;
66     Int_t Row;
67     Int_t Pad;
68     Int_t Dig;
69     Int_t Time;
70   };
71   DataPad data;
72
73   //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
74   Int_t sliceNumber=1;
75   char  filename[15];
76   sprintf(filename,"TPCslice%d",sliceNumber); 
77   cout<<"   Creating "<<filename<<endl;
78   AliTPCBuffer160 *buffer=new AliTPCBuffer160(filename,1);
79
80   ULong_t count=0;
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
86   Int_t bunchLength=0;
87   Int_t countDDL=0;
88   Int_t nwords=0;
89   ULong_t numPackets=0;
90   while (f.read((char*)(&data),sizeof(data))){
91     count++;
92     if (pPadNumber==-1){
93       pSecNumber=data.Sec;
94       pRowNumber=data.Row;
95       pPadNumber=data.Pad;
96       pTimeBin=data.Time;
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;
100       bunchLength=1;
101       buffer->FillBuffer(data.Dig-offset);
102       nwords++;
103     }//end if
104     else{
105       if ( (data.Time==(pTimeBin+1)) &&
106            (pPadNumber==data.Pad) &&
107            (pRowNumber==data.Row) &&
108            (pSecNumber==data.Sec)){
109         bunchLength++;
110       }//end if
111       else{
112         buffer->FillBuffer(pTimeBin);
113         buffer->FillBuffer(bunchLength+2);
114         nwords+=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);
118           numPackets++;
119           nwords=0;
120
121           if(pSubSector!=data.SubSec){
122             countDDL++;
123             if(countDDL==ddlPerFile){
124               //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
125               buffer->Flush();
126               buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
127               //cout<<"Mini header for DDL:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
128               delete buffer;
129               sliceNumber++;
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;
134               countDDL=0;
135             }//end if
136             else{
137               buffer->Flush();
138               buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
139               buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
140             }
141             pSubSector=data.SubSec;
142           }//end if
143         }//end if
144         
145         bunchLength=1;
146         pPadNumber=data.Pad;
147         pRowNumber=data.Row;
148         pSecNumber=data.Sec;
149       }//end else
150       pTimeBin=data.Time;
151       buffer->FillBuffer(data.Dig-offset);
152       nwords++;
153     }//end else
154   }//end while
155   buffer->FillBuffer(pTimeBin);
156   buffer->FillBuffer(bunchLength+2);
157   nwords+=2;
158   buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
159   //write the  M.H.
160   buffer->Flush();
161   buffer->WriteMiniHeader(1,pSecNumber,pSubSector,0,0);
162   //cout<<"Mini header for D D L:"<<pSecNumber<<" Sub-sec:"<<pSubSector<<endl;
163   delete buffer;
164   cout<<"Number of digits: "<<count<<endl;
165   f.close();
166   return;
167 }
168 ////////////////////////////////////////////////////////////////////////////
169 ////////////////////////////////////////////////////////////////////////////
170
171
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;
175   char filename[20];
176   char dest[20];
177   fstream f;
178   ULong_t size=0;
179   //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector;
180   Int_t flag=0;
181   for(Int_t i=1;i<=LDCsNumber;i++){
182     if(!Comp){
183       sprintf(filename,"TPCslice%d",i);
184       sprintf(dest,"TPCslice%d.comp",i);
185     }
186     else{
187       sprintf(filename,"TPCslice%d.comp",i);
188       sprintf(dest,"TPCslice%d.decomp",i);
189     }
190 #ifndef __DECCXX
191     f.open(filename,ios::binary|ios::in);
192 #else
193     f.open(filename,ios::in);
194 #endif
195     if(!f){cout<<"File doesn't exist \n";exit(1);}
196     cout<<filename<<"  "<<dest<<endl;
197     ofstream fdest;
198 #ifndef __DECCXX
199     fdest.open(dest,ios::binary);
200 #else
201     fdest.open(dest);
202 #endif
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)) ){
209       size=miniHeader[0];
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
213       ofstream fo;
214       char temp[15]="TempFile";
215 #ifndef __DECCXX
216       fo.open(temp,ios::binary);
217 #else
218       fo.open(temp);
219 #endif
220       Int_t car=0;
221       for(ULong_t j=0;j<size;j++){
222         f.read((char*)(&car),1);
223         fo.write((char*)(&car),1);
224       }//end for
225       fo.close();
226       //The temp file is compressed or decompressed
227       AliTPCCompression *util = new AliTPCCompression();
228       if(!Comp)
229         util->CompressDataOptTables(kNumTables,temp,"TempCompDecomp");
230       else
231         util->DecompressDataOptTables(kNumTables,temp,"TempCompDecomp");
232       delete util;
233       //the temp compressed file is open and copied to the final file fdest
234       ifstream fi;
235 #ifndef __DECCXX
236       fi.open("TempCompDecomp",ios::binary);
237 #else
238       fi.open("TempCompDecomp");
239 #endif
240       fi.seekg(0,ios::end);
241       size=fi.tellg();
242       fi.seekg(0);
243       //The Mini Header is updated (size and Compressed flag) 
244       //and written into the output file
245       miniHeader[0]=size;
246       if(!Comp)
247         flag=1;
248       else
249         flag=0;
250       ULong_t aux=0xFFFF;
251       aux<<=16;
252       aux|=flag;
253       aux|=0xFF;
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);
260       }//end for
261       fi.close();
262     }//end while
263     f.clear();
264     f.close();
265     fdest.close();
266     remove("TempFile");
267     remove("TempCompDecomp");
268   }//end for
269   return 0;
270 }
271
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
276   Int_t offset=1;
277   ifstream f;
278 #ifndef __DECCXX
279   f.open("AliTPCDDL.dat",ios::binary);
280 #else
281   f.open("AliTPCDDL.dat");
282 #endif
283   if(!f){cout<<"File doesn't exist !!"<<endl;return;}
284   struct DataPad{
285     Int_t Sec;
286     Int_t SubSec;
287     Int_t Row;
288     Int_t Pad;
289     Int_t Dig;
290     Int_t Time;
291   };
292   DataPad data;
293
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);
298
299   ULong_t count=0;
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
304   Int_t bunchLength=0;
305   Int_t nwords=0;
306   ULong_t numPackets=0;
307   while (f.read((char*)(&data),sizeof(data))){
308     count++;
309     if (pPadNumber==-1){
310       pSecNumber=data.Sec;
311       pRowNumber=data.Row;
312       pPadNumber=data.Pad;
313       pTimeBin=data.Time;
314       bunchLength=1;
315       buffer->FillBuffer(data.Dig-offset);
316       nwords++;
317     }//end if
318     else{
319       if ( (data.Time==(pTimeBin+1)) &&
320            (pPadNumber==data.Pad) &&
321            (pRowNumber==data.Row) &&
322            (pSecNumber==data.Sec)){
323         bunchLength++;
324       }//end if
325       else{
326         buffer->FillBuffer(pTimeBin);
327         buffer->FillBuffer(bunchLength+2);
328         nwords+=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);
332           numPackets++;
333           nwords=0;
334         }//end if
335         
336         bunchLength=1;
337         pPadNumber=data.Pad;
338         pRowNumber=data.Row;
339         pSecNumber=data.Sec;
340       }//end else
341       pTimeBin=data.Time;
342       buffer->FillBuffer(data.Dig-offset);
343       nwords++;
344     }//end else
345   }//end while
346   buffer->FillBuffer(pTimeBin);
347   buffer->FillBuffer(bunchLength+2);
348   nwords+=2;
349   buffer->WriteTrailer(nwords,pPadNumber,pRowNumber,pSecNumber);
350   delete buffer;
351   cout<<"Number of digits: "<<count<<endl;
352   f.close(); 
353   return;
354 }
355
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
360   //complaiant.
361   //It is used mainly in the debugging phase 
362   char filename[15];
363   char dest[30];
364   fstream f;
365   if(!Comp)
366     sprintf(dest,"AltroDDLRecomposed.dat");
367   else
368     sprintf(dest,"AltroDDLRecomposedDec.dat");
369   ofstream fdest;
370
371 #ifndef __DECCXX
372   fdest.open(dest,ios::binary);
373 #else
374   fdest.open(dest);
375 #endif
376   ULong_t size=0;
377   //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector,flag=0;
378   for(Int_t i=1;i<=LDCsNumber;i++){
379     if(!Comp)
380       sprintf(filename,"TPCslice%d",i);  
381     else
382       sprintf(filename,"TPCslice%d.decomp",i);  
383 #ifndef __DECCXX
384     f.open(filename,ios::binary|ios::in);
385 #else
386     f.open(filename,ios::in);
387 #endif
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;
396       Int_t car=0;
397       size=miniHeader[0];
398       for(ULong_t j=0;j<size;j++){
399         f.read((char*)(&car),1);
400         fdest.write((char*)(&car),1);
401       }//end for
402     }//end while
403     f.clear();
404     f.close();
405   }//end for
406   fdest.close();
407   return;
408 }
409