X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=RAW%2FAliRawReaderRoot.cxx;h=1fde2b8018387b002b2f991c708449121463234b;hb=9c6bd7496184aff662636ed7f003838c9284136c;hp=bcd41cc80d1f5086ad7efa058e498abf80970446;hpb=04fa961a68e4ca38be22e31a659eabd80ad1ffcf;p=u%2Fmrichter%2FAliRoot.git diff --git a/RAW/AliRawReaderRoot.cxx b/RAW/AliRawReaderRoot.cxx index bcd41cc80d1..1fde2b80183 100644 --- a/RAW/AliRawReaderRoot.cxx +++ b/RAW/AliRawReaderRoot.cxx @@ -13,70 +13,195 @@ * provided "as is" without express or implied warranty. * **************************************************************************/ +/* $Id$ */ + /////////////////////////////////////////////////////////////////////////////// -// -// This is a class for reading a raw data from a root file and providing -// information about digits -// +/// +/// This is a class for reading raw data from a root file. +/// +/// The root file is expected to contain a tree of name "RAW" with +/// a branch of name "rawevent" which contains objects of type +/// AliRawVEvent. +/// +/// The file name and the event number are arguments of the constructor +/// of AliRawReaderRoot. +/// /////////////////////////////////////////////////////////////////////////////// +#include +#include #include "AliRawReaderRoot.h" +#include "AliRawVEvent.h" +#include "AliRawEventHeaderBase.h" +#include "AliRawVEquipment.h" +#include "AliRawEquipmentHeader.h" +#include "AliRawData.h" ClassImp(AliRawReaderRoot) +AliRawReaderRoot::AliRawReaderRoot() : + fFile(NULL), + fBranch(NULL), + fEventIndex(-1), + fEvent(NULL), + fEventHeader(NULL), + fSubEventIndex(0), + fSubEvent(NULL), + fEquipmentIndex(0), + fEquipment(NULL), + fRawData(NULL), + fPosition(NULL), + fEnd(NULL) +{ +// default constructor + +} -AliRawReaderRoot::AliRawReaderRoot(const char* fileName, Int_t eventNumber) +AliRawReaderRoot::AliRawReaderRoot(const char* fileName, Int_t eventNumber) : + fFile(NULL), + fBranch(NULL), + fEventIndex(eventNumber), + fEvent(NULL), + fEventHeader(NULL), + fSubEventIndex(0), + fSubEvent(NULL), + fEquipmentIndex(0), + fEquipment(NULL), + fRawData(NULL), + fPosition(NULL), + fEnd(NULL) { // create an object to read digits from the given input file for the // event with the given number + TDirectory* dir = gDirectory; fFile = TFile::Open(fileName); + dir->cd(); if (!fFile || !fFile->IsOpen()) { Error("AliRawReaderRoot", "could not open file %s", fileName); + fIsValid = kFALSE; return; } TTree* tree = (TTree*) fFile->Get("RAW"); if (!tree) { Error("AliRawReaderRoot", "no raw data tree found"); + fIsValid = kFALSE; return; } - TBranch* branch = tree->GetBranch("rawevent"); - if (!branch) { + fBranch = tree->GetBranch("rawevent"); + if (!fBranch) { Error("AliRawReaderRoot", "no raw data branch found"); + fIsValid = kFALSE; return; } - fEvent = new AliRawEvent; - branch->SetAddress(&fEvent); - if (branch->GetEntry(eventNumber) <= 0) { - Error("AliRawReaderRoot", "no event with number %d found", eventNumber); - return; + fBranch->SetAddress(&fEvent); + if (fEventIndex >= 0) { + if (fBranch->GetEntry(fEventIndex) <= 0) { + Error("AliRawReaderRoot", "no event with number %d found", fEventIndex); + fIsValid = kFALSE; + return; + } + fEventHeader = fEvent->GetHeader(); } - - fSubEventIndex = 0; - fSubEvent = NULL; - fRawData = NULL; - fMiniHeader = NULL; - - fCount = 0; - fPosition = fEnd = NULL; } -AliRawReaderRoot::AliRawReaderRoot(AliRawEvent* event) +AliRawReaderRoot::AliRawReaderRoot(AliRawVEvent* event) : + fFile(NULL), + fBranch(NULL), + fEventIndex(-1), + fEvent(event), + fEventHeader(event->GetHeader()), + fSubEventIndex(0), + fSubEvent(NULL), + fEquipmentIndex(0), + fEquipment(NULL), + fRawData(NULL), + fPosition(NULL), + fEnd(NULL) { // create an object to read digits from the given raw event + if (!fEvent) fIsValid = kFALSE; +} - fFile = NULL; - fEvent = event; - - fSubEventIndex = 0; - fSubEvent = NULL; - fRawData = NULL; - fMiniHeader = NULL; +AliRawReaderRoot::AliRawReaderRoot(const AliRawReaderRoot& rawReader) : + AliRawReader(rawReader), + fFile(NULL), + fBranch(NULL), + fEventIndex(rawReader.fEventIndex), + fEvent(NULL), + fEventHeader(NULL), + fSubEventIndex(rawReader.fSubEventIndex), + fSubEvent(NULL), + fEquipmentIndex(rawReader.fEquipmentIndex), + fEquipment(NULL), + fRawData(NULL), + fPosition(NULL), + fEnd(NULL) +{ +// copy constructor + + if (rawReader.fFile) { + TDirectory* dir = gDirectory; + fFile = TFile::Open(rawReader.fFile->GetName()); + dir->cd(); + if (!fFile || !fFile->IsOpen()) { + Error("AliRawReaderRoot", "could not open file %s", + rawReader.fFile->GetName()); + fIsValid = kFALSE; + return; + } + TTree* tree = (TTree*) fFile->Get("RAW"); + if (!tree) { + Error("AliRawReaderRoot", "no raw data tree found"); + fIsValid = kFALSE; + return; + } + fBranch = tree->GetBranch("rawevent"); + if (!fBranch) { + Error("AliRawReaderRoot", "no raw data branch found"); + fIsValid = kFALSE; + return; + } - fCount = 0; - fPosition = fEnd = NULL; + fBranch->SetAddress(&fEvent); + if (fEventIndex >= 0) { + if (fBranch->GetEntry(fEventIndex) <= 0) { + Error("AliRawReaderRoot", "no event with number %d found", + fEventIndex); + fIsValid = kFALSE; + return; + } + fEventHeader = fEvent->GetHeader(); + } + } else { + fEvent = rawReader.fEvent; + fEventHeader = rawReader.fEventHeader; + } + + if (fSubEventIndex > 0) { + fSubEvent = fEvent->GetSubEvent(fSubEventIndex-1); + fEquipment = fSubEvent->GetEquipment(fEquipmentIndex); + fRawData = fEquipment->GetRawData(); + fCount = 0; + fHeader = (AliRawDataHeader*) ((UChar_t*) fRawData->GetBuffer() + + ((UChar_t*) rawReader.fHeader - + (UChar_t*) rawReader.fRawData->GetBuffer())); + fPosition = (UChar_t*) fRawData->GetBuffer() + + (rawReader.fPosition - (UChar_t*) rawReader.fRawData->GetBuffer()); + fEnd = ((UChar_t*) fRawData->GetBuffer()) + fRawData->GetSize(); + } +} + +AliRawReaderRoot& AliRawReaderRoot::operator = (const AliRawReaderRoot& + rawReader) +{ +// assignment operator + + this->~AliRawReaderRoot(); + new(this) AliRawReaderRoot(rawReader); + return *this; } AliRawReaderRoot::~AliRawReaderRoot() @@ -90,94 +215,263 @@ AliRawReaderRoot::~AliRawReaderRoot() } } +const AliRawEventHeaderBase* AliRawReaderRoot::GetEventHeader() const +{ + // Get the even header + // Return NULL in case of failure + return fEventHeader; +} -UInt_t AliRawReaderRoot::GetType() +UInt_t AliRawReaderRoot::GetType() const { // get the type from the event header - if (!fEvent) return 0; - return fEvent->GetHeader()->GetType(); + if (!fEventHeader) return 0; + return fEventHeader->Get("Type"); } -UInt_t AliRawReaderRoot::GetRunNumber() +UInt_t AliRawReaderRoot::GetRunNumber() const { // get the run number from the event header - if (!fEvent) return 0; - return fEvent->GetHeader()->GetRunNumber(); + if (!fEventHeader) return 0; + return fEventHeader->Get("RunNb"); } -const UInt_t* AliRawReaderRoot::GetEventId() +const UInt_t* AliRawReaderRoot::GetEventId() const { // get the event id from the event header - if (!fEvent) return NULL; - return fEvent->GetHeader()->GetId(); + if (!fEventHeader) return NULL; + return fEventHeader->GetP("Id"); } -const UInt_t* AliRawReaderRoot::GetTriggerPattern() +const UInt_t* AliRawReaderRoot::GetTriggerPattern() const { // get the trigger pattern from the event header - if (!fEvent) return NULL; - return fEvent->GetHeader()->GetTriggerPattern(); + if (!fEventHeader) return NULL; + return fEventHeader->GetP("TriggerPattern"); } -const UInt_t* AliRawReaderRoot::GetDetectorPattern() +const UInt_t* AliRawReaderRoot::GetDetectorPattern() const { // get the detector pattern from the event header - if (!fEvent) return NULL; - return fEvent->GetHeader()->GetDetectorPattern(); + if (!fEventHeader) return NULL; + return fEventHeader->GetP("DetectorPattern"); } -const UInt_t* AliRawReaderRoot::GetAttributes() +const UInt_t* AliRawReaderRoot::GetAttributes() const { // get the type attributes from the event header - if (!fEvent) return NULL; - return fEvent->GetHeader()->GetTypeAttribute(); + if (!fEventHeader) return NULL; + return fEventHeader->GetP("TypeAttribute"); +} + +const UInt_t* AliRawReaderRoot::GetSubEventAttributes() const +{ +// get the type attributes from the sub event header + + if (!fSubEvent) return NULL; + return fSubEvent->GetHeader()->GetP("TypeAttribute"); +} + +UInt_t AliRawReaderRoot::GetLDCId() const +{ +// get the LDC Id from the event header + + if (!fEvent || !fSubEvent) return 0; + return fSubEvent->GetHeader()->Get("LdcId"); } -UInt_t AliRawReaderRoot::GetGDCId() +UInt_t AliRawReaderRoot::GetGDCId() const { // get the GDC Id from the event header - if (!fEvent) return 0; - return fEvent->GetHeader()->GetGDCId(); + if (!fEventHeader) return 0; + return fEventHeader->Get("GdcId"); } +UInt_t AliRawReaderRoot::GetTimestamp() const +{ + if (!fEventHeader) return 0; + return fEventHeader->Get("Timestamp"); +} -Bool_t AliRawReaderRoot::ReadMiniHeader() +Int_t AliRawReaderRoot::GetEquipmentSize() const { -// read a mini header at the current position -// returns kFALSE if the mini header could not be read +// get the size of the equipment + + if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return 0; + return fEquipment->GetEquipmentHeader()->GetEquipmentSize(); +} +Int_t AliRawReaderRoot::GetEquipmentType() const +{ +// get the type from the equipment header + + if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return -1; + return fEquipment->GetEquipmentHeader()->GetEquipmentType(); +} + +Int_t AliRawReaderRoot::GetEquipmentId() const +{ +// get the ID from the equipment header + + if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return -1; + return fEquipment->GetEquipmentHeader()->GetId(); +} + +const UInt_t* AliRawReaderRoot::GetEquipmentAttributes() const +{ +// get the attributes from the equipment header + + if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return NULL; + return fEquipment->GetEquipmentHeader()->GetTypeAttribute(); +} + +Int_t AliRawReaderRoot::GetEquipmentElementSize() const +{ +// get the basic element size from the equipment header + + if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return 0; + return fEquipment->GetEquipmentHeader()->GetBasicSizeType(); +} + +Int_t AliRawReaderRoot::GetEquipmentHeaderSize() const +{ +// get the size of the equipment header (28 bytes by default) + + if (!fEvent || !fEquipment || !fEquipment->GetEquipmentHeader()) return 0; + return fEquipment->GetEquipmentHeader()->HeaderSize(); +} + +// _________________________________________________________________________ +void AliRawReaderRoot::SwapData(const void* inbuf, const void* outbuf, UInt_t size) { + // The method swaps the contents of the + // raw-data event header + UInt_t intCount = (size+3)/sizeof(UInt_t); + + UInt_t* buf = (UInt_t*) inbuf; // temporary integers buffer + for (UInt_t i=0; i 0) fPosition += fCount; // skip payload if event was not selected - if (!fSubEvent || (fPosition >= fEnd)) { // new sub event - if (fSubEventIndex >= fEvent->GetNSubEvents()) return kFALSE; - fSubEvent = fEvent->GetSubEvent(fSubEventIndex++); - fRawData = fSubEvent->GetRawData(); + // skip payload (if event was not selected) + if (fCount > 0) fPosition += fCount; + + // get the first or the next equipment if at the end of an equipment + if (!fEquipment || (fPosition >= fEnd)) { + + // get the first or the next sub event if at the end of a sub event + if (!fSubEvent || (fEquipmentIndex >= fSubEvent->GetNEquipments())) { + + // check for end of event data + if (fSubEventIndex >= fEvent->GetNSubEvents()) return kFALSE; + fSubEvent = fEvent->GetSubEvent(fSubEventIndex++); + + // check the magic word of the sub event + if (!fSubEvent->GetHeader()->IsValid()) { + Error("ReadHeader", "wrong magic number in sub event!"); + fSubEvent->GetHeader()->Dump(); + fErrorCode = kErrMagic; + return kFALSE; + } + + fEquipmentIndex = 0; + fEquipment = NULL; + fRawData = NULL; + } + + // get the next equipment and raw data fCount = 0; + if (fEquipmentIndex >= fSubEvent->GetNEquipments()) { + fEquipment = NULL; + continue; + } + fEquipment = fSubEvent->GetEquipment(fEquipmentIndex++); + if (!fEquipment) continue; + if (!IsSelected()) { + fPosition = fEnd; + continue; + } + fRawData = fEquipment->GetRawData(); + if (!fRawData) { + fPosition = fEnd; + continue; + } fPosition = (UChar_t*) fRawData->GetBuffer(); fEnd = ((UChar_t*) fRawData->GetBuffer()) + fRawData->GetSize(); } - if (fPosition >= fEnd) continue; // no data left in the payload - if (fPosition + sizeof(AliMiniHeader) > fEnd) { - Error("ReadMiniHeader", "could not read data!"); - return kFALSE; + + // continue with the next equipment if no data left in the payload + if (fPosition >= fEnd) continue; + + if (fRequireHeader) { + // check that there are enough bytes left for the data header + if (fPosition + sizeof(AliRawDataHeader) > fEnd) { + Error("ReadHeader", "could not read data header!"); + Warning("ReadHeader", "skipping %ld bytes", fEnd - fPosition); + fEquipment->GetEquipmentHeader()->Dump(); + fCount = 0; + fPosition = fEnd; + fErrorCode = kErrNoDataHeader; + continue; + } + + // "read" the data header + fHeader = (AliRawDataHeader*) fPosition; +#ifndef R__BYTESWAP + SwapData((void*) fHeader, (void*) fHeaderSwapped, sizeof(AliRawDataHeader)); + fHeader=fHeaderSwapped; +#endif + if ((fPosition + fHeader->fSize) != fEnd) { + if (fHeader->fSize != 0xFFFFFFFF) + Warning("ReadHeader", + "Equipment %d : raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !", + fEquipment->GetEquipmentHeader()->GetId(),fHeader->fSize, fEnd - fPosition); + fHeader->fSize = fEnd - fPosition; + } + fPosition += sizeof(AliRawDataHeader); } - fMiniHeader = (AliMiniHeader*) fPosition; - fPosition += sizeof(AliMiniHeader); - CheckMiniHeader(); - fCount = fMiniHeader->fSize; - if (fPosition + fCount > fEnd) { // check data size in mini header and sub event - Error("ReadMiniHeader", "size in mini header exceeds event size!"); - fMiniHeader->fSize = fCount = fEnd - fPosition; + + if (fHeader && (fHeader->fSize != 0xFFFFFFFF)) { + fCount = fHeader->fSize - sizeof(AliRawDataHeader); + + // check consistency of data size in the header and in the sub event + if (fPosition + fCount > fEnd) { + Error("ReadHeader", "size in data header exceeds event size!"); + Warning("ReadHeader", "skipping %ld bytes", fEnd - fPosition); + fEquipment->GetEquipmentHeader()->Dump(); + fCount = 0; + fPosition = fEnd; + fErrorCode = kErrSize; + continue; + } + + } else { + fCount = fEnd - fPosition; } + } while (!IsSelected()); + return kTRUE; } @@ -186,8 +480,9 @@ Bool_t AliRawReaderRoot::ReadNextData(UChar_t*& data) // reads the next payload at the current position // returns kFALSE if the data could not be read + fErrorCode = 0; while (fCount == 0) { - if (!ReadMiniHeader()) return kFALSE; + if (!ReadHeader()) return kFALSE; } data = fPosition; fPosition += fCount; @@ -200,11 +495,14 @@ Bool_t AliRawReaderRoot::ReadNext(UChar_t* data, Int_t size) // reads the next block of data at the current position // returns kFALSE if the data could not be read + 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; @@ -217,11 +515,177 @@ Bool_t AliRawReaderRoot::Reset() fSubEventIndex = 0; fSubEvent = NULL; + fEquipmentIndex = 0; + fEquipment = NULL; fRawData = NULL; - fMiniHeader = NULL; + fHeader = NULL; fCount = 0; fPosition = fEnd = NULL; return kTRUE; } + +Bool_t AliRawReaderRoot::NextEvent() +{ +// go to the next event in the root file + + if (!fBranch) return kFALSE; + + do { + delete fEvent; + fEvent = NULL; + fEventHeader = NULL; + fBranch->SetAddress(&fEvent); + if (fBranch->GetEntry(fEventIndex+1) <= 0) + return kFALSE; + fEventHeader = fEvent->GetHeader(); + fEventIndex++; + } while (!IsEventSelected()); + fEventNumber++; + return Reset(); +} + +Bool_t AliRawReaderRoot::RewindEvents() +{ +// go back to the beginning of the root file + + if (!fBranch) return kFALSE; + + fEventIndex = -1; + delete fEvent; + fEvent = NULL; + fEventHeader = NULL; + fBranch->SetAddress(&fEvent); + fEventNumber = -1; + return Reset(); +} + +Bool_t AliRawReaderRoot::GotoEvent(Int_t event) +{ + // go to a particular event + // Uses the absolute event index inside the + // raw-data file + + if (!fBranch) return kFALSE; + + delete fEvent; + fEvent = NULL; + fEventHeader = NULL; + fBranch->SetAddress(&fEvent); + if (fBranch->GetEntry(event) <= 0) + return kFALSE; + fEventHeader = fEvent->GetHeader(); + fEventIndex = event; + fEventNumber++; + return Reset(); +} + +Int_t AliRawReaderRoot::GetNumberOfEvents() const +{ + // Get the total number of events in + // the raw-data tree + + if (!fBranch) return -1; + + return fBranch->GetEntries(); +} + +Int_t AliRawReaderRoot::CheckData() const +{ +// check the consistency of the data + + if (!fEvent) return 0; + + AliRawVEvent* subEvent = NULL; + Int_t subEventIndex = 0; + AliRawVEquipment* equipment = NULL; + Int_t equipmentIndex = 0; + UChar_t* position = 0; + UChar_t* end = 0; + Int_t result = 0; + + while (kTRUE) { + // get the first or the next sub event if at the end of an equipment + if (!subEvent || (equipmentIndex >= subEvent->GetNEquipments())) { + + // check for end of event data + if (subEventIndex >= fEvent->GetNSubEvents()) return result; + subEvent = fEvent->GetSubEvent(subEventIndex++); + + // check the magic word of the sub event + if (!fSubEvent->GetHeader()->IsValid()) { + result |= kErrMagic; + return result; + } + + equipmentIndex = 0; + } + + // get the next equipment and raw data + if (equipmentIndex >= subEvent->GetNEquipments()) { + equipment = NULL; + continue; + } + equipment = subEvent->GetEquipment(equipmentIndex++); + if (!equipment) continue; + AliRawData* rawData = equipment->GetRawData(); + if (!rawData) continue; + position = (UChar_t*) rawData->GetBuffer(); + end = ((UChar_t*) rawData->GetBuffer()) + rawData->GetSize(); + + // continue with the next sub event if no data left in the payload + if (position >= end) continue; + + if (fRequireHeader) { + // check that there are enough bytes left for the data header + if (position + sizeof(AliRawDataHeader) > end) { + result |= kErrNoDataHeader; + continue; + } + + // check consistency of data size in the header and in the equipment + AliRawDataHeader* header = (AliRawDataHeader*) position; + if ((position + header->fSize) != end) { + if (header->fSize != 0xFFFFFFFF) + Warning("ReadHeader", + "Equipment %d : raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !", + equipment->GetEquipmentHeader()->GetId(),header->fSize, end - position); + header->fSize = end - position; + result |= kErrSize; + } + } + position = end; + }; + + return result; +} + +AliRawReader* AliRawReaderRoot::CloneSingleEvent() const +{ + // Clones the current event and + // creates raw-reader for the cloned event + // Can be used in order to make asynchronious + // access to the current raw data within + // several threads (online event display/reco) + + if (fEvent) { + // Root formatted raw data + AliRawVEvent *gdcRootEvent = (AliRawVEvent*)fEvent->Clone(); + for (Int_t ldcCounter=0; ldcCounter < gdcRootEvent->GetNSubEvents(); ldcCounter++) { + AliRawVEvent *ldcRootEvent = gdcRootEvent->GetSubEvent(ldcCounter); + AliRawVEvent *subEvent = fEvent->GetSubEvent(ldcCounter); + for (Int_t eqCounter=0; eqCounter < ldcRootEvent->GetNEquipments(); eqCounter++) { + AliRawVEquipment *equipment=ldcRootEvent->GetEquipment(eqCounter); + AliRawVEquipment *eq = subEvent->GetEquipment(eqCounter); + equipment->CloneRawData(eq->GetRawData()); + } + } + // Reset original event and newly + // produced one + gdcRootEvent->GetSubEvent(-1); + fEvent->GetSubEvent(-1); + return new AliRawReaderRoot(gdcRootEvent); + } + return NULL; +}