]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/misc/AliHLTDataHandler.cxx
L3 becomes HLT
[u/mrichter/AliRoot.git] / HLT / misc / AliHLTDataHandler.cxx
CommitLineData
3e87ef69 1// @(#) $Id$
b328544b 2
3// Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
3e87ef69 4//*-- Copyright &copy ALICE HLT Group
b328544b 5
4aa41877 6#include "AliHLTStandardIncludes.h"
24dbb695 7
4aa41877 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"
b328544b 16
5929c18d 17#if __GNUC__ >= 3
24dbb695 18using namespace std;
19#endif
b328544b 20
4aa41877 21/** \class AliHLTDataHandler
3e87ef69 22<pre>
b328544b 23//_____________________________________________________________
4aa41877 24// AliHLTDataHandler
b328544b 25//
26// HLT Binary file handler.
27//
4aa41877 28// This class have more or less the same functionality as AliHLTMemHandler,
b328544b 29// except that it handles 8 bit ADC-values. Reading and writing is done in the same way
4aa41877 30// as illustrated in example 1) and 2) in AliHLTMemHandler.
b328544b 31//
32// For converting 10 bit data files to 8 bit data files, do:
33//
4aa41877 34// AliHLTMemHandler *file = new AliHLTDataHandler();
494015ab 35// file->Init(slice,patch);
b328544b 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.
4aa41877 47// Conversion is done in the class AliHLTTransBit.
b328544b 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
ffe3a919 54// pad, 2 zeros are written. Example:
b328544b 55//
bbe06357 56// ROW NPADSWITHDATA PAD 0 NZEROS ADC ADC ADC ADC 0 NZEROS ADC ADC 0 0
b328544b 57//
58// Everything is written using 8 bit;
59// (ROW < 176, PAD < 200, ADC < 255, if(NZEROS > 255) write 2 words;)
3e87ef69 60</pre>
61*/
b328544b 62
4aa41877 63ClassImp(AliHLTDataHandler)
b328544b 64
4aa41877 65AliHLTDataHandler::AliHLTDataHandler()
b328544b 66{
54b54089 67 // default constructor
b328544b 68 fBitTransformer = 0;
4aa41877 69 LOG(AliHLTLog::kInformational,"AliHLTDataHandler::AliHLTDataHandler","Data format")
bbac14c8 70 <<"8 bit data handler initialized"<<ENDLOG;
b328544b 71}
72
4aa41877 73AliHLTDataHandler::~AliHLTDataHandler()
b328544b 74{
54b54089 75 // destructor
b328544b 76 if(fBitTransformer)
77 delete fBitTransformer;
b328544b 78}
79
4aa41877 80void AliHLTDataHandler::Convert10to8Bit()
b328544b 81{
82 //Convert from 10 bit data in inputfile, to 8 bit data written to outputfile.
83
84 if(!fInBinary)
85 {
4aa41877 86 LOG(AliHLTLog::kError,"AliHLTDataHandler::Convert10to8Bit","File")
87 <<AliHLTLog::kHex<<"Pointer to input file : "<<(void*)fInBinary<<ENDLOG;
b328544b 88 return;
89 }
90 if(!fOutBinary)
91 {
4aa41877 92 LOG(AliHLTLog::kError,"AliHLTDataHandler::Convert10to8Bit","File")
93 <<AliHLTLog::kHex<<"Pointer to output file : "<<(void*)fOutBinary<<ENDLOG;
b328544b 94 return;
95 }
96
97
98 //Initialize the bit transformation class:
4aa41877 99 fBitTransformer = new AliHLTTransBitV1();
b328544b 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
4aa41877 106 AliHLTMemHandler *memory = new AliHLTMemHandler();
494015ab 107 memory->Init(fSlice,fPatch);
b328544b 108 memory->SetBinaryInput(fInBinary);
109 UInt_t nrow;
4aa41877 110 AliHLTDigitRowData *data = (AliHLTDigitRowData*)memory->CompBinary2Memory(nrow);
b328544b 111
112 Memory2CompBinary(nrow,data);
113
114 delete memory;
115}
116
4aa41877 117Bool_t AliHLTDataHandler::Memory2CompBinary(UInt_t nrow,AliHLTDigitRowData *data)
b328544b 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 {
4aa41877 126 LOG(AliHLTLog::kError,"AliHLTDataHandler::Memory2CompBinary","File")
b328544b 127 <<"Error writing to file "<<ENDLOG;
128 return 0;
129 }
130 Free();
131 return kTRUE;
132}
133
4aa41877 134AliHLTDigitRowData *AliHLTDataHandler::CompBinary2Memory(UInt_t &nrow)
b328544b 135{
136 //Read RLE compressed binary file, unpack it and return pointer to it.
137
4aa41877 138 AliHLTMemHandler *memory = new AliHLTMemHandler();
b328544b 139 memory->SetBinaryInput(fInBinary);
140 Byte_t *comp = memory->Allocate();
141
142 if(!CompBinary2CompMemory(nrow,comp))
143 {
4aa41877 144 LOG(AliHLTLog::kError,"AliHLTDataHandler::CompBinary2Memory","File")
b328544b 145 <<"Error reading from file "<<ENDLOG;
146 return 0;
147 }
f587d39d 148
b328544b 149 UInt_t size = GetMemorySize(nrow,comp);
4aa41877 150 AliHLTDigitRowData *data = (AliHLTDigitRowData*)Allocate(size);
b328544b 151 CompMemory2Memory(nrow,data,comp);
152 delete memory;
153 return data;
154}
155
4aa41877 156void AliHLTDataHandler::Write(Byte_t *comp,UInt_t &index,UShort_t value)
b328544b 157{
158 //Write one value (=1 byte) to array comp.
159
160 if(value > 255)
161 {
4aa41877 162 LOG(AliHLTLog::kFatal,"AliHLTDataHandler::Write","Bitnumbers")
b328544b 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
4aa41877 169Short_t AliHLTDataHandler::Read(Byte_t *comp,UInt_t &index)
b328544b 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
4aa41877 178Short_t AliHLTDataHandler::Test(Byte_t *comp,UInt_t index)
b328544b 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
4aa41877 186Bool_t AliHLTDataHandler::Memory2CompMemory(UInt_t nrow,AliHLTDigitRowData *data,Byte_t *comp)
b328544b 187{
188 //Perform RLE.
189
190 if(!data)
191 {
4aa41877 192 LOG(AliHLTLog::kError,"AliHLTDataHandler::Memory2CompMemory","Data")
193 <<AliHLTLog::kHex<<" Pointer to data = "<<(void*)data<<ENDLOG;
b328544b 194 return 0;
195 }
196 if(!comp)
197 {
4aa41877 198 LOG(AliHLTLog::kError,"AliHLTDataHandler::Memory2CompMemory","Data")
199 <<AliHLTLog::kHex<<" Pointer to compressed data = "<<(void*)comp<<ENDLOG;
b328544b 200 return 0;
201 }
202
4aa41877 203 AliHLTDigitRowData *rowPt = data;
b328544b 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
54b54089 214 UShort_t numberOfPads=0;
215 UShort_t maxPad = 0;
b328544b 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 {
54b54089 228 numberOfPads++;
229 maxPad = j;
b328544b 230 }
231 }
232
233 //Write the number of pads on this row:
54b54089 234 Write(comp,index,numberOfPads);
b328544b 235 UInt_t digit=0;
236
54b54089 237 for(UShort_t pad=0; pad <= maxPad; pad++)
b328544b 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:
54b54089 255 Int_t numberOfZeroIntervals=0;
bbe06357 256 if(rowPt->fDigitData[digit].fTime >= 255)
b328544b 257 {
54b54089 258 numberOfZeroIntervals++;
b328544b 259 Write(comp,index,255);
bbe06357 260 if(rowPt->fDigitData[digit].fTime >= 2*255)
b328544b 261 {
4aa41877 262 cerr<<"AliHLTDataHandler::Memory2CompMemory : Should not happen "<<(Int_t)rowPt->fDigitData[digit].fTime<<endl;
b328544b 263 Write(comp,index,255);
54b54089 264 numberOfZeroIntervals++;
b328544b 265 }
266 }
54b54089 267 Write(comp,index,(rowPt->fDigitData[digit].fTime - numberOfZeroIntervals*255));
b328544b 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:
ffe3a919 279 if(charge>255)
b328544b 280 {
4aa41877 281 LOG(AliHLTLog::kWarning,"AliHLTDataHandler::Memory2CompMemory","Digit")
b328544b 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:
54b54089 298 Int_t numberOfZeroIntervals=0;
bbe06357 299 if(nzero >= 255)
b328544b 300 {
54b54089 301 numberOfZeroIntervals++;
b328544b 302 Write(comp,index,255);
bbe06357 303 if(nzero >= 2*255)
b328544b 304 {
4aa41877 305 cerr<<"AliHLTDataHandler::Memory2CompMemory : Should not happen "<<(Int_t)rowPt->fDigitData[digit].fTime<<endl;
b328544b 306 Write(comp,index,255);
54b54089 307 numberOfZeroIntervals++;
b328544b 308 }
309 }
54b54089 310 Write(comp,index,(nzero - numberOfZeroIntervals*255));
b328544b 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
4aa41877 329UInt_t AliHLTDataHandler::GetCompMemorySize(UInt_t nrow,AliHLTDigitRowData *data)
b328544b 330{
331 //Calculate the size (in bytes) of RLE data.
332
333 if(!data)
334 {
4aa41877 335 LOG(AliHLTLog::kError,"AliHLTDataHandler::GetCompMemorySize","Data")
336 <<AliHLTLog::kHex<<" Data pointer = "<<(void*)data<<ENDLOG;
b328544b 337 return 0;
338 }
339
4aa41877 340 AliHLTDigitRowData *rowPt = data;
b328544b 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
54b54089 350 UShort_t maxPad=0;
351 UShort_t numberOfPads = 0;
b328544b 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 {
54b54089 365 numberOfPads++;
366 maxPad = j;
b328544b 367 }
368 }
369
370 //Write the number of pads on this row:
371 index++;
372
373 UInt_t digit=0;
54b54089 374 for(UShort_t pad=0; pad <= maxPad; pad++)
b328544b 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:
bbe06357 394 if(rowPt->fDigitData[digit].fTime >= 255)
b328544b 395 index++;
bbe06357 396 if(rowPt->fDigitData[digit].fTime >= 2*255)
b328544b 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;
bbe06357 416 if(nzeros >= 255)
b328544b 417 index++;
bbe06357 418 if(nzeros >= 2*255)
b328544b 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
4aa41877 437UInt_t AliHLTDataHandler::CompMemory2Memory(UInt_t nrow,AliHLTDigitRowData *data,Byte_t *comp)
b328544b 438{
439 //Uncompress RLE data.
440
441 if(!data)
442 {
4aa41877 443 LOG(AliHLTLog::kError,"AliHLTDataHandler::CompMemory2Memory","Array")
444 <<AliHLTLog::kHex<<"Pointer to data: "<<(void*)data<<ENDLOG;
b328544b 445 return 0;
446 }
447 if(!comp)
448 {
4aa41877 449 LOG(AliHLTLog::kError,"AliHLTDataHandler::CompMemory2Memory","Array")
450 <<AliHLTLog::kHex<<"Pointer to compressed data: "<<(void*)comp<<ENDLOG;
b328544b 451 return 0;
452 }
453
454 Int_t outsize=0;
455
4aa41877 456 AliHLTDigitRowData *rowPt = data;
b328544b 457 UInt_t index=0;
ffe3a919 458
b328544b 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);
ffe3a919 466
b328544b 467 //Read the number of pads:
468 UShort_t npads = Read(comp,index);
ffe3a919 469
b328544b 470 for(UShort_t p=0; p<npads; p++)
471 {
472 //Read the current pad:
473 pad = Read(comp,index);
474
475 time = 0;
ffe3a919 476
477 //Check for zeros:
b328544b 478 if(Test(comp,index) == 0) //Zeros
479 {
480 //Read the first zero
481 Read(comp,index);
bbe06357 482
483
b328544b 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 }
f587d39d 493
b328544b 494 while(1)
495 {
496 while( (charge = Read(comp,index)) != 0)
497 {
4aa41877 498 if(time >= AliHLTTransform::GetNTimeBins())
499 cerr<<"AliHLTDataHandler::CompMemory2Memory : Time out of range "<<time<<endl;
b328544b 500 rowPt->fDigitData[ndigit].fPad = pad;
501 rowPt->fDigitData[ndigit].fTime = time;
502 rowPt->fDigitData[ndigit].fCharge = charge;
b328544b 503 ndigit++;
bbe06357 504 if(Test(comp,index) != 0)
505 time++;
b328544b 506 }
507 if(Test(comp,index) == 0)
508 {
509 Read(comp,index); //end of pad
510 break;
511 }
54b54089 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;
bbe06357 517
b328544b 518 }
519 }
520 rowPt->fNDigit = ndigit;
521 UpdateRowPointer(rowPt);
4aa41877 522 outsize += sizeof(AliHLTDigitData)*ndigit + sizeof(AliHLTDigitRowData);
b328544b 523 }
524
525 return outsize;
526}
527
4aa41877 528UInt_t AliHLTDataHandler::GetMemorySize(UInt_t nrow,Byte_t *comp)
b328544b 529{
530 //Calculate size (in bytes) of unpacked data.
531
532 UInt_t index=0;
533 Int_t outsize=0;
ffe3a919 534
b328544b 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);
ffe3a919 543
b328544b 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 }
ffe3a919 558 if(Read(comp,index) == 255) //There can be up to 3 bytes with zero coding.
559 if(Read(comp,index) == 255)
b328544b 560 Read(comp,index);
ffe3a919 561 }
562
563 while(1)
564 {
565 while(Read(comp,index) != 0) ndigit++;
b328544b 566
ffe3a919 567 if(Test(comp,index) == 0)
b328544b 568 {
ffe3a919 569 Read(comp,index); //2 zeros = end of pad.
570 break;
b328544b 571 }
ffe3a919 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
b328544b 576 }
ffe3a919 577
b328544b 578 }
4aa41877 579 Int_t size = sizeof(AliHLTDigitData)*ndigit + sizeof(AliHLTDigitRowData);
b328544b 580 outsize += size;
581 }
582 return outsize;
583}
584
4aa41877 585Bool_t AliHLTDataHandler::CompBinary2CompMemory(UInt_t &nrow,Byte_t *comp)
b328544b 586{
587 //Read RLE data from binary file into array comp.
b328544b 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 {
4aa41877 594 LOG(AliHLTLog::kError,"AliHLTDataHandler::CompBinary2CompMemory","Filetype")
b328544b 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
4aa41877 604Bool_t AliHLTDataHandler::CompMemory2CompBinary(UInt_t nrow,Byte_t *comp,UInt_t size)
b328544b 605{
606 //Write RLE data in comp to binary file.
494015ab 607 //In order to distinguish these files from 10 bit data,
b328544b 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}