ALIROOT-5708 AliRawReaderDate gets into a loop. The fix treats the cases when the...
[u/mrichter/AliRoot.git] / RAW / RAWDatarec / AliRawReaderDate.cxx
CommitLineData
16048fcf 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
bea6b2a4 16/* $Id$ */
17
16048fcf 18///////////////////////////////////////////////////////////////////////////////
bea6b2a4 19///
20/// This is a class for reading raw data from a date file or event.
21///
22/// The AliRawReaderDate is constructed either with a pointer to a
23/// date event or with a file name and an event number.
24///
16048fcf 25///////////////////////////////////////////////////////////////////////////////
26
27#include "AliRawReaderDate.h"
16048fcf 28#include "event.h"
16048fcf 29
30ClassImp(AliRawReaderDate)
31
32
34576417 33AliRawReaderDate::AliRawReaderDate(void* event, Bool_t owner) :
dd9a70fe 34 fFile(NULL),
c946ab02 35 fEvent(NULL),
36 fSubEvent(NULL),
37 fEquipment(NULL),
c946ab02 38 fPosition(NULL),
d87c6cb8 39 fEnd(NULL),
40 fOwner(owner)
16048fcf 41{
42// create an object to read digits from the given date event
43
16048fcf 44 fEvent = (eventHeaderStruct*) event;
c946ab02 45}
46
34576417 47AliRawReaderDate::AliRawReaderDate(const char* fileName, Int_t eventNumber) :
dd9a70fe 48 fFile(NULL),
c946ab02 49 fEvent(NULL),
50 fSubEvent(NULL),
51 fEquipment(NULL),
c946ab02 52 fPosition(NULL),
d87c6cb8 53 fEnd(NULL),
54 fOwner(kTRUE)
c946ab02 55{
56// create an object to read digits from the given date event
57
dd9a70fe 58 fFile = fopen(fileName, "rb");
59 if (!fFile) {
c946ab02 60 Error("AliRawReaderDate", "could not open file %s", fileName);
a97af23d 61 fIsValid = kFALSE;
c946ab02 62 return;
63 }
dd9a70fe 64 if (eventNumber < 0) return;
65
c946ab02 66 eventHeaderStruct header;
67 UInt_t headerSize = sizeof(eventHeaderStruct);
dd9a70fe 68 while (fread(&header, 1, headerSize, fFile) == headerSize) {
c946ab02 69 if (eventNumber == 0) {
70 UChar_t* buffer = new UChar_t[header.eventSize];
b91d160c 71 fseek(fFile, -(long)headerSize, SEEK_CUR);
dd9a70fe 72 if (fread(buffer, 1, header.eventSize, fFile) != header.eventSize) break;
c946ab02 73 fEvent = (eventHeaderStruct*) buffer;
c946ab02 74 break;
75 }
dd9a70fe 76 fseek(fFile, header.eventSize-headerSize, SEEK_CUR);
c946ab02 77 eventNumber--;
78 }
c946ab02 79
16048fcf 80}
81
c946ab02 82AliRawReaderDate::~AliRawReaderDate()
83{
84// destructor
85
d87c6cb8 86 if (fEvent && fOwner) delete[] fEvent;
dd9a70fe 87 if (fFile) {
dd9a70fe 88 fclose(fFile);
89 }
c946ab02 90}
91
16048fcf 92
93UInt_t AliRawReaderDate::GetType() const
94{
95// get the type from the event header
96
16048fcf 97 if (!fEvent) return 0;
98 return fEvent->eventType;
16048fcf 99}
100
101UInt_t AliRawReaderDate::GetRunNumber() const
102{
103// get the run number from the event header
104
16048fcf 105 if (!fEvent) return 0;
106 return fEvent->eventRunNb;
16048fcf 107}
108
109const UInt_t* AliRawReaderDate::GetEventId() const
110{
111// get the event id from the event header
112
16048fcf 113 if (!fEvent) return NULL;
114 return fEvent->eventId;
16048fcf 115}
116
117const UInt_t* AliRawReaderDate::GetTriggerPattern() const
118{
119// get the trigger pattern from the event header
120
16048fcf 121 if (!fEvent) return NULL;
122 return fEvent->eventTriggerPattern;
16048fcf 123}
124
125const UInt_t* AliRawReaderDate::GetDetectorPattern() const
126{
127// get the detector pattern from the event header
128
16048fcf 129 if (!fEvent) return NULL;
130 return fEvent->eventDetectorPattern;
16048fcf 131}
132
133const UInt_t* AliRawReaderDate::GetAttributes() const
134{
135// get the type attributes from the event header
136
16048fcf 137 if (!fEvent) return NULL;
138 return fEvent->eventTypeAttribute;
16048fcf 139}
140
e94ad92c 141const UInt_t* AliRawReaderDate::GetSubEventAttributes() const
142{
143// get the type attributes from the sub event header
144
e94ad92c 145 if (!fSubEvent) return NULL;
146 return fSubEvent->eventTypeAttribute;
e94ad92c 147}
148
c946ab02 149UInt_t AliRawReaderDate::GetLDCId() const
150{
151// get the LDC Id from the event header
152
c946ab02 153 if (!fSubEvent) return 0;
154 return fSubEvent->eventLdcId;
c946ab02 155}
156
16048fcf 157UInt_t AliRawReaderDate::GetGDCId() const
158{
159// get the GDC Id from the event header
160
16048fcf 161 if (!fEvent) return 0;
162 return fEvent->eventGdcId;
16048fcf 163}
164
741c154c 165UInt_t AliRawReaderDate::GetTimestamp() const
166{
167// get the timestamp from the event header
168
741c154c 169 if (!fEvent) return 0;
170 return fEvent->eventTimestamp;
741c154c 171}
16048fcf 172
c946ab02 173Int_t AliRawReaderDate::GetEquipmentSize() const
174{
299738b9 175// get the size of the equipment (including the header)
c946ab02 176
c946ab02 177 if (!fEquipment) return 0;
87db01b0 178 if (fSubEvent->eventVersion <= 0x00030001) {
299738b9 179 return fEquipment->equipmentSize + sizeof(equipmentHeaderStruct);
87db01b0 180 } else {
299738b9 181 return fEquipment->equipmentSize;
87db01b0 182 }
c946ab02 183}
184
185Int_t AliRawReaderDate::GetEquipmentType() const
186{
187// get the type from the equipment header
188
c946ab02 189 if (!fEquipment) return -1;
190 return fEquipment->equipmentType;
c946ab02 191}
192
193Int_t AliRawReaderDate::GetEquipmentId() const
194{
195// get the ID from the equipment header
196
c946ab02 197 if (!fEquipment) return -1;
198 return fEquipment->equipmentId;
c946ab02 199}
200
201const UInt_t* AliRawReaderDate::GetEquipmentAttributes() const
202{
203// get the attributes from the equipment header
204
c946ab02 205 if (!fEquipment) return NULL;
206 return fEquipment->equipmentTypeAttribute;
c946ab02 207}
208
209Int_t AliRawReaderDate::GetEquipmentElementSize() const
210{
211// get the basic element size from the equipment header
212
c946ab02 213 if (!fEquipment) return 0;
214 return fEquipment->equipmentBasicElementSize;
c946ab02 215}
216
299738b9 217Int_t AliRawReaderDate::GetEquipmentHeaderSize() const
218{
219 // Get the equipment header size
220 // 28 bytes by default
299738b9 221 return sizeof(equipmentHeaderStruct);
299738b9 222}
c946ab02 223
224Bool_t AliRawReaderDate::ReadHeader()
16048fcf 225{
39f9963f 226// read a data header at the current position
227// returns kFALSE if the data header could not be read
16048fcf 228
b4857df7 229 fErrorCode = 0;
230
921a8308 231 fHeader = NULL;
16048fcf 232 if (!fEvent) return kFALSE;
b4857df7 233 // check whether there are sub events
234 if (fEvent->eventSize <= fEvent->eventHeadSize) return kFALSE;
235
16048fcf 236 do {
b4857df7 237 // skip payload (if event was not selected)
238 if (fCount > 0) fPosition += fCount;
239
c946ab02 240 // get the first or the next equipment if at the end of an equipment
241 if (!fEquipment || (fPosition >= fEnd)) {
921a8308 242 fEquipment = NULL;
c946ab02 243
244 // get the first or the next sub event if at the end of a sub event
245 if (!fSubEvent ||
246 (fPosition >= ((UChar_t*)fSubEvent) + fSubEvent->eventSize)) {
247
248 // check for end of event data
249 if (fPosition >= ((UChar_t*)fEvent)+fEvent->eventSize) return kFALSE;
5ba96ac1 250 if (!TEST_SYSTEM_ATTRIBUTE(fEvent->eventTypeAttribute,
251 ATTR_SUPER_EVENT)) {
252 fSubEvent = fEvent; // no super event
253 } else if (fSubEvent) {
c946ab02 254 fSubEvent = (eventHeaderStruct*) (((UChar_t*)fSubEvent) +
255 fSubEvent->eventSize);
256 } else {
257 fSubEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) +
258 fEvent->eventHeadSize);
259 }
260
261 // check the magic word of the sub event
262 if (fSubEvent->eventMagic != EVENT_MAGIC_NUMBER) {
263 Error("ReadHeader", "wrong magic number in sub event!\n"
264 " run: %d event: %d %d LDC: %d GDC: %d\n",
265 fSubEvent->eventRunNb,
266 fSubEvent->eventId[0], fSubEvent->eventId[1],
267 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
268 fErrorCode = kErrMagic;
269 return kFALSE;
270 }
271
921a8308 272 // continue if no data in the subevent
273 if (fSubEvent->eventSize == fSubEvent->eventHeadSize) {
274 fPosition = fEnd = ((UChar_t*)fSubEvent) + fSubEvent->eventSize;
275 fCount = 0;
276 continue;
277 }
278
c946ab02 279 fEquipment = (equipmentHeaderStruct*)
280 (((UChar_t*)fSubEvent) + fSubEvent->eventHeadSize);
b4857df7 281
16048fcf 282 } else {
c946ab02 283 fEquipment = (equipmentHeaderStruct*) fEnd;
b4857df7 284 }
285
16048fcf 286 fCount = 0;
c946ab02 287 fPosition = ((UChar_t*)fEquipment) + sizeof(equipmentHeaderStruct);
87db01b0 288 if (fSubEvent->eventVersion <= 0x00030001) {
921a8308 289 fEnd = fPosition + fEquipment->equipmentSize;
290 } else {
291 fEnd = ((UChar_t*)fEquipment) + fEquipment->equipmentSize;
292 }
16048fcf 293 }
b4857df7 294
295 // continue with the next sub event if no data left in the payload
296 if (fPosition >= fEnd) continue;
297
39f9963f 298 if (fRequireHeader) {
299 // check that there are enough bytes left for the data header
300 if (fPosition + sizeof(AliRawDataHeader) > fEnd) {
301 Error("ReadHeader", "could not read data header data!");
34576417 302 Warning("ReadHeader", "skipping %ld bytes\n"
c946ab02 303 " run: %d event: %d %d LDC: %d GDC: %d\n",
304 fEnd - fPosition, fSubEvent->eventRunNb,
305 fSubEvent->eventId[0], fSubEvent->eventId[1],
306 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
307 fCount = 0;
308 fPosition = fEnd;
39f9963f 309 fErrorCode = kErrNoDataHeader;
c946ab02 310 continue;
311 }
b4857df7 312
39f9963f 313 // "read" the data header
314 fHeader = (AliRawDataHeader*) fPosition;
ba74320c 315 // Now check the version of the header
316 UChar_t version = 2;
317 if (fHeader) version=fHeader->GetVersion();
318
9974f9d8 319 switch (version) {
320 case 2:
321 {
322 if ((fPosition + fHeader->fSize) != fEnd) {
323 if ((fHeader->fSize != 0xFFFFFFFF) &&
324 (fEquipment->equipmentId != 4352))
325 Warning("ReadHeader",
326 "raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !",
327 fHeader->fSize, fEnd - fPosition);
328 fHeader->fSize = fEnd - fPosition;
329 }
330 fPosition += sizeof(AliRawDataHeader);
331 fHeaderV3 = 0;
332 break;
333 }
334 case 3:
335 {
336 fHeaderV3 = (AliRawDataHeaderV3*) fPosition;
337 if ((fPosition + fHeaderV3->fSize) != fEnd) {
338 if ((fHeaderV3->fSize != 0xFFFFFFFF) &&
339 (fEquipment->equipmentId != 4352))
340 Warning("ReadHeader",
341 "raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !",
342 fHeaderV3->fSize, fEnd - fPosition);
343 fHeaderV3->fSize = fEnd - fPosition;
344 }
345 fPosition += sizeof(AliRawDataHeaderV3);
346 fHeader = 0;
347 break;
ba74320c 348 }
9974f9d8 349 default:
350 // We have got a version we don't know
351 Error("ReadHeader",
352 "version is neither 2 nor 3, we can't handle it (version found : %d). Jump to the end of the equipment",version);
353 Warning("ReadHeader",
354 " run: %d event: %d %d LDC: %d GDC: %d\n",
355 fSubEvent->eventRunNb,
356 fSubEvent->eventId[0], fSubEvent->eventId[1],
357 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
358
359 fHeader = 0x0;
360 fHeaderV3 = 0x0;
361 fPosition = fEnd;
362 continue;
299738b9 363 }
72dd1d4f 364 }
39f9963f 365 if (fHeader && (fHeader->fSize != 0xFFFFFFFF)) {
366 fCount = fHeader->fSize - sizeof(AliRawDataHeader);
c946ab02 367
39f9963f 368 // check consistency of data size in the header and in the sub event
c946ab02 369 if (fPosition + fCount > fEnd) {
39f9963f 370 Error("ReadHeader", "size in data header exceeds event size!");
34576417 371 Warning("ReadHeader", "skipping %ld bytes\n"
c946ab02 372 " run: %d event: %d %d LDC: %d GDC: %d\n",
373 fEnd - fPosition, fSubEvent->eventRunNb,
374 fSubEvent->eventId[0], fSubEvent->eventId[1],
375 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
376 fCount = 0;
377 fPosition = fEnd;
378 fErrorCode = kErrSize;
379 continue;
380 }
381
ba74320c 382 } else if (fHeaderV3 && (fHeaderV3->fSize != 0xFFFFFFFF)) {
383 fCount = fHeaderV3->fSize - sizeof(AliRawDataHeaderV3);
384
385 // check consistency of data size in the header and in the sub event
386 if (fPosition + fCount > fEnd) {
387 Error("ReadHeader", "size in data header exceeds event size!");
34576417 388 Warning("ReadHeader", "skipping %ld bytes\n"
ba74320c 389 " run: %d event: %d %d LDC: %d GDC: %d\n",
390 fEnd - fPosition, fSubEvent->eventRunNb,
391 fSubEvent->eventId[0], fSubEvent->eventId[1],
392 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
393 fCount = 0;
394 fPosition = fEnd;
395 fErrorCode = kErrSize;
396 continue;
397 }
398
c946ab02 399 } else {
400 fCount = fEnd - fPosition;
16048fcf 401 }
b4857df7 402
921a8308 403 } while (!fEquipment || !IsSelected());
b4857df7 404
16048fcf 405 return kTRUE;
16048fcf 406}
407
408Bool_t AliRawReaderDate::ReadNextData(UChar_t*& data)
409{
410// reads the next payload at the current position
411// returns kFALSE if the data could not be read
412
b4857df7 413 fErrorCode = 0;
16048fcf 414 while (fCount == 0) {
c946ab02 415 if (!ReadHeader()) return kFALSE;
16048fcf 416 }
417 data = fPosition;
418 fPosition += fCount;
419 fCount = 0;
420 return kTRUE;
421}
422
423Bool_t AliRawReaderDate::ReadNext(UChar_t* data, Int_t size)
424{
425// reads the next block of data at the current position
426// returns kFALSE if the data could not be read
427
b4857df7 428 fErrorCode = 0;
16048fcf 429 if (fPosition + size > fEnd) {
430 Error("ReadNext", "could not read data!");
b4857df7 431 fErrorCode = kErrOutOfBounds;
16048fcf 432 return kFALSE;
433 }
434 memcpy(data, fPosition, size);
435 fPosition += size;
436 fCount -= size;
437 return kTRUE;
438}
439
440
441Bool_t AliRawReaderDate::Reset()
442{
443// reset the current position to the beginning of the event
444
16048fcf 445 fSubEvent = NULL;
d7aa1c7c 446 fEquipment = NULL;
16048fcf 447 fCount = 0;
448 fPosition = fEnd = NULL;
ba74320c 449 fHeader=NULL;
450 fHeaderV3=NULL;
16048fcf 451 return kTRUE;
452}
b4857df7 453
454
dd9a70fe 455Bool_t AliRawReaderDate::NextEvent()
456{
457// go to the next event in the date file
458
b04576f7 459 if (!fFile) {
460 if (fEventNumber < 0 && fEvent) {
461 fEventNumber++;
462 return kTRUE;
463 }
464 else
465 return kFALSE;
466 }
dd9a70fe 467
d7aa1c7c 468 Reset();
dd9a70fe 469 eventHeaderStruct header;
470 UInt_t headerSize = sizeof(eventHeaderStruct);
471 if (fEvent) delete[] fEvent;
472 fEvent = &header;
473
474 while (fread(&header, 1, headerSize, fFile) == headerSize) {
475 if (!IsEventSelected()) {
476 fseek(fFile, header.eventSize-headerSize, SEEK_CUR);
477 continue;
478 }
479 UChar_t* buffer = new UChar_t[header.eventSize];
b91d160c 480 fseek(fFile, -(long)headerSize, SEEK_CUR);
dd9a70fe 481 if (fread(buffer, 1, header.eventSize, fFile) != header.eventSize) {
482 Error("NextEvent", "could not read event from file");
483 delete[] buffer;
484 break;
485 }
486 fEvent = (eventHeaderStruct*) buffer;
38cf12f3 487 fEventNumber++;
dd9a70fe 488 return kTRUE;
489 };
490
491 fEvent = NULL;
5bec8712 492
dd9a70fe 493 return kFALSE;
494}
495
496Bool_t AliRawReaderDate::RewindEvents()
497{
498// go back to the beginning of the date file
499
b04576f7 500 if (fFile)
501 fseek(fFile, 0, SEEK_SET);
dd9a70fe 502
38cf12f3 503 fEventNumber = -1;
dd9a70fe 504 return Reset();
505}
506
507
b4857df7 508Int_t AliRawReaderDate::CheckData() const
509{
510// check the consistency of the data
511
b4857df7 512 if (!fEvent) return 0;
513 // check whether there are sub events
514 if (fEvent->eventSize <= fEvent->eventHeadSize) return 0;
515
516 eventHeaderStruct* subEvent = NULL;
517 UChar_t* position = 0;
518 UChar_t* end = 0;
be50fca2 519 Int_t result = 0;
b4857df7 520
521 while (kTRUE) {
522 // get the first or the next sub event if at the end of a sub event
523 if (!subEvent || (position >= end)) {
524
525 // check for end of event data
be50fca2 526 if (position >= ((UChar_t*)fEvent)+fEvent->eventSize) return result;
5ba96ac1 527 if (!TEST_SYSTEM_ATTRIBUTE(fEvent->eventTypeAttribute,
528 ATTR_SUPER_EVENT)) {
529 subEvent = fEvent; // no super event
530 } else if (subEvent) {
b4857df7 531 subEvent = (eventHeaderStruct*) (((UChar_t*)subEvent) +
532 subEvent->eventSize);
533 } else {
534 subEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) +
535 fEvent->eventHeadSize);
536 }
537
538 // check the magic word of the sub event
be50fca2 539 if (subEvent->eventMagic != EVENT_MAGIC_NUMBER) {
540 result |= kErrMagic;
541 return result;
542 }
b4857df7 543
544 position = ((UChar_t*)subEvent) + subEvent->eventHeadSize +
545 sizeof(equipmentHeaderStruct);
546 end = ((UChar_t*)subEvent) + subEvent->eventSize;
547 }
548
549 // continue with the next sub event if no data left in the payload
550 if (position >= end) continue;
551
18882b3b 552 if (fRequireHeader) {
39f9963f 553 // check that there are enough bytes left for the data header
18882b3b 554 if (position + sizeof(AliRawDataHeader) > end) {
555 result |= kErrNoDataHeader;
39f9963f 556 position = end;
18882b3b 557 continue;
558 }
559
4433a5ac 560 // Here we have to check if we have header v2 or v3
18882b3b 561 // check consistency of data size in the data header and in the sub event
562 AliRawDataHeader* header = (AliRawDataHeader*) position;
4433a5ac 563 UChar_t version = header->GetVersion();
564 if (version==2) {
565 if ((position + header->fSize) != end) {
566 if (header->fSize != 0xFFFFFFFF)
567 Warning("CheckData",
568 "raw data size found in the header V2 is wrong (%d != %ld)! Using the equipment size instead !",
569 header->fSize, end - position);
570 header->fSize = end - position;
571 result |= kErrSize;
572 }
39f9963f 573 }
4433a5ac 574 else if (version==3) {
575 AliRawDataHeaderV3 * headerV3 = (AliRawDataHeaderV3*) position;
576 if ((position + headerV3->fSize) != end) {
577 if (headerV3->fSize != 0xFFFFFFFF)
578 Warning("CheckData",
579 "raw data size found in the header V3 is wrong (%d != %ld)! Using the equipment size instead !",
580 headerV3->fSize, end - position);
581 headerV3->fSize = end - position;
582 result |= kErrSize;
583 }
584 }
585
be50fca2 586 }
18882b3b 587 position = end;
b4857df7 588 };
589
b4857df7 590 return 0;
591}
b900a426 592
593AliRawReader* AliRawReaderDate::CloneSingleEvent() const
594{
595 // Clones the current event and
596 // creates raw-reader for the cloned event
597 // Can be used in order to make asynchronious
598 // access to the current raw data within
599 // several threads (online event display/reco)
600
b900a426 601 if (fEvent) {
602 UInt_t evSize = fEvent->eventSize;
603 if (evSize) {
604 UChar_t *newEvent = new UChar_t[evSize];
605 memcpy(newEvent,fEvent,evSize);
d87c6cb8 606 return new AliRawReaderDate((void *)newEvent,kTRUE);
b900a426 607 }
608 }
b900a426 609 return NULL;
610}