//*-- Author : Manuel Sanchez
//*-- Modified : 08/10/2003 by Romain Holzmann
//*-- Modified : 24/02/2003 by Ilse Koenig
//*-- Modified : 23/05/2002 by Manuel Sanchez
//*-- Modified : 01/03/2000 by Manuel Sanchez
//*-- Modified : 5/05/98 by Manuel Sanchez
//*-- Copyright : GENP (Univ. Santiago de Compostela)

//_HADES_CLASS_DESCRIPTION 
////////////////////////////////////////////////////////////////////////////
// HRootSource
//
// This data source can read data from a ROOT file generated by
// HYDRA, this includes both the reconstruction and simulation software.
//
// The data source takes care of instantiating the appropriate classes even
// if they are non-standard. That is, if you have an input file with 
// HMdcHitSim instead of HMdcHit; HRootSource will take care of using
// HMdcHitSim during the analysis.
//
////////////////////////////////////////////////////////////////////////////
using namespace std;
#include "hrootsource.h"
#include "hades.h"
#include "hrecevent.h"
#include "heventheader.h"
#include "hpartialevent.h"
#include "hcategory.h"
#include <iostream> 
#include <iomanip>
#include <limits.h>
#include <unistd.h>
#include <TKey.h>

ClassImp(HRootSource)

   HRootSource::HRootSource(Bool_t fPers, Bool_t fMerg) {
  // for fPers==kFALSE, input cats are suppressed in output
  // for fMerg==kTRUE, partial events in input tree are merged into current
  // event, if it exists already at init().
  fInput=0;
  fEventInFile=0;
  fCursor=0;
  fCurrentRunId=INT_MIN;
  fCurrentRefId=-1;
  fGlobalRefId=-1;
  fDirectory="./";
  fPersistency=fPers;
  fMerge=fMerg;
  fEventList=0;
  fLastRunId=-1;
  overwriteVersion=kFALSE;
  replaceVersion=0;
}

 HRootSource::~HRootSource(void) {
  //Class destructor, it clears the data source.
  Clear();
}

 Bool_t HRootSource::init(void) {
  // Initializes the data source connecting the parts of the input tree in
  // the input ROOT file to the event structure used for the analysis. If
  // no event structure has been set by the user, HRootSource::init() will
  // set one read from the input file. If it exists, it will be used as such
  // (fMerge==kFALSE) or merged with the one in the input file (fMerge==kTRUE).
  Bool_t r=kTRUE;

  if (fEventInFile!=0) {
    //If there is an active event structure
    HRecEvent* fCurrentEvent = (HRecEvent*)gHades->getCurrentEvent();
    if (fCurrentEvent!=0) {
      if (fMerge) {  // merge the 2 event structures

        Warning("init","Merging with predefined event structure"); 
        ((HRecEvent*)fEventInFile)->merge(fCurrentEvent);

      } else {
         Warning("init","Using predefined event structure");
      }

    } else  gHades->setEvent(fEventInFile); 
    
    if ( fInput!=0) {
      Char_t sl=*(strchr(fInput->GetTitle(),'.')+1);
      switch (sl) {
      case '0' : fSplitLevel=0; break;
      case '1' : fSplitLevel=1; break;
      case '2' : fSplitLevel=2; break;
      default : fSplitLevel=0;
      }
      fInput->SetBranchStatus("*",kFALSE);
      gHades->activateTree(fInput);
      if (fEventList)
	fEntries = fEventList->GetN();
      else 
	fEntries=fInput->GetEntries();
      if (fCursor >= fEntries) {
	Error("init","Entry not existing %i",fCursor);
	return kFALSE; //Entry not existing
      }
      if (fEventList)
	fInput->GetEvent(fEventList->GetEntry(fCursor));
      else
	fInput->GetEvent(fCursor);
      fCurrentRunId=gHades->getCurrentEvent()->getHeader()
	->getEventRunNumber();
      fLastRunId=fCurrentRunId; 

      if(overwriteVersion)
      { // fix not set version in simulation
         gHades->getCurrentEvent()->getHeader()->setVersion(replaceVersion);
      }

      if (fRefIds.find(fCurrentRunId) != fRefIds.end())
	fCurrentRefId=fRefIds[fCurrentRunId];
      else
	fCurrentRefId=fGlobalRefId;

      if (fPersistency==kFALSE) { // set all input categories non-persistent

        for(Int_t i=0;i<16;i++) { // loop over partial events
          HPartialEvent* fPar = 
             ((HRecEvent*)fEventInFile)->getPartialEvent(i<<kBitCategorySize);
          if (fPar) fPar->setPersistency(kFALSE);
        }
      }

      r=kTRUE;
    } else {
      Warning("init","Not input");
      Clear();
      r=kFALSE;
    }
  } else {
    r=kFALSE;
  }
  return r;
}

 EDsState HRootSource::getNextEvent(Bool_t doUnpack) {
  //Retrieves next event in the input file.
  Int_t bread=0;

  if (fInput) {
    if (fSplitLevel<2) (*fEventAddr)->clearAll(fSplitLevel);
    if (fCursor<fEntries) {
      if (fEventList)
	bread = fInput->GetEvent(fEventList->GetEntry(fCursor));
      else
	bread=fInput->GetEvent(fCursor);
      if (bread == 0) return kDsEndData;
      fCursor++;
      fCurrentRunId=gHades->getCurrentEvent()->getHeader()
	                                     ->getEventRunNumber();
      if(overwriteVersion)
      {  // fix not set version in simulation
         gHades->getCurrentEvent()->getHeader()->setVersion(replaceVersion);
      }
      if (fCurrentRunId != fLastRunId) {
	if (fRefIds.find(fCurrentRunId) != fRefIds.end()) 
	  fCurrentRefId=fRefIds[fCurrentRunId];
	else
	  fCurrentRefId=fGlobalRefId;
        fLastRunId=fCurrentRunId;
	return kDsEndFile;
      }
    } else return kDsEndData;
  } else return kDsError;
  return kDsOk;
}

 Bool_t HRootSource::getEvent(Int_t eventN) {
  //Retrieves event in position eventN in the input file, copying the 
  //information to the event structure.
  if (fInput) {
    if (fEventList) 
      if (fInput->GetEvent(fEventList->GetEntry(eventN))>0) return kTRUE;
    else
      if (fInput->GetEvent(eventN)>0) return kTRUE;
    else return kFALSE;
  }
  return kFALSE;
}

 void HRootSource::Clear(void) {
  //Closes the input file.
  if (fInput) {delete fInput; fInput=0;}
}

 void HRootSource::setDirectory(Text_t dirName[]) {
  //Sets the directory where to read files from.
  fDirectory=dirName;
  if (fDirectory[fDirectory.Length()-1] != '/') fDirectory+="/";
}

 Bool_t HRootSource::fileExists(const TString &name) {
  //Checks for the existence on one file.
  return (access(name.Data(),F_OK)==0)?kTRUE:kFALSE;
}

 TString HRootSource::getFileName(Text_t *file)
{
  TString fname;
  if (file[0] == '/') { //Absolute or relative path??
    fname=file;
  } else {
    fname=fDirectory;
    fname+=file;
  }
  return fname;
}

 Bool_t HRootSource::addFile(Text_t *file) 
{
  Text_t treeName[]="T";
  TString fname = getFileName(file);

  if (fileExists(fname)) {
    if (!fInput) { //If chain doesn't already exist
      TFile *fileTemp;
      TKey *key=0;
      TString title;

      fileTemp=getFile(fname.Data()); //Obtain tree title
      //new TFile(fname.Data());
      key=fileTemp->GetKey(treeName);  //No need to delete this pointer
      fEventInFile=(HEvent *)fileTemp->Get("Event");
      fCurrentRunId=fEventInFile->getHeader()->getEventRunNumber();
      if (fRefIds.find(fCurrentRunId) != fRefIds.end()) 
	fCurrentRefId=fRefIds[fCurrentRunId];
      else
	fCurrentRefId=fGlobalRefId;
      title=key->GetTitle();
      fileTemp->Close();
      delete fileTemp;
      fInput=new TChain(treeName,title.Data()); 
    }
    fInput->Add(fname.Data());
    
  } else {
    Warning("addFile","File %s not found",fname.Data());
    return kFALSE;
  }
  return kTRUE;
}

 Bool_t HRootSource::setInput(Text_t *fileName,Text_t *treeName) {
  //Sets the input file and tree. Opening the corresponding files, it also
  //loads in memory the input event description so the disableCategory() 
  //method can be used.
  if (strcmp(treeName,"T") != 0) return kFALSE;
  return addFile(fileName);
}

 Bool_t HRootSource::disableCategory(Cat_t aCat) {
  //Disables the category aCat so it is not read even if it is stored in
  //the input file. This method shouldn't be called after init()
  //Returns kTRUE if the aCat was stored in the input file and has succesfully
  //been disabled, otherwise the return value is kFALSE.
  if (!fEventInFile) return kFALSE;
  return fEventInFile->removeCategory(aCat);
}

 Bool_t HRootSource::disablePartialEvent(Cat_t aCat) {
  if (!fEventInFile) return kFALSE;
  return ((HRecEvent*)fEventInFile)->removePartialEvent(aCat);
}

 Int_t HRootSource::getSplitLevel(void) {
  //Returns the split level of the input tree.
  return fSplitLevel;
}

 void HRootSource::deactivateBranch(Text_t *branchName) {
  //Deactivates a branch so it is not read. 
  //This method is deprecated, use disableCategory() instead.
  if (fInput) {
    fInput->SetBranchStatus(branchName,kFALSE);
  }
}

 TTree *HRootSource::getTree(void) {
  //Returns the input tree.
  return fInput;
}

 EDsState HRootSource::skipEvents(Int_t nEv) {
  enum EDsState state = kDsOk;

  if (nEv>0) {
    Int_t newCursor = fCursor + nEv;

    if (newCursor < fEntries) {
      	  fCursor = newCursor - 1;
	  state = getNextEvent();
    } else state = kDsEndData;
  }

  return state;
}

 TFile * HRootSource::getFile(TString name)
{
  return TFile::Open(name.Data(),"READ");
};




ROOT page - Class index - Class Hierarchy - 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.