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