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