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