// <h2>Histogram tool</h2>
// <p>
// The tool allows to book and fill many histograms inside an analysis
// in a transparent and efficient way.
// </p>
// <p>
// For each tool a folder with the name of the tool is created inside
// the output file of the analysis job. The histograms can also be
// managed in subfolders simply by prepending the path in the
// hisotgram name (see the example below). The subfolders are created
// automatically if they do not exist.
// </p>
// <p>
// <h3>Example:</h3>
// MyAnalysis.h:
// <pre>
// private:
// AtlHistogramTool *fHistograms1; // List 1
// AtlHistogramTool *fHistograms2; // List 2
// ...
// </pre>
// MyAnalysis::BookHistograms():
// <pre>
//
// // Pre-tagged histograms
// fHistograms1 = new AtlHistogramTool("PreTag",
// "Pre-tagged histograms");
// AddTool(fHistograms1)
//
// // Leading lepton Pt
// fHistograms1->Add("leptons/h_lep1_Pt", "Leading Lepton Pt", 40, 0., 200.,
// "Leading lepton p_{T} [GeV]", "Events");
//
// // Leading lepton eta
// fHistograms1->Add("leptons/h_lep1_Eta", "Leading Lepton Eta",
// 50, -2.5, 2.5, "Leading lepton #eta", "Events");
//
// // Leading electron Pt
// fHistograms1->Add("leptons/el/h_el1_Pt", "Leading Electron Pt", 40, 0., 200.,
// "Leading electron p_{T} [GeV]", "Events");
// ...
//
// // b-tagged histograms
// fHistograms2 = new AtlHistogramTool("bTag",
// "b-tagged histograms");
// AddTool(fHistograms2)
//
// // Leading jet Pt
// fHistograms2->Add("jets/h_jet1_Pt", "Leading Jet Pt",
// 40, 0., 200., "Leading jet p_{T} [GeV]", "Events");
//
// // Leading jet eta
// fHistograms2->Add("jets/h_jet1_Eta", "Leading Jet Eta",
// 100, -5., 5., "Leading jet #eta", "Events");
// ...
// </pre>
//
// MyAnalysis::ProcessCut():
// <pre>
// fHistograms1->Fill("leptons/h_lep1_Pt", lep1->Pt(), w1);
// fHistograms1->Fill("leptons/h_lep1_Eta", lep1->Eta(), w1);
// fHistograms1->Fill("leptons/el/h_el1_Pt", el1->Pt(), w1);
// ...
// // Perform b-tagging
// ...
// fHistograms1->Fill("jets/h_jet1_Pt", jet1->Pt(), w2);
// fHistograms1->Fill("jets/h_jet1_Eta", jet1->Eta(), w2);
// ...
// </pre>
//
// END_HTML
#ifndef ATLAS_AtlHistogramTool
#include <AtlHistogramTool.h>
#endif
#include <AtlSelector.h>
#include <TFile.h>
#include <iostream>
using namespace std;
#ifndef __CINT__
ClassImp(AtlHistogramTool);
#endif
AtlHistogramTool::AtlHistogramTool(const char* name, const char* title) :
AtlAnalysisTool(name, title) {
fProcessMode = kIndividual;
fParentDir = 0;
fHistograms = new THashList();
}
AtlHistogramTool::~AtlHistogramTool() {
fHistograms->Delete();
delete fHistograms;
}
TH1D* AtlHistogramTool::Add(const char* hname, const char* title,
Int_t nbinsx, Double_t xlow, Double_t xup,
const char* xtitle, const char* ytitle) {
TDirectory *savdir = gDirectory;
if ( fParentDir == 0 ) {
fParent->GetOutputFile()->cd();
fParentDir = gDirectory->mkdir(GetName(), GetTitle());
}
fParentDir->cd();
TString dirname = gSystem->DirName(hname);
if ( dirname != "." ) {
MkDirWithParents(dirname.Data());
}
const char* bname = gSystem->BaseName(hname);
if ( gDirectory->FindObject(bname) != 0 ) {
Error("Add", "Histogram with given name \"%s\" exists already in the current folder. Please use a different name. Abort!", bname);
gSystem->Abort(1);
}
TH1D *h = new TH1D(bname, title, nbinsx, xlow, xup);
h->SetXTitle(xtitle);
h->SetYTitle(ytitle);
fHistograms->Add(new AtlHistObject(hname, title, h));
savdir->cd();
return h;
}
TH2D* AtlHistogramTool::Add(const char* hname, const char* title,
Int_t nbinsx, Double_t xlow, Double_t xup,
Int_t nbinsy, Double_t ylow, Double_t yup,
const char* xtitle, const char* ytitle,
const char* ztitle) {
TDirectory *savdir = gDirectory;
if ( fParentDir == 0 ) {
fParent->GetOutputFile()->cd();
fParentDir = gDirectory->mkdir(GetName(), GetTitle());
}
fParentDir->cd();
TString dirname = gSystem->DirName(hname);
if ( dirname != "." ) {
MkDirWithParents(dirname.Data());
}
const char* bname = gSystem->BaseName(hname);
if ( gDirectory->FindObject(bname) != 0 ) {
Error("Add", "Histogram with given name \"%s\" exists already in the current folder. Please use a different name. Abort!", bname);
gSystem->Abort(1);
}
TH2D *h = new TH2D(bname, title, nbinsx, xlow, xup, nbinsy, ylow, yup);
h->SetXTitle(xtitle);
h->SetYTitle(ytitle);
h->SetZTitle(ztitle);
fHistograms->Add(new AtlHistObject(hname, title, h));
savdir->cd();
return h;
}
TH2D* AtlHistogramTool::Add(const char* hname, const char* title,
Int_t nbinsx, Double_t xlow, Double_t xup,
Int_t nbinsy, const Double_t *ybins,
const char* xtitle, const char* ytitle,
const char* ztitle) {
TDirectory *savdir = gDirectory;
if ( fParentDir == 0 ) {
fParent->GetOutputFile()->cd();
fParentDir = gDirectory->mkdir(GetName(), GetTitle());
}
fParentDir->cd();
TString dirname = gSystem->DirName(hname);
if ( dirname != "." ) {
MkDirWithParents(dirname.Data());
}
const char* bname = gSystem->BaseName(hname);
if ( gDirectory->FindObject(bname) != 0 ) {
Error("Add", "Histogram with given name \"%s\" exists already in the current folder. Please use a different name. Abort!", bname);
gSystem->Abort(1);
}
TH2D *h = new TH2D(bname, title, nbinsx, xlow, xup, nbinsy, ybins);
h->SetXTitle(xtitle);
h->SetYTitle(ytitle);
h->SetZTitle(ztitle);
fHistograms->Add(new AtlHistObject(hname, title, h));
savdir->cd();
return h;
}
void AtlHistogramTool::Fill(const char* name, Double_t x, Double_t w) {
AtlHistObject *h_obj = (AtlHistObject*)fHistograms->FindObject(name);
if ( h_obj == 0 ) {
Error("Fill",
"Histogram \"%s\" not found. Check histogram name! Abort.",
name);
gSystem->Abort(1);
}
TH1D *h = (TH1D*)h_obj->GetHistogram();
h->Fill(x, w);
}
void AtlHistogramTool::Fill(const char* name, Double_t x, Double_t y,
Double_t w) {
AtlHistObject *h_obj = (AtlHistObject*)fHistograms->FindObject(name);
if ( h_obj == 0 ) {
Error("Fill",
"Histogram \"%s\" not found. Check histogram name! Abort.",
name);
gSystem->Abort(1);
}
TH2D *h = (TH2D*)h_obj->GetHistogram();
h->Fill(x, y, w);
}
TDirectory* AtlHistogramTool::MkDirWithParents(const char* dir) {
TString fulldir(dir);
TObjArray *subdirs = fulldir.Tokenize("/");
fParentDir->cd();
TIter next_dir(subdirs);
TObjString *subdir = 0;
while ( (subdir = (TObjString*)next_dir()) ) {
if ( gDirectory->FindObject(subdir->GetString().Data()) == 0 ) {
gDirectory->mkdir(subdir->GetString().Data());
if ( gDebug > 0 ) {
Info("MkDirWithParents", "Create folder %s/",
subdir->GetString().Data());
}
}
gDirectory->cd(subdir->GetString().Data());
}
delete subdirs;
delete subdir;
return gDirectory;
}
void AtlHistogramTool::Print() const {
Info("Print", "Registered analysis tool \"%s\" of type AtlHistogramTool with the following configuration:",
GetName());
cout << endl;
fParentDir->ls();
cout << endl;
}