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