]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/src/AliL3MemHandler.cxx
Cleaned up code for coding conventions.
[u/mrichter/AliRoot.git] / HLT / src / AliL3MemHandler.cxx
1 // @(#) $Id$
2
3 // Author: Uli Frankenfeld <mailto:franken@fi.uib.no>, Anders Vestbo <mailto:vestbo$fi.uib.no>, Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
4 //*-- Copyright &copy ALICE HLT Group 
5
6 #include "AliL3StandardIncludes.h"
7
8 #include "AliL3Logging.h"
9 #include "AliL3Transform.h"
10 #include "AliL3TrackSegmentData.h"
11 #include "AliL3SpacePointData.h"
12 #include "AliL3TrackArray.h"
13 #include "AliL3MemHandler.h"
14
15 #if __GNUC__ == 3
16 using namespace std;
17 #endif
18
19 /** \class AliL3MemHandler 
20 <pre>
21 //_____________________________________________________________
22 // AliL3MemHandler
23 //
24 // The HLT Binary File handler 
25 //
26 //  This class does all the memory I/O handling of HLT binary files.
27 //  
28 //  Examples:
29 //  ---------
30 //
31 //  1) Reading a binary file:
32 //  
33 //  AliL3MemHandler file;
34 //  file.SetBinaryInput(filename);
35 //  file.Init(slice,patch);
36 //
37 //  UInt_t nrowss;
38 //  AliL3DigitRowData *data = file.CompBinary2Memory(nrows);
39 //  
40 //  for(int i=0; i<nrows; i++) 
41 //    {
42 //    
43 //    AliL3DigitData *dataPt = (AliL3DigitData*)data->fDigitData;
44 //    for(int j=0; j<data->fNDigit; j++) 
45 //      {
46 //        pad = dataPt[j].fPad;
47 //        time = dataPt[j].fTime;
48 //        charge = dataPt[j].fCharge;
49 //      }
50 //     
51 //    file.UpdateRowPointer(data);
52 //  
53 //    }
54 //  file.CloseBinaryInput();
55 //  ________________________
56 //  
57 //  2) Writing a binary file:
58 //  
59 //  //First of all you need to store the data in memory,
60 //  //and have a pointer to it of type AliL3DigitRowData.
61 //  //E.g. if you just want to write the data you read in example 1)
62 //  //into a new file, you can do the following:
63 //  
64 //  AliL3MemHandler newfile;
65 //  newfile.Init(slice,patch);
66 //  newfile.SetBinaryOutput(newfilename);
67 //  newfile.Memory2CompBinary((UInt_t)NumberOfRowsInPatch,(AliL3DigitRowData*)data);
68 //  newfile.CloseBinaryOutput();
69 //
70 //
71 // Compressed file format:
72 // -----------------------
73 //
74 // The data is RLE encoded and currently using _10_ bit range for the ADC-values.
75 </pre>
76 */  
77   
78 ClassImp(AliL3MemHandler)
79   
80 AliL3MemHandler::AliL3MemHandler()
81
82   //Constructor
83   fPt = 0;
84   fSize =0;
85   fInBinary = 0;
86   fOutBinary = 0;
87   fNRandom = 0;
88   Init(0,0);
89   fIsRandom = kFALSE;
90   fRandomDigits = 0;
91   fDPt =0;
92   fNGenerate = 0;
93   fNUsed = 0;
94   fNDigits = 0;
95   ResetROI();
96 }
97
98
99 AliL3MemHandler::~AliL3MemHandler()
100 {
101   //Destructor
102   if(fPt) delete[] fPt;
103   if(fRandomDigits) delete [] fRandomDigits;
104   if(fDPt) delete [] fDPt;
105 }
106
107 void AliL3MemHandler::Init(Int_t s,Int_t p, Int_t *r)
108 {
109   //init handler
110   fSlice=s;fPatch=p;
111   if(r) {
112     fRowMin=r[0];
113     fRowMax=r[1];
114   }else{
115      fRowMin=AliL3Transform::GetFirstRow(p);
116      fRowMax=AliL3Transform::GetLastRow(p); 
117   }
118   ResetROI();
119 }
120
121 void AliL3MemHandler::ResetROI()
122 {
123   //Resets the Look-up table for Region of Interest mode.
124   for(Int_t i=fRowMin; i<=fRowMax; i++)
125     {
126       fEtaMinTimeBin[i] = 0;
127       fEtaMaxTimeBin[i] = AliL3Transform::GetNTimeBins()-1;
128     }
129 }
130
131 void AliL3MemHandler::SetROI(Float_t *eta,Int_t */*slice*/)
132 {
133   // Init the Look-up table for the Region of Interest mode.
134   //   Here you can specify a certain etaregion, - all data
135   //   outside this region will be discarded:
136   //   eta[0] = mimium eta
137   //   eta[1] = maximum eta
138   //   slice[0] = mimumum slice
139   //   slice[1] = maximum slice
140
141
142   if(eta[1]==0)
143     {
144       LOG(AliL3Log::kWarning,"AliL3MemHandler::SetROI","Eta Values")
145         <<"Bad ROI parameters. IDIOT! "<<ENDLOG;
146       for(Int_t i=fRowMin; i<=fRowMax; i++)
147         {
148           fEtaMinTimeBin[i]=0;
149           fEtaMaxTimeBin[i]=0;
150         }
151       return;
152     }
153   
154   for(Int_t i=fRowMin; i<=fRowMax; i++)
155     {
156       Int_t sector,row;
157       Float_t xyz[3];
158       
159       Float_t thetamax = 2*atan(exp(-1.*eta[1]));
160       
161       xyz[0] = AliL3Transform::Row2X(i);
162       xyz[1]=0;
163       xyz[2] = xyz[0]/tan(thetamax);
164       AliL3Transform::Slice2Sector(fSlice,i,sector,row);
165       AliL3Transform::Local2Raw(xyz,sector,row);
166       
167       fEtaMinTimeBin[i] = (Int_t)xyz[2];
168       
169       if(eta[0]==0)
170         fEtaMaxTimeBin[i] = 445;
171       else
172         {
173           Float_t thetamin = 2*atan(exp(-1.*eta[0]));
174           xyz[0] = AliL3Transform::Row2X(i);
175           xyz[1] = AliL3Transform::GetMaxY(i);
176           Float_t radii = sqrt(pow(xyz[0],2) + pow(xyz[1],2));
177           xyz[2] = radii/tan(thetamin);
178           AliL3Transform::Local2Raw(xyz,sector,row);
179           fEtaMaxTimeBin[i] = (Int_t)xyz[2];
180         }
181     }
182   
183 }
184
185 Bool_t AliL3MemHandler::SetBinaryInput(char *name)
186 {
187   //Set the input binary file.
188   fInBinary = fopen(name,"r");
189   if(!fInBinary){
190     LOG(AliL3Log::kWarning,"AliL3MemHandler::SetBinaryInput","File Open")
191       <<"Error opening file "<<name<<ENDLOG;
192     return kFALSE;
193   }
194   return kTRUE;
195 }
196
197 Bool_t AliL3MemHandler::SetBinaryInput(FILE *file)
198 {
199   //Set the input binary file.
200   fInBinary = file;
201   if(!fInBinary){
202     LOG(AliL3Log::kWarning,"AliL3MemHandler::SetBinaryInput","File Open")
203     <<"Pointer to File = 0x0 "<<ENDLOG;
204     return kFALSE;
205   }
206   return kTRUE;
207 }
208
209 void AliL3MemHandler::CloseBinaryInput()
210 {
211   //Close the input file.
212   if(!fInBinary){
213     LOG(AliL3Log::kWarning,"AliL3MemHandler::CloseBinaryInput","File Close")
214       <<"Nothing to Close"<<ENDLOG;
215     return;
216   }
217   fclose(fInBinary);
218   fInBinary =0;
219 }
220
221 Bool_t AliL3MemHandler::SetBinaryOutput(char *name)
222 {
223   //Set the binary output file.
224     fOutBinary = fopen(name,"w");
225   if(!fOutBinary){
226     LOG(AliL3Log::kWarning,"AliL3MemHandler::SetBinaryOutput","File Open")
227       <<"Pointer to File = 0x0 "<<ENDLOG;
228     return kFALSE;
229   }
230   return kTRUE;
231 }
232
233 Bool_t AliL3MemHandler::SetBinaryOutput(FILE *file)
234 {
235   //Set the binary output file.
236     fOutBinary = file;
237   if(!fOutBinary){
238     LOG(AliL3Log::kWarning,"AliL3MemHandler::SetBinaryOutput","File Open")
239       <<"Pointer to File = 0x0 "<<ENDLOG;
240     return kFALSE;
241   }
242   return kTRUE;
243 }
244
245 void AliL3MemHandler::CloseBinaryOutput()
246 {
247   //close binary  
248   if(!fOutBinary){
249     LOG(AliL3Log::kWarning,"AliL3MemHandler::CloseBinaryOutPut","File Close")
250       <<"Nothing to Close"<<ENDLOG;
251     return;
252   }
253   fclose(fOutBinary);
254   fOutBinary =0;
255 }
256
257 UInt_t AliL3MemHandler::GetFileSize()
258 {
259   //Returns the file size in bytes of the input file.
260   if(!fInBinary){
261     LOG(AliL3Log::kWarning,"AliL3MemHandler::GetFileSize","File")
262       <<"No Input File"<<ENDLOG;
263     return 0;
264   }
265   fseek(fInBinary,0,SEEK_END);
266   UInt_t size = (UInt_t) ftell(fInBinary);
267   rewind(fInBinary);
268   return size; 
269 }
270
271 Byte_t *AliL3MemHandler::Allocate()
272 {
273   //Allocate
274   return Allocate(GetFileSize()); 
275 }
276
277 Byte_t *AliL3MemHandler::Allocate(AliL3TrackArray *array)
278 {
279   //Allocate memory for tracks in memory. Used by TrackArray2Binary()
280   if(!array){
281     LOG(AliL3Log::kWarning,"AliL3MemHandler::Allocate","Memory")
282       <<"Pointer to AliL3TrackArray = 0x0 "<<ENDLOG;
283     return 0;
284   }
285   return Allocate(array->GetOutSize()); 
286 }
287
288 Byte_t *AliL3MemHandler::Allocate(UInt_t size)
289 {
290   //Allocate memory of size in bytes.
291   if(fPt){
292     LOG(AliL3Log::kWarning,"AliL3MemHandler::Allocate","Memory")
293       <<"Delete Memory"<<ENDLOG;
294     Free();
295   } 
296   fPt = new Byte_t[size];
297   fSize = size;
298   memset(fPt,0,fSize);
299   LOG(AliL3Log::kDebug,"AliL3MemHandler::Allocate","Memory")
300   <<AliL3Log::kDec<<"Allocate "<<size<<" Bytes of Memory"<<ENDLOG;
301   return fPt;
302 }
303
304 void AliL3MemHandler::Free()
305 {
306   //Clear the memory, if allocated.
307   if(!fPt){
308     LOG(AliL3Log::kInformational,"AliL3MemHandler::Free","Memory")
309       <<"No Memory allocated - can't Free"<<ENDLOG;
310     return;
311   }  
312   delete[] fPt;
313   fPt = 0;
314   fSize =0;
315 }
316
317 ///////////////////////////////////////// Random
318 void AliL3MemHandler::SetRandomSeed()
319 {
320   //If you are adding random data to the original data.
321   time_t *tp=0;
322   SetRandomSeed(time(tp));
323 }
324
325 void AliL3MemHandler::SetRandomCluster(Int_t maxnumber)
326 {
327   //If you are adding random data to the original data.
328   
329   fIsRandom = kTRUE;
330   fNRandom = maxnumber;
331   fNDigits = 0;
332   if(fRandomDigits) delete [] fRandomDigits;
333   fRandomDigits = new AliL3RandomDigitData[fNRandom*9];
334   if(fDPt) delete [] fDPt;
335   fDPt = new AliL3RandomDigitData *[fNRandom*9];
336 }
337
338 void AliL3MemHandler::QSort(AliL3RandomDigitData **a, Int_t first, Int_t last)
339 {
340
341    // Sort array of AliL3RandomDigitData pointers using a quicksort algorithm.
342    // Uses CompareDigits() to compare objects.
343    // Thanks to Root!
344
345    static AliL3RandomDigitData *tmp;
346    static int i;           // "static" to save stack space
347    int j;
348
349    while (last - first > 1) {
350       i = first;
351       j = last;
352       for (;;) {
353          while (++i < last && CompareDigits(a[i], a[first]) < 0)
354             ;
355          while (--j > first && CompareDigits(a[j], a[first]) > 0)
356             ;
357          if (i >= j)
358             break;
359
360          tmp  = a[i];
361          a[i] = a[j];
362          a[j] = tmp;
363       }
364       if (j == first) {
365          ++first;
366          continue;
367       }
368       tmp = a[first];
369       a[first] = a[j];
370       a[j] = tmp;
371
372       if (j - first < last - (j + 1)) {
373         QSort(a, first, j);
374         first = j + 1;   // QSort(j + 1, last);
375       } else {
376         QSort(a, j + 1, last);
377         last = j;        // QSort(first, j);
378       }
379    }
380 }
381
382 UInt_t AliL3MemHandler::GetRandomSize() const
383 {
384   //get random size
385   Int_t nrandom = 0;
386   for(Int_t r=fRowMin;r<=fRowMax;r++){
387     Int_t npad=AliL3Transform::GetNPads(r);
388     nrandom  += Int_t (fNGenerate * ((Double_t) npad/141.));
389   }
390   return 9 * nrandom * sizeof(AliL3DigitData);
391 }
392
393 void AliL3MemHandler::Generate(Int_t row)
394 {
395   //Generate random data on row, if you didn't 
396   //ask for this, nothing happens here.
397   
398   if(!fIsRandom) return;
399   ResetRandom();
400   fNDigits = 0;
401   Int_t npad=AliL3Transform::GetNPads(row);
402   Int_t ntime = fEtaMaxTimeBin[row] - fEtaMinTimeBin[row];
403   Int_t nrandom  = Int_t (fNGenerate * ((Double_t) npad/141.) * 
404                           (Double_t) ntime/(Double_t) AliL3Transform::GetNTimeBins() );
405   
406   for(Int_t n=0;n<nrandom;n++){
407     Int_t pad = (int)((float)rand()/RAND_MAX*npad);
408     Int_t time =(int)((float)rand()/RAND_MAX*ntime+fEtaMinTimeBin[row] );
409     Int_t charge = (int)((float)rand()/RAND_MAX*AliL3Transform::GetADCSat());
410     DigitizePoint(row,pad,time,charge);
411   }
412   QSort(fDPt,0,fNDigits);
413 }
414
415
416 void AliL3MemHandler::DigitizePoint(Int_t row, Int_t pad, 
417                                     Int_t time,Int_t charge)
418 {
419   //Making one single random cluster.
420   for(Int_t j=-1;j<2;j++){
421     for(Int_t k=-1;k<2;k++){
422       Int_t dcharge = charge;
423       if(j) dcharge /=2;
424       if(k) dcharge /=2;
425       if(dcharge<10) continue;
426       Int_t dpad  = j + pad;
427       Int_t dtime = k + time;
428       
429       if(dpad<0||dpad>=AliL3Transform::GetNPads(row))  continue;
430       if(dtime<0||dtime>=AliL3Transform::GetNTimeBins()) continue;
431       
432       fRandomDigits[fNDigits].fCharge = dcharge;
433       fRandomDigits[fNDigits].fRow = row;
434       fRandomDigits[fNDigits].fPad = dpad;
435       fRandomDigits[fNDigits].fTime = dtime;
436       fDPt[fNDigits] = &fRandomDigits[fNDigits];
437       fNDigits++;
438     }
439   }
440 }
441
442 ///////////////////////////////////////// Digit IO  
443 Bool_t AliL3MemHandler::Memory2Binary(UInt_t nrow,AliL3DigitRowData *data)
444 {
445   //Write data to the outputfile as is. No run-length encoding is done.
446   
447   if(!fOutBinary){
448     LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2Binary","File")
449       <<"No Output File"<<ENDLOG;
450     return kFALSE;
451   }
452   if(!data){
453     LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2Binary","Memory")
454       <<"Pointer to AliL3DigitRowData = 0x0 "<<ENDLOG;
455     return kFALSE;
456   }
457   
458   AliL3DigitRowData *row_pt = data; 
459   Int_t outsize = 0;
460   for(UInt_t i=0;i<nrow;i++){
461     Int_t size = sizeof(AliL3DigitData) * row_pt->fNDigit 
462       + sizeof(AliL3DigitRowData);
463     outsize += size;
464     fwrite(row_pt,size,1,fOutBinary);
465     Byte_t  *byte_pt =(Byte_t *) row_pt;
466     byte_pt += size;
467     row_pt = (AliL3DigitRowData *) byte_pt;
468   }
469   LOG(AliL3Log::kDebug,"AliL3MemHandler::Memory2Binary","Memory")
470     <<AliL3Log::kDec<<"Wrote "<<outsize<<" Bytes to Memory ("
471     <<nrow<<" Rows)"<<ENDLOG;
472   return kTRUE;
473 }
474
475 Bool_t AliL3MemHandler::Binary2Memory(UInt_t & nrow,AliL3DigitRowData *data)
476 {
477   //Read inputfile into memory as is, and store it in data. 
478   // No run-length encoding is assumed.
479
480   if(!fInBinary){
481     LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2Memory","File")
482       <<"No Input File"<<ENDLOG;
483     return kFALSE;
484   }
485   if(!data){
486     LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2Memory","Memory")
487       <<"Pointer to AliL3DigitRowData = 0x0 "<<ENDLOG;
488     return kFALSE;
489   }
490   rewind(fInBinary);
491   AliL3DigitRowData *row_pt = data;
492   UInt_t rowcount = 0;
493   Int_t outsize =0;
494   while(!feof(fInBinary)){
495     Byte_t  *byte_pt =(Byte_t *) row_pt;
496
497     if(fread(row_pt,sizeof(AliL3DigitRowData),1,fInBinary)!=1) break;
498
499     byte_pt += sizeof(AliL3DigitRowData);
500     outsize += sizeof(AliL3DigitRowData);
501
502     Int_t size = sizeof(AliL3DigitData) * row_pt->fNDigit;
503
504     //if(fread(byte_pt,size,1,fInBinary)!=1) break;
505     fread(byte_pt,size,1,fInBinary);
506     byte_pt += size;
507     outsize += size;
508     row_pt = (AliL3DigitRowData *) byte_pt;
509     rowcount++;
510   }  
511   nrow= rowcount;
512     LOG(AliL3Log::kDebug,"AliL3MemHandler::Binary2Memory","Memory")
513     <<AliL3Log::kDec<<"Wrote "<<outsize<<" Bytes to Memory ("
514     <<rowcount<<" Rows)"<<ENDLOG;
515   return kTRUE;
516 }
517
518 void AliL3MemHandler::AddData(AliL3DigitData *data,UInt_t & ndata,
519                               UInt_t /*row*/,UShort_t pad,UShort_t time,UShort_t charge) const
520 {
521   //add some data
522   data[ndata].fPad = pad;
523   data[ndata].fTime = time;
524   data[ndata].fCharge = charge;
525   ndata++;
526 }
527
528 void AliL3MemHandler::AddRandom(AliL3DigitData *data, UInt_t & ndata)
529 {
530   //add some random data
531   data[ndata].fPad = fDPt[fNUsed]->fPad;
532   data[ndata].fTime = fDPt[fNUsed]->fTime;
533   data[ndata].fCharge = fDPt[fNUsed]->fCharge;
534   ndata++;
535   fNUsed++;
536 }
537
538 void AliL3MemHandler::MergeDataRandom(AliL3DigitData *data, UInt_t & ndata,
539                                       UInt_t row, UShort_t pad, UShort_t time, UShort_t charge)
540 {
541   //merge random data
542   data[ndata].fPad = pad;
543   data[ndata].fTime = time;
544   data[ndata].fCharge = charge;
545   while(ComparePoints(row,pad,time)==0){
546     Int_t ch = data[ndata].fCharge + fDPt[fNUsed]->fCharge;
547     if(charge>=AliL3Transform::GetADCSat()) ch = AliL3Transform::GetADCSat();
548     data[ndata].fCharge = ch;
549     fNUsed++;
550   }
551   ndata++;
552 }
553
554 void AliL3MemHandler::AddDataRandom(AliL3DigitData *data, UInt_t & ndata,
555                    UInt_t row, UShort_t pad, UShort_t time, UShort_t charge)
556 {
557   //add data random
558   Int_t action;
559   while((action=ComparePoints(row,pad,time))==1){
560     AddRandom(data,ndata);
561   }
562   if(action==0){
563     MergeDataRandom(data,ndata,row,pad,time,charge);
564   }
565   if(action<0){
566     AddData(data,ndata,row,pad,time,charge);
567   }  
568 }
569
570 void AliL3MemHandler::Write(UInt_t *comp, UInt_t & index, 
571                             UInt_t & subindex, UShort_t value) const
572 {
573   //write compressed data
574   UInt_t shift[3] = {0,10,20};
575   if(subindex==0) comp[index] =0; //clean up memory
576   comp[index] |= (value&0x03ff)<<shift[subindex];
577   if(subindex == 2){
578     subindex = 0;
579     index++;
580   }
581   else subindex++;
582 }
583
584 UShort_t AliL3MemHandler::Read(UInt_t *comp, UInt_t & index, UInt_t & subindex) const
585
586   //read compressed data
587   UInt_t shift[3] = {0,10,20};
588   UShort_t value = (comp[index]>>shift[subindex])&0x03ff;
589   if(subindex == 2){
590     subindex = 0;
591     index++;
592   }
593   else subindex++;
594   
595   return value;
596 }
597
598 UShort_t AliL3MemHandler::Test(UInt_t *comp, 
599                                UInt_t index, UInt_t  subindex) const
600 {
601   //supi dupi test
602   UInt_t shift[3] = {0,10,20};
603   return (comp[index]>>shift[subindex])&0x03ff;
604 }
605
606 Int_t AliL3MemHandler::Memory2CompMemory(UInt_t nrow,
607                                          AliL3DigitRowData *data,UInt_t *comp)
608 {
609   //Performs run-length encoding on data stored in memory pointed to by data.
610   //The compressed data is written to comp.
611   if(!comp){
612     LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2CompMemory","Memory")
613       <<"Pointer to compressed data = 0x0 "<<ENDLOG;
614     return 0;
615   }
616   if(!data){
617     LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2CompMemory","Memory")
618       <<"Pointer to AliL3DigitRowData = 0x0 "<<ENDLOG;
619     return 0;
620   }
621   AliL3DigitRowData *row_pt = data;
622   UInt_t index=0;
623   UInt_t subindex=0;
624   
625   for(UInt_t i=0;i<nrow;i++){
626     UShort_t value = row_pt->fRow;
627     Write(comp,index,subindex,value);
628     UShort_t maxpad=0; 
629     UShort_t npad=0;
630     Int_t ddd[1000];
631     for(Int_t d=0;d<200;d++) ddd[d]=0;
632     for(UInt_t dig=0;dig<row_pt->fNDigit;dig++){
633       if(row_pt->fDigitData[dig].fPad <200){ 
634         ddd[row_pt->fDigitData[dig].fPad]++;
635       }
636     }
637     for(Int_t d=0;d<200;d++){ 
638       if(ddd[d]){
639         npad++;
640         maxpad =d;
641       }
642     }
643     Write(comp,index,subindex,npad);
644     UInt_t digit=0;
645     for(UShort_t pad=0;pad <= maxpad;pad++){
646       if(digit>=row_pt->fNDigit || row_pt->fDigitData[digit].fPad !=  pad)
647         continue;
648       Write(comp,index,subindex,pad);
649 //    write zero if time != 0
650       if(digit<row_pt->fNDigit && row_pt->fDigitData[digit].fPad == pad){
651         if(row_pt->fDigitData[digit].fTime>0){
652           Write(comp,index,subindex,0);
653           Write(comp,index,subindex,row_pt->fDigitData[digit].fTime);
654         }
655       }
656       while(digit<row_pt->fNDigit && row_pt->fDigitData[digit].fPad == pad){
657         UShort_t charge = row_pt->fDigitData[digit].fCharge;
658         if(charge>=1023){
659           charge=1023;
660         }
661         Write(comp,index,subindex,charge);
662         if(digit+1<row_pt->fNDigit&&row_pt->fDigitData[digit+1].fPad == pad){
663           if(row_pt->fDigitData[digit].fTime +1 !=
664                      row_pt->fDigitData[digit+1].fTime){
665             Write(comp,index,subindex,0);
666             UShort_t nzero = row_pt->fDigitData[digit+1].fTime - 
667                              (row_pt->fDigitData[digit].fTime +1);
668             Write(comp,index,subindex,nzero);
669           }  
670         }
671         digit++;
672       }
673       Write(comp,index,subindex,0);
674       Write(comp,index,subindex,0);
675     }
676     
677     Int_t size = sizeof(AliL3DigitData) * row_pt->fNDigit+
678                                             sizeof(AliL3DigitRowData);
679     Byte_t  *byte_pt =(Byte_t *) row_pt;
680     byte_pt += size;
681     row_pt = (AliL3DigitRowData *) byte_pt;
682   }
683   while(subindex)
684     Write(comp,index,subindex,0);
685   return index * sizeof(UInt_t);
686 }
687
688 Int_t AliL3MemHandler::CompMemory2Memory(UInt_t  nrow,
689                                          AliL3DigitRowData *data,UInt_t *comp)
690 {
691   //Uncompress the run-length encoded data in memory pointed to by comp, and
692   //  store it in data.
693
694   if(!comp){
695     LOG(AliL3Log::kWarning,"AliL3MemHandler::CompMemory2Memory","Memory")
696       <<"Pointer to compressed data = 0x0 "<<ENDLOG;
697     return 0;
698   }
699   if(!data){
700     LOG(AliL3Log::kWarning,"AliL3MemHandler::CompMemory2Memory","Memory")
701       <<"Pointer to AliL3DigitRowData = 0x0 "<<ENDLOG;
702     return 0;
703   }
704   Int_t outsize=0;
705   
706   AliL3DigitRowData *row_pt = data;
707   UInt_t index=0;
708   UInt_t subindex=0;
709   
710   for(UInt_t i=0;i<nrow;i++){
711     UInt_t ndigit=0;
712     UInt_t row =Read(comp,index,subindex);
713     row_pt->fRow=row;
714     Generate(row);
715     UShort_t npad = Read(comp,index,subindex);
716     for(UShort_t p=0;p<npad;p++){
717       UShort_t charge;
718       UShort_t time =0;
719       UShort_t pad = Read(comp,index,subindex);
720       if(Test(comp,index,subindex)==0){
721         Read(comp,index,subindex);
722         if( (time = Read(comp,index,subindex)) == 0 ){
723           continue;
724         }
725       }
726       for(;;){
727         while( (charge=Read(comp,index,subindex)) != 0){
728           if(time>=fEtaMinTimeBin[row]&&time<=fEtaMaxTimeBin[row])
729             //AddData(row_pt->fDigitData,ndigit,row,pad,time,charge);
730             //seems we are using this function... but dont know why
731             AddDataRandom(row_pt->fDigitData,ndigit,row,pad,time,charge);
732           time++;
733         }
734         UShort_t tshift = Read(comp,index,subindex);
735         if(tshift == 0) break;
736         time += tshift;
737       }
738     }
739     row_pt->fNDigit = ndigit;
740     Int_t size = sizeof(AliL3DigitData) * row_pt->fNDigit+
741       sizeof(AliL3DigitRowData);
742     Byte_t  *byte_pt =(Byte_t *) row_pt;
743     byte_pt += size;
744     outsize += size;
745     row_pt = (AliL3DigitRowData *) byte_pt;
746   }
747   return outsize;
748 }
749
750 UInt_t AliL3MemHandler::GetCompMemorySize(UInt_t nrow,AliL3DigitRowData *data) const
751 {
752   //Return the size of RLE data, after compressing data.
753   
754   if(!data){
755     LOG(AliL3Log::kWarning,"AliL3MemHandler::GetCompMemorySize","Memory")
756       <<"Pointer to AliL3DigitRowData = 0x0 "<<ENDLOG;
757     return 0;
758   }
759   AliL3DigitRowData *row_pt = data;
760   UInt_t index=0;
761   
762   for(UInt_t i=0;i<nrow;i++){
763     index++;
764     UShort_t maxpad=0; 
765     UShort_t npad=0;
766     Int_t ddd[1000];
767     for(Int_t d=0;d<200;d++) ddd[d]=0;
768     for(UInt_t dig=0;dig<row_pt->fNDigit;dig++){
769       if(row_pt->fDigitData[dig].fPad <200){ 
770         ddd[row_pt->fDigitData[dig].fPad]++;
771       }
772     }
773     for(Int_t d=0;d<200;d++){ 
774       if(ddd[d]){
775         npad++;
776         maxpad =d;
777       }
778     }
779     index++;
780     UInt_t digit=0;
781     for(UShort_t pad=0;pad <= maxpad;pad++){
782       if(digit>=row_pt->fNDigit || row_pt->fDigitData[digit].fPad !=  pad)
783         continue;
784       index++;
785       //    write zero if time != 0
786       if(digit<row_pt->fNDigit && row_pt->fDigitData[digit].fPad == pad){
787         if(row_pt->fDigitData[digit].fTime>0){
788           index++;
789           index++;
790         }
791       }
792       while(digit<row_pt->fNDigit && row_pt->fDigitData[digit].fPad == pad){
793         index++;
794         if(digit+1<row_pt->fNDigit&&row_pt->fDigitData[digit+1].fPad == pad){
795           if(row_pt->fDigitData[digit].fTime +1 !=
796                      row_pt->fDigitData[digit+1].fTime){
797             index++;
798             index++;
799           }  
800         }
801         digit++;
802       }
803       index++;
804       index++;
805     }
806
807     Int_t size = sizeof(AliL3DigitData) * row_pt->fNDigit+
808                                             sizeof(AliL3DigitRowData);
809     Byte_t  *byte_pt =(Byte_t *) row_pt;
810     byte_pt += size;
811     row_pt = (AliL3DigitRowData *) byte_pt;
812   }
813   while(index%3)
814     index++;
815   return (index/3) * sizeof(UInt_t);
816 }
817
818 UInt_t AliL3MemHandler::GetMemorySize(UInt_t nrow,UInt_t *comp) const
819 {
820   //get memory size
821   if(!comp){
822     LOG(AliL3Log::kWarning,"AliL3MemHandler::GetMemorySize","Memory")
823     <<"Pointer to compressed data = 0x0 "<<ENDLOG;
824     return 0;
825   }
826   Int_t outsize=0;
827
828   UInt_t index=0;
829   UInt_t subindex=0;
830
831   for(UInt_t i=0;i<nrow;i++){
832     UInt_t ndigit=0;
833     Read(comp,index,subindex);
834     UShort_t npad = Read(comp,index,subindex);
835     for(UShort_t p=0;p<npad;p++){
836       Read(comp,index,subindex);
837       if(Test(comp,index,subindex)==0){
838         Read(comp,index,subindex);
839         if(Read(comp,index,subindex)== 0) continue;
840       }
841       for(;;){
842         while(Read(comp,index,subindex)!=0) ndigit++;
843         if(Read(comp,index,subindex)==0) break;
844       }
845     }
846     Int_t size = sizeof(AliL3DigitData) * ndigit+
847                                         sizeof(AliL3DigitRowData);
848     outsize += size;
849   }
850    
851   return outsize;
852 }
853
854 UInt_t AliL3MemHandler::GetNRow(UInt_t *comp,UInt_t size)
855 {
856   //get number of rows
857   if(!comp){
858     LOG(AliL3Log::kWarning,"AliL3MemHandler::GetNRow","Memory")
859       <<"Pointer to compressed data = 0x0 "<<ENDLOG;
860     return 0;
861   }
862   size = size /4;
863   UInt_t nrow=0;
864   UInt_t index=0;
865   UInt_t subindex=0;
866   while(index<size-1){ //don't start with last word
867     nrow++;
868     UInt_t ndigit=0;
869     Read(comp,index,subindex);
870     UShort_t npad = Read(comp,index,subindex);
871     for(UShort_t p=0;p<npad;p++){
872       Read(comp,index,subindex);
873       if(Test(comp,index,subindex)==0){
874         Read(comp,index,subindex);
875         if(Read(comp,index,subindex)==0)continue;
876       }
877       for(;;){
878         while(Read(comp,index,subindex)!=0) ndigit++;
879         if(Read(comp,index,subindex)==0) break;
880       }
881     }
882   }
883   if(index==size-1){  //last word
884     if(subindex<2){
885       if(Read(comp,index,subindex)!=0) nrow++;
886     }
887   }
888   return nrow;
889 }
890
891 Bool_t AliL3MemHandler::CompMemory2CompBinary(UInt_t nrow,UInt_t *comp,
892                                               UInt_t size)
893 {
894   //Write the RLE data in comp to the output file.
895   
896   if(!fOutBinary){
897     LOG(AliL3Log::kWarning,"AliL3MemHandler::CompMemory2CompBinary","File")
898     <<"No Output File"<<ENDLOG;
899     return kFALSE;
900   }
901   if(!comp){
902     LOG(AliL3Log::kWarning,"AliL3MemHandler::CompMemory2CompBinary","Memory")
903     <<"Pointer to compressed data = 0x0 "<<ENDLOG;
904     return kFALSE;
905   }
906   if(size==0)
907     size=GetMemorySize(nrow,comp);
908   if(!size){
909     LOG(AliL3Log::kWarning,"AliL3MemHandler::CompMemory2CompBinary","Memory")
910     <<"Memory size = 0 "<<ENDLOG;
911     return kFALSE;
912   }
913   UInt_t length = size/sizeof(UInt_t);
914   fwrite(&length,sizeof(UInt_t),1,fOutBinary);  
915   fwrite(comp,size,1,fOutBinary);
916   return kTRUE;
917 }
918
919 Bool_t AliL3MemHandler::CompBinary2CompMemory(UInt_t & nrow,UInt_t *comp)
920 {
921   //Read the RLE data from file, and store it in comp. No unpacking yet.
922
923   if(!fInBinary){
924     LOG(AliL3Log::kWarning,"AliL3MemHandler::CompBinary2CompMemory","File")
925       <<"No Output File"<<ENDLOG;
926     return kFALSE;
927   }
928   if(!comp){
929     LOG(AliL3Log::kWarning,"AliL3MemHandler::CompBinary2CompMemory","Memory")
930       <<"Pointer to compressed data = 0x0 "<<ENDLOG;
931     return kFALSE;
932   }
933   rewind(fInBinary);
934   UInt_t length;
935   if(fread(&length,sizeof(UInt_t),1,fInBinary)!=1) return kFALSE;
936   UInt_t size = length*sizeof(UInt_t);
937   if(fread(comp,size,1,fInBinary)!=1) return kFALSE;
938   // now find the number of dig
939   nrow =  GetNRow(comp,size);
940   return kTRUE;
941 }
942
943 AliL3DigitRowData *AliL3MemHandler::CompBinary2Memory(UInt_t & nrow)
944 {
945   // Read the RLE inputfile, unpack it and return the pointer to it.
946   AliL3MemHandler * handler = new AliL3MemHandler();
947   handler->SetBinaryInput(fInBinary);
948   UInt_t *comp =(UInt_t *)handler->Allocate();
949   handler->CompBinary2CompMemory(nrow,comp);
950   UInt_t size = GetMemorySize(nrow,comp);
951   AliL3DigitRowData *data = (AliL3DigitRowData *)Allocate(size);
952   CompMemory2Memory(nrow,data,comp);
953   handler->Free();
954   delete handler;
955   return data;  
956 }
957
958 Bool_t AliL3MemHandler::Memory2CompBinary(UInt_t nrow,AliL3DigitRowData *data)
959 {
960   //Perform RLE on the data, and write it to the output file.
961   Bool_t out = kTRUE;
962   AliL3MemHandler * handler = new AliL3MemHandler();
963   UInt_t size = GetCompMemorySize(nrow,data);
964   UInt_t *comp =(UInt_t *)handler->Allocate(size);
965   Memory2CompMemory(nrow,data,comp);
966   CompMemory2CompBinary(nrow,comp,size);
967   handler->Free();
968   delete handler;
969   return out;
970 }
971
972
973 ///////////////////////////////////////// Point IO  
974 Bool_t AliL3MemHandler::Memory2Binary(UInt_t npoint,AliL3SpacePointData *data)
975 {
976   //Writing spacepoints stored in data to the outputfile.
977   if(!fOutBinary){
978     LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2Binary","File")
979       <<"No Output File"<<ENDLOG;
980     return kFALSE;
981   }
982   if(!data){
983     LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2Binary","Memory")
984       <<"Pointer to AliL3SpacePointData = 0x0 "<<ENDLOG;
985     return kFALSE;
986   }
987   UInt_t size = npoint*sizeof(AliL3SpacePointData);
988   fwrite(data,size,1,fOutBinary);
989   
990   return kTRUE;
991 }
992
993 Bool_t AliL3MemHandler::Transform(UInt_t npoint,AliL3SpacePointData *data,Int_t slice)
994 {
995   //Transform the space points in data, to global coordinates in slice.
996   if(!data){
997     LOG(AliL3Log::kWarning,"AliL3MemHandler::Transform","Memory")
998     <<"Pointer to AliL3SpacePointData = 0x0 "<<ENDLOG;
999     return kFALSE;
1000   }
1001   
1002   for(UInt_t i=0;i<npoint;i++){
1003     Float_t xyz[3];
1004     xyz[0] = data[i].fX;
1005     xyz[1] = data[i].fY;
1006     xyz[2] = data[i].fZ;
1007     AliL3Transform::Local2Global(xyz,slice);
1008     data[i].fX = xyz[0];
1009     data[i].fY = xyz[1];
1010     data[i].fZ = xyz[2];
1011   }
1012   return kTRUE;
1013 }
1014
1015 Bool_t AliL3MemHandler::Binary2Memory(UInt_t & npoint,AliL3SpacePointData *data)
1016 {
1017   //Read the space points in inputfile, and store it in data.
1018   if(!fInBinary){
1019     LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2Memory","File")
1020     <<"No Input File"<<ENDLOG;
1021     return kFALSE;
1022   }
1023   if(!data){
1024     LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2Memory","Memory")
1025     <<"Pointer to AliL3SpacePointData = 0x0 "<<ENDLOG;
1026     return kFALSE;
1027   }
1028
1029   Int_t size = GetFileSize(); 
1030   npoint = size/sizeof(AliL3SpacePointData);
1031   if(size==0) {
1032     LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2Memory","File")
1033     <<"File Size == 0"<<ENDLOG;
1034     return kFALSE;
1035   }
1036
1037   if(fread(data,size,1,fInBinary)!=1){
1038     LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File")
1039     <<"File Read Error "<<ENDLOG;
1040     return kFALSE;
1041   }
1042   if(size%sizeof(AliL3SpacePointData)){
1043     LOG(AliL3Log::kFatal,"AliL3MemHandler::Binary2Memory","File Size")
1044     <<"File Size wrong "<<ENDLOG;
1045     return kFALSE; 
1046   }
1047   LOG(AliL3Log::kDebug,"AliL3MemHandler::Binary2Memory","File")
1048   <<AliL3Log::kDec<<"Wrote  "<<size<<" Bytes to Memory"<<ENDLOG;
1049   return kTRUE;
1050 }
1051
1052 ///////////////////////////////////////// Track IO  
1053 Bool_t AliL3MemHandler::Memory2Binary(UInt_t ntrack,AliL3TrackSegmentData *data)
1054 {
1055   //Write the tracks stored in data, to outputfile.
1056   if(!fOutBinary){
1057     LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2Binary","File")
1058     <<"No Output File"<<ENDLOG;
1059     return kFALSE;
1060   }
1061   if(!data){
1062     LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2Binary","Memory")
1063     <<"Pointer to AliL3TrackSegmentData = 0x0 "<<ENDLOG;
1064     return kFALSE;
1065   }
1066   AliL3TrackSegmentData *track_pt = data;
1067   for(UInt_t i=0;i<ntrack;i++){
1068     Int_t size=sizeof(AliL3TrackSegmentData)+track_pt->fNPoints*sizeof(UInt_t); 
1069     fwrite(track_pt,size,1,fOutBinary);
1070     Byte_t *byte_pt = (Byte_t*) track_pt;
1071     byte_pt += size; 
1072     track_pt = (AliL3TrackSegmentData*) byte_pt;
1073   }
1074   LOG(AliL3Log::kDebug,"AliL3MemHandler::Memory2Binary","File")
1075   <<AliL3Log::kDec<<"Wrote  "<<ntrack<<" Tracks to File"<<ENDLOG;
1076   
1077   return kTRUE;
1078 }
1079
1080 Bool_t AliL3MemHandler::Binary2Memory(UInt_t & ntrack,AliL3TrackSegmentData *data)
1081 {
1082   //Read the tracks in inputfile, and store it in data.
1083   if(!fInBinary){
1084     LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2Memory","File")
1085     <<"No Input File"<<ENDLOG;
1086     return kFALSE;
1087   }
1088   if(!data){
1089     LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2Memory","Memory")
1090     <<"Pointer to AliL3TrackSegmentData = 0x0 "<<ENDLOG;
1091     return kFALSE;
1092   }
1093
1094   ntrack=0;
1095   AliL3TrackSegmentData *track_pt = data;
1096   rewind(fInBinary);
1097
1098   while(!feof(fInBinary)){
1099     if(fread(track_pt,sizeof(AliL3TrackSegmentData),1,fInBinary)!=1) break;
1100     Int_t size=track_pt->fNPoints*sizeof(UInt_t);
1101     if(fread(track_pt->fPointIDs,size,1,fInBinary)!=1) break;
1102     Byte_t *byte_pt = (Byte_t*) track_pt;
1103     byte_pt += sizeof(AliL3TrackSegmentData)+size;
1104     track_pt = (AliL3TrackSegmentData*) byte_pt;
1105     ntrack++; 
1106   }
1107   LOG(AliL3Log::kDebug,"AliL3MemHandler::Binary2Memory","File")
1108   <<AliL3Log::kDec<<"Wrote  "<<ntrack<<" Tracks to Memory"<<ENDLOG;
1109   return kTRUE;
1110 }
1111
1112 Bool_t AliL3MemHandler::TrackArray2Binary(AliL3TrackArray *array)
1113 {
1114   //Write the trackarray to the outputfile.
1115   if(!fOutBinary){
1116     LOG(AliL3Log::kWarning,"AliL3MemHandler::TrackArray2Binary","File")
1117     <<"No Output File"<<ENDLOG;
1118     return kFALSE;
1119   }
1120   if(!array){
1121     LOG(AliL3Log::kWarning,"AliL3MemHandler::TrackArray2Binary","Memory")
1122     <<"Pointer to AliL3TrackArray = 0x0 "<<ENDLOG;
1123     return kFALSE;
1124   }
1125   AliL3TrackSegmentData *data = (AliL3TrackSegmentData *)Allocate(array);
1126
1127   UInt_t ntrack;
1128   TrackArray2Memory(ntrack,data,array);
1129   Memory2Binary(ntrack,data);
1130   Free();
1131   return kTRUE;
1132 }
1133
1134 Bool_t AliL3MemHandler::Binary2TrackArray(AliL3TrackArray *array)
1135 {
1136   //Read the tracks in inputfile, and fill it in trackarray. 
1137   //array should already be constructed.
1138   if(!fInBinary){
1139     LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2TrackArray","File")
1140     <<"No Input File"<<ENDLOG;
1141     return kFALSE;
1142   }
1143   if(!array){
1144     LOG(AliL3Log::kWarning,"AliL3MemHandler::Binary2TrackArray","Memory")
1145     <<"Pointer to AliL3TrackArray = 0x0 "<<ENDLOG;
1146     return kFALSE;
1147   }
1148   AliL3TrackSegmentData *data = (AliL3TrackSegmentData *)Allocate();
1149   UInt_t ntrack;
1150   Binary2Memory(ntrack,data);
1151   Memory2TrackArray(ntrack,data,array);  
1152   Free();
1153   return kTRUE;
1154 }
1155
1156 Bool_t AliL3MemHandler::TrackArray2Memory(UInt_t & ntrack,AliL3TrackSegmentData *data,AliL3TrackArray *array) const
1157 {
1158   //Fill the trackarray into the AliTrackSegmentData structures before writing to outputfile.
1159   if(!data){
1160     LOG(AliL3Log::kWarning,"AliL3MemHandler::TrackArray2Memory","Memory")
1161     <<"Pointer to AliL3TrackSegmentData = 0x0 "<<ENDLOG;
1162     return kFALSE;
1163   }
1164   if(!array){
1165     LOG(AliL3Log::kWarning,"AliL3MemHandler::TrackArray2Memory","Memory")
1166     <<"Pointer to AliL3TrackArray = 0x0 "<<ENDLOG;
1167     return kFALSE;
1168   }
1169
1170   array->WriteTracks(ntrack,data);
1171   return kTRUE;
1172 }
1173
1174 Bool_t AliL3MemHandler::Memory2TrackArray(UInt_t ntrack,AliL3TrackSegmentData *data,AliL3TrackArray *array) const
1175 {
1176   //Fill the tracks in data into trackarray.
1177   
1178   if(!data){
1179     LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2TrackArray","Memory")
1180     <<"Pointer to AliL3TrackSegmentData = 0x0 "<<ENDLOG;
1181     return kFALSE;
1182   }
1183   if(!array){
1184     LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2TrackArray","Memory")
1185     <<"Pointer to AliL3TrackArray = 0x0 "<<ENDLOG;
1186     return kFALSE;
1187   }
1188   array->FillTracks(ntrack,data);
1189   return kTRUE;
1190 }
1191
1192 Bool_t AliL3MemHandler::Memory2TrackArray(UInt_t ntrack,AliL3TrackSegmentData *data,AliL3TrackArray *array,Int_t slice) const
1193 {
1194   //Fill the tracks in data into trackarray, and rotate the tracks to global coordinates.
1195     
1196   if(!data){
1197     LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2TrackArray","Memory")
1198     <<"Pointer to AliL3TrackSegmentData = 0x0 "<<ENDLOG;
1199     return kFALSE;
1200   }
1201   if(!array){
1202     LOG(AliL3Log::kWarning,"AliL3MemHandler::Memory2TrackArray","Memory")
1203     <<"Pointer to AliL3TrackArray = 0x0 "<<ENDLOG;
1204     return kFALSE;
1205   }
1206   array->FillTracks(ntrack,data,slice);
1207   return kTRUE;
1208 }
1209
1210 void AliL3MemHandler::UpdateRowPointer(AliL3DigitRowData *&tempPt)
1211 {
1212   //Update the data pointer to the next padrow in memory.
1213   
1214   Byte_t *tmp = (Byte_t*)tempPt;
1215   Int_t size = sizeof(AliL3DigitRowData) + tempPt->fNDigit*sizeof(AliL3DigitData);
1216   tmp += size;
1217   tempPt = (AliL3DigitRowData*)tmp;
1218 }