L3 becomes HLT
[u/mrichter/AliRoot.git] / HLT / comp / AliHLTCompressAC.cxx
1 // @(#) $Id$
2
3 // Author: Anders Vestbo <mailto:vestbo$fi.uib.no>
4 //*-- Copyright &copy ALICE HLT Group
5 //_____________________________________________________________
6 //
7 //  AliHLTCompressAC
8 //
9 // Compression class which performs Arithmetic Coding of the quantized residuals.
10 // The implemented algorithm is inspired by the examples in The Data Compression Book 
11 // by Nelson & Gailly.
12
13 #if __GNUC__ >= 3
14 using namespace std;
15 #endif
16
17 #include "AliHLTStandardIncludes.h"
18 #include "AliHLTTrackArray.h"
19 #include "AliHLTModelTrack.h"
20 #include "AliHLTTransform.h"
21 #include "AliHLTMemHandler.h"
22 #include "AliHLTCompress.h"
23 #include "AliHLTDataCompressorHelper.h"
24 #include "AliHLTCompressAC.h"
25
26
27 ClassImp(AliHLTCompressAC)
28
29 AliHLTCompressAC::AliHLTCompressAC()
30 {
31   // default constructor
32   fCount=0;
33   fTotals=0;
34   fMax=0;
35   fRange=0;
36   fLow=0;
37   fHigh=0;
38   fUnderflowBits=0;
39   fCode=0;
40 }
41
42 AliHLTCompressAC::AliHLTCompressAC(Int_t slice,Int_t patch,Char_t *path,Bool_t writeshape,Int_t event) :
43   AliHLTCompress(slice,patch,path,writeshape,event)
44 {
45   // constructor
46   fCount=0;
47   fTotals=0;
48   fMax=0;
49   fRange=0;
50   fLow=0;
51   fHigh=0;
52   fUnderflowBits=0;
53   fCode=0;
54 }
55
56 AliHLTCompressAC::~AliHLTCompressAC()
57 {
58   // destructor
59   ClearArrays();
60 }
61
62 void AliHLTCompressAC::ClearArrays()
63 {
64   // cleans all arrays
65   fMax=0;
66   if(fCount)
67     delete [] fCount;
68   if(fTotals)
69     delete [] fTotals;
70 }
71
72 void AliHLTCompressAC::BuildModel(BIT_FILE *output)
73 {
74   //Build the model from the input data, i.e. probability distributions of the quantized residuals.
75   
76   ClearArrays();
77   ReadFile('m');
78   
79   UInt_t nmax=10000,qres;
80   UInt_t * temp = new UInt_t[nmax];
81   memset(&temp[0],0,nmax*sizeof(UInt_t));
82
83   AliHLTTrackArray *tracks = GetTracks();
84   for(Int_t t=0; t<tracks->GetNTracks(); t++)
85     {
86       AliHLTModelTrack *track = (AliHLTModelTrack*)tracks->GetCheckedTrack(t);
87       if(!track) continue;
88       for(Int_t padrow=0; padrow<AliHLTTransform::GetNRows(); padrow++)
89         {
90           if(!track->IsPresent(padrow)) continue;
91           qres = abs((Int_t)rint(track->GetClusterModel(padrow)->fDPad));
92           if(qres >= nmax)
93             {
94               cerr<<"AliHLTCompressAC::BuildModel() : Residual values seems way too big!"<<endl;
95               continue;
96             }
97           if(qres > fMax)
98             fMax=qres;
99           temp[qres]++;
100           qres = abs((Int_t)rint(track->GetClusterModel(padrow)->fDTime));
101           if(qres > fMax)
102             fMax = qres;
103           temp[qres]++;
104
105         }
106     }
107   
108   fCount = new UChar_t[fMax+1];
109   
110   //Find the highest counts in order to do scaling:
111   UInt_t i,maxCount=0;
112   for(i=0; i<=fMax; i++)
113     {
114       if(temp[i] > maxCount)
115         maxCount=temp[i];
116     }
117
118   //Perform the scaling
119   UInt_t scale,total=1;
120   scale = maxCount / 256 + 1;
121   for(i=0; i<=fMax; i++)
122     {
123       fCount[i] = (UChar_t)(temp[i]/scale);
124       if(fCount[i]==0 && temp[i]!=0)
125         fCount[i] = 1;
126       total += (UInt_t)fCount[i];
127     }
128   if(total > (32767 - 256))
129     scale=4;
130   else if(total > 16383)
131     scale=2;
132   else
133     scale=1;
134   if(scale > 1)
135     for(i=0; i<=fMax; i++)
136       fCount[i] /= scale;
137
138   cout<<"Writing "<<sizeof(UChar_t)*fMax+1<<" bytes with model information to compressed file"<<endl;
139   fwrite(&fMax,sizeof(UShort_t),1,output->file);
140   fwrite(fCount,sizeof(UChar_t),fMax+1,output->file);
141   
142   FillTotals();
143   delete [] temp;
144 }
145
146 void AliHLTCompressAC::RebuildModel(BIT_FILE *input)
147 {
148   //Rebuild the model from the counts written to the beginning of the compressed file.
149   
150   ClearArrays();
151   fread(&fMax,sizeof(UShort_t),1,input->file);
152   fCount = new UChar_t[fMax+1];
153   fread(fCount,sizeof(UChar_t),fMax+1,input->file);
154   FillTotals();
155 }
156
157 void AliHLTCompressAC::FillTotals()
158 {
159   //Fill the array of totals, which is actually the model being used during encoding/decoding.
160   if(fMax == 0)
161     cerr<<"AliHLTCompressAC::FillTotals : max value is zero!"<<endl;
162
163   fTotals = new UInt_t[fMax+3];//up to max, and one reserved for endofstream symbol
164   
165   UInt_t i;
166   fTotals[0]=0;
167   for(i=0; i<=fMax; i++)
168     {
169       fTotals[i+1] = fTotals[i] + fCount[i];
170     }
171   fTotals[fMax+2] = fTotals[fMax+1]+1;//Used for the scale
172 }
173
174 void AliHLTCompressAC::PrintTotals() const
175 {
176   // prints totals
177   cout<<"Totals:"<<endl;
178   for(UInt_t i=0; i<=fMax; i++)
179     {
180       cout<<"Totals "<<i<<" "<<fTotals[i]<<" count "<<(int)fCount[i]<<endl;
181     }
182 }
183
184 void AliHLTCompressAC::InitEncoder()
185 {
186   // inits the encoder
187   fLow = 0;
188   fHigh = 0xffff;
189   fUnderflowBits=0;
190 }
191
192 void AliHLTCompressAC::InitDecoder(BIT_FILE *input)
193 {
194   // inits the decoder
195   fCode=0;
196   for(Int_t i=0; i<16; i++)
197     {
198       fCode <<= 1;
199       fCode += InputBit(input);
200     }
201   fLow = 0;
202   fHigh = 0xffff;
203 }
204
205 void AliHLTCompressAC::ConvertIntToSymbol(Int_t value)
206 {
207   // converst integer to symbol
208   UInt_t range = fHigh - fLow + 1;
209   fHigh = fLow + (UShort_t)((range*fTotals[value+1])/fTotals[fMax+2] - 1);
210   fLow = fLow + (UShort_t)((range*fTotals[value])/fTotals[fMax+2]);
211 }
212
213 UInt_t AliHLTCompressAC::ConvertSymbolToInt()
214 {
215   // converts symbol to integer
216   UInt_t range = (UInt_t)(fHigh-fLow) + 1;
217   UShort_t count = (UShort_t)((((UInt_t)(fCode-fLow)+1)*fTotals[fMax+2] - 1)/range);
218   UInt_t j=fMax+1;
219   while(count < fTotals[j])
220     j--;
221   
222   return j;
223 }
224
225 void AliHLTCompressAC::EncodeSymbol(BIT_FILE *output)
226 {
227   // encodes symbol
228   while(1)
229     {
230       if( (fHigh & 0x8000) == (fLow & 0x8000) )
231         {
232           OutputBit(output,fHigh & 0x8000);
233           while(fUnderflowBits > 0)
234             {
235               OutputBit(output,~fHigh & 0x8000);
236               fUnderflowBits--;
237             }
238         }
239       else if( (fLow & 0x4000) && !(fHigh & 0x4000) )
240         {
241           fUnderflowBits++;
242           fLow &= 0x3fff;
243           fHigh |= 0x4000;
244         }
245       else
246         return;
247       fLow <<= 1;
248       fHigh <<= 1;
249       fHigh |= 1;
250     }
251 }
252
253 void AliHLTCompressAC::RemoveSymbolFromStream(BIT_FILE *input,Int_t j)
254 {
255   // remves symbol fro stream
256   UInt_t range = (UInt_t)(fHigh-fLow)+1;
257   fHigh = fLow + (UShort_t)((range*fTotals[j+1])/fTotals[fMax+2]-1);
258   fLow = fLow + (UShort_t)((range*fTotals[j])/fTotals[fMax+2]);
259   while(1)
260     {
261       if( (fHigh & 0x8000)==(fLow & 0x8000) )
262         {}
263       else if((fLow & 0x4000) == 0x4000 && (fHigh & 0x4000)==0)
264         {
265           fCode ^= 0x4000;
266           fLow &= 0x3fff;
267           fHigh |= 0x4000;
268         }
269       else
270         return;
271       fLow <<= 1;
272       fHigh <<= 1;
273       fHigh |= 1;
274       fCode <<= 1;
275       fCode += InputBit(input);
276     }
277 }
278
279 void AliHLTCompressAC::FlushEncoder(BIT_FILE *output)
280 {
281   //Flush the encoder:
282   OutputBit(output,fLow & 0x4000);
283   fUnderflowBits++;
284   while(fUnderflowBits-- > 0)
285     OutputBit(output,~fLow & 0x4000);
286   
287 }
288
289
290 Bool_t AliHLTCompressAC::CompressFile()
291 {
292   // comresses file
293   Char_t fname[100];
294   if(fEvent<0)
295     sprintf(fname,"%s/comp/tracks_ac_%d_%d.raw",fPath,fSlice,fPatch);
296   else
297     sprintf(fname,"%s/comp/tracks_ac_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
298   BIT_FILE *output = OpenOutputBitFile(fname);
299   
300   if(fEvent<0)
301     sprintf(fname,"%s/comp/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
302   else
303     sprintf(fname,"%s/comp/tracks_m_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
304   
305   FILE *input = fopen(fname,"r");
306   if(!input)
307     {
308       cerr<<"AliHLTCompressAC::CompressFileAC() : Error opening file: "<<fname<<endl;
309       return kFALSE;
310     }
311   
312   BuildModel(output);
313
314   AliHLTTrackModel track;
315   Int_t temp,power,i,j;
316   
317   fseek(input,0,SEEK_END);
318   UInt_t size = ftell(input);
319   rewind(input);
320   Int_t trackcount = size/(sizeof(AliHLTTrackModel) + sizeof(AliHLTClusterModel)*AliHLTTransform::GetNRows(fPatch));
321   
322   //Write the number of tracks in the beginning of stream.
323   fwrite(&trackcount,sizeof(Int_t),1,output->file);
324   
325   AliHLTClusterModel **clusters = new AliHLTClusterModel*[trackcount];
326   Int_t *clustercount = new Int_t[trackcount];
327   i=0;
328   
329   //Read all the tracks from input file, and write them all to the outputfile.
330   //Store the clusters in memory for later encoding and storing.
331   while(!feof(input))
332     {
333       if(fread(&track,sizeof(AliHLTTrackModel),1,input)!=1) break;
334       fwrite(&track,sizeof(AliHLTTrackModel),1,output->file);
335       
336       clusters[i] = new AliHLTClusterModel[AliHLTTransform::GetNRows()];
337       clustercount[i]=0;
338       
339       //Read in the clusters:
340       fread(clusters[i],sizeof(AliHLTClusterModel),AliHLTTransform::GetNRows(fPatch),input);
341       i++;
342     }
343   if(i != trackcount)
344     {
345       cerr<<"AliHLTCompressAC::CompressFile : Mismatching file size and trackcount "<<i<<" "<<trackcount<<endl;
346       exit(5);
347     }
348   fclose(input);
349   
350   //Write all the fixed size variables of the clusters:
351   for(i=0; i<trackcount; i++)
352     {
353       Int_t origslice=-1,slice;
354       for(j=0; j<AliHLTTransform::GetNRows(fPatch); j++)
355         {
356           temp = (Int_t)clusters[i][j].fPresent;
357           OutputBit(output,temp);
358           if(!temp) continue;
359           
360           if(clusters[i][j].fSlice<0 || clusters[i][j].fSlice>35)
361             {
362               cerr<<"AliHLTDataCompress::CompressFile : Fucked up slice number :"<<clusters[i][j].fSlice<<endl;
363               exit(5);
364             }
365           
366           //Write slice number of first point
367           if(clustercount[i]==0)
368             {
369               origslice = clusters[i][j].fSlice;
370               OutputBits(output,origslice,6); //Need 6 bits to encode slice number
371             }
372           else
373             {
374               slice = clusters[i][j].fSlice;
375               if(slice == origslice)
376                 {
377                   OutputBit(output,0);  //No change of slice
378                 }
379               else
380                 {
381                   OutputBit(output,1);
382                   if(abs(slice - origslice)==1)
383                     {
384                       if(slice > origslice)
385                         OutputBit(output,1);
386                       else
387                         OutputBit(output,0);
388                     }
389                   else
390                     {
391                       if( (slice == 0 && origslice == 17) || (slice == 18 && origslice == 35) )
392                         OutputBit(output,1);
393                       else if( (slice == 17 && origslice == 0) || (slice == 35 && origslice == 18) )
394                         OutputBit(output,0);
395                     }
396                   origslice=slice;
397                 }
398             }
399           
400           //Write charge information:
401           temp = (Int_t)clusters[i][j].fDCharge;
402           power = 1<<(AliHLTDataCompressorHelper::GetNChargeBits());
403           if(abs(temp)>=power)
404             {
405               temp=power - 1;
406             }
407           OutputBits(output,abs(temp),(AliHLTDataCompressorHelper::GetNChargeBits()));
408
409           //Write sign information of the residuals:
410           temp = (Int_t)rint(clusters[i][j].fDTime);
411           if(temp<0)
412             OutputBit(output,0);
413           else
414             OutputBit(output,1);
415           temp = (Int_t)rint(clusters[i][j].fDPad);
416           if(temp<0)
417             OutputBit(output,0);
418           else
419             OutputBit(output,1);
420
421           //Write shape information if requested:
422           if(fWriteShape)
423             {
424               temp = (Int_t)rint(clusters[i][j].fDSigmaY);
425               if(temp<0)
426                 OutputBit(output,0);
427               else
428                 OutputBit(output,1);
429               power = 1<<(AliHLTDataCompressorHelper::GetNShapeBits()-1);
430               if(abs(temp) >= power)
431                 {
432                   temp = power - 1;
433                 }
434               OutputBits(output,abs(temp),(AliHLTDataCompressorHelper::GetNShapeBits()-1));
435               
436               temp = (Int_t)rint(clusters[i][j].fDSigmaZ);
437               if(temp<0)
438                 OutputBit(output,0);
439               else
440                 OutputBit(output,1);
441               power = 1<<(AliHLTDataCompressorHelper::GetNShapeBits()-1);
442               if(abs(temp) >= power)
443                 {
444                   temp=power - 1;
445                 }
446               OutputBits(output,abs(temp),(AliHLTDataCompressorHelper::GetNShapeBits()-1));
447             }
448           clustercount[i]++;
449         }
450     }
451
452   InitEncoder();
453   
454   //Start the arithmetic coding of the residuals.
455   //All the residuals (both pad and time) are coded in one go,
456   //i.e. for all tracks and clusters in the input file.
457   for(i=0; i<trackcount; i++)
458     {
459       Int_t counter=0;
460       
461       for(j=0; j<AliHLTTransform::GetNRows(fPatch); j++)
462         {
463           if(!clusters[i][j].fPresent) continue;
464           temp = abs((Int_t)rint(clusters[i][j].fDTime));
465           ConvertIntToSymbol(temp);
466           EncodeSymbol(output);
467
468           temp = abs((Int_t)rint(clusters[i][j].fDPad));
469           ConvertIntToSymbol(temp);
470           EncodeSymbol(output);
471           counter++;
472         }
473       if(counter != clustercount[i])
474         {
475           cerr<<"AliHLTCompressAC::CompressFile : Mismatching clustercount "<<counter<<" "<<clustercount[i]<<endl;
476           exit(5);
477         }
478
479     }
480   
481   ConvertIntToSymbol(fMax+1);//End of stream symbol
482   EncodeSymbol(output);
483   FlushEncoder(output);
484   OutputBits(output,0,16);
485
486   for(i=0; i<trackcount; i++)
487     delete [] clusters[i];
488   delete [] clusters;
489   delete [] clustercount;
490   
491
492   CloseOutputBitFile(output);
493   
494   return kTRUE;
495 }
496
497 Bool_t AliHLTCompressAC::ExpandFile()
498 {
499   // expands file
500   Char_t fname[100];
501   if(fEvent<0)
502     sprintf(fname,"%s/comp/tracks_ac_%d_%d.raw",fPath,fSlice,fPatch);
503   else
504     sprintf(fname,"%s/comp/tracks_ac_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
505   BIT_FILE *input = OpenInputBitFile(fname);
506   
507   if(fEvent<0)
508     sprintf(fname,"%s/comp/tracks_u_%d_%d.raw",fPath,fSlice,fPatch);
509   else
510     sprintf(fname,"%s/comp/tracks_u_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
511   FILE *output = fopen(fname,"w");
512   if(!output)
513     {
514       cerr<<"AliHLTCompress::ExpandFile() : Error opening file: "<<fname<<endl;
515       return kFALSE;
516     }
517   
518   RebuildModel(input);
519
520   int trackcount,i,j;
521   fread(&trackcount,sizeof(Int_t),1,input->file);
522
523   AliHLTTrackModel *trackmodels = new AliHLTTrackModel[trackcount];
524   AliHLTClusterModel **clusters = new AliHLTClusterModel*[trackcount];
525   Int_t *clustercount = new Int_t[trackcount];
526
527   fread(trackmodels,sizeof(AliHLTTrackModel),trackcount,input->file);
528   
529   for(i=0; i<trackcount; i++)
530     {
531       clusters[i] = new AliHLTClusterModel[AliHLTTransform::GetNRows(fPatch)];
532       clustercount[i]=0;
533
534       //Read the fixed size variables:
535       Int_t origslice=-1;
536       Int_t temp,sign;
537       for(j=0; j<AliHLTTransform::GetNRows(fPatch); j++)
538         {
539           //Read empty flag:
540           temp = InputBit(input);
541           if(!temp) 
542             {
543               clusters[i][j].fPresent=kFALSE;
544               continue;
545             }
546           clusters[i][j].fPresent=kTRUE;
547           
548           //Read slice information
549           if(clustercount[i]==0)
550             {
551               temp = InputBits(input,6);
552               clusters[i][j].fSlice = temp;
553               origslice = temp;
554             }
555           else
556             {
557               temp = InputBit(input);
558               if(!temp)//no change
559                 clusters[i][j].fSlice = origslice;
560               else
561                 {
562                   temp = InputBit(input);
563                   if(temp)
564                     {
565                       if(origslice == 17)
566                         origslice = 0;
567                       else if(origslice == 35)
568                         origslice = 18;
569                       else
570                         origslice++;
571                     }
572                   else
573                     {
574                       if(origslice == 0)
575                         origslice = 17;
576                       else if(origslice == 18)
577                         origslice = 35;
578                       else
579                         origslice--;
580                     }
581                   if(origslice < 0 || origslice > 35)
582                     {
583                       cerr<<"AliHLTCompressAC::ExpandFile : Bad slice number "<<temp<<endl;
584                       exit(5);
585                     }
586                   clusters[i][j].fSlice = origslice;
587                 }
588             }
589           
590           //Read charge information:
591           temp=InputBits(input,(AliHLTDataCompressorHelper::GetNChargeBits()));
592           clusters[i][j].fDCharge = temp;
593           
594           //Read sign information of the residuals:
595           sign=InputBit(input);
596           if(!sign)
597             clusters[i][j].fDTime = -1;
598           else
599             clusters[i][j].fDTime = 1;
600           sign=InputBit(input);
601           if(!sign)
602             clusters[i][j].fDPad = -1;
603           else
604             clusters[i][j].fDPad = 1;
605           
606           //Read shape information if requested
607           if(fWriteShape)
608             {
609               sign = InputBit(input);
610               temp = InputBits(input,(AliHLTDataCompressorHelper::GetNShapeBits()-1));
611               if(!sign)
612                 temp*=-1;
613               clusters[i][j].fDSigmaY = temp;
614               
615               sign = InputBit(input);
616               temp = InputBits(input,(AliHLTDataCompressorHelper::GetNShapeBits()-1));
617               if(!sign)
618                 temp*=-1;
619               clusters[i][j].fDSigmaZ = temp;
620             }
621           clustercount[i]++;
622         }
623     }
624   
625   InitDecoder(input);
626   
627   Int_t temp;
628   for(i=0; i<trackcount; i++)
629     {
630       Int_t count=0;
631       for(j=0; j<AliHLTTransform::GetNRows(fPatch); j++)
632         {
633           if(!clusters[i][j].fPresent) continue;
634             
635           temp = ConvertSymbolToInt();
636           RemoveSymbolFromStream(input,temp);
637           clusters[i][j].fDTime *= temp;
638           
639           temp = ConvertSymbolToInt();
640           RemoveSymbolFromStream(input,temp);
641           clusters[i][j].fDPad *= temp;
642           count++;
643         }
644
645       if(count != clustercount[i])
646         {
647           cerr<<"AliHLTCompressAC::ExpandFile : Mismatching clustercount "<<count<<" "<<clustercount[i]<<endl;
648           exit(5);
649         }
650     }
651   
652   //Now there should be a endofstream indicator, if not something went wrong during encoding/decoding.
653   temp = ConvertSymbolToInt();
654   if((UShort_t)temp != fMax + 1)
655     cerr<<"AliHLTCompressAC::ExpandFile : Missing the endofstream indicator!"<<endl;
656   
657   CloseInputBitFile(input);
658
659   //Write everything to the uncompressed outfile:
660   for(i=0; i<trackcount; i++)
661     {
662       fwrite(&trackmodels[i],sizeof(AliHLTTrackModel),1,output);
663       fwrite(clusters[i],AliHLTTransform::GetNRows(fPatch)*sizeof(AliHLTClusterModel),1,output);
664     }
665   
666   fclose(output);
667   
668   for(i=0; i<trackcount; i++)
669     delete [] clusters[i];
670   delete [] clusters;
671   delete [] trackmodels;
672   delete [] clustercount;
673   
674   return kTRUE;
675 }
676
677 void AliHLTCompressAC::PrintCompRatio(ofstream *outfile)
678 {
679   // pristc compression ratio
680   AliHLTMemHandler *mem = new AliHLTMemHandler();
681   Char_t fname[1024];
682   UInt_t remainSize=0,digitSize=0;
683   for(Int_t i=0; i<36; i++)
684     {
685       if(fEvent<0)
686         sprintf(fname,"%s/comp/remains_%d_%d.raw",fPath,i,-1);
687       else
688         sprintf(fname,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,i,-1);
689       mem->SetBinaryInput(fname);
690       remainSize += mem->GetFileSize();
691       mem->CloseBinaryInput();
692
693       sprintf(fname,"%s/binaries/digits_c8_%d_%d_%d.raw",fPath,fEvent,i,-1);
694       mem->SetBinaryInput(fname);
695       digitSize += mem->GetFileSize();
696       mem->CloseBinaryInput();
697     }
698   
699   
700   if(fEvent<0)
701     sprintf(fname,"%s/comp/tracks_ac_%d_%d.raw",fPath,fSlice,fPatch);
702   else
703     sprintf(fname,"%s/comp/tracks_ac_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
704
705   mem->SetBinaryInput(fname);
706   UInt_t compressSize = mem->GetFileSize();
707   mem->CloseBinaryInput();
708   
709   if(digitSize==0)
710     {
711       cerr<<"AliHLTCompress::PrintCompRatio : Zero digit size, not able to obtain comp. ratios!"<<endl;
712       return;
713     }
714   
715   Float_t compratio = (Float_t)(compressSize + remainSize)/(Float_t)digitSize;
716   Float_t entropy[3];
717   Int_t trackSize = GetEntropy(entropy[0],entropy[1],entropy[2])*sizeof(AliHLTTrackModel);
718   if(outfile)
719     {
720       ofstream &out = *outfile;
721       out<<compressSize<<' '<<remainSize<<' '<<digitSize<<' '<<trackSize<<' '<<entropy[0]<<' '<<entropy[1]<<endl;
722     }
723   
724   cout<<"=========================================="<<endl;
725   cout<<"Original digits size : "<<digitSize/1000<<" kByte ( 100 % )"<<endl;
726   cout<<"Compressed file size : "<<compressSize/1000<<" kByte ( "<<(Float_t)compressSize*100/(Float_t)digitSize<<" % )"<<endl;
727   cout<<"Remaining file size  : "<<remainSize/1000<<" kByte ( "<<(Float_t)remainSize*100/(Float_t)digitSize<<" % )"<<endl;
728   cout<<"Relative track size  : "<<trackSize/1000<<" kByte ( "<<(Float_t)trackSize*100/(Float_t)compressSize<<" % )"<<endl;
729   cout<<"Relative cluster size: "<<(compressSize-trackSize)/1000<<" kByte ( "<<(Float_t)(compressSize-trackSize)*100/(Float_t)compressSize<<" % )"<<endl;
730   cout<<"---------------------- "<<endl;
731   cout<<"Compression ratio    : "<<compratio*100<<" %"<<endl;
732   cout<<"=========================================="<<endl;
733   cout<<"Entropy of residual and charge : "<<entropy[0]<<" "<<entropy[1]<<" "<<entropy[2]<<endl;
734 }
735