#include "BrEventIO.h"
#include "BrEvent.h"
#include "TDatime.h"
#include <iostream.h>
ClassImp(BrEventIO)
///////////////////////////////////////////////////////////////////////
// //
// BrEventIO //
// //
// Class to write/read GBRAHMS Event data in ROOT format //
// //
// the class is derived from the BrIOModule class //
// //
// Description: //
// This class is meant to simplify writing BRAHMS output in ROOT //
// format. The user simply creates the object which has defaults //
// that work. Several options are also provided in case they are //
// needed. //
// //
// Usage: //
// The standard usage is to create the object, open the //
// file and then use the Event(BrEvent* event) method for event //
// by event writing of event objects. The file can be opened //
// either in READ mode for readonly operations or in RECREATE //
// mode for write operations. The TFile APPEND option is not //
// currently supported. The default file mode is a ROOT tree. //
// The mode can be manually selected using the SetFileMode(option)//
// method. //
// //
// Example: //
// BrEventIO *io = new BrEventIO("Digitized Output"); //
// io->Open("digitized_output.root","RECREATE"); //
// . //
// . //
// . //
// Event Loop //
// . //
// . //
// Digitize data and create BrEvent *event //
// io->Event(digitized_event) //
// . //
// . //
// End Event Loop //
// io->Close(); //
///////////////////////////////////////////////////////////////////////
BrEventIO::BrEventIO()
{
// Default constructor
fROOTFile = 0;
fTree = 0;
for(Int_t ibranch=0;ibranch<MaxNumEventBranches;ibranch++) fBranch[ibranch] = 0;
}
BrEventIO::BrEventIO(Char_t *Name) :
BrIOModule(Name, Name)
{
//
// Constructor.
// name becomes Name and Title for the Module.
// No data file is opened this has to be done in
// the Open() method.
//
// Option can by "READ" "RECREATE"
//
fROOTFile = 0; //Don't create the object until file is to be opened.
fTree = 0; //Don't create tree yet; will be created in open statement
for(Int_t ibranch=0;ibranch<MaxNumEventBranches;ibranch++) fBranch[ibranch] = 0;
//Set default file mode.
fFileMode = ROOT_FILE_TREE;
}
BrEventIO::~BrEventIO(){
//
// Destructor for BrEventIO. Close the file if open. Delete the TFile object
//
if(fTree)
delete fTree;
for(Int_t ibranch=0;ibranch<MaxNumEventBranches;ibranch++) {
if(fBranch[ibranch] == 0) delete fBranch[ibranch];
}
if(fROOTFile) {
fROOTFile->Close();
delete fROOTFile;
fROOTFile = 0;
}
}
Bool_t BrEventIO::Open(Char_t *fname,Option_t *option)
{
// Open the file with fname. Returns kFALSE
// if the file can't be opened.
// Otherwise the fFileName data member is set to the
// corresponding filepointer.
//
// Options: READ for readonly mode or RECREATE for write mode.
//
// RECREATE mode
// if option is RECREATE, a new file is created. This object is written out
// to indicate the file mode (Tree or Serial). If file mode is to be different
// than the default (Tree), the SetFileMode(mode) needs to be used before the Open
// method.
//
// READ mode
// if option is READ, existing file is opened. This object is read in to get
// information on file mode.
//First check to see if fROOTFile already exists, if so see if open
if(fROOTFile) {
if(fROOTFile->IsOpen()) {
TObject::Error("Open","File %s is already opened, please close before trying to open", fname);
return kFALSE;
}
delete fROOTFile;
fROOTFile = 0;
}
strcpy(fFileName,fname);
fFileOption= option; //save option file was opened with
if(!fFileOption.CompareTo("RECREATE",TString::kIgnoreCase)) {
// Opening new file for writing, need to set the mode
fWriteFile = kTRUE;
fROOTFile = new TFile(fFileName,"RECREATE",fFileName,1); //extra options needed???
printf("Writing fFileMode = %dn",fFileMode);
fROOTFile->cd();
TDatime td;
strcpy(fDateTimeCreated,td.AsString());
this->Write("BRAHMS ROOT I/O File"); //essentially to write out fFileMode
}
else if(!fFileOption.CompareTo("READ",TString::kIgnoreCase)) {
fWriteFile = kFALSE;
fROOTFile = new TFile(fFileName,"READ"); //extra options needed???
fROOTFile->cd();
this->Read("BRAHMS ROOT I/O File"); //essentially to read in fFileMode
printf("File created at %s with fFileMode = %d is openedn",fDateTimeCreated,fFileMode);
}
else {
fWriteFile = kFALSE; //don't allow write access if nothing selected
fROOTFile = new TFile(fFileName,"READ"); //extra options needed???
fROOTFile->cd();
this->Read("BRAHMS ROOT I/O File"); //essentially to read in fFileMode
}
if(fROOTFile) {
if(!fROOTFile->IsOpen()) {
delete fROOTFile;
fROOTFile = 0;
return kFALSE;
}
}
Bool_t ret_status = kTRUE;
if( fFileMode == ROOT_FILE_SERIAL ) {
ret_status = InitializeRootSerialFile();
fEventNumber = 0;
}
else if( fFileMode == ROOT_FILE_TREE ) {
ret_status = InitializeRootTreeFile();
} //if(ROOT_FILE_TREE)
fStatus = 1;
fEof = kFALSE;
fError = kFALSE;
return ret_status;
}
Bool_t BrEventIO::InitializeRootSerialFile() {
//Routine to Initialize ROOT serial file
//This routine does nothing if in write mode.
//If in read mode, a list of Keys is found from the event file and stored
//in fListOfKeys. The file header key is removed from the list of keys
if(!fWriteFile) { //Need this only for reading file
//Set up the keys
fROOTFile->cd();
fListOfKeys = gDirectory->GetListOfKeys();
TObject *iofile = fListOfKeys->FindObject("BRAHMS ROOT I/O File");
if(iofile) fListOfKeys->Remove(iofile); //remove so we don't use in event loop
else {
cout<<"This file does not have an index object"<<endl;
}
fNextKey = new TIter(fListOfKeys);
fNumBytesRead = 0;
fEventNumber = 0;
}
return kTRUE;
}
Bool_t BrEventIO::InitializeRootTreeFile() {
//Routine to initialize ROOT tree file (default writing mode)
//if file opened in write mode:
//Create the tree
//Initialize some counters
//Set up a single branch with fSplit=1. Setting branches by hand is not yet supported.
//
//if file opened in read mode.
//Get the tree object from the file
//Set counter of the number of entries in the file
//Initialize some counters and flags
if(fWriteFile) {
// Create a ROOT Tree and one superbranch
fSplit = 1;
fTree = new TTree("T","An example of a ROOT tree");
fTree->SetAutoSave(500000); // autosave when .5 Mbyte written
fBufsize = 25600;
if (fSplit) fBufsize /= 4;
fNumBytesWritten = 0;
fCreateBranch = kTRUE;
BrEvent *dummy_event = new BrEvent("Digitized Table",0,0);
fBranch[0] = fTree->Branch("event","BrEvent",&dummy_event,fBufsize,fSplit);
delete dummy_event;
}
else {
fROOTFile->ls();
fTree = (TTree*)fROOTFile->Get("T");
if(fTree) {
fBranch[0] = fTree->GetBranch("event");
fNumEntries = (Int_t)fTree->GetEntries();
printf("Number of entries in tree is %dn",fNumEntries);
fNumBytesRead = 0;
fEventNumber = 0;
fStatus = 1;
fError = kFALSE;
fEof = kFALSE;
}
else {
return kFALSE; //error
}
}
return kTRUE;
}
Bool_t BrEventIO::Close()
{
// Close the file Opened by the object. Return
// kFALSE if no file was open.
if(fROOTFile) {
if(!fROOTFile->IsOpen()) return kFALSE;
if(fWriteFile) fROOTFile->Write();
fROOTFile->Close();
delete fROOTFile;
fROOTFile = 0;
return kTRUE;
}
return kFALSE;
}
Bool_t BrEventIO::SkipEvent(Int_t numevt)
{
// Skip events on input only
//
if(fWriteFile){
if(fFileMode == ROOT_FILE_SERIAL) {
for(Int_t i=0;i<numevt;i++) {
TKey *key = (TKey *) fNextKey->operator()();
if( !key ) {
// if(fVerbose) cout<<"No keys left - skipped past EOF"<<endl;
fEof = kTRUE;
return kFALSE;
}
}
}
else if(fFileMode == ROOT_FILE_TREE) {
fEventNumber += numevt;
if(fEventNumber > fNumEntries) {
// if(fVerbose) cout<<"Skipped past EOF"<<endl;
fEof = kTRUE;
return kFALSE;
}
}
return kTRUE;
}
else{
Warning("Skip Event","Not allowed on write");
return kFALSE;
}
}
void BrEventIO::Event(BrEvent* event)
{
// Reads or writes one event depending on whether we are in read mode or write mode
if(fFileMode == ROOT_FILE_SERIAL) {
ProcessRootSerialFile(event);
}
else if(fFileMode == ROOT_FILE_TREE) {
ProcessRootTreeFile(event);
} //if fFileMode
}
void BrEventIO::ProcessRootSerialFile(BrEvent *event) {
//Do Serial File specific actions to read or write the file depending on mode
//if write mode, simply write the object and increment number of events written.
//if read mode,
//get the next key,
//Create a dummy event using key->ReadObj();
//Copy the dummy event into the event we are passing back.
//increment number of events read
TDirectory *cursav = gDirectory;
fROOTFile->cd(); //change to file we want to be in.
if(fWriteFile) {
event->Write(); //should be that simple
fEventNumber++;
}
else {
TKey *key;
key = (TKey *) fNextKey->operator()();
if(key) {
// printf("Trying to read eventn");
// key->Read(event);
// printf("Event successfully read inn");
// event = (BrEvent *) key->ReadObj();
// Read the event creating a new dummy_event
BrEvent *dummy_event = (BrEvent *) key->ReadObj();
// Check and see if we got a valid event back
if(dummy_event == 0){
cout << "returned Null event" << endl;
fEof = kTRUE;
fStatus = kFALSE;
cursav->cd();
return; //put back original directory
}
dummy_event->Copy(*event);
fEventNumber++;
// Event is copied, but still accesses objects which are now in event.
// The data is not actually copied; the pointers to the data in fObjectList1
// are copied to fObjectList2. Maybe need a more sophisticated copy method.
// So need to clear before deleting
dummy_event->Clear();
delete dummy_event;
}
else {
fEof = kTRUE;
fStatus = kFALSE;
cursav->cd(); //put back original directory
return;
}
}
cursav->cd(); //put back original directory
return;
}
void BrEventIO::ProcessRootTreeFile(BrEvent *event) {
//Do Tree File specific actions to read or write the file depending on mode
//if Write mode, set the branch address to the event argument, then fTree->Fill();
//if Read mode, set branch address to event argument, then fTree->GetEvent(fEventNumber);
if(fWriteFile) {
fBranch[0]->SetAddress(&event);
fTree->Fill();
}
else {
if(fEventNumber >= fNumEntries) {
fEof = kTRUE;
return;
}
fBranch[0]->SetAddress(&event);
fNumBytesRead += fTree->GetEvent(fEventNumber);
fEventNumber++;
}
}
void BrEventIO::SetFileMode(Int_t mode) {
//Set file mode.
//mode can be either tree or serial
//mode must be set before opening the file.
if(fROOTFile) {
cout<<"File mode must be selected before file is opened"<<endl;
cout<<"File mode has been selected to be "<<fFileMode<<" and will remain so"<<endl;
return;
}
if(mode != ROOT_FILE_SERIAL && mode != ROOT_FILE_TREE) {
cout<<"Invalid file mode, can only be ROOT_FILE_SERIAL or ROOT_FILE_TREE"<<endl;
return;
}
fFileMode = mode;
}
void BrEventIO::Streamer(TBuffer &R__b)
{
// Stream an object of class BrEventIO.
if (R__b.IsReading()) {
Version_t R__v = R__b.ReadVersion(); if (R__v) { }
BrIOModule::Streamer(R__b); //do we need this???
R__b >> fFileMode;
R__b.ReadStaticArray(fDateTimeCreated);
} else {
R__b.WriteVersion(BrIOModule::IsA());
BrIOModule::Streamer(R__b); //do we need this
R__b << fFileMode;
R__b.WriteArray(fDateTimeCreated,32);
}
}
ostream& operator<< (ostream & os,BrEventIO *digio_p)
{
os<<"Digitize IO; fFileMode ="<<digio_p->GetFileMode();
os<<endl;
return os;
}
ostream& operator<< (ostream & os,BrEventIO &digio_p)
{
os<<"Digitize IO; fFileMode ="<<digio_p.GetFileMode();
os<<endl;
return os;
}
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.