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