ROOT logo
/**************************************************************************
 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/*
 * Container class for histogram objects. Currenly can handle
 *   TH1
 *   TH2
 *   TH3
 *   THnSparse
 * Histograms can be stored in groups. For this the parent group is 
 * included inside the histogram name, i.e. /base/inheriting/histogram.
 * In case just the histogram name is given, it is assumed that the
 * histogram is stored at the top level.
 *
 *   Author: Markus Fasel
 */

#include <cstring>
#include <string>
#include <vector>
#include <TArrayD.h>
#include <TAxis.h>
#include <TH1.h>
#include <TH2.h>
#include <TH3.h>
#include <THnSparse.h>
#include <THashList.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TString.h>

#include "THistManager.h"

ClassImp(THistManager)

//______________________________________________________________________________
THistManager::THistManager():
		TNamed(),
		fHistos(NULL),
		fIsOwner(true)
{
	/*
	 * Default constructor, only initialising pointers with 0
	 */
}

//______________________________________________________________________________
THistManager::THistManager(const char *name):
		TNamed(name, Form("Histogram container %s", name)),
		fHistos(NULL),
		fIsOwner(true)
{
	/*
	 * Main constructor, creating also a list for the histograms
	 *
	 * @param name: Name of the object (list named accordingly)
	 */
	fHistos = new THashList();
	fHistos->SetName(Form("histos%s", name));
	fHistos->SetOwner();
}

//______________________________________________________________________________
THistManager::~THistManager(){
	/*
	 * Destructor, deletes the list of histograms if it is the owner
	 */
	if(fHistos && fIsOwner) delete fHistos;
}

//______________________________________________________________________________
void THistManager::CreateHistoGroup(const char *groupname, const char *parent) {
	/*
	 * Create a new group of histograms within a parent group. Groups are represented as list. The default parent is
	 * always the top list. List name structure accouding to unix paths (i.e. top list /, hirarchies separated by /).
	 *
	 * @param groupname: Name of the new group
	 * @param parent (@default "/"): Name of the parent group
	 * @throw HistManagerException
	 */
	THashList *parentgroup = FindGroup(parent);
	if(!parentgroup){
		Fatal("THistManager::CreateHistoGroup", "Parent group %s does not exist", parentgroup->GetName());
	}
	THashList *childgroup = new THashList();
	childgroup->SetName(groupname);
	parentgroup->Add(childgroup);
}

//______________________________________________________________________________
void THistManager::CreateTH1(const char *name, const char *title, int nbins, double xmin, double xmax){
	/*
	 * Create a new TH1 within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param title: Title of the histogram
	 * @param nbins: number of bins
	 * @param xmin: min. value of the range
	 * @param xmax: max. value of the range
	 * Raises fatals in case the parent group does not exist or the object is attempted to be duplicated within the group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::CreateTH1", "Parent %s does not exist", dirname.Data());
	if(parent->FindObject(hname.Data()))
		Fatal("THistManager::CreateTH1", "Object %s already exists in group %s does not exist", hname.Data(), dirname.Data());
	parent->Add(new TH1D(hname.Data(), title, nbins, xmin, xmax));
}

//______________________________________________________________________________
void THistManager::CreateTH1(const char *name, const char *title, int nbins, const double *xbins){
	/*
	 * Create a new TH1 within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param title: Title of the histogram
	 * @param nbins: number of bins
	 * @param xbins: array of bin limits
	 * Raises fatals in case the parent group does not exist or the object is attempted to be duplicated within the group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname));
	if(!parent)
		Fatal("THistManager::CreateTH1", "Parent %s does not exist", dirname.Data());
	if(parent->FindObject(hname.Data()))
		Fatal("THistManager::CreateTH1", "Object %s already exists in group %s does not exist", hname.Data(), dirname.Data());
	parent->Add(new TH1D(hname.Data(), title, nbins, xbins));
}

//______________________________________________________________________________
void THistManager::CreateTH1(const char *name, const char *title, const TArrayD &xbins){
	/*
	 * Create a new TH1 within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param title: Title of the histogram
	 * @param xbins: array of bin limits (contains also number of bins)
	 * Raises fatals in case the parent group does not exist or the object is attempted to be duplicated within the group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname));
	if(!parent)
		Fatal("THistManager::CreateTH1", "Parent %s does not exist", dirname.Data());
	if(parent->FindObject(hname.Data()))
		Fatal("THistManager::CreateTH1", "Object %s already exists in group %s does not exist", hname.Data(), dirname.Data());
	parent->Add(new TH1D(hname.Data(), title, xbins.GetSize()-1, xbins.GetArray()));
}

//______________________________________________________________________________
void THistManager::CreateTH2(const char *name, const char *title, int nbinsx, double xmin, double xmax, int nbinsy, double ymin, double ymax){
	/*
	 * Create a new TH2 within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param title: Title of the histogram
	 * @param nbinsx: number of bins in x-direction
	 * @param xmin: min. value of the range in x-direction
	 * @param xmax: max. value of the range in x-direction
	 * @param nbinsy: number of bins in y-direction
	 * @param ymin: min. value of the range in y-direction
	 * @param ymax: max. value of the range in y-direction
	 * Raises fatals in case the parent group does not exist or the object is attempted to be duplicated within the group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::CreateTH2", "Parent %s does not exist", dirname.Data());
	if(parent->FindObject(hname.Data()))
		Fatal("THistManager::CreateTH2", "Object %s already exists in group %s does not exist", hname.Data(), dirname.Data());
	parent->Add(new TH2D(hname.Data(), title, nbinsx, xmin, xmax, nbinsy, ymin, ymax));
}

//______________________________________________________________________________
void THistManager::CreateTH2(const char *name, const char *title, int nbinsx, const double *xbins, int nbinsy, const double *ybins){
	/*
	 * Create a new TH2 within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param title: Title of the histogram
	 * @param nbinsx: number of bins in x-direction
	 * @param xbins: array of bin limits in x-direction
	 * @param nbinsy: number of bins in y-direction
	 * @param ybins: array of bin limits in y-direction
	 * Raises fatals in case the parent group does not exist or the object is attempted to be duplicated within the group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::CreateTH2", "Parent %s does not exist", dirname.Data());
	if(parent->FindObject(hname.Data()))
		Fatal("THistManager::CreateTH2", "Object %s already exists in group %s does not exist", hname.Data(), dirname.Data());
	parent->Add(new TH2D(hname.Data(), title, nbinsx, xbins, nbinsy, ybins));
}

//______________________________________________________________________________
void THistManager::CreateTH2(const char *name, const char *title, const TArrayD &xbins, const TArrayD &ybins){
	/*
	 * Create a new TH2 within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param title: Title of the histogram
	 * @param xbins: array of bin limits in x-direction (contains also the number of bins)
	 * @param ybins: array of bin limits in y-direction (contains also the number of bins)
	 * Raises fatals in case the parent group does not exist or the object is attempted to be duplicated within the group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::CreateTH2", "Parent %s does not exist", dirname.Data());
	if(parent->FindObject(hname.Data()))
		Fatal("THistManager::CreateTH2", "Object %s already exists in group %s does not exist", hname.Data(), dirname.Data());
	parent->Add(new TH2D(hname.Data(), title, xbins.GetSize() - 1, xbins.GetArray(), ybins.GetSize() - 1, ybins.GetArray()));
}

//______________________________________________________________________________
void THistManager::CreateTH3(const char* name, const char* title, int nbinsx, double xmin, double xmax, int nbinsy, double ymin, double ymax, int nbinsz, double zmin, double zmax) {
	/*
	 * Create a new TH3 within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param nbinsx: number of bins in x-direction
	 * @param xmin: min. value of the range in x-direction
	 * @param xmax: max. value of the range in x-direction
	 * @param nbinsy: number of bins in y-direction
	 * @param ymin: min. value of the range in y-direction
	 * @param ymax: max. value of the range in y-direction
	 * @param nbinsz: number of bins in z-direction
	 * @param zmin: min. value of the range in z-direction
	 * @param zmax: max. value of the range in z-direction
	 * Raises fatals in case the parent group does not exist or the object is attempted to be duplicated within the group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::CreateTH3", "Parent %s does not exist", dirname.Data());
	if(parent->FindObject(hname.Data()))
		Fatal("THistManager::CreateTH3", "Object %s already exists in group %s does not exist", hname.Data(), dirname.Data());
	parent->Add(new TH3D(hname.Data(), title, nbinsx, xmin, xmax, nbinsy, ymin, ymax, nbinsz, zmin, zmax));
}

//______________________________________________________________________________
void THistManager::CreateTH3(const char* name, const char* title, int nbinsx, const double* xbins, int nbinsy, const double* ybins, int nbinsz, const double* zbins) {
	/*
	 * Create a new TH3 within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param title: Title of the histogram
	 * @param nbinsx: number of bins in x-direction
	 * @param xbins: array of bin limits in x-direction
	 * @param nbinsy: number of bins in y-direction
	 * @param ybins: array of bin limits in y-direction
	 * @param nbinsz: number of bins in z-direction
	 * @param zbins: array of bin limits in z-direction
	 * Raises fatals in case the parent group does not exist or the object is attempted to be duplicated within the group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::CreateTH3", "Parent %s does not exist", dirname.Data());
	if(parent->FindObject(hname.Data()))
		Fatal("THistManager::CreateTH3", "Object %s already exists in group %s does not exist", hname.Data(), dirname.Data());
	parent->Add(new TH3D(hname.Data(), title, nbinsx, xbins, nbinsy, ybins, nbinsz, zbins));
}

//______________________________________________________________________________
void THistManager::CreateTH3(const char* name, const char* title, const TArrayD& xbins, const TArrayD& ybins, const TArrayD& zbins) {
	/*
	 * Create a new TH3 within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param title: Title of the histogram
	 * @param xbins: array of bin limits in x-direction (contains also the number of bins)
	 * @param ybins: array of bin limits in y-direction (contains also the number of bins)
	 * @param zbins: array of bin limits in z-direction (contains also the number of bins)
	 * Raises fatals in case the parent group does not exist or the object is attempted to be duplicated within the group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::CreateTH3", "Parent %s does not exist", dirname.Data());
	if(parent->FindObject(hname.Data()))
		Fatal("THistManager::CreateTH3", "Object %s already exists in group %s does not exist", hname.Data(), dirname.Data());
	parent->Add(new TH3D(hname.Data(), title, xbins.GetSize()-1, xbins.GetArray(), ybins.GetSize()-1, ybins.GetArray(), zbins.GetSize()-1, zbins.GetArray()));
}

//______________________________________________________________________________
void THistManager::CreateTHnSparse(const char *name, const char *title, int ndim, const int *nbins, const double *min, const double *max) {
	/*
	 * Create a new THnSparse within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param title: Title of the histogram
	 * @param ndim: Number of dimensions
	 * @param nbins: Number of bins per dimension
	 * @param min: min. value of the range for each dimension
	 * @param max: max. value of the range for each dimension
	 * Raises fatals in case the parent group does not exist or the object is attempted to be duplicated within the group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::CreateTHnSparse", "Parent %s does not exist", dirname.Data());
	if(parent->FindObject(hname.Data()))
		Fatal("THistManager::CreateTHnSparse", "Object %s already exists in group %s does not exist", hname.Data(), dirname.Data());
	parent->Add(new THnSparseD(hname.Data(), title, ndim, nbins, min, max));
}

//______________________________________________________________________________
void THistManager::CreateTHnSparse(const char *name, const char *title, int ndim, const TAxis **axes) {
	/*
	 * Create a new THnSparse within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param title: Title of the histogram
	 * @param ndim: Number of dimensions
	 * @param axes: Array of pointers to TAxis for containing the axis definition for each dimension
	 * Raises fatals in case the parent group does not exist or the object is attempted to be duplicated within the group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::CreateTHnSparse", "Parent %s does not exist", dirname.Data());
	if(parent->FindObject(hname))
		Fatal("THistManager::CreateTHnSparse", "Object %s already exists in group %s does not exist", hname.Data(), dirname.Data());
	TArrayD xmin(ndim), xmax(ndim);
	TArrayI nbins(ndim);
	for(int idim = 0; idim < ndim; ++idim){
		const TAxis &myaxis = *(axes[idim]);
		nbins[idim] = myaxis.GetNbins();
		xmin[idim] = myaxis.GetXmin();
		xmax[idim] = myaxis.GetXmax();
	}
	THnSparseD *hsparse = new THnSparseD(hname.Data(), title, ndim, nbins.GetArray(), xmin.GetArray(), xmax.GetArray());
	for(int id = 0; id < ndim; ++id)
		*(hsparse->GetAxis(id)) = *(axes[id]);
	parent->Add(hsparse);
}

//______________________________________________________________________________
void THistManager::SetObject(TObject * const o, const char *group) {
	/*
	 * Set a new group into the container into the parent group
	 *
	 * @param o: the object ot be included
	 * Raises fatals in case the parent group is not found, the object is attempted to be duplicated in the group, or the type of
	 * the object is not a histogram type
	 */
	THashList *parent(FindGroup(group));
	if(!parent)
		Fatal("THistManager::SetObject", "Parent %s does not exist", strcmp(group, "/") ? group : "");
	if(parent->FindObject(o->GetName()))
		Fatal("THistManager::SetObject", "Parent %s does not exist", strcmp(group, "/") ? group : "");
	if(!(dynamic_cast<THnBase *>(o) || dynamic_cast<TH1 *>(o)))
		Fatal("THistManager::SetObject",  "Object %s is not of a histogram type",o->GetName());
	fHistos->Add(o);
}

//______________________________________________________________________________
void THistManager::FillTH1(const char *name, double x, double weight) {
	/*
	 * Fill a 1D histogram within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param x: x-coordinate
	 * @param weight (@default 1): optional weight of the entry
	 * Raises fatals in case the parent group is not found or the histogram is not found in the parent group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::FillTH1", "Parnt group %s does not exist", dirname.Data());
	TH1 *hist = dynamic_cast<TH1 *>(parent->FindObject(hname.Data()));
	if(!hist)
		Fatal("THistManager::FillTH1", "Histogram %s not found in parent group %s", hname.Data(), dirname.Data());
	hist->Fill(x, weight);
}

//______________________________________________________________________________
void THistManager::FillTH2(const char *name, double x, double y, double weight) {
	/*
	 * Fill a 2D histogram within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param x: x-coordinate
	 * @param y: y-coordinate
	 * @param weight (@default 1): optional weight of the entry
	 * Raises fatals in case the parent group is not found or the histogram is not found in the parent group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::FillTH2", "Parnt group %s does not exist", dirname.Data());
	TH2 *hist = dynamic_cast<TH2 *>(parent->FindObject(hname.Data()));
	if(!hist)
		Fatal("THistManager::FillTH2", "Histogram %s not found in parent group %s", hname.Data(), dirname.Data());
	hist->Fill(x, y, weight);
}

//______________________________________________________________________________
void THistManager::FillTH2(const char *name, double *point, double weight) {
	/*
	 * Fill a 2D histogram within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param point: coordinates of the data
	 * @param weight (@default 1): optional weight of the entry
	 * Raises fatals in case the parent group is not found or the histogram is not found in the parent group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::FillTH2", "Parnt group %s does not exist", dirname.Data());
	TH2 *hist = dynamic_cast<TH2 *>(parent->FindObject(hname.Data()));
	if(!hist)
		Fatal("THistManager::FillTH2", "Histogram %s not found in parent group %s", hname.Data(), dirname.Data());
	hist->Fill(point[0], point[1], weight);
}

//______________________________________________________________________________
void THistManager::FillTH3(const char* name, double x, double y, double z, double weight) {
	/*
	 * Fill a 3D histogram within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param x: x-coordinate
	 * @param y: y-coordinate
	 * @param z: z-coordinate
	 * @param weight (@default 1): optional weight of the entry
	 * Raises fatals in case the parent group is not found or the histogram is not found in the parent group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::FillTH3", "Parnt group %s does not exist", dirname.Data());
	TH3 *hist = dynamic_cast<TH3 *>(parent->FindObject(hname.Data()));
	if(!hist)
		Fatal("THistManager::FillTH3", "Histogram %s not found in parent group %s", hname.Data(), dirname.Data());
	hist->Fill(x, y, z, weight);
}

//______________________________________________________________________________
void THistManager::FillTH3(const char* name, const double* point, double weight) {
	/*
	 * Fill a 3D histogram within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param point: 3D-coordinate of the point
	 * @param weight (@default 1): optional weight of the entry
	 * Raises fatals in case the parent group is not found or the histogram is not found in the parent group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::FillTH3", "Parnt group %s does not exist", dirname.Data());
	TH3 *hist = dynamic_cast<TH3 *>(parent->FindObject(hname.Data()));
	if(!hist)
		Fatal("THistManager::FillTH3", "Histogram %s not found in parent group %s", hname.Data(), dirname.Data());
	hist->Fill(point[0], point[1], point[2], weight);
}


//______________________________________________________________________________
void THistManager::FillTHnSparse(const char *name, const double *x, double weight) {
	/*
	 * Fill a  nD histogram within the container. The histogram name also contains the parent group(s) according to the common
	 * group notation.
	 *
	 * @param name: Name of the histogram
	 * @param x: coordinates of the data
	 * @param weight (@default 1): optional weight of the entry
	 * Raises fatals in case the parent group is not found or the histogram is not found in the parent group
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent)
		Fatal("THistManager::FillTH3", "Parnt group %s does not exist", dirname.Data());
	THnSparseD *hist = dynamic_cast<THnSparseD *>(parent->FindObject(hname.Data()));
	if(!hist)
		Fatal("THistManager::FillTH3", "Histogram %s not found in parent group %s", hname.Data(), dirname.Data());
	hist->Fill(x, weight);
}

//______________________________________________________________________________
TObject *THistManager::FindObject(const char *name) const {
	/*
	 * Find an object inside the container. The object can also be within a
	 * histogram group. For this the name has to follow the common notation
	 *
	 * @param name: Name of the object to find inside the container
	 * @return: pointer to the object (NULL if not found)
	 */
	TString dirname(basename(name)), hname(histname(name));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent) return NULL;
	return parent->FindObject(name);
}

//______________________________________________________________________________
TObject* THistManager::FindObject(const TObject* obj) const {
	/*
	 * Find and object inside the container. The object name is expected to contain the
	 * full path of the histogram object, including parent groups
	 *
	 * @param obj: the object to find
	 * @return: pointer to the object (NULL if not found)
	 */
	TString dirname(basename(obj->GetName())), hname(histname(obj->GetName()));
	THashList *parent(FindGroup(dirname.Data()));
	if(!parent) return NULL;
	return parent->FindObject(hname);
}

//______________________________________________________________________________
THashList *THistManager::FindGroup(const char *dirname) const {
	/*
	 * Find histogram group. Name is using common notation
	 *
	 * @param dirname: Path of the group (treat empty path as top node
	 * @return: TList of objects (NULL if group does not exist)
	 */
	if(!strlen(dirname) || !strcmp(dirname, "/")) return fHistos;
	std::vector<std::string> tokens;
	TokenizeFilename(dirname, "/", tokens);
	THashList *currentdir(fHistos);
	for(std::vector<std::string>::iterator it = tokens.begin(); it != tokens.end(); ++it){
		currentdir = dynamic_cast<THashList *>(currentdir->FindObject(it->c_str()));
		if(!currentdir) break;
	}
	return currentdir;
}

//______________________________________________________________________________
void THistManager::TokenizeFilename(const char *name, const char *delim, std::vector<std::string> &listoftokens) const {
	/*
	 * Tokenizes a string. Results are stored inside the vector listoftokens
	 *
	 * @ param name: string to be tokenised
	 * @ param delim: delimiter string
	 * @ param listoftokens: list of tokens (C++ strings)
	 */
	TString s(name);
	TObjArray *arr = s.Tokenize(delim);
	TObjString *ostr(NULL);
	TIter toks(arr);
	while((ostr = dynamic_cast<TObjString *>(toks()))){
		listoftokens.push_back(std::string(ostr->String().Data()));
	}
	delete arr;
}

//______________________________________________________________________________
const char *THistManager::basename(const char *path) const {
	/*
	 * Helper function extracting the basename from a given histogram path.
	 *
	 * @param path: histogram path
	 * @return: basename extracted
	 */
	TString s(path);
	int index = s.Last('/');
	if(index < 0) return "";  // no directory structure
	return TString(s(0, index)).Data();
}

//______________________________________________________________________________
const char *THistManager::histname(const char *path) const {
	/*
	 * Helper function extracting the histogram name from a given histogram path.
	 *
	 * @param path: histogram path
	 * @return: basename extracted
	 */
	TString s(path);
	int index = s.Last('/');
	if(index < 0) return path;    // no directory structure
	return TString(s(index+1, s.Length() - (index+1))).Data();
}
 THistManager.cxx:1
 THistManager.cxx:2
 THistManager.cxx:3
 THistManager.cxx:4
 THistManager.cxx:5
 THistManager.cxx:6
 THistManager.cxx:7
 THistManager.cxx:8
 THistManager.cxx:9
 THistManager.cxx:10
 THistManager.cxx:11
 THistManager.cxx:12
 THistManager.cxx:13
 THistManager.cxx:14
 THistManager.cxx:15
 THistManager.cxx:16
 THistManager.cxx:17
 THistManager.cxx:18
 THistManager.cxx:19
 THistManager.cxx:20
 THistManager.cxx:21
 THistManager.cxx:22
 THistManager.cxx:23
 THistManager.cxx:24
 THistManager.cxx:25
 THistManager.cxx:26
 THistManager.cxx:27
 THistManager.cxx:28
 THistManager.cxx:29
 THistManager.cxx:30
 THistManager.cxx:31
 THistManager.cxx:32
 THistManager.cxx:33
 THistManager.cxx:34
 THistManager.cxx:35
 THistManager.cxx:36
 THistManager.cxx:37
 THistManager.cxx:38
 THistManager.cxx:39
 THistManager.cxx:40
 THistManager.cxx:41
 THistManager.cxx:42
 THistManager.cxx:43
 THistManager.cxx:44
 THistManager.cxx:45
 THistManager.cxx:46
 THistManager.cxx:47
 THistManager.cxx:48
 THistManager.cxx:49
 THistManager.cxx:50
 THistManager.cxx:51
 THistManager.cxx:52
 THistManager.cxx:53
 THistManager.cxx:54
 THistManager.cxx:55
 THistManager.cxx:56
 THistManager.cxx:57
 THistManager.cxx:58
 THistManager.cxx:59
 THistManager.cxx:60
 THistManager.cxx:61
 THistManager.cxx:62
 THistManager.cxx:63
 THistManager.cxx:64
 THistManager.cxx:65
 THistManager.cxx:66
 THistManager.cxx:67
 THistManager.cxx:68
 THistManager.cxx:69
 THistManager.cxx:70
 THistManager.cxx:71
 THistManager.cxx:72
 THistManager.cxx:73
 THistManager.cxx:74
 THistManager.cxx:75
 THistManager.cxx:76
 THistManager.cxx:77
 THistManager.cxx:78
 THistManager.cxx:79
 THistManager.cxx:80
 THistManager.cxx:81
 THistManager.cxx:82
 THistManager.cxx:83
 THistManager.cxx:84
 THistManager.cxx:85
 THistManager.cxx:86
 THistManager.cxx:87
 THistManager.cxx:88
 THistManager.cxx:89
 THistManager.cxx:90
 THistManager.cxx:91
 THistManager.cxx:92
 THistManager.cxx:93
 THistManager.cxx:94
 THistManager.cxx:95
 THistManager.cxx:96
 THistManager.cxx:97
 THistManager.cxx:98
 THistManager.cxx:99
 THistManager.cxx:100
 THistManager.cxx:101
 THistManager.cxx:102
 THistManager.cxx:103
 THistManager.cxx:104
 THistManager.cxx:105
 THistManager.cxx:106
 THistManager.cxx:107
 THistManager.cxx:108
 THistManager.cxx:109
 THistManager.cxx:110
 THistManager.cxx:111
 THistManager.cxx:112
 THistManager.cxx:113
 THistManager.cxx:114
 THistManager.cxx:115
 THistManager.cxx:116
 THistManager.cxx:117
 THistManager.cxx:118
 THistManager.cxx:119
 THistManager.cxx:120
 THistManager.cxx:121
 THistManager.cxx:122
 THistManager.cxx:123
 THistManager.cxx:124
 THistManager.cxx:125
 THistManager.cxx:126
 THistManager.cxx:127
 THistManager.cxx:128
 THistManager.cxx:129
 THistManager.cxx:130
 THistManager.cxx:131
 THistManager.cxx:132
 THistManager.cxx:133
 THistManager.cxx:134
 THistManager.cxx:135
 THistManager.cxx:136
 THistManager.cxx:137
 THistManager.cxx:138
 THistManager.cxx:139
 THistManager.cxx:140
 THistManager.cxx:141
 THistManager.cxx:142
 THistManager.cxx:143
 THistManager.cxx:144
 THistManager.cxx:145
 THistManager.cxx:146
 THistManager.cxx:147
 THistManager.cxx:148
 THistManager.cxx:149
 THistManager.cxx:150
 THistManager.cxx:151
 THistManager.cxx:152
 THistManager.cxx:153
 THistManager.cxx:154
 THistManager.cxx:155
 THistManager.cxx:156
 THistManager.cxx:157
 THistManager.cxx:158
 THistManager.cxx:159
 THistManager.cxx:160
 THistManager.cxx:161
 THistManager.cxx:162
 THistManager.cxx:163
 THistManager.cxx:164
 THistManager.cxx:165
 THistManager.cxx:166
 THistManager.cxx:167
 THistManager.cxx:168
 THistManager.cxx:169
 THistManager.cxx:170
 THistManager.cxx:171
 THistManager.cxx:172
 THistManager.cxx:173
 THistManager.cxx:174
 THistManager.cxx:175
 THistManager.cxx:176
 THistManager.cxx:177
 THistManager.cxx:178
 THistManager.cxx:179
 THistManager.cxx:180
 THistManager.cxx:181
 THistManager.cxx:182
 THistManager.cxx:183
 THistManager.cxx:184
 THistManager.cxx:185
 THistManager.cxx:186
 THistManager.cxx:187
 THistManager.cxx:188
 THistManager.cxx:189
 THistManager.cxx:190
 THistManager.cxx:191
 THistManager.cxx:192
 THistManager.cxx:193
 THistManager.cxx:194
 THistManager.cxx:195
 THistManager.cxx:196
 THistManager.cxx:197
 THistManager.cxx:198
 THistManager.cxx:199
 THistManager.cxx:200
 THistManager.cxx:201
 THistManager.cxx:202
 THistManager.cxx:203
 THistManager.cxx:204
 THistManager.cxx:205
 THistManager.cxx:206
 THistManager.cxx:207
 THistManager.cxx:208
 THistManager.cxx:209
 THistManager.cxx:210
 THistManager.cxx:211
 THistManager.cxx:212
 THistManager.cxx:213
 THistManager.cxx:214
 THistManager.cxx:215
 THistManager.cxx:216
 THistManager.cxx:217
 THistManager.cxx:218
 THistManager.cxx:219
 THistManager.cxx:220
 THistManager.cxx:221
 THistManager.cxx:222
 THistManager.cxx:223
 THistManager.cxx:224
 THistManager.cxx:225
 THistManager.cxx:226
 THistManager.cxx:227
 THistManager.cxx:228
 THistManager.cxx:229
 THistManager.cxx:230
 THistManager.cxx:231
 THistManager.cxx:232
 THistManager.cxx:233
 THistManager.cxx:234
 THistManager.cxx:235
 THistManager.cxx:236
 THistManager.cxx:237
 THistManager.cxx:238
 THistManager.cxx:239
 THistManager.cxx:240
 THistManager.cxx:241
 THistManager.cxx:242
 THistManager.cxx:243
 THistManager.cxx:244
 THistManager.cxx:245
 THistManager.cxx:246
 THistManager.cxx:247
 THistManager.cxx:248
 THistManager.cxx:249
 THistManager.cxx:250
 THistManager.cxx:251
 THistManager.cxx:252
 THistManager.cxx:253
 THistManager.cxx:254
 THistManager.cxx:255
 THistManager.cxx:256
 THistManager.cxx:257
 THistManager.cxx:258
 THistManager.cxx:259
 THistManager.cxx:260
 THistManager.cxx:261
 THistManager.cxx:262
 THistManager.cxx:263
 THistManager.cxx:264
 THistManager.cxx:265
 THistManager.cxx:266
 THistManager.cxx:267
 THistManager.cxx:268
 THistManager.cxx:269
 THistManager.cxx:270
 THistManager.cxx:271
 THistManager.cxx:272
 THistManager.cxx:273
 THistManager.cxx:274
 THistManager.cxx:275
 THistManager.cxx:276
 THistManager.cxx:277
 THistManager.cxx:278
 THistManager.cxx:279
 THistManager.cxx:280
 THistManager.cxx:281
 THistManager.cxx:282
 THistManager.cxx:283
 THistManager.cxx:284
 THistManager.cxx:285
 THistManager.cxx:286
 THistManager.cxx:287
 THistManager.cxx:288
 THistManager.cxx:289
 THistManager.cxx:290
 THistManager.cxx:291
 THistManager.cxx:292
 THistManager.cxx:293
 THistManager.cxx:294
 THistManager.cxx:295
 THistManager.cxx:296
 THistManager.cxx:297
 THistManager.cxx:298
 THistManager.cxx:299
 THistManager.cxx:300
 THistManager.cxx:301
 THistManager.cxx:302
 THistManager.cxx:303
 THistManager.cxx:304
 THistManager.cxx:305
 THistManager.cxx:306
 THistManager.cxx:307
 THistManager.cxx:308
 THistManager.cxx:309
 THistManager.cxx:310
 THistManager.cxx:311
 THistManager.cxx:312
 THistManager.cxx:313
 THistManager.cxx:314
 THistManager.cxx:315
 THistManager.cxx:316
 THistManager.cxx:317
 THistManager.cxx:318
 THistManager.cxx:319
 THistManager.cxx:320
 THistManager.cxx:321
 THistManager.cxx:322
 THistManager.cxx:323
 THistManager.cxx:324
 THistManager.cxx:325
 THistManager.cxx:326
 THistManager.cxx:327
 THistManager.cxx:328
 THistManager.cxx:329
 THistManager.cxx:330
 THistManager.cxx:331
 THistManager.cxx:332
 THistManager.cxx:333
 THistManager.cxx:334
 THistManager.cxx:335
 THistManager.cxx:336
 THistManager.cxx:337
 THistManager.cxx:338
 THistManager.cxx:339
 THistManager.cxx:340
 THistManager.cxx:341
 THistManager.cxx:342
 THistManager.cxx:343
 THistManager.cxx:344
 THistManager.cxx:345
 THistManager.cxx:346
 THistManager.cxx:347
 THistManager.cxx:348
 THistManager.cxx:349
 THistManager.cxx:350
 THistManager.cxx:351
 THistManager.cxx:352
 THistManager.cxx:353
 THistManager.cxx:354
 THistManager.cxx:355
 THistManager.cxx:356
 THistManager.cxx:357
 THistManager.cxx:358
 THistManager.cxx:359
 THistManager.cxx:360
 THistManager.cxx:361
 THistManager.cxx:362
 THistManager.cxx:363
 THistManager.cxx:364
 THistManager.cxx:365
 THistManager.cxx:366
 THistManager.cxx:367
 THistManager.cxx:368
 THistManager.cxx:369
 THistManager.cxx:370
 THistManager.cxx:371
 THistManager.cxx:372
 THistManager.cxx:373
 THistManager.cxx:374
 THistManager.cxx:375
 THistManager.cxx:376
 THistManager.cxx:377
 THistManager.cxx:378
 THistManager.cxx:379
 THistManager.cxx:380
 THistManager.cxx:381
 THistManager.cxx:382
 THistManager.cxx:383
 THistManager.cxx:384
 THistManager.cxx:385
 THistManager.cxx:386
 THistManager.cxx:387
 THistManager.cxx:388
 THistManager.cxx:389
 THistManager.cxx:390
 THistManager.cxx:391
 THistManager.cxx:392
 THistManager.cxx:393
 THistManager.cxx:394
 THistManager.cxx:395
 THistManager.cxx:396
 THistManager.cxx:397
 THistManager.cxx:398
 THistManager.cxx:399
 THistManager.cxx:400
 THistManager.cxx:401
 THistManager.cxx:402
 THistManager.cxx:403
 THistManager.cxx:404
 THistManager.cxx:405
 THistManager.cxx:406
 THistManager.cxx:407
 THistManager.cxx:408
 THistManager.cxx:409
 THistManager.cxx:410
 THistManager.cxx:411
 THistManager.cxx:412
 THistManager.cxx:413
 THistManager.cxx:414
 THistManager.cxx:415
 THistManager.cxx:416
 THistManager.cxx:417
 THistManager.cxx:418
 THistManager.cxx:419
 THistManager.cxx:420
 THistManager.cxx:421
 THistManager.cxx:422
 THistManager.cxx:423
 THistManager.cxx:424
 THistManager.cxx:425
 THistManager.cxx:426
 THistManager.cxx:427
 THistManager.cxx:428
 THistManager.cxx:429
 THistManager.cxx:430
 THistManager.cxx:431
 THistManager.cxx:432
 THistManager.cxx:433
 THistManager.cxx:434
 THistManager.cxx:435
 THistManager.cxx:436
 THistManager.cxx:437
 THistManager.cxx:438
 THistManager.cxx:439
 THistManager.cxx:440
 THistManager.cxx:441
 THistManager.cxx:442
 THistManager.cxx:443
 THistManager.cxx:444
 THistManager.cxx:445
 THistManager.cxx:446
 THistManager.cxx:447
 THistManager.cxx:448
 THistManager.cxx:449
 THistManager.cxx:450
 THistManager.cxx:451
 THistManager.cxx:452
 THistManager.cxx:453
 THistManager.cxx:454
 THistManager.cxx:455
 THistManager.cxx:456
 THistManager.cxx:457
 THistManager.cxx:458
 THistManager.cxx:459
 THistManager.cxx:460
 THistManager.cxx:461
 THistManager.cxx:462
 THistManager.cxx:463
 THistManager.cxx:464
 THistManager.cxx:465
 THistManager.cxx:466
 THistManager.cxx:467
 THistManager.cxx:468
 THistManager.cxx:469
 THistManager.cxx:470
 THistManager.cxx:471
 THistManager.cxx:472
 THistManager.cxx:473
 THistManager.cxx:474
 THistManager.cxx:475
 THistManager.cxx:476
 THistManager.cxx:477
 THistManager.cxx:478
 THistManager.cxx:479
 THistManager.cxx:480
 THistManager.cxx:481
 THistManager.cxx:482
 THistManager.cxx:483
 THistManager.cxx:484
 THistManager.cxx:485
 THistManager.cxx:486
 THistManager.cxx:487
 THistManager.cxx:488
 THistManager.cxx:489
 THistManager.cxx:490
 THistManager.cxx:491
 THistManager.cxx:492
 THistManager.cxx:493
 THistManager.cxx:494
 THistManager.cxx:495
 THistManager.cxx:496
 THistManager.cxx:497
 THistManager.cxx:498
 THistManager.cxx:499
 THistManager.cxx:500
 THistManager.cxx:501
 THistManager.cxx:502
 THistManager.cxx:503
 THistManager.cxx:504
 THistManager.cxx:505
 THistManager.cxx:506
 THistManager.cxx:507
 THistManager.cxx:508
 THistManager.cxx:509
 THistManager.cxx:510
 THistManager.cxx:511
 THistManager.cxx:512
 THistManager.cxx:513
 THistManager.cxx:514
 THistManager.cxx:515
 THistManager.cxx:516
 THistManager.cxx:517
 THistManager.cxx:518
 THistManager.cxx:519
 THistManager.cxx:520
 THistManager.cxx:521
 THistManager.cxx:522
 THistManager.cxx:523
 THistManager.cxx:524
 THistManager.cxx:525
 THistManager.cxx:526
 THistManager.cxx:527
 THistManager.cxx:528
 THistManager.cxx:529
 THistManager.cxx:530
 THistManager.cxx:531
 THistManager.cxx:532
 THistManager.cxx:533
 THistManager.cxx:534
 THistManager.cxx:535
 THistManager.cxx:536
 THistManager.cxx:537
 THistManager.cxx:538
 THistManager.cxx:539
 THistManager.cxx:540
 THistManager.cxx:541
 THistManager.cxx:542
 THistManager.cxx:543
 THistManager.cxx:544
 THistManager.cxx:545
 THistManager.cxx:546
 THistManager.cxx:547
 THistManager.cxx:548
 THistManager.cxx:549
 THistManager.cxx:550
 THistManager.cxx:551
 THistManager.cxx:552
 THistManager.cxx:553
 THistManager.cxx:554
 THistManager.cxx:555
 THistManager.cxx:556
 THistManager.cxx:557
 THistManager.cxx:558
 THistManager.cxx:559
 THistManager.cxx:560
 THistManager.cxx:561
 THistManager.cxx:562
 THistManager.cxx:563
 THistManager.cxx:564
 THistManager.cxx:565
 THistManager.cxx:566
 THistManager.cxx:567
 THistManager.cxx:568
 THistManager.cxx:569
 THistManager.cxx:570
 THistManager.cxx:571
 THistManager.cxx:572
 THistManager.cxx:573
 THistManager.cxx:574
 THistManager.cxx:575
 THistManager.cxx:576
 THistManager.cxx:577
 THistManager.cxx:578
 THistManager.cxx:579
 THistManager.cxx:580
 THistManager.cxx:581
 THistManager.cxx:582
 THistManager.cxx:583
 THistManager.cxx:584
 THistManager.cxx:585
 THistManager.cxx:586
 THistManager.cxx:587
 THistManager.cxx:588
 THistManager.cxx:589
 THistManager.cxx:590
 THistManager.cxx:591
 THistManager.cxx:592
 THistManager.cxx:593
 THistManager.cxx:594
 THistManager.cxx:595
 THistManager.cxx:596
 THistManager.cxx:597
 THistManager.cxx:598
 THistManager.cxx:599
 THistManager.cxx:600
 THistManager.cxx:601
 THistManager.cxx:602
 THistManager.cxx:603
 THistManager.cxx:604
 THistManager.cxx:605