#include "AliRawReaderDate.h"
#include "event.h"
ClassImp(AliRawReaderDate)
AliRawReaderDate::AliRawReaderDate(void* event, Bool_t owner) :
fFile(NULL),
fEvent(NULL),
fSubEvent(NULL),
fEquipment(NULL),
fPosition(NULL),
fEnd(NULL),
fOwner(owner)
{
fEvent = (eventHeaderStruct*) event;
}
AliRawReaderDate::AliRawReaderDate(const char* fileName, Int_t eventNumber) :
fFile(NULL),
fEvent(NULL),
fSubEvent(NULL),
fEquipment(NULL),
fPosition(NULL),
fEnd(NULL),
fOwner(kTRUE)
{
fFile = fopen(fileName, "rb");
if (!fFile) {
Error("AliRawReaderDate", "could not open file %s", fileName);
fIsValid = kFALSE;
return;
}
if (eventNumber < 0) return;
eventHeaderStruct header;
UInt_t headerSize = sizeof(eventHeaderStruct);
while (fread(&header, 1, headerSize, fFile) == headerSize) {
if (eventNumber == 0) {
UChar_t* buffer = new UChar_t[header.eventSize];
fseek(fFile, -(long)headerSize, SEEK_CUR);
if (fread(buffer, 1, header.eventSize, fFile) != header.eventSize) break;
fEvent = (eventHeaderStruct*) buffer;
break;
}
fseek(fFile, header.eventSize-headerSize, SEEK_CUR);
eventNumber--;
}
}
AliRawReaderDate::~AliRawReaderDate()
{
if (fEvent && fOwner) delete[] fEvent;
if (fFile) {
fclose(fFile);
}
}
UInt_t AliRawReaderDate::GetType() const
{
if (!fEvent) return 0;
return fEvent->eventType;
}
UInt_t AliRawReaderDate::GetRunNumber() const
{
if (!fEvent) return 0;
return fEvent->eventRunNb;
}
const UInt_t* AliRawReaderDate::GetEventId() const
{
if (!fEvent) return NULL;
return fEvent->eventId;
}
const UInt_t* AliRawReaderDate::GetTriggerPattern() const
{
if (!fEvent) return NULL;
return fEvent->eventTriggerPattern;
}
const UInt_t* AliRawReaderDate::GetDetectorPattern() const
{
if (!fEvent) return NULL;
return fEvent->eventDetectorPattern;
}
const UInt_t* AliRawReaderDate::GetAttributes() const
{
if (!fEvent) return NULL;
return fEvent->eventTypeAttribute;
}
const UInt_t* AliRawReaderDate::GetSubEventAttributes() const
{
if (!fSubEvent) return NULL;
return fSubEvent->eventTypeAttribute;
}
UInt_t AliRawReaderDate::GetLDCId() const
{
if (!fSubEvent) return 0;
return fSubEvent->eventLdcId;
}
UInt_t AliRawReaderDate::GetGDCId() const
{
if (!fEvent) return 0;
return fEvent->eventGdcId;
}
UInt_t AliRawReaderDate::GetTimestamp() const
{
if (!fEvent) return 0;
return fEvent->eventTimestamp;
}
Int_t AliRawReaderDate::GetEquipmentSize() const
{
if (!fEquipment) return 0;
if (fSubEvent->eventVersion <= 0x00030001) {
return fEquipment->equipmentSize + sizeof(equipmentHeaderStruct);
} else {
return fEquipment->equipmentSize;
}
}
Int_t AliRawReaderDate::GetEquipmentType() const
{
if (!fEquipment) return -1;
return fEquipment->equipmentType;
}
Int_t AliRawReaderDate::GetEquipmentId() const
{
if (!fEquipment) return -1;
return fEquipment->equipmentId;
}
const UInt_t* AliRawReaderDate::GetEquipmentAttributes() const
{
if (!fEquipment) return NULL;
return fEquipment->equipmentTypeAttribute;
}
Int_t AliRawReaderDate::GetEquipmentElementSize() const
{
if (!fEquipment) return 0;
return fEquipment->equipmentBasicElementSize;
}
Int_t AliRawReaderDate::GetEquipmentHeaderSize() const
{
return sizeof(equipmentHeaderStruct);
}
Bool_t AliRawReaderDate::ReadHeader()
{
fErrorCode = 0;
fHeader = NULL;
if (!fEvent) return kFALSE;
if (fEvent->eventSize <= fEvent->eventHeadSize) return kFALSE;
do {
if (fCount > 0) fPosition += fCount;
if (!fEquipment || (fPosition >= fEnd)) {
fEquipment = NULL;
if (!fSubEvent ||
(fPosition >= ((UChar_t*)fSubEvent) + fSubEvent->eventSize)) {
if (fPosition >= ((UChar_t*)fEvent)+fEvent->eventSize) return kFALSE;
if (!TEST_SYSTEM_ATTRIBUTE(fEvent->eventTypeAttribute,
ATTR_SUPER_EVENT)) {
fSubEvent = fEvent;
} else if (fSubEvent) {
fSubEvent = (eventHeaderStruct*) (((UChar_t*)fSubEvent) +
fSubEvent->eventSize);
} else {
fSubEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) +
fEvent->eventHeadSize);
}
if (fSubEvent->eventMagic != EVENT_MAGIC_NUMBER) {
Error("ReadHeader", "wrong magic number in sub event!\n"
" run: %d event: %d %d LDC: %d GDC: %d\n",
fSubEvent->eventRunNb,
fSubEvent->eventId[0], fSubEvent->eventId[1],
fSubEvent->eventLdcId, fSubEvent->eventGdcId);
fErrorCode = kErrMagic;
return kFALSE;
}
if (fSubEvent->eventSize == fSubEvent->eventHeadSize) {
fPosition = fEnd = ((UChar_t*)fSubEvent) + fSubEvent->eventSize;
fCount = 0;
continue;
}
fEquipment = (equipmentHeaderStruct*)
(((UChar_t*)fSubEvent) + fSubEvent->eventHeadSize);
} else {
fEquipment = (equipmentHeaderStruct*) fEnd;
}
fCount = 0;
fPosition = ((UChar_t*)fEquipment) + sizeof(equipmentHeaderStruct);
if (fSubEvent->eventVersion <= 0x00030001) {
fEnd = fPosition + fEquipment->equipmentSize;
} else {
fEnd = ((UChar_t*)fEquipment) + fEquipment->equipmentSize;
}
}
if (fPosition >= fEnd) continue;
if (fRequireHeader) {
if (fPosition + sizeof(AliRawDataHeader) > fEnd) {
Error("ReadHeader", "could not read data header data!");
Warning("ReadHeader", "skipping %ld bytes\n"
" run: %d event: %d %d LDC: %d GDC: %d\n",
fEnd - fPosition, fSubEvent->eventRunNb,
fSubEvent->eventId[0], fSubEvent->eventId[1],
fSubEvent->eventLdcId, fSubEvent->eventGdcId);
fCount = 0;
fPosition = fEnd;
fErrorCode = kErrNoDataHeader;
continue;
}
fHeader = (AliRawDataHeader*) fPosition;
UChar_t version = 2;
if (fHeader) version=fHeader->GetVersion();
if (version==2) {
if ((fPosition + fHeader->fSize) != fEnd) {
if ((fHeader->fSize != 0xFFFFFFFF) &&
(fEquipment->equipmentId != 4352))
Warning("ReadHeader",
"raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !",
fHeader->fSize, fEnd - fPosition);
fHeader->fSize = fEnd - fPosition;
}
fPosition += sizeof(AliRawDataHeader);
fHeaderV3 = 0;
} else if (version==3) {
fHeaderV3 = (AliRawDataHeaderV3*) fPosition;
if ((fPosition + fHeaderV3->fSize) != fEnd) {
if ((fHeaderV3->fSize != 0xFFFFFFFF) &&
(fEquipment->equipmentId != 4352))
Warning("ReadHeader",
"raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !",
fHeaderV3->fSize, fEnd - fPosition);
fHeaderV3->fSize = fEnd - fPosition;
}
fPosition += sizeof(AliRawDataHeaderV3);
fHeader = 0;
}
}
if (fHeader && (fHeader->fSize != 0xFFFFFFFF)) {
fCount = fHeader->fSize - sizeof(AliRawDataHeader);
if (fPosition + fCount > fEnd) {
Error("ReadHeader", "size in data header exceeds event size!");
Warning("ReadHeader", "skipping %ld bytes\n"
" run: %d event: %d %d LDC: %d GDC: %d\n",
fEnd - fPosition, fSubEvent->eventRunNb,
fSubEvent->eventId[0], fSubEvent->eventId[1],
fSubEvent->eventLdcId, fSubEvent->eventGdcId);
fCount = 0;
fPosition = fEnd;
fErrorCode = kErrSize;
continue;
}
} else if (fHeaderV3 && (fHeaderV3->fSize != 0xFFFFFFFF)) {
fCount = fHeaderV3->fSize - sizeof(AliRawDataHeaderV3);
if (fPosition + fCount > fEnd) {
Error("ReadHeader", "size in data header exceeds event size!");
Warning("ReadHeader", "skipping %ld bytes\n"
" run: %d event: %d %d LDC: %d GDC: %d\n",
fEnd - fPosition, fSubEvent->eventRunNb,
fSubEvent->eventId[0], fSubEvent->eventId[1],
fSubEvent->eventLdcId, fSubEvent->eventGdcId);
fCount = 0;
fPosition = fEnd;
fErrorCode = kErrSize;
continue;
}
} else {
fCount = fEnd - fPosition;
}
} while (!fEquipment || !IsSelected());
return kTRUE;
}
Bool_t AliRawReaderDate::ReadNextData(UChar_t*& data)
{
fErrorCode = 0;
while (fCount == 0) {
if (!ReadHeader()) return kFALSE;
}
data = fPosition;
fPosition += fCount;
fCount = 0;
return kTRUE;
}
Bool_t AliRawReaderDate::ReadNext(UChar_t* data, Int_t size)
{
fErrorCode = 0;
if (fPosition + size > fEnd) {
Error("ReadNext", "could not read data!");
fErrorCode = kErrOutOfBounds;
return kFALSE;
}
memcpy(data, fPosition, size);
fPosition += size;
fCount -= size;
return kTRUE;
}
Bool_t AliRawReaderDate::Reset()
{
fSubEvent = NULL;
fEquipment = NULL;
fCount = 0;
fPosition = fEnd = NULL;
fHeader=NULL;
fHeaderV3=NULL;
return kTRUE;
}
Bool_t AliRawReaderDate::NextEvent()
{
if (!fFile) {
if (fEventNumber < 0 && fEvent) {
fEventNumber++;
return kTRUE;
}
else
return kFALSE;
}
Reset();
eventHeaderStruct header;
UInt_t headerSize = sizeof(eventHeaderStruct);
if (fEvent) delete[] fEvent;
fEvent = &header;
while (fread(&header, 1, headerSize, fFile) == headerSize) {
if (!IsEventSelected()) {
fseek(fFile, header.eventSize-headerSize, SEEK_CUR);
continue;
}
UChar_t* buffer = new UChar_t[header.eventSize];
fseek(fFile, -(long)headerSize, SEEK_CUR);
if (fread(buffer, 1, header.eventSize, fFile) != header.eventSize) {
Error("NextEvent", "could not read event from file");
delete[] buffer;
break;
}
fEvent = (eventHeaderStruct*) buffer;
fEventNumber++;
return kTRUE;
};
fEvent = NULL;
return kFALSE;
}
Bool_t AliRawReaderDate::RewindEvents()
{
if (fFile)
fseek(fFile, 0, SEEK_SET);
fEventNumber = -1;
return Reset();
}
Int_t AliRawReaderDate::CheckData() const
{
if (!fEvent) return 0;
if (fEvent->eventSize <= fEvent->eventHeadSize) return 0;
eventHeaderStruct* subEvent = NULL;
UChar_t* position = 0;
UChar_t* end = 0;
Int_t result = 0;
while (kTRUE) {
if (!subEvent || (position >= end)) {
if (position >= ((UChar_t*)fEvent)+fEvent->eventSize) return result;
if (!TEST_SYSTEM_ATTRIBUTE(fEvent->eventTypeAttribute,
ATTR_SUPER_EVENT)) {
subEvent = fEvent;
} else if (subEvent) {
subEvent = (eventHeaderStruct*) (((UChar_t*)subEvent) +
subEvent->eventSize);
} else {
subEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) +
fEvent->eventHeadSize);
}
if (subEvent->eventMagic != EVENT_MAGIC_NUMBER) {
result |= kErrMagic;
return result;
}
position = ((UChar_t*)subEvent) + subEvent->eventHeadSize +
sizeof(equipmentHeaderStruct);
end = ((UChar_t*)subEvent) + subEvent->eventSize;
}
if (position >= end) continue;
if (fRequireHeader) {
if (position + sizeof(AliRawDataHeader) > end) {
result |= kErrNoDataHeader;
position = end;
continue;
}
AliRawDataHeader* header = (AliRawDataHeader*) position;
UChar_t version = header->GetVersion();
if (version==2) {
if ((position + header->fSize) != end) {
if (header->fSize != 0xFFFFFFFF)
Warning("CheckData",
"raw data size found in the header V2 is wrong (%d != %ld)! Using the equipment size instead !",
header->fSize, end - position);
header->fSize = end - position;
result |= kErrSize;
}
}
else if (version==3) {
AliRawDataHeaderV3 * headerV3 = (AliRawDataHeaderV3*) position;
if ((position + headerV3->fSize) != end) {
if (headerV3->fSize != 0xFFFFFFFF)
Warning("CheckData",
"raw data size found in the header V3 is wrong (%d != %ld)! Using the equipment size instead !",
headerV3->fSize, end - position);
headerV3->fSize = end - position;
result |= kErrSize;
}
}
}
position = end;
};
return 0;
}
AliRawReader* AliRawReaderDate::CloneSingleEvent() const
{
if (fEvent) {
UInt_t evSize = fEvent->eventSize;
if (evSize) {
UChar_t *newEvent = new UChar_t[evSize];
memcpy(newEvent,fEvent,evSize);
return new AliRawReaderDate((void *)newEvent,kTRUE);
}
}
return NULL;
}