3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright © ALICE HLT Group
6 #include "AliHLTStandardIncludes.h"
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"
21 /** \class AliHLTDataHandler
23 //_____________________________________________________________
26 // HLT Binary file handler.
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.
32 // For converting 10 bit data files to 8 bit data files, do:
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();
43 // Compress data format
44 // --------------------
46 // The data is RLE encoded, using _8_bit representation of the ADC-values.
47 // Conversion is done in the class AliHLTTransBit.
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:
56 // ROW NPADSWITHDATA PAD 0 NZEROS ADC ADC ADC ADC 0 NZEROS ADC ADC 0 0
58 // Everything is written using 8 bit;
59 // (ROW < 176, PAD < 200, ADC < 255, if(NZEROS > 255) write 2 words;)
63 ClassImp(AliHLTDataHandler)
65 AliHLTDataHandler::AliHLTDataHandler()
67 // default constructor
69 LOG(AliHLTLog::kInformational,"AliHLTDataHandler::AliHLTDataHandler","Data format")
70 <<"8 bit data handler initialized"<<ENDLOG;
73 AliHLTDataHandler::~AliHLTDataHandler()
77 delete fBitTransformer;
80 void AliHLTDataHandler::Convert10to8Bit()
82 //Convert from 10 bit data in inputfile, to 8 bit data written to outputfile.
86 LOG(AliHLTLog::kError,"AliHLTDataHandler::Convert10to8Bit","File")
87 <<AliHLTLog::kHex<<"Pointer to input file : "<<(void*)fInBinary<<ENDLOG;
92 LOG(AliHLTLog::kError,"AliHLTDataHandler::Convert10to8Bit","File")
93 <<AliHLTLog::kHex<<"Pointer to output file : "<<(void*)fOutBinary<<ENDLOG;
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();
106 AliHLTMemHandler *memory = new AliHLTMemHandler();
107 memory->Init(fSlice,fPatch);
108 memory->SetBinaryInput(fInBinary);
110 AliHLTDigitRowData *data = (AliHLTDigitRowData*)memory->CompBinary2Memory(nrow);
112 Memory2CompBinary(nrow,data);
117 Bool_t AliHLTDataHandler::Memory2CompBinary(UInt_t nrow,AliHLTDigitRowData *data)
119 //Compress data by RLE, and write to a binary file.
121 UInt_t size = GetCompMemorySize(nrow,data);
122 Byte_t *comp = Allocate(size);
123 Memory2CompMemory(nrow,data,comp);
124 if(!CompMemory2CompBinary(nrow,comp,size))
126 LOG(AliHLTLog::kError,"AliHLTDataHandler::Memory2CompBinary","File")
127 <<"Error writing to file "<<ENDLOG;
134 AliHLTDigitRowData *AliHLTDataHandler::CompBinary2Memory(UInt_t &nrow)
136 //Read RLE compressed binary file, unpack it and return pointer to it.
138 AliHLTMemHandler *memory = new AliHLTMemHandler();
139 memory->SetBinaryInput(fInBinary);
140 Byte_t *comp = memory->Allocate();
142 if(!CompBinary2CompMemory(nrow,comp))
144 LOG(AliHLTLog::kError,"AliHLTDataHandler::CompBinary2Memory","File")
145 <<"Error reading from file "<<ENDLOG;
149 UInt_t size = GetMemorySize(nrow,comp);
150 AliHLTDigitRowData *data = (AliHLTDigitRowData*)Allocate(size);
151 CompMemory2Memory(nrow,data,comp);
156 void AliHLTDataHandler::Write(Byte_t *comp,UInt_t &index,UShort_t value)
158 //Write one value (=1 byte) to array comp.
162 LOG(AliHLTLog::kFatal,"AliHLTDataHandler::Write","Bitnumbers")
163 <<"Value too big for storing in 1 byte, something is wrong: "<<value<<" "<<index<<ENDLOG;
165 comp[index] = (Byte_t)value;
169 Short_t AliHLTDataHandler::Read(Byte_t *comp,UInt_t &index)
171 //Read one value (=1 byte) from array comp
173 Short_t value = (Short_t)comp[index];
178 Short_t AliHLTDataHandler::Test(Byte_t *comp,UInt_t index)
180 //Check the value (=1 byte) in array comp, but not read.
182 Short_t value = (Short_t)comp[index];
186 Bool_t AliHLTDataHandler::Memory2CompMemory(UInt_t nrow,AliHLTDigitRowData *data,Byte_t *comp)
192 LOG(AliHLTLog::kError,"AliHLTDataHandler::Memory2CompMemory","Data")
193 <<AliHLTLog::kHex<<" Pointer to data = "<<(void*)data<<ENDLOG;
198 LOG(AliHLTLog::kError,"AliHLTDataHandler::Memory2CompMemory","Data")
199 <<AliHLTLog::kHex<<" Pointer to compressed data = "<<(void*)comp<<ENDLOG;
203 AliHLTDigitRowData *rowPt = data;
208 for(UInt_t i=0; i<nrow; i++)
210 //Write the row number:
211 UShort_t value = rowPt->fRow;
212 Write(comp,index,value);
214 UShort_t numberOfPads=0;
217 for(Int_t j=0; j<200; j++)
219 for(UInt_t dig=0; dig<rowPt->fNDigit; dig++)
221 if(rowPt->fDigitData[dig].fPad < 200)
222 npads[rowPt->fDigitData[dig].fPad]++;
224 for(Int_t j=0; j<200; j++)
233 //Write the number of pads on this row:
234 Write(comp,index,numberOfPads);
237 for(UShort_t pad=0; pad <= maxPad; pad++)
240 if(digit >= rowPt->fNDigit || rowPt->fDigitData[digit].fPad != pad)
243 //Write the current pad:
244 Write(comp,index,pad);
246 if(digit < rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad)
248 if(rowPt->fDigitData[digit].fTime > 0)
250 //If first time!=0, write the number of following zeros,
251 //and then the first timebin:
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)
258 numberOfZeroIntervals++;
259 Write(comp,index,255);
260 if(rowPt->fDigitData[digit].fTime >= 2*255)
262 cerr<<"AliHLTDataHandler::Memory2CompMemory : Should not happen "<<(Int_t)rowPt->fDigitData[digit].fTime<<endl;
263 Write(comp,index,255);
264 numberOfZeroIntervals++;
267 Write(comp,index,(rowPt->fDigitData[digit].fTime - numberOfZeroIntervals*255));
271 while(digit < rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad)
273 UShort_t charge = rowPt->fDigitData[digit].fCharge;
276 charge = fBitTransformer->Get0to1(charge); //Transform 10 to 8 bit.
278 //Check for saturation:
281 LOG(AliHLTLog::kWarning,"AliHLTDataHandler::Memory2CompMemory","Digit")
282 <<"ADC-value saturated : "<<charge<<ENDLOG;
287 Write(comp,index,charge);
289 //Check if the next digit is zero:
290 if(digit+1 < rowPt->fNDigit && rowPt->fDigitData[digit+1].fPad == pad)
292 if(rowPt->fDigitData[digit].fTime + 1 != rowPt->fDigitData[digit+1].fTime)
295 UShort_t nzero = rowPt->fDigitData[digit+1].fTime - (rowPt->fDigitData[digit].fTime + 1);
297 //Check if we have to use more than one byte to write the zeros:
298 Int_t numberOfZeroIntervals=0;
301 numberOfZeroIntervals++;
302 Write(comp,index,255);
305 cerr<<"AliHLTDataHandler::Memory2CompMemory : Should not happen "<<(Int_t)rowPt->fDigitData[digit].fTime<<endl;
306 Write(comp,index,255);
307 numberOfZeroIntervals++;
310 Write(comp,index,(nzero - numberOfZeroIntervals*255));
316 //This is the end of the pad, state it with 2 zeros:
321 UpdateRowPointer(rowPt);
325 return index * sizeof(Byte_t);
329 UInt_t AliHLTDataHandler::GetCompMemorySize(UInt_t nrow,AliHLTDigitRowData *data)
331 //Calculate the size (in bytes) of RLE data.
335 LOG(AliHLTLog::kError,"AliHLTDataHandler::GetCompMemorySize","Data")
336 <<AliHLTLog::kHex<<" Data pointer = "<<(void*)data<<ENDLOG;
340 AliHLTDigitRowData *rowPt = data;
345 for(UInt_t i=0;i<nrow;i++)
347 //Write the row number:
351 UShort_t numberOfPads = 0;
353 for(Int_t j=0; j<200; j++)
356 for(UInt_t dig=0; dig<rowPt->fNDigit; dig++)
358 if(rowPt->fDigitData[dig].fPad <200)
359 npads[rowPt->fDigitData[dig].fPad]++;
361 for(Int_t j=0; j<200; j++)
370 //Write the number of pads on this row:
374 for(UShort_t pad=0; pad <= maxPad; pad++)
376 if(digit>=rowPt->fNDigit || rowPt->fDigitData[digit].fPad != pad)
379 //Write the current pad:
383 if(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad)
385 if(rowPt->fDigitData[digit].fTime > 0)
387 //If first time!=0, write the number of following zeros,
388 //and then the first timebin:
393 //Check if we have to use more than 1 byte to write the zeros:
394 if(rowPt->fDigitData[digit].fTime >= 255)
396 if(rowPt->fDigitData[digit].fTime >= 2*255)
401 while(digit < rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad)
406 //Check if the next digit is zero:
407 if(digit+1 < rowPt->fNDigit && rowPt->fDigitData[digit+1].fPad == pad)
409 if(rowPt->fDigitData[digit].fTime +1 != rowPt->fDigitData[digit+1].fTime)
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;
425 //Mark the end of the pad with 2 zeros:
430 UpdateRowPointer(rowPt);
433 return index * sizeof(Byte_t);
437 UInt_t AliHLTDataHandler::CompMemory2Memory(UInt_t nrow,AliHLTDigitRowData *data,Byte_t *comp)
439 //Uncompress RLE data.
443 LOG(AliHLTLog::kError,"AliHLTDataHandler::CompMemory2Memory","Array")
444 <<AliHLTLog::kHex<<"Pointer to data: "<<(void*)data<<ENDLOG;
449 LOG(AliHLTLog::kError,"AliHLTDataHandler::CompMemory2Memory","Array")
450 <<AliHLTLog::kHex<<"Pointer to compressed data: "<<(void*)comp<<ENDLOG;
456 AliHLTDigitRowData *rowPt = data;
459 UShort_t pad,time,charge;
460 for(UInt_t i=0; i<nrow; i++)
465 rowPt->fRow = Read(comp,index);
467 //Read the number of pads:
468 UShort_t npads = Read(comp,index);
470 for(UShort_t p=0; p<npads; p++)
472 //Read the current pad:
473 pad = Read(comp,index);
478 if(Test(comp,index) == 0) //Zeros
480 //Read the first zero
484 if(Test(comp,index) == 0)//end of pad.
486 time = Read(comp,index);
489 if( (time = Read(comp,index)) == 255 )
490 if( (time += Read(comp,index)) == 2*255)
491 time += Read(comp,index);
496 while( (charge = Read(comp,index)) != 0)
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;
504 if(Test(comp,index) != 0)
507 if(Test(comp,index) == 0)
509 Read(comp,index); //end of pad
513 if( (timeShift = Read(comp,index)) == 255)
514 if( (timeShift += Read(comp,index)) == 2*255)
515 timeShift += Read(comp,index);
520 rowPt->fNDigit = ndigit;
521 UpdateRowPointer(rowPt);
522 outsize += sizeof(AliHLTDigitData)*ndigit + sizeof(AliHLTDigitRowData);
528 UInt_t AliHLTDataHandler::GetMemorySize(UInt_t nrow,Byte_t *comp)
530 //Calculate size (in bytes) of unpacked data.
535 for(UInt_t i=0; i<nrow; i++)
537 UInt_t ndigit=0;//Digits on this row.
542 UShort_t npad = Read(comp,index);
544 for(UShort_t pad=0; pad<npad; pad++)
546 //Read the pad number:
550 if(Test(comp,index)==0) //Zeros are coming
553 if(Test(comp,index) == 0)
555 Read(comp,index); //This was the end of pad.
558 if(Read(comp,index) == 255) //There can be up to 3 bytes with zero coding.
559 if(Read(comp,index) == 255)
565 while(Read(comp,index) != 0) ndigit++;
567 if(Test(comp,index) == 0)
569 Read(comp,index); //2 zeros = end of pad.
572 if(Read(comp,index) == 255) //There can be up to 3 bytes with zero coding.
573 if(Read(comp,index) == 255)
579 Int_t size = sizeof(AliHLTDigitData)*ndigit + sizeof(AliHLTDigitRowData);
585 Bool_t AliHLTDataHandler::CompBinary2CompMemory(UInt_t &nrow,Byte_t *comp)
587 //Read RLE data from binary file into array comp.
589 UInt_t size = GetFileSize() - 2;
591 if(fread(&type,1,1,fInBinary)!=1) return kFALSE;
594 LOG(AliHLTLog::kError,"AliHLTDataHandler::CompBinary2CompMemory","Filetype")
595 <<"Inputfile does not seem to contain 8 bit data : "<<type<<ENDLOG;
598 if(fread(&nrow,1,1,fInBinary)!=1) return kFALSE;
599 if(fread(comp,size,1,fInBinary)!=1) return kFALSE;
604 Bool_t AliHLTDataHandler::CompMemory2CompBinary(UInt_t nrow,Byte_t *comp,UInt_t size)
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.
610 Byte_t length = (Byte_t)nrow;
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;