1 #include "RooGaussian.h"
2 #include "RooChebychev.h"
3 #include "RooVoigtian.h"
4 #include "RooExponential.h"
5 #include "RooRealVar.h"
6 #include "RooFormulaVar.h"
7 #include "RooDataHist.h"
9 #include "RooGlobalFunc.h"
10 #include "RooCategory.h"
11 #include "RooSimultaneous.h"
12 #include "RooChi2Var.h"
17 #include "TProfile2D.h"
44 :
mass(
"mass",
"mass", 0., 100.,
"GeV"),
45 mean(
"mean",
"mean", 0., 100.,
"GeV"),
46 sigma(
"sigma",
"sigma", 0., 100.,
"GeV"),
47 efficiency(
"efficiency",
"efficiency", 0.5, 0.0, 1.0),
48 nSignalAll(
"nSignalAll",
"nSignalAll", 0., 1e10),
67 void setup(
double expectedMean_,
double massLow,
double massHigh,
double expectedSigma_) {
73 virtual void fit(TH1*
num, TH1* den) = 0;
78 using namespace RooFit;
79 RooPlot*
frame =
mass.frame(
Name(
name), Title(
"Failing and Passing Probe Distributions"));
80 data->plotOn(
frame, Cut(
"category==category::pass"), LineColor(kGreen), MarkerColor(kGreen));
81 data->plotOn(
frame, Cut(
"category==category::fail"), LineColor(kRed), MarkerColor(kRed));
85 data->statOn(
frame, Layout(0.70, 0.99, 0.5));
91 TH3* pass, TH3*
all,
int massDimension, TProfile2D*& eff, TProfile2D*& effChi2,
const TString&
plotName =
"") {
93 TAxis *par1Axis, *par2Axis, *massAxis;
94 int par1C, par2C, massC;
95 if (massDimension == 1) {
96 massAxis =
all->GetXaxis();
98 par1Axis =
all->GetYaxis();
99 par1C =
all->GetXaxis()->GetNbins() + 2;
100 par2Axis =
all->GetZaxis();
101 par2C = (
all->GetXaxis()->GetNbins() + 2) * (
all->GetYaxis()->GetNbins() + 2);
102 }
else if (massDimension == 2) {
103 par1Axis =
all->GetXaxis();
105 massAxis =
all->GetYaxis();
106 massC =
all->GetXaxis()->GetNbins() + 2;
107 par2Axis =
all->GetZaxis();
108 par2C = (
all->GetXaxis()->GetNbins() + 2) * (
all->GetYaxis()->GetNbins() + 2);
109 }
else if (massDimension == 3) {
110 par1Axis =
all->GetXaxis();
112 par2Axis =
all->GetYaxis();
113 par2C =
all->GetXaxis()->GetNbins() + 2;
114 massAxis =
all->GetZaxis();
115 massC = (
all->GetXaxis()->GetNbins() + 2) * (
all->GetYaxis()->GetNbins() + 2);
117 return "massDimension > 3 !, skipping...";
121 if (!par1Axis || !par2Axis)
122 return "No par1Axis or par2Axis!";
123 if (par1Axis->GetXbins()->GetSize() == 0 && par2Axis->GetXbins()->GetSize() == 0) {
124 eff =
new TProfile2D(
"efficiency",
126 par1Axis->GetNbins(),
129 par2Axis->GetNbins(),
131 par2Axis->GetXmax());
132 }
else if (par1Axis->GetXbins()->GetSize() == 0) {
133 eff =
new TProfile2D(
"efficiency",
135 par1Axis->GetNbins(),
138 par2Axis->GetNbins(),
139 par2Axis->GetXbins()->GetArray());
140 }
else if (par2Axis->GetXbins()->GetSize() == 0) {
141 eff =
new TProfile2D(
"efficiency",
143 par1Axis->GetNbins(),
144 par1Axis->GetXbins()->GetArray(),
145 par2Axis->GetNbins(),
147 par2Axis->GetXmax());
149 eff =
new TProfile2D(
"efficiency",
151 par1Axis->GetNbins(),
152 par1Axis->GetXbins()->GetArray(),
153 par2Axis->GetNbins(),
154 par2Axis->GetXbins()->GetArray());
157 eff->SetXTitle(par1Axis->GetTitle());
158 eff->SetYTitle(par2Axis->GetTitle());
159 eff->SetStats(kFALSE);
160 effChi2 = (TProfile2D*)eff->Clone(
"efficiencyChi2");
161 eff->SetZTitle(
"Efficiency");
162 eff->SetOption(
"colztexte");
163 eff->GetZaxis()->SetRangeUser(-0.001, 1.001);
164 effChi2->SetZTitle(
"Chi^2/NDF");
165 effChi2->SetOption(
"colztext");
168 TH1D* all1D = (massAxis->GetXbins()->GetSize() == 0)
169 ?
new TH1D(
"all1D",
"all1D", massAxis->GetNbins(), massAxis->GetXmin(), massAxis->GetXmax())
170 :
new TH1D(
"all1D",
"all1D", massAxis->GetNbins(), massAxis->GetXbins()->GetArray());
171 auto* pass1D = (TH1D*)all1D->Clone(
"pass1D");
174 for (
int par1 = 1;
par1 <= par1Axis->GetNbins();
par1++) {
175 for (
int par2 = 1;
par2 <= par2Axis->GetNbins();
par2++) {
176 for (
int mass = 1;
mass <= massAxis->GetNbins();
mass++) {
179 pass1D->SetBinContent(
mass, pass->GetBinContent(
index));
184 eff->SetBinEntries(
index, 1);
185 eff->SetBinError(
index,
188 effChi2->SetBinEntries(
index, 1);
200 TH2* pass, TH2*
all,
int massDimension, TProfile*& eff, TProfile*& effChi2,
const TString&
plotName =
"") {
202 TAxis *par1Axis, *massAxis;
204 if (massDimension == 1) {
205 massAxis =
all->GetXaxis();
207 par1Axis =
all->GetYaxis();
208 par1C =
all->GetXaxis()->GetNbins() + 2;
209 }
else if (massDimension == 2) {
210 par1Axis =
all->GetXaxis();
212 massAxis =
all->GetYaxis();
213 massC =
all->GetXaxis()->GetNbins() + 2;
215 return "massDimension > 2 !, skipping...";
220 return "No par1Axis!";
222 (par1Axis->GetXbins()->GetSize() == 0)
223 ?
new TProfile(
"efficiency",
"efficiency", par1Axis->GetNbins(), par1Axis->GetXmin(), par1Axis->GetXmax())
224 :
new TProfile(
"efficiency",
"efficiency", par1Axis->GetNbins(), par1Axis->GetXbins()->GetArray());
226 eff->SetXTitle(par1Axis->GetTitle());
227 eff->SetLineColor(2);
228 eff->SetLineWidth(2);
229 eff->SetMarkerStyle(20);
230 eff->SetMarkerSize(0.8);
231 eff->SetStats(kFALSE);
232 effChi2 = (TProfile*)eff->Clone(
"efficiencyChi2");
233 eff->SetYTitle(
"Efficiency");
234 eff->SetOption(
"PE");
235 eff->GetYaxis()->SetRangeUser(-0.001, 1.001);
236 effChi2->SetYTitle(
"Chi^2/NDF");
237 effChi2->SetOption(
"HIST");
240 TH1D* all1D = (massAxis->GetXbins()->GetSize() == 0)
241 ?
new TH1D(
"all1D",
"all1D", massAxis->GetNbins(), massAxis->GetXmin(), massAxis->GetXmax())
242 :
new TH1D(
"all1D",
"all1D", massAxis->GetNbins(), massAxis->GetXbins()->GetArray());
243 auto* pass1D = (TH1D*)all1D->Clone(
"pass1D");
246 for (
int par1 = 1;
par1 <= par1Axis->GetNbins();
par1++) {
247 for (
int mass = 1;
mass <= massAxis->GetNbins();
mass++) {
250 pass1D->SetBinContent(
mass, pass->GetBinContent(
index));
255 eff->SetBinEntries(
index, 1);
258 effChi2->SetBinEntries(
index, 1);
284 slopeFail(
"slopeFail",
"slopeFail", 0., -1., 1.),
285 linearFail(
"linearFail",
"linearFail",
mass, slopeFail),
286 slopePass(
"slopePass",
"slopePass", 0., -1., 1.),
287 linearPass(
"linearPass",
"linearPass",
mass, slopePass),
290 simPdf.addPdf(pdfFail,
"fail");
291 simPdf.addPdf(pdfPass,
"pass");
296 using namespace RooFit;
301 data =
new RooDataHist(
"data",
"data",
mass, Index(
category), Import(
"fail", *fail), Import(
"pass", *pass));
302 if (pass->Integral() + fail->Integral() < 5) {
310 efficiency.setVal(pass->Integral() / (pass->Integral() + fail->Integral()));
311 nSignalAll.setVal(0.5 * (fail->Integral() + pass->Integral()));
314 slopeFail.setVal(0.);
315 slopePass.setVal(0.);
319 simPdf.fitTo(*
data,
Verbose(kFALSE), PrintLevel(-1), Warnings(kFALSE), PrintEvalErrors(-1));
321 RooDataHist dataFail(
"fail",
"fail",
mass, fail);
322 RooDataHist dataPass(
"pass",
"pass",
mass, pass);
323 chi2 = (RooChi2Var(
"chi2Fail",
"chi2Fail", pdfFail, dataFail, DataError(RooAbsData::Poisson)).getVal() +
324 RooChi2Var(
"chi2Pass",
"chi2Pass", pdfPass, dataPass, DataError(RooAbsData::Poisson)).getVal()) /
325 (2 * pass->GetNbinsX() - 8);
348 width(
"width",
"width", 2.5,
"GeV"),
350 slopeFail(
"slopeFail",
"slopeFail", 0., -1., 0.),
351 exponentialFail(
"linearFail",
"linearFail",
mass, slopeFail),
352 slopePass(
"slopePass",
"slopePass", 0., -1., 0.),
353 exponentialPass(
"linearPass",
"linearPass",
mass, slopePass),
358 width.setConstant(kTRUE);
359 simPdf.addPdf(pdfFail,
"fail");
360 simPdf.addPdf(pdfPass,
"pass");
364 void setup(
double expectedMean_,
double massLow,
double massHigh,
double expectedSigma_,
double width_) {
369 width.setVal(width_);
372 using namespace RooFit;
377 data =
new RooDataHist(
"data",
"data",
mass, Index(
category), Import(
"fail", *fail), Import(
"pass", *pass));
378 if (pass->Integral() + fail->Integral() < 5) {
386 efficiency.setVal(pass->Integral() / (pass->Integral() + fail->Integral()));
387 nSignalAll.setVal(0.5 * (fail->Integral() + pass->Integral()));
390 slopeFail.setVal(0.);
391 slopePass.setVal(0.);
395 simPdf.fitTo(*
data,
Verbose(kFALSE), PrintLevel(-1), Warnings(kFALSE), PrintEvalErrors(-1));
397 RooDataHist dataFail(
"fail",
"fail",
mass, fail);
398 RooDataHist dataPass(
"pass",
"pass",
mass, pass);
399 chi2 = (RooChi2Var(
"chi2Fail",
"chi2Fail", pdfFail, dataFail, DataError(RooAbsData::Poisson)).getVal() +
400 RooChi2Var(
"chi2Pass",
"chi2Pass", pdfPass, dataPass, DataError(RooAbsData::Poisson)).getVal()) /
401 (2 *
all->GetNbinsX() - 8);