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