#ifndef HEP_HepDataMCPlot
#include <HepDataMCPlot.h>
#endif
#include <HepTemplate.h>
#include <TList.h>
#include <TObjString.h>
#include <HepDataMCSample.h>
#include <TStyle.h>
#include <TBrowser.h>
#include <TPad.h>
#include <iostream>
#include <TObjectTable.h>
#include <TLegendEntry.h>
#include <TFeldmanCousins.h>
#include <TFractionFitter.h>
#include <TVirtualFitter.h>
#include <Fit/Fitter.h>
#include <TSystem.h>
#include <TROOT.h>
#include <TMath.h>
#include <TLatex.h>
#include <TPave.h>
#include <cmath>
#include <TLine.h>
#include <TMarker.h>
#include <TH1.h>
#include "Math/Math.h"
#include "Math/SpecFuncMathCore.h"
#include "Math/QuantFuncMathCore.h"
using namespace std;
#ifndef __CINT__
ClassImp(HepDataMCPlot);
#endif
static TFeldmanCousins fgFC(0.680);
static Double_t fgFCHigherCache[33] = {1.28,2.755,4.255,5.305,6.78,7.81,9.28,10.305,11.32,12.795,13.81,14.82,16.295,17.305,18.32,19.325,20.8,21.81,22.82,23.825,25.305,26.31,27.32,28.325,29.33,30.805,31.815,32.82,33.825,34.83,36.24,37.315,38.32};
static Double_t fgFCLowerCache[33] = {0,0.37,0.74,1.105,2.34,2.755,3.825,4.255,5.305,6.335,6.78,7.81,8.83,9.28,10.305,11.32,12.335,12.795,13.81,14.82,15.835,16.295,17.305,18.32,19.325,20.335,20.8,21.81,22.82,23.825,24.835,25.305,26.31};
HepDataMCPlot::HepDataMCPlot() {
fMCHistStack = 0;
fLegend = 0;
fLegendLarge = 0;
fXTitle = 0;
fYTitle = 0;
fMCFolders = 0;
fMCSingleSamples = 0;
fMCErrors = 0;
fMCFittedHistStack = 0;
fGraphDATA = 0;
fDrawData = kTRUE;
fDrawDataErrorX = kTRUE;
fAddRange = 1.1;
fRatioHeight = 0.4;
fRatioLine = 0;
fUseShortCMSLumiLabel = kTRUE;
fHistogramLastInStack = 0;
fFirstDraw = kTRUE;
}
HepDataMCPlot::HepDataMCPlot(const char* name, const char* title) :
TNamed(name, title) {
fHistDATA = 0;
fMCHistStack = new THStack(Form("hstack_%s", name), title);
fLegend = new TLegend(0.59, 0.42, 0.90, 0.86);
fLegendLarge = 0;
fFirstDraw = kTRUE;
fFirstLegend = kTRUE;
fXTitle = new TString;
fYTitle = new TString;
fN_MCHistograms = 0;
fMCFolders = 0;
fMCSingleSamples = 0;
fGroupHistograms = kTRUE;
fUnifyMCStack = kFALSE;
fDrawMCError = kFALSE;
fDrawNormError = kFALSE;
fDrawData = kTRUE;
fDrawDataErrorX = kTRUE;
fDrawDataZeroEntryErrors = kTRUE;
fDrawDataZeroEntries = kTRUE;
fUseOverflowUnderflow = kTRUE;
fMCErrors = 0;
fGraphDATA = 0;
fMCFitTemplates = 0;
fFitter = 0;
fMCFittedHistStack = 0;
fDrawCMSLumiAtlasLabel = kTRUE;
fUseShortCMSLumiLabel = kTRUE;
fUseAtlasStyle = kTRUE;
fAtlasLabelStatus = "Internal";
fCenterOfMassEnergyLabel = "7";
fLuminosityLabel = "4.7 fb^{-1}";
fAtlasLabelPosX = 0.56;
fAtlasLabelPosY = 0.88;
fCMSEnergyLabelPosX = 0.20;
fCMSEnergyLabelPosY = 0.79;
fLuminosityLabelPosX = 0.20;
fLuminosityLabelPosY = 0.85;
fYRangeUser = kFALSE;
fDrawDataMCRatio = kTRUE;
fDataMCRatioCenterOne = kFALSE;
fDrawSignificance = kFALSE;
fCanvas = 0;
fMainPad = 0;
fRatioPad1 = 0;
fRatioPad2 = 0;
fRatioHeight = 0.4;
fHistogramMainPad = 0;
fHistogramRatioPad1 = 0;
fHistogramRatioPad2 = 0;
fRatioLine = 0;
fHistogramLastInStack = 0;
fScaleOverlay = 1.;
fDrawSignalOverlay = kTRUE;
}
HepDataMCPlot::~HepDataMCPlot() {
if ( fMCHistStack != 0 ) {
if ( fMCHistStack->GetHists() != 0 ) fMCHistStack->GetHists()->Delete();
delete fMCHistStack;
}
if ( fLegend != 0 ) delete fLegend;
if ( fLegendLarge != 0 ) delete fLegendLarge;
if ( fXTitle != 0 ) delete fXTitle;
if ( fYTitle != 0 ) delete fYTitle;
fHistDATA = 0;
if ( fMCFolders != 0 ) {
delete fMCFolders;
}
}
void HepDataMCPlot::SetHistDATA(TH1F *h, const char* label = "Data",
Float_t lumiData = 1.) {
fHistDATA = h;
fHistDATA->SetName(Form("%s_data", h->GetName()));
fHistDATA->SetTitle(label);
fLumiDATA = lumiData;
}
void HepDataMCPlot::AddHistMC(TH1F *h, HepDataMCSample *sample) {
fMCHistStack->Add(h);
sample->SetHistogram(h);
h->SetName(Form("%s_mc%d", h->GetName(), fN_MCHistograms++));
h->SetTitle(sample->GetLabel());
h->SetLineColor(gStyle->GetHistLineColor());
h->SetLineStyle(sample->GetLineStyle());
h->SetLineWidth(sample->GetLineWidth());
h->SetFillColor(sample->GetColor());
h->SetFillStyle(sample->GetFillStyle());
fLegend->AddEntry(h, sample->GetLabel(), "F");
}
void HepDataMCPlot::AddHistMC(TH1F *h, HepDataMCFolder *folder,
HepDataMCSample *sample) {
AddHistMC(h, sample);
}
void HepDataMCPlot::Draw(Option_t *option) {
TString opt = option;
opt.ToLower();
if ( fUseAtlasStyle ) SetAtlasStyle();
if ( opt.Contains("nodata") )
fDrawData = kFALSE;
Bool_t nostack = opt.Contains("nostack");
if ( nostack || !fDrawData || fHistDATA == 0 ) {
fDrawDataMCRatio = kFALSE;
fDrawSignificance = kFALSE;
}
if ( fUseOverflowUnderflow ) {
if ( fHistDATA != 0 )
AddOverflowUnderflowBins(fHistDATA);
TH1F *h_mc = 0;
TIter next_hist(fMCHistStack->GetHists());
while ( (h_mc = (TH1F*)next_hist()) )
AddOverflowUnderflowBins(h_mc);
fMCHistStack->Modified();
}
if ( fDrawCMSLumiAtlasLabel ) fAddRange = 1.3;
SetupPad();
TH1F *h_mc = 0;
TIter next_hist(fMCHistStack->GetHists());
while ( (h_mc = (TH1F*)next_hist()) ) {
h_mc->SetXTitle("");
h_mc->SetYTitle("");
h_mc->SetLabelSize(0., "X");
}
if ( nostack ) {
DrawNoStack(opt.Data());
fDrawMCError = kFALSE;
} else {
DrawStack(opt.Data());
}
if ( fDrawDataMCRatio ) {
DrawDataMCRatio();
}
if ( fDrawSignificance ) {
DrawSignificance();
}
if ( !opt.Contains("noleg") ) {
DrawLegend();
}
fCanvas->cd();
if (fDrawCMSLumiAtlasLabel) {
fMainPad->cd();
DrawATLASLabel(fAtlasLabelPosX,
fAtlasLabelPosY,
fAtlasLabelStatus);
if ( fUseShortCMSLumiLabel ) {
DrawTextLatex(fCMSEnergyLabelPosX,
fCMSEnergyLabelPosY,
1, "#sqrt{s} = "+fCenterOfMassEnergyLabel+" TeV, "+fLuminosityLabel);
} else {
DrawTextLatex(fCMSEnergyLabelPosX,
fCMSEnergyLabelPosY,
1
,"#sqrt{s} = "+fCenterOfMassEnergyLabel+" TeV");
DrawTextLatex(fLuminosityLabelPosX,
fLuminosityLabelPosY, 1,
"#int Ldt = "+fLuminosityLabel);
}
}
SetupAxis();
fCanvas->cd();
fCanvas->Update();
if ( fFirstDraw ) fFirstDraw = kFALSE;
}
TString HepDataMCPlot::GetPathInsideFile(TDirectory *dir) {
TString path(dir->GetPath());
TObjArray *tokens = path.Tokenize(":");
if ( tokens->GetEntries() < 2 ) return "";
TString PathInsideFile = ((TObjString*)tokens->At(1))->GetString().Copy();
tokens->Delete();
return PathInsideFile;
}
void HepDataMCPlot::SetXTitle(const char* title) {
fXTitle->Remove(0);
fXTitle->Append(title);
if ( gPad != 0 ) {
TIter next(gPad->GetListOfPrimitives());
TObject *obj = 0;
while ( (obj = next()) ) {
TString objname(obj->GetName());
if ( objname.Contains(GetName()) ) {
if ( obj->InheritsFrom("THStack") ) {
((THStack*)obj)->GetXaxis()->SetTitle(title);
}
if ( obj->InheritsFrom("TH1F") ) {
((TH1F*)obj)->SetXTitle(title);
}
}
}
gPad->Modified();
gPad->Update();
}
}
void HepDataMCPlot::SetYTitle(const char* title) {
fYTitle->Remove(0);
fYTitle->Append(title);
if ( gPad != 0 ) {
TIter next(gPad->GetListOfPrimitives());
TObject *obj = 0;
while ( (obj = next()) ) {
TString objname(obj->GetName());
if ( objname.Contains(GetName()) ) {
if ( obj->InheritsFrom("THStack") ) {
((THStack*)obj)->GetYaxis()->SetTitle(title);
}
if ( obj->InheritsFrom("TH1F") ) {
((TH1F*)obj)->SetYTitle(title);
}
}
}
gPad->Modified();
gPad->Update();
}
}
void HepDataMCPlot::SetXRange(Double_t xmin, Double_t xmax) {
if ( fCanvas != 0 ) {
if ( fMainPad != 0 )
SetXRange(fMainPad, xmin, xmax);
if ( fRatioPad1 != 0 ) {
SetXRange(fRatioPad1, xmin, xmax);
if ( fRatioLine != 0 ) {
fRatioLine->SetX1(xmin);
fRatioLine->SetX2(xmax);
}
}
if ( fRatioPad2 != 0 )
SetXRange(fRatioPad2, xmin, xmax);
fCanvas->Modified();
fCanvas->Update();
}
}
void HepDataMCPlot::SetXRange(TPad *pad, Double_t xmin, Double_t xmax) {
TIter next(pad->GetListOfPrimitives());
TObject *obj = 0;
while ( (obj = next()) ) {
if ( obj->InheritsFrom("THStack") ) {
((THStack*)obj)->GetXaxis()->SetRangeUser(xmin, xmax);
}
if ( obj->InheritsFrom("TH1") ) {
((TH1*)obj)->GetXaxis()->SetRangeUser(xmin, xmax);
}
}
pad->Modified();
pad->Update();
}
void HepDataMCPlot::SetYRange(Double_t ymin, Double_t ymax) {
fYRangeUser = kTRUE;
fYRangeUserMin = ymin;
fYRangeUserMax = ymax;
}
void HepDataMCPlot::SetYRangeRatio(Double_t ymin, Double_t ymax, Int_t ratio) {
if ( ratio == 1 && fRatioPad1 != 0
&& (fDrawDataMCRatio || fDrawSignificance)) {
fHistogramRatioPad1->GetYaxis()->SetRangeUser(ymin, ymax);
fRatioPad1->Modified();
fRatioPad1->Update();
} else if ( ratio == 2 && fRatioPad2 != 0
&& (fDrawDataMCRatio && fDrawSignificance)) {
fHistogramRatioPad2->GetYaxis()->SetRangeUser(ymin, ymax);
fRatioPad2->Modified();
fRatioPad2->Update();
} else {
Error("SetYRangeRatio", "Ratio plot not available!");
}
}
void HepDataMCPlot::SetNdivisionsX(Int_t n, Bool_t optim) {
if ( gPad != 0 ) {
fMCHistStack->GetXaxis()->SetNdivisions(n, optim);
gPad->Modified();
gPad->Update();
}
}
void HepDataMCPlot::SetNdivisionsY(Int_t n, Bool_t optim) {
if ( gPad != 0 ) {
fMCHistStack->GetYaxis()->SetNdivisions(n, optim);
gPad->Modified();
gPad->Update();
}
}
void HepDataMCPlot::Browse(TBrowser *b) {
Draw(b ? b->GetDrawOption() : "");
gPad->Update();
}
void HepDataMCPlot::DrawLegend() {
TPad *padsav = (TPad*)gPad;
fMainPad->cd();
fLegend->Clear();
fLegend->SetFillColor(0);
fLegend->SetFillStyle(0);
fLegend->SetLineColor(0);
fLegend->SetBorderSize(0);
if ( (fHistDATA != 0) && fDrawData ) {
fLegend->AddEntry(fHistDATA, fHistDATA->GetTitle(), "P");
}
if ( fUnifyMCStack == kTRUE ) {
fLegend->AddEntry(fHistMCTop, "MC", "F");
} else {
TList *hists_to_draw = new TList;
hists_to_draw->AddAll(fMCHistStack->GetHists());
TH1F *h_mc = 0;
if ( fGroupHistograms == kTRUE ) {
TIter next_folder(fMCFolders, kIterBackward);
HepDataMCFolder *folder = 0;
while ( (folder = (HepDataMCFolder*)next_folder()) ) {
HepDataMCSample *sample = 0;
TIter next_sample(folder->GetMCSamples(), kIterBackward);
while ( (sample = (HepDataMCSample*)next_sample()) ) {
h_mc = sample->GetHistogram();
hists_to_draw->Remove(h_mc);
if ( sample == folder->GetMCSamples()->Last() ) {
TString label = folder->GetTitle();
if ( fDrawSignalOverlay && h_mc == fHistogramLastInStack
&& fScaleOverlay != 1. ) {
label.Append(Form(" #times %-.0f", fScaleOverlay));
}
fLegend->AddEntry(h_mc, label, "F");
}
}
}
}
TIter next_ungrouped_hist(hists_to_draw, kIterBackward);
while ( (h_mc = (TH1F*)next_ungrouped_hist()) ) {
TString label = h_mc->GetTitle();
if ( fDrawSignalOverlay && h_mc == fHistogramLastInStack
&& fScaleOverlay != 1. ) {
label.Append(Form(" #times %-.0f", fScaleOverlay));
}
fLegend->AddEntry(h_mc, label, "F");
}
delete hists_to_draw;
}
if ( fDrawMCError && fDrawNormError ) {
fLegend->AddEntry(fMCErrors, "MC + Norm. Uncertainty", "f" );
} else if ( fDrawMCError ) {
fLegend->AddEntry(fMCErrors, "MC Uncertainty", "f" );
}
if ( fFirstLegend ) {
fFirstLegend = kFALSE;
fLegend->Paint();
}
fLegend->Draw();
padsav->cd();
}
void HepDataMCPlot::DrawLegendPad() {
if ( fLegendLarge != 0 ) delete fLegendLarge;
fLegendLarge = (TLegend*)fLegend->Clone();
fLegendLarge->SetX1NDC(0.);
fLegendLarge->SetX2NDC(1.);
fLegendLarge->SetY1NDC(0.);
fLegendLarge->SetY2NDC(1.);
fLegendLarge->SetX1(0.);
fLegendLarge->SetX2(1.);
fLegendLarge->SetY1(0.);
fLegendLarge->SetY2(1.);
if ( gPad ) gPad->Clear();
fLegendLarge->Draw();
gPad->Modified();
gPad->Update();
}
void HepDataMCPlot::SetGroupHistograms(Bool_t GroupHistograms) {
fGroupHistograms = GroupHistograms;
if ( gPad ) {
Draw();
gPad->Update();
}
}
Int_t HepDataMCPlot::DistancetoPrimitive(Int_t px, Int_t py) {
const Int_t kMaxDist = 10;
Int_t dist = 99999;
TH1 *h = fMCHistStack->GetHistogram();
if ( h != 0 ) dist = h->DistancetoPrimitive(px, py);
Int_t distt = 99999;
if ( fHistDATA != 0 ) {
distt = fHistDATA->DistancetoPrimitive(px, py);
if ( distt < dist ) dist = distt;
}
h = (TH1*)fMCHistStack->GetStack()->Last();
distt = h->DistancetoPrimitive(px, py);
if ( distt < dist ) dist = distt;
if ( dist < kMaxDist ) {
gPad->SetSelected(this);
gPad->SetCursor(kPointer);
}
return dist;
}
void HepDataMCPlot::SetUnifyMCStack(Bool_t UnifyMCStack) {
SetUnifyMCStack(UnifyMCStack, kTRUE);
}
void HepDataMCPlot::SetUnifyMCStack(Bool_t UnifyMCStack, Bool_t DoRedraw) {
fUnifyMCStack = UnifyMCStack;
if ( DoRedraw == kTRUE ) {
Draw();
gPad->Update();
}
}
void HepDataMCPlot::SetDrawData(Bool_t DrawData) {
fDrawData = DrawData;
if ( gPad ) {
Draw();
gPad->Update();
}
}
void HepDataMCPlot::SetDrawDataMCRatio(Bool_t DrawDataMCRatio) {
fDrawDataMCRatio = DrawDataMCRatio;
if ( gPad ) {
Draw();
gPad->Update();
}
}
void HepDataMCPlot::SetDrawSignificance(Bool_t DrawSignificance) {
fDrawSignificance = DrawSignificance;
if ( gPad ) {
Draw();
gPad->Update();
}
}
void HepDataMCPlot::SetDataMCRatioCenterOne(Bool_t DataMCRatioCenterOne) {
fDataMCRatioCenterOne = DataMCRatioCenterOne;
if ( gPad ) {
Draw();
gPad->Update();
}
}
void HepDataMCPlot::SetDrawMCError(Bool_t DrawMCError) {
SetDrawMCError(DrawMCError, kTRUE);
}
void HepDataMCPlot::SetDrawNormError(Bool_t DrawNormError) {
fDrawNormError = DrawNormError;
}
void HepDataMCPlot::SetDrawDataZeroEntryErrors(Bool_t DrawDataZeroEntryErrors) {
fDrawDataZeroEntryErrors = DrawDataZeroEntryErrors;
if ( gPad ) {
Draw();
gPad->Update();
}
}
void HepDataMCPlot::SetDrawDataZeroEntries(Bool_t flag) {
fDrawDataZeroEntries = flag;
if ( gPad ) {
Draw();
gPad->Update();
}
}
void HepDataMCPlot::SetDrawMCError(Bool_t DrawMCError, Bool_t DoRedraw) {
fDrawMCError = DrawMCError;
if ( DoRedraw == kTRUE ) {
Draw();
gPad->Update();
}
}
void HepDataMCPlot::SetUseOverflowUnderflow(Bool_t UseOverflowUnderflow) {
fUseOverflowUnderflow = UseOverflowUnderflow;
if ( gPad ) {
Draw();
gPad->Update();
}
}
TGraphAsymmErrors* HepDataMCPlot::SetErrors(TH1F *hist,
Bool_t IsData,
Option_t *option) {
TString opt = option;
Double_t y = 0.;
Double_t ey_lo = 0.;
Double_t ey_up = 0.;
Double_t stat_ey_lo = 0.;
Double_t stat_ey_up = 0.;
Double_t norm_ey_lo = 0.;
Double_t norm_ey_up = 0.;
TGraphAsymmErrors *ErrorGraph = new TGraphAsymmErrors(hist->GetNbinsX());
for ( Int_t i = 0; i < hist->GetNbinsX(); i++ ) {
Int_t bin = i+1;
y = hist->GetBinContent(bin);
if (opt.Contains("norm")) {
y = y/hist->GetSumOfWeights();
}
ErrorGraph->SetPoint(i, hist->GetBinCenter(bin), y);
if ( IsData && !fDrawDataZeroEntries && y == 0 )
ErrorGraph->SetPoint(i, hist->GetBinCenter(bin), -9999.);
ComputeStatisticalUncertainty(hist, bin,
stat_ey_up,
stat_ey_lo);
if ( !IsData && fDrawNormError ) {
ComputeNormUncertainty(bin,
norm_ey_up,
norm_ey_lo);
}
ey_up = TMath::Sqrt(stat_ey_up*stat_ey_up + norm_ey_up*norm_ey_up);
ey_lo = TMath::Sqrt(stat_ey_lo*stat_ey_lo + norm_ey_lo*norm_ey_lo);
if (IsData && y == 0 && !fDrawDataZeroEntryErrors)
ey_up = 0;
if ( opt.Contains("norm") ) {
ey_lo = ey_lo/hist->GetSumOfWeights();
ey_up = ey_up/hist->GetSumOfWeights();
}
if (IsData && !fDrawDataErrorX ) {
ErrorGraph->SetPointError(i,
0., 0.,
ey_lo, ey_up);
} else {
ErrorGraph->SetPointError(i,
hist->GetBinWidth(bin)*0.5,
hist->GetBinWidth(bin)*0.5,
ey_lo, ey_up);
}
}
return ErrorGraph;
}
void HepDataMCPlot::ComputeStatisticalUncertainty(TH1F *h, Int_t bin,
Double_t &ey_up, Double_t &ey_lo) {
Double_t y = h->GetBinContent(bin);
if ( y < fgFeldmanCousinsMaxEntries ) {
if ( y < 0 )
y = TMath::Abs(y);
ey_up = fgFCHigherCache[(Int_t)y] - y; if(ey_up<0) ey_up = y;
ey_lo = y - fgFCLowerCache[(Int_t)y]; if(ey_lo<0) ey_lo = y;
} else {
ey_up = h->GetBinError(bin);
ey_lo = h->GetBinError(bin);
}
}
void HepDataMCPlot::ComputeNormUncertainty(Int_t bin,
Double_t &ey_up,
Double_t &ey_lo) {
TList *hists_mc = GetListOfMCTemplates("err");
TH1F *h_mc = 0;
Double_t rel_unc = 0.;
HepDataMCFolder *folder;
Double_t err2 = 0.;
for ( Int_t i = 0; i < hists_mc->GetEntries(); i++ ) {
rel_unc = 0.;
h_mc = (TH1F*) hists_mc->At(i);
if ( fMCFolders->GetEntries() > i ) {
folder = (HepDataMCFolder*) fMCFolders->At(i);
rel_unc = folder->GetNormUncertainty();
}
err2 += TMath::Power(rel_unc*h_mc->GetBinContent(bin),2);
}
ey_up = TMath::Sqrt(err2);
ey_lo = ey_up;
hists_mc->Delete();
delete hists_mc;
}
void HepDataMCPlot::PrepareFit(Bool_t single_samples, Bool_t prepare_effs) {
if(fHistDATA==0) {
Error("PrepareFit", "Plot contains no data histogram. Fit is not possible.");
gSystem->Abort(-1);
}
if(fMCFitTemplates==0) fMCFitTemplates = new TList();
Float_t eff = 0;
Float_t denom = 0;
Float_t weight = 0;
if (single_samples) {
Info("PrepareFit", "Creating templates for single samples.");
TIter next_folder(fMCFolders);
HepDataMCFolder *folder = 0;
while ( (folder = (HepDataMCFolder*)next_folder()) ) {
TIter next_sample(folder->GetMCSamples());
HepDataMCSample *sample = 0;
while ( (sample = (HepDataMCSample*)next_sample()) ) {
HepTemplate* temp = new HepTemplate();
temp->SetName(gSystem->BaseName(sample->GetName()));
temp->SetInputHistogram(sample->GetHistogram());
temp->SetColor(sample->GetColor());
if(prepare_effs) {
if(sample->GetNEvents()>0)
eff = sample->GetHistogram()->Integral()/(sample->GetNEvents()*fLumiDATA/sample->GetLumi());
else eff = 0;
temp->SetCutEfficiency(eff);
}
fMCFitTemplates->Add(temp);
Info("PrepareFit", "Added template: %s", temp->GetName());
}
}
TIter next_singlesample(fMCSingleSamples);
HepDataMCSample *single_sample = 0;
while ( (single_sample = (HepDataMCSample*)next_singlesample()) ) {
HepTemplate* temp = new HepTemplate();
temp->SetName(gSystem->BaseName(single_sample->GetName()));
temp->SetInputHistogram(single_sample->GetHistogram());
temp->SetColor(single_sample->GetColor());
if(prepare_effs) {
if(single_sample->GetNEvents()>0)
eff = single_sample->GetHistogram()->Integral()/(single_sample->GetNEvents()*fLumiDATA/single_sample->GetLumi());
else eff = 0;
temp->SetCutEfficiency(eff);
}
fMCFitTemplates->Add(temp);
Info("PrepareFit", "Added template: %s", temp->GetName());
}
}
else {
Info("PrepareFit", "Creating templates using folder structure.");
TIter next_folder(fMCFolders);
HepDataMCFolder *folder = 0;
while ( (folder = (HepDataMCFolder*)next_folder()) ) {
TIter next_sample(folder->GetMCSamples());
HepTemplate* temp = new HepTemplate();
HepDataMCSample *sample = 0;
sample = (HepDataMCSample*)next_sample();
if(sample==0) continue;
TH1F *h_folder = (TH1F*)((TH1F*)sample->GetHistogram())->Clone();
temp->SetName(folder->GetName());
temp->SetColor(folder->GetColor());
if(prepare_effs) {
eff = 0;
denom = 0;
weight = 0;
}
while ( (sample = (HepDataMCSample*)next_sample()) ) {
h_folder->Add(sample->GetHistogram());
if(prepare_effs) {
denom = denom + sample->GetHistogram()->Integral()*fLumiDATA/sample->GetLumi();
}
}
temp->SetInputHistogram(h_folder);
if(prepare_effs) {
TIter next_sample2(folder->GetMCSamples());
while ( (sample = (HepDataMCSample*)next_sample2()) ) {
weight = sample->GetHistogram()->Integral()*fLumiDATA/(sample->GetLumi()*denom);
eff = eff + weight * sample->GetHistogram()->Integral()/(sample->GetNEvents()*fLumiDATA/sample->GetLumi());
}
temp->SetCutEfficiency(eff);
}
fMCFitTemplates->Add(temp);
Info("PrepareFit", "Added template: %s", temp->GetName());
}
TIter next_singlesample(fMCSingleSamples);
HepDataMCSample *single_sample = 0;
while ( (single_sample = (HepDataMCSample*)next_singlesample()) ) {
HepTemplate* temp = new HepTemplate();
temp->SetName(gSystem->BaseName(single_sample->GetName()));
temp->SetTitle(gSystem->BaseName(single_sample->GetName()));
temp->SetInputHistogram(single_sample->GetHistogram());
temp->SetColor(single_sample->GetColor());
if(prepare_effs) {
if(single_sample->GetNEvents()>0)
eff = single_sample->GetHistogram()->Integral()/(single_sample->GetNEvents()*fLumiDATA/single_sample->GetLumi());
else eff = 0;
temp->SetCutEfficiency(eff);
}
fMCFitTemplates->Add(temp);
Info("PrepareFit", "Added template: %s",temp->GetName());
}
}
Info("PrepareFit", "Created %d template objects.",fMCFitTemplates->GetEntries());
cout << endl;
}
Int_t HepDataMCPlot::Fit() {
if(fMCFitTemplates==0) {
Info("Fit", "Empty template list. Calling PrepareFit() function.");
PrepareFit();
}
if(fMCFitTemplates->GetEntries()==0) {
Info("Fit", "Template list has 0 entries. Empty plot? Calling PrepareFit() function.");
PrepareFit();
if(fMCFitTemplates->GetEntries()==0) {
Error("Fit", "Still no templates. Assuming that plot is empty. Abort !!!");
return -1;
}
}
TObjArray *mc = new TObjArray(fMCFitTemplates->GetEntries());
HepTemplate* templ = 0;
TH1F *templ_hist = 0;
TList *templ_list = new TList();
for ( Int_t i = 0; i < fMCFitTemplates->GetEntries(); i++){
templ = (HepTemplate*)fMCFitTemplates->At(i);
templ_hist = templ->GetInputHistogram();
if(templ_hist->GetEntries()>0) {
mc->Add(templ_hist);
templ_list->Add(templ);
}
}
fFitter = new TFractionFitter(fHistDATA, mc);
#if (ROOT_VERSION_CODE < ROOT_VERSION(5,99,0))
TVirtualFitter * fVFitter = fFitter->GetFitter();
#endif
for ( Int_t i = 0; i < templ_list->GetEntries(); i++ ){
templ = (HepTemplate*)templ_list->At(i);
#if (ROOT_VERSION_CODE < ROOT_VERSION(5,99,0))
if ( templ->HasStartValue() ) {
fVFitter->SetParameter(i,templ->GetName(),templ->GetStartValue(),templ->GetStartValueError(),
templ->GetLowerBound(),templ->GetUpperBound());
}
else if ( !templ->HasStartValue() && templ->IsBound() ){
fFitter->Constrain( i ,templ->GetLowerBound(), templ->GetUpperBound());
}
#else
ROOT::Fit::ParameterSettings & par = fFitter->GetFitter()->Config().ParSettings(i);
par.SetName(templ->GetName());
if ( templ->HasStartValue() ) {
par.SetValue(templ->GetStartValue());
par.SetStepSize(templ->GetStartValueError());
}
if ( templ->IsBound() ) {
par.SetLowerLimit(templ->GetLowerBound());
par.SetUpperLimit(templ->GetUpperBound());
}
#endif
}
cout << endl;
cout << "===============================================" << endl;
Info("Fit", "Starting fit procedure !!!");
cout << "===============================================" << endl;
cout << endl;
Int_t status = fFitter->Fit();
cout << endl;
if (status == 0) {
cout << "===============================================" << endl;
Info("Fit", "Fitter converged !!!");
cout << "===============================================" << endl;
cout << endl;
Double_t fraction, error;
TH1F* result = (TH1F*)fFitter->GetPlot();
fMCFittedHistStack = new THStack(Form("%s_stacked",result->GetName()),
Form("%s (stacked)", result->GetTitle()));
TH1F* stack_hist = 0;
for (Int_t i = 0; i < templ_list->GetEntries(); ++i ) {
templ = (HepTemplate*)templ_list->At(i);
fFitter->GetResult(i, fraction, error);
templ->SetFitFraction(fraction);
templ->SetFitFractionError(error);
templ_hist = (TH1F*)fFitter->GetMCPrediction(i);
templ_hist->SetName(Form("%s_fitted", templ->GetInputHistogram()->GetName()));
templ_hist->SetTitle(Form("%s (fitted), fraction = %f, uncertainty = %f",
templ->GetInputHistogram()->GetTitle(),
fraction, error));
templ->SetFittedHistogram(templ_hist);
stack_hist = (TH1F*)templ_hist->Clone();
stack_hist->SetFillColor(templ->GetColor());
stack_hist->Scale(result->Integral()/stack_hist->Integral()*fraction);
fMCFittedHistStack->Add(stack_hist);
}
}
else {
cout << endl;
Error("Fit", "Fitter failed with status code %d !!!", status);
return status;
}
delete templ_list;
return 0;
}
void HepDataMCPlot::DrawFit(Option_t *option) {
TString opt = option;
opt.ToLower();
fHistDATA->Draw("Ep");
fMCFittedHistStack->Draw("hist,same");
fHistDATA->Draw("Epsame");
if ( !opt.Contains("noleg") ) {
DrawLegend();
}
}
void HepDataMCPlot::ListFolders() {
cout << endl;
Info("ListFolders", "Listing names of HepDataMCFolder objects:");
for(Int_t i = 0; i < fMCFolders->GetEntries(); i++) {
Info("ListFolders", "%s", gSystem->BaseName(fMCFolders->At(i)->GetName()));
}
cout << endl;
}
void HepDataMCPlot::ListSingleSamples() {
cout << endl;
Info("ListSingleSamples", "Listing names of HepDataMCSample single sample objects:");
for(Int_t i = 0; i < fMCSingleSamples->GetEntries(); i++) {
Info("ListSingleSamples", "%s", gSystem->BaseName(fMCSingleSamples->At(i)->GetName()));
}
cout << endl;
}
void HepDataMCPlot::ListTemplateFractions() {
cout << endl;
Info("ListTemplateFractions", "Listing fractions and errors of all templates:");
cout << "Template name \t\t\t\t" << " Fraction \t " << " Fraction error" << endl;
cout << "----------------------------------------------------------------------------------------" << endl;
HepTemplate *templ = 0;
TString name = "";
TString tab = "";
Float_t frac = 0;
for(Int_t i = 0; i < fMCFitTemplates->GetEntries(); i++) {
templ = (HepTemplate*)fMCFitTemplates->At(i);
name = templ->GetName();
frac = templ->GetFitFraction();
if(name.Length()<9) name = Form("%s\t\t\t\t",name.Data());
else if(name.Length()>8 && name.Length()<17) name = Form("%s\t\t\t",name.Data());
else if(name.Length()>16 && name.Length()<25) name = Form("%s\t\t",name.Data());
else if(name.Length()>24 && name.Length()<33) name = Form("%s\t",name.Data());
if(frac==0) tab = " \t\t ";
else tab = " \t ";
cout << name << " \t " << frac
<< tab << templ->GetFitFractionError() << endl;
}
cout << "----------------------------------------------------------------------------------------" << endl;
cout << endl;
}
Double_t HepDataMCPlot::GetTemplateFitFraction(const char* template_name) {
HepTemplate *templ = (HepTemplate*)fMCFitTemplates->FindObject(template_name);
if(templ!=0) return templ->GetFitFraction();
else {
Error("GetTemplateFitFraction", "Could not find template with name %s.", template_name);
return -1;
}
}
Double_t HepDataMCPlot::GetTemplateFitFractionError(const char* template_name) {
HepTemplate *templ = (HepTemplate*)fMCFitTemplates->FindObject(template_name);
if(templ!=0) return templ->GetFitFractionError();
else {
Error("GetTemplateFitFractionError", "Could not find template with name %s.", template_name);
return -1;
}
}
Float_t HepDataMCPlot::GetTemplateCutEfficiency(const char* template_name) {
HepTemplate *templ = (HepTemplate*)fMCFitTemplates->FindObject(template_name);
if(templ!=0) return templ->GetCutEfficiency();
else {
Error("GetTemplateCutEfficiency", "Could not find template with name %s.", template_name);
return -1;
}
}
void HepDataMCPlot::SetTemplateBounds(const char* template_name, Double_t Lower, Double_t Upper) {
HepTemplate *templ = (HepTemplate*)fMCFitTemplates->FindObject(template_name);
if(templ!=0) templ->SetBounds(Lower, Upper);
else {
Error("SetTemplateBounds", "Could not find template with name %s.", template_name);
}
}
void HepDataMCPlot::SetTemplateStartValue(const char* template_name, Double_t frac, Double_t frac_err) {
HepTemplate *templ = (HepTemplate*)fMCFitTemplates->FindObject(template_name);
if(templ!=0) templ->SetStartValue(frac, frac_err);
else {
Error("SetTemplateStartValue", "Could not find template with name %s.", template_name);
}
}
void HepDataMCPlot::FixTemplateFraction(const char* template_name, Bool_t fix) {
HepTemplate *templ = (HepTemplate*)fMCFitTemplates->FindObject(template_name);
if(templ!=0) templ->FixFraction(fix);
else {
Error("FixTemplateFraction", "Could not find template with name %s.", template_name);
}
}
void HepDataMCPlot::Rebin(Int_t ngroup) {
TH1F *h_mc = 0;
TIter next_hist(fMCHistStack->GetHists());
while ( (h_mc = (TH1F*)next_hist()) ) {
h_mc->Rebin(ngroup);
}
TObjArray *arr = 0;
arr = fMCHistStack->GetStack();
for ( Int_t i = 0; i < arr->GetEntries(); i++ ) {
h_mc = (TH1F*)arr->At(i);
h_mc->Rebin(ngroup);
}
fMCHistStack->Modified();
if ( fHistogramLastInStack != 0 ) fHistogramLastInStack->Rebin(ngroup);
if( fHistDATA!=0 ) fHistDATA->Rebin(ngroup);
if ( gPad ) {
Draw();
gPad->Update();
}
}
void HepDataMCPlot::ScaleMCStack(Float_t scale) {
TH1F *h_mc = 0;
TIter next_hist(fMCHistStack->GetHists());
while ( (h_mc = (TH1F*)next_hist()) ) {
h_mc->Scale(scale);
}
fHistMCTop->Scale(scale);
TObjArray *arr = 0;
arr = fMCHistStack->GetStack();
for (Int_t i = 0; i < arr->GetEntries(); i++) {
h_mc = (TH1F*)arr->At(i);
h_mc->Scale(scale);
}
if ( gPad ) {
Draw();
gPad->Update();
}
}
void HepDataMCPlot::ScaleMCFolder(Float_t scale, const char* mc_folder) {
TString FolderToScale = mc_folder;
TH1F *h_mc = 0;
TIter next_folder(fMCFolders);
HepDataMCFolder *folder = 0;
while ( (folder = (HepDataMCFolder*)next_folder()) ) {
if ( !(FolderToScale.Contains(folder->GetName())) )
continue;
TIter next_sample(folder->GetMCSamples());
HepDataMCSample *sample = 0;
while ( (sample = (HepDataMCSample*)next_sample()) ) {
h_mc = sample->GetHistogram();
h_mc->Scale(scale);
}
}
fMCHistStack->Modified();
}
void HepDataMCPlot::DrawATLASLabel(Double_t x,Double_t y,
TString text,Color_t color) {
TLatex l;
l.SetNDC();
l.SetTextFont(72);
l.SetTextColor(color);
double delx = 0.;
if ( fDrawDataMCRatio && fDrawSignificance )
delx = 0.115*696*gPad->GetWh()/(737*gPad->GetWw());
else if ( fDrawDataMCRatio || fDrawSignificance )
delx = 0.115*696*gPad->GetWh()/(604*gPad->GetWw());
else
delx = 0.115*696*gPad->GetWh()/(472*gPad->GetWw());
l.DrawLatex(x,y,"ATLAS");
if (text.Data()) {
TLatex p;
p.SetNDC();
p.SetTextFont(42);
p.SetTextColor(color);
p.DrawLatex(x+delx,y,text.Data());
}
}
void HepDataMCPlot::DrawTextLatex(Double_t x,Double_t y,
Color_t color,TString text,
Double_t tsize) {
TLatex l;
l.SetNDC();
l.SetTextColor(color);
l.SetTextFont(42);
l.SetTextSize(tsize);
l.DrawLatex(x,y,text.Data());
}
void HepDataMCPlot::SetAtlasStyle(){
TStyle *AtlasStyle = gROOT->GetStyle("ATLAS");
if ( AtlasStyle == 0 ) {
Warning("SetAtlasStyle", "Could not find ATLAS Style! Using current style.\nPlease load the ATLAS Style in your .rootlogon.C!");
} else {
gROOT->SetStyle("ATLAS");
gROOT->ForceStyle();
}
}
void HepDataMCPlot::Print(Option_t *option) const {
TString opt = option;
opt.ToUpper();
cout << endl
<< "===========================" << endl
<< "Process Events " << endl
<< "===========================" << endl;
Float_t n_signal = 0.;
Float_t err2_signal = 0.;
Float_t n_totmc = 0.;
Float_t totmcerr2 = 0.;
Double_t err = 0.;
if ( opt.Contains("SPLIT") ) {
TIter next(GetMCHistStack()->GetHists(), kIterBackward);
TH1F *h_mc = 0;
Float_t n_mc = 0.;
while ( (h_mc = (TH1F*)next()) ) {
Int_t first = h_mc->GetXaxis()->GetFirst() - 1;
Int_t last = h_mc->GetXaxis()->GetLast() + 1;
n_mc = h_mc->IntegralAndError(first, last, err);
if ( opt.Contains("LATEX") ) {
printf("%-16s & %-16f & %-16f\n",
h_mc->GetTitle(),
n_mc, err);
} else {
printf("%-16s%-.f ± %-.f\n",
h_mc->GetTitle(),
n_mc, err);
}
n_totmc += n_mc;
totmcerr2 += err*err;
}
} else {
TIter next_folder(GetMCFolders(), kIterBackward);
HepDataMCFolder *folder = 0;
TH1F *h_mc = 0;
Bool_t is_first_folder = kTRUE;
while ( (folder = (HepDataMCFolder*)next_folder()) ) {
Float_t err2 = 0.;
Float_t n_mc = 0.;
TIter next_sample(folder->GetMCSamples());
HepDataMCSample *sample = 0;
while ( (sample = (HepDataMCSample*)next_sample()) ) {
h_mc = sample->GetHistogram();
Int_t first = h_mc->GetXaxis()->GetFirst() - 1;
Int_t last = h_mc->GetXaxis()->GetLast() + 1;
n_mc += h_mc->IntegralAndError(first, last, err);
err2 += err*err;
totmcerr2 += err*err;
if ( is_first_folder ){
err2_signal = err2;
n_signal = n_mc;
}
}
is_first_folder = kFALSE;
if ( opt.Contains("LATEX") ) {
printf("\\text{%-16s} & %f & %f\n",
folder->GetName(),
n_mc, TMath::Sqrt(err2));
} else {
printf("%-16s%-.f +- %-.f\n",
folder->GetName(),
n_mc, TMath::Sqrt(err2));
}
n_totmc += n_mc;
}
}
cout << "---------------------------" << endl;
if ( opt.Contains("LATEX") ) {
printf("\\text{MC total} & %f & %f\n",
n_totmc, TMath::Sqrt(totmcerr2));
} else {
printf("MC total %-.f +- %-.f\n",
n_totmc, TMath::Sqrt(totmcerr2));
}
if ( GetHistDATA() != 0 ) {
cout << "---------------------------" << endl;
Int_t first = GetHistDATA()->GetXaxis()->GetFirst() - 1;
Int_t last = GetHistDATA()->GetXaxis()->GetLast() + 1;
Double_t err = 0;
Float_t n_data = GetHistDATA()->IntegralAndError(first, last, err);
if ( opt.Contains("LATEX") ) {
printf("\\text{DATA} & %f & %f\n",
n_data, TMath::Sqrt(n_data));
} else {
printf("DATA %-.f +- %-.f\n",
n_data, TMath::Sqrt(n_data));
}
}
cout << "===========================" << endl;
if ( !opt.Contains("SPLIT") ) {
printf("S/B %1.4f\n", n_signal/(n_totmc-n_signal));
printf("S/err_B %1.4f\n", n_signal/TMath::Sqrt(totmcerr2-err2_signal));
cout << "===========================" << endl;
}
cout << endl;
}
void HepDataMCPlot::AddOverflowUnderflowBins(TH1* hist) {
Double_t underflow = hist->GetBinContent(0);
Double_t underflow_err = hist->GetBinError(0);
Double_t first = hist->GetBinContent(1);
Double_t first_err = hist->GetBinError(1);
hist->SetBinContent(0., 0.);
hist->SetBinError(0., 0.);
hist->SetBinContent(1, underflow + first);
hist->SetBinError(1, TMath::Sqrt(underflow_err*underflow_err+
first_err*first_err));
Int_t maxbin = hist->GetNbinsX();
Double_t overflow = hist->GetBinContent(maxbin+1);
Double_t overflow_err = hist->GetBinError(maxbin+1);
Double_t last = hist->GetBinContent(maxbin);
Double_t last_err = hist->GetBinError(maxbin);
hist->SetBinContent(maxbin, last + overflow);
hist->SetBinError(maxbin, TMath::Sqrt(last_err*last_err +
overflow_err*overflow_err));
hist->SetBinContent(maxbin+1, 0.);
hist->SetBinError(maxbin+1, 0.);
}
void HepDataMCPlot::DrawNoStack(Option_t *option) {
TString opt = option;
opt.ToLower();
TPad *padsav = (TPad*)gPad;
fMainPad->Draw();
fMainPad->cd();
fDrawData = kFALSE;
TList *hists_to_draw = new TList;
hists_to_draw->AddAll(fMCHistStack->GetHists());
SetColorsNoStack();
TH1F *h_mc = 0;
if ( fGroupHistograms ) {
TIter next_folder(fMCFolders);
HepDataMCFolder *folder = 0;
while ( (folder = (HepDataMCFolder*)next_folder()) ) {
TIter next_sample(folder->GetMCSamples());
HepDataMCSample *sample = 0;
TH1F *h_mcgroup = 0;
while ( (sample = (HepDataMCSample*)next_sample()) ) {
h_mc = sample->GetHistogram();
hists_to_draw->Remove(h_mc);
if ( h_mcgroup == 0 ) {
h_mcgroup = (TH1F*) h_mc->Clone();
h_mcgroup->SetLineColor(folder->GetAttFill().GetFillColor());
} else {
h_mcgroup->Add(h_mc);
}
}
hists_to_draw->Add(h_mcgroup);
}
}
TIter next_hist(hists_to_draw);
Double_t max_mc = 0.;
while ( (h_mc = (TH1F*)next_hist()) ) {
if( max_mc < h_mc->GetBinContent(h_mc->GetMaximumBin()) )
max_mc = h_mc->GetBinContent(h_mc->GetMaximumBin());
}
max_mc *= fAddRange;
next_hist.Reset();
Bool_t first = kTRUE;
while ( (h_mc = (TH1F*)next_hist()) ) {
if ( fYRangeUser ) {
max_mc = fYRangeUserMax;
h_mc->SetMinimum(fYRangeUserMin);
}
h_mc->SetMaximum(max_mc);
if ( first ) {
first = kFALSE;
if ( opt.Contains("norm") ) {
if ( h_mc->Integral() == 0 ) {
Warning("DrawNoStack",
"Integral is 0. Drawing of histogram %s not possible.",
h_mc->GetTitle());
first = kTRUE;
} else {
TH1* h_copy = h_mc->DrawNormalized("hist", 1.);
fHistogramMainPad = h_copy;
}
} else {
h_mc->Draw("hist");
fHistogramMainPad = h_mc;
}
} else {
if ( opt.Contains("norm") )
if ( h_mc->Integral() == 0 ) {
Warning("DrawNoStack",
"Integral is 0. Drawing of histogram %s not possible.",
h_mc->GetTitle());
} else {
h_mc->DrawNormalized("hist,same", 1.);
}
else
h_mc->Draw("hist,same");
}
}
delete hists_to_draw;
padsav->cd();
}
void HepDataMCPlot::SetColorsNoStack() {
TList *hists_to_draw = new TList;
hists_to_draw->AddAll(fMCHistStack->GetHists());
TIter next_folder(fMCFolders);
TH1F *h_mc = 0;
HepDataMCFolder *folder = 0;
while ( (folder = (HepDataMCFolder*)next_folder()) ) {
TIter next_sample(folder->GetMCSamples());
HepDataMCSample *sample = 0;
while ( (sample = (HepDataMCSample*)next_sample()) ) {
h_mc = sample->GetHistogram();
hists_to_draw->Remove(h_mc);
h_mc->SetFillStyle(0);
h_mc->SetLineColor(sample->GetAttFill().GetFillColor());
h_mc->SetLineWidth(gStyle->GetHistLineWidth());
h_mc->SetLineStyle(gStyle->GetHistLineStyle());
}
}
TIter next_ungrouped_hist(hists_to_draw);
while ( (h_mc = (TH1F*)next_ungrouped_hist()) ) {
h_mc->SetFillStyle(0);
h_mc->SetLineWidth(gStyle->GetHistLineWidth());
h_mc->SetLineStyle(gStyle->GetHistLineStyle());
}
delete hists_to_draw;
}
void HepDataMCPlot::ExportTemplates(TFile *f, const char* suffix) {
if ( !f->IsWritable() ) {
Error("SaveTemplates",
"File %s is not writable! Abort!",
f->GetName());
gSystem->Abort(0);
}
f->cd();
TList *hists_to_save = GetListOfMCTemplates(suffix);
TH1F *h = 0;
TIter next_hist(hists_to_save);
while ( (h = (TH1F*)next_hist()) ) {
h->SetDirectory(f);
}
if ( fHistDATA ) {
TH1F *h_data = (TH1F*) fHistDATA->Clone(Form("%s_%s",
"data",
suffix));
h_data->SetDirectory(f);
}
f->Write();
hists_to_save->Delete();
delete hists_to_save;
}
TList* HepDataMCPlot::GetListOfMCTemplates(const char* suffix) {
TList *hists_to_save = new TList;
hists_to_save->AddAll(fMCHistStack->GetHists());
TH1F *h_mc = 0;
TIter next_folder(fMCFolders);
HepDataMCFolder *folder = 0;
while ( (folder = (HepDataMCFolder*)next_folder()) ) {
TIter next_sample(folder->GetMCSamples());
HepDataMCSample *sample = 0;
TH1F *h_mcgroup = 0;
while ( (sample = (HepDataMCSample*)next_sample()) ) {
h_mc = sample->GetHistogram();
hists_to_save->Remove(h_mc);
if ( h_mcgroup == 0 )
h_mcgroup = (TH1F*) h_mc->Clone(Form("%s_%s",
folder->GetName(),
suffix));
else
h_mcgroup->Add(h_mc);
}
hists_to_save->Add(h_mcgroup);
}
return hists_to_save;
}
void HepDataMCPlot::PrintBinStatistics(Option_t *option) {
TString opt = option;
opt.ToUpper();
TList *hists = GetListOfMCTemplates("Statistics");
TH1F *bkg = (TH1F*)((TH1F*) hists->At(0))->Clone("bkg");
for ( Int_t i = 1; i < hists->GetEntries()-1; i++ ) {
bkg->Add((TH1F*)hists->At(i));
}
TH1F *sig = (TH1F*)((TH1F*) hists->At(hists->GetEntries()-1))->Clone("sig");
printf("========================================\n");
printf(" Bin Low Edge | S/B | S/sqrt(B) \n");
printf("========================================\n");
for ( Int_t bin = 1; bin <= sig->GetNbinsX(); bin++ ) {
if ( opt.Contains("LATEX") ) {
printf(" %-4.3f & %-8f & %-8f\n",
sig->GetXaxis()->GetBinLowEdge(bin),
sig->GetBinContent(bin)/bkg->GetBinContent(bin),
sig->GetBinContent(bin)/TMath::Sqrt((bkg->GetSumw2())->At(bin)));
} else {
printf(" %-4.3f | %-8f | %-8f\n",
sig->GetXaxis()->GetBinLowEdge(bin),
sig->GetBinContent(bin)/bkg->GetBinContent(bin),
sig->GetBinContent(bin)/TMath::Sqrt((bkg->GetSumw2())->At(bin)));
}
}
printf("========================================\n");
delete bkg;
delete sig;
hists->Delete();
delete hists;
}
void HepDataMCPlot::DrawStack(Option_t *option) {
TString opt = option;
opt.ToLower();
TPad *padsav = (TPad*)gPad;
fMainPad->Draw();
fMainPad->cd();
if ( fFirstDraw && fDrawSignalOverlay ) {
fHistogramLastInStack = (TH1*)fMCHistStack->GetHists()->Last();
fHistogramLastInStack->Scale(fScaleOverlay);
fMCHistStack->GetHists()->RemoveLast();
}
SetColorsStack();
Double_t max_mc = fMCHistStack->GetMaximum();
Double_t max_data = 0.;
if ( fHistDATA != 0 && fDrawData )
max_data = fHistDATA->GetMaximum();
Double_t ymax = 0.;
if ( max_mc > max_data )
ymax = max_mc;
else
ymax = max_data;
ymax *= fAddRange;
if ( fYRangeUser ) {
ymax = fYRangeUserMax;
fMCHistStack->SetMinimum(fYRangeUserMin);
if ( fHistDATA )
fHistDATA->SetMinimum(fYRangeUserMin);
}
fMCHistStack->SetMaximum(ymax);
if ( fHistDATA != 0 )
fHistDATA->SetMaximum(ymax);
if ( fUnifyMCStack ) {
fHistMCTop = (TH1F*) (fMCHistStack->GetStack()->Last())->Clone("top_last");
fHistMCTop->Draw("hist,same");
fHistMCTop->SetXTitle(fXTitle->Data());
fHistMCTop->SetYTitle(fYTitle->Data());
fHistMCTop->SetFillStyle(1001);
fHistMCTop->SetFillColor(fgUnifyColor);
fHistogramMainPad = fHistMCTop;
} else {
fMCHistStack->Draw("hist");
fMCHistStack->GetHistogram()->SetXTitle(fXTitle->Data());
fMCHistStack->GetHistogram()->SetYTitle(fYTitle->Data());
fHistogramMainPad = fMCHistStack->GetHistogram();
fHistMCTop = (TH1F*) (fMCHistStack->GetStack()->Last())->Clone("top_last");
fHistMCTop->Draw("hist,same");
fHistMCTop->SetFillStyle(0);
}
if ( fDrawSignalOverlay ) {
fHistogramLastInStack->SetFillColorAlpha(kMagenta, 0.2);
fHistogramLastInStack->SetLineColor(kMagenta);
fHistogramLastInStack->SetLineWidth(2);
fHistogramLastInStack->Draw("hist,same");
}
if ( fDrawMCError ) {
fMCErrors = SetErrors(fHistMCTop, kFALSE);
fMCErrors->SetLineColor(16);
fMCErrors->SetFillColor(16);
fMCErrors->SetFillStyle(3254);
fMCErrors->Draw("2,same");
} else {
Info("Draw",
"MC error graph was not set. No MC errors are drawn.");
}
if ( fDrawData && (fHistDATA != 0) ) {
fHistDATA->SetMarkerStyle(gStyle->GetMarkerStyle());
fGraphDATA = SetErrors(fHistDATA,kTRUE,option);
fGraphDATA->SetMarkerStyle(fHistDATA->GetMarkerStyle());
fGraphDATA->SetLineColor(fHistDATA->GetLineColor());
fGraphDATA->Draw("EP");
}
padsav->cd();
}
void HepDataMCPlot::SetColorsStack() {
TList *hists_to_draw = new TList;
hists_to_draw->AddAll(fMCHistStack->GetHists());
TIter next_folder(fMCFolders);
HepDataMCFolder *folder = 0;
TH1F *h_mc = 0;
TH1F *h_mc2 = 0;
while ( (folder = (HepDataMCFolder*)next_folder()) ) {
TIter next_sample(folder->GetMCSamples());
HepDataMCSample *sample = 0;
while ( (sample = (HepDataMCSample*)next_sample()) ) {
h_mc = sample->GetHistogram();
h_mc2 = (TH1F*)fMCHistStack->GetStack()->FindObject(h_mc->GetName());
h_mc ->SetFillStyle(1001);
h_mc ->SetFillColor(folder->GetAttFill().GetFillColor());
h_mc ->SetLineStyle(gStyle->GetHistLineStyle());
h_mc ->SetLineColor(folder->GetAttFill().GetFillColor());
h_mc ->SetLineWidth(0);
if ( h_mc2 != 0 ) {
h_mc2->SetFillStyle(1001);
h_mc2->SetFillColor(folder->GetAttFill().GetFillColor());
h_mc2->SetLineStyle(gStyle->GetHistLineStyle());
h_mc2->SetLineColor(folder->GetAttFill().GetFillColor());
h_mc2->SetLineWidth(0);
}
if ( fGroupHistograms == kTRUE ) {
hists_to_draw->Remove(h_mc);
if ( folder->GetAttFill().GetFillColor() == kWhite ) {
h_mc ->SetLineColor(kBlack);
h_mc ->SetLineWidth(1);
if ( h_mc2 != 0 ) {
h_mc2->SetLineColor(kBlack);
h_mc2->SetLineWidth(1);
}
}
} else {
if ( h_mc2 != 0 ) {
h_mc2->SetLineWidth(1);
}
}
}
}
TIter next_ungrouped_hist(hists_to_draw);
while ( (h_mc = (TH1F*)next_ungrouped_hist()) ) {
h_mc2 = (TH1F*)fMCHistStack->GetStack()->FindObject(h_mc->GetName());
h_mc ->SetFillStyle(1001);
h_mc ->SetLineColor(gStyle->GetHistLineColor());
h_mc ->SetLineStyle(gStyle->GetHistLineStyle());
h_mc ->SetLineWidth(0);
h_mc2->SetFillStyle(1001);
h_mc2->SetLineColor(gStyle->GetHistLineColor());
h_mc2->SetLineStyle(gStyle->GetHistLineStyle());
h_mc2->SetLineWidth(0);
}
delete hists_to_draw;
}
void HepDataMCPlot::SetupPad() {
Int_t NRatios = 0;
if ( fDrawDataMCRatio ) NRatios++;
if ( fDrawSignificance ) NRatios++;
if ( gPad ) {
gPad->Clear();
fCanvas = 0;
} else {
fCanvas = gROOT->MakeDefCanvas();
}
Double_t newheight = 1.;
Double_t newheight2 = 1.;
Double_t addspace = fRatioHeight - gStyle->GetPadBottomMargin() + gStyle->GetLabelSize()*0.5;
if ( NRatios == 1 ) {
newheight = (1. + addspace);
fMainPad = new TPad("MainPad", "", 0., 1.- 1./newheight, 1., 1.);
fRatioPad1 = new TPad("RatioPad1", "", 0., 0., 1., fRatioHeight/newheight);
fRatioPad1->SetBottomMargin(gStyle->GetPadBottomMargin()/fRatioHeight);
fRatioPad2 = 0;
} else if ( NRatios == 2 ) {
newheight = (1. + addspace);
newheight2 = (1. + 2.*addspace);
fMainPad = new TPad("MainPad", "", 0., 1.- 1./newheight2, 1., 1.);
fRatioPad1 = new TPad("RatioPad1", "", 0., 1.-newheight/newheight2, 1., 1.-(newheight-fRatioHeight)/newheight2);
fRatioPad1->SetBottomMargin(gStyle->GetPadBottomMargin()/fRatioHeight);
fRatioPad2 = new TPad("RatioPad1", "", 0., 0., 1., fRatioHeight/newheight2);
fRatioPad2->SetBottomMargin(gStyle->GetPadBottomMargin()/fRatioHeight);
} else {
fMainPad = new TPad("MainPad", "", 0., 0., 1., 1.);
fRatioPad1 = 0;
fRatioPad2 = 0;
}
if ( fCanvas != 0 )
fCanvas->SetWindowSize(fCanvas->GetWindowWidth(),
fCanvas->GetWindowHeight()*(1 + NRatios*addspace));
fCanvas = (TCanvas*) gPad;
}
void HepDataMCPlot::DrawDataMCRatio() {
TPad *padsav = (TPad*)gPad;
fRatioPad1->Draw();
fRatioPad1->cd();
fRatioPad1->SetGrid();
if ( fHistDATA == 0 ) {
Error("DrawDataMCRatio", "Data histogram does not exist. Abort!");
gSystem->Abort(0);
} else if ( fHistMCTop == 0 ) {
Error("DrawDataMCRatio", "Stack is not drawn. Draw stack first! Abort!");
gSystem->Abort(0);
}
TH1F *h_ratio = (TH1F*) fHistDATA->Clone("ratio");
TH1F *h_error = (TH1F*) fHistMCTop->Clone("PredictionUncertainty");
for ( Int_t bin = 1; bin <= fHistMCTop->GetNbinsX(); bin++ ) {
h_error->SetBinError(bin, fMCErrors->GetErrorY(bin-1));
if ( h_error->GetBinContent(bin) == 0 )
h_error->SetBinError(bin, 0.);
else
h_error->SetBinError(bin, h_error->GetBinError(bin)/h_error->GetBinContent(bin));
}
if ( fDataMCRatioCenterOne ) {
h_ratio->Divide(fHistMCTop);
for ( Int_t bin = 1; bin <= h_error->GetNbinsX(); bin++ )
h_error->SetBinContent(bin, 1);
} else {
h_ratio->Add(fHistMCTop, -1.);
h_ratio->Divide(fHistMCTop);
for ( Int_t bin = 1; bin <= h_error->GetNbinsX(); bin++ )
h_error->SetBinContent(bin, 0);
}
for (Int_t bin = 0; bin < h_error->GetNbinsX(); bin++) {
if ( fHistMCTop->GetBinContent(bin) == 0 ) {
h_ratio->SetBinError(bin, 0.);
} else {
h_ratio->SetBinError(bin, fHistDATA->GetBinError(bin)/fHistMCTop->GetBinContent(bin));
}
}
h_ratio->SetMarkerStyle(gStyle->GetMarkerStyle());
h_ratio->SetMarkerSize(0.8*gStyle->GetMarkerSize());
Double_t ymax = h_ratio->GetBinContent(h_ratio->GetMaximumBin());
Double_t ymin = h_ratio->GetBinContent(h_ratio->GetMinimumBin());
if ( fDataMCRatioCenterOne ) {
ymax -= 1.;
ymin -= 1.;
}
if ( ymax > 0. && ymin < 0. ) {
ymin = TMath::Abs(ymin);
} else if ( ymax < 0 && ymin < 0 ) {
ymax = TMath::Abs(ymax);
ymin = TMath::Abs(ymin);
}
Double_t yrange = ymax > ymin ? ymax*fAddRange/1.3 : ymin*fAddRange/1.3;
if ( fDataMCRatioCenterOne ) {
h_ratio->SetYTitle("Data / MC");
h_ratio->SetMaximum(1+yrange);
h_ratio->SetMinimum(1-yrange);
} else {
h_ratio->SetYTitle("Data/MC - 1");
h_ratio->SetMaximum( yrange);
h_ratio->SetMinimum(-yrange);
}
h_ratio->Draw("axis");
if ( fDataMCRatioCenterOne ) {
fRatioLine = new TLine(h_error->GetXaxis()->GetXmin(), 1.,
h_error->GetXaxis()->GetXmax(), 1.);
} else {
fRatioLine = new TLine(h_error->GetXaxis()->GetXmin(), 0.,
h_error->GetXaxis()->GetXmax(), 0.);
}
fRatioLine->SetHorizontal(kTRUE);
fRatioLine->SetLineStyle(7);
fRatioLine->SetLineColor(kBlack);
fRatioLine->Draw();
TGraphAsymmErrors *h_errorband = new TGraphAsymmErrors(h_error);
h_errorband->SetFillStyle(3254);
h_errorband->SetFillColor(16);
h_errorband->SetLineColor(16);
h_errorband->SetMarkerSize(0.);
h_errorband->Draw("5,same");
if ( fDrawDataErrorX )
h_ratio->Draw("E0 P same");
else
h_ratio->Draw("E0 P X0 same");
fHistogramRatioPad1 = h_ratio;
fRatioPad1->RedrawAxis("g");
padsav->cd();
}
void HepDataMCPlot::SetupAxis() {
if ( fDrawDataMCRatio && fDrawSignificance ) {
fHistogramRatioPad2->SetTitleSize(1./fRatioHeight*gStyle->GetTitleSize("X"), "X");
fHistogramRatioPad2->SetLabelSize(1./fRatioHeight*gStyle->GetLabelSize("X"), "X");
fHistogramRatioPad2->SetTitleSize(1./fRatioHeight*gStyle->GetTitleSize("Y"), "Y");
fHistogramRatioPad2->SetLabelSize(1./fRatioHeight*gStyle->GetLabelSize("Y"), "Y");
fHistogramRatioPad2->SetTitleFont(gStyle->GetTitleFont("X"), "X");
fHistogramRatioPad2->SetTitleFont(gStyle->GetTitleFont("Y"), "Y");
fHistogramRatioPad2->SetXTitle(fXTitle->Data());
fHistogramRatioPad2->SetTitleOffset(gStyle->GetTitleOffset("X"),"X");
fHistogramRatioPad2->SetTitleOffset(gStyle->GetTitleOffset("Y")*fRatioHeight,"Y");
fHistogramRatioPad2->GetYaxis()->SetNdivisions(505);
fHistogramRatioPad2->GetYaxis()->SetDecimals(kTRUE);
fHistogramRatioPad2->GetXaxis()->SetDecimals(kTRUE);
}
if ( fDrawDataMCRatio || fDrawSignificance ) {
if ( fDrawDataMCRatio && fDrawSignificance ) {
fHistogramRatioPad1->SetTitleSize(0., "X");
fHistogramRatioPad1->SetLabelSize(0., "X");
} else {
fHistogramRatioPad1->SetTitleSize(1./fRatioHeight*gStyle->GetTitleSize("X"), "X");
fHistogramRatioPad1->SetLabelSize(1./fRatioHeight*gStyle->GetLabelSize("X"), "X");
}
fHistogramRatioPad1->SetTitleSize(1./fRatioHeight*gStyle->GetTitleSize("Y"), "Y");
fHistogramRatioPad1->SetLabelSize(1./fRatioHeight*gStyle->GetLabelSize("Y"), "Y");
fHistogramRatioPad1->SetTitleFont(gStyle->GetTitleFont("X"), "X");
fHistogramRatioPad1->SetTitleFont(gStyle->GetTitleFont("Y"), "Y");
fHistogramRatioPad1->SetXTitle(fXTitle->Data());
fHistogramRatioPad1->SetTitleOffset(gStyle->GetTitleOffset("X"),"X");
fHistogramRatioPad1->SetTitleOffset(gStyle->GetTitleOffset("Y")*fRatioHeight,"Y");
fHistogramRatioPad1->GetYaxis()->SetNdivisions(505);
fHistogramRatioPad1->GetYaxis()->SetDecimals(kTRUE);
fHistogramRatioPad1->GetXaxis()->SetDecimals(kTRUE);
fHistogramMainPad->SetXTitle(fXTitle->Data());
fHistogramMainPad->SetYTitle(fYTitle->Data());
fHistogramMainPad->SetLabelSize(0., "X");
fHistogramMainPad->SetTitleSize(0., "X");
fHistogramMainPad->GetXaxis()->SetDecimals(kTRUE);
fHistogramMainPad->GetYaxis()->SetDecimals(kTRUE);
}
if ( !fDrawDataMCRatio && !fDrawSignificance ) {
fHistogramMainPad->SetXTitle(fXTitle->Data());
fHistogramMainPad->SetYTitle(fYTitle->Data());
fHistogramMainPad->SetLabelSize(gStyle->GetLabelSize("X"), "X");
fHistogramMainPad->SetTitleSize(gStyle->GetTitleSize("X"), "X");
}
}
void HepDataMCPlot::DrawSignificance() {
TPad *padsav = (TPad*)gPad;
if ( fDrawDataMCRatio ) {
fRatioPad2->Draw();
fRatioPad2->cd();
fRatioPad2->SetGrid();
} else {
fRatioPad1->Draw();
fRatioPad1->cd();
fRatioPad1->SetGrid();
}
if ( fHistDATA == 0 ) {
Error("DrawDataMCRatio", "Data histogram does not exist. Abort!");
gSystem->Abort(0);
} else if ( fHistMCTop == 0 ) {
Error("DrawDataMCRatio", "Stack is not drawn. Draw stack first! Abort!");
gSystem->Abort(0);
}
TH1F *h_sigma = CompareHistograms(fHistDATA, fHistMCTop);
h_sigma->SetYTitle("Significance");
h_sigma->SetFillColor(kGray);
Double_t ymax = h_sigma->GetBinContent(h_sigma->GetMaximumBin());
Double_t ymin = h_sigma->GetBinContent(h_sigma->GetMinimumBin());
if ( ymax > 0. && ymin < 0. ) {
ymin = TMath::Abs(ymin);
} else if ( ymax < 0 && ymin < 0 ) {
ymax = TMath::Abs(ymax);
ymin = TMath::Abs(ymin);
}
Double_t yrange = ymax > ymin ? ymax*fAddRange : ymin*fAddRange;
h_sigma->SetMaximum( yrange);
h_sigma->SetMinimum(-yrange);
h_sigma->Draw("hist");
if ( fDrawDataMCRatio && fDrawSignificance )
fHistogramRatioPad2 = h_sigma;
else
fHistogramRatioPad1 = h_sigma;
padsav->cd();
}
TH1F* HepDataMCPlot::CompareHistograms(TH1* hObs, TH1* hExp,
bool neglectUncertainty,
bool variableBinning,
TH1* hPull) {
if (hObs==0 || hExp==0) {
cerr << "ERROR in CompareHistograms(): invalid input" << endl;
return 0;
}
TString name=hObs->GetName();
name+="_cmp_";
name+=hExp->GetName();
int Nbins = hObs->GetNbinsX();
if (Nbins != hExp->GetNbinsX()) {
cerr << "ERROR in CompareHistograms(): different binning" << endl;
return 0;
}
TH1F* hOut = 0;
if (variableBinning) {
hOut = new TH1F(name, "",
hObs->GetXaxis()->GetNbins(),
hObs->GetXaxis()->GetXbins()->GetArray());
} else {
hOut = new TH1F(name, "",
Nbins,
hObs->GetXaxis()->GetXmin(),
hObs->GetXaxis()->GetXmax());
}
hOut->GetXaxis()->SetTitle( hObs->GetXaxis()->GetTitle() );
hOut->GetYaxis()->SetTitle("significance");
hOut->SetFillColor(2);
for (int i=1; i<=Nbins; ++i) {
unsigned nObs = (int) hObs->GetBinContent(i);
float nExp = hExp->GetBinContent(i);
float vrnc = hExp->GetBinError(i);
vrnc *= vrnc;
float zValue = 0;
float pValue = 1;
if (vrnc>0 && !neglectUncertainty) {
pValue = pValuePoissonError(nObs, nExp, vrnc);
} else {
pValue = pValuePoisson(nObs,nExp);
}
zValue = pValueToSignificance(pValue, (nObs>nExp));
if (pValue<0.5) hOut->SetBinContent(i, zValue);
if (hPull) hPull->Fill(zValue);
}
return hOut;
}
Double_t HepDataMCPlot::pja_normal_quantile(double p) {
double a[6] = {
-3.969683028665376e+01,
2.209460984245205e+02,
-2.759285104469687e+02,
1.383577518672690e+02,
-3.066479806614716e+01,
2.506628277459239e+00,
};
double b[5] = {
-5.447609879822406e+01,
1.615858368580409e+02,
-1.556989798598866e+02,
6.680131188771972e+01,
-1.328068155288572e+01,
};
double c[6] = {
-7.784894002430293e-03,
-3.223964580411365e-01,
-2.400758277161838e+00,
-2.549732539343734e+00,
4.374664141464968e+00,
2.938163982698783e+00,
};
double d[4] = {
7.784695709041462e-03,
3.224671290700398e-01,
2.445134137142996e+00,
3.754408661907416e+00,
};
double p_low = 0.02425;
double p_high = 1 - p_low;
double x=0;
if (0 < p && p < p_low) {
double q = sqrt(-2*log(p));
x = (((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) /
((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1);
}
else if (p_low <= p && p <= p_high) {
double q = p - 0.5;
double r = q*q;
x = (((((a[0]*r+a[1])*r+a[2])*r+a[3])*r+a[4])*r+a[5])*q /
(((((b[0]*r+b[1])*r+b[2])*r+b[3])*r+b[4])*r+1);
}
else if (p_high < p && p < 1) {
double q = sqrt(-2*log(1-p));
x = -(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) /
((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1);
}
return x;
}
Double_t HepDataMCPlot::pValuePoisson(unsigned nObs, double nExp) {
if (nExp==0) return 0.5;
if (nExp<0) {
cerr << "ERROR in pValuePoisson(): invalid expectation = " << nExp
<< " returning 0.5" << endl;
return 0.5;
}
if (nObs>nExp)
return ROOT::Math::inc_gamma(nObs,nExp);
else
return ROOT::Math::inc_gamma_c(nObs+1,nExp);
}
Double_t HepDataMCPlot::pValuePoissonError(unsigned nObs,
double E,
double V) {
if (E<=0 || V<=0) {
cerr << "ERROR in pValuePoissonError(): expectation and variance must be positive. "
<< "Returning 0.5" << endl;
return 0.5;
}
double B = E/V;
double A = E*B;
if (A>100) {
unsigned stop=nObs;
if (nObs>E) --stop;
double logProb = A*log(B/(1+B));
double sum=exp(logProb);
for (unsigned u=1; u<=stop; ++u) {
logProb += log((A+u-1)/(u*(1+B)));
sum += exp(logProb);
}
if (nObs>E)
return 1-sum;
else
return sum;
} else {
double p0 = pow(B/(1+B),A);
double nExp = A/B;
if (nObs>nExp) {
double pLast = p0;
double sum = p0;
for (unsigned k=1; k<=nObs-1; ++k) {
double p = pLast * (A+k-1) / (k*(1+B));
sum += p;
pLast = p;
}
return 1-sum;
} else {
double pLast = p0;
double sum = p0;
for (unsigned k=1; k<=nObs; ++k) {
double p = pLast * (A+k-1) / (k*(1+B));
sum += p;
pLast = p;
}
return sum;
}
}
}
Double_t HepDataMCPlot::pValueToSignificance(double p, bool excess) {
if (p<0 || p>1) {
cerr << "ERROR: p-value must belong to [0,1] but input value is " << p << endl;
return 0;
}
if (excess)
return pja_normal_quantile(1-p);
else
return pja_normal_quantile(p);
}
void HepDataMCPlot::OptimizeBinning(Double_t zs, Double_t zb,
Bool_t DrawStack) {
// Z(i,j) = z_{S}*#frac{n_{S}(i,j)}{N_S} + z_{B}*#frac{n_{B}(i,j)}{N_B}
// END_LATEX
// n_{S(B)}(i,j) = #text{Number of signal (bkg) events with indices between i and j}
// N_{S(B)} = #text{Number of signal (bkg) events}
// END_LATEX
const Int_t maxbins = 51;
TList *hists_mc = GetListOfMCTemplates("binning");
TH1F *h_sig = (TH1F*) hists_mc->Last();
TH1F *h_bkg = (TH1F*) ((TH1F*) hists_mc->At(0))->Clone("bkg");
for ( Int_t i = 1; i < hists_mc->GetEntries() - 1; i++ ) {
h_bkg->Add((TH1F*) hists_mc->At(i));
}
Double_t Ns = h_sig->Integral();
Double_t Nb = h_bkg->Integral();
TArrayD *bkg_sw2 = h_bkg->GetSumw2();
Double_t lowbinedges[maxbins];
Int_t binnumbers[maxbins];
for ( Int_t a = 0; a < maxbins; a++ ) { lowbinedges[a] = 0.; }
cout << "Bin | Binrange | S/B | S/sqrt(B) |" << endl;
Int_t nbins = 1;
for ( Int_t j = h_sig->GetNbinsX(); j > 0; j-- ) {
Double_t Zij = 0;
Double_t ns_ij = 0;
Double_t nb_ij = 0;
Double_t bkg_err = 0;
Int_t i = j;
for (; i > 0; i-- ) {
ns_ij += h_sig->GetBinContent(i);
nb_ij += h_bkg->GetBinContent(i);
bkg_err += bkg_sw2->At(i);
Zij = zs*ns_ij/Ns + zb*nb_ij/Nb;
if ( (Zij > 1. && sqrt(bkg_err)/Nb < 0.1)
|| i == 1 ) {
lowbinedges[nbins] = h_sig->GetXaxis()->GetBinLowEdge(i);
binnumbers[nbins] = j;
std::cout.precision(8);
nbins++;
if ( nbins == maxbins ) {
Error("OptimizeBinning",
"Maximum number of allowed bins reached. Stop.");
return;
}
break;
}
}
j = i;
}
Int_t lastbin = h_sig->GetNbinsX();
lowbinedges[0] = h_sig->GetXaxis()->GetBinLowEdge(lastbin+1);
binnumbers[nbins] = 0.;
cout << "Array[" << nbins << "] = {" ;
for ( Int_t bin = nbins-1; bin >= 0; bin-- ) {
printf("%8.8f", lowbinedges[bin]);
if ( bin > 0 ) cout << ", ";
else cout << "}" << endl;
}
if ( DrawStack ) {
THStack *stack = new THStack;
Bool_t rebinData = kTRUE;
TH1F *hdata = new TH1F("hist_data", "hist_data", nbins-1, 0., 1.);
for ( Int_t l = 0; l < hists_mc->GetEntries(); l++ ) {
TH1F *hist = new TH1F(Form("hist_%d", l), Form("hist_%d", l),
nbins-1, 0., 1.);
TH1F *h_org = (TH1F*) hists_mc->At(l);
Int_t bin = 1;
for ( Int_t m = nbins; m > 1; m-- ) {
if ( rebinData ) {
Double_t val2 = fHistDATA->Integral(binnumbers[m] + 1, binnumbers[m-1]);
hdata->SetBinContent(bin, val2);
}
Double_t val = h_org->Integral(binnumbers[m] + 1, binnumbers[m-1]);
hist->SetBinContent(bin, val);
bin++;
}
rebinData = kFALSE;
hist->SetFillColor(h_org->GetFillColor());
hist->SetLineColor(h_org->GetFillColor());
hist->SetLineWidth(1);
hist->SetFillStyle(1001);
cout << hist->Integral() << endl;
stack->Add(hist);
}
stack->Draw();
hdata->Draw("same");
}
}
void HepDataMCPlot::SetScaleOverlay(Float_t ScaleOverlay) {
fScaleOverlay = ScaleOverlay;
if ( gPad ) Draw();
}
void HepDataMCPlot::SetDrawSignalOverlay(Bool_t DrawSignalOverlay) {
fDrawSignalOverlay = DrawSignalOverlay;
if ( gPad ) Draw();
}