b842b70ea7f45a6cb85f43b766dc38f0386f3d7d
[u/mrichter/AliRoot.git] / HLT / comp / AliL3Compress.cxx
1 // @(#) $Id$
2
3 // Author: Anders Vestbo <mailto:vestbo$fi.uib.no>
4 //*-- Copyright &copy ALICE HLT Group
5
6 #include "AliL3StandardIncludes.h"
7
8 #include "bitio.h"
9 #include "AliL3RootTypes.h"
10 #include "AliL3Models.h"
11 #include "AliL3DigitData.h"
12 #include "AliL3Logging.h"
13 #include "AliL3TrackArray.h"
14 #include "AliL3ModelTrack.h"
15 #include "AliL3Transform.h"
16 #include "AliL3MemHandler.h"
17 #include "AliL3DataCompressor.h"
18
19 #if 0
20 #ifdef use_root
21 #include <TH1.h>
22 #include <TH2.h>
23 #include <TRandom.h>
24 #endif
25 #ifdef use_aliroot
26 #include "AliL3FileHandler.h"
27 #endif
28 #endif
29
30 #include "AliL3Compress.h"
31
32 #if GCCVERSION == 3
33 using namespace std;
34 #endif
35
36 //_____________________________________________________________
37 //
38 //  AliL3Compress
39 //
40 // Class for compressing and uncompressing data.
41
42 ClassImp(AliL3Compress)
43
44 AliL3Compress::AliL3Compress()
45 {
46   fTracks=0;
47   fSlice =0;
48   fPatch=0;
49   fWriteShape=kFALSE;
50   fEvent=-1;
51 }
52
53 AliL3Compress::AliL3Compress(Int_t slice,Int_t patch,Char_t *path,Bool_t writeshape,Int_t event)
54 {
55   fEvent=event;
56   fSlice=slice;
57   fPatch=patch;
58   fTracks=0;
59   sprintf(fPath,"%s",path);
60   fWriteShape=writeshape;
61 }
62
63 AliL3Compress::~AliL3Compress()
64 {
65   if(fTracks)
66     delete fTracks;
67 }
68
69 Bool_t AliL3Compress::WriteFile(AliL3TrackArray *tracks,Char_t *filename)
70 {
71   Char_t fname[1024];
72   if(filename)
73     sprintf(fname,"%s/comp/%s",fPath,filename);
74   else if(fEvent<0)
75     sprintf(fname,"%s/comp/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
76   else
77     sprintf(fname,"%s/comp/tracks_m_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
78
79   FILE *file = fopen(fname,"w");
80   if(!file)
81     {
82       cerr<<"AliL3Compress::WriteFile : Error opening file "<<fname<<endl;
83       return kFALSE;
84     }
85   Short_t ntracks = tracks->GetNTracks();
86     
87   Int_t count=0;
88   AliL3ClusterModel *clusters=0;
89   AliL3TrackModel *model=0;
90   for(Int_t i=0; i<ntracks; i++)
91     {
92       AliL3ModelTrack *track = (AliL3ModelTrack*)tracks->GetCheckedTrack(i);
93       if(!track) continue;
94
95       //Do not save useless tracks or clusters:
96       //if(track->GetNPresentClusters() == 0)
97       //continue;
98       
99       track->FillModel();
100       model = track->GetModel();
101       //if(model->fNClusters==0) continue;
102       clusters = track->GetClusters();
103       if(fwrite(model,sizeof(AliL3TrackModel),1,file)!=1) break;
104       //if(fwrite(clusters,model->fNClusters*sizeof(AliL3ClusterModel),1,file)!=1) break;
105       if(fwrite(clusters,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel),1,file)!=1) break;
106       count++;
107       
108     }
109   fclose(file);
110   return kTRUE;
111 }
112
113 Bool_t AliL3Compress::ReadFile(Char_t which,Char_t *filename)
114 {
115   //Read the trackfile.
116
117   Char_t fname[1024];
118   if(filename)
119     sprintf(fname,"%s/comp/%s",fPath,filename);
120   else
121     {
122       if(which == 'm')
123         {
124           if(fEvent<0)
125             sprintf(fname,"%s/comp/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
126           else
127             sprintf(fname,"%s/comp/tracks_m_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
128         }
129       else if(which == 'u')
130         {
131           if(fEvent<0)
132             sprintf(fname,"%s/comp/tracks_u_%d_%d.raw",fPath,fSlice,fPatch);
133           else
134             sprintf(fname,"%s/comp/tracks_u_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
135         }
136       else
137         {
138           cerr<<"AliL3Compress::ReadFile() : Wrong option"<<endl;
139           return kFALSE;
140         }
141     }
142
143   FILE *file = fopen(fname,"r");
144   if(!file)
145     {
146       cerr<<"AliL3Compress::ReadFile : Cannot open file "<<fname<<endl;
147       return kFALSE;
148     }
149
150   if(fTracks)
151     delete fTracks;
152   fTracks = new AliL3TrackArray("AliL3ModelTrack");
153   
154   while(!feof(file))
155     {
156       AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->NextTrack();
157       track->Init(fSlice,fPatch);
158       AliL3TrackModel *model = track->GetModel();
159       AliL3ClusterModel *clusters = track->GetClusters();
160       if(fread(model,sizeof(AliL3TrackModel),1,file)!=1) break;
161       //if(fread(clusters,model->fNClusters*sizeof(AliL3ClusterModel),1,file)!=1) break;
162       if(fread(clusters,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel),1,file)!=1) break;
163       track->FillTrack();
164     }
165
166   fTracks->RemoveLast();
167   fclose(file);
168   return kTRUE;
169 }
170
171 Bool_t AliL3Compress::CompressFile()
172 {
173   Char_t fname[100];
174   if(fEvent<0)
175     sprintf(fname,"%s/comp/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
176   else
177     sprintf(fname,"%s/comp/tracks_c_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
178   BIT_FILE *output = OpenOutputBitFile(fname);
179   
180   if(fEvent<0)
181     sprintf(fname,"%s/comp/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
182   else
183     sprintf(fname,"%s/comp/tracks_m_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
184   
185   FILE *input = fopen(fname,"r");
186   if(!input)
187     {
188       cerr<<"AliL3Compress::CompressFile() : Error opening file: "<<fname<<endl;
189       return kFALSE;
190     }
191
192   AliL3TrackModel track;
193   AliL3ClusterModel cluster;
194   Int_t temp;
195   Int_t power;
196   
197   Int_t timeo,pado,chargeo,shapeo;
198   timeo=pado=chargeo=shapeo=0;
199   while(!feof(input))
200     {
201       if(fread(&track,sizeof(AliL3TrackModel),1,input)!=1) break;
202       
203       if(output->mask != 0x80) //Write the current byte to file.
204         {
205           //cerr<<"\nAliL3Compress::CompressFile() : Writing overhead bits!!!"<<endl;
206           if(putc(output->rack,output->file )!=output->rack)
207             cerr<<"AliL3Compress::ComressFile : Error writing to bitfile"<<endl;
208           output->mask=0x80;
209           output->rack=0;
210         }
211       
212       //Write track parameters:
213       fwrite(&track,sizeof(AliL3TrackModel),1,output->file);
214       
215       Int_t origslice=-1,slice,clustercount=0;
216       for(Int_t i=0; i<AliL3Transform::GetNRows(fPatch); i++)
217         {
218           if(fread(&cluster,sizeof(AliL3ClusterModel),1,input)!=1) break;
219           
220           //Write empty flag:
221           temp = (Int_t)cluster.fPresent;
222           OutputBit(output,temp);
223           if(!temp) continue;
224           
225           if(cluster.fSlice<0 || cluster.fSlice>35)
226             {
227               cerr<<"AliL3DataCompress::CompressFile : Fucked up slice number :"<<cluster.fSlice<<endl;
228               exit(5);
229             }
230           
231           //Write slice number of first point
232           if(clustercount==0)
233             {
234               origslice = cluster.fSlice;
235               OutputBits(output,origslice,6); //Need 6 bits to encode slice number
236             }
237           else
238             {
239               slice = cluster.fSlice;
240               if(slice == origslice)
241                 OutputBit(output,0);
242               else
243                 {
244                   OutputBit(output,1);
245                   OutputBits(output,slice,6);
246                   origslice=slice;
247                 }
248             }
249           
250           //Write time information:
251           temp = (Int_t)rint(cluster.fDTime);
252           if(temp<0)
253             OutputBit(output,0);
254           else
255             OutputBit(output,1);
256           power = 1<<(AliL3DataCompressor::GetNTimeBits()-1);
257           if(abs(temp)>=power)
258             {
259               timeo++;
260               temp=power - 1;
261             }
262           OutputBits(output,abs(temp),(AliL3DataCompressor::GetNTimeBits()-1));
263           
264           //Write pad information:
265           temp = (Int_t)rint(cluster.fDPad);
266           if(temp<0)
267             OutputBit(output,0);
268           else
269             OutputBit(output,1);
270           power = 1<<(AliL3DataCompressor::GetNPadBits()-1);
271           if(abs(temp)>=power)
272             {
273               pado++;
274               temp=power - 1;
275             }
276           OutputBits(output,abs(temp),(AliL3DataCompressor::GetNPadBits()-1));
277           
278           //Write charge information:
279           temp = (Int_t)cluster.fDCharge;
280           power = 1<<(AliL3DataCompressor::GetNChargeBits());
281           if(abs(temp)>=power)
282             {
283               chargeo++;
284               temp=power - 1;
285             }
286           OutputBits(output,abs(temp),(AliL3DataCompressor::GetNChargeBits()));
287           
288           if(fWriteShape)
289             {
290               //Write shape information:
291               temp = (Int_t)cluster.fDSigmaY2;
292               if(temp<0)
293                 OutputBit(output,0);
294               else
295                 OutputBit(output,1);
296               power = 1<<(AliL3DataCompressor::GetNShapeBits()-1);
297               if(abs(temp) >= power)
298                 {
299                   shapeo++;
300                   temp = power - 1;
301                 }
302               OutputBits(output,abs(temp),(AliL3DataCompressor::GetNShapeBits()-1));
303               
304               temp = (Int_t)cluster.fDSigmaZ2;
305               if(temp<0)
306                 OutputBit(output,0);
307               else
308                 OutputBit(output,1);
309               power = 1<<(AliL3DataCompressor::GetNShapeBits()-1);
310               if(abs(temp) >= power)
311                 {
312                   shapeo++;
313                   temp=power - 1;
314                 }
315               OutputBits(output,abs(temp),(AliL3DataCompressor::GetNShapeBits()-1));
316             }
317           
318           clustercount++;
319         }
320     }
321   
322   fclose(input);
323   CloseOutputBitFile(output);
324   if(pado || timeo || chargeo || shapeo)
325     {
326       cout<<endl<<"Saturations: "<<endl
327           <<"Pad "<<pado<<endl
328           <<"Time "<<timeo<<endl
329           <<"Charge "<<chargeo<<endl
330           <<"Shape "<<shapeo<<endl<<endl;
331     }
332   return kTRUE;
333 }
334
335 Bool_t AliL3Compress::ExpandFile()
336 {
337   Char_t fname[100];
338   if(fEvent<0)
339     sprintf(fname,"%s/comp/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
340   else
341     sprintf(fname,"%s/comp/tracks_c_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
342   BIT_FILE *input = OpenInputBitFile(fname);
343   
344   if(fEvent<0)
345     sprintf(fname,"%s/comp/tracks_u_%d_%d.raw",fPath,fSlice,fPatch);
346   else
347     sprintf(fname,"%s/comp/tracks_u_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
348   FILE *output = fopen(fname,"w");
349   if(!output)
350     {
351       cerr<<"AliL3Compress::ExpandFile() : Error opening file: "<<fname<<endl;
352       return kFALSE;
353     }
354
355   AliL3TrackModel trackmodel;
356   AliL3ClusterModel *clusters=0;
357   Int_t count=0;
358   
359   clusters = new AliL3ClusterModel[(AliL3Transform::GetNRows(fPatch))];
360   while(!feof(input->file))
361     {
362       input->mask=0x80;//make sure we read a new byte from file.
363       
364       //Read and write track:
365       if(fread(&trackmodel,sizeof(AliL3TrackModel),1,input->file)!=1) break;
366       fwrite(&trackmodel,sizeof(AliL3TrackModel),1,output);
367
368       memset(clusters,0,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel));
369       Int_t origslice=-1,clustercount=0;
370       for(Int_t i=0; i<AliL3Transform::GetNRows(fPatch); i++)
371         {
372           Int_t temp,sign;
373           
374           //Read empty flag:
375           temp = InputBit(input);
376           if(!temp) 
377             {
378               clusters[i].fPresent=kFALSE;
379               continue;
380             }
381           clusters[i].fPresent=kTRUE;
382           
383           //Read slice information
384           if(clustercount==0)
385             {
386               temp = InputBits(input,6);
387               clusters[i].fSlice = temp;
388               origslice = temp;
389             }
390           else
391             {
392               temp = InputBit(input);
393               if(!temp)//no change
394                 clusters[i].fSlice = origslice;
395               else
396                 {
397                   temp = InputBits(input,6);//read new slice
398                   clusters[i].fSlice = temp;
399                   origslice = temp;//store new slice
400                 }
401             }
402           
403           //Read time information:
404           sign=InputBit(input);
405           temp = InputBits(input,(AliL3DataCompressor::GetNTimeBits()-1));
406           if(!sign)
407             temp*=-1;
408           clusters[i].fDTime = temp;
409           
410           //Read pad information:
411           sign=InputBit(input);
412           temp = InputBits(input,(AliL3DataCompressor::GetNPadBits()-1));
413           if(!sign)
414             temp*=-1;
415           clusters[i].fDPad = temp;
416           
417           //Read charge information:
418           temp=InputBits(input,(AliL3DataCompressor::GetNChargeBits()));
419           clusters[i].fDCharge = temp;
420           
421           if(fWriteShape)
422             {
423               //Read shape information:
424               sign = InputBit(input);
425               temp = InputBits(input,(AliL3DataCompressor::GetNShapeBits()-1));
426               if(!sign)
427                 temp*=-1;
428               clusters[i].fDSigmaY2 = temp;
429               
430               sign = InputBit(input);
431               temp = InputBits(input,(AliL3DataCompressor::GetNShapeBits()-1));
432               if(!sign)
433                 temp*=-1;
434               clusters[i].fDSigmaZ2 = temp;
435             }
436           clustercount++;
437         }
438       count++;
439       //fwrite(clusters,(trackmodel.fNClusters)*sizeof(AliL3ClusterModel),1,output);
440       fwrite(clusters,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel),1,output);
441     }
442   
443   delete [] clusters;
444   fclose(output);
445   CloseInputBitFile(input);
446   return kTRUE;
447 }
448
449 void AliL3Compress::PrintCompRatio(ofstream *outfile)
450 {
451   AliL3MemHandler *mem = new AliL3MemHandler();
452   Char_t fname[1024];
453   UInt_t remain_size=0,digit_size=0;
454   for(Int_t i=0; i<36; i++)
455     {
456       if(fEvent<0)
457         sprintf(fname,"%s/comp/remains_%d_%d.raw",fPath,i,-1);
458       else
459         sprintf(fname,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,i,-1);
460       mem->SetBinaryInput(fname);
461       remain_size += mem->GetFileSize();
462       mem->CloseBinaryInput();
463
464       sprintf(fname,"%s/binaries/digits_c8_%d_%d_%d.raw",fPath,fEvent,i,-1);
465       mem->SetBinaryInput(fname);
466       digit_size += mem->GetFileSize();
467       mem->CloseBinaryInput();
468     }
469   
470   
471   if(fEvent<0)
472     sprintf(fname,"%s/comp/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
473   else
474     sprintf(fname,"%s/comp/tracks_c_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
475
476   mem->SetBinaryInput(fname);
477   UInt_t compress_size = mem->GetFileSize();
478   mem->CloseBinaryInput();
479   
480   if(digit_size==0)
481     {
482       cerr<<"AliL3Compress::PrintCompRatio : Zero digit size, not able to obtain comp. ratios!"<<endl;
483       return;
484     }
485   
486   Float_t compratio = (Float_t)(compress_size + remain_size)/(Float_t)digit_size;
487   if(outfile)
488     {
489       ofstream &out = *outfile;
490       out<<compress_size<<' '<<remain_size<<' '<<digit_size<<endl;
491     }
492
493   cout<<"=========================================="<<endl;
494   cout<<"Original digits size : "<<digit_size/1000<<" kByte ( 100 % )"<<endl;
495   cout<<"Compressed file size : "<<compress_size/1000<<" kByte ( "<<(Float_t)compress_size*100/(Float_t)digit_size<<" % )"<<endl;
496   cout<<"Remainig file size   : "<<remain_size/1000<<" kByte ( "<<(Float_t)remain_size*100/(Float_t)digit_size<<" % )"<<endl;
497   cout<<"---------------------- "<<endl;
498   cout<<"Compression ratio    : "<<compratio*100<<" %"<<endl;
499   cout<<"=========================================="<<endl;
500 }