ITS/AliITSDDLRawData.cxx (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
16 #include "TObjArray.h"
17 #include "Riostream.h"
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include "AliTPCCompression.h"
21 #include "AliTPCBuffer160.h"
22 #include "AliTPCDDLRawData.h"
23
24 ClassImp(AliTPCDDLRawData)
25 ////////////////////////////////////////////////////////////////////////////////////////
26
27 AliTPCDDLRawData::AliTPCDDLRawData(const AliTPCDDLRawData &source){
28   // Copy Constructor
29   return;
30 }
31
32 AliTPCDDLRawData& AliTPCDDLRawData::operator=(const AliTPCDDLRawData &source){
33   //Assigment operator
34   return *this;
35 }
36
37
38 ////////////////////////////////////////////////////////////////////////////
39 void AliTPCDDLRawData::RawData(Int_t LDCsNumber){
40   //Number of DDL=2*36+4*36=216
41   //2 DDL for each inner sector
42   //4 DDL for each outer sector
43   Int_t DDLPerFile=216/LDCsNumber;
44   Int_t offset=1;
45   if (216%LDCsNumber) DDLPerFile++;
46   cout<<"Number of DDL per slide: "<<DDLPerFile<<endl;
47   ifstream f;
48   f.open("AliTPCDDL.dat",ios::binary);
49   if(!f){cout<<"File doesn't exist !!"<<endl;return;}
50   struct DataPad{
51     Int_t Sec;
52     Int_t SubSec;
53     Int_t Row;
54     Int_t Pad;
55     Int_t Dig;
56     Int_t Time;
57   };
58   DataPad data;
59
60   //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
61   Int_t SliceNumber=1;
62   char  filename[15];
63   sprintf(filename,"TPCslice%d",SliceNumber); 
64   cout<<"   Creating "<<filename<<endl;
65   AliTPCBuffer160 *Buffer=new AliTPCBuffer160(filename,1);
66
67   ULong_t Count=0;
68   Int_t PSecNumber=-1;  //Previous Sector number
69   Int_t PRowNumber=-1;  //Previous Row number  
70   Int_t PPadNumber=-1;  //Previous Pad number
71   Int_t PTimeBin=-1;    //Previous Time-Bin
72   Int_t PSubSector=-1;  //Previous Sub Sector
73   Int_t BunchLength=0;
74   Int_t CountDDL=0;
75   Int_t nwords=0;
76   ULong_t numPackets=0;
77   while (f.read((char*)(&data),sizeof(data))){
78     Count++;
79     if (PPadNumber==-1){
80       PSecNumber=data.Sec;
81       PRowNumber=data.Row;
82       PPadNumber=data.Pad;
83       PTimeBin=data.Time;
84       PSubSector=data.SubSec;
85       //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
86       Buffer->WriteMiniHeader(0,PSecNumber,PSubSector,0,0);//Dummy;
87       BunchLength=1;
88       Buffer->FillBuffer(data.Dig-offset);
89       nwords++;
90     }//end if
91     else{
92       if ( (data.Time==(PTimeBin+1)) &&
93            (PPadNumber==data.Pad) &&
94            (PRowNumber==data.Row) &&
95            (PSecNumber==data.Sec)){
96         BunchLength++;
97       }//end if
98       else{
99         Buffer->FillBuffer(PTimeBin);
100         Buffer->FillBuffer(BunchLength+2);
101         nwords+=2;
102         if ((PPadNumber!=data.Pad)||(PRowNumber!=data.Row)||(PSecNumber!=data.Sec)){
103           //Trailer is formatted and inserted!!
104           Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
105           numPackets++;
106           nwords=0;
107
108           if(PSubSector!=data.SubSec){
109             CountDDL++;
110             if(CountDDL==DDLPerFile){
111               //size magic word sector number sub-sector number 0 for TPC 0 for uncompressed
112               Buffer->Flush();
113               Buffer->WriteMiniHeader(1,PSecNumber,PSubSector,0,0);
114               //cout<<"Mini header for DDL:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
115               delete Buffer;
116               SliceNumber++;
117               sprintf(filename,"TPCslice%d",SliceNumber);
118               cout<<"   Creating "<<filename<<endl;
119               Buffer=new AliTPCBuffer160(filename,1);
120               Buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
121               CountDDL=0;
122             }//end if
123             else{
124               Buffer->Flush();
125               Buffer->WriteMiniHeader(1,PSecNumber,PSubSector,0,0);
126               Buffer->WriteMiniHeader(0,data.Sec,data.SubSec,0,0);//Dummy;
127             }
128             PSubSector=data.SubSec;
129           }//end if
130         }//end if
131         
132         BunchLength=1;
133         PPadNumber=data.Pad;
134         PRowNumber=data.Row;
135         PSecNumber=data.Sec;
136       }//end else
137       PTimeBin=data.Time;
138       Buffer->FillBuffer(data.Dig-offset);
139       nwords++;
140     }//end else
141   }//end while
142   Buffer->FillBuffer(PTimeBin);
143   Buffer->FillBuffer(BunchLength+2);
144   nwords+=2;
145   Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
146   //write the  M.H.
147   Buffer->Flush();
148   Buffer->WriteMiniHeader(1,PSecNumber,PSubSector,0,0);
149   //cout<<"Mini header for D D L:"<<PSecNumber<<" Sub-sec:"<<PSubSector<<endl;
150   delete Buffer;
151   cout<<"Number of digits: "<<Count<<endl;
152   f.close();
153   return;
154 }
155 ////////////////////////////////////////////////////////////////////////////
156 ////////////////////////////////////////////////////////////////////////////
157 //This method is used to Compress and decompress the slides
158
159 Int_t AliTPCDDLRawData::RawDataCompDecompress(Int_t LDCsNumber,Int_t Comp){
160   static const Int_t NumTable=5;
161   char filename[20];
162   char dest[20];
163   fstream f;
164   ULong_t Size=0;
165   //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector;
166   Int_t Flag=0;
167   for(Int_t i=1;i<=LDCsNumber;i++){
168     if(!Comp){
169       sprintf(filename,"TPCslice%d",i);
170       sprintf(dest,"TPCslice%d.comp",i);
171     }
172     else{
173       sprintf(filename,"TPCslice%d.comp",i);
174       sprintf(dest,"TPCslice%d.decomp",i);
175     }
176     f.open(filename,ios::binary|ios::in);
177     if(!f){cout<<"File doesn't exist \n";exit(1);}
178     cout<<filename<<"  "<<dest<<endl;
179     ofstream fdest;
180     fdest.open(dest,ios::binary);
181     //loop over the DDL block 
182     //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
183     //The number of block is ceil(216/LDCsNumber)
184     ULong_t MiniHeader[3];
185     //here the Mini Header is read
186     while( (f.read((char*)(MiniHeader),sizeof(ULong_t)*3)) ){
187       Size=MiniHeader[0];
188       //Int_t dim=sizeof(ULong_t)+sizeof(Int_t)*5;
189       //cout<<" Sec "<<SecNumber<<" SubSector "<<SubSector<<" Size "<<Size<<endl;
190       //open the temporay File
191       ofstream fo;
192       char temp[15]="TempFile";
193       fo.open(temp,ios::binary);
194       Int_t car=0;
195       for(ULong_t j=0;j<Size;j++){
196         f.read((char*)(&car),1);
197         fo.write((char*)(&car),1);
198       }//end for
199       fo.close();
200       //The temp file is compressed or decompressed
201       AliTPCCompression *util = new AliTPCCompression();
202       if(!Comp)
203         util->CompressDataOptTables(NumTable,temp,"TempCompDecomp");
204       else
205         util->DecompressDataOptTables(NumTable,temp,"TempCompDecomp");
206       delete util;
207       //the temp compressed file is open and copied to the final file fdest
208       ifstream fi;
209       fi.open("TempCompDecomp",ios::binary);
210       fi.seekg(0,ios::end);
211       Size=fi.tellg();
212       fi.seekg(0);
213       //The Mini Header is updated (Size and Compressed flag) 
214       //and written into the output file
215       MiniHeader[0]=Size;
216       if(!Comp)
217         Flag=1;
218       else
219         Flag=0;
220       ULong_t aux=0xFFFF;
221       aux<<=16;
222       aux|=Flag;
223       aux|=0xFF;
224       MiniHeader[2]=MiniHeader[2]&aux;
225       fdest.write((char*)(MiniHeader),sizeof(ULong_t)*3);
226       //The compressem temp file is copied into the output file fdest
227       for(ULong_t j=0;j<Size;j++){
228         fi.read((char*)(&car),1);
229         fdest.write((char*)(&car),1);
230       }//end for
231       fi.close();
232     }//end while
233     f.clear();
234     f.close();
235     fdest.close();
236     remove("TempFile");
237     remove("TempCompDecomp");
238   }//end for
239   return 0;
240 }
241
242 /////////////////////////////////////////////////////////////////////////////////
243 //This method is used to build the Altro format from AliTPCDDL.dat
244 //It is used to debug the code and create the tables used in the compresseion phase
245 void AliTPCDDLRawData::RawDataAltro(){
246   Int_t offset=1;
247   ifstream f;
248   f.open("AliTPCDDL.dat",ios::binary);
249   if(!f){cout<<"File doesn't exist !!"<<endl;return;}
250   struct DataPad{
251     Int_t Sec;
252     Int_t SubSec;
253     Int_t Row;
254     Int_t Pad;
255     Int_t Dig;
256     Int_t Time;
257   };
258   DataPad data;
259
260   //AliTPCBuffer160 is used in write mode to generate AltroFormat.dat file
261   char  filename[30]="AltroFormatDDL.dat";
262   cout<<"   Creating "<<filename<<endl;
263   AliTPCBuffer160 *Buffer=new AliTPCBuffer160(filename,1);
264
265   ULong_t Count=0;
266   Int_t PSecNumber=-1;  //Previous Sector number
267   Int_t PRowNumber=-1;  //Previous Row number  
268   Int_t PPadNumber=-1;  //Previous Pad number
269   Int_t PTimeBin=-1;    //Previous Time-Bin
270   Int_t BunchLength=0;
271   Int_t nwords=0;
272   ULong_t numPackets=0;
273   while (f.read((char*)(&data),sizeof(data))){
274     Count++;
275     if (PPadNumber==-1){
276       PSecNumber=data.Sec;
277       PRowNumber=data.Row;
278       PPadNumber=data.Pad;
279       PTimeBin=data.Time;
280       BunchLength=1;
281       Buffer->FillBuffer(data.Dig-offset);
282       nwords++;
283     }//end if
284     else{
285       if ( (data.Time==(PTimeBin+1)) &&
286            (PPadNumber==data.Pad) &&
287            (PRowNumber==data.Row) &&
288            (PSecNumber==data.Sec)){
289         BunchLength++;
290       }//end if
291       else{
292         Buffer->FillBuffer(PTimeBin);
293         Buffer->FillBuffer(BunchLength+2);
294         nwords+=2;
295         if ((PPadNumber!=data.Pad)||(PRowNumber!=data.Row)||(PSecNumber!=data.Sec)){
296           //Trailer is formatted and inserted!!
297           Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
298           numPackets++;
299           nwords=0;
300         }//end if
301         
302         BunchLength=1;
303         PPadNumber=data.Pad;
304         PRowNumber=data.Row;
305         PSecNumber=data.Sec;
306       }//end else
307       PTimeBin=data.Time;
308       Buffer->FillBuffer(data.Dig-offset);
309       nwords++;
310     }//end else
311   }//end while
312   Buffer->FillBuffer(PTimeBin);
313   Buffer->FillBuffer(BunchLength+2);
314   nwords+=2;
315   Buffer->WriteTrailer(nwords,PPadNumber,PRowNumber,PSecNumber);
316   delete Buffer;
317   cout<<"Number of digits: "<<Count<<endl;
318   f.close(); 
319   return;
320 }
321
322
323 void AliTPCDDLRawData::RawDataAltroDecode(Int_t LDCsNumber,Int_t Comp){
324   char filename[15];
325   char dest[30];
326   fstream f;
327   if(!Comp)
328     sprintf(dest,"AltroDDLRecomposed.dat");
329   else
330     sprintf(dest,"AltroDDLRecomposedDec.dat");
331   ofstream fdest;
332
333   fdest.open(dest,ios::binary);
334   ULong_t Size=0;
335   //Int_t MagicWord,DDLNumber,SecNumber,SubSector,Detector,Flag=0;
336   for(Int_t i=1;i<=LDCsNumber;i++){
337     if(!Comp)
338       sprintf(filename,"TPCslice%d",i);  
339     else
340       sprintf(filename,"TPCslice%d.decomp",i);  
341     f.open(filename,ios::binary|ios::in);
342     if(!f){cout<<"The file doesn't exist"<<endl;exit(1);}
343     //loop over the DDL block 
344     //Each block contains a Mini Header followed by raw data (ALTRO FORMAT)
345     //The number of block is ceil(216/LDCsNumber)
346     ULong_t MiniHeader[3];
347     //here the Mini Header is read
348     while( (f.read((char*)(MiniHeader),sizeof(ULong_t)*3)) ){
349       //cout<<"Mini header dimension "<<MiniHeader[0]<<endl;
350       Int_t car=0;
351       Size=MiniHeader[0];
352       for(ULong_t j=0;j<Size;j++){
353         f.read((char*)(&car),1);
354         fdest.write((char*)(&car),1);
355       }//end for
356     }//end while
357     f.clear();
358     f.close();
359   }//end for
360   fdest.close();
361   return;
362 }
363