// // Implement a class to read an event from a file. // #include #include #include #include #include "ICOMETInput.hxx" #include "ICOMETEvent.hxx" #include "IOADatabase.hxx" #include "ICOMETLog.hxx" COMET::ICOMETInput::ICOMETInput(const char* name, Option_t* option, Int_t compress) : fFile(NULL), fSequence(0), fEventTree(NULL), fEventPointer(0), fEventsRead(0), fAttached(false) { fFile = new TFile(name, option, "ROOT Input File", compress); if (!fFile || !fFile->IsOpen()) { throw COMET::ENoCOMETInputFile(); } static int msg_showed=0; if(msg_showed<3){ COMETWarn("ROOT may produce warning messages about missing ShowMembers" << " methods which may be ignored"); ++msg_showed; } IsAttached(); COMET::IOADatabase::Get().SetCurrentInputFile(fFile); COMETVerbose("Input file " << fFile->GetName() << " is open"); } COMET::ICOMETInput::ICOMETInput(TFile* file) : fFile(file), fSequence(0), fEventTree(NULL), fEventPointer(0), fEventsRead(0), fAttached(false) { if (!fFile || !fFile->IsOpen()) { throw COMET::ENoCOMETInputFile(); } static int msg_showed=0; if(msg_showed<3){ COMETWarn("ROOT may produce warning messages about missing ShowMembers" << " methods which may be ignored"); ++msg_showed; } IsAttached(); COMET::IOADatabase::Get().SetCurrentInputFile(fFile); COMETVerbose("Input file " << fFile->GetName() << " is open"); } COMET::ICOMETInput::~ICOMETInput(void) { Close(); if (fFile) delete fFile; } #ifdef PRIVATE_COPY COMET::ICOMETInput::ICOMETInput(const COMET::ICOMETInput& aFile) { // Copy constructor not implemented MayNotUse("Copy Constructor"); return; } #endif const char* COMET::ICOMETInput::GetInputName() const { if (fFile) return fFile->GetName(); return NULL; } bool COMET::ICOMETInput::IsAttached(void) { if (!IsOpen()) return false; // Make sure the **** global file pointer is pointing to this file. if (gFile != fFile) { if (gFile) { COMETDebug("Changing current file from " << gFile->GetName() << " to " << fFile->GetName() << " to read."); } fFile->cd(); } // Make sure that we have the event tree. if (!fEventTree) { fEventTree = dynamic_cast(fFile->Get("COMETEvents")); if (!fEventTree) throw ENoEvents(); } return true; } Int_t COMET::ICOMETInput::GetEventsInFile(void) { // Returns number of events in this file that can be read. if (!IsAttached()) return 0; return static_cast(fEventTree->GetEntries()); } Int_t COMET::ICOMETInput::GetEventsRead(void) { // Returns number of events read from this file return fEventsRead; } bool COMET::ICOMETInput::IsOpen(void) { return fFile->IsOpen(); } bool COMET::ICOMETInput::EndOfFile(void) { // Flag that we are past an end of the file. This is true if the next // event to be read is before the first event, or after the last event. if (fSequence<0) { fSequence = -1; return true; } if (GetEventsInFile()<=fSequence) { fSequence = GetEventsInFile(); return true; } return false; } COMET::ICOMETEvent* COMET::ICOMETInput::NextEvent(int skip) { fSequence += skip; return ReadEvent(++fSequence); } COMET::ICOMETEvent* COMET::ICOMETInput::PreviousEvent(int skip) { fSequence -= skip; return ReadEvent(--fSequence); } COMET::ICOMETEvent* COMET::ICOMETInput::ReadEvent(Int_t n) { // Read the n'th event (starting from 0) in the file fSequence = n; if (fSequence<0) { fSequence = -1; return NULL; } if (!IsAttached()) return NULL; // Set up for a new event structure to be allocated. // TODO EG this may cause memory problems if this event is not looked after fEventPointer = new COMET::ICOMETEvent; fEventTree->SetBranchAddress("COMETEvent",&fEventPointer); // Read the new event. int nBytes = fEventTree->GetEntry(fSequence); if (nBytes > 0) { fEventsRead++; fEventPointer->Register(); } else { fSequence = GetEventsInFile(); delete fEventPointer; fEventPointer = NULL; } COMET::IOADatabase::Get().SetCurrentInputFile(fFile); return fEventPointer; } void COMET::ICOMETInput::Close(Option_t* opt) { TFile* current = COMET::IOADatabase::Get().CurrentInputFile(); if (fFile == current) COMET::IOADatabase::Get().SetCurrentInputFile(NULL); fFile->Close(opt); } ClassImp(COMET::ICOMETInput)