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