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