3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright © ASV
6 #include "AliL3StandardIncludes.h"
8 #include "AliL3DataHandler.h"
9 #include "AliL3Logging.h"
10 #include "AliTransBit.h"
11 #include "AliL3Transform.h"
17 //_____________________________________________________________
20 // HLT Binary file handler.
22 // This class have more or less the same functionality as AliL3MemHandler,
23 // except that it handles 8 bit ADC-values. Reading and writing is done in the same way
24 // as illustrated in example 1) and 2) in AliL3MemHandler.
26 // For converting 10 bit data files to 8 bit data files, do:
28 // AliL3MemHandler *file = new AliL3DataHandler();
29 // file->Init(slice,patch);
30 // file->SetBinaryInput(inputfile); //10 bit data file
31 // file->SetBinaryOutput(outputfile); //8 bit data file
32 // file->Convert10to8Bit();
33 // file->CloseBinaryInput();
34 // file->CloseBinaryOutput();
37 // Compress data format
38 // --------------------
40 // The data is RLE encoded, using _8_bit representation of the ADC-values.
41 // Conversion is done in the class AliTransBit.
43 // In the beginning of every row, the row number if written and the number of pads
44 // containing data on that row. For every pad with data the pad number is written,
45 // and then comes the ADC-values on that pad. When a serie of zeros occure, a zero
46 // is written followed by the number of zeros. If the number of zeros is more than
47 // 255 (8 bit), another 8 bit word is written for the remaining. At the end of one
48 // pad, 2 zeros are written. Example:
50 // ROW NPADSWITHDATA PAD 0 NZEROS ADC ADC ADC ADC 0 NZEROS ADC ADC 0 0
52 // Everything is written using 8 bit;
53 // (ROW < 176, PAD < 200, ADC < 255, if(NZEROS > 255) write 2 words;)
55 ClassImp(AliL3DataHandler)
58 AliL3DataHandler::AliL3DataHandler()
61 LOG(AliL3Log::kInformational,"AliL3DataHandler::AliL3DataHandler","Data format")
62 <<"8 bit data handler initialized"<<ENDLOG;
65 AliL3DataHandler::~AliL3DataHandler()
68 delete fBitTransformer;
72 void AliL3DataHandler::Convert10to8Bit()
74 //Convert from 10 bit data in inputfile, to 8 bit data written to outputfile.
78 LOG(AliL3Log::kError,"AliL3DataHandler::Convert10to8Bit","File")
79 <<AliL3Log::kHex<<"Pointer to input file : "<<(Int_t)fInBinary<<ENDLOG;
84 LOG(AliL3Log::kError,"AliL3DataHandler::Convert10to8Bit","File")
85 <<AliL3Log::kHex<<"Pointer to output file : "<<(Int_t)fOutBinary<<ENDLOG;
90 //Initialize the bit transformation class:
91 fBitTransformer = new AliTransBit_v1();
92 Int_t b0=10; // original number of bits
93 Int_t b1=8; // compressed
94 fBitTransformer->SetBits(b0,b1);
95 fBitTransformer->FindOptimumX0();
96 fBitTransformer->Update();
98 AliL3MemHandler *memory = new AliL3MemHandler();
99 memory->Init(fSlice,fPatch);
100 memory->SetBinaryInput(fInBinary);
102 AliL3DigitRowData *data = (AliL3DigitRowData*)memory->CompBinary2Memory(nrow);
104 Memory2CompBinary(nrow,data);
109 Bool_t AliL3DataHandler::Memory2CompBinary(UInt_t nrow,AliL3DigitRowData *data)
111 //Compress data by RLE, and write to a binary file.
113 UInt_t size = GetCompMemorySize(nrow,data);
114 Byte_t *comp = Allocate(size);
115 Memory2CompMemory(nrow,data,comp);
116 if(!CompMemory2CompBinary(nrow,comp,size))
118 LOG(AliL3Log::kError,"AliL3DataHandler::Memory2CompBinary","File")
119 <<"Error writing to file "<<ENDLOG;
126 AliL3DigitRowData *AliL3DataHandler::CompBinary2Memory(UInt_t &nrow)
128 //Read RLE compressed binary file, unpack it and return pointer to it.
130 AliL3MemHandler *memory = new AliL3MemHandler();
131 memory->SetBinaryInput(fInBinary);
132 Byte_t *comp = memory->Allocate();
134 if(!CompBinary2CompMemory(nrow,comp))
136 LOG(AliL3Log::kError,"AliL3DataHandler::CompBinary2Memory","File")
137 <<"Error reading from file "<<ENDLOG;
140 UInt_t size = GetMemorySize(nrow,comp);
141 AliL3DigitRowData *data = (AliL3DigitRowData*)Allocate(size);
142 CompMemory2Memory(nrow,data,comp);
147 void AliL3DataHandler::Write(Byte_t *comp,UInt_t &index,UShort_t value)
149 //Write one value (=1 byte) to array comp.
153 LOG(AliL3Log::kFatal,"AliL3DataHandler::Write","Bitnumbers")
154 <<"Value too big for storing in 1 byte, something is wrong: "<<value<<" "<<index<<ENDLOG;
156 comp[index] = (Byte_t)value;
160 Short_t AliL3DataHandler::Read(Byte_t *comp,UInt_t &index)
162 //Read one value (=1 byte) from array comp
164 Short_t value = (Short_t)comp[index];
169 Short_t AliL3DataHandler::Test(Byte_t *comp,UInt_t index)
171 //Check the value (=1 byte) in array comp, but not read.
173 Short_t value = (Short_t)comp[index];
177 Bool_t AliL3DataHandler::Memory2CompMemory(UInt_t nrow,AliL3DigitRowData *data,Byte_t *comp)
183 LOG(AliL3Log::kError,"AliL3DataHandler::Memory2CompMemory","Data")
184 <<AliL3Log::kHex<<" Pointer to data = "<<(Int_t)data<<ENDLOG;
189 LOG(AliL3Log::kError,"AliL3DataHandler::Memory2CompMemory","Data")
190 <<AliL3Log::kHex<<" Pointer to compressed data = "<<(Int_t)comp<<ENDLOG;
194 AliL3DigitRowData *rowPt = data;
199 for(UInt_t i=0; i<nrow; i++)
201 //Write the row number:
202 UShort_t value = rowPt->fRow;
203 Write(comp,index,value);
205 UShort_t number_of_pads=0;
206 UShort_t max_pad = 0;
208 for(Int_t j=0; j<200; j++)
210 for(UInt_t dig=0; dig<rowPt->fNDigit; dig++)
212 if(rowPt->fDigitData[dig].fPad < 200)
213 npads[rowPt->fDigitData[dig].fPad]++;
215 for(Int_t j=0; j<200; j++)
224 //Write the number of pads on this row:
225 Write(comp,index,number_of_pads);
228 for(UShort_t pad=0; pad <= max_pad; pad++)
231 if(digit >= rowPt->fNDigit || rowPt->fDigitData[digit].fPad != pad)
234 //Write the current pad:
235 Write(comp,index,pad);
237 if(digit < rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad)
239 if(rowPt->fDigitData[digit].fTime > 0)
241 //If first time!=0, write the number of following zeros,
242 //and then the first timebin:
245 //Check if we have to use more than 1 byte to write the zeros:
246 Int_t number_of_zero_intervals=0;
247 if(rowPt->fDigitData[digit].fTime >= 255)
249 number_of_zero_intervals++;
250 Write(comp,index,255);
251 if(rowPt->fDigitData[digit].fTime >= 2*255)
253 cerr<<"AliL3DataHandler::Memory2CompMemory : Should not happen "<<(Int_t)rowPt->fDigitData[digit].fTime<<endl;
254 Write(comp,index,255);
255 number_of_zero_intervals++;
258 Write(comp,index,(rowPt->fDigitData[digit].fTime - number_of_zero_intervals*255));
262 while(digit < rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad)
264 UShort_t charge = rowPt->fDigitData[digit].fCharge;
267 charge = fBitTransformer->Get0to1(charge); //Transform 10 to 8 bit.
269 //Check for saturation:
272 LOG(AliL3Log::kWarning,"AliL3DataHandler::Memory2CompMemory","Digit")
273 <<"ADC-value saturated : "<<charge<<ENDLOG;
278 Write(comp,index,charge);
280 //Check if the next digit is zero:
281 if(digit+1 < rowPt->fNDigit && rowPt->fDigitData[digit+1].fPad == pad)
283 if(rowPt->fDigitData[digit].fTime + 1 != rowPt->fDigitData[digit+1].fTime)
286 UShort_t nzero = rowPt->fDigitData[digit+1].fTime - (rowPt->fDigitData[digit].fTime + 1);
288 //Check if we have to use more than one byte to write the zeros:
289 Int_t number_of_zero_intervals=0;
292 number_of_zero_intervals++;
293 Write(comp,index,255);
296 cerr<<"AliL3DataHandler::Memory2CompMemory : Should not happen "<<(Int_t)rowPt->fDigitData[digit].fTime<<endl;
297 Write(comp,index,255);
298 number_of_zero_intervals++;
301 Write(comp,index,(nzero - number_of_zero_intervals*255));
307 //This is the end of the pad, state it with 2 zeros:
312 UpdateRowPointer(rowPt);
316 return index * sizeof(Byte_t);
320 UInt_t AliL3DataHandler::GetCompMemorySize(UInt_t nrow,AliL3DigitRowData *data)
322 //Calculate the size (in bytes) of RLE data.
326 LOG(AliL3Log::kError,"AliL3DataHandler::GetCompMemorySize","Data")
327 <<AliL3Log::kHex<<" Data pointer = "<<(Int_t)data<<ENDLOG;
331 AliL3DigitRowData *rowPt = data;
336 for(UInt_t i=0;i<nrow;i++)
338 //Write the row number:
342 UShort_t number_of_pads = 0;
344 for(Int_t j=0; j<200; j++)
347 for(UInt_t dig=0; dig<rowPt->fNDigit; dig++)
349 if(rowPt->fDigitData[dig].fPad <200)
350 npads[rowPt->fDigitData[dig].fPad]++;
352 for(Int_t j=0; j<200; j++)
361 //Write the number of pads on this row:
365 for(UShort_t pad=0; pad <= max_pad; pad++)
367 if(digit>=rowPt->fNDigit || rowPt->fDigitData[digit].fPad != pad)
370 //Write the current pad:
374 if(digit<rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad)
376 if(rowPt->fDigitData[digit].fTime > 0)
378 //If first time!=0, write the number of following zeros,
379 //and then the first timebin:
384 //Check if we have to use more than 1 byte to write the zeros:
385 if(rowPt->fDigitData[digit].fTime >= 255)
387 if(rowPt->fDigitData[digit].fTime >= 2*255)
392 while(digit < rowPt->fNDigit && rowPt->fDigitData[digit].fPad == pad)
397 //Check if the next digit is zero:
398 if(digit+1 < rowPt->fNDigit && rowPt->fDigitData[digit+1].fPad == pad)
400 if(rowPt->fDigitData[digit].fTime +1 != rowPt->fDigitData[digit+1].fTime)
405 //Check if we have to use more than 1 byte to write the zeros:
406 UInt_t nzeros = rowPt->fDigitData[digit+1].fTime - rowPt->fDigitData[digit].fTime + 1;
416 //Mark the end of the pad with 2 zeros:
421 UpdateRowPointer(rowPt);
424 return index * sizeof(Byte_t);
428 UInt_t AliL3DataHandler::CompMemory2Memory(UInt_t nrow,AliL3DigitRowData *data,Byte_t *comp)
430 //Uncompress RLE data.
434 LOG(AliL3Log::kError,"AliL3DataHandler::CompMemory2Memory","Array")
435 <<AliL3Log::kHex<<"Pointer to data: "<<(Int_t)data<<ENDLOG;
440 LOG(AliL3Log::kError,"AliL3DataHandler::CompMemory2Memory","Array")
441 <<AliL3Log::kHex<<"Pointer to compressed data: "<<(Int_t)data<<ENDLOG;
447 AliL3DigitRowData *rowPt = data;
450 UShort_t pad,time,charge;
451 for(UInt_t i=0; i<nrow; i++)
456 rowPt->fRow = Read(comp,index);
458 //Read the number of pads:
459 UShort_t npads = Read(comp,index);
461 for(UShort_t p=0; p<npads; p++)
463 //Read the current pad:
464 pad = Read(comp,index);
469 if(Test(comp,index) == 0) //Zeros
471 //Read the first zero
475 if(Test(comp,index) == 0)//end of pad.
477 time = Read(comp,index);
480 if( (time = Read(comp,index)) == 255 )
481 if( (time += Read(comp,index)) == 2*255)
482 time += Read(comp,index);
486 while( (charge = Read(comp,index)) != 0)
488 if(time >= AliL3Transform::GetNTimeBins())
489 cerr<<"AliL3DataHandler::CompMemory2Memory : Time out of range "<<time<<endl;
490 rowPt->fDigitData[ndigit].fPad = pad;
491 rowPt->fDigitData[ndigit].fTime = time;
492 rowPt->fDigitData[ndigit].fCharge = charge;
494 if(Test(comp,index) != 0)
498 if(Test(comp,index) == 0)
500 Read(comp,index); //end of pad
504 if( (time_shift = Read(comp,index)) == 255)
505 if( (time_shift += Read(comp,index)) == 2*255)
506 time_shift += Read(comp,index);
511 rowPt->fNDigit = ndigit;
512 UpdateRowPointer(rowPt);
513 outsize += sizeof(AliL3DigitData)*ndigit + sizeof(AliL3DigitRowData);
519 UInt_t AliL3DataHandler::GetMemorySize(UInt_t nrow,Byte_t *comp)
521 //Calculate size (in bytes) of unpacked data.
526 for(UInt_t i=0; i<nrow; i++)
528 UInt_t ndigit=0;//Digits on this row.
533 UShort_t npad = Read(comp,index);
535 for(UShort_t pad=0; pad<npad; pad++)
537 //Read the pad number:
541 if(Test(comp,index)==0) //Zeros are coming
544 if(Test(comp,index) == 0)
546 Read(comp,index); //This was the end of pad.
549 if(Read(comp,index) == 255) //There can be up to 3 bytes with zero coding.
550 if(Read(comp,index) == 255)
556 while(Read(comp,index) != 0) ndigit++;
558 if(Test(comp,index) == 0)
560 Read(comp,index); //2 zeros = end of pad.
563 if(Read(comp,index) == 255) //There can be up to 3 bytes with zero coding.
564 if(Read(comp,index) == 255)
570 Int_t size = sizeof(AliL3DigitData)*ndigit + sizeof(AliL3DigitRowData);
576 Bool_t AliL3DataHandler::CompBinary2CompMemory(UInt_t &nrow,Byte_t *comp)
578 //Read RLE data from binary file into array comp.
580 UInt_t size = GetFileSize() - 2;
582 if(fread(&type,1,1,fInBinary)!=1) return kFALSE;
585 LOG(AliL3Log::kError,"AliL3DataHandler::CompBinary2CompMemory","Filetype")
586 <<"Inputfile does not seem to contain 8 bit data : "<<type<<ENDLOG;
589 if(fread(&nrow,1,1,fInBinary)!=1) return kFALSE;
590 if(fread(comp,size,1,fInBinary)!=1) return kFALSE;
595 Bool_t AliL3DataHandler::CompMemory2CompBinary(UInt_t nrow,Byte_t *comp,UInt_t size)
597 //Write RLE data in comp to binary file.
598 //In order to distinguish these files from 10 bit data,
599 //a zero is written to the beginning of the file.
601 Byte_t length = (Byte_t)nrow;
603 if(fwrite(&type,1,1,fOutBinary)!=1) return kFALSE; //Write a zero, to mark that this file contains 8 bit data.
604 if(fwrite(&length,1,1,fOutBinary)!=1) return kFALSE;
605 if(fwrite(comp,size,1,fOutBinary)!=1) return kFALSE;