Changed parameters of WriteRootFile
[u/mrichter/AliRoot.git] / HLT / comp / AliL3Compress.cxx
1 //$Id$
2
3 // Author: Anders Vestbo <mailto:vestbo$fi.uib.no>
4 //*-- Copyright &copy ASV
5
6 #include "AliL3StandardIncludes.h"
7 #include <TH1.h>
8 #include <TH2.h>
9 #include <TRandom.h>
10
11 #include "AliL3Logging.h"
12 #include "AliL3Compress.h"
13 #include "AliL3TrackArray.h"
14 #include "AliL3ModelTrack.h"
15 #include "AliL3Transform.h"
16 #include "AliL3MemHandler.h"
17 #ifdef use_aliroot
18 #include "AliL3FileHandler.h"
19 #endif
20 #include "bitio.h"
21
22 //_____________________________________________________________
23 //
24 //  AliL3Compress
25 //
26 // Class for compressing and uncompressing data.
27
28 ClassImp(AliL3Compress)
29
30 AliL3Compress::AliL3Compress()
31 {
32   fTracks=0;
33   SetBitNumbers(0,0,0,0);
34   fSlice =0;
35   fPatch=0;
36   fDigits=0;
37   fDPt=0;
38   fWriteShape=kFALSE;
39 }
40
41 AliL3Compress::AliL3Compress(Int_t slice,Int_t patch,Char_t *path,Bool_t writeshape)
42 {
43   fSlice=slice;
44   fPatch=patch;
45   SetBitNumbers(0,0,0,0);
46   fTracks=0;
47   fDigits=0;
48   fDPt=0;
49   sprintf(fPath,"%s",path);
50   fWriteShape=writeshape;
51 }
52
53 AliL3Compress::~AliL3Compress()
54 {
55   if(fTracks)
56     delete fTracks;
57   if(fDigits)
58     delete [] fDigits;
59   if(fDPt)
60     delete [] fDPt;
61 }
62
63 void AliL3Compress::SetBitNumbers(Int_t pad,Int_t time,Int_t charge,Int_t shape)
64 {
65   fNumPadBits=pad;
66   fNumTimeBits=time;
67   fNumChargeBits=charge;
68   fNumShapeBits=shape;
69 }
70
71 void AliL3Compress::WriteFile(AliL3TrackArray *tracks)
72 {
73   Char_t fname[100];
74   sprintf(fname,"%s/comp/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
75   FILE *file = fopen(fname,"w");
76   if(!file)
77     {
78       cerr<<"AliL3Compress::WriteFile : Error opening file "<<fname<<endl;
79       return;
80     }
81   Short_t ntracks = tracks->GetNTracks();
82   //cout<<"Writing "<<ntracks<<" tracks to file"<<endl;
83     
84   Int_t count=0;
85   AliL3ClusterModel *clusters=0;
86   AliL3TrackModel *model=0;
87   for(Int_t i=0; i<ntracks; i++)
88     {
89       AliL3ModelTrack *track = (AliL3ModelTrack*)tracks->GetCheckedTrack(i);
90       if(!track) continue;
91       
92       //Do not save useless tracks or clusters:
93       if(track->GetNPresentClusters() == 0)
94         continue;
95       
96       track->FillModel();
97       model = track->GetModel();
98       if(model->fNClusters==0) continue;
99       clusters = track->GetClusters();
100       //cout<<"Writing "<<(int)model->fNClusters<<" clusters"<<endl;
101       if(fwrite(model,sizeof(AliL3TrackModel),1,file)!=1) break;
102       //cout<<"Writing "<<(int)model->fNClusters<<" clusters to file"<<endl;
103       if(fwrite(clusters,model->fNClusters*sizeof(AliL3ClusterModel),1,file)!=1) break;
104       //track->Print();
105       count++;
106       
107     }
108   //cout<<"Wrote "<<count<<" tracks "<<endl;
109   fclose(file);
110 }
111
112 void AliL3Compress::ReadFile(Char_t which)
113 {
114   //Read the trackfile.
115
116   Char_t fname[100];
117   if(which == 'm')
118     sprintf(fname,"%s/comp/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
119   else if(which == 'u')
120     sprintf(fname,"%s/comp/tracks_u_%d_%d.raw",fPath,fSlice,fPatch);
121   else
122     {
123       cerr<<"AliL3Compress::ReadFile() : Wrong option"<<endl;
124       return;
125     }
126
127   FILE *file = fopen(fname,"r");
128   if(!file)
129     {
130       cerr<<"AliL3Compress::ReadFile : Cannot open file "<<fname<<endl;
131       return;
132     }
133
134   if(fTracks)
135     delete fTracks;
136   fTracks = new AliL3TrackArray("AliL3ModelTrack");
137   
138   //cout<<"Reading file "<<fname<<endl;
139   while(!feof(file))
140     {
141       AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->NextTrack();
142       track->Init(fSlice,fPatch);
143       AliL3TrackModel *model = track->GetModel();
144       AliL3ClusterModel *clusters = track->GetClusters();
145       if(fread(model,sizeof(AliL3TrackModel),1,file)!=1) break;
146       if(fread(clusters,(model->fNClusters)*sizeof(AliL3ClusterModel),1,file)!=1) break;
147       track->FillTrack();
148     }
149
150   fTracks->RemoveLast();
151   //cout<<"Read "<<fTracks->GetNTracks()<<" tracks from file"<<endl;
152   fclose(file);
153 }
154
155 void AliL3Compress::CompressFile()
156 {
157   if(fNumTimeBits==0)
158     {
159       cerr<<"AliL3Compress::CompressFile() : Bitnumbers not set"<<endl;
160       return;
161     }
162   
163   Char_t fname[100];
164   sprintf(fname,"%s/comp/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
165   BIT_FILE *output = OpenOutputBitFile(fname);
166   
167   sprintf(fname,"%s/comp/tracks_m_%d_%d.raw",fPath,fSlice,fPatch);
168   FILE *input = fopen(fname,"r");
169   if(!input)
170     {
171       cerr<<"AliL3Compress::CompressFile() : Error opening file: "<<fname<<endl;
172       return;
173     }
174
175   AliL3TrackModel track;
176   AliL3ClusterModel cluster;
177   Int_t temp;
178   Int_t power;
179   
180   Int_t timeo,pado,chargeo,shapeo;
181   timeo=pado=chargeo=shapeo=0;
182   while(!feof(input))
183     {
184       if(fread(&track,sizeof(AliL3TrackModel),1,input)!=1) break;
185       
186       if(output->mask != 0x80) //Write the current byte to file.
187         {
188           //cerr<<"\nAliL3Compress::CompressFile() : Writing overhead bits!!!"<<endl;
189           if(putc(output->rack,output->file )!=output->rack)
190             cerr<<"AliL3Compress::ComressFile : Error writing to bitfile"<<endl;
191           output->mask=0x80;
192           output->rack=0;
193         }
194       
195       //Write track parameters:
196       fwrite(&track,sizeof(AliL3TrackModel),1,output->file);
197       for(Int_t i=0; i<track.fNClusters; i++)
198         {
199           if(fread(&cluster,sizeof(AliL3ClusterModel),1,input)!=1) break;
200           
201           //Write empty flag:
202           temp = (Int_t)cluster.fPresent;
203           OutputBit(output,temp);
204           if(!temp) continue;
205           
206           //Write time information:
207           temp = (Int_t)cluster.fDTime;
208           if(temp<0)
209             OutputBit(output,0);
210           else
211             OutputBit(output,1);
212           power = 1<<(fNumTimeBits-1);
213           if(abs(temp)>=power)
214             {
215               timeo++;
216               temp=power - 1;
217             }
218           OutputBits(output,abs(temp),(fNumTimeBits-1));
219           
220           //Write pad information:
221           temp = (Int_t)cluster.fDPad;
222           if(temp<0)
223             OutputBit(output,0);
224           else
225             OutputBit(output,1);
226           power = 1<<(fNumPadBits-1);
227           if(abs(temp)>=power)
228             {
229               pado++;
230               temp=power - 1;
231             }
232           OutputBits(output,abs(temp),(fNumPadBits-1));
233           
234           //Write charge information:
235           temp = (Int_t)cluster.fDCharge;
236           power = 1<<(fNumChargeBits);
237           if(abs(temp)>=power)
238             {
239               chargeo++;
240               temp=power - 1;
241             }
242           OutputBits(output,abs(temp),(fNumChargeBits));
243           
244           if(fWriteShape)
245             {
246               //Write shape information:
247               temp = (Int_t)cluster.fDSigmaY2;
248               if(temp<0)
249                 OutputBit(output,0);
250               else
251                 OutputBit(output,1);
252               power = 1<<(fNumShapeBits-1);
253               if(abs(temp) >= power)
254                 {
255                   shapeo++;
256                   temp = power - 1;
257                 }
258               OutputBits(output,abs(temp),(fNumShapeBits-1));
259               
260               temp = (Int_t)cluster.fDSigmaZ2;
261               if(temp<0)
262                 OutputBit(output,0);
263               else
264                 OutputBit(output,1);
265               power = 1<<(fNumShapeBits-1);
266               if(abs(temp) >= power)
267                 {
268                   shapeo++;
269                   temp=power - 1;
270                 }
271               OutputBits(output,abs(temp),(fNumShapeBits-1));
272             }
273         }
274     }
275   
276   fclose(input);
277   CloseOutputBitFile(output);
278   if(pado || timeo || chargeo || shapeo)
279     {
280       cout<<endl<<"Saturations: "<<endl
281           <<"Pad "<<pado<<endl
282           <<"Time "<<timeo<<endl
283           <<"Charge "<<chargeo<<endl
284           <<"Shape "<<shapeo<<endl;
285     }
286 }
287
288 void AliL3Compress::ExpandFile()
289 {
290   if(fNumTimeBits==0)
291     {
292       cerr<<"AliL3Compress::ExpandFile() : Bitnumbers not set"<<endl;
293       return;
294     }
295   
296   Char_t fname[100];
297   sprintf(fname,"%s/comp/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
298   BIT_FILE *input = OpenInputBitFile(fname);
299   
300   sprintf(fname,"%s/comp/tracks_u_%d_%d.raw",fPath,fSlice,fPatch);
301   FILE *output = fopen(fname,"w");
302   if(!output)
303     {
304       cerr<<"AliL3Compress::ExpandFile() : Error opening file: "<<fname<<endl;
305       return;
306     }
307
308   AliL3TrackModel trackmodel;
309   AliL3ClusterModel *clusters=0;
310   Int_t count=0;
311   
312   clusters = new AliL3ClusterModel[(AliL3Transform::GetNRows(fPatch))];
313   while(!feof(input->file))
314     {
315       input->mask=0x80;//make sure we read a new byte from file.
316       
317       //Read and write track:
318       if(fread(&trackmodel,sizeof(AliL3TrackModel),1,input->file)!=1) break;
319       fwrite(&trackmodel,sizeof(AliL3TrackModel),1,output);
320
321       memset(clusters,0,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel));
322       for(Int_t i=0; i<AliL3Transform::GetNRows(fPatch); i++)
323         {
324           Int_t temp,sign;
325           
326           //Read empty flag:
327           temp = InputBit(input);
328           if(!temp) 
329             {
330               clusters[i].fPresent=kFALSE;
331               continue;
332             }
333           clusters[i].fPresent=kTRUE;
334           
335           //Read time information:
336           sign=InputBit(input);
337           temp = InputBits(input,(fNumTimeBits-1));
338           if(!sign)
339             temp*=-1;
340           clusters[i].fDTime = temp;
341           
342           //Read pad information:
343           sign=InputBit(input);
344           temp = InputBits(input,(fNumPadBits-1));
345           if(!sign)
346             temp*=-1;
347           clusters[i].fDPad = temp;
348           
349           //Read charge information:
350           temp=InputBits(input,(fNumChargeBits));
351           clusters[i].fDCharge = temp;
352           
353           if(fWriteShape)
354             {
355               //Read shape information:
356               sign = InputBit(input);
357               temp = InputBits(input,(fNumShapeBits-1));
358               if(!sign)
359                 temp*=-1;
360               clusters[i].fDSigmaY2 = temp;
361               
362               sign = InputBit(input);
363               temp = InputBits(input,(fNumShapeBits-1));
364               if(!sign)
365                 temp*=-1;
366               clusters[i].fDSigmaZ2 = temp;
367             }
368         }
369       count++;
370       fwrite(clusters,(trackmodel.fNClusters)*sizeof(AliL3ClusterModel),1,output);
371       
372     }
373   
374   delete [] clusters;
375   fclose(output);
376   CloseInputBitFile(input);
377 }
378
379 void AliL3Compress::CreateDigitArray(Int_t maxnumber)
380 {
381   fNUsed=0;
382   fNDigits = 0;
383   fMaxDigits=maxnumber;
384   if(fDigits) delete [] fDigits;
385   fDigits = new AliL3RandomDigitData[maxnumber];
386   if(fDPt) delete [] fDPt;
387   fDPt = new AliL3RandomDigitData*[maxnumber];
388 }
389
390 void AliL3Compress::RestoreData(Char_t which)
391 {
392   //Restore the data.
393   //which == u : restore compressed data
394   //which == m : restore uncompressed data
395   
396   if(!fWriteShape)
397     {
398       cerr<<"AliL3Compress::RestoreData : Not implemented without shape info "<<endl;
399       return;
400     }
401
402   ReadFile(which);
403   
404   CreateDigitArray(10000000);
405   
406   Float_t pad,time,sigmaY2,sigmaZ2;
407   Int_t charge,npads;
408   for(Int_t j=AliL3Transform::GetFirstRow(fPatch); j<=AliL3Transform::GetLastRow(fPatch); j++)
409     {
410       cout<<"Building clusters on row "<<j<<endl;
411       for(Int_t i=0; i<fTracks->GetNTracks(); i++)
412         {
413           AliL3ModelTrack *track = (AliL3ModelTrack*)fTracks->GetCheckedTrack(i);
414           if(!track) continue;
415           if(!track->GetPad(j,pad) || 
416              !track->GetTime(j,time) || 
417              !track->GetClusterCharge(j,charge) ||
418              !track->GetXYWidth(j,sigmaY2) || 
419              !track->GetZWidth(j,sigmaZ2))
420             continue;
421           npads = track->GetNPads(j);
422           CreateDigits(j,npads,pad,time,charge,sigmaY2,sigmaZ2);
423         }
424     }
425   
426   QSort(fDPt,0,fNDigits);
427 }
428
429 void AliL3Compress::PrintDigits(Int_t padrow)
430 {
431   Int_t pad,time,charge,row;
432   for(Int_t i=0; i<fNDigits; i++)
433     {
434       row = fDPt[i]->fRow;
435       if(padrow > 0)
436         if(row != padrow) continue;
437       pad = fDPt[i]->fPad;
438       time = fDPt[i]->fTime;
439       charge = fDPt[i]->fCharge;
440       if(i>0 && row != fDPt[i-1]->fRow)
441         cout<<"---Padrow "<<row<<"---"<<endl;
442       cout<<"Padrow "<<row<<" Pad "<<pad<<" time "<<time<<" charge "<<charge<<endl;
443     }
444 }
445
446 void AliL3Compress::WriteRestoredData()
447 {
448     Char_t fname[100];
449   
450   //Get the remaining raw data array:
451   AliL3MemHandler *mem = new AliL3MemHandler();
452   sprintf(fname,"%s/comp/remains_%d_%d.raw",fPath,fSlice,fPatch);
453   mem->SetBinaryInput(fname);
454   UInt_t numdigits;
455   AliL3DigitRowData *origRow = mem->CompBinary2Memory(numdigits);
456   mem->CloseBinaryInput();
457   
458   //Allocate memory for the merged data:
459   UInt_t size = mem->GetAllocatedSize() + fNDigits*sizeof(AliL3DigitData);
460   cout<<"Allocating "<<size<<" bytes for merged data array "<<endl;
461   Byte_t *data = new Byte_t[size];
462   memset(data,0,size);
463   AliL3DigitRowData *tempRow = (AliL3DigitRowData*)data;
464
465   Int_t ndigits,action,charge;
466   UShort_t pad,time;
467       
468   UInt_t digit_counter;
469   Int_t row_counter=0;
470   for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
471     {
472       tempRow->fRow = i;
473       ndigits=0;
474       AliL3DigitData *origDig = origRow->fDigitData;
475       AliL3DigitData *tempDig = tempRow->fDigitData;
476       if((Int_t)origRow->fRow != i)
477         cerr<<"AliL3Compress::WriteRestoredData() : Mismatching row numbering "<<(Int_t)origRow->fRow<<" "<<i<<endl;
478
479       //cout<<"Writing row "<<i<<" with "<<(Int_t)origRow->fNDigit<<" old digits"<<endl;
480       digit_counter=0;
481       
482       while(1)
483         {
484           while(digit_counter < origRow->fNDigit)
485             {
486               pad = origDig[digit_counter].fPad;
487               time = origDig[digit_counter].fTime;
488               charge = origDig[digit_counter].fCharge;
489               digit_counter++;
490               while( (action=ComparePoints(i,pad,time)) == 1)
491                 {
492                   tempDig[ndigits].fPad = fDPt[fNUsed]->fPad;
493                   tempDig[ndigits].fTime = fDPt[fNUsed]->fTime;
494                   tempDig[ndigits].fCharge = fDPt[fNUsed]->fCharge;
495                   ndigits++;
496                   fNUsed++;
497
498                 }
499               if(action == 0)
500                 {
501                   tempDig[ndigits].fPad = pad;
502                   tempDig[ndigits].fTime = time;
503                   tempDig[ndigits].fCharge = charge;
504                   ndigits++;
505                 }
506             }
507           
508           if(fNUsed >= fNDigits) 
509             {
510               //cerr<<"AliL3Compress::WriteRestoredData() : Array out of range : "<<fNUsed<<" "<<fNDigits<<endl;
511               break;
512             }
513           if(fDPt[fNUsed]->fRow != i) //we are on a new row
514             break;
515           tempDig[ndigits].fPad = fDPt[fNUsed]->fPad;
516           tempDig[ndigits].fTime = fDPt[fNUsed]->fTime;
517           tempDig[ndigits].fCharge = fDPt[fNUsed]->fCharge;
518           ndigits++;
519           fNUsed++;
520         }
521       //cout<<"Writing "<<ndigits<<" digits on row "<<i<<endl;
522       if(ndigits > 4)
523         {
524           row_counter++;
525         }
526       tempRow->fNDigit = ndigits;
527       Int_t size = sizeof(AliL3DigitData)*tempRow->fNDigit + sizeof(AliL3DigitRowData);
528       Byte_t *byte_pt = (Byte_t*)tempRow;
529       byte_pt += size;
530       tempRow = (AliL3DigitRowData*)byte_pt;
531       mem->UpdateRowPointer(origRow);
532     }
533   
534   if(row_counter != AliL3Transform::GetNRows(fPatch))
535     cerr<<"AliL3Compress::WriteRestoredData() : Written rows: "<<row_counter<<" total rows "<<AliL3Transform::GetNRows(fPatch)<<endl;
536   
537   mem->Free();  
538   sprintf(fname,"%s/comp/restored_%d_%d.raw",fPath,fSlice,fPatch);
539   mem->SetBinaryOutput(fname);
540   mem->Memory2CompBinary((UInt_t)AliL3Transform::GetNRows(fPatch),(AliL3DigitRowData*)data);
541   mem->CloseBinaryOutput();
542   
543   delete [] data;
544   delete mem;
545   
546 }
547
548 void AliL3Compress::CreateDigits(Int_t row,Int_t npads,Float_t pad,Float_t time,Int_t charge,Float_t sigmaY2,Float_t sigmaZ2)
549 {
550   //Create raw data out of the cluster.
551     
552   if(npads == 1)//If there was only 1 pad, the xywidth is set to zero.
553     sigmaY2 = 0;
554   
555   if(sigmaY2 < 0 || sigmaZ2 <= 0)
556     {
557       cerr<<"AliL3Compress::CreateDigits() : Wrong sigmas : "<<sigmaY2<<" "<<sigmaZ2;
558       cerr<<" on row "<<row<<" pad "<<pad<<" time "<<time<<endl;
559       return;
560     }
561   
562   TRandom *random = new TRandom();
563   
564   Int_t entries=2000;
565   TH1F *hist1 = new TH1F("hist1","",AliL3Transform::GetNPads(row),0,AliL3Transform::GetNPads(row)-1);
566   TH1F *hist2 = new TH1F("hist2","",AliL3Transform::GetNTimeBins(),0,AliL3Transform::GetNTimeBins()-1);
567   TH2F *hist3 = new TH2F("hist3","",AliL3Transform::GetNPads(row),0,AliL3Transform::GetNPads(row)-1,AliL3Transform::GetNTimeBins(),0,AliL3Transform::GetNTimeBins()-1);
568
569
570   
571   //Create the distributions in pad and time:
572   for(Int_t i=0; i<entries; i++)
573     {
574       hist1->Fill(random->Gaus(pad,sqrt(sigmaY2)));
575       hist2->Fill(random->Gaus(time,sqrt(sigmaZ2)));
576     }
577     
578   //Create the cluster:
579   Int_t bin1,bin2;
580   Double_t content1,content2,dpad,dtime;
581   for(Int_t i=0; i<hist1->GetEntries(); i++)
582     {
583       bin1 = hist1->GetBin(i);
584       content1 = hist1->GetBinContent(bin1);
585       if((Int_t)content1==0) continue;
586       content1 = charge*content1/entries;
587       dpad = hist1->GetBinCenter(bin1);
588       for(Int_t j=0; j<hist2->GetEntries(); j++)
589         {
590           bin2 = hist2->GetBin(j);
591           content2 = hist2->GetBinContent(bin2);
592           if((Int_t)content2==0) continue;
593           content2 = content1*content2/entries;
594           dtime = hist2->GetBinCenter(bin2);
595           hist3->Fill(dpad,dtime,content2);
596         }
597     }
598   
599   Int_t local_dig=0;
600   //Fill it into the digit array:
601   for(Int_t i=0; i<hist3->GetNbinsX(); i++)
602     {
603       for(Int_t j=0; j<hist3->GetNbinsY(); j++)
604         {
605           bin1 = hist3->GetBin(i,j);
606           content1 = hist3->GetBinContent(bin1);
607           if((Int_t)content1 < 3) continue;
608           if(content1 >= 1024)
609             content1 = 1023;
610           if(fNDigits >= fMaxDigits)
611             {
612               cerr<<"AliL3Compress::CreateDigits() : Array index out of range : "<<fNDigits<<endl;
613               return;
614             }
615           fDigits[fNDigits].fCharge=(Int_t)content1;
616           fDigits[fNDigits].fRow = row;
617           fDigits[fNDigits].fPad = (Int_t)hist3->GetXaxis()->GetBinCenter(i);
618           fDigits[fNDigits].fTime = (Int_t)hist3->GetYaxis()->GetBinCenter(j);
619           fDPt[fNDigits] = &fDigits[fNDigits];
620           fNDigits++;
621           local_dig++;
622         }
623     }
624   //if(local_dig < 5)
625   //  cout<<"Small cluster "<<local_dig<<" pad "<<(Int_t)fDigits[fNDigits-1].fPad<<" time "<<(Int_t)fDigits[fNDigits-1].fTime<<endl;
626   
627   delete random;
628   delete hist1;
629   delete hist2;
630   delete hist3;
631 }
632
633 void AliL3Compress::PrintCompRatio(FILE *outfile)
634 {
635   Char_t fname[100];
636   sprintf(fname,"%s/comp/remains_%d_%d.raw",fPath,fSlice,fPatch);
637   AliL3MemHandler *mem = new AliL3MemHandler();
638   if(!mem->SetBinaryInput(fname))
639     {
640       cerr<<"AliL3Compress::PrintCompRatio(): Error opening file: "<<fname<<endl;
641       return;
642     } 
643   UInt_t ndigits;
644   AliL3DigitRowData *rowPt = (AliL3DigitRowData*)mem->CompBinary2Memory(ndigits);
645   mem->CloseBinaryInput();
646
647   Int_t digit_counter=0;
648   for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
649     {
650       digit_counter += rowPt->fNDigit;
651       mem->UpdateRowPointer(rowPt);
652     }
653   delete mem;
654   
655   sprintf(fname,"%s/comp/tracks_c_%d_%d.raw",fPath,fSlice,fPatch);
656   FILE *file1 = fopen(fname,"r");
657   if(!file1)
658     {
659       cerr<<"AliL3Compress::PrintCompRatio(): Error opening file: "<<fname<<endl;
660       return;
661     }
662   fseek(file1,0,SEEK_END);
663   UInt_t filesize1 = (UInt_t)ftell(file1);
664   fclose(file1);
665   
666   sprintf(fname,"%s/digits_%d_%d.raw",fPath,fSlice,fPatch);
667   FILE *file2 = fopen(fname,"r");
668   if(!file2)
669     {
670       cerr<<"AliL3Compress::PrintCompRatio(): Error opening file: "<<fname<<endl;
671       return;
672     }
673   fseek(file2,0,SEEK_END);
674   UInt_t filesize2 = (UInt_t)ftell(file2);
675   fclose(file2);
676   
677   if(outfile)
678     fprintf(outfile,"%f\n",(Float_t)(filesize1 + (10*digit_counter)/8)/(Float_t)(filesize2));
679   else
680     {
681       cout<<"----------------------"<<endl;
682       cout<<"Original file size   : "<<filesize2<<endl;
683       cout<<"Compressed file size : "<<filesize1<<endl;
684       cout<<"Remaining digits     : "<<digit_counter<<endl;
685       cout<<"Compression ratio    : "<<(Float_t)(filesize1 + (10*digit_counter)/8)/(Float_t)(filesize2)<<endl;
686     }
687 }
688
689 void AliL3Compress::QSort(AliL3RandomDigitData **a, Int_t first, Int_t last)
690 {
691   
692   // Sort array of AliL3RandomDigitData pointers using a quicksort algorithm.
693   // Uses CompareDigits() to compare objects.
694   // Thanks to Root!
695   
696   static AliL3RandomDigitData *tmp;
697   static int i;           // "static" to save stack space
698   int j;
699   
700   while (last - first > 1) {
701     i = first;
702     j = last;
703     for (;;) {
704       while (++i < last && CompareDigits(a[i], a[first]) < 0)
705         ;
706       while (--j > first && CompareDigits(a[j], a[first]) > 0)
707         ;
708       if (i >= j)
709         break;
710       
711       tmp  = a[i];
712       a[i] = a[j];
713       a[j] = tmp;
714     }
715     if (j == first) {
716       ++first;
717       continue;
718     }
719     tmp = a[first];
720     a[first] = a[j];
721     a[j] = tmp;
722     if (j - first < last - (j + 1)) {
723       QSort(a, first, j);
724       first = j + 1;   // QSort(j + 1, last);
725     } else {
726       QSort(a, j + 1, last);
727       last = j;        // QSort(first, j);
728     }
729   }
730 }
731
732 void AliL3Compress::WriteRootFile(Char_t *newrootfile,Char_t *digitfile)
733 {
734 #ifdef use_aliroot
735   Char_t fname[100];
736   AliL3MemHandler *mem = new AliL3MemHandler();
737   sprintf(fname,"%s/comp/remains_%d_%d.raw",fPath,fSlice,fPatch);
738   mem->Init(fSlice,fPatch);
739   mem->SetBinaryInput(fname);
740   UInt_t ndigits;
741   AliL3DigitRowData *rowPt = (AliL3DigitRowData*)mem->CompBinary2Memory(ndigits);
742   mem->CloseBinaryInput();
743   
744   if(!digitfile)
745     sprintf(fname,"%s/digitfile.root",fPath);
746   else
747     sprintf(fname,"%s",digitfile);
748
749   AliL3FileHandler *file = new AliL3FileHandler();
750   if(!file->SetAliInput(fname))
751     {
752       cerr<<"AliL3Compress::WriteRootFile() : Error opening file: "<<fname<<endl;
753       return;
754     }
755
756   file->Init(fSlice,fPatch);
757   file->AliDigits2RootFile(rowPt,newrootfile);
758   file->CloseAliInput();
759
760   delete mem;
761   delete file;
762 #endif
763   return;
764 }