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