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