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