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