ALIROOT-5420 ALIROOT5683 Consistent version (3.14) of event.h from DATE
[u/mrichter/AliRoot.git] / RAW / 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
319 if (version==2) {
320 if ((fPosition + fHeader->fSize) != fEnd) {
321 if ((fHeader->fSize != 0xFFFFFFFF) &&
322 (fEquipment->equipmentId != 4352))
323 Warning("ReadHeader",
34576417 324 "raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !",
ba74320c 325 fHeader->fSize, fEnd - fPosition);
326 fHeader->fSize = fEnd - fPosition;
327 }
328 fPosition += sizeof(AliRawDataHeader);
329 fHeaderV3 = 0;
330 } else if (version==3) {
331 fHeaderV3 = (AliRawDataHeaderV3*) fPosition;
332 if ((fPosition + fHeaderV3->fSize) != fEnd) {
333 if ((fHeaderV3->fSize != 0xFFFFFFFF) &&
334 (fEquipment->equipmentId != 4352))
335 Warning("ReadHeader",
34576417 336 "raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !",
ba74320c 337 fHeaderV3->fSize, fEnd - fPosition);
338 fHeaderV3->fSize = fEnd - fPosition;
339 }
340 fPosition += sizeof(AliRawDataHeaderV3);
341 fHeader = 0;
299738b9 342 }
72dd1d4f 343 }
c946ab02 344
39f9963f 345 if (fHeader && (fHeader->fSize != 0xFFFFFFFF)) {
346 fCount = fHeader->fSize - sizeof(AliRawDataHeader);
c946ab02 347
39f9963f 348 // check consistency of data size in the header and in the sub event
c946ab02 349 if (fPosition + fCount > fEnd) {
39f9963f 350 Error("ReadHeader", "size in data header exceeds event size!");
34576417 351 Warning("ReadHeader", "skipping %ld bytes\n"
c946ab02 352 " run: %d event: %d %d LDC: %d GDC: %d\n",
353 fEnd - fPosition, fSubEvent->eventRunNb,
354 fSubEvent->eventId[0], fSubEvent->eventId[1],
355 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
356 fCount = 0;
357 fPosition = fEnd;
358 fErrorCode = kErrSize;
359 continue;
360 }
361
ba74320c 362 } else if (fHeaderV3 && (fHeaderV3->fSize != 0xFFFFFFFF)) {
363 fCount = fHeaderV3->fSize - sizeof(AliRawDataHeaderV3);
364
365 // check consistency of data size in the header and in the sub event
366 if (fPosition + fCount > fEnd) {
367 Error("ReadHeader", "size in data header exceeds event size!");
34576417 368 Warning("ReadHeader", "skipping %ld bytes\n"
ba74320c 369 " run: %d event: %d %d LDC: %d GDC: %d\n",
370 fEnd - fPosition, fSubEvent->eventRunNb,
371 fSubEvent->eventId[0], fSubEvent->eventId[1],
372 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
373 fCount = 0;
374 fPosition = fEnd;
375 fErrorCode = kErrSize;
376 continue;
377 }
378
c946ab02 379 } else {
380 fCount = fEnd - fPosition;
16048fcf 381 }
b4857df7 382
921a8308 383 } while (!fEquipment || !IsSelected());
b4857df7 384
16048fcf 385 return kTRUE;
16048fcf 386}
387
388Bool_t AliRawReaderDate::ReadNextData(UChar_t*& data)
389{
390// reads the next payload at the current position
391// returns kFALSE if the data could not be read
392
b4857df7 393 fErrorCode = 0;
16048fcf 394 while (fCount == 0) {
c946ab02 395 if (!ReadHeader()) return kFALSE;
16048fcf 396 }
397 data = fPosition;
398 fPosition += fCount;
399 fCount = 0;
400 return kTRUE;
401}
402
403Bool_t AliRawReaderDate::ReadNext(UChar_t* data, Int_t size)
404{
405// reads the next block of data at the current position
406// returns kFALSE if the data could not be read
407
b4857df7 408 fErrorCode = 0;
16048fcf 409 if (fPosition + size > fEnd) {
410 Error("ReadNext", "could not read data!");
b4857df7 411 fErrorCode = kErrOutOfBounds;
16048fcf 412 return kFALSE;
413 }
414 memcpy(data, fPosition, size);
415 fPosition += size;
416 fCount -= size;
417 return kTRUE;
418}
419
420
421Bool_t AliRawReaderDate::Reset()
422{
423// reset the current position to the beginning of the event
424
16048fcf 425 fSubEvent = NULL;
d7aa1c7c 426 fEquipment = NULL;
16048fcf 427 fCount = 0;
428 fPosition = fEnd = NULL;
ba74320c 429 fHeader=NULL;
430 fHeaderV3=NULL;
16048fcf 431 return kTRUE;
432}
b4857df7 433
434
dd9a70fe 435Bool_t AliRawReaderDate::NextEvent()
436{
437// go to the next event in the date file
438
b04576f7 439 if (!fFile) {
440 if (fEventNumber < 0 && fEvent) {
441 fEventNumber++;
442 return kTRUE;
443 }
444 else
445 return kFALSE;
446 }
dd9a70fe 447
d7aa1c7c 448 Reset();
dd9a70fe 449 eventHeaderStruct header;
450 UInt_t headerSize = sizeof(eventHeaderStruct);
451 if (fEvent) delete[] fEvent;
452 fEvent = &header;
453
454 while (fread(&header, 1, headerSize, fFile) == headerSize) {
455 if (!IsEventSelected()) {
456 fseek(fFile, header.eventSize-headerSize, SEEK_CUR);
457 continue;
458 }
459 UChar_t* buffer = new UChar_t[header.eventSize];
b91d160c 460 fseek(fFile, -(long)headerSize, SEEK_CUR);
dd9a70fe 461 if (fread(buffer, 1, header.eventSize, fFile) != header.eventSize) {
462 Error("NextEvent", "could not read event from file");
463 delete[] buffer;
464 break;
465 }
466 fEvent = (eventHeaderStruct*) buffer;
38cf12f3 467 fEventNumber++;
dd9a70fe 468 return kTRUE;
469 };
470
471 fEvent = NULL;
5bec8712 472
dd9a70fe 473 return kFALSE;
474}
475
476Bool_t AliRawReaderDate::RewindEvents()
477{
478// go back to the beginning of the date file
479
b04576f7 480 if (fFile)
481 fseek(fFile, 0, SEEK_SET);
dd9a70fe 482
38cf12f3 483 fEventNumber = -1;
dd9a70fe 484 return Reset();
485}
486
487
b4857df7 488Int_t AliRawReaderDate::CheckData() const
489{
490// check the consistency of the data
491
b4857df7 492 if (!fEvent) return 0;
493 // check whether there are sub events
494 if (fEvent->eventSize <= fEvent->eventHeadSize) return 0;
495
496 eventHeaderStruct* subEvent = NULL;
497 UChar_t* position = 0;
498 UChar_t* end = 0;
be50fca2 499 Int_t result = 0;
b4857df7 500
501 while (kTRUE) {
502 // get the first or the next sub event if at the end of a sub event
503 if (!subEvent || (position >= end)) {
504
505 // check for end of event data
be50fca2 506 if (position >= ((UChar_t*)fEvent)+fEvent->eventSize) return result;
5ba96ac1 507 if (!TEST_SYSTEM_ATTRIBUTE(fEvent->eventTypeAttribute,
508 ATTR_SUPER_EVENT)) {
509 subEvent = fEvent; // no super event
510 } else if (subEvent) {
b4857df7 511 subEvent = (eventHeaderStruct*) (((UChar_t*)subEvent) +
512 subEvent->eventSize);
513 } else {
514 subEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) +
515 fEvent->eventHeadSize);
516 }
517
518 // check the magic word of the sub event
be50fca2 519 if (subEvent->eventMagic != EVENT_MAGIC_NUMBER) {
520 result |= kErrMagic;
521 return result;
522 }
b4857df7 523
524 position = ((UChar_t*)subEvent) + subEvent->eventHeadSize +
525 sizeof(equipmentHeaderStruct);
526 end = ((UChar_t*)subEvent) + subEvent->eventSize;
527 }
528
529 // continue with the next sub event if no data left in the payload
530 if (position >= end) continue;
531
18882b3b 532 if (fRequireHeader) {
39f9963f 533 // check that there are enough bytes left for the data header
18882b3b 534 if (position + sizeof(AliRawDataHeader) > end) {
535 result |= kErrNoDataHeader;
39f9963f 536 position = end;
18882b3b 537 continue;
538 }
539
540 // check consistency of data size in the data header and in the sub event
541 AliRawDataHeader* header = (AliRawDataHeader*) position;
299738b9 542 if ((position + header->fSize) != end) {
806e573c 543 if (header->fSize != 0xFFFFFFFF)
544 Warning("ReadHeader",
34576417 545 "raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !",
806e573c 546 header->fSize, end - position);
299738b9 547 header->fSize = end - position;
548 result |= kErrSize;
39f9963f 549 }
be50fca2 550 }
18882b3b 551 position = end;
b4857df7 552 };
553
b4857df7 554 return 0;
555}
b900a426 556
557AliRawReader* AliRawReaderDate::CloneSingleEvent() const
558{
559 // Clones the current event and
560 // creates raw-reader for the cloned event
561 // Can be used in order to make asynchronious
562 // access to the current raw data within
563 // several threads (online event display/reco)
564
b900a426 565 if (fEvent) {
566 UInt_t evSize = fEvent->eventSize;
567 if (evSize) {
568 UChar_t *newEvent = new UChar_t[evSize];
569 memcpy(newEvent,fEvent,evSize);
d87c6cb8 570 return new AliRawReaderDate((void *)newEvent,kTRUE);
b900a426 571 }
572 }
b900a426 573 return NULL;
574}