removing old CF configurations, ids redirected to HWCF; global tracking option enable...
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCMemHandler.cxx
1 // $Id$
2
3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project        * 
5 //* ALICE Experiment at CERN, All rights reserved.                         *
6 //*                                                                        *
7 //* Primary Authors: U. Frankenfeld, A. Vestbo, C. Loizides                *
8 //*                  Matthias Richter <Matthias.Richter@ift.uib.no>        *
9 //*                  for The ALICE HLT Project.                            *
10 //*                                                                        *
11 //* Permission to use, copy, modify and distribute this software and its   *
12 //* documentation strictly for non-commercial purposes is hereby granted   *
13 //* without fee, provided that the above copyright notice appears in all   *
14 //* copies and that both the copyright notice and this permission notice   *
15 //* appear in the supporting documentation. The authors make no claims     *
16 //* about the suitability of this software for any purpose. It is          *
17 //* provided "as is" without express or implied warranty.                  *
18 //**************************************************************************
19
20 //  @file   AliHLTTPCMemHandler.cxx
21 //  @author U. Frankenfeld, A. Vestbo, C. Loizides, maintained by
22 //          Matthias Richter
23 //  @date   
24 //  @brief  input interface base class for the TPC tracking code before
25 //          migration to the HLT component framework
26
27 #include <cassert>
28 #include "AliHLTTPCDigitData.h"
29 #include "AliHLTTPCLogging.h"
30 #include "AliHLTTPCTransform.h"
31 #include "AliHLTTPCSpacePointData.h"
32 #include "AliHLTTPCMemHandler.h"
33 #include "TMath.h"
34
35 using namespace std;
36   
37 ClassImp(AliHLTTPCMemHandler)
38   
39 AliHLTTPCMemHandler::AliHLTTPCMemHandler()
40   :
41   fRowMin(0),
42   fRowMax(0),
43   fSlice(0),
44   fPatch(0),
45   fInBinary(NULL),
46   fOutBinary(NULL),
47   fPt(NULL),
48   fSize(0),
49   fIsRandom(kFALSE),
50   fNRandom(0),
51   fNGenerate(0),
52   fNUsed(0),
53   fNDigits(0),
54   fDPt(NULL),
55   fRandomDigits(NULL),
56   fDummy(0)
57
58   //Constructor
59   Init(0,0);
60   ResetROI();
61 }
62
63 AliHLTTPCMemHandler::~AliHLTTPCMemHandler()
64 {
65   //Destructor
66   if(fPt) delete[] fPt;
67   if(fRandomDigits) delete [] fRandomDigits;
68   if(fDPt) delete [] fDPt;
69 }
70
71 void AliHLTTPCMemHandler::Init(Int_t s,Int_t p, Int_t *r)
72 {
73   //init handler
74   assert(s<fgkNSlice);
75   if (s>fgkNSlice) {
76     fSlice=0;
77     fPatch=0;
78     fRowMin=0;
79     fRowMax=0;
80     if (r) *r=0;
81     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Init","sector coordinates")
82       <<"Invalid slice no " << s <<ENDLOG;
83     return;
84   }
85   fSlice=s;fPatch=p;
86   if(r) {
87     fRowMin=r[0];
88     fRowMax=r[1];
89   }else{
90      fRowMin=AliHLTTPCTransform::GetFirstRow(p);
91      fRowMax=AliHLTTPCTransform::GetLastRow(p); 
92   }
93   ResetROI();
94 }
95
96 void AliHLTTPCMemHandler::ResetROI()
97 {
98   //Resets the Look-up table for Region of Interest mode.
99   for(Int_t i=fRowMin; i<=fRowMax; i++)
100     {
101       fEtaMinTimeBin[i] = 0;
102       fEtaMaxTimeBin[i] = AliHLTTPCTransform::GetNTimeBins()-1;
103     }
104 }
105
106 void AliHLTTPCMemHandler::SetROI(const Float_t *eta,Int_t */*slice*/)
107 {
108   // Init the Look-up table for the Region of Interest mode.
109   //   Here you can specify a certain etaregion, - all data
110   //   outside this region will be discarded:
111   //   eta[0] = mimium eta
112   //   eta[1] = maximum eta
113   //   slice[0] = mimumum slice
114   //   slice[1] = maximum slice
115
116
117   if(TMath::Abs(eta[1])<.00001)
118     {
119       LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetROI","Eta Values")
120         <<"Bad ROI parameters."<<ENDLOG;
121       for(Int_t i=fRowMin; i<=fRowMax; i++)
122         {
123           fEtaMinTimeBin[i]=0;
124           fEtaMaxTimeBin[i]=0;
125         }
126       return;
127     }
128   
129   for(Int_t i=fRowMin; i<=fRowMax; i++)
130     {
131       Int_t sector,row;
132       Float_t xyz[3];
133       
134       Float_t thetamax = 2*atan(exp(-1.*eta[1]));
135       
136       xyz[0] = AliHLTTPCTransform::Row2X(i);
137       xyz[1]=0;
138       xyz[2] = xyz[0]/tan(thetamax);
139       AliHLTTPCTransform::Slice2Sector(fSlice,i,sector,row);
140       AliHLTTPCTransform::Local2Raw(xyz,sector,row);
141       
142       fEtaMinTimeBin[i] = (Int_t)xyz[2];
143       
144       if(TMath::Abs(eta[0])<.00001)
145         fEtaMaxTimeBin[i] = 445;
146       else
147         {
148           Float_t thetamin = 2*atan(exp(-1.*eta[0]));
149           xyz[0] = AliHLTTPCTransform::Row2X(i);
150           xyz[1] = AliHLTTPCTransform::GetMaxY(i);
151           Float_t radii = sqrt(pow(xyz[0],2) + pow(xyz[1],2));
152           xyz[2] = radii/tan(thetamin);
153           AliHLTTPCTransform::Local2Raw(xyz,sector,row);
154           fEtaMaxTimeBin[i] = (Int_t)xyz[2];
155         }
156     }
157   
158 }
159
160 Bool_t AliHLTTPCMemHandler::SetBinaryInput(char *name)
161 {
162   //Set the input binary file.
163   fInBinary = fopen(name,"r");
164   if(!fInBinary){
165     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryInput","File Open")
166       <<"Error opening file "<<name<<ENDLOG;
167     return kFALSE;
168   }
169   return kTRUE;
170 }
171
172 Bool_t AliHLTTPCMemHandler::SetBinaryInput(FILE *file)
173 {
174   //Set the input binary file.
175   fInBinary = file;
176   if(!fInBinary){
177     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryInput","File Open")
178     <<"Pointer to File = 0x0 "<<ENDLOG;
179     return kFALSE;
180   }
181   return kTRUE;
182 }
183
184 void AliHLTTPCMemHandler::CloseBinaryInput()
185 {
186   //Close the input file.
187   if(!fInBinary){
188     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CloseBinaryInput","File Close")
189       <<"Nothing to Close"<<ENDLOG;
190     return;
191   }
192   fclose(fInBinary);
193   fInBinary =0;
194 }
195
196 Bool_t AliHLTTPCMemHandler::SetBinaryOutput(char *name)
197 {
198   //Set the binary output file.
199     fOutBinary = fopen(name,"w");
200   if(!fOutBinary){
201     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryOutput","File Open")
202       <<"Pointer to File = 0x0 "<<ENDLOG;
203     return kFALSE;
204   }
205   return kTRUE;
206 }
207
208 Bool_t AliHLTTPCMemHandler::SetBinaryOutput(FILE *file)
209 {
210   //Set the binary output file.
211     fOutBinary = file;
212   if(!fOutBinary){
213     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::SetBinaryOutput","File Open")
214       <<"Pointer to File = 0x0 "<<ENDLOG;
215     return kFALSE;
216   }
217   return kTRUE;
218 }
219
220 void AliHLTTPCMemHandler::CloseBinaryOutput()
221 {
222   //close binary  
223   if(!fOutBinary){
224     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CloseBinaryOutPut","File Close")
225       <<"Nothing to Close"<<ENDLOG;
226     return;
227   }
228   fclose(fOutBinary);
229   fOutBinary =0;
230 }
231
232 UInt_t AliHLTTPCMemHandler::GetFileSize()
233 {
234   //Returns the file size in bytes of the input file.
235   if(!fInBinary){
236     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetFileSize","File")
237       <<"No Input File"<<ENDLOG;
238     return 0;
239   }
240   fseek(fInBinary,0,SEEK_END);
241   long size=ftell(fInBinary);
242   rewind(fInBinary);
243   if (size<0) return 0;
244   return (UInt_t)size;
245 }
246
247 Byte_t *AliHLTTPCMemHandler::Allocate()
248 {
249   //Allocate
250   return Allocate(GetFileSize()); 
251 }
252
253 Byte_t *AliHLTTPCMemHandler::Allocate(UInt_t size)
254 {
255   //Allocate memory of size in bytes.
256   if(fPt){
257     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Allocate","Memory")
258       <<"Delete Memory"<<ENDLOG;
259     Free();
260   } 
261   fPt = new Byte_t[size];
262   fSize = size;
263   memset(fPt,0,fSize);
264   LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Allocate","Memory")
265   <<AliHLTTPCLog::kDec<<"Allocate "<<size<<" Bytes of Memory"<<ENDLOG;
266   return fPt;
267 }
268
269 void AliHLTTPCMemHandler::Free()
270 {
271   //Clear the memory, if allocated.
272   if(!fPt){
273     //    LOG(AliHLTTPCLog::kInformational,"AliHLTTPCMemHandler::Free","Memory")
274     //      <<"No Memory allocated - can't Free"<<ENDLOG;
275     return;
276   }  
277   delete[] fPt;
278   fPt = 0;
279   fSize =0;
280 }
281
282 ///////////////////////////////////////// Random
283 void AliHLTTPCMemHandler::SetRandomSeed()
284 {
285   //If you are adding random data to the original data.
286   time_t *tp=0;
287   SetRandomSeed(time(tp));
288 }
289
290 void AliHLTTPCMemHandler::SetRandomCluster(Int_t maxnumber)
291 {
292   //If you are adding random data to the original data.
293   
294   fIsRandom = kTRUE;
295   fNRandom = maxnumber;
296   fNDigits = 0;
297   if(fRandomDigits) delete [] fRandomDigits;
298   fRandomDigits = new AliHLTTPCRandomDigitData[fNRandom*9];
299   if(fDPt) delete [] fDPt;
300   fDPt = new AliHLTTPCRandomDigitData *[fNRandom*9];
301 }
302
303 void AliHLTTPCMemHandler::QSort(AliHLTTPCRandomDigitData **a, Int_t first, Int_t last)
304 {
305
306    // Sort array of AliHLTTPCRandomDigitData pointers using a quicksort algorithm.
307    // Uses CompareDigits() to compare objects.
308    // Thanks to Root!
309
310    static AliHLTTPCRandomDigitData *tmp;
311    static int i;           // "static" to save stack space
312    int j;
313
314    while (last - first > 1) {
315       i = first;
316       j = last;
317       for (;;) {
318          while (++i < last && CompareDigits(a[i], a[first]) < 0)
319             ;
320          while (--j > first && CompareDigits(a[j], a[first]) > 0)
321             ;
322          if (i >= j)
323             break;
324
325          tmp  = a[i];
326          a[i] = a[j];
327          a[j] = tmp;
328       }
329       if (j == first) {
330          ++first;
331          continue;
332       }
333       tmp = a[first];
334       a[first] = a[j];
335       a[j] = tmp;
336
337       if (j - first < last - (j + 1)) {
338         QSort(a, first, j);
339         first = j + 1;   // QSort(j + 1, last);
340       } else {
341         QSort(a, j + 1, last);
342         last = j;        // QSort(first, j);
343       }
344    }
345 }
346
347 UInt_t AliHLTTPCMemHandler::GetRandomSize() const
348 {
349   //get random size
350   Int_t nrandom = 0;
351   for(Int_t r=fRowMin;r<=fRowMax;r++){
352     Int_t npad=AliHLTTPCTransform::GetNPads(r);
353     nrandom  += Int_t (fNGenerate * ((Double_t) npad/141.));
354   }
355   return 9 * nrandom * sizeof(AliHLTTPCDigitData);
356 }
357
358 void AliHLTTPCMemHandler::DigitizePoint(Int_t row, Int_t pad, 
359                                     Int_t time,Int_t charge)
360 {
361   //Making one single random cluster.
362   for(Int_t j=-1;j<2;j++){
363     for(Int_t k=-1;k<2;k++){
364       Int_t dcharge = charge;
365       if(j) dcharge /=2;
366       if(k) dcharge /=2;
367       if(dcharge<10) continue;
368       Int_t dpad  = j + pad;
369       Int_t dtime = k + time;
370       
371       if(dpad<0||dpad>=AliHLTTPCTransform::GetNPads(row))  continue;
372       if(dtime<0||dtime>=AliHLTTPCTransform::GetNTimeBins()) continue;
373       
374       fRandomDigits[fNDigits].fCharge = dcharge;
375       fRandomDigits[fNDigits].fRow = row;
376       fRandomDigits[fNDigits].fPad = dpad;
377       fRandomDigits[fNDigits].fTime = dtime;
378       fDPt[fNDigits] = &fRandomDigits[fNDigits];
379       fNDigits++;
380     }
381   }
382 }
383
384 ///////////////////////////////////////// Digit IO  
385 Bool_t AliHLTTPCMemHandler::Memory2BinaryFile(UInt_t nrow,AliHLTTPCDigitRowData *data)
386 {
387   //Write data to the outputfile as is. No run-length encoding is done.
388
389   if(!fOutBinary){
390     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","File")
391       <<"No Output File"<<ENDLOG;
392     return kFALSE;
393   }
394   if(!data){
395     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","Memory")
396       <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
397     return kFALSE;
398   }
399   
400   AliHLTTPCDigitRowData *rowPt = data; 
401   Int_t outsize = 0;
402   for(UInt_t i=0;i<nrow;i++){
403     Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit 
404       + sizeof(AliHLTTPCDigitRowData);
405     outsize += size;
406     fwrite(rowPt,size,1,fOutBinary);
407     Byte_t  *bytePt =(Byte_t *) rowPt;
408     bytePt += size;
409     rowPt = (AliHLTTPCDigitRowData *) bytePt;
410   }
411   LOG(AliHLTTPCLog::kDebug,"AliHLTTPCMemHandler::Memory2Binary","Memory")
412     <<AliHLTTPCLog::kDec<<"Wrote "<<outsize<<" Bytes to Memory ("
413     <<nrow<<" Rows)"<<ENDLOG;
414   return kTRUE;
415 }
416
417 void AliHLTTPCMemHandler::AddData(AliHLTTPCDigitData *data,UInt_t & ndata,
418                               UInt_t /*row*/,UShort_t pad,UShort_t time,UShort_t charge) const
419 {
420   //add some data
421   data[ndata].fPad = pad;
422   data[ndata].fTime = time;
423   data[ndata].fCharge = charge;
424   ndata++;
425 }
426
427 void AliHLTTPCMemHandler::AddRandom(AliHLTTPCDigitData *data, UInt_t & ndata)
428 {
429   //add some random data
430   data[ndata].fPad = fDPt[fNUsed]->fPad;
431   data[ndata].fTime = fDPt[fNUsed]->fTime;
432   data[ndata].fCharge = fDPt[fNUsed]->fCharge;
433   ndata++;
434   fNUsed++;
435 }
436
437 void AliHLTTPCMemHandler::MergeDataRandom(AliHLTTPCDigitData *data, UInt_t & ndata,
438                                       UInt_t row, UShort_t pad, UShort_t time, UShort_t charge)
439 {
440   //merge random data
441   data[ndata].fPad = pad;
442   data[ndata].fTime = time;
443   data[ndata].fCharge = charge;
444   while(ComparePoints(row,pad,time)==0){
445     Int_t ch = data[ndata].fCharge + fDPt[fNUsed]->fCharge;
446     if(charge>=AliHLTTPCTransform::GetADCSat()) ch = AliHLTTPCTransform::GetADCSat();
447     data[ndata].fCharge = ch;
448     fNUsed++;
449   }
450   ndata++;
451 }
452
453 void AliHLTTPCMemHandler::AddDataRandom(AliHLTTPCDigitData *data, UInt_t & ndata,
454                    UInt_t row, UShort_t pad, UShort_t time, UShort_t charge)
455 {
456   //add data random
457   Int_t action;
458   while((action=ComparePoints(row,pad,time))==1){
459     AddRandom(data,ndata);
460   }
461   if(action==0){
462     MergeDataRandom(data,ndata,row,pad,time,charge);
463   }
464   if(action<0){
465     AddData(data,ndata,row,pad,time,charge);
466   }  
467 }
468
469 void AliHLTTPCMemHandler::Write(UInt_t *comp, UInt_t & index, 
470                             UInt_t & subindex, UShort_t value) const
471 {
472   //write compressed data
473   UInt_t shift[3] = {0,10,20};
474   if(subindex==0) comp[index] =0; //clean up memory
475   comp[index] |= (value&0x03ff)<<shift[subindex];
476   if(subindex == 2){
477     subindex = 0;
478     index++;
479   }
480   else subindex++;
481 }
482
483 UShort_t AliHLTTPCMemHandler::Read(UInt_t *comp, UInt_t & index, UInt_t & subindex) const
484
485   //read compressed data
486   UInt_t shift[3] = {0,10,20};
487   UShort_t value = (comp[index]>>shift[subindex])&0x03ff;
488   if(subindex == 2){
489     subindex = 0;
490     index++;
491   }
492   else subindex++;
493   
494   return value;
495 }
496
497 UShort_t AliHLTTPCMemHandler::Test(const UInt_t *comp, 
498                                UInt_t index, UInt_t  subindex) const
499 {
500   //supi dupi test
501   UInt_t shift[3] = {0,10,20};
502   return (comp[index]>>shift[subindex])&0x03ff;
503 }
504
505 Int_t AliHLTTPCMemHandler::Memory2CompMemory(UInt_t nrow,
506                                          AliHLTTPCDigitRowData *data,UInt_t *comp)
507 {
508   //Performs run-length encoding on data stored in memory pointed to by data.
509   //The compressed data is written to comp.
510   if(!comp){
511     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2CompMemory","Memory")
512       <<"Pointer to compressed data = 0x0 "<<ENDLOG;
513     return 0;
514   }
515   if(!data){
516     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2CompMemory","Memory")
517       <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
518     return 0;
519   }
520   AliHLTTPCDigitRowData *rowPt = data;
521   UInt_t index=0;
522   UInt_t subindex=0;
523   
524   for(UInt_t i=0;i<nrow;i++){
525     UShort_t value = rowPt->fRow;
526     Write(comp,index,subindex,value);
527     UShort_t maxpad=0; 
528     UShort_t npad=0;
529     Int_t ddd[1000];
530     for(Int_t d=0;d<200;d++) ddd[d]=0;
531     for(UInt_t dig=0;dig<rowPt->fNDigit;dig++){
532       if(rowPt->fDigitData[dig].fPad <200){ 
533         ddd[rowPt->fDigitData[dig].fPad]++;
534       }
535     }
536     for(Int_t d=0;d<200;d++){ 
537       if(ddd[d]){
538         npad++;
539         maxpad =d;
540       }
541     }
542     Write(comp,index,subindex,npad);
543     UInt_t digit=0;
544     for(UShort_t pad=0;pad <= maxpad;pad++){
545       if(digit>=rowPt->fNDigit || rowPt->fDigitData[digit].fPad !=  pad)
546         continue;
547       Write(comp,index,subindex,pad);
548 //    write zero if time != 0
549       if(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
550         if(rowPt->fDigitData[digit].fTime>0){
551           Write(comp,index,subindex,0);
552           Write(comp,index,subindex,rowPt->fDigitData[digit].fTime);
553         }
554       }
555       while(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
556         UShort_t charge = rowPt->fDigitData[digit].fCharge;
557         if(charge>=1023){
558           charge=1023;
559         }
560         Write(comp,index,subindex,charge);
561         if(digit+1<rowPt->fNDigit&&rowPt->fDigitData[digit+1].fPad == pad){
562           if(rowPt->fDigitData[digit].fTime +1 !=
563                      rowPt->fDigitData[digit+1].fTime){
564             Write(comp,index,subindex,0);
565             UShort_t nzero = rowPt->fDigitData[digit+1].fTime - 
566                              (rowPt->fDigitData[digit].fTime +1);
567             Write(comp,index,subindex,nzero);
568           }  
569         }
570         digit++;
571       }
572       Write(comp,index,subindex,0);
573       Write(comp,index,subindex,0);
574     }
575     
576     Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit+
577                                             sizeof(AliHLTTPCDigitRowData);
578     Byte_t  *bytePt =(Byte_t *) rowPt;
579     bytePt += size;
580     rowPt = (AliHLTTPCDigitRowData *) bytePt;
581   }
582   while(subindex)
583     Write(comp,index,subindex,0);
584   return index * sizeof(UInt_t);
585 }
586
587 UInt_t AliHLTTPCMemHandler::GetCompMemorySize(UInt_t nrow,AliHLTTPCDigitRowData *data) const
588 {
589   //Return the size of RLE data, after compressing data.
590   
591   if(!data){
592     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetCompMemorySize","Memory")
593       <<"Pointer to AliHLTTPCDigitRowData = 0x0 "<<ENDLOG;
594     return 0;
595   }
596   AliHLTTPCDigitRowData *rowPt = data;
597   UInt_t index=0;
598   
599   for(UInt_t i=0;i<nrow;i++){
600     index++;
601     UShort_t maxpad=0; 
602     UShort_t npad=0;
603     Int_t ddd[1000];
604     for(Int_t d=0;d<200;d++) ddd[d]=0;
605     for(UInt_t dig=0;dig<rowPt->fNDigit;dig++){
606       if(rowPt->fDigitData[dig].fPad <200){ 
607         ddd[rowPt->fDigitData[dig].fPad]++;
608       }
609     }
610     for(Int_t d=0;d<200;d++){ 
611       if(ddd[d]){
612         npad++;
613         maxpad =d;
614       }
615     }
616     index++;
617     UInt_t digit=0;
618     for(UShort_t pad=0;pad <= maxpad;pad++){
619       if(digit>=rowPt->fNDigit || rowPt->fDigitData[digit].fPad !=  pad)
620         continue;
621       index++;
622       //    write zero if time != 0
623       if(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
624         if(rowPt->fDigitData[digit].fTime>0){
625           index++;
626           index++;
627         }
628       }
629       while(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad){
630         index++;
631         if(digit+1<rowPt->fNDigit&&rowPt->fDigitData[digit+1].fPad == pad){
632           if(rowPt->fDigitData[digit].fTime +1 !=
633                      rowPt->fDigitData[digit+1].fTime){
634             index++;
635             index++;
636           }  
637         }
638         digit++;
639       }
640       index++;
641       index++;
642     }
643
644     Int_t size = sizeof(AliHLTTPCDigitData) * rowPt->fNDigit+
645                                             sizeof(AliHLTTPCDigitRowData);
646     Byte_t  *bytePt =(Byte_t *) rowPt;
647     bytePt += size;
648     rowPt = (AliHLTTPCDigitRowData *) bytePt;
649   }
650   while(index%3)
651     index++;
652   return (index/3) * sizeof(UInt_t);
653 }
654
655 UInt_t AliHLTTPCMemHandler::GetMemorySize(UInt_t nrow,UInt_t *comp) const
656 {
657   //get memory size
658   if(!comp){
659     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetMemorySize","Memory")
660     <<"Pointer to compressed data = 0x0 "<<ENDLOG;
661     return 0;
662   }
663   Int_t outsize=0;
664
665   UInt_t index=0;
666   UInt_t subindex=0;
667
668   for(UInt_t i=0;i<nrow;i++){
669     UInt_t ndigit=0;
670     Read(comp,index,subindex);
671     UShort_t npad = Read(comp,index,subindex);
672     for(UShort_t p=0;p<npad;p++){
673       Read(comp,index,subindex);
674       if(Test(comp,index,subindex)==0){
675         Read(comp,index,subindex);
676         if(Read(comp,index,subindex)== 0) continue;
677       }
678       for(;;){
679         while(Read(comp,index,subindex)!=0) ndigit++;
680         if(Read(comp,index,subindex)==0) break;
681       }
682     }
683     Int_t size = sizeof(AliHLTTPCDigitData) * ndigit+
684                                         sizeof(AliHLTTPCDigitRowData);
685     outsize += size;
686   }
687    
688   return outsize;
689 }
690
691 UInt_t AliHLTTPCMemHandler::GetNRow(UInt_t *comp,UInt_t size)
692 {
693   //get number of rows
694   if(!comp){
695     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::GetNRow","Memory")
696       <<"Pointer to compressed data = 0x0 "<<ENDLOG;
697     return 0;
698   }
699   size = size /4;
700   UInt_t nrow=0;
701   UInt_t index=0;
702   UInt_t subindex=0;
703   while(index<size-1){ //don't start with last word
704     nrow++;
705     UInt_t ndigit=0;
706     Read(comp,index,subindex);
707     UShort_t npad = Read(comp,index,subindex);
708     for(UShort_t p=0;p<npad;p++){
709       Read(comp,index,subindex);
710       if(Test(comp,index,subindex)==0){
711         Read(comp,index,subindex);
712         if(Read(comp,index,subindex)==0)continue;
713       }
714       for(;;){
715         while(Read(comp,index,subindex)!=0) ndigit++;
716         if(Read(comp,index,subindex)==0) break;
717       }
718     }
719   }
720   if(index==size-1){  //last word
721     if(subindex<2){
722       if(Read(comp,index,subindex)!=0) nrow++;
723     }
724   }
725   return nrow;
726 }
727
728 Bool_t AliHLTTPCMemHandler::CompMemory2CompBinary(UInt_t nrow,UInt_t *comp,
729                                              UInt_t size)
730 {
731   //Write the RLE data in comp to the output file.
732   
733   if(!fOutBinary){
734     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2CompBinary","File")
735     <<"No Output File"<<ENDLOG;
736     return kFALSE;
737   }
738   if(!comp){
739     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2CompBinary","Memory")
740     <<"Pointer to compressed data = 0x0 "<<ENDLOG;
741     return kFALSE;
742   }
743   if(size==0)
744     size=GetMemorySize(nrow,comp);
745   if(!size){
746     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::CompMemory2CompBinary","Memory")
747     <<"Memory size = 0 "<<ENDLOG;
748     return kFALSE;
749   }
750   UInt_t length = size/sizeof(UInt_t);
751   fwrite(&length,sizeof(UInt_t),1,fOutBinary);  
752   fwrite(comp,size,1,fOutBinary);
753   return kTRUE;
754 }
755
756
757 Bool_t AliHLTTPCMemHandler::Memory2CompBinary(UInt_t nrow,AliHLTTPCDigitRowData *data)
758 {
759   //Perform RLE on the data, and write it to the output file.
760   Bool_t out = kTRUE;
761   AliHLTTPCMemHandler * handler = new AliHLTTPCMemHandler();
762   UInt_t size = GetCompMemorySize(nrow,data);
763   UInt_t *comp =(UInt_t *)handler->Allocate(size);
764   Memory2CompMemory(nrow,data,comp);
765   CompMemory2CompBinary(nrow,comp,size);
766   handler->Free();
767   delete handler;
768   return out;
769 }
770
771
772 ///////////////////////////////////////// Point IO  
773 Bool_t AliHLTTPCMemHandler::Memory2Binary(UInt_t npoint,AliHLTTPCSpacePointData *data)
774 {
775   //Writing spacepoints stored in data to the outputfile.
776   if(!fOutBinary){
777     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","File")
778       <<"No Output File"<<ENDLOG;
779     return kFALSE;
780   }
781   if(!data){
782     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Memory2Binary","Memory")
783       <<"Pointer to AliHLTTPCSpacePointData = 0x0 "<<ENDLOG;
784     return kFALSE;
785   }
786   UInt_t size = npoint*sizeof(AliHLTTPCSpacePointData);
787   fwrite(data,size,1,fOutBinary);
788   
789   return kTRUE;
790 }
791
792 Bool_t AliHLTTPCMemHandler::Transform(UInt_t npoint,AliHLTTPCSpacePointData *data,Int_t slice)
793 {
794   //Transform the space points in data, to global coordinates in slice.
795   if(!data){
796     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCMemHandler::Transform","Memory")
797     <<"Pointer to AliHLTTPCSpacePointData = 0x0 "<<ENDLOG;
798     return kFALSE;
799   }
800   
801   for(UInt_t i=0;i<npoint;i++){
802     Float_t xyz[3];
803     xyz[0] = data[i].fX;
804     xyz[1] = data[i].fY;
805     xyz[2] = data[i].fZ;
806     AliHLTTPCTransform::Local2Global(xyz,slice);
807     data[i].fX = xyz[0];
808     data[i].fY = xyz[1];
809     data[i].fZ = xyz[2];
810   }
811   return kTRUE;
812 }
813
814 void AliHLTTPCMemHandler::UpdateRowPointer(AliHLTTPCDigitRowData *&tempPt)
815 {
816   //Update the data pointer to the next padrow in memory.
817   
818   Byte_t *tmp = (Byte_t*)tempPt;
819   Int_t size = sizeof(AliHLTTPCDigitRowData) + tempPt->fNDigit*sizeof(AliHLTTPCDigitData);
820   tmp += size;
821   tempPt = (AliHLTTPCDigitRowData*)tmp;
822 }
823
824 Int_t  AliHLTTPCMemHandler::ComparePoints(UInt_t /*row*/,UShort_t pad,UShort_t time) const
825 {
826   //compare two points
827   if(fNUsed>=fNDigits) return -2;
828
829   if(pad==fDPt[fNUsed]->fPad&&time==fDPt[fNUsed]->fTime) return 0;
830
831   if(pad<fDPt[fNUsed]->fPad) return -1;
832   if(pad==fDPt[fNUsed]->fPad&&time<fDPt[fNUsed]->fTime)  return -1;
833
834   return 1;
835 }
836
837 Int_t AliHLTTPCMemHandler::CompareDigits(const AliHLTTPCRandomDigitData *a,const AliHLTTPCRandomDigitData *b) const
838 {
839   //compare two digits
840   if(a->fPad==b->fPad && a->fTime == b->fTime) return 0;
841
842   if(a->fPad<b->fPad) return -1;
843   if(a->fPad==b->fPad && a->fTime<b->fTime) return -1;
844   
845   return 1;
846 }