#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.