]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/misc/AliL3DataHandler.cxx
Coding violation fixes.
[u/mrichter/AliRoot.git] / HLT / misc / AliL3DataHandler.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
24dbb695 6#include "AliL3StandardIncludes.h"
7
3e87ef69 8#include "AliL3RootTypes.h"
9#include "AliL3Logging.h"
10#include "AliL3MemHandler.h"
b328544b 11#include "AliL3Logging.h"
d8dd4947 12#include "AliL3TransBit.h"
bbe06357 13#include "AliL3Transform.h"
3e87ef69 14#include "AliL3DataHandler.h"
4feb6a26 15#include "AliL3DigitData.h"
b328544b 16
0bd0c1ef 17#if __GNUC__ == 3
24dbb695 18using namespace std;
19#endif
b328544b 20
3e87ef69 21/** \class AliL3DataHandler
22<pre>
b328544b 23//_____________________________________________________________
24// AliL3DataHandler
25//
26// HLT Binary file handler.
27//
28// This class have more or less the same functionality as AliL3MemHandler,
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 AliL3MemHandler.
31//
32// For converting 10 bit data files to 8 bit data files, do:
33//
34// AliL3MemHandler *file = new AliL3DataHandler();
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.
d8dd4947 47// Conversion is done in the class AliL3TransBit.
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
63ClassImp(AliL3DataHandler)
b328544b 64
65AliL3DataHandler::AliL3DataHandler()
66{
54b54089 67 // default constructor
b328544b 68 fBitTransformer = 0;
bbac14c8 69 LOG(AliL3Log::kInformational,"AliL3DataHandler::AliL3DataHandler","Data format")
70 <<"8 bit data handler initialized"<<ENDLOG;
b328544b 71}
72
73AliL3DataHandler::~AliL3DataHandler()
74{
54b54089 75 // destructor
b328544b 76 if(fBitTransformer)
77 delete fBitTransformer;
b328544b 78}
79
80void AliL3DataHandler::Convert10to8Bit()
81{
82 //Convert from 10 bit data in inputfile, to 8 bit data written to outputfile.
83
84 if(!fInBinary)
85 {
86 LOG(AliL3Log::kError,"AliL3DataHandler::Convert10to8Bit","File")
87 <<AliL3Log::kHex<<"Pointer to input file : "<<(Int_t)fInBinary<<ENDLOG;
88 return;
89 }
90 if(!fOutBinary)
91 {
92 LOG(AliL3Log::kError,"AliL3DataHandler::Convert10to8Bit","File")
93 <<AliL3Log::kHex<<"Pointer to output file : "<<(Int_t)fOutBinary<<ENDLOG;
94 return;
95 }
96
97
98 //Initialize the bit transformation class:
54b54089 99 fBitTransformer = new AliL3TransBitV1();
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
106 AliL3MemHandler *memory = new AliL3MemHandler();
494015ab 107 memory->Init(fSlice,fPatch);
b328544b 108 memory->SetBinaryInput(fInBinary);
109 UInt_t nrow;
110 AliL3DigitRowData *data = (AliL3DigitRowData*)memory->CompBinary2Memory(nrow);
111
112 Memory2CompBinary(nrow,data);
113
114 delete memory;
115}
116
117Bool_t AliL3DataHandler::Memory2CompBinary(UInt_t nrow,AliL3DigitRowData *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(AliL3Log::kError,"AliL3DataHandler::Memory2CompBinary","File")
127 <<"Error writing to file "<<ENDLOG;
128 return 0;
129 }
130 Free();
131 return kTRUE;
132}
133
134AliL3DigitRowData *AliL3DataHandler::CompBinary2Memory(UInt_t &nrow)
135{
136 //Read RLE compressed binary file, unpack it and return pointer to it.
137
138 AliL3MemHandler *memory = new AliL3MemHandler();
139 memory->SetBinaryInput(fInBinary);
140 Byte_t *comp = memory->Allocate();
141
142 if(!CompBinary2CompMemory(nrow,comp))
143 {
144 LOG(AliL3Log::kError,"AliL3DataHandler::CompBinary2Memory","File")
145 <<"Error reading from file "<<ENDLOG;
146 return 0;
147 }
f587d39d 148
b328544b 149 UInt_t size = GetMemorySize(nrow,comp);
150 AliL3DigitRowData *data = (AliL3DigitRowData*)Allocate(size);
151 CompMemory2Memory(nrow,data,comp);
152 delete memory;
153 return data;
154}
155
156void AliL3DataHandler::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(AliL3Log::kFatal,"AliL3DataHandler::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
169Short_t AliL3DataHandler::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
178Short_t AliL3DataHandler::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
186Bool_t AliL3DataHandler::Memory2CompMemory(UInt_t nrow,AliL3DigitRowData *data,Byte_t *comp)
187{
188 //Perform RLE.
189
190 if(!data)
191 {
192 LOG(AliL3Log::kError,"AliL3DataHandler::Memory2CompMemory","Data")
193 <<AliL3Log::kHex<<" Pointer to data = "<<(Int_t)data<<ENDLOG;
194 return 0;
195 }
196 if(!comp)
197 {
198 LOG(AliL3Log::kError,"AliL3DataHandler::Memory2CompMemory","Data")
199 <<AliL3Log::kHex<<" Pointer to compressed data = "<<(Int_t)comp<<ENDLOG;
200 return 0;
201 }
202
203 AliL3DigitRowData *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
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 {
bbe06357 262 cerr<<"AliL3DataHandler::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 {
281 LOG(AliL3Log::kWarning,"AliL3DataHandler::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:
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 {
bbe06357 305 cerr<<"AliL3DataHandler::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
329UInt_t AliL3DataHandler::GetCompMemorySize(UInt_t nrow,AliL3DigitRowData *data)
330{
331 //Calculate the size (in bytes) of RLE data.
332
333 if(!data)
334 {
335 LOG(AliL3Log::kError,"AliL3DataHandler::GetCompMemorySize","Data")
336 <<AliL3Log::kHex<<" Data pointer = "<<(Int_t)data<<ENDLOG;
337 return 0;
338 }
339
340 AliL3DigitRowData *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
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
437UInt_t AliL3DataHandler::CompMemory2Memory(UInt_t nrow,AliL3DigitRowData *data,Byte_t *comp)
438{
439 //Uncompress RLE data.
440
441 if(!data)
442 {
443 LOG(AliL3Log::kError,"AliL3DataHandler::CompMemory2Memory","Array")
444 <<AliL3Log::kHex<<"Pointer to data: "<<(Int_t)data<<ENDLOG;
445 return 0;
446 }
447 if(!comp)
448 {
449 LOG(AliL3Log::kError,"AliL3DataHandler::CompMemory2Memory","Array")
450 <<AliL3Log::kHex<<"Pointer to compressed data: "<<(Int_t)data<<ENDLOG;
451 return 0;
452 }
453
454 Int_t outsize=0;
455
456 AliL3DigitRowData *rowPt = data;
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 {
bbe06357 498 if(time >= AliL3Transform::GetNTimeBins())
499 cerr<<"AliL3DataHandler::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);
522 outsize += sizeof(AliL3DigitData)*ndigit + sizeof(AliL3DigitRowData);
523 }
524
525 return outsize;
526}
527
528UInt_t AliL3DataHandler::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;
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 }
579 Int_t size = sizeof(AliL3DigitData)*ndigit + sizeof(AliL3DigitRowData);
580 outsize += size;
581 }
582 return outsize;
583}
584
585Bool_t AliL3DataHandler::CompBinary2CompMemory(UInt_t &nrow,Byte_t *comp)
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 {
594 LOG(AliL3Log::kError,"AliL3DataHandler::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
604Bool_t AliL3DataHandler::CompMemory2CompBinary(UInt_t nrow,Byte_t *comp,UInt_t size)
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}