1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////////
18 // This is a class for reading a raw data from a date event and providing
19 // information about digits
21 ///////////////////////////////////////////////////////////////////////////////
23 #include "AliRawReaderDate.h"
28 ClassImp(AliRawReaderDate)
31 AliRawReaderDate::AliRawReaderDate(
38 fRequireMiniHeader(kTRUE),
46 // create an object to read digits from the given date event
49 fEvent = (eventHeaderStruct*) event;
51 Fatal("AliRawReaderDate", "this class was compiled without DATE");
55 AliRawReaderDate::AliRawReaderDate(
57 const char* fileName, Int_t eventNumber
59 const char* /*fileName*/,
63 fRequireMiniHeader(kTRUE),
71 // create an object to read digits from the given date event
74 FILE* file = fopen(fileName, "rb");
76 Error("AliRawReaderDate", "could not open file %s", fileName);
79 eventHeaderStruct header;
80 UInt_t headerSize = sizeof(eventHeaderStruct);
81 while (fread(&header, 1, headerSize, file) == headerSize) {
82 if (eventNumber == 0) {
83 UChar_t* buffer = new UChar_t[header.eventSize];
84 fseek(file, -headerSize, SEEK_CUR);
85 if (fread(buffer, 1, header.eventSize, file) != header.eventSize) break;
86 fEvent = (eventHeaderStruct*) buffer;
90 fseek(file, header.eventSize-headerSize, SEEK_CUR);
96 Fatal("AliRawReaderDate", "this class was compiled without DATE");
100 AliRawReaderDate::AliRawReaderDate(const AliRawReaderDate& rawReader) :
101 AliRawReader(rawReader),
102 fRequireMiniHeader(rawReader.fRequireMiniHeader),
103 fEvent(rawReader.fEvent),
104 fSubEvent(rawReader.fSubEvent),
105 fEquipment(rawReader.fEquipment),
107 fPosition(rawReader.fPosition),
115 AliRawReaderDate& AliRawReaderDate::operator = (const AliRawReaderDate&
118 // assignment operator
120 this->~AliRawReaderDate();
121 new(this) AliRawReaderDate(rawReader);
125 AliRawReaderDate::~AliRawReaderDate()
130 if (fIsOwner) delete[] fEvent;
135 UInt_t AliRawReaderDate::GetType() const
137 // get the type from the event header
140 if (!fEvent) return 0;
141 return fEvent->eventType;
147 UInt_t AliRawReaderDate::GetRunNumber() const
149 // get the run number from the event header
152 if (!fEvent) return 0;
153 return fEvent->eventRunNb;
159 const UInt_t* AliRawReaderDate::GetEventId() const
161 // get the event id from the event header
164 if (!fEvent) return NULL;
165 return fEvent->eventId;
171 const UInt_t* AliRawReaderDate::GetTriggerPattern() const
173 // get the trigger pattern from the event header
176 if (!fEvent) return NULL;
177 return fEvent->eventTriggerPattern;
183 const UInt_t* AliRawReaderDate::GetDetectorPattern() const
185 // get the detector pattern from the event header
188 if (!fEvent) return NULL;
189 return fEvent->eventDetectorPattern;
195 const UInt_t* AliRawReaderDate::GetAttributes() const
197 // get the type attributes from the event header
200 if (!fEvent) return NULL;
201 return fEvent->eventTypeAttribute;
207 UInt_t AliRawReaderDate::GetLDCId() const
209 // get the LDC Id from the event header
212 if (!fSubEvent) return 0;
213 return fSubEvent->eventLdcId;
219 UInt_t AliRawReaderDate::GetGDCId() const
221 // get the GDC Id from the event header
224 if (!fEvent) return 0;
225 return fEvent->eventGdcId;
232 Int_t AliRawReaderDate::GetEquipmentSize() const
234 // get the size of the equipment
237 if (!fEquipment) return 0;
238 return fEquipment->equipmentSize;
244 Int_t AliRawReaderDate::GetEquipmentType() const
246 // get the type from the equipment header
249 if (!fEquipment) return -1;
250 return fEquipment->equipmentType;
256 Int_t AliRawReaderDate::GetEquipmentId() const
258 // get the ID from the equipment header
261 if (!fEquipment) return -1;
262 return fEquipment->equipmentId;
268 const UInt_t* AliRawReaderDate::GetEquipmentAttributes() const
270 // get the attributes from the equipment header
273 if (!fEquipment) return NULL;
274 return fEquipment->equipmentTypeAttribute;
280 Int_t AliRawReaderDate::GetEquipmentElementSize() const
282 // get the basic element size from the equipment header
285 if (!fEquipment) return 0;
286 return fEquipment->equipmentBasicElementSize;
293 Bool_t AliRawReaderDate::ReadHeader()
295 // read a mini header at the current position
296 // returns kFALSE if the mini header could not be read
301 if (!fEvent) return kFALSE;
302 // check whether there are sub events
303 if (fEvent->eventSize <= fEvent->eventHeadSize) return kFALSE;
306 // skip payload (if event was not selected)
307 if (fCount > 0) fPosition += fCount;
309 // get the first or the next equipment if at the end of an equipment
310 if (!fEquipment || (fPosition >= fEnd)) {
312 // get the first or the next sub event if at the end of a sub event
314 (fPosition >= ((UChar_t*)fSubEvent) + fSubEvent->eventSize)) {
316 // check for end of event data
317 if (fPosition >= ((UChar_t*)fEvent)+fEvent->eventSize) return kFALSE;
319 fSubEvent = (eventHeaderStruct*) (((UChar_t*)fSubEvent) +
320 fSubEvent->eventSize);
322 fSubEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) +
323 fEvent->eventHeadSize);
326 // check the magic word of the sub event
327 if (fSubEvent->eventMagic != EVENT_MAGIC_NUMBER) {
328 Error("ReadHeader", "wrong magic number in sub event!\n"
329 " run: %d event: %d %d LDC: %d GDC: %d\n",
330 fSubEvent->eventRunNb,
331 fSubEvent->eventId[0], fSubEvent->eventId[1],
332 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
333 fErrorCode = kErrMagic;
337 fEquipment = (equipmentHeaderStruct*)
338 (((UChar_t*)fSubEvent) + fSubEvent->eventHeadSize);
341 fEquipment = (equipmentHeaderStruct*) fEnd;
345 fPosition = ((UChar_t*)fEquipment) + sizeof(equipmentHeaderStruct);
346 fEnd = fPosition + fEquipment->equipmentSize;
349 // continue with the next sub event if no data left in the payload
350 if (fPosition >= fEnd) continue;
353 if (fRequireMiniHeader) {
354 // check that there are enough bytes left for the mini header
355 if (fPosition + sizeof(AliMiniHeader) > fEnd) {
356 Error("ReadHeader", "could not read mini header data!");
357 Warning("ReadHeader", "skipping %d bytes\n"
358 " run: %d event: %d %d LDC: %d GDC: %d\n",
359 fEnd - fPosition, fSubEvent->eventRunNb,
360 fSubEvent->eventId[0], fSubEvent->eventId[1],
361 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
364 fErrorCode = kErrNoMiniHeader;
368 // "read" and check the mini header
369 fMiniHeader = (AliMiniHeader*) fPosition;
370 fPosition += sizeof(AliMiniHeader);
371 if (!CheckMiniHeader()) {
372 Error("ReadHeader", "wrong magic word in mini header!");
373 Warning("ReadHeader", "skipping %d bytes\n"
374 " run: %d event: %d %d LDC: %d GDC: %d\n",
375 fEnd - fPosition, fSubEvent->eventRunNb,
376 fSubEvent->eventId[0], fSubEvent->eventId[1],
377 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
380 fErrorCode = kErrMiniMagic;
384 } else { // if mini header not required
385 // assume there is a mini header if the magic word is correct
386 if ((fPosition + sizeof(AliMiniHeader) <= fEnd) &&
387 CheckMiniHeader((AliMiniHeader*) fPosition)) {
388 fMiniHeader = (AliMiniHeader*) fPosition;
389 fPosition += sizeof(AliMiniHeader);
394 fCount = fMiniHeader->fSize;
396 // check consistency of data size in the mini header and in the sub event
397 if (fPosition + fCount > fEnd) {
398 Error("ReadHeader", "size in mini header exceeds event size!");
399 Warning("ReadHeader", "skipping %d bytes\n"
400 " run: %d event: %d %d LDC: %d GDC: %d\n",
401 fEnd - fPosition, fSubEvent->eventRunNb,
402 fSubEvent->eventId[0], fSubEvent->eventId[1],
403 fSubEvent->eventLdcId, fSubEvent->eventGdcId);
406 fErrorCode = kErrSize;
411 fCount = fEnd - fPosition;
414 } while (!IsSelected());
422 Bool_t AliRawReaderDate::ReadNextData(UChar_t*& data)
424 // reads the next payload at the current position
425 // returns kFALSE if the data could not be read
428 while (fCount == 0) {
429 if (!ReadHeader()) return kFALSE;
437 Bool_t AliRawReaderDate::ReadNext(UChar_t* data, Int_t size)
439 // reads the next block of data at the current position
440 // returns kFALSE if the data could not be read
443 if (fPosition + size > fEnd) {
444 Error("ReadNext", "could not read data!");
445 fErrorCode = kErrOutOfBounds;
448 memcpy(data, fPosition, size);
455 Bool_t AliRawReaderDate::Reset()
457 // reset the current position to the beginning of the event
463 fPosition = fEnd = NULL;
468 Int_t AliRawReaderDate::CheckData() const
470 // check the consistency of the data
473 if (!fEvent) return 0;
474 // check whether there are sub events
475 if (fEvent->eventSize <= fEvent->eventHeadSize) return 0;
477 eventHeaderStruct* subEvent = NULL;
478 UChar_t* position = 0;
483 // get the first or the next sub event if at the end of a sub event
484 if (!subEvent || (position >= end)) {
486 // check for end of event data
487 if (position >= ((UChar_t*)fEvent)+fEvent->eventSize) return result;
489 subEvent = (eventHeaderStruct*) (((UChar_t*)subEvent) +
490 subEvent->eventSize);
492 subEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) +
493 fEvent->eventHeadSize);
496 // check the magic word of the sub event
497 if (subEvent->eventMagic != EVENT_MAGIC_NUMBER) {
502 position = ((UChar_t*)subEvent) + subEvent->eventHeadSize +
503 sizeof(equipmentHeaderStruct);
504 end = ((UChar_t*)subEvent) + subEvent->eventSize;
507 // continue with the next sub event if no data left in the payload
508 if (position >= end) continue;
510 // check that there are enough bytes left for the mini header
511 if (position + sizeof(AliMiniHeader) > end) {
512 result |= kErrNoMiniHeader;
517 // "read" and check the mini header
518 AliMiniHeader* miniHeader = (AliMiniHeader*) position;
519 position += sizeof(AliMiniHeader);
520 if (!CheckMiniHeader(miniHeader)){
521 result |= kErrMiniMagic;
526 // check consistency of data size in the mini header and in the sub event
527 if (position + miniHeader->fSize > end) result |= kErrSize;
528 position += miniHeader->fSize;