3ea47630 |
1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * |
3 | * * |
4 | * Author: The ALICE Off-line Project. * |
5 | * Contributors are mentioned in the code where appropriate. * |
6 | * * |
7 | * Permission to use, copy, modify and distribute this software and its * |
8 | * documentation strictly for non-commercial purposes is hereby granted * |
9 | * without fee, provided that the above copyright notice appears in all * |
10 | * copies and that both the copyright notice and this permission notice * |
11 | * appear in the supporting documentation. The authors make no claims * |
12 | * about the suitability of this software for any purpose. It is * |
13 | * provided "as is" without express or implied warranty. * |
14 | **************************************************************************/ |
15 | |
16 | /* $Id$ */ |
17 | |
18 | // Interface to the Altro format |
19 | // to read and write digits |
20 | // To be used in Alice Data Challenges |
21 | // and in the compression of the RAW data |
22 | // Author: D.Favretto |
23 | |
24 | #include "AliAltroBuffer.h" |
5802cf2d |
25 | #include "AliAltroMapping.h" |
3ea47630 |
26 | #include "AliRawDataHeader.h" |
5802cf2d |
27 | #include "AliLog.h" |
3ea47630 |
28 | #include <Riostream.h> |
29 | #include <stdlib.h> |
30 | |
31 | |
32 | ClassImp(AliAltroBuffer) |
33 | |
3ea47630 |
34 | //_____________________________________________________________________________ |
5802cf2d |
35 | AliAltroBuffer::AliAltroBuffer(const char* fileName, Int_t flag, const AliAltroMapping *mapping): |
3ea47630 |
36 | fShift(0), |
37 | fCurrentCell(0), |
38 | fFreeCellBuffer(0), |
39 | fFlag(flag), |
40 | fVerbose(0), |
41 | fFile(NULL), |
42 | fMaskBackward(0xFF), |
43 | fFilePosition(0), |
44 | fFileEnd(0), |
45 | fDataHeaderPos(0), |
5802cf2d |
46 | fEndingFillWords(0), |
47 | fMapping(mapping) |
3ea47630 |
48 | { |
49 | //if flag = 1 the actual object is used in the write mode |
50 | //if flag = 0 the actual object is used in the read mode |
51 | |
52 | //the buffer is cleaned |
53 | for (Int_t i = 0; i < 5; i++) fBuffer[i] = 0; |
54 | |
55 | if (flag) { |
56 | fFreeCellBuffer = 16; |
57 | fShift = 32; |
58 | //open the output file |
59 | #ifndef __DECCXX |
60 | fFile = new fstream(fileName, ios::binary|ios::out); |
61 | #else |
62 | fFile = new fstream(fileName, ios::out); |
63 | #endif |
64 | } else { |
65 | //open the input file |
66 | #ifndef __DECCXX |
67 | fFile = new fstream(fileName, ios::binary|ios::in); |
68 | #else |
69 | fFile = new fstream(fileName, ios::in); |
70 | #endif |
71 | if (!fFile) { |
72 | Error("AliAltroBuffer", "File doesn't exist: %s", fileName); |
73 | return; |
74 | } |
75 | fShift = 0; |
76 | //To get the file dimension (position of the last element in term of bytes) |
77 | fFile->seekg(0, ios::end); |
78 | fFilePosition = fFile->tellg(); |
79 | fFileEnd = fFilePosition; |
80 | fFile->seekg(0); |
81 | } |
5802cf2d |
82 | |
3ea47630 |
83 | } |
84 | |
85 | //_____________________________________________________________________________ |
86 | AliAltroBuffer::~AliAltroBuffer() |
87 | { |
88 | // destructor |
89 | |
90 | if (fFlag) { |
91 | //Flush out the Buffer content at the end only if Buffer wasn't completely filled |
92 | Flush(); |
93 | if (fVerbose) Info("~AliAltroBuffer", "File Created"); |
94 | }//end if |
95 | fFile->close(); |
96 | delete fFile; |
5802cf2d |
97 | |
3ea47630 |
98 | } |
99 | |
100 | //_____________________________________________________________________________ |
101 | AliAltroBuffer::AliAltroBuffer(const AliAltroBuffer& source): |
102 | TObject(source), |
103 | fShift(source.fShift), |
104 | fCurrentCell(source.fCurrentCell), |
105 | fFreeCellBuffer(source.fFreeCellBuffer), |
106 | fFlag(source.fFlag), |
107 | fVerbose(source.fVerbose), |
108 | fFile(NULL), |
109 | fMaskBackward(source.fMaskBackward), |
110 | fFilePosition(source.fFilePosition), |
111 | fFileEnd(source.fFileEnd), |
112 | fDataHeaderPos(source.fDataHeaderPos), |
5802cf2d |
113 | fEndingFillWords(source.fEndingFillWords), |
114 | fMapping(source.fMapping) |
3ea47630 |
115 | { |
116 | // Copy Constructor |
117 | |
118 | Fatal("AliAltroBuffer", "copy constructor not implemented"); |
119 | } |
120 | |
121 | //_____________________________________________________________________________ |
122 | AliAltroBuffer& AliAltroBuffer::operator = (const AliAltroBuffer& /*source*/) |
123 | { |
124 | //Assigment operator |
125 | |
126 | Fatal("operator =", "assignment operator not implemented"); |
127 | return *this; |
128 | } |
129 | |
130 | |
131 | //_____________________________________________________________________________ |
132 | Int_t AliAltroBuffer::GetNext() |
133 | { |
134 | //It reads a 10 bits word in forward dicection from the Buffer. |
135 | //A new Buffer is read from the file only when Buffer is empty. |
136 | //If there aren't elements anymore -1 is returned otherwise |
137 | //the next element is returned |
138 | |
139 | UInt_t mask = 0xFFC00000; |
140 | UInt_t temp; |
141 | UInt_t value; |
142 | if (!fShift) { |
143 | if (fFile->tellg() >= (Int_t)fFileEnd) return -1; |
144 | if (fFile->read((char*)fBuffer, sizeof(UInt_t)*5)) { |
145 | fCurrentCell = 0; |
146 | fShift = 22; |
147 | value = fBuffer[fCurrentCell] & mask; |
148 | value = value >> 22; |
149 | fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << 10; |
150 | return value; |
151 | } else { |
152 | return -1; |
153 | } |
154 | } else { |
155 | if (fShift >= 10) { |
156 | value = fBuffer[fCurrentCell] & mask; |
157 | value = value >> 22; |
158 | fShift -= 10; |
159 | fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << 10; |
160 | } else { |
161 | value = fBuffer[fCurrentCell] & mask; |
162 | fCurrentCell++; |
163 | temp = fBuffer[fCurrentCell]; |
164 | temp = temp >> fShift; |
165 | temp = temp & mask; |
166 | value = value | temp; |
167 | value = value >> 22; |
168 | fBuffer[fCurrentCell] = fBuffer[fCurrentCell] << (10-fShift); |
169 | fShift += 22; |
170 | } |
171 | return value; |
172 | }//end else |
173 | } |
174 | |
175 | //_____________________________________________________________________________ |
176 | Int_t AliAltroBuffer::GetNextBackWord() |
177 | { |
178 | //It reads a 10 bits word in backward dicection from the Buffer. |
179 | //A new Buffer is read from the file only when Buffer is empty. |
180 | //If there aren't elements anymore -1 is returned otherwise |
181 | //the next element is returned |
182 | |
183 | UInt_t mask = 0x3FF; |
184 | UInt_t temp; |
185 | UInt_t value; |
186 | if (!fShift) { |
187 | if (fFilePosition > fDataHeaderPos){ |
188 | fFilePosition -= sizeof(UInt_t)*5; |
189 | fFile->seekg(fFilePosition); |
190 | fFile->read((char*)fBuffer, sizeof(UInt_t)*5); |
191 | |
192 | fCurrentCell = 4; |
193 | fShift = 22; |
194 | fMaskBackward = 0xFF; |
195 | value = fBuffer[fCurrentCell] & mask; |
196 | fBuffer[fCurrentCell] = fBuffer[fCurrentCell] >> 10; |
197 | return value; |
198 | } else { |
199 | fFile->seekg(fDataHeaderPos); |
200 | return -1; |
201 | } |
202 | } else { |
203 | if (fShift >= 10) { |
204 | value = fBuffer[fCurrentCell] & mask; |
205 | fShift -= 10; |
206 | fBuffer[fCurrentCell] = fBuffer[fCurrentCell] >> 10; |
207 | } else { |
208 | value = fBuffer[fCurrentCell]; |
209 | fCurrentCell--; |
210 | temp = fBuffer[fCurrentCell] & mask; |
211 | temp = temp & fMaskBackward; |
212 | fMaskBackward = fMaskBackward >> 2; |
213 | temp = temp << fShift; |
214 | value = value | temp; |
215 | fBuffer[fCurrentCell] = fBuffer[fCurrentCell] >> (10-fShift); |
216 | fShift = 22 + fShift; |
217 | } |
218 | return value; |
219 | }//end else |
220 | } |
221 | |
222 | //_____________________________________________________________________________ |
223 | void AliAltroBuffer::Flush() |
224 | { |
225 | // Flushes the Buffer content |
226 | if (fFreeCellBuffer != 16) { |
227 | Int_t temp = fFreeCellBuffer; |
228 | for (Int_t i = 0; i < temp; i++){ |
229 | FillBuffer(0x2AA); |
230 | }//end for |
231 | }//end if |
232 | } |
233 | |
234 | //_____________________________________________________________________________ |
235 | void AliAltroBuffer::FillBuffer(Int_t val) |
236 | { |
237 | //Fills the Buffer with 16 ten bits words and write into a file |
238 | |
23b19451 |
239 | if ((val > 0x3FF) || (val < 0)) { |
240 | Error("FillBuffer", "Value out of range (10 bits): %d", val); |
241 | val = 0x3FF; |
242 | } |
3ea47630 |
243 | fFreeCellBuffer--; |
244 | if (fShift < 10) { |
245 | Int_t temp = val; |
246 | val = val >> (10-fShift); |
247 | fBuffer[fCurrentCell] |= val; |
248 | fCurrentCell++; |
249 | fShift += 32; |
250 | val = temp; |
251 | } |
252 | fShift -= 10; |
253 | val = val << fShift; |
254 | fBuffer[fCurrentCell] |= val; |
255 | if (!fShift) { |
256 | //Buffer is written into a file |
257 | fFile->write((char*)fBuffer, sizeof(UInt_t)*5); |
258 | //Buffer is empty |
259 | for (Int_t j = 0; j < 5; j++) fBuffer[j] = 0; |
260 | fShift = 32; |
261 | fCurrentCell = 0; |
262 | fFreeCellBuffer = 16; |
263 | } |
264 | } |
265 | |
266 | |
5802cf2d |
267 | //_____________________________________________________________________________ |
268 | void AliAltroBuffer::WriteDummyTrailer(Int_t wordsNumber, Int_t padNumber, |
269 | Int_t rowNumber, Int_t secNumber) |
270 | { |
271 | //Writes a trailer of 40 bits |
272 | |
273 | Int_t num = fFreeCellBuffer % 4; |
274 | for(Int_t i = 0; i < num; i++) { |
275 | FillBuffer(0x2AA); |
276 | }//end for |
277 | FillBuffer(wordsNumber); |
278 | FillBuffer(padNumber); |
279 | FillBuffer(rowNumber); |
280 | FillBuffer(secNumber); |
281 | } |
282 | |
3ea47630 |
283 | //_____________________________________________________________________________ |
284 | void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Int_t padNumber, |
285 | Int_t rowNumber, Int_t secNumber) |
286 | { |
287 | //Writes a trailer of 40 bits |
288 | |
5802cf2d |
289 | if (!fMapping) { |
290 | AliError("No ALTRO mapping information is loaded! Filling a dummy trailer!"); |
291 | return WriteDummyTrailer(wordsNumber,padNumber, |
292 | rowNumber,secNumber); |
293 | } |
294 | |
20daa34d |
295 | Short_t hwAdress = fMapping->GetHWAdress(rowNumber,padNumber,secNumber); |
296 | if (hwAdress == -1) |
297 | AliFatal(Form("No hardware (ALTRO) adress found for these pad-row (%d) and pad (%d) indeces !",rowNumber,padNumber)); |
298 | WriteTrailer(wordsNumber,hwAdress); |
299 | } |
300 | |
301 | //_____________________________________________________________________________ |
302 | void AliAltroBuffer::WriteTrailer(Int_t wordsNumber, Short_t hwAdress) |
303 | { |
304 | //Writes a trailer of 40 bits using |
305 | //a given hardware adress |
3ea47630 |
306 | Int_t num = fFreeCellBuffer % 4; |
307 | for(Int_t i = 0; i < num; i++) { |
308 | FillBuffer(0x2AA); |
309 | }//end for |
5802cf2d |
310 | Int_t temp; |
311 | temp = 0x2AA; |
312 | FillBuffer(temp); |
313 | temp = 0xA << 6; |
16e29964 |
314 | temp |= ((wordsNumber & 0x3FF) >> 4); |
5802cf2d |
315 | FillBuffer(temp); |
316 | temp = (wordsNumber << 6) & 0x3FF; |
317 | temp |= (0xA << 2); |
318 | |
5802cf2d |
319 | temp |= (hwAdress >> 10) & 0x3; |
320 | FillBuffer(temp); |
321 | temp = hwAdress & 0x3FF; |
322 | FillBuffer(temp); |
3ea47630 |
323 | } |
324 | |
325 | //_____________________________________________________________________________ |
16e29964 |
326 | Bool_t AliAltroBuffer::ReadDummyTrailer(Int_t& wordsNumber, Int_t& padNumber, |
327 | Int_t& rowNumber, Int_t& secNumber) |
3ea47630 |
328 | { |
16e29964 |
329 | //Read a dummy trailer of 40 bits in the forward reading mode |
3ea47630 |
330 | |
331 | wordsNumber = GetNext(); |
332 | if (wordsNumber == -1) return kFALSE; |
333 | padNumber = GetNext(); |
334 | if (padNumber == -1) return kFALSE; |
335 | rowNumber = GetNext(); |
336 | if (rowNumber == -1) return kFALSE; |
337 | secNumber = GetNext(); |
338 | if (secNumber == -1) return kFALSE; |
339 | return kTRUE; |
340 | } |
341 | |
16e29964 |
342 | //_____________________________________________________________________________ |
343 | Bool_t AliAltroBuffer::ReadTrailer(Int_t& wordsNumber, Int_t& padNumber, |
344 | Int_t& rowNumber, Int_t& secNumber) |
345 | { |
346 | //Read a trailer of 40 bits in the forward reading mode |
347 | if (!fMapping) { |
348 | AliError("No ALTRO mapping information is loaded! Reading a dummy trailer!"); |
349 | return ReadDummyTrailer(wordsNumber,padNumber, |
350 | rowNumber,secNumber); |
351 | } |
352 | |
20daa34d |
353 | Short_t hwAdress; |
354 | if (!ReadTrailer(wordsNumber,hwAdress)) return kFALSE; |
355 | rowNumber = fMapping->GetPadRow(hwAdress); |
356 | padNumber = fMapping->GetPad(hwAdress); |
357 | secNumber = fMapping->GetSector(hwAdress); |
358 | |
359 | return kTRUE; |
360 | } |
361 | |
362 | //_____________________________________________________________________________ |
363 | Bool_t AliAltroBuffer::ReadTrailer(Int_t& wordsNumber, Short_t& hwAdress) |
364 | { |
365 | //Read a trailer of 40 bits in the forward reading mode |
366 | |
16e29964 |
367 | Int_t temp = GetNext(); |
368 | if (temp != 0x2AA) |
369 | AliFatal(Form("Incorrect trailer found ! Expecting 0x2AA but found %x !",temp)); |
370 | |
371 | temp = GetNext(); |
372 | if ((temp >> 6) != 0xA) |
373 | AliFatal(Form("Incorrect trailer found ! Expecting 0xA but found %x !",temp >> 6)); |
374 | wordsNumber = (temp << 4) & 0x3FF; |
375 | |
376 | temp = GetNext(); |
377 | wordsNumber |= (temp >> 6); |
20daa34d |
378 | if (((temp >> 2) & 0xF) != 0xA) |
16e29964 |
379 | AliFatal(Form("Incorrect trailer found ! Expecting second 0xA but found %x !",temp >> 6)); |
20daa34d |
380 | hwAdress = (temp & 0x3) << 10; |
16e29964 |
381 | |
382 | temp = GetNext(); |
383 | hwAdress |= temp; |
384 | |
16e29964 |
385 | return kTRUE; |
386 | } |
387 | |
3ea47630 |
388 | //_____________________________________________________________________________ |
20daa34d |
389 | Bool_t AliAltroBuffer::ReadDummyTrailerBackward(Int_t& wordsNumber, Int_t& padNumber, |
390 | Int_t& rowNumber, Int_t& secNumber) |
3ea47630 |
391 | { |
392 | //Read a trailer of 40 bits in the backward reading mode |
393 | |
394 | Int_t temp; |
395 | fEndingFillWords = 0; |
396 | do { |
397 | temp = GetNextBackWord(); |
398 | fEndingFillWords++; |
399 | if (temp == -1) return kFALSE; |
400 | } while (temp == 0x2AA); |
401 | fEndingFillWords--; |
402 | secNumber = temp; |
403 | rowNumber = GetNextBackWord(); |
404 | if (rowNumber == -1) return kFALSE; |
405 | padNumber = GetNextBackWord(); |
406 | if (padNumber == -1) return kFALSE; |
407 | wordsNumber = GetNextBackWord(); |
408 | if (wordsNumber == -1) return kFALSE; |
409 | return kTRUE; |
410 | } |
411 | |
20daa34d |
412 | //_____________________________________________________________________________ |
413 | Bool_t AliAltroBuffer::ReadTrailerBackward(Int_t& wordsNumber, Int_t& padNumber, |
414 | Int_t& rowNumber, Int_t& secNumber) |
415 | { |
416 | //Read a trailer of 40 bits in the backward reading mode |
417 | if (!fMapping) { |
418 | AliError("No ALTRO mapping information is loaded! Reading a dummy trailer!"); |
419 | return ReadDummyTrailerBackward(wordsNumber,padNumber, |
420 | rowNumber,secNumber); |
421 | } |
422 | |
423 | Short_t hwAdress; |
424 | if (!ReadTrailerBackward(wordsNumber,hwAdress)) return kFALSE; |
425 | rowNumber = fMapping->GetPadRow(hwAdress); |
426 | padNumber = fMapping->GetPad(hwAdress); |
427 | secNumber = fMapping->GetSector(hwAdress); |
428 | |
429 | return kTRUE; |
430 | } |
431 | |
432 | //_____________________________________________________________________________ |
433 | Bool_t AliAltroBuffer::ReadTrailerBackward(Int_t& wordsNumber, Short_t& hwAdress) |
434 | { |
435 | //Read a trailer of 40 bits in the backward reading mode |
436 | |
437 | Int_t temp; |
438 | fEndingFillWords = 0; |
439 | do { |
440 | temp = GetNextBackWord(); |
441 | fEndingFillWords++; |
442 | if (temp == -1) return kFALSE; |
443 | } while (temp == 0x2AA); |
444 | fEndingFillWords--; |
445 | |
446 | hwAdress = temp; |
447 | |
448 | temp = GetNextBackWord(); |
449 | hwAdress |= (temp & 0x3) << 10; |
450 | if (((temp >> 2) & 0xF) != 0xA) |
451 | AliFatal(Form("Incorrect trailer found ! Expecting second 0xA but found %x !",temp >> 6)); |
452 | wordsNumber = (temp >> 6); |
453 | |
454 | temp = GetNextBackWord(); |
455 | wordsNumber |= (temp << 4) & 0x3FF; |
456 | if ((temp >> 6) != 0xA) |
457 | AliFatal(Form("Incorrect trailer found ! Expecting 0xA but found %x !",temp >> 6)); |
458 | |
459 | temp = GetNextBackWord(); |
460 | if (temp != 0x2AA) |
461 | AliFatal(Form("Incorrect trailer found ! Expecting 0x2AA but found %x !",temp)); |
462 | |
463 | return kTRUE; |
464 | } |
3ea47630 |
465 | |
466 | //_____________________________________________________________________________ |
467 | void AliAltroBuffer::WriteChannel(Int_t padNumber, Int_t rowNumber, |
468 | Int_t secNumber, |
469 | Int_t nTimeBins, const Int_t* adcValues, |
470 | Int_t threshold) |
471 | { |
472 | //Write all ADC values and the trailer of a channel |
473 | |
474 | Int_t nWords = 0; |
475 | Int_t timeBin = -1; |
476 | Int_t bunchLength = 0; |
477 | |
478 | // loop over time bins |
479 | for (Int_t iTime = 0; iTime < nTimeBins; iTime++) { |
480 | if (adcValues[iTime] >= threshold) { // ADC value above threshold |
481 | FillBuffer(adcValues[iTime]); |
482 | nWords++; |
483 | timeBin = iTime; |
484 | bunchLength++; |
485 | |
486 | } else if (timeBin >= 0) { // end of bunch |
487 | FillBuffer(timeBin); |
488 | FillBuffer(bunchLength + 2); |
489 | nWords += 2; |
490 | timeBin = -1; |
491 | bunchLength = 0; |
492 | } |
493 | } |
494 | |
495 | if (timeBin >= 0) { // end of bunch |
496 | FillBuffer(timeBin); |
497 | FillBuffer(bunchLength + 2); |
498 | nWords += 2; |
499 | } |
500 | |
501 | // write the trailer |
502 | WriteTrailer(nWords, padNumber, rowNumber, secNumber); |
503 | } |
504 | |
20daa34d |
505 | //_____________________________________________________________________________ |
506 | void AliAltroBuffer::ReadChannel(Int_t padNumber, Int_t rowNumber, |
507 | Int_t secNumber, |
508 | Int_t& nTimeBins, Int_t* adcValues) |
509 | { |
510 | //Read all ADC values and the trailer of a channel |
511 | |
512 | Int_t wordsNumber; |
513 | if (!ReadTrailer(wordsNumber,padNumber, |
514 | rowNumber,secNumber)) return; |
515 | |
516 | if (wordsNumber < 0) return; |
517 | // Number of fill words |
518 | Int_t nFillWords; |
519 | if ((wordsNumber % 4) == 0) |
520 | nFillWords = 0; |
521 | else |
522 | nFillWords = 4 - wordsNumber % 4; |
523 | // Read the fill words |
524 | for (Int_t i = 0; i < nFillWords; i++) { |
525 | Int_t temp = GetNext(); |
526 | if (temp != 0x2AA) |
527 | AliFatal(Form("Invalid fill word, expected 0x2AA, but got %X", temp)); |
528 | } |
529 | |
530 | // Decoding |
531 | Int_t lastWord = wordsNumber; |
532 | nTimeBins = -1; |
533 | while (lastWord > 0) { |
534 | Int_t l = GetNext(); |
535 | if (l < 0) AliFatal(Form("Bad bunch length (%d) !", l)); |
536 | Int_t t = GetNext(); |
537 | if (t < 0) AliFatal(Form("Bad bunch time (%d) !", t)); |
538 | lastWord -= 2; |
539 | if (nTimeBins == -1) nTimeBins = t + 1; |
540 | for (Int_t i = 2; i < l; i++) { |
541 | Int_t amp = GetNext(); |
542 | if (amp < 0) AliFatal(Form("Bad adc value (%X) !", amp)); |
543 | adcValues[t - (i-2)] = amp; |
544 | lastWord--; |
545 | } |
546 | } |
547 | |
548 | } |
3ea47630 |
549 | |
550 | //_____________________________________________________________________________ |
551 | void AliAltroBuffer::WriteDataHeader(Bool_t dummy, Bool_t compressed) |
552 | { |
553 | //Write a (dummy or real) DDL data header, |
554 | //set the compression bit if compressed |
555 | |
556 | AliRawDataHeader header; |
557 | if (dummy) { |
558 | //if size=0 it means that this data header is a dummy data header |
559 | fDataHeaderPos = fFile->tellp(); |
560 | fFile->write((char*)(&header), sizeof(header)); |
561 | } else { |
562 | UInt_t currentFilePos = fFile->tellp(); |
563 | fFile->seekp(fDataHeaderPos); |
564 | header.fSize = currentFilePos-fDataHeaderPos; |
565 | header.SetAttribute(0); // valid data |
566 | if (compressed) header.SetAttribute(1); |
567 | fFile->write((char*)(&header), sizeof(header)); |
568 | fFile->seekp(currentFilePos); |
569 | } |
570 | } |
b0aef454 |
571 | |
572 | //_____________________________________________________________________________ |
573 | Bool_t AliAltroBuffer::ReadDataHeader() |
574 | { |
575 | //Read the DDL data header at the beginning of the file, |
576 | //returns true in case of valid data |
577 | |
578 | AliRawDataHeader header; |
579 | UInt_t currentPos = fFile->tellp(); |
580 | fFile->seekp(0); |
581 | if (!fFile->read((char*)(&header), sizeof(header))) return kFALSE; |
582 | fDataHeaderPos = fFile->tellp(); |
583 | fFile->seekp(currentPos); |
584 | return header.TestAttribute(0); |
585 | } |
5802cf2d |
586 | |