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