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