2bbf8b99e29e571a29646cdd149133bc00be68b8
[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 //
7 //  AliL3Compress
8 //
9 // Class for compressing and uncompressing data.
10
11 #include "AliL3StandardIncludes.h"
12
13 #include "bitio.h"
14 #include "AliL3RootTypes.h"
15 #include "AliL3Models.h"
16 #include "AliL3DigitData.h"
17 #include "AliL3Logging.h"
18 #include "AliL3TrackArray.h"
19 #include "AliL3ModelTrack.h"
20 #include "AliL3Transform.h"
21 #include "AliL3MemHandler.h"
22 #include "AliL3DataCompressorHelper.h"
23 #include "AliL3DataCompressor.h"
24 #include "AliL3SpacePointData.h"
25
26 #if 0
27 #ifdef use_root
28 #include <TH1.h>
29 #include <TH2.h>
30 #include <TRandom.h>
31 #endif
32 #ifdef use_aliroot
33 #include "AliL3FileHandler.h"
34 #endif
35 #endif
36
37 #include "AliL3Compress.h"
38
39 #if __GNUC__ >= 3
40 using namespace std;
41 #endif
42
43
44 ClassImp(AliL3Compress)
45
46 AliL3Compress::AliL3Compress()
47 {
48   // default constructor
49   fTracks=0;
50   fSlice =0;
51   fPatch=0;
52   fWriteShape=kFALSE;
53   fEvent=-1;
54 }
55
56 AliL3Compress::AliL3Compress(Int_t slice,Int_t patch,Char_t *path,Bool_t writeshape,Int_t event)
57 {
58   // constructor
59   fEvent=event;
60   fSlice=slice;
61   fPatch=patch;
62   fTracks=0;
63   sprintf(fPath,"%s",path);
64   fWriteShape=writeshape;
65 }
66
67 AliL3Compress::~AliL3Compress()
68 {
69   // destructor
70   if(fTracks)
71     delete fTracks;
72 }
73
74 Bool_t AliL3Compress::WriteFile(AliL3TrackArray *tracks,Char_t *filename)
75 {
76   // writes file
77   Char_t fname[1024];
78   if(filename)
79     sprintf(fname,"%s/comp/%s",fPath,filename);
80   else if(fEvent<0)
81     sprintf(fname,"%s/comp/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
82   else
83     sprintf(fname,"%s/comp/tracks_m_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
84
85   FILE *file = fopen(fname,"w");
86   if(!file)
87     {
88       cerr<<"AliL3Compress::WriteFile : Error opening file "<<fname<<endl;
89       return kFALSE;
90     }
91   Short_t ntracks = tracks->GetNTracks();
92     
93   Int_t count=0;
94   AliL3ClusterModel *clusters=0;
95   AliL3TrackModel *model=0;
96   for(Int_t i=0; i<ntracks; i++)
97     {
98       AliL3ModelTrack *track = (AliL3ModelTrack*)tracks->GetCheckedTrack(i);
99       if(!track) continue;
100
101       //Do not save useless tracks or clusters:
102       //if(track->GetNPresentClusters() == 0)
103       //continue;
104       
105       track->FillModel();
106       model = track->GetModel();
107       //if(model->fNClusters==0) continue;
108       clusters = track->GetClusters();
109       if(fwrite(model,sizeof(AliL3TrackModel),1,file)!=1) break;
110       //if(fwrite(clusters,model->fNClusters*sizeof(AliL3ClusterModel),1,file)!=1) break;
111       if(fwrite(clusters,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel),1,file)!=1) break;
112       count++;
113       
114     }
115   fclose(file);
116   return kTRUE;
117 }
118
119 Bool_t AliL3Compress::ReadFile(Char_t which,Char_t *filename)
120 {
121   //Read the trackfile.
122
123   Char_t fname[1024];
124   if(filename)
125     sprintf(fname,"%s/comp/%s",fPath,filename);
126   else
127     {
128       if(which == 'm')
129         {
130           if(fEvent<0)
131             sprintf(fname,"%s/comp/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
132           else
133             sprintf(fname,"%s/comp/tracks_m_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
134         }
135       else if(which == 'u')
136         {
137           if(fEvent<0)
138             sprintf(fname,"%s/comp/tracks_u_%d_%d.raw",fPath,fSlice,fPatch);
139           else
140             sprintf(fname,"%s/comp/tracks_u_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
141         }
142       else
143         {
144           cerr<<"AliL3Compress::ReadFile() : Wrong option"<<endl;
145           return kFALSE;
146         }
147     }
148
149   FILE *file = fopen(fname,"r");
150   if(!file)
151     {
152       cerr<<"AliL3Compress::ReadFile : Cannot open file "<<fname<<endl;
153       return kFALSE;
154     }
155
156   if(fTracks)
157     delete fTracks;
158   fTracks = new AliL3TrackArray("AliL3ModelTrack");
159   
160   while(!feof(file))
161     {
162       AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->NextTrack();
163       track->Init(fSlice,fPatch);
164       AliL3TrackModel *model = track->GetModel();
165       AliL3ClusterModel *clusters = track->GetClusters();
166       if(fread(model,sizeof(AliL3TrackModel),1,file)!=1) break;
167       //if(fread(clusters,model->fNClusters*sizeof(AliL3ClusterModel),1,file)!=1) break;
168       if(fread(clusters,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel),1,file)!=1) break;
169       track->FillTrack();
170     }
171
172   fTracks->RemoveLast();
173   fclose(file);
174   return kTRUE;
175 }
176
177 Bool_t AliL3Compress::CompressFile()
178 {
179   // compresses file
180   Char_t fname[100];
181   if(fEvent<0)
182     sprintf(fname,"%s/comp/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
183   else
184     sprintf(fname,"%s/comp/tracks_c_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
185   BIT_FILE *output = OpenOutputBitFile(fname);
186   
187   if(fEvent<0)
188     sprintf(fname,"%s/comp/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
189   else
190     sprintf(fname,"%s/comp/tracks_m_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
191   
192   FILE *input = fopen(fname,"r");
193   if(!input)
194     {
195       cerr<<"AliL3Compress::CompressFile() : Error opening file: "<<fname<<endl;
196       return kFALSE;
197     }
198
199   AliL3TrackModel track;
200   AliL3ClusterModel cluster;
201   Int_t temp;
202   Int_t power;
203   
204   Int_t timeo,pado,chargeo,padshapeo,timeshapeo;
205   timeo=pado=chargeo=padshapeo=timeshapeo=0;
206   while(!feof(input))
207     {
208       if(fread(&track,sizeof(AliL3TrackModel),1,input)!=1) break;
209       
210       if(output->mask != 0x80) //Write the current byte to file.
211         {
212           //cerr<<"\nAliL3Compress::CompressFile() : Writing overhead bits!!!"<<endl;
213           if(putc(output->rack,output->file )!=output->rack)
214             cerr<<"AliL3Compress::ComressFile : Error writing to bitfile"<<endl;
215           output->mask=0x80;
216           output->rack=0;
217         }
218       
219       //Write track parameters:
220       fwrite(&track,sizeof(AliL3TrackModel),1,output->file);
221       
222       Int_t origslice=-1,slice,clustercount=0;
223       for(Int_t i=0; i<AliL3Transform::GetNRows(fPatch); i++)
224         {
225           if(fread(&cluster,sizeof(AliL3ClusterModel),1,input)!=1) break;
226           
227           //Write empty flag:
228           temp = (Int_t)cluster.fPresent;
229           OutputBit(output,temp);
230           if(!temp) continue;
231           
232           if(cluster.fSlice<0 || cluster.fSlice>35)
233             {
234               cerr<<"AliL3DataCompress::CompressFile : Fucked up slice number :"<<cluster.fSlice<<endl;
235               exit(5);
236             }
237           
238           //Write slice number of first point
239           if(clustercount==0)
240             {
241               origslice = cluster.fSlice;
242               OutputBits(output,origslice,6); //Need 6 bits to encode slice number
243             }
244           else
245             {
246               slice = cluster.fSlice;
247               if(slice == origslice)
248                 OutputBit(output,0);  //No change of slice
249               else
250                 {
251                   OutputBit(output,1);
252                   OutputBits(output,slice,6);
253                   origslice=slice;
254                 }
255             }
256           
257           //Write time information:
258           temp = (Int_t)rint(cluster.fDTime);
259           if(temp<0)
260             OutputBit(output,0);
261           else
262             OutputBit(output,1);
263           power = 1<<(AliL3DataCompressorHelper::GetNTimeBits()-1);
264           if(abs(temp)>=power)
265             {
266               //cout<<abs(temp)<<" "<<power<<endl;
267               timeo++;
268               temp=power - 1;
269             }
270           OutputBits(output,abs(temp),(AliL3DataCompressorHelper::GetNTimeBits()-1));
271           
272           //Write pad information:
273           temp = (Int_t)rint(cluster.fDPad);
274           if(temp<0)
275             OutputBit(output,0);
276           else
277             OutputBit(output,1);
278           power = 1<<(AliL3DataCompressorHelper::GetNPadBits()-1);
279           if(abs(temp)>=power)
280             {
281               pado++;
282               temp=power - 1;
283             }
284           OutputBits(output,abs(temp),(AliL3DataCompressorHelper::GetNPadBits()-1));
285           
286           //Write charge information:
287           temp = (Int_t)cluster.fDCharge;
288           power = 1<<(AliL3DataCompressorHelper::GetNChargeBits());
289           if(abs(temp)>=power)
290             {
291               chargeo++;
292               temp=power - 1;
293             }
294           OutputBits(output,abs(temp),(AliL3DataCompressorHelper::GetNChargeBits()));
295           
296           if(fWriteShape)
297             {
298               //Write shape information:
299               temp = (Int_t)rint(cluster.fDSigmaY);
300               if(temp<0)
301                 OutputBit(output,0);
302               else
303                 OutputBit(output,1);
304               power = 1<<(AliL3DataCompressorHelper::GetNShapeBits()-1);
305               if(abs(temp) >= power)
306                 {
307                   padshapeo++;
308                   temp = power - 1;
309                 }
310               OutputBits(output,abs(temp),(AliL3DataCompressorHelper::GetNShapeBits()-1));
311               
312               temp = (Int_t)rint(cluster.fDSigmaZ);
313               if(temp<0)
314                 OutputBit(output,0);
315               else
316                 OutputBit(output,1);
317               power = 1<<(AliL3DataCompressorHelper::GetNShapeBits()-1);
318               if(abs(temp) >= power)
319                 {
320                   timeshapeo++;
321                   temp=power - 1;
322                 }
323               OutputBits(output,abs(temp),(AliL3DataCompressorHelper::GetNShapeBits()-1));
324             }
325           
326           clustercount++;
327         }
328     }
329   
330   fclose(input);
331   CloseOutputBitFile(output);
332   if(pado || timeo || chargeo || padshapeo || timeshapeo)
333     {
334       cout<<endl<<"Saturations: "<<endl
335           <<"Pad "<<pado<<endl
336           <<"Time "<<timeo<<endl
337           <<"Charge "<<chargeo<<endl
338           <<"Padshape "<<padshapeo<<endl
339           <<"Timeshape "<<timeshapeo<<endl<<endl;
340     }
341   return kTRUE;
342 }
343
344 Bool_t AliL3Compress::ExpandFile()
345 {
346   // expands file
347   Char_t fname[100];
348   if(fEvent<0)
349     sprintf(fname,"%s/comp/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
350   else
351     sprintf(fname,"%s/comp/tracks_c_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
352   BIT_FILE *input = OpenInputBitFile(fname);
353   
354   if(fEvent<0)
355     sprintf(fname,"%s/comp/tracks_u_%d_%d.raw",fPath,fSlice,fPatch);
356   else
357     sprintf(fname,"%s/comp/tracks_u_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
358   FILE *output = fopen(fname,"w");
359   if(!output)
360     {
361       cerr<<"AliL3Compress::ExpandFile() : Error opening file: "<<fname<<endl;
362       return kFALSE;
363     }
364
365   AliL3TrackModel trackmodel;
366   AliL3ClusterModel *clusters=0;
367   Int_t count=0;
368   
369   clusters = new AliL3ClusterModel[(AliL3Transform::GetNRows(fPatch))];
370   while(!feof(input->file))
371     {
372       input->mask=0x80;//make sure we read a new byte from file.
373       
374       //Read and write track:
375       if(fread(&trackmodel,sizeof(AliL3TrackModel),1,input->file)!=1) break;
376       fwrite(&trackmodel,sizeof(AliL3TrackModel),1,output);
377
378       memset(clusters,0,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel));
379       Int_t origslice=-1,clustercount=0;
380       for(Int_t i=0; i<AliL3Transform::GetNRows(fPatch); i++)
381         {
382           Int_t temp,sign;
383           
384           //Read empty flag:
385           temp = InputBit(input);
386           if(!temp) 
387             {
388               clusters[i].fPresent=kFALSE;
389               continue;
390             }
391           clusters[i].fPresent=kTRUE;
392           
393           //Read slice information
394           if(clustercount==0)
395             {
396               temp = InputBits(input,6);
397               clusters[i].fSlice = temp;
398               origslice = temp;
399             }
400           else
401             {
402               temp = InputBit(input);
403               if(!temp)//no change
404                 clusters[i].fSlice = origslice;
405               else
406                 {
407                   temp = InputBits(input,6);//read new slice
408                   clusters[i].fSlice = temp;
409                   origslice = temp;//store new slice
410                 }
411             }
412           
413           //Read time information:
414           sign=InputBit(input);
415           temp = InputBits(input,(AliL3DataCompressorHelper::GetNTimeBits()-1));
416           if(!sign)
417             temp*=-1;
418           clusters[i].fDTime = temp;
419           
420           //Read pad information:
421           sign=InputBit(input);
422           temp = InputBits(input,(AliL3DataCompressorHelper::GetNPadBits()-1));
423           if(!sign)
424             temp*=-1;
425           clusters[i].fDPad = temp;
426           
427           //Read charge information:
428           temp=InputBits(input,(AliL3DataCompressorHelper::GetNChargeBits()));
429           clusters[i].fDCharge = temp;
430           
431           if(fWriteShape)
432             {
433               //Read shape information:
434               sign = InputBit(input);
435               temp = InputBits(input,(AliL3DataCompressorHelper::GetNShapeBits()-1));
436               if(!sign)
437                 temp*=-1;
438               clusters[i].fDSigmaY = temp;
439               
440               sign = InputBit(input);
441               temp = InputBits(input,(AliL3DataCompressorHelper::GetNShapeBits()-1));
442               if(!sign)
443                 temp*=-1;
444               clusters[i].fDSigmaZ = temp;
445             }
446           clustercount++;
447         }
448       count++;
449       //fwrite(clusters,(trackmodel.fNClusters)*sizeof(AliL3ClusterModel),1,output);
450       fwrite(clusters,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel),1,output);
451     }
452   
453   delete [] clusters;
454   fclose(output);
455   CloseInputBitFile(input);
456   return kTRUE;
457 }
458
459 void AliL3Compress::CompressRemaining(AliL3SpacePointData *clusters[36][6],UInt_t nclusters[36][6])
460 {
461   //Write the remaining clusters in a compressed format.
462
463   Char_t filename[1024];
464   Int_t nrows = AliL3Transform::GetNRows();
465   Int_t *npoints = new Int_t[nrows];
466   for(Int_t slice=0; slice<=35; slice++)
467     {
468       for(Int_t patch=0; patch < 1; patch++)
469         {
470           sprintf(filename,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,slice,-1);
471           BIT_FILE *output = OpenOutputBitFile(filename);
472           if(!output)
473             {
474               cerr<<"AliL3Compress::CompressRemaining : Cannot open file "<<filename<<endl;
475               exit(5);
476             }
477           AliL3SpacePointData *cl = clusters[slice][patch];
478           memset(npoints,0,nrows*sizeof(Int_t));
479           
480           UInt_t i;
481           for(i=0; i<nclusters[slice][patch]; i++)
482             {
483               if(cl[i].fCharge == 0) continue; //has been used
484               npoints[cl[i].fPadRow]++;
485             }
486           Int_t rowspresent=0;
487           for(Int_t j=0; j<nrows; j++)
488             {
489               if(!npoints[j]) continue;
490               rowspresent++;
491             }
492           
493           //Write number of padrows with clusters
494           OutputBits(output,rowspresent,8);
495           
496           Int_t lastPadrow=-1;
497           for(i=0; i<nclusters[slice][patch]; i++)
498             {
499               if(cl[i].fCharge == 0) continue; //has been used
500               Int_t padrow = cl[i].fPadRow;
501               if(padrow != lastPadrow)
502                 {
503                   OutputBits(output,padrow,8);//Write padrow #
504                   if(npoints[padrow] >= 1<<10)
505                     {
506                       cerr<<"AliL3Compress::CompressRemaining : Too many remaining clusters "<<npoints[padrow]<<endl;
507                       exit(5);
508                     }
509                   OutputBits(output,npoints[padrow],10);//Write number of clusters on this padrow
510                   lastPadrow = padrow;
511                 }
512               
513               Float_t xyz[3] = {cl[i].fX,cl[i].fY,cl[i].fZ};
514               Int_t sector,row,buff;
515               AliL3Transform::Slice2Sector(slice,padrow,sector,row);
516               AliL3Transform::Global2Raw(xyz,sector,row);
517               
518               Float_t padw = sqrt(cl[i].fSigmaY2) / AliL3Transform::GetPadPitchWidth(AliL3Transform::GetPatch(padrow));
519               Float_t timew = sqrt(cl[i].fSigmaZ2) / AliL3Transform::GetZWidth();
520               
521               //Check for saturation in the widths.
522               //Basically only store a certain number of decimals here, and cut the widths which is higher:
523               if(padw >= (1<<AliL3DataCompressorHelper::GetNShapeBitsRemaining()) / AliL3DataCompressorHelper::GetPadPrecisionFactor())
524                 padw = (1<<AliL3DataCompressorHelper::GetNShapeBitsRemaining()) / AliL3DataCompressorHelper::GetPadPrecisionFactor() - 1/AliL3DataCompressorHelper::GetPadPrecisionFactor();
525               if(timew >= (1<<AliL3DataCompressorHelper::GetNShapeBitsRemaining()) / AliL3DataCompressorHelper::GetTimePrecisionFactor())
526                 timew = (1<<AliL3DataCompressorHelper::GetNShapeBitsRemaining()) / AliL3DataCompressorHelper::GetTimePrecisionFactor() - 1/AliL3DataCompressorHelper::GetTimePrecisionFactor();;
527               
528               //Write pad
529               buff = (Int_t)rint(xyz[1]*AliL3DataCompressorHelper::GetPadPrecisionFactor());
530               if(buff<0)
531                 {
532                   cerr<<"AliL3Compress:CompressRemaining : Wrong pad value "<<buff<<endl;
533                   exit(5);
534                 }
535               OutputBits(output,buff,AliL3DataCompressorHelper::GetNPadBitsRemaining());
536               
537               //Write time
538               buff = (Int_t)rint(xyz[2]*AliL3DataCompressorHelper::GetTimePrecisionFactor());
539               if(buff<0)
540                 {
541                   cerr<<"AliL3Compress:CompressRemaining : Wrong time value "<<buff<<endl;
542                   exit(5);
543                 }
544               OutputBits(output,buff,AliL3DataCompressorHelper::GetNTimeBitsRemaining());
545               
546               //Write widths
547               buff = (Int_t)rint(padw*AliL3DataCompressorHelper::GetPadPrecisionFactor());
548               OutputBits(output,buff,AliL3DataCompressorHelper::GetNShapeBitsRemaining());
549               buff = (Int_t)rint(timew*AliL3DataCompressorHelper::GetTimePrecisionFactor());
550               OutputBits(output,buff,AliL3DataCompressorHelper::GetNShapeBitsRemaining());
551               
552               //Write charge 
553               buff = cl[i].fCharge;
554               if(buff >= 1<<(AliL3DataCompressorHelper::GetNChargeBits()))
555                 buff = (1<<(AliL3DataCompressorHelper::GetNChargeBits()))-1;
556               OutputBits(output,buff,AliL3DataCompressorHelper::GetNChargeBits());
557             }
558           
559           CloseOutputBitFile(output);
560         }
561       
562     }
563   delete [] npoints;
564 }
565
566 void AliL3Compress::ExpandRemaining(TempCluster **clusters,Int_t *ncl, Int_t /*maxpoints*/)
567 {
568   //Expand the remaining clusters stored using function CompressRemaining
569   
570   Char_t filename[1024];
571   Int_t buff;
572   for(Int_t slice=0; slice<=35; slice++)
573     {
574       for(Int_t p=0; p<1; p++)
575         {
576           sprintf(filename,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,slice,-1);
577           BIT_FILE *input = OpenInputBitFile(filename);
578           
579           //Read number of padrows 
580           buff = InputBits(input,8);
581           Int_t nrows = buff;
582           
583           for(Int_t i=0; i<nrows; i++)
584             {
585               //Read padrow
586               buff = InputBits(input,8);
587               Int_t padrow = buff;
588               
589               //Read nclusters;
590               buff = InputBits(input,10);
591               Int_t npoints = buff;
592               
593               for(Int_t i=0; i<npoints; i++)
594                 {
595                   clusters[slice][ncl[slice]].fPadrow = padrow;
596
597                   //Read pad
598                   buff = InputBits(input,AliL3DataCompressorHelper::GetNPadBitsRemaining());
599                   clusters[slice][ncl[slice]].fPad = (Float_t)buff/AliL3DataCompressorHelper::GetPadPrecisionFactor();
600                   
601                   //Read time
602                   buff = InputBits(input,AliL3DataCompressorHelper::GetNTimeBitsRemaining());
603                   clusters[slice][ncl[slice]].fTime = (Float_t)buff/AliL3DataCompressorHelper::GetTimePrecisionFactor();
604                   
605                   //Read widths 
606                   buff = InputBits(input,AliL3DataCompressorHelper::GetNShapeBitsRemaining());
607                   clusters[slice][ncl[slice]].fSigmaY2 = pow((Float_t)buff/AliL3DataCompressorHelper::GetPadPrecisionFactor(),2);
608                   buff = InputBits(input,AliL3DataCompressorHelper::GetNShapeBitsRemaining());
609                   clusters[slice][ncl[slice]].fSigmaZ2 = pow((Float_t)buff/AliL3DataCompressorHelper::GetPadPrecisionFactor(),2);
610                   
611                   //Read charge
612                   buff = InputBits(input,AliL3DataCompressorHelper::GetNChargeBits());
613                   clusters[slice][ncl[slice]].fCharge = buff;
614                   
615                   ncl[slice]++;
616                 }
617               
618             }
619           CloseInputBitFile(input);
620         }
621     }
622 }
623
624 void AliL3Compress::PrintCompRatio(ofstream *outfile)
625 {
626   // prints the compression ratio
627   AliL3MemHandler *mem = new AliL3MemHandler();
628   Char_t fname[1024];
629   UInt_t remainSize=0,digitSize=0;
630   for(Int_t i=0; i<36; i++)
631     {
632       if(fEvent<0)
633         sprintf(fname,"%s/comp/remains_%d_%d.raw",fPath,i,-1);
634       else
635         sprintf(fname,"%s/comp/remains_%d_%d_%d.raw",fPath,fEvent,i,-1);
636       mem->SetBinaryInput(fname);
637       remainSize += mem->GetFileSize();
638       mem->CloseBinaryInput();
639
640       sprintf(fname,"%s/binaries/digits_c8_%d_%d_%d.raw",fPath,fEvent,i,-1);
641       mem->SetBinaryInput(fname);
642       digitSize += mem->GetFileSize();
643       mem->CloseBinaryInput();
644     }
645   
646   
647   if(fEvent<0)
648     sprintf(fname,"%s/comp/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
649   else
650     sprintf(fname,"%s/comp/tracks_c_%d_%d_%d.raw",fPath,fEvent,fSlice,fPatch);
651
652   mem->SetBinaryInput(fname);
653   UInt_t compressSize = mem->GetFileSize();
654   mem->CloseBinaryInput();
655   
656   if(digitSize==0)
657     {
658       cerr<<"AliL3Compress::PrintCompRatio : Zero digit size, not able to obtain comp. ratios!"<<endl;
659       return;
660     }
661   
662   Float_t compratio = (Float_t)(compressSize + remainSize)/(Float_t)digitSize;
663   Float_t entropy[3];
664   Int_t trackSize = GetEntropy(entropy[0],entropy[1],entropy[2])*sizeof(AliL3TrackModel);
665   if(outfile)
666     {
667       ofstream &out = *outfile;
668       out<<compressSize<<' '<<remainSize<<' '<<digitSize<<' '<<trackSize<<' '<<entropy[0]<<' '<<entropy[1]<<endl;
669     }
670   
671   cout<<"=========================================="<<endl;
672   cout<<"Original digits size : "<<digitSize/1000<<" kByte ( 100 % )"<<endl;
673   cout<<"Compressed file size : "<<compressSize/1000<<" kByte ( "<<(Float_t)compressSize*100/(Float_t)digitSize<<" % )"<<endl;
674   cout<<"Remaining file size  : "<<remainSize/1000<<" kByte ( "<<(Float_t)remainSize*100/(Float_t)digitSize<<" % )"<<endl;
675   cout<<"Relative track size  : "<<trackSize/1000<<" kByte ( "<<(Float_t)trackSize*100/(Float_t)digitSize<<" % )"<<endl;
676   cout<<"Relative cluster size: "<<(compressSize-trackSize)/1000<<" kByte ( "<<(Float_t)(compressSize-trackSize)*100/(Float_t)digitSize<<" % )"<<endl;
677   cout<<"---------------------- "<<endl;
678   cout<<"Compression ratio    : "<<compratio*100<<" %"<<endl;
679   cout<<"=========================================="<<endl;
680   cout<<"Entropy of residuals : "<<entropy[0]<<" "<<entropy[1]<<endl;
681 }
682
683 Int_t AliL3Compress::GetEntropy(Float_t &padEntropy,Float_t &timeEntropy,Float_t &chargeEntropy)
684 {
685   //Calculate the entropy of the quantized residuals in both directions
686   
687   if(!ReadFile('m'))
688     return 0;
689   const Int_t knmax=100000;
690   Float_t pads[knmax];
691   Float_t times[knmax];
692   Float_t charge[knmax];
693   memset(&pads[0],0,knmax*sizeof(Float_t));
694   memset(&times[0],0,knmax*sizeof(Float_t));
695   memset(&charge[0],0,knmax*sizeof(Float_t));
696   Float_t counter=0;
697
698   for(Int_t i=0; i<fTracks->GetNTracks(); i++)
699     {
700       AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
701       if(!track) continue;
702       for(Int_t padrow=0; padrow<AliL3Transform::GetNRows(); padrow++)
703         {
704           if(!track->IsPresent(padrow)) continue;
705           Int_t dpad = abs((Int_t)rint(track->GetClusterModel(padrow)->fDPad));
706           Int_t dtime = abs((Int_t)rint(track->GetClusterModel(padrow)->fDTime));
707           Int_t dcharge = (Int_t)track->GetClusterModel(padrow)->fDCharge;
708           if(dpad >= knmax || dtime >= knmax || dcharge >= knmax)
709             {
710               cerr<<"AliL3Compress::GetEntropy : Quantization out of range: "<<dpad<<" "<<dtime<<" "<<dcharge<<endl;
711               break;
712             }
713           pads[dpad]++;
714           times[dtime]++;
715           charge[dcharge]++;
716           counter++;
717         }
718     }
719   padEntropy=timeEntropy=chargeEntropy=0;
720   for(Int_t i=0; i<knmax; i++)
721     {
722       if(pads[i]>0)
723         padEntropy += (pads[i]/counter)*(log(pads[i]/counter)/log(2.0));
724       if(times[i]>0)
725         timeEntropy += (times[i]/counter)*(log(times[i]/counter)/log(2.0));
726       if(charge[i]>0)
727         chargeEntropy += (charge[i]/counter)*(log(charge[i]/counter)/log(2.0));
728     }
729   
730   padEntropy*=-1;
731   timeEntropy*=-1;
732   chargeEntropy*=-1;
733   return fTracks->GetNTracks();
734 }