]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/misc/AliHLTDataHandler.cxx
- Changed module names to be the same as the libraries names;
[u/mrichter/AliRoot.git] / HLT / misc / AliHLTDataHandler.cxx
1 // @(#) $Id$
2
3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright &copy ALICE HLT Group
5
6 #include "AliHLTStandardIncludes.h"
7
8 #include "AliHLTRootTypes.h"
9 #include "AliHLTLogging.h"
10 #include "AliHLTMemHandler.h"
11 #include "AliHLTLogging.h"
12 #include "AliHLTTransBit.h"
13 #include "AliHLTTransform.h"
14 #include "AliHLTDataHandler.h"
15 #include "AliHLTDigitData.h"
16
17 #if __GNUC__ >= 3
18 using namespace std;
19 #endif
20
21 /** \class AliHLTDataHandler
22 <pre>
23 //_____________________________________________________________
24 // AliHLTDataHandler
25 //
26 // HLT Binary file handler.
27 //
28 // This class have more or less the same functionality as AliHLTMemHandler,
29 // except that it handles 8 bit ADC-values. Reading and writing is done in the same way
30 // as illustrated in example 1) and 2) in AliHLTMemHandler.
31 //
32 // For converting 10 bit data files to 8 bit data files, do:
33 //
34 // AliHLTMemHandler *file = new AliHLTDataHandler();
35 // file->Init(slice,patch);
36 // file->SetBinaryInput(inputfile);    //10 bit data file
37 // file->SetBinaryOutput(outputfile);  //8 bit data file
38 // file->Convert10to8Bit();
39 // file->CloseBinaryInput();
40 // file->CloseBinaryOutput();
41 // delete file;
42 //
43 // Compress data format
44 // --------------------
45 //
46 // The data is RLE encoded, using _8_bit representation of the ADC-values.
47 // Conversion is done in the class AliHLTTransBit.
48 //
49 // In the beginning of every row, the row number if written and the number of pads
50 // containing data on that row. For every pad with data the pad number is written,
51 // and then comes the ADC-values on that pad. When a serie of zeros occure, a zero
52 // is written followed by the number of zeros. If the number of zeros is more than
53 // 255 (8 bit), another 8 bit word is written for the remaining. At the end of one 
54 // pad, 2 zeros are written. Example:
55 //
56 // ROW NPADSWITHDATA PAD 0 NZEROS ADC ADC ADC ADC 0 NZEROS ADC ADC 0 0
57 //
58 // Everything is written using 8 bit;
59 // (ROW < 176, PAD < 200, ADC < 255, if(NZEROS > 255) write 2 words;)
60 </pre>
61 */
62
63 ClassImp(AliHLTDataHandler)
64   
65 AliHLTDataHandler::AliHLTDataHandler()
66 {
67   // default constructor
68   fBitTransformer = 0;
69   LOG(AliHLTLog::kInformational,"AliHLTDataHandler::AliHLTDataHandler","Data format")
70     <<"8 bit data handler initialized"<<ENDLOG;
71 }
72
73 AliHLTDataHandler::~AliHLTDataHandler()
74 {
75   // destructor
76   if(fBitTransformer)
77     delete fBitTransformer;
78 }
79
80 void AliHLTDataHandler::Convert10to8Bit()
81 {
82   //Convert from 10 bit data in inputfile, to 8 bit data written to outputfile.
83   
84   if(!fInBinary)
85     {
86       LOG(AliHLTLog::kError,"AliHLTDataHandler::Convert10to8Bit","File")
87         <<AliHLTLog::kHex<<"Pointer to input file : "<<(void*)fInBinary<<ENDLOG;
88       return;
89     }
90   if(!fOutBinary)
91     {
92       LOG(AliHLTLog::kError,"AliHLTDataHandler::Convert10to8Bit","File")
93         <<AliHLTLog::kHex<<"Pointer to output file : "<<(void*)fOutBinary<<ENDLOG;
94       return;
95     }
96   
97   
98   //Initialize the bit transformation class:
99   fBitTransformer = new AliHLTTransBitV1();
100   Int_t b0=10;  // original number of bits
101   Int_t b1=8;   // compressed
102   fBitTransformer->SetBits(b0,b1);
103   fBitTransformer->FindOptimumX0();
104   fBitTransformer->Update();
105   
106   AliHLTMemHandler *memory = new AliHLTMemHandler();
107   memory->Init(fSlice,fPatch);
108   memory->SetBinaryInput(fInBinary);
109   UInt_t nrow;
110   AliHLTDigitRowData *data = (AliHLTDigitRowData*)memory->CompBinary2Memory(nrow);
111   
112   Memory2CompBinary(nrow,data);
113   
114   delete memory;
115 }
116
117 Bool_t AliHLTDataHandler::Memory2CompBinary(UInt_t nrow,AliHLTDigitRowData *data)
118 {
119   //Compress data by RLE, and write to a binary file.
120   
121   UInt_t size = GetCompMemorySize(nrow,data);
122   Byte_t *comp = Allocate(size);
123   Memory2CompMemory(nrow,data,comp);
124   if(!CompMemory2CompBinary(nrow,comp,size))
125     {
126       LOG(AliHLTLog::kError,"AliHLTDataHandler::Memory2CompBinary","File")
127         <<"Error writing to file "<<ENDLOG;
128       return 0;
129     }
130   Free();
131   return kTRUE;
132 }
133
134 AliHLTDigitRowData *AliHLTDataHandler::CompBinary2Memory(UInt_t &nrow)
135 {
136   //Read RLE compressed binary file, unpack it and return pointer to it.
137   
138   AliHLTMemHandler *memory = new AliHLTMemHandler();
139   memory->SetBinaryInput(fInBinary);
140   Byte_t *comp = memory->Allocate();
141     
142   if(!CompBinary2CompMemory(nrow,comp))
143     {
144       LOG(AliHLTLog::kError,"AliHLTDataHandler::CompBinary2Memory","File")
145         <<"Error reading from file "<<ENDLOG;
146       return 0;
147     }
148
149   UInt_t size = GetMemorySize(nrow,comp);
150   AliHLTDigitRowData *data = (AliHLTDigitRowData*)Allocate(size);
151   CompMemory2Memory(nrow,data,comp);
152   delete memory;
153   return data;
154 }
155
156 void AliHLTDataHandler::Write(Byte_t *comp,UInt_t &index,UShort_t value)
157 {
158   //Write one value (=1 byte) to array comp.
159
160   if(value > 255)
161     {
162       LOG(AliHLTLog::kFatal,"AliHLTDataHandler::Write","Bitnumbers")
163         <<"Value too big for storing in 1 byte, something is wrong: "<<value<<" "<<index<<ENDLOG;
164     }
165   comp[index] = (Byte_t)value;
166   index++;
167 }
168
169 Short_t AliHLTDataHandler::Read(Byte_t *comp,UInt_t &index)
170 {
171   //Read one value (=1 byte) from array comp
172
173   Short_t value = (Short_t)comp[index];
174   index++;
175   return value;
176 }
177
178 Short_t AliHLTDataHandler::Test(Byte_t *comp,UInt_t index)
179 {
180   //Check the value (=1 byte) in array comp, but not read.
181
182   Short_t value = (Short_t)comp[index];
183   return value;
184 }
185
186 Bool_t AliHLTDataHandler::Memory2CompMemory(UInt_t nrow,AliHLTDigitRowData *data,Byte_t *comp)
187 {
188   //Perform RLE.
189   
190   if(!data)
191     {
192       LOG(AliHLTLog::kError,"AliHLTDataHandler::Memory2CompMemory","Data")
193         <<AliHLTLog::kHex<<" Pointer to data = "<<(void*)data<<ENDLOG;
194       return 0;  
195     }
196   if(!comp)
197     {
198       LOG(AliHLTLog::kError,"AliHLTDataHandler::Memory2CompMemory","Data")
199         <<AliHLTLog::kHex<<" Pointer to compressed data = "<<(void*)comp<<ENDLOG;
200       return 0;  
201     }
202
203   AliHLTDigitRowData *rowPt = data;
204   
205   UInt_t index = 0;
206   Int_t npads[200];      
207   
208   for(UInt_t i=0; i<nrow; i++)
209     {
210       //Write the row number:
211       UShort_t value = rowPt->fRow;
212       Write(comp,index,value);
213       
214       UShort_t numberOfPads=0;
215       UShort_t maxPad = 0;
216       
217       for(Int_t j=0; j<200; j++)
218         npads[j]=0;
219       for(UInt_t dig=0; dig<rowPt->fNDigit; dig++)
220         {
221           if(rowPt->fDigitData[dig].fPad < 200)
222             npads[rowPt->fDigitData[dig].fPad]++;
223         }
224       for(Int_t j=0; j<200; j++)
225         {
226           if(npads[j])
227             {
228               numberOfPads++;
229               maxPad = j;
230             }
231         }
232       
233       //Write the number of pads on this row:
234       Write(comp,index,numberOfPads);
235       UInt_t digit=0;
236       
237       for(UShort_t pad=0; pad <= maxPad; pad++)
238         {
239           
240           if(digit >= rowPt->fNDigit || rowPt->fDigitData[digit].fPad !=  pad)
241             continue;
242         
243           //Write the current pad:
244           Write(comp,index,pad);
245           
246           if(digit < rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad)
247             {
248               if(rowPt->fDigitData[digit].fTime > 0)
249                 {
250                   //If first time!=0, write the number of following zeros, 
251                   //and then the first timebin:
252                   Write(comp,index,0);
253                   
254                   //Check if we have to use more than 1 byte to write the zeros:
255                   Int_t numberOfZeroIntervals=0;
256                   if(rowPt->fDigitData[digit].fTime >= 255)
257                     {
258                       numberOfZeroIntervals++;
259                       Write(comp,index,255);
260                       if(rowPt->fDigitData[digit].fTime >= 2*255)
261                         {
262                           cerr<<"AliHLTDataHandler::Memory2CompMemory : Should not happen "<<(Int_t)rowPt->fDigitData[digit].fTime<<endl;
263                           Write(comp,index,255);
264                           numberOfZeroIntervals++;
265                         }
266                     }
267                   Write(comp,index,(rowPt->fDigitData[digit].fTime - numberOfZeroIntervals*255));
268                 }
269             }
270           
271           while(digit < rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad)
272             {
273               UShort_t charge = rowPt->fDigitData[digit].fCharge;
274               
275               if(fBitTransformer)
276                 charge = fBitTransformer->Get0to1(charge); //Transform 10 to 8 bit.
277               
278               //Check for saturation:
279               if(charge>255)
280                 {
281                   LOG(AliHLTLog::kWarning,"AliHLTDataHandler::Memory2CompMemory","Digit")
282                     <<"ADC-value saturated : "<<charge<<ENDLOG;
283                   charge=255;
284                 }
285               
286               //Write the charge:
287               Write(comp,index,charge);
288               
289               //Check if the next digit is zero:
290               if(digit+1 < rowPt->fNDigit && rowPt->fDigitData[digit+1].fPad == pad)
291                 {
292                   if(rowPt->fDigitData[digit].fTime + 1 != rowPt->fDigitData[digit+1].fTime)
293                     {
294                       Write(comp,index,0);
295                       UShort_t nzero = rowPt->fDigitData[digit+1].fTime - (rowPt->fDigitData[digit].fTime + 1);
296                       
297                       //Check if we have to use more than one byte to write the zeros:
298                       Int_t numberOfZeroIntervals=0;
299                       if(nzero >= 255)
300                         {
301                           numberOfZeroIntervals++;
302                           Write(comp,index,255);
303                           if(nzero >= 2*255)
304                             {
305                               cerr<<"AliHLTDataHandler::Memory2CompMemory : Should not happen "<<(Int_t)rowPt->fDigitData[digit].fTime<<endl;
306                               Write(comp,index,255);
307                               numberOfZeroIntervals++;
308                             }
309                         }
310                       Write(comp,index,(nzero - numberOfZeroIntervals*255));
311                     }  
312                 }
313               digit++;
314             }
315           
316           //This is the end of the pad, state it with 2 zeros:
317           Write(comp,index,0);
318           Write(comp,index,0);
319         }
320       
321       UpdateRowPointer(rowPt);
322       
323     }
324   
325   return index * sizeof(Byte_t);
326     
327 }
328
329 UInt_t AliHLTDataHandler::GetCompMemorySize(UInt_t nrow,AliHLTDigitRowData *data)
330 {
331   //Calculate the size (in bytes) of RLE data.
332   
333   if(!data)
334     {
335       LOG(AliHLTLog::kError,"AliHLTDataHandler::GetCompMemorySize","Data")
336         <<AliHLTLog::kHex<<" Data pointer = "<<(void*)data<<ENDLOG;
337       return 0;
338     }
339   
340   AliHLTDigitRowData *rowPt = data;
341   
342   UInt_t index = 0;
343   Int_t npads[200];
344   
345   for(UInt_t i=0;i<nrow;i++)
346     {
347       //Write the row number:
348       index++;
349       
350       UShort_t maxPad=0; 
351       UShort_t numberOfPads = 0;
352       
353       for(Int_t j=0; j<200; j++) 
354         npads[j]=0;
355       
356       for(UInt_t dig=0; dig<rowPt->fNDigit; dig++)
357         {
358           if(rowPt->fDigitData[dig].fPad <200)
359             npads[rowPt->fDigitData[dig].fPad]++;
360         }
361       for(Int_t j=0; j<200; j++)
362         { 
363           if(npads[j])
364             {
365               numberOfPads++;
366               maxPad = j;
367             }
368         }
369       
370       //Write the number of pads on this row:
371       index++;
372       
373       UInt_t digit=0;
374       for(UShort_t pad=0; pad <= maxPad; pad++)
375         {
376           if(digit>=rowPt->fNDigit || rowPt->fDigitData[digit].fPad !=  pad)
377             continue;
378           
379           //Write the current pad:
380           index++;
381           
382           
383           if(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad)
384             {
385               if(rowPt->fDigitData[digit].fTime > 0)
386                 {
387                   //If first time!=0, write the number of following zeros, 
388                   //and then the first timebin:
389                   
390                   index++;
391                   index++;
392                   
393                   //Check if we have to use more than 1 byte to write the zeros:
394                   if(rowPt->fDigitData[digit].fTime >= 255)
395                     index++;
396                   if(rowPt->fDigitData[digit].fTime >= 2*255)
397                     index++;
398                 }
399             }
400           
401           while(digit < rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad)
402             {
403               //Write the charge:
404               index++;
405               
406               //Check if the next digit is zero:
407               if(digit+1 < rowPt->fNDigit && rowPt->fDigitData[digit+1].fPad == pad)
408                 {
409                   if(rowPt->fDigitData[digit].fTime +1 != rowPt->fDigitData[digit+1].fTime)
410                     {
411                       index++;
412                       index++;
413                       
414                       //Check if we have to use more than 1 byte to write the zeros:
415                       UInt_t nzeros = rowPt->fDigitData[digit+1].fTime - rowPt->fDigitData[digit].fTime + 1;
416                       if(nzeros >= 255)
417                         index++;
418                       if(nzeros >= 2*255)
419                         index++;
420                     }  
421                 }
422               digit++;
423             }
424           
425           //Mark the end of the pad with 2 zeros:
426           index++;
427           index++;
428         }
429       
430       UpdateRowPointer(rowPt);
431     }
432   
433   return index * sizeof(Byte_t);
434   
435 }
436
437 UInt_t AliHLTDataHandler::CompMemory2Memory(UInt_t nrow,AliHLTDigitRowData *data,Byte_t *comp)
438 {
439   //Uncompress RLE data.
440   
441   if(!data)
442     {
443       LOG(AliHLTLog::kError,"AliHLTDataHandler::CompMemory2Memory","Array")
444         <<AliHLTLog::kHex<<"Pointer to data: "<<(void*)data<<ENDLOG;
445       return 0;
446     }
447   if(!comp)
448     {
449       LOG(AliHLTLog::kError,"AliHLTDataHandler::CompMemory2Memory","Array")
450         <<AliHLTLog::kHex<<"Pointer to compressed data: "<<(void*)comp<<ENDLOG;
451       return 0;
452     }
453   
454   Int_t outsize=0;
455   
456   AliHLTDigitRowData *rowPt = data;
457   UInt_t index=0;
458
459   UShort_t pad,time,charge;
460   for(UInt_t i=0; i<nrow; i++)
461     {
462       UInt_t ndigit=0;
463       
464       //Read the row:
465       rowPt->fRow = Read(comp,index);
466
467       //Read the number of pads:
468       UShort_t npads = Read(comp,index);
469       
470       for(UShort_t p=0; p<npads; p++)
471         {
472           //Read the current pad:
473           pad = Read(comp,index);
474           
475           time = 0;
476           
477           //Check for zeros:
478           if(Test(comp,index) == 0) //Zeros
479             {
480               //Read the first zero
481               Read(comp,index);
482               
483                 
484               if(Test(comp,index) == 0)//end of pad.
485                 {
486                   time = Read(comp,index); 
487                   continue;
488                 }
489               if( (time = Read(comp,index)) == 255 )
490                 if( (time += Read(comp,index)) == 2*255)
491                   time += Read(comp,index);
492             }
493
494           while(1)
495             {
496               while( (charge = Read(comp,index)) != 0)
497                 {
498                   if(time >= AliHLTTransform::GetNTimeBins())
499                     cerr<<"AliHLTDataHandler::CompMemory2Memory : Time out of range "<<time<<endl;
500                   rowPt->fDigitData[ndigit].fPad = pad;
501                   rowPt->fDigitData[ndigit].fTime = time;
502                   rowPt->fDigitData[ndigit].fCharge = charge;
503                   ndigit++;
504                   if(Test(comp,index) != 0)
505                     time++;
506                 }
507               if(Test(comp,index) == 0)
508                 {
509                   Read(comp,index); //end of pad
510                   break;
511                 }
512               UShort_t timeShift;
513               if( (timeShift = Read(comp,index)) == 255)
514                 if( (timeShift += Read(comp,index)) == 2*255)
515                   timeShift += Read(comp,index);
516               time += timeShift;
517               
518             }
519         }
520       rowPt->fNDigit = ndigit;
521       UpdateRowPointer(rowPt);
522       outsize += sizeof(AliHLTDigitData)*ndigit + sizeof(AliHLTDigitRowData);
523     }
524   
525   return outsize;
526 }
527
528 UInt_t AliHLTDataHandler::GetMemorySize(UInt_t nrow,Byte_t *comp)
529 {
530   //Calculate size (in bytes) of unpacked data.
531
532   UInt_t index=0;
533   Int_t outsize=0;
534   
535   for(UInt_t i=0; i<nrow; i++)
536     {
537       UInt_t ndigit=0;//Digits on this row.
538
539       //Row number:
540       Read(comp,index);
541       
542       UShort_t npad = Read(comp,index);
543       
544       for(UShort_t pad=0; pad<npad; pad++)
545         {
546           //Read the pad number:
547           Read(comp,index);
548           
549           //Check for zeros:
550           if(Test(comp,index)==0) //Zeros are coming
551             {
552               Read(comp,index);
553               if(Test(comp,index) == 0) 
554                 {
555                   Read(comp,index); //This was the end of pad.
556                   continue; 
557                 }
558               if(Read(comp,index) == 255) //There can be up to 3 bytes with zero coding.
559                 if(Read(comp,index) == 255)
560                   Read(comp,index);
561             }
562           
563           while(1)
564             {
565               while(Read(comp,index) != 0) ndigit++;
566               
567               if(Test(comp,index) == 0)
568                 {
569                   Read(comp,index); //2 zeros = end of pad.
570                   break;
571                 }
572               if(Read(comp,index) == 255) //There can be up to 3 bytes with zero coding.
573                 if(Read(comp,index) == 255)
574                   Read(comp,index);
575               
576             }
577           
578         }
579       Int_t size = sizeof(AliHLTDigitData)*ndigit + sizeof(AliHLTDigitRowData);
580       outsize += size;
581     }
582   return outsize;
583 }
584
585 Bool_t AliHLTDataHandler::CompBinary2CompMemory(UInt_t &nrow,Byte_t *comp)
586 {
587   //Read RLE data from binary file into array comp.
588   rewind(fInBinary);
589   UInt_t size = GetFileSize() - 2;
590   Byte_t type;
591   if(fread(&type,1,1,fInBinary)!=1) return kFALSE;
592   if(type > 0)
593     {
594       LOG(AliHLTLog::kError,"AliHLTDataHandler::CompBinary2CompMemory","Filetype")
595         <<"Inputfile does not seem to contain 8 bit data : "<<type<<ENDLOG;
596       return kFALSE;
597     }
598   if(fread(&nrow,1,1,fInBinary)!=1) return kFALSE;
599   if(fread(comp,size,1,fInBinary)!=1) return kFALSE;
600
601   return kTRUE;
602 }
603
604 Bool_t AliHLTDataHandler::CompMemory2CompBinary(UInt_t nrow,Byte_t *comp,UInt_t size)
605 {
606   //Write RLE data in comp to binary file.
607   //In order to distinguish these files from 10 bit data, 
608   //a zero is written to the beginning of the file.
609
610   Byte_t length = (Byte_t)nrow;
611   Byte_t type = 0;
612   if(fwrite(&type,1,1,fOutBinary)!=1) return kFALSE; //Write a zero, to mark that this file contains 8 bit data.
613   if(fwrite(&length,1,1,fOutBinary)!=1) return kFALSE;
614   if(fwrite(comp,size,1,fOutBinary)!=1) return kFALSE;
615   return kTRUE;
616 }