#include "hsuexemacro.h"
#include "hcategory.h"
#include <getopt.h>
// -----------------------------------------------------------------------------
// $Id: hsuexemacro.cc,v 1.5 2002/09/05 12:48:11 jaskula Exp $
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// *-- Author : Marcin Jaskula
// -----------------------------------------------------------------------------
HSUBranchElement::HSUBranchElement(const char* pBranchName, EBranchType eType)
{
if((eType < 0) || (eType >= kMax))
{
Error("HSUBranchElement", "Unknown type %dn", eType);
gSystem->Exit(-1);
}
m_pArray = NULL;
m_pBranch = NULL;
m_eType = eType;
m_pName = new TString(pBranchName);
}
// -----------------------------------------------------------------------------
HSUBranchElement::~HSUBranchElement(void)
{
SAFE_DELETE_ROOT(m_pArray);
SAFE_DELETE(m_pName);
}
// -----------------------------------------------------------------------------
const char* HSUBranchElement::getBranchNameSufix(void)
{
static const char* asHSUBranchElementBranchesSufix[HSUBranchElement::kMax]
= { ".fData", "." };
return asHSUBranchElementBranchesSufix[m_eType];
}
//______________________________________________________________________________
// A class to make live easier with chains and branches in an executive macro.
// It is dedicated for making complicate correlation between branches.
//
// It supports:
// - TChain with files consists of HADES 'T' Tree
// - automatic access to branches' data by HCategory or TClonesArray
// - easy access to program arguments
// - easy access to parameters in a parameter files
//
// A simple program which shows possibility may looks like:
//
// int main(int iArg, char* vArg[])
// {
// HSUExeMacro eEM;
//
// eEM.loadArgs(iArg, vArg);
// eEM.openInput();
// eEM.openParamFile();
// eEM.openOutput();
//
// HCategory *pMdcCategory;
// TCutG *pCut = NULL;
// HMdcSeg *pSeg;
//
// if(eEM.getOptBool())
// pCut = (TCutG *)eEM.getParamObject("some_cut");
//
// pMdcCategory = eEM.getHCategory("HMdcSeg");
//
// while(eEM.nextEvent() >= 0)
// {
// for(i = 0; i < pMdcCategory->getEntries(); i++)
// {
// if((pSeg = (HMdcSeg * )pMdcCategory->getObject(i)) == NULL)
// continue;
//
// ...
// }
// }
//
// eEM.writeOutput();
//
// return 0;
// }
//
// Arguments of the program supported by the class:
// -i file_name - (may appear many times) define a list of input files.
// If the file is *.root it is added to the chain.
// Otherwise it is taken as a text file with a list of root files
// all empty lines and lines starting with # are skipped
// -o file_name - a name of an output file
// -e number - maximum number of events to process
// -p file_name - a name of an optional file with some object for the program;
// they are easy to get by getParamObject() method
// -h - prints a help message
//
// Other program arguments which may be used by the program:
// -s string - string can be get by getOptString() method
// -n int - can be get by getOptInt()
// -f float - can be get by getOptFloat()
// -b - existence of the parameter can be get by getOptBool()
//
//______________________________________________________________________________
ClassImp(HSUExeMacro)
// -----------------------------------------------------------------------------
HSUExeMacro::HSUExeMacro(void)
{
// A constructor of the class
m_pChain = new TChain("T");
m_pProgress = NULL;
m_iEvents = -1;
m_pOutputFile = NULL;
m_iCurrentFile = -1;
m_iEvent = -1;
m_bExitOnError = kTRUE;
m_pInputArray = new TObjArray();
m_pInputArray->SetOwner();
m_pActiveBranches = new TObjArray();
m_pActiveBranches->SetOwner();
m_pParamFile = NULL;
m_iOptInt = 0;
m_fOptFloat = 0.0f;
m_bOptBool = kFALSE;
m_bNotFileChange = kFALSE;
}
// -----------------------------------------------------------------------------
HSUExeMacro::~HSUExeMacro()
{
// Destructor.
// Close all input and output files opened by the class and delete what was used
SAFE_DELETE_ROOT(m_pChain);
SAFE_DELETE_ROOT(m_pInputArray);
SAFE_DELETE_ROOT(m_pOutputFile);
SAFE_DELETE_ROOT(m_pActiveBranches);
SAFE_DELETE(m_pProgress);
SAFE_DELETE_ROOT(m_pParamFile);
}
// -----------------------------------------------------------------------------
void HSUExeMacro::setProgress(HSUProgress *pProgress)
{
// Set a progress bar used by the class during the events loop
deleteProgress();
m_pProgress = pProgress;
}
// -----------------------------------------------------------------------------
void HSUExeMacro::setProgress(Bool_t bSet)
{
// Set a default progress bar used by the class during the events loop.
// If bSet == kFALSE - removes the progress bar
deleteProgress();
if(bSet)
{
m_pProgress = new HSUProgress();
m_pProgress->SetSpinEvents(1000);
}
}
// -----------------------------------------------------------------------------
HSUProgress* HSUExeMacro::getProgress(void) const
{
// Return the progress bar used by the class
return m_pProgress;
}
// -----------------------------------------------------------------------------
void HSUExeMacro::deleteProgress(void)
{
// Delete the progress bar used by the class
SAFE_DELETE(m_pProgress);
}
// -----------------------------------------------------------------------------
Int_t HSUExeMacro::loadArgs(int iArg, char* vArg[])
{
// Load all arguments from the program arguments given as the parameters.
// All parameters supported by the class are listed in the class description.
int option;
int i, iError;
float f;
opterr = 0;
iError = 0;
while((option = getopt(iArg, vArg, "n:p:f:s:i:c:o:e:hb")) != -1)
{
switch(option)
{
case 'i':
m_pInputArray->Add(new TObjString(optarg));
break;
case 'o':
m_sOutputName = optarg;
break;
case 'e':
if(sscanf(optarg, "%d", &i) != 1)
iError++;
else
m_iEvents = i;
break;
case 'h':
iError = -1000000;
break;
case 'p':
m_sParamFileName = optarg;
break;
case 's':
m_sOptString = optarg;
break;
case 'n':
if(sscanf(optarg, "%d", &i) != 1)
iError++;
else
m_iOptInt = i;
break;
case 'f':
if(sscanf(optarg, "%f", &f) != 1)
iError++;
else
m_fOptFloat = f;
break;
case 'b':
m_bOptBool = kTRUE;
break;
case '?':
break;
default:
Error("loadArgs", "Unknown option %cn", optopt);
iError++;
break;
}
}
if(iError != 0)
printInfo(vArg[0]);
return ((iError < 0) || ((iError > 0) && (m_bExitOnError))) ? -1 : 0;
}
// -----------------------------------------------------------------------------
void HSUExeMacro::printInfo(const char *pProgramName) const
{
// Print info about all standard options. Used when `-h' is in the arguments.
printf("Use:n\n%s -i file -o file [-e events] [-p param_file]n\n"
"t-i file - a root file (*.root) or text file with "
"list of filesn"
"t-o file - output filen"
"t-e num - number of events to processn"
"t-p param_file - a root file with parametersn\n",
pProgramName);
}
// -----------------------------------------------------------------------------
Bool_t HSUExeMacro::openInput(void)
{
// Create the chain from all files given as the arguments of the program
Int_t iMax = m_pInputArray->GetEntries();
Int_t i;
TString rStr;
if(iMax <= 0)
{
Error("openInput", "No input files");
if(m_bExitOnError)
gSystem->Exit(-1);
return kFALSE;
}
for(i = 0; i < iMax; i++)
{
rStr = ((TObjString *)m_pInputArray->At(i))->GetString();
if(rStr.EndsWith(".root", TString::kIgnoreCase))
{
if( ! addInputFile(rStr.Data()))
return kFALSE;
continue;
}
if( ! addFilesFromList(rStr.Data()))
return kFALSE;
}
return kTRUE;
}
// -----------------------------------------------------------------------------
Bool_t HSUExeMacro::addInputFile(const char* pStr)
{
// Add a root file to the chain
Int_t iRet;
if((iRet = m_pChain->Add(pStr, -1)) <= 0)
{
Error("addInputFile", "Cannot open file: `%s'", pStr);
if(m_bExitOnError)
gSystem->Exit(-1);
return kFALSE;
}
printf("Input file: %-50s %8d evtsn", pStr,
m_pChain->GetTreeOffset()[m_pChain->GetNtrees()]
- m_pChain->GetTreeOffset()[m_pChain->GetNtrees() - 1]);
return kTRUE;
}
// -----------------------------------------------------------------------------
Bool_t HSUExeMacro::addFilesFromList(const char *pStr)
{
// Add all root files listed in a text file given as the argument.
// All empty lines or lines starting with `#' are skipped.
// File names are trimmed before use
// (all start and tail white characters are removed)
FILE *pFile;
char s[1000];
char *p1, *p2;
if((pFile = fopen(pStr, "r")) == NULL)
{
Error("addFilesFromList", "Cannot open file: %s", pStr);
if(m_bExitOnError)
gSystem->Exit(-1);
return kFALSE;
}
while(fgets(s, 1000, pFile))
{
for(p1 = s; isspace(*p1); p1++)
;
for(p2 = p1 + strlen(p1) - 1; (p2 > p1) && (isspace(*p2)); p2--)
;
*(p2 + 1) = '0';
if((*p1 == '#') || (p2 <= p1))
continue;
if( ! addInputFile(p1))
return kFALSE;
}
fclose(pFile);
return kTRUE;
}
// -----------------------------------------------------------------------------
Bool_t HSUExeMacro::openOutput(void)
{
// Open the output file
if(m_sOutputName.Length() <= 0)
{
Error("openOutput", "No output file name");
if(m_bExitOnError)
gSystem->Exit(-1);
return kFALSE;
}
if(((m_pOutputFile = new TFile(m_sOutputName, "RECREATE")) == NULL)
|| ( ! m_pOutputFile->IsOpen()))
{
Error("openOutput", "Cannot open file: %s", m_sOutputName.Data());
if(m_bExitOnError)
gSystem->Exit(-1);
return kFALSE;
}
printf("Output file: %s openedn", m_sOutputName.Data());
return kTRUE;
}
// -----------------------------------------------------------------------------
Bool_t HSUExeMacro::writeOutput(void)
{
// Simple close the output file. All root objects created since the openOutput
// are written to the file
if((m_pOutputFile != NULL) && (m_pOutputFile->IsOpen()))
return m_pOutputFile->Write();
Error("writeOutput", "Output file not opened");
return kFALSE;
}
// -----------------------------------------------------------------------------
TClonesArray* HSUExeMacro::getTClonesArray(const char *pBranchName)
{
// Get the TClonesArray from the file.
// To get a proper branch a `.fData' suffix is added to `pBranchName'
HSUBranchElement *pBE;
if((pBE = findAciveBranch(pBranchName)) == NULL)
return getNewArrayFromBranch(pBranchName);
if(pBE->m_eType == HSUBranchElement::kArray)
return (TClonesArray *)pBE->m_pArray;
Error("getTClonesArray", "Branch %s has no array", pBranchName);
if(m_bExitOnError)
gSystem->Exit(-1);
return NULL;
}
// -----------------------------------------------------------------------------
HCategory* HSUExeMacro::getHCategory(const char *pCategoryName)
{
// Get the HCategory from the file.
// To get a proper branch a `.' suffix is added to `pCategoryName'
HSUBranchElement *pBE;
if((pBE = findAciveBranch(pCategoryName)) == NULL)
return getNewHCategoryFromBranch(pCategoryName);
if(pBE->m_eType == HSUBranchElement::kCategory)
return (HCategory *)pBE->m_pArray;
Error("getTClonesArray", "Branch %s has no HCategory", pCategoryName);
if(m_bExitOnError)
gSystem->Exit(-1);
return NULL;
}
// -----------------------------------------------------------------------------
TBranch* HSUExeMacro::getBranch(const char *pBranchName)
{
// Get the brach from the `T'
// if was activated by getHCategory or getTClonesArray
HSUBranchElement *pBE;
return ((pBE = findAciveBranch(pBranchName)) == NULL)
? NULL : pBE->m_pBranch;
}
// -----------------------------------------------------------------------------
TClonesArray* HSUExeMacro::getNewArrayFromBranch(const char *pBranchName)
{
// Create new branch and a TClonesArray for it
HSUBranchElement *pBE;
TObjString str(pBranchName);
TBranch *pBranch;
pBE = new HSUBranchElement(pBranchName, HSUBranchElement::kArray);
TString strDataBranch = str.GetString() + pBE->getBranchNameSufix();
if((pBranch = m_pChain->GetBranch(strDataBranch.Data())) == NULL)
{
delete pBE;
Error("getNewArrayFromBranch", "No branch %s in Tree",
strDataBranch.Data());
if(m_bExitOnError)
gSystem->Exit(-1);
return NULL;
}
pBE->m_pBranch = pBranch;
pBE->m_pArray = new TClonesArray(pBranchName);
m_pActiveBranches->Add(pBE);
m_pChain->SetBranchStatus(strDataBranch.Data(), 1);
pBE->m_pBranch->SetAddress(&(pBE->m_pArray));
return (TClonesArray *)pBE->m_pArray;
}
// -----------------------------------------------------------------------------
HCategory* HSUExeMacro::getNewHCategoryFromBranch(const char *pBranchName)
{
// Create new branch and a HCategory for it
HSUBranchElement *pBE;
TObjString str(pBranchName);
TBranch *pBranch;
HCategory *pCat;
pBE = new HSUBranchElement(pBranchName, HSUBranchElement::kCategory);
TString strDataBranch = str.GetString() + pBE->getBranchNameSufix();
if((pBranch = m_pChain->GetBranch(strDataBranch.Data())) == NULL)
{
delete pBE;
Error("getNewArrayFromBranch", "No branch %s in Tree",
strDataBranch.Data());
if(m_bExitOnError)
gSystem->Exit(-1);
return NULL;
}
TDirectory *pDirSav = gDirectory;
m_pChain->GetDirectory()->cd();
if((pCat = (HCategory *)gDirectory->FindObject(pBranchName))
== NULL)
{
pDirSav->cd();
delete pBE;
Error("getNewArrayFromBranch", "No HCategory %s in Tree", pBranchName);
if(m_bExitOnError)
gSystem->Exit(-1);
return NULL;
}
pDirSav->cd();
pBE->m_pBranch = pBranch;
pBE->m_pArray = pCat->Clone();
m_pActiveBranches->Add(pBE);
m_pChain->SetBranchStatus(strDataBranch.Data(), 1);
pBE->m_pBranch->SetAddress(&(pBE->m_pArray));
return (HCategory *)pBE->m_pArray;
}
// -----------------------------------------------------------------------------
HSUBranchElement* HSUExeMacro::findAciveBranch(const char *pBranchName)
{
// Find an active branch by name
Int_t i, iMax;
HSUBranchElement *pBE;
iMax = m_pActiveBranches->GetEntries();
for(i = 0; i < iMax; i++)
{
if((pBE = (HSUBranchElement *)m_pActiveBranches->At(i)) == NULL)
continue;
if(pBE->m_pName->CompareTo(pBranchName) == 0)
return pBE;
}
return NULL;
}
// -----------------------------------------------------------------------------
Int_t HSUExeMacro::loadTree(Int_t iEvent)
{
// Load the event from tree.
// All active categories and array are filled with the new data.
// If switch of the files is needed then new branches are created automatically.
Int_t iE;
if((iE = m_pChain->LoadTree(iEvent)) < 0)
return iE;
if(m_pChain->IsA() != TChain::Class())
return iE;
if(m_pChain->GetTreeNumber() != m_iCurrentFile)
{
m_iCurrentFile = m_pChain->GetTreeNumber();
if( ! notifyBranches())
iE = -1;
if(m_bNotFileChange)
{
Warning("loadTree", "File changed to: %sn",
m_pChain->GetFile()->GetName());
}
}
return iE;
}
// -----------------------------------------------------------------------------
Bool_t HSUExeMacro::notifyBranches(void)
{
// Get branches from a new file in the chain.
// Called by loadTree if needed
Int_t i, iMax;
HSUBranchElement *pBE;
TString str;
Bool_t bReturn = kTRUE;
iMax = m_pActiveBranches->GetEntries();
for(i = 0; i < iMax; i++)
{
if((pBE = (HSUBranchElement *)m_pActiveBranches->At(i)) == NULL)
continue;
str = *pBE->m_pName;
str += pBE->getBranchNameSufix();
if((pBE->m_pBranch = m_pChain->GetBranch(str.Data())) == NULL)
{
Error("notifyBranches", "No branch `%s'n\tin file: `%s'",
str.Data(), m_pChain->GetFile()->GetName());
if(m_bExitOnError)
gSystem->Exit(-1);
bReturn = kFALSE;
}
pBE->m_pBranch->SetAddress(&(pBE->m_pArray));
}
return bReturn;
}
// -----------------------------------------------------------------------------
void HSUExeMacro::clear(void)
{
// Clear all arrays and categories before next event
HSUBranchElement *pBE;
Int_t i, iMax;
iMax = m_pActiveBranches->GetEntries();
for(i = 0; i < iMax; i++)
{
if((pBE = (HSUBranchElement *)m_pActiveBranches->At(i)) == NULL)
continue;
pBE->m_pArray->Clear();
}
}
// -----------------------------------------------------------------------------
void HSUExeMacro::getBranchesEntry(Int_t iEntry)
{
// Fill the array or category with the data of the current event
HSUBranchElement *pBE;
Int_t i, iMax;
iMax = m_pActiveBranches->GetEntries();
for(i = 0; i < iMax; i++)
{
if((pBE = (HSUBranchElement *)m_pActiveBranches->At(i)) != NULL)
pBE->m_pBranch->GetEntry(iEntry);
}
}
// -----------------------------------------------------------------------------
Int_t HSUExeMacro::getEvent(Int_t iEvent)
{
// Get all data for the event.
// If no events left return value < 0
Int_t iE;
clear();
if((iE = loadTree(iEvent)) >= 0)
getBranchesEntry(iE);
return iE;
}
// -----------------------------------------------------------------------------
Bool_t HSUExeMacro::checkBranches(void)
{
// Check if all activated branches exist in the every file in the chain
Int_t i, iMax;
Bool_t bReturn = kTRUE;
iMax = m_pChain->GetNtrees();
for(i = 0; i < iMax; i++)
{
if(getEvent(m_pChain->GetTreeOffset()[i]) < 0)
bReturn = kFALSE;
}
m_iCurrentFile = -1;
return bReturn;
}
// -----------------------------------------------------------------------------
Int_t HSUExeMacro::nextEvent(void)
{
// Get next event
// Return >= 0 if ok, or < 0 when at the end of the events list
if(m_iEvent < 0)
{
Int_t iE;
if(((iE = (Int_t)m_pChain->GetEntries()) < m_iEvents)
|| (m_iEvents < 0))
{
m_iEvents = iE;
}
if(m_pProgress != NULL)
m_pProgress->SetMaxValue(m_iEvents);
}
if(++m_iEvent >= m_iEvents)
return -1;
if(m_pProgress != NULL)
m_pProgress->Next();
if(getEvent(m_iEvent) < 0)
return -2;
return m_iEvent;
}
// -----------------------------------------------------------------------------
Bool_t HSUExeMacro::openParamFile(const char *pParamFileName)
{
// Open a file with parameters. The parameters from the file may be get by:
// HSUExeMacro::getParamObject method
if(m_pParamFile != NULL)
{
m_pParamFile->Close();
m_pParamFile->Delete();
}
if(pParamFileName != NULL)
m_sParamFileName = pParamFileName;
if(m_sParamFileName.Length() <= 0)
{
Error("openParamFile", "No param file name !");
if(m_bExitOnError)
gSystem->Exit(-1);
return kFALSE;
}
if(((m_pParamFile = new TFile(m_sParamFileName, "READ")) == NULL)
|| ( ! m_pParamFile->IsOpen()))
{
Error("openParamFile", "Cannot open param file: %s",
m_sParamFileName.Data());
if(m_pParamFile != NULL)
{
m_pParamFile->Close();
m_pParamFile->Delete();
m_pParamFile = NULL;
}
if(m_bExitOnError)
gSystem->Exit(-1);
return kFALSE;
}
return kTRUE;
}
// -----------------------------------------------------------------------------
TObject* HSUExeMacro::getParamObject(const char *pName)
{
// Get an object from the parameter file (if opened)
if(m_pParamFile == NULL)
{
Error("getParamObject", "Param file not opened");
if(m_bExitOnError)
gSystem->Exit(-1);
return NULL;
}
return m_pParamFile->Get(pName);
}
// -----------------------------------------------------------------------------
const TString& HSUExeMacro::getParamFileName(void) const
{
// Return param file name or empty string if the name not set
return m_sParamFileName;
}
// -----------------------------------------------------------------------------
Float_t HSUExeMacro::getMdcPhi(Int_t iSector, Float_t fPhiMdc) const
{
// Convert MDC's phi angle to the coordinate system used in other detectors
static Float_t R2D = 180.0 / TMath::Pi();
Float_t fPhi;
fPhi = R2D * fPhiMdc;
switch(iSector)
{
case 0:
break;
case 1:
case 2:
case 3:
case 4:
fPhi += 60.0f * iSector;
break;
default:
fPhi -= 60.0f;
break;
}
return fPhi;
}
// -----------------------------------------------------------------------------
Float_t HSUExeMacro::getMdcTheta(Float_t fThetaMdc) const
{
// Convert MDC's theta angle to the coordinate system used in other detectors
static Float_t R2D = 180.0 / TMath::Pi();
return fThetaMdc * R2D;
}
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.