00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <iostream>
00011
00012 #include <TROOT.h>
00013 #include <TH2D.h>
00014 #include <THStack.h>
00015 #include <TCanvas.h>
00016 #include <TLegend.h>
00017 #include <TMath.h>
00018 #include <TRandom3.h>
00019 #include <TGraphAsymmErrors.h>
00020 #include <TPostScript.h>
00021 #include <TPad.h>
00022 #include <TLine.h>
00023 #include <TDirectory.h>
00024
00025 #include "../../BAT/BCMath.h"
00026 #include "../../BAT/BCLog.h"
00027 #include "../../BAT/BCH1D.h"
00028
00029 #include "BCTemplateFitter.h"
00030
00031
00032 BCTemplateFitter::BCTemplateFitter()
00033 : BCModel()
00034 , fFlagFixNorm(false)
00035 , fFlagPhysicalLimits(true)
00036 , fUncertaintyHistogramExp(0)
00037 , fUncertaintyHistogramObsPosterior(0)
00038 , fNorm(-1)
00039 , fNBins(-1)
00040 , fXmin(1.)
00041 , fXmax(0.)
00042 {
00043 BCLog::OutWarning("Class BCTemplateFitter is depreceted and it will be removed");
00044 BCLog::OutWarning("in the future version of BAT. Use the new class BCMTF instead.");
00045 }
00046
00047
00048 BCTemplateFitter::BCTemplateFitter(const char * name)
00049 : BCModel(name)
00050 , fFlagFixNorm(false)
00051 , fFlagPhysicalLimits(true)
00052 , fUncertaintyHistogramExp(0)
00053 , fUncertaintyHistogramObsPosterior(0)
00054 , fNorm(-1)
00055 , fNBins(-1)
00056 , fXmin(1.)
00057 , fXmax(0.)
00058 {
00059 BCLog::OutWarning("Class BCTemplateFitter is depreceted and it will be removed");
00060 BCLog::OutWarning("in the future version of BAT. Use the new class BCMTF instead.");
00061 }
00062
00063
00064 BCTemplateFitter::~BCTemplateFitter()
00065 {
00066 if (fUncertaintyHistogramExp)
00067 delete fUncertaintyHistogramExp;
00068
00069 if (fUncertaintyHistogramObsPosterior)
00070 delete fUncertaintyHistogramObsPosterior;
00071 }
00072
00073
00074 double BCTemplateFitter::LogLikelihood(const std::vector<double> & parameters)
00075 {
00076 double logprob = 0.;
00077
00078
00079 FixTemplateFunctions(parameters);
00080
00081
00082 for (int ibin = 1; ibin <= fNBins; ++ibin) {
00083
00084 double nexp = Expectation(ibin, parameters);
00085
00086
00087 double ndata = fHistData.GetBinContent(ibin);
00088
00089
00090 logprob += BCMath::LogPoisson(ndata, nexp);
00091 }
00092
00093
00094 return logprob;
00095 }
00096
00097
00098 double BCTemplateFitter::Expectation(int binnumber, const std::vector<double>& parameters)
00099 {
00100
00101 double nexp = 0;
00102
00103
00104 int ntemplates = GetNTemplates();
00105
00106
00107 for (int itemp = 0; itemp < ntemplates; ++itemp) {
00108
00109
00110 int templateindex = fTemplateParIndexContainer.at(itemp);
00111
00112
00113 double efficiency = TemplateEfficiency(itemp, binnumber, parameters);
00114
00115
00116 double probability = TemplateProbability(itemp, binnumber, parameters);
00117
00118
00119 nexp += parameters.at(templateindex)
00120 * efficiency
00121 * probability;
00122 }
00123
00124
00125 if (nexp < 0) {
00126 BCLog::OutWarning("BCTemplateFitter::Expectation : Expectation value smaller than 0. Force it to be 0.");
00127 nexp = 0;
00128 }
00129
00130 return nexp;
00131 }
00132
00133
00134 double BCTemplateFitter::TemplateEfficiency(int templatenumber, int binnumber, const std::vector<double>& parameters)
00135 {
00136
00137 int nsyst = GetNSystErrors();
00138
00139
00140 int effindex = fEffParIndexContainer.at(templatenumber);
00141
00142
00143 double efficiency = fEffHistogramContainer.at(templatenumber).GetBinContent(binnumber);
00144
00145
00146 double efferr = fEffErrHistogramContainer.at(templatenumber).GetBinContent(binnumber);
00147
00148
00149
00150 efficiency += parameters.at(effindex) * efferr;
00151
00152
00153 for (int isyst = 0; isyst < nsyst; ++isyst) {
00154
00155 int systindex = fSystErrorParIndexContainer.at(isyst);
00156
00157
00158 double deff = fSystErrorHistogramContainer.at(isyst).at(templatenumber).GetBinContent(binnumber);
00159
00160
00161 efficiency += parameters.at(systindex) * deff;
00162 }
00163
00164
00165 if (efficiency < 0.)
00166 efficiency = 0.;
00167 if (efficiency > 1.)
00168 efficiency = 1.;
00169
00170
00171 return efficiency;
00172 }
00173
00174
00175 double BCTemplateFitter::TemplateProbability(int templatenumber, int binnumber, const std::vector<double>& )
00176 {
00177
00178 double probability = 0;
00179
00180
00181 int templatetype = fTemplateTypeContainer[templatenumber];
00182
00183
00184 if (templatetype == 0) {
00185 int index = GetHistogramIndex(templatenumber);
00186
00187 probability = fTemplateHistogramContainer.at(index).GetBinContent(binnumber);
00188 }
00189 else if (templatetype == 1) {
00190 double bincenter = fHistData.GetBinCenter(binnumber);
00191 int index = GetFunctionIndex(templatenumber);
00192 probability = fTemplateFunctionContainer.at(index).Eval(bincenter);
00193 }
00194
00195
00196 return probability;
00197 }
00198
00199
00200 int BCTemplateFitter::FixTemplateFunctions(const std::vector<double>& parameters)
00201 {
00202
00203 int ntemplates = GetNTemplates();
00204
00205
00206 for (int i = 0; i < ntemplates; ++i) {
00207 if (fTemplateTypeContainer.at(i) == 1) {
00208 int index = GetFunctionIndex(i);
00209 TF1* func = &(fTemplateFunctionContainer.at(index));
00210 int npar = func->GetNpar();
00211 int tempindex = GetParIndexTemplate(i);
00212 for (int i = 0; i < npar; ++i) {
00213 func->FixParameter(i, parameters.at(tempindex+2+i));
00214 }
00215 }
00216 }
00217
00218
00219 return 1;
00220 }
00221
00222 int BCTemplateFitter::SetData(const TH1D& hist)
00223 {
00224
00225 if (fHistData.Integral() > 0.) {
00226 if (CompareHistogramProperties(fHistData, hist) != 1) {
00227 BCLog::OutError("BCTemplateFitter::SetData : Data and this histogram properties are incompatible.");
00228 return 0;
00229 }
00230 }
00231
00232
00233 fNBins = hist.GetNbinsX();
00234 fXmin = (hist.GetXaxis())->GetXmin();
00235 fXmax = (hist.GetXaxis())->GetXmax();
00236 fHistData = TH1D(hist);
00237
00238
00239 for (int i = 1; i <= fNBins; ++i)
00240 fHistData.SetBinContent(i, hist.GetBinContent(i));
00241
00242
00243 fHistData.SetXTitle((hist.GetXaxis())->GetTitle());
00244 fHistData.SetYTitle((hist.GetYaxis())->GetTitle());
00245 fHistData.SetMarkerStyle(20);
00246 fHistData.SetMarkerSize(1.1);
00247 fHistData.SetStats(kFALSE);
00248
00249
00250 fNorm = hist.Integral();
00251
00252
00253 return 1;
00254 }
00255
00256
00257 int BCTemplateFitter::AddTemplate(TH1D hist, const char * name, double Nmin, double Nmax)
00258 {
00259
00260 if (hist.Integral() <= 0.) {
00261 BCLog::OutError("BCTemplateFitter::AddTemplate : Normalization is zero or less than that.");
00262 return 0;
00263 }
00264
00265
00266 if (fHistData.Integral() > 0.) {
00267 if (CompareHistogramProperties(fHistData, hist) != 1) {
00268 BCLog::OutError("BCTemplateFitter::AddTemplate : Data and template histogram properties are incompatible.");
00269 return 0;
00270 }
00271 }
00272 else {
00273 SetData( TH1D("", "", hist.GetNbinsX(), hist.GetXaxis()->GetXmin(), hist.GetXaxis()->GetXmax()) );
00274 }
00275
00276
00277 if (fFlagPhysicalLimits && Nmin < 0)
00278 Nmin = 0;
00279
00280 if (Nmin > Nmax) {
00281 BCLog::OutError("BCTemplateFitter::AddTemplate : Lower limit exceeds upper limit.");
00282 return 0;
00283 }
00284
00285
00286 int ntemplates = GetNTemplates();
00287
00288
00289 hist.SetFillColor(2 + ntemplates);
00290 hist.SetFillStyle(1001);
00291 hist.SetStats(kFALSE);
00292
00293
00294 hist.Scale(1.0 / hist.Integral());
00295
00296
00297 if (ntemplates > 0)
00298 if (!CompareHistogramProperties(fTemplateHistogramContainer.at(0), hist)) {
00299 BCLog::OutError("BCTemplateFitter::AddTemplate : Properties of template histogram is not compatible with older template histograms.");
00300 return 0;
00301 }
00302
00303
00304 TH1D histsysterror = TH1D(fHistData);
00305
00306
00307 for (int i = 1; i <= fNBins; ++i)
00308 histsysterror.SetBinContent(i, 0.);
00309
00310
00311 int parindex = GetNParameters();
00312
00313
00314 AddParameter(name, Nmin, Nmax);
00315
00316
00317 int effindex = GetNParameters();
00318
00319
00320 AddParameter(Form("Efficiency_%s", name), -5.0, 5.0);
00321
00322
00323 fTemplateHistogramContainer.push_back(hist);
00324 fHistogramIndexContainer.push_back(GetNTemplatesType(0));
00325 fFunctionIndexContainer.push_back(-1);
00326 fTemplateTypeContainer.push_back(0);
00327 fTemplateNameContainer.push_back(name);
00328 fTemplateParIndexContainer.push_back(parindex);
00329 fEffParIndexContainer.push_back(effindex);
00330
00331
00332 fEffHistogramContainer.push_back(TH1D());
00333 fEffErrHistogramContainer.push_back(TH1D());
00334 SetTemplateEfficiency(name, 1., 0.);
00335
00336
00337 SetPriorGauss(Form("Efficiency_%s", name), 0., 1.);
00338
00339
00340 for (int i = 0; i < GetNSystErrors(); ++i) {
00341 std::vector<TH1D> histvector = fSystErrorHistogramContainer.at(i);
00342 histvector.push_back(histsysterror);
00343 }
00344
00345
00346 return 1;
00347 }
00348
00349
00350 int BCTemplateFitter::AddTemplate(TF1 func, const char * name, double Nmin, double Nmax, const char* )
00351 {
00352
00353 if (fFlagPhysicalLimits && Nmin < 0)
00354 Nmin = 0;
00355
00356 if (Nmin > Nmax) {
00357 BCLog::OutError("BCTemplateFitter::AddTemplate : Lower limit exceeds upper limit.");
00358 return 0;
00359 }
00360
00361
00362 int parindex = GetNParameters();
00363
00364
00365 AddParameter(name, Nmin, Nmax);
00366
00367
00368 int effindex = GetNParameters();
00369
00370
00371 AddParameter(Form("Efficiency_%s", name), -5.0, 5.0);
00372
00373
00374 int npar = func.GetNpar();
00375
00376 for (int i = 0; i < npar; ++i) {
00377 double parmin;
00378 double parmax;
00379 func.GetParLimits(i, parmin, parmax);
00380 AddParameter(func.GetParName(i), parmin, parmax);
00381 }
00382
00383
00384
00385 fTemplateFunctionContainer.push_back(func);
00386 fHistogramIndexContainer.push_back(-1);
00387 fFunctionIndexContainer.push_back(GetNTemplatesType(1));
00388 fTemplateTypeContainer.push_back(1);
00389 fTemplateNameContainer.push_back(name);
00390 fTemplateParIndexContainer.push_back(parindex);
00391 fEffParIndexContainer.push_back(effindex);
00392
00393
00394 fEffHistogramContainer.push_back(TH1D());
00395 fEffErrHistogramContainer.push_back(TH1D());
00396 SetTemplateEfficiency(name, 1., 0.);
00397
00398
00399 SetPriorGauss(Form("Efficiency_%s", name), 0., 1.);
00400
00401
00402 return 1;
00403 }
00404
00405
00406 int BCTemplateFitter::AddSystError(const char * errorname, const char * errtype)
00407 {
00408
00409 double dx = 1.0;
00410
00411
00412 if (std::string(errtype) == std::string("gauss"))
00413 dx = 5.0;
00414 else if (std::string(errtype) == std::string("flat"))
00415 dx = 1.0;
00416 else {
00417 BCLog::OutError("BCTemplateFitter::AddSystError : Unknown error type.");
00418 return 0;
00419 }
00420
00421
00422 AddParameter(Form("%s", errorname), -dx, dx);
00423
00424
00425 SetPriorGauss(Form("%s", errorname), 0., 1.);
00426
00427
00428 fSystErrorNameContainer.push_back(errorname);
00429 fSystErrorParIndexContainer.push_back(GetNParameters()-1);
00430
00431
00432 TH1D hist = TH1D(fHistData);
00433
00434
00435 for (int i = 1; i <= fNBins; ++i)
00436 hist.SetBinContent(i, 0.);
00437
00438
00439 int n = GetNTemplates();
00440
00441
00442 std::vector<TH1D> histvector;
00443
00444
00445 for (int i = 0; i < n; ++i)
00446 histvector.push_back(hist);
00447
00448
00449 fSystErrorHistogramContainer.push_back(histvector);
00450
00451
00452 fSystErrorTypeContainer.push_back(std::string(errtype));
00453
00454
00455 return 1;
00456 }
00457
00458
00459 int BCTemplateFitter::SetTemplateSystError(const char * errorname, const char * templatename, TH1D parerror)
00460 {
00461
00462 int errindex = GetIndexSystError(errorname);
00463
00464
00465 if (errindex < 0) {
00466 BCLog::OutError("BCTemplateFitter::SetTemplateSystError : Did not find parameter.");
00467 return 0;
00468 }
00469
00470
00471 int tempindex = GetIndexTemplate(templatename);
00472
00473
00474 if (tempindex < 0) {
00475 BCLog::OutError("BCTemplateFitter::SetTemplateSystError : Could not find template.");
00476 return 0;
00477 }
00478
00479
00480 parerror.SetStats(kFALSE);
00481
00482
00483 (fSystErrorHistogramContainer.at(errindex))[tempindex] = parerror;
00484
00485
00486 return 1;
00487 }
00488
00489
00490 int BCTemplateFitter::Initialize()
00491 {
00492
00493 if (fHistData.Integral() <= 0) {
00494 BCLog::OutError("BCTemplateFitter::Initialize : Normalization of data histogram is zero or less than that.");
00495 return 0;
00496 }
00497
00498
00499
00500 double minimum = TMath::Max(0., fHistData.GetMinimum() - 5.*sqrt(fHistData.GetMinimum()));
00501 double maximum = fHistData.GetMaximum() + 5.*sqrt(fHistData.GetMaximum());
00502
00503 std::vector<double> a(fHistData.GetNbinsX()+1);
00504 for (int i = 0; i < fHistData.GetNbinsX()+1; ++i) {
00505 a[i] = fHistData.GetXaxis()->GetBinLowEdge(i+1);
00506 }
00507
00508 fUncertaintyHistogramExp = new TH2D(
00509 TString::Format("UncertaintyExp_%i", BCLog::GetHIndex()), "",
00510
00511 fHistData.GetNbinsX(), &a[0],
00512
00513 100, minimum, maximum);
00514
00515 fUncertaintyHistogramObsPosterior = new TH2D(
00516 TString::Format("UncertaintyObsPosterior_%i", BCLog::GetHIndex()), "",
00517 fHistData.GetNbinsX(), &a[0],
00518
00519 int(maximum) + 1, -0.5, double(int(maximum))+0.5);
00520
00521
00522 double xmin = 0;
00523 double xmax = 0;
00524 int ntemplates = GetNTemplates();
00525
00526
00527
00528 for (int i = 0; i < ntemplates; ++i) {
00529
00530 int parindex = fTemplateParIndexContainer.at(i);
00531 int effindex = fEffParIndexContainer.at(i);
00532
00533
00534 BCParameter * par = this->GetParameter(parindex);
00535 BCParameter * eff = this->GetParameter(effindex);
00536
00537
00538 xmin += par->GetLowerLimit() * eff->GetLowerLimit();
00539 xmax += par->GetUpperLimit() * eff->GetUpperLimit();
00540 }
00541
00542
00543 fHistNorm = TH1D("", ";N_{norm};dN/dN_{norm}", 100, xmin, xmax);
00544
00545
00546 return 1;
00547 }
00548
00549
00550 int BCTemplateFitter::CalculateRatio(int index, std::vector<int> indices, double rmin, double rmax)
00551 {
00552
00553 int ntemplates = GetNTemplates();
00554
00555
00556 if (index < 0 || index >= ntemplates) {
00557 return 0;
00558 }
00559
00560
00561 for (int i = 0; i < int(indices.size()); ++i) {
00562 if (indices.at(i) < 0 || indices.at(i) >= ntemplates) {
00563 return 0;
00564 }
00565 }
00566
00567
00568 std::vector<int> tempvec;
00569 tempvec.push_back(index);
00570 for (int i = 0; i < int(indices.size()); ++i)
00571 tempvec.push_back(indices.at(i));
00572
00573
00574 fIndicesRatios1D.push_back(tempvec);
00575
00576
00577 int nratios = int(fHistRatios1D.size());
00578
00579
00580 double fmin = rmin;
00581 double fmax = rmax;
00582 if (fFlagPhysicalLimits) {
00583 fmin = TMath::Max(rmin, 0.0);
00584 fmax = TMath::Min(1.0, rmax);
00585 }
00586
00587 TH1D hist_ratio1d(TString::Format("ratio %i", nratios), ";r;p(r|data)", 100, fmin, fmax);
00588 fHistRatios1D.push_back(hist_ratio1d);
00589
00590
00591 return 1;
00592 }
00593
00594
00595 int BCTemplateFitter::CompareHistogramProperties(TH1D hist1, TH1D hist2)
00596 {
00597
00598 if (hist1.GetNbinsX() != hist2.GetNbinsX())
00599 return 0;
00600
00601
00602 if (hist1.GetXaxis()->GetXmin() != hist2.GetXaxis()->GetXmin())
00603 return 0;
00604
00605
00606 if (hist1.GetXaxis()->GetXmax() != hist2.GetXaxis()->GetXmax())
00607 return 0;
00608
00609
00610 return 1;
00611 }
00612
00613
00614 void BCTemplateFitter::PrintStack(const char * filename, const char * options)
00615 {
00616 int nbins = fHistData.GetNbinsX();
00617 int ntemplates = GetNTemplates();
00618
00619
00620 bool flag_legend = false;
00621 bool flag_error0 = false;
00622 bool flag_error1 = false;
00623 bool flag_error2 = false;
00624 bool flag_error3 = false;
00625 bool flag_diff = false;
00626 bool flag_logx = false;
00627 bool flag_logy = false;
00628
00629 if (std::string(options).find("L") < std::string(options).size())
00630 flag_legend = true;
00631
00632 if (std::string(options).find("E0") < std::string(options).size())
00633 flag_error0 = true;
00634
00635 if (std::string(options).find("E1") < std::string(options).size())
00636 flag_error1 = true;
00637
00638 if (std::string(options).find("E2") < std::string(options).size())
00639 flag_error2 = true;
00640
00641 if (std::string(options).find("E3") < std::string(options).size())
00642 flag_error3 = true;
00643
00644 if (std::string(options).find("D") < std::string(options).size())
00645 flag_diff = true;
00646
00647 if (std::string(options).find("logx") < std::string(options).size())
00648 flag_logx = true;
00649
00650 if (std::string(options).find("logy") < std::string(options).size())
00651 flag_logy = true;
00652
00653
00654 TCanvas* c1 = new TCanvas("", "", 700, 700);
00655 c1->cd();
00656 TPad * pad1;
00657 TPad * pad2;
00658
00659 double fraction_pads = 0.3;
00660
00661 if(!flag_diff)
00662 fraction_pads=0.0;
00663
00664 if (flag_diff) {
00665 pad1 = new TPad("pad1", "", 0.0, fraction_pads, 1.0, 1.0);
00666 pad1->SetTopMargin (0.13/(1.0-fraction_pads));
00667 pad1->SetBottomMargin(0.0);
00668 pad1->SetLeftMargin (0.15);
00669 pad1->SetRightMargin (0.13);
00670 pad1->SetFillColor(kWhite);
00671 pad2 = new TPad("pad2", "", 0.0, 0.0, 1.0, fraction_pads);
00672 pad2->SetTopMargin (0.0);
00673 pad2->SetBottomMargin(0.15 / fraction_pads);
00674 pad2->SetLeftMargin (0.15);
00675 pad2->SetRightMargin (0.13);
00676 pad2->SetFillColor(kWhite);
00677 if (flag_logx) {
00678 pad1->SetLogx();
00679 pad2->SetLogx();
00680 }
00681 if (flag_logy)
00682 pad1->SetLogy();
00683 pad1->Draw();
00684 pad2->Draw();
00685 }
00686 else {
00687 pad1 = new TPad("pad1", "",0.0, 0.0, 1.0, 1.0);
00688 pad1->SetFillColor(kWhite);
00689 pad2 = new TPad();
00690 if (flag_logx)
00691 pad1->SetLogx();
00692 if (flag_logy)
00693 pad1->SetLogy();
00694 pad1->Draw();
00695 }
00696
00697 pad1->cd();
00698
00699
00700 double ymin = 0.01;
00701 double ymax = 1.1 * (fHistData.GetMaximum() + sqrt(fHistData.GetMaximum()));
00702 fHistData.GetYaxis()->SetRangeUser(ymin, ymax);
00703 fHistData.GetXaxis()->SetNdivisions(505);
00704 if (flag_diff) {
00705 fHistData.GetXaxis()->SetLabelSize(fHistData.GetXaxis()->GetLabelSize()/(1.0-fraction_pads));
00706 fHistData.GetXaxis()->SetLabelOffset(fHistData.GetXaxis()->GetLabelOffset()*(1.0-fraction_pads));
00707 fHistData.GetXaxis()->SetTitleSize(fHistData.GetXaxis()->GetTitleSize()/(1.0-fraction_pads));
00708 fHistData.GetXaxis()->SetTitleOffset(fHistData.GetXaxis()->GetTitleOffset()*(1.0-fraction_pads));
00709 fHistData.GetYaxis()->SetLabelSize(fHistData.GetYaxis()->GetLabelSize()/(1.0-fraction_pads));
00710 fHistData.GetYaxis()->SetLabelOffset(fHistData.GetYaxis()->GetLabelOffset()/(fraction_pads));
00711 fHistData.GetYaxis()->SetTitleSize(fHistData.GetYaxis()->GetTitleSize()/(1.0-fraction_pads));
00712 fHistData.GetYaxis()->SetTitleOffset(fHistData.GetYaxis()->GetTitleOffset()*(1.0-fraction_pads));
00713 }
00714 fHistData.Draw("P");
00715
00716
00717
00718 TH1D * histsum = new TH1D(fHistData);
00719
00720
00721 THStack stack("histostack","");
00722
00723
00724 TLegend* legend1;
00725 TLegend* legend2;
00726
00727 if (flag_diff)
00728 legend1 = new TLegend(0.15, (0.88-fraction_pads)/(1-fraction_pads), 0.50, 0.99);
00729 else
00730 legend1 = new TLegend(0.15, 0.88, 0.50, 0.99);
00731 legend1->SetBorderSize(0);
00732 legend1->SetFillColor(kWhite);
00733 legend1->AddEntry(&fHistData, "Data", "LEP");
00734 legend1->AddEntry(&fHistData, "Total expected uncertainty", "LE");
00735
00736 double y = 0.99;
00737 if (ntemplates > 2 && ntemplates <7)
00738 y -= 0.11 / 4. * double(ntemplates - 2);
00739 legend2 = new TLegend(0.50,(y-fraction_pads)/(1-fraction_pads) , 0.85, 0.99);
00740 legend2->SetBorderSize(0);
00741 legend2->SetFillColor(kWhite);
00742
00743
00744
00745 std::vector<TH1D*> histcontainer;
00746
00747
00748 std::vector<double> parameters = GetBestFitParameters();
00749
00750
00751 FixTemplateFunctions(parameters);
00752
00753
00754 for (int itemp = 0; itemp < ntemplates; ++itemp) {
00755
00756
00757 int templateindex = fTemplateParIndexContainer.at(itemp);
00758
00759
00760 TH1D* hist;
00761 if (fTemplateTypeContainer[itemp] == 0) {
00762 int histogramindex = GetHistogramIndex(itemp);
00763 hist = new TH1D( fTemplateHistogramContainer.at(histogramindex) );
00764 }
00765 else if (fTemplateTypeContainer[itemp] == 1) {
00766 hist = new TH1D( fHistData );
00767 for (int i = 1; i <= fNBins; ++i) {
00768 double bincenter = fHistData.GetBinCenter(i);
00769 int index = GetFunctionIndex(itemp);
00770 double bincontent = fTemplateFunctionContainer.at(index).Eval(bincenter);
00771 hist->SetBinContent(i, bincontent);
00772 }
00773
00774 hist->Scale(1.0/hist->Integral());
00775 }
00776
00777
00778 hist->SetFillColor(2 + itemp);
00779 hist->SetFillStyle(1001);
00780 hist->SetStats(kFALSE);
00781
00782
00783 histcontainer.push_back(hist);
00784
00785
00786 for (int ibin = 1; ibin <= fNBins; ++ibin) {
00787
00788
00789 double efficiency = TemplateEfficiency(itemp, ibin, parameters);
00790
00791
00792 double probability = TemplateProbability(itemp, ibin, parameters);
00793
00794
00795 double nexp = parameters.at(templateindex)
00796 * efficiency
00797 * probability;
00798
00799
00800 hist->SetBinContent(ibin, nexp);
00801 }
00802
00803
00804
00805 stack.Add(hist);
00806 if (itemp < 2)
00807 legend1->AddEntry(hist, fTemplateNameContainer.at(itemp).data(), "F");
00808 else if (itemp < 6)
00809 legend2->AddEntry(hist, fTemplateNameContainer.at(itemp).data(), "F");
00810 }
00811
00812
00813 for (int ibin = 1; ibin <= nbins; ++ibin) {
00814
00815 histsum->SetBinContent(ibin, Expectation(ibin, parameters));
00816 }
00817
00818
00819 TGraphAsymmErrors * graph_error_exp = new TGraphAsymmErrors(nbins);
00820 graph_error_exp->SetLineWidth(2);
00821 graph_error_exp->SetMarkerStyle(0);
00822
00823 TGraphAsymmErrors * graph_error_obs = new TGraphAsymmErrors(nbins);
00824 graph_error_obs->SetMarkerStyle(0);
00825
00826
00827 if (flag_error1)
00828 for (int i = 1; i <= nbins; ++i) {
00829 double nexp = histsum->GetBinContent(i);
00830 histsum->SetBinError(i, sqrt(nexp));
00831 histsum->SetMarkerStyle(0);
00832 }
00833
00834 if (flag_error2)
00835 for (int i = 1; i <= nbins; ++i) {
00836 TH1D * proj = fUncertaintyHistogramExp->ProjectionY("_py", i, i);
00837 if (proj->Integral() > 0)
00838 proj->Scale(1.0 / proj->Integral());
00839 double quantiles[3];
00840 double sums[3] = {0.16, 0.5, 0.84};
00841 proj->GetQuantiles(3, quantiles, sums);
00842 graph_error_exp->SetPoint(i-1, histsum->GetBinCenter(i), quantiles[1]);
00843 graph_error_exp->SetPointError(i-1, 0.0, 0.0, quantiles[1] - quantiles[0], quantiles[2]-quantiles[1]);
00844 delete proj;
00845 }
00846
00847 if (flag_error3)
00848 for (int i = 1; i <= nbins; ++i) {
00849 TH1D * proj = fUncertaintyHistogramObsPosterior->ProjectionY("_py", i, i);
00850 if (proj->Integral() > 0)
00851 proj->Scale(1.0 / proj->Integral());
00852 double quantiles[3];
00853 double sums[3] = {0.16, 0.5, 0.84};
00854 proj->GetQuantiles(3, quantiles, sums);
00855 graph_error_obs->SetPoint(i-1, histsum->GetBinCenter(i), quantiles[1]);
00856 graph_error_obs->SetPointError(i-1, 0.0, 0.0, quantiles[1] - TMath::Floor(quantiles[0]), TMath::Ceil(quantiles[2])-quantiles[1]);
00857 delete proj;
00858 }
00859
00860
00861 TH1D * hist_diff = 0;
00862
00863 TGraphAsymmErrors * graph_diff_exp = 0;
00864
00865 if (flag_diff) {
00866 ymin = 0;
00867 ymax = 0;
00868
00869
00870 std::vector<double> a(fHistData.GetNbinsX()+1);
00871 for (int i = 0; i < fHistData.GetNbinsX()+1; ++i) {
00872 a[i] = fHistData.GetXaxis()->GetBinLowEdge(i+1);
00873 }
00874
00875 hist_diff = new TH1D("hist_diff", "", nbins, &a[0]);
00876 hist_diff->SetName("hist_diff");
00877 hist_diff->GetXaxis()->SetTitle(fHistData.GetXaxis()->GetTitle());
00878 hist_diff->GetYaxis()->SetTitle("#Delta N");
00879 hist_diff->GetXaxis()->SetNdivisions(505);
00880 hist_diff->GetXaxis()->SetLabelSize(hist_diff->GetXaxis()->GetLabelSize()/(fraction_pads));
00881 hist_diff->GetXaxis()->SetLabelOffset(hist_diff->GetXaxis()->GetLabelOffset()/fraction_pads*2.);
00882 hist_diff->GetXaxis()->SetTitleSize(hist_diff->GetXaxis()->GetTitleSize()/(fraction_pads));
00883 hist_diff->GetXaxis()->SetTitleOffset((hist_diff->GetXaxis()->GetTitleOffset()-(1.0-fraction_pads))/(fraction_pads));
00884 hist_diff->GetYaxis()->SetNdivisions(503);
00885 hist_diff->GetYaxis()->SetLabelSize(hist_diff->GetYaxis()->GetLabelSize()/(fraction_pads));
00886 hist_diff->GetYaxis()->SetLabelOffset(hist_diff->GetYaxis()->GetLabelOffset()/(fraction_pads));
00887 hist_diff->GetYaxis()->SetTitleSize(hist_diff->GetYaxis()->GetTitleSize()/(fraction_pads));
00888 hist_diff->GetYaxis()->SetTitleOffset(hist_diff->GetYaxis()->GetTitleOffset()*(fraction_pads));
00889 hist_diff->SetStats(kFALSE);
00890
00891 graph_diff_exp = new TGraphAsymmErrors(nbins);
00892 graph_diff_exp->SetLineWidth(2);
00893 graph_diff_exp->SetMarkerStyle(0);
00894 graph_diff_exp->SetFillColor(kYellow);
00895 for (int i = 0; i < nbins; ++i) {
00896 hist_diff->SetBinContent(i+1, fHistData.GetBinContent(i+1)-histsum->GetBinContent(i+1));
00897 hist_diff->SetBinError(i+1, fHistData.GetBinError(i+1));
00898 graph_diff_exp->SetPoint(i, (graph_error_exp->GetX())[i], 0.0);
00899 graph_diff_exp->SetPointEXlow(i, 0.0);
00900 graph_diff_exp->SetPointEXhigh(i, 0.0);
00901 graph_diff_exp->SetPointEYlow(i, (graph_error_exp->GetEYlow())[i]);
00902 graph_diff_exp->SetPointEYhigh(i, (graph_error_exp->GetEYhigh())[i]);
00903
00904 if (-(graph_error_exp->GetEYlow())[i] < ymin)
00905 ymin = -(graph_error_exp->GetEYlow())[i];
00906 if ((graph_error_exp->GetEYhigh())[i] > ymax)
00907 ymax = (graph_error_exp->GetEYhigh())[i];
00908 }
00909 if (ymax < (hist_diff->GetMaximum() + hist_diff->GetBinError(hist_diff->GetMaximumBin())))
00910 ymax = 1.1 * (hist_diff->GetMaximum() + hist_diff->GetBinError(hist_diff->GetMaximumBin()));
00911 if (ymin>(hist_diff->GetMinimum() - hist_diff->GetBinError(hist_diff->GetMaximumBin())))
00912 ymin = 1.1 * (hist_diff->GetMinimum() - hist_diff->GetBinError(hist_diff->GetMaximumBin()));
00913 (hist_diff->GetYaxis())->SetRangeUser(TMath::Floor(-1.1*TMath::Max(-ymin, ymax)), TMath::Ceil(1.1*TMath::Max(-ymin, ymax)));
00914
00915 }
00916
00917
00918 stack.Draw("SAMEAF");
00919 stack.GetHistogram() -> SetXTitle("");
00920 stack.GetHistogram() -> SetYTitle("");
00921 stack.GetHistogram() -> GetXaxis() -> SetLabelSize(0);
00922 stack.GetHistogram() -> GetYaxis() -> SetLabelSize(0);
00923 stack.Draw("SAME");
00924 fHistData.Draw("SAMEP");
00925
00926 if (flag_error0)
00927 fHistData.Draw("SAMEPE");
00928
00929 if (flag_error1)
00930 histsum->Draw("SAMEE");
00931
00932 if (flag_error3)
00933 graph_error_obs->Draw("SAMEZ");
00934
00935 if (flag_error2)
00936 graph_error_exp->Draw("SAME||");
00937
00938 if (flag_legend) {
00939 legend1->Draw();
00940 if (ntemplates>2)
00941 legend2->Draw();
00942 }
00943
00944 TLine * line = 0;
00945 if (flag_diff) {
00946 pad2->cd();
00947 hist_diff->Draw("P");
00948 graph_diff_exp->Draw("SAME4");
00949 line = new TLine((hist_diff->GetXaxis())->GetXmin(), 0.0, (hist_diff->GetXaxis())->GetXmax(), 0.0);
00950 line->SetLineWidth(2);
00951 line->SetLineColor(kBlack);
00952 line->Draw("SAME");
00953 hist_diff->Draw("SAMEP");
00954 }
00955
00956 c1->Print(filename);
00957
00958
00959 delete pad1;
00960 delete pad2;
00961 delete c1;
00962 delete legend1;
00963 delete legend2;
00964 delete graph_error_exp;
00965 delete graph_error_obs;
00966 delete histsum;
00967 if (flag_diff) {
00968 delete hist_diff;
00969 delete graph_diff_exp;
00970 delete line;
00971 }
00972 }
00973
00974
00975 double BCTemplateFitter::CalculateChi2(const std::vector<double> & parameters)
00976 {
00977 double chi2 = 0;
00978
00979
00980 for (int ibin = 1; ibin <= fNBins; ++ibin) {
00981
00982 double nexp = Expectation(ibin, parameters);
00983
00984
00985 double ndata = fHistData.GetBinContent(ibin);
00986
00987
00988 chi2 += (nexp - ndata) * (nexp - ndata) / nexp;
00989 }
00990
00991
00992 return chi2;
00993 }
00994
00995
00996 double BCTemplateFitter::CalculateChi2Prob(const std::vector<double> & parameters)
00997 {
00998 double chi2 = CalculateChi2(parameters);
00999 int ndf = GetNDF();
01000
01001
01002 return TMath::Prob(chi2, ndf);
01003 }
01004
01005
01006 double BCTemplateFitter::CalculateMaxLike()
01007 {
01008
01009 return Eval( GetBestFitParameters() );
01010 }
01011
01012
01013 double BCTemplateFitter::CalculateKSProb()
01014 {
01015
01016 TH1D * histsum = new TH1D(fHistData);
01017
01018
01019 std::vector<double> parameters = GetBestFitParameters();
01020
01021
01022 for (int ibin = 1; ibin <= fNBins; ++ibin) {
01023
01024 double nexp = Expectation(ibin, parameters);
01025
01026
01027 histsum->SetBinContent(ibin, nexp);
01028 }
01029
01030
01031 double ksprob = histsum->KolmogorovTest(&fHistData);
01032
01033
01034 delete histsum;
01035
01036 return ksprob;
01037 }
01038
01039
01040 double BCTemplateFitter::CalculatePValue()
01041 {
01042
01043 std::vector<double> par = GetBestFitParameters();
01044
01045
01046 if (par.size() != GetNParameters()) {
01047 BCLog::OutWarning("BCBCTemplateFitter::CalculatePValueFast : Number of parameters is inconsistent.");
01048 return -1;
01049 }
01050
01051 std::vector<int> histogram;
01052 std::vector<double> expectation;
01053 histogram.assign(fNBins, 0);
01054 expectation.assign(fNBins, 0);
01055
01056 double logp = 0;
01057 double logp_start = 0;
01058 int counter_pvalue = 0;
01059
01060
01061 for (int ibin = 1; ibin <= fNBins; ++ibin) {
01062
01063
01064 double nexp = Expectation(ibin, par);
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090 histogram[ibin-1] = int(nexp);
01091 expectation[ibin-1] = nexp;
01092
01093
01094 logp += BCMath::LogPoisson(double(int(nexp)), nexp);
01095 logp_start += BCMath::LogPoisson(fHistData.GetBinContent(ibin), nexp);
01096 }
01097
01098 int niter = 100000;
01099
01100
01101 for (int iiter = 0; iiter < niter; ++iiter) {
01102
01103 for (int ibin = 0; ibin < fNBins; ++ibin) {
01104
01105 double ptest = fRandom->Rndm() - 0.5;
01106
01107
01108 if (ptest > 0) {
01109
01110 double r = expectation.at(ibin) / double(histogram.at(ibin) + 1);
01111
01112
01113 if (fRandom->Rndm() < r) {
01114 histogram[ibin] = histogram.at(ibin) + 1;
01115 logp += log(r);
01116 }
01117 }
01118
01119
01120 else if (ptest <= 0 && histogram[ibin] > 0) {
01121
01122 double r = double(histogram.at(ibin)) / expectation.at(ibin);
01123
01124
01125 if (fRandom->Rndm() < r) {
01126 histogram[ibin] = histogram.at(ibin) - 1;
01127 logp += log(r);
01128 }
01129 }
01130 }
01131
01132
01133 if (logp < logp_start)
01134 counter_pvalue++;
01135
01136 }
01137
01138
01139 return double(counter_pvalue) / double(niter);
01140 }
01141
01142
01143 void BCTemplateFitter::MCMCUserIterationInterface()
01144 {
01145
01146 for (int ibin = 1; ibin <= fNBins; ++ibin) {
01147
01148 double bincontent = Expectation(ibin, fMCMCx);
01149
01150
01151 fUncertaintyHistogramExp->Fill(fHistData.GetBinCenter(ibin), bincontent);
01152
01153
01154 int nbinsy = fUncertaintyHistogramObsPosterior->GetNbinsY();
01155 for (int jbin = 1; jbin <= nbinsy; ++jbin) {
01156 int n = jbin - 1;
01157 if (fabs(n - bincontent) < 2*sqrt(bincontent))
01158 fUncertaintyHistogramObsPosterior->Fill(fHistData.GetBinCenter(ibin), n, TMath::Poisson(bincontent, n));
01159 }
01160 }
01161
01162
01163 fHistNorm.Fill(fNorm);
01164
01165
01166 int nratios = int( fIndicesRatios1D.size() );
01167
01168
01169 for (int i = 0; i < nratios; ++i) {
01170 int nsum = int( (fIndicesRatios1D.at(i)).size() ) - 1;
01171 double sum = 0;
01172 for (int j = 1; j <= nsum; ++j) {
01173 int indexsum = fIndicesRatios1D.at(i).at(j);
01174 sum += fMCMCx.at(fTemplateParIndexContainer.at(indexsum));
01175 }
01176
01177 fHistRatios1D.at(i).Fill(fMCMCx.at(fTemplateParIndexContainer.at(fIndicesRatios1D.at(i).at(0)))/sum);
01178 }
01179
01180 }
01181
01182
01183 void BCTemplateFitter::PrintRatios(const char * filename, int options, double ovalue)
01184 {
01185 int nratios = int(fHistRatios1D.size());
01186
01187 TCanvas * c1 = new TCanvas("");
01188
01189 TPostScript * ps = new TPostScript(filename, 112);
01190 ps->NewPage();
01191
01192 c1->cd();
01193 BCH1D * h1temp = new BCH1D(&fHistNorm);
01194 h1temp->Draw();
01195 c1->Update();
01196 ps->NewPage();
01197 for (int i = 0; i < nratios; ++i) {
01198 c1->Update();
01199 ps->NewPage();
01200 c1->cd();
01201 BCH1D* h1temp = new BCH1D(&fHistRatios1D.at(i));
01202 h1temp->Draw(options, ovalue);
01203 }
01204 c1->Update();
01205 ps->Close();
01206
01207
01208 delete c1;
01209 delete ps;
01210 }
01211
01212
01213 int BCTemplateFitter::SetTemplateEfficiency(const char * name, TH1D eff, TH1D efferr)
01214 {
01215
01216 int index = GetIndexTemplate(name);
01217
01218
01219 if (index < 0) {
01220 BCLog::OutError("BCTemplateFitter::SetTemplateEfficiency : Could not find template.");
01221 return 0;
01222 }
01223
01224
01225 if (fTemplateTypeContainer[index]==0)
01226 if (CompareHistogramProperties(fTemplateHistogramContainer.at(index), eff) != 1) {
01227 BCLog::OutError("BCTemplateFitter::SetTemplate efficiency : Template and efficiency histogram properties are incompatible.");
01228 return 0;
01229 }
01230
01231
01232 eff.SetXTitle((fHistData.GetXaxis())->GetTitle());
01233 eff.SetYTitle("Efficiency");
01234
01235 efferr.SetXTitle((fHistData.GetXaxis())->GetTitle());
01236 efferr.SetYTitle("Efficiency uncertainty");
01237
01238
01239 fEffHistogramContainer[index] = eff;
01240 fEffErrHistogramContainer[index] = efferr;
01241
01242
01243 return 1;
01244 }
01245
01246
01247 int BCTemplateFitter::SetTemplateEfficiency(const char * name, double effmean, double effsigma)
01248 {
01249
01250 int index = GetIndexTemplate(name);
01251
01252
01253 if (index < 0) {
01254 BCLog::OutError("BCTemplateFitter::SetTemplateEfficiency : Could not find template.");
01255 return 0;
01256 }
01257
01258
01259 TH1D histeff = TH1D(fHistData);
01260 TH1D histefferr = TH1D(fHistData);
01261
01262
01263 for (int i = 1; i <= fNBins; ++i) {
01264 histeff.SetBinContent(i, effmean);
01265 histefferr.SetBinContent(i, effsigma);
01266 }
01267
01268
01269 int err = SetTemplateEfficiency(name, histeff, histefferr);
01270
01271
01272 return err;
01273 }
01274
01275
01276 int BCTemplateFitter::ConstrainSum(std::vector<int> indices, double mean, double rms)
01277 {
01278
01279 fConstraintSumIndices.push_back(indices);
01280 fConstraintSumMean.push_back(mean);
01281 fConstraintSumRMS.push_back(rms);
01282
01283
01284 return 1;
01285 }
01286
01287
01288 void BCTemplateFitter::PrintTemp()
01289 {
01290 TCanvas * c1 = new TCanvas("");
01291
01292 c1->cd();
01293 fUncertaintyHistogramExp->Draw("COL");
01294 c1->Print("uncertainty_exp.eps");
01295
01296 c1->cd();
01297 fUncertaintyHistogramObsPosterior->Draw("COL");
01298 c1->Print("uncertainty_obs.eps");
01299
01300 delete c1;
01301 }
01302
01303
01304 int BCTemplateFitter::PrintTemplate(const char * name, const char * filename)
01305 {
01306
01307 int nsyst = GetNSystErrors();
01308
01309
01310 int index = GetIndexTemplate(name);
01311
01312
01313 if (index < 0) {
01314 BCLog::OutError("BCTemplateFitter::PrintTemplate : Could not find template.");
01315 return 0;
01316 }
01317
01318
01319 TDirectory* dir = gDirectory;
01320
01321
01322 TPostScript * ps = new TPostScript(filename);
01323
01324
01325 TCanvas * c1 = new TCanvas("", "", 700, 700);
01326
01327 c1->Update();
01328 ps->NewPage();
01329 c1->cd();
01330
01331
01332 TLegend l1(0.18, 0.75, 0.85, 0.85);
01333 l1.SetBorderSize(0);
01334 l1.SetFillColor(kWhite);
01335
01336
01337 TH1D hist_template = fTemplateHistogramContainer.at(index);
01338 hist_template.SetFillColor(kWhite);
01339 hist_template.SetFillStyle(0);
01340 hist_template.SetMarkerSize(0);
01341 hist_template.SetLineWidth(0);
01342 l1.AddEntry(&hist_template, name, "L");
01343 TH1D hist_totalerr = CombineUncertainties(name);
01344 TH1D hist_template_totalerr = CreateErrorHist(hist_template, hist_totalerr);
01345 hist_template_totalerr.SetFillColor(kYellow);
01346 hist_template_totalerr.SetFillStyle(1001);
01347 hist_template_totalerr.SetMarkerSize(0);
01348 l1.AddEntry(&hist_template_totalerr, "Systematic uncertainties", "F");
01349 TH1D hist_efferr = fEffErrHistogramContainer.at(index);
01350 TH1D hist_template_efferr = CreateErrorHist(hist_template, hist_efferr);
01351 hist_template_totalerr.SetFillColor(kRed);
01352 hist_template_totalerr.SetFillStyle(1001);
01353 hist_template_efferr.SetMarkerSize(0);
01354 l1.AddEntry(&hist_template_efferr, "Efficiency uncertainties", "F");
01355 int binmax = hist_template.GetMaximumBin();
01356 double ymax = hist_template.GetBinContent(binmax) + 2.0 * hist_template_totalerr.GetBinError(binmax);
01357 hist_template_totalerr.GetYaxis()->SetRangeUser(0.0, 1.25 * ymax);
01358 hist_template_totalerr.Draw("E2");
01359 hist_template_efferr.Draw("SAMEE2");
01360 hist_template.Draw("SAME");
01361
01362
01363 l1.Draw();
01364
01365
01366 c1->Update();
01367 ps->NewPage();
01368 c1->cd();
01369
01370
01371 TLegend l2(0.18, 0.75, 0.85, 0.85);
01372 l2.SetBorderSize(0);
01373 l2.SetFillColor(kWhite);
01374
01375
01376 c1->cd(2);
01377 hist_efferr = fEffErrHistogramContainer.at(index);
01378 double ymin = hist_efferr.GetMinimum();
01379 ymax = hist_efferr.GetMaximum();
01380 l2.AddEntry(&hist_efferr, "Efficiency", "L");
01381 hist_efferr.SetStats(kFALSE);
01382 hist_efferr.Draw();
01383
01384
01385 for (int i = 0; i < nsyst; ++i) {
01386 TH1D * hist = new TH1D(fSystErrorHistogramContainer.at(i).at(index));
01387 hist->SetLineColor(2 + i);
01388 if (hist->GetMaximum()>ymax)
01389 ymax = hist->GetMaximum();
01390 if (hist->GetMinimum()<ymin)
01391 ymin = hist->GetMinimum();
01392 l2.AddEntry(hist, fSystErrorNameContainer.at(i).c_str(), "L");
01393 hist->Draw("SAME");
01394 }
01395 if (ymin < 0)
01396 ymin = 1.25*ymin;
01397 else
01398 ymin = 0.8*ymin;
01399
01400 if (ymax > 0)
01401 ymax = 1.25*ymax;
01402 else
01403 ymax = 0.8*ymax;
01404
01405 hist_efferr.GetYaxis()->SetRangeUser(ymin, ymax);
01406
01407
01408 l2.Draw();
01409
01410
01411 c1->Update();
01412 ps->Close();
01413
01414
01415 dir->cd();
01416
01417
01418 delete c1;
01419 delete ps;
01420
01421
01422 return 1;
01423 }
01424
01425
01426 TH1D BCTemplateFitter::CreateErrorHist(TH1D hist, TH1D histerr)
01427 {
01428
01429 if (CompareHistogramProperties(fHistData, hist) != 1) {
01430 BCLog::OutError("BCTemplateFitter::CreateErrorHist : Histograms are incompatible.");
01431 return hist;
01432 }
01433
01434
01435 TH1D h = hist;
01436
01437
01438 h.SetStats(kFALSE);
01439 h.SetFillColor(kYellow);
01440 h.SetFillStyle(1001);
01441
01442
01443 int nbins = hist.GetNbinsX();
01444
01445
01446 for (int i = 1; i <= nbins; ++i)
01447 h.SetBinError(i, histerr.GetBinContent(i) * hist.GetBinContent(i));
01448
01449
01450 return h;
01451 }
01452
01453
01454 TH1D BCTemplateFitter::CombineUncertainties(const char * name)
01455 {
01456
01457 int nsyst = GetNSystErrors();
01458
01459
01460 int tempindex = GetIndexTemplate(name);
01461
01462
01463
01464 TH1D hist = TH1D(fHistData);
01465
01466
01467 for (int ibin = 1; ibin <= fNBins; ++ibin) {
01468
01469
01470 double err = 0;
01471
01472
01473 double erreff = fEffErrHistogramContainer.at(tempindex).GetBinContent(ibin);
01474 err += erreff * erreff;
01475
01476
01477 for (int isyst = 0; isyst < nsyst; ++isyst) {
01478 double errsyst = fSystErrorHistogramContainer.at(isyst).at(tempindex).GetBinContent(ibin);
01479 err += errsyst*errsyst;
01480 }
01481
01482
01483 err = sqrt(err);
01484
01485
01486 hist.SetBinContent(ibin, err);
01487 }
01488
01489
01490 return hist;
01491 }
01492
01493
01494 int BCTemplateFitter::GetIndexTemplate(const char * name)
01495 {
01496 int index = -1;
01497 int n = GetNTemplates();
01498
01499 for (int i = 0; i < n; i++)
01500 if (name == fTemplateNameContainer.at(i))
01501 index = i;
01502
01503 if (index < 0) {
01504 BCLog::OutWarning("BCTemplateFitter::GetIndexTemplate : Template does not exist.");
01505 return 0;
01506 }
01507
01508
01509 return index;
01510 }
01511
01512
01513 int BCTemplateFitter::GetIndexSystError(const char * name)
01514 {
01515 int index = -1;
01516 int n = GetNSystErrors();
01517
01518 for (int i = 0; i < n; i++)
01519 if (name == fSystErrorNameContainer.at(i))
01520 index = i;
01521
01522 if (index < 0) {
01523 BCLog::OutWarning("BCTemplateFitter::GetIndexSystError : Template does not exist.");
01524 return 0;
01525 }
01526
01527
01528 return index;
01529 }
01530
01531
01532 int BCTemplateFitter::GetParIndexTemplate(const char * name)
01533 {
01534 int index = -1;
01535 int n = GetNTemplates();
01536
01537 for (int i = 0; i < n; i++)
01538 if (name == fTemplateNameContainer.at(i))
01539 index = fTemplateParIndexContainer.at(i);
01540
01541 if (index < 0) {
01542 BCLog::OutWarning("BCTemplateFitter::GetParIndexTemplate : Template does not exist.");
01543 return 0;
01544 }
01545
01546
01547 return index;
01548 }
01549
01550
01551 int BCTemplateFitter::GetParIndexTemplate(int index)
01552 {
01553
01554 int n = GetNTemplates();
01555
01556 if (index < 0 || index > n) {
01557 BCLog::OutError("BCTemplateFitter::GetParIndexTemplate : Index out of range.");
01558 return -1;
01559 }
01560
01561
01562 return fTemplateParIndexContainer.at(index);
01563 }
01564
01565
01566 int BCTemplateFitter::GetParIndexEff(const char * name)
01567 {
01568 int index = -1;
01569 int n = GetNTemplates();
01570
01571 for (int i = 0; i < n; i++)
01572 if (name == fTemplateNameContainer.at(i))
01573 index = fTemplateParIndexContainer.at(i);
01574
01575 if (index < 0) {
01576 BCLog::OutWarning("BCTemplateFitter::GetParIndexEff : Template does not exist.");
01577 return 0;
01578 }
01579
01580
01581 return index;
01582 }
01583
01584
01585 int BCTemplateFitter::GetParIndexSystError(const char * name)
01586 {
01587 int index = -1;
01588 int n = GetNTemplates();
01589
01590 for (int i = 0; i < n; i++)
01591 if (name == fSystErrorNameContainer.at(i))
01592 index = fSystErrorParIndexContainer.at(i);
01593
01594 if (index < 0) {
01595 BCLog::OutWarning("BCTemplateFitter::GetParIndexStatError : Systematic error does not exist.");
01596 return 0;
01597 }
01598
01599
01600 return index;
01601 }
01602
01603
01604 int BCTemplateFitter::PerformFit()
01605 {
01606
01607 if (!Initialize()) {
01608 BCLog::OutError("BCTemplateFitter::PerformFit : Could not initialize template fitter.");
01609 return 0;
01610 }
01611
01612
01613 MarginalizeAll();
01614
01615
01616 FindMode();
01617
01618
01619 return 1;
01620 }
01621
01622
01623 int BCTemplateFitter::GetNTemplatesType(int templatetype)
01624 {
01625
01626 int ntemplates = GetNTemplates();
01627
01628
01629 int counter = 0;
01630
01631
01632 for (int i = 0; i < ntemplates; ++i) {
01633
01634 if (templatetype == fTemplateTypeContainer.at(i))
01635 counter++;
01636 }
01637
01638
01639 return counter;
01640 }
01641
01642