• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

BCTemplateFitter.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008-2012, Daniel Kollar and Kevin Kroeninger.
00003  * All rights reserved.
00004  *
00005  * For the licensing terms see doc/COPYING.
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    // fix the parameters of all functions
00079    FixTemplateFunctions(parameters);
00080 
00081    // loop over bins
00082    for (int ibin = 1; ibin <= fNBins; ++ibin) {
00083       // get expectation
00084       double nexp = Expectation(ibin, parameters);
00085 
00086       // get data
00087       double ndata = fHistData.GetBinContent(ibin);
00088 
00089       // add Poisson term
00090       logprob += BCMath::LogPoisson(ndata, nexp);
00091    }
00092 
00093    // return log likelihood
00094    return logprob;
00095 }
00096 
00097 // ---------------------------------------------------------
00098 double BCTemplateFitter::Expectation(int binnumber, const std::vector<double>& parameters)
00099 {
00100    // initialize number of expected events with 0
00101    double nexp = 0;
00102 
00103    // get number of templates
00104    int ntemplates = GetNTemplates();
00105 
00106    // loop over all templates
00107    for (int itemp = 0; itemp < ntemplates; ++itemp) {
00108 
00109       // get template index
00110       int templateindex = fTemplateParIndexContainer.at(itemp);
00111 
00112       // calculate efficiency for this template and bin
00113       double efficiency = TemplateEfficiency(itemp, binnumber, parameters);
00114 
00115       // calculate probability for this template and bin
00116       double probability = TemplateProbability(itemp, binnumber, parameters);
00117 
00118       // calculate expectation value for this template
00119       nexp += parameters.at(templateindex)
00120          * efficiency
00121          * probability;
00122    }
00123 
00124    // check that expectation is larger or equal to zero
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    // get number of sources of systematic uncertainties
00137    int nsyst = GetNSystErrors();
00138 
00139    // get efficiency index
00140    int effindex = fEffParIndexContainer.at(templatenumber);
00141 
00142    // get efficiency for the bin
00143    double efficiency = fEffHistogramContainer.at(templatenumber).GetBinContent(binnumber);
00144 
00145    // modify efficiency by uncertainty
00146    double efferr = fEffErrHistogramContainer.at(templatenumber).GetBinContent(binnumber);
00147 
00148    // check that efficiency error is larger than 0
00149    // add efficiency contribution from template
00150    efficiency += parameters.at(effindex) * efferr;
00151 
00152    // loop over sources of systematic uncertainties
00153    for (int isyst = 0; isyst < nsyst; ++isyst) {
00154       // get parameter index
00155       int systindex = fSystErrorParIndexContainer.at(isyst);
00156 
00157       // add efficiency
00158       double deff = fSystErrorHistogramContainer.at(isyst).at(templatenumber).GetBinContent(binnumber);
00159 
00160       // add efficiency contribution from systematic
00161       efficiency += parameters.at(systindex) * deff;
00162    }
00163 
00164    // make sure efficiency is between 0 and 1
00165    if (efficiency < 0.)
00166       efficiency = 0.;
00167    if (efficiency > 1.)
00168       efficiency = 1.;
00169 
00170    // return efficiency
00171    return efficiency;
00172 }
00173 
00174 // ---------------------------------------------------------
00175 double BCTemplateFitter::TemplateProbability(int templatenumber, int binnumber, const std::vector<double>& /*parameters*/)
00176 {
00177    // initialize probability
00178    double probability = 0;
00179 
00180    // get template type
00181    int templatetype = fTemplateTypeContainer[templatenumber];
00182 
00183    // calculate probability from template histogram
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    // return probability
00196    return probability;
00197 }
00198 
00199 // ---------------------------------------------------------
00200 int BCTemplateFitter::FixTemplateFunctions(const std::vector<double>& parameters)
00201 {
00202    // get number of templates
00203    int ntemplates = GetNTemplates();
00204 
00205    // fix all function parameters
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    // no errors
00219    return 1;
00220 }
00221 // ---------------------------------------------------------
00222 int BCTemplateFitter::SetData(const TH1D& hist)
00223 {
00224    // compare previous data set with this one
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    // create histogram
00233    fNBins = hist.GetNbinsX();
00234    fXmin = (hist.GetXaxis())->GetXmin();
00235    fXmax = (hist.GetXaxis())->GetXmax();
00236    fHistData = TH1D(hist);
00237 
00238    // copy histogram content
00239    for (int i = 1; i <= fNBins; ++i)
00240       fHistData.SetBinContent(i, hist.GetBinContent(i));
00241 
00242    // set histogram style
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    // calculate norm
00250    fNorm = hist.Integral();
00251 
00252    // no errors
00253    return 1;
00254 }
00255 
00256 // ---------------------------------------------------------
00257 int BCTemplateFitter::AddTemplate(TH1D hist, const char * name, double Nmin, double Nmax)
00258 {
00259    // check if histogram if filled
00260    if (hist.Integral() <= 0.) {
00261       BCLog::OutError("BCTemplateFitter::AddTemplate : Normalization is zero or less than that.");
00262       return 0;
00263    }
00264 
00265    // compare template properties with data
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    // check if prior makes sense
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    // get number of templates
00286    int ntemplates = GetNTemplates();
00287 
00288    // set histogram color and style
00289    hist.SetFillColor(2 + ntemplates);
00290    hist.SetFillStyle(1001);
00291    hist.SetStats(kFALSE);
00292 
00293    // scale histogram
00294    hist.Scale(1.0 / hist.Integral());
00295 
00296    // check if template is consistent with other templates
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    // histograms
00304    TH1D histsysterror = TH1D(fHistData);
00305 
00306    // fill histograms
00307    for (int i = 1; i <= fNBins; ++i)
00308       histsysterror.SetBinContent(i, 0.);
00309 
00310    // get parameter index
00311    int parindex = GetNParameters();
00312 
00313    // add a parameter for the expectation value
00314    AddParameter(name, Nmin, Nmax);
00315 
00316    // get efficiency parameter index
00317    int effindex = GetNParameters();
00318 
00319     // add a parameter for the efficiency
00320    AddParameter(Form("Efficiency_%s", name), -5.0, 5.0);
00321 
00322    // add histogram, name and index to containers
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    // set efficiency histograms to one without uncertainty
00332    fEffHistogramContainer.push_back(TH1D());
00333    fEffErrHistogramContainer.push_back(TH1D());
00334    SetTemplateEfficiency(name, 1., 0.);
00335 
00336    // set prior for efficiencies
00337    SetPriorGauss(Form("Efficiency_%s", name), 0., 1.);
00338 
00339    // add systematic uncertainties
00340    for (int i = 0; i < GetNSystErrors(); ++i) {
00341       std::vector<TH1D> histvector = fSystErrorHistogramContainer.at(i);
00342       histvector.push_back(histsysterror);
00343    }
00344 
00345    // successfully added histogram to container
00346    return 1;
00347 }
00348 
00349 // ---------------------------------------------------------
00350 int BCTemplateFitter::AddTemplate(TF1 func, const char * name, double Nmin, double Nmax, const char* /*options*/)
00351 {
00352    // check if prior makes sense
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    // get parameter index
00362    int parindex = GetNParameters();
00363 
00364    // add a parameter for the expectation value
00365    AddParameter(name, Nmin, Nmax);
00366 
00367    // get efficiency parameter index
00368    int effindex = GetNParameters();
00369 
00370     // add a parameter for the efficiency
00371    AddParameter(Form("Efficiency_%s", name), -5.0, 5.0);
00372 
00373    // add all additional parameters
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    // add histogram, name and index to containers
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    // set efficiency histograms to one without uncertainty
00394    fEffHistogramContainer.push_back(TH1D());
00395    fEffErrHistogramContainer.push_back(TH1D());
00396    SetTemplateEfficiency(name, 1., 0.);
00397 
00398    // set prior for efficiencies
00399    SetPriorGauss(Form("Efficiency_%s", name), 0., 1.);
00400 
00401    // successfully added histogram to container
00402    return 1;
00403 }
00404 
00405 // ---------------------------------------------------------
00406 int BCTemplateFitter::AddSystError(const char * errorname, const char * errtype)
00407 {
00408    // define parameter range
00409    double dx = 1.0;
00410 
00411    // check error type
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    // add a parameter for the expectation value
00422    AddParameter(Form("%s", errorname), -dx, dx);
00423 
00424    // set prior for systematics
00425    SetPriorGauss(Form("%s", errorname), 0., 1.);
00426 
00427    // add name and index to containers
00428    fSystErrorNameContainer.push_back(errorname);
00429    fSystErrorParIndexContainer.push_back(GetNParameters()-1);
00430 
00431    // create histogram
00432    TH1D hist = TH1D(fHistData);
00433 
00434    // fill histograms
00435    for (int i = 1; i <= fNBins; ++i)
00436       hist.SetBinContent(i, 0.);
00437 
00438    // get number of templates
00439    int n = GetNTemplates();
00440 
00441    // define vector of histograms
00442    std::vector<TH1D> histvector;
00443 
00444    // add histograms
00445    for (int i = 0; i < n; ++i)
00446       histvector.push_back(hist);
00447 
00448    // add histogram vector
00449    fSystErrorHistogramContainer.push_back(histvector);
00450 
00451    // add error type to container
00452    fSystErrorTypeContainer.push_back(std::string(errtype));
00453 
00454    // no error
00455    return 1;
00456 }
00457 
00458 // ---------------------------------------------------------
00459 int BCTemplateFitter::SetTemplateSystError(const char * errorname, const char * templatename, TH1D parerror)
00460 {
00461    // get error index
00462    int errindex = GetIndexSystError(errorname);
00463 
00464    // check parameter index
00465    if (errindex < 0) {
00466       BCLog::OutError("BCTemplateFitter::SetTemplateSystError : Did not find parameter.");
00467       return 0;
00468    }
00469 
00470    // get template index
00471    int tempindex = GetIndexTemplate(templatename);
00472 
00473    // check index
00474    if (tempindex < 0) {
00475       BCLog::OutError("BCTemplateFitter::SetTemplateSystError : Could not find template.");
00476       return 0;
00477    }
00478 
00479    // set style
00480    parerror.SetStats(kFALSE);
00481 
00482    // set histogram
00483    (fSystErrorHistogramContainer.at(errindex))[tempindex] = parerror;
00484 
00485    // no error
00486    return 1;
00487 }
00488 
00489 // ---------------------------------------------------------
00490 int BCTemplateFitter::Initialize()
00491 {
00492    // check data integral
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    // create histograms for uncertainty determination
00499    //   double maximum = 1.5 * fHistData.GetMaximum();
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          //         fHistData.GetNbinsX(), fHistData.GetXaxis()->GetXbins()->GetArray(),
00511          fHistData.GetNbinsX(), &a[0],
00512          //         fHistData.GetNbinsX(), fHistData.GetXaxis()->GetXmin(), fHistData.GetXaxis()->GetXmax(),
00513          100, minimum, maximum);
00514 
00515    fUncertaintyHistogramObsPosterior = new TH2D(
00516          TString::Format("UncertaintyObsPosterior_%i", BCLog::GetHIndex()), "",
00517          fHistData.GetNbinsX(), &a[0],
00518          //         fHistData.GetNbinsX(), fHistData.GetXaxis()->GetXbins()->GetArray(),         //         fHistData.GetNbinsX(), fHistData.GetXaxis()->GetXmin(), fHistData.GetXaxis()->GetXmax(),
00519          int(maximum) + 1, -0.5, double(int(maximum))+0.5);
00520 
00521    // create histogram containing the normalization
00522    double xmin = 0;
00523    double xmax = 0;
00524    int ntemplates = GetNTemplates();
00525 
00526    // calculate the limits on the norm from the sum of all parameter
00527    // limits
00528    for (int i = 0; i < ntemplates; ++i) {
00529       // get parameter index
00530       int parindex = fTemplateParIndexContainer.at(i);
00531       int effindex = fEffParIndexContainer.at(i);
00532 
00533       // get parameter
00534       BCParameter * par = this->GetParameter(parindex);
00535       BCParameter * eff = this->GetParameter(effindex);
00536 
00537       // increate limits
00538       xmin += par->GetLowerLimit() * eff->GetLowerLimit();
00539       xmax += par->GetUpperLimit() * eff->GetUpperLimit();
00540    }
00541 
00542    // create new histogram for norm
00543    fHistNorm = TH1D("", ";N_{norm};dN/dN_{norm}", 100, xmin, xmax);
00544 
00545    // no error
00546    return 1;
00547 }
00548 
00549 // ---------------------------------------------------------
00550 int BCTemplateFitter::CalculateRatio(int index, std::vector<int> indices, double rmin, double rmax)
00551 {
00552    // get number of templates
00553    int ntemplates = GetNTemplates();
00554 
00555    // check index
00556    if (index < 0 || index >= ntemplates) {
00557       return 0;
00558    }
00559 
00560    // check indices
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    // create temporary vector
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    // add ratio
00574    fIndicesRatios1D.push_back(tempvec);
00575 
00576    // get number of ratios
00577    int nratios = int(fHistRatios1D.size());
00578 
00579    // create histogram
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    // no error
00591    return 1;
00592 }
00593 
00594 // ---------------------------------------------------------
00595 int BCTemplateFitter::CompareHistogramProperties(TH1D hist1, TH1D hist2)
00596 {
00597    // compare number of bins
00598    if (hist1.GetNbinsX() != hist2.GetNbinsX())
00599       return 0;
00600 
00601    // compare minimum x-values
00602    if (hist1.GetXaxis()->GetXmin() != hist2.GetXaxis()->GetXmin())
00603       return 0;
00604 
00605    // compare maximum x-values
00606    if (hist1.GetXaxis()->GetXmax() != hist2.GetXaxis()->GetXmax())
00607       return 0;
00608 
00609    // conclusion: they have the same properties
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    // check options
00620    bool flag_legend = false;
00621    bool flag_error0 = false; // symm. poisson error for data
00622    bool flag_error1 = false; // symm. poisson error for exp.
00623    bool flag_error2 = false; // asymm. poisson error of expectation value
00624    bool flag_error3 = false; // asymm. poisson error of expected no. of events
00625    bool flag_diff   = false; // plot difference between data and expectation below stack plot
00626    bool flag_logx   = false; // plot x-axis in log-scale
00627    bool flag_logy   = false; // plot y-axis in log-scale
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    // create canvas
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    // set style and draw data
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    // create a histogram with the sum of all contributions
00717    //    TH1D * histsum = (TH1D*) fHistData.Clone("temp");
00718     TH1D * histsum = new TH1D(fHistData);
00719 
00720    // create stack
00721    THStack stack("histostack","");
00722 
00723    // create legends
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    // create new histograms for plotting
00745    std::vector<TH1D*> histcontainer;
00746 
00747    // get best fit parameters
00748    std::vector<double> parameters = GetBestFitParameters();
00749 
00750    // fix the parameters of all functions
00751    FixTemplateFunctions(parameters);
00752 
00753    // scale histograms and add to stack and legend
00754    for (int itemp = 0; itemp < ntemplates; ++itemp) {
00755 
00756       // get template index
00757       int templateindex = fTemplateParIndexContainer.at(itemp);
00758 
00759       // create new histogram
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          // scale histogram
00774          hist->Scale(1.0/hist->Integral());
00775       }
00776 
00777       // set histogram color and style
00778       hist->SetFillColor(2 + itemp);
00779       hist->SetFillStyle(1001);
00780       hist->SetStats(kFALSE);
00781 
00782       // add histogram to list of histograms
00783       histcontainer.push_back(hist);
00784 
00785       // loop over bins and set them
00786       for (int ibin = 1; ibin <= fNBins; ++ibin) {
00787 
00788          // calculate efficiency for this template and bin
00789          double efficiency = TemplateEfficiency(itemp, ibin, parameters);
00790 
00791          // calculate probability for this template and bin
00792          double probability = TemplateProbability(itemp, ibin, parameters);
00793 
00794          // calculate expectation value for this template
00795          double nexp = parameters.at(templateindex)
00796             * efficiency
00797             * probability;
00798 
00799          // set bin content
00800          hist->SetBinContent(ibin, nexp);
00801       }
00802 
00803 
00804       // add histogram to stack
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    // loop over all bins
00813    for (int ibin = 1; ibin <= nbins; ++ibin) {
00814       // set bin content
00815       histsum->SetBinContent(ibin, Expectation(ibin, parameters));
00816    }
00817 
00818    // define error graph
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    // calculate uncertainty
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    // create difference histogram
00861    TH1D * hist_diff = 0;
00862 
00863    TGraphAsymmErrors * graph_diff_exp = 0;
00864 
00865    if (flag_diff) {
00866       ymin = 0;
00867       ymax = 0;
00868       //      hist_diff = new TH1D("hist_diff", "", nbins, histsum->GetXaxis()->GetXmin(), histsum->GetXaxis()->GetXmax() );
00869       //      hist_diff = new TH1D(*histsum);
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    // draw histograms
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    // delete temporary histograms
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    // loop over bins
00980    for (int ibin = 1; ibin <= fNBins; ++ibin) {
00981       // get expectation
00982       double nexp = Expectation(ibin, parameters);
00983 
00984       // get data
00985       double ndata = fHistData.GetBinContent(ibin);
00986 
00987       // add to chi2
00988       chi2 += (nexp - ndata) * (nexp - ndata) / nexp;
00989    }
00990 
00991    // return chi2
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    // return chi2 probability
01002    return TMath::Prob(chi2, ndf);
01003 }
01004 
01005 // ---------------------------------------------------------
01006 double BCTemplateFitter::CalculateMaxLike()
01007 {
01008    // return maximum likelihood
01009    return Eval( GetBestFitParameters() );
01010 }
01011 
01012 // ---------------------------------------------------------
01013 double BCTemplateFitter::CalculateKSProb()
01014 {
01015    // create a temporary histogram with the sum of all contributions
01016     TH1D * histsum = new TH1D(fHistData);
01017 
01018    // get best fit parameters
01019    std::vector<double> parameters = GetBestFitParameters();
01020 
01021    // loop over bins
01022    for (int ibin = 1; ibin <= fNBins; ++ibin) {
01023       // get expectation
01024       double nexp = Expectation(ibin, parameters);
01025 
01026       // set bin content
01027       histsum->SetBinContent(ibin, nexp);
01028    }
01029 
01030    // perform KS test
01031    double ksprob = histsum->KolmogorovTest(&fHistData);
01032 
01033    // delete histogram
01034    delete histsum;
01035 
01036    return ksprob;
01037 }
01038 
01039 // ---------------------------------------------------------
01040 double BCTemplateFitter::CalculatePValue()
01041 {
01042    // get best fit parameters
01043    std::vector<double> par = GetBestFitParameters();
01044 
01045    // check size of parameter vector
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    // define starting distribution
01061    for (int ibin = 1; ibin <= fNBins; ++ibin) {
01062 
01063       // get expectation
01064       double nexp = Expectation(ibin, par);
01065 
01066       /*
01067       double nexp = 0;
01068 
01069       // loop over all templates
01070       for (int itemp = 0; itemp < ntemplates; ++itemp) {
01071          int tempindex = fTemplateParIndexContainer.at(itemp);
01072          int effindex = fEffParIndexContainer.at(itemp);
01073 
01074          // get efficiency for the bin
01075          double efficiency = fEffHistogramContainer.at(itemp).GetBinContent(ibin);
01076 
01077          // modify efficiency by uncertainty
01078          double efferr = fEffErrHistogramContainer.at(itemp).GetBinContent(ibin);
01079 
01080          // check efficiency error
01081          if (efferr > 0)
01082             efficiency = TMath::Max(0., efficiency + par.at(effindex) * efferr);
01083 
01084          // add expectation from bin
01085          nexp += par.at(tempindex) * efficiency * fTemplateHistogramContainer.at(itemp).GetBinContent(ibin);
01086       }
01087       */
01088 
01089 
01090       histogram[ibin-1]   = int(nexp);
01091       expectation[ibin-1] = nexp;
01092 
01093       // calculate p;
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    // loop over iterations
01101    for (int iiter = 0; iiter < niter; ++iiter) {
01102       // loop over bins
01103       for (int ibin = 0; ibin < fNBins; ++ibin) {
01104          // random step up or down in statistics for this bin
01105          double ptest = fRandom->Rndm() - 0.5;
01106 
01107          // increase statistics by 1
01108          if (ptest > 0) {
01109             // calculate factor of probability
01110             double r = expectation.at(ibin) / double(histogram.at(ibin) + 1);
01111 
01112             // walk, or don't (this is the Metropolis part)
01113             if (fRandom->Rndm() < r) {
01114                histogram[ibin] = histogram.at(ibin) + 1;
01115                logp += log(r);
01116             }
01117          }
01118 
01119          // decrease statistics by 1
01120          else if (ptest <= 0 && histogram[ibin] > 0) {
01121             // calculate factor of probability
01122             double r = double(histogram.at(ibin)) / expectation.at(ibin);
01123 
01124             // walk, or don't (this is the Metropolis part)
01125             if (fRandom->Rndm() < r) {
01126                histogram[ibin] = histogram.at(ibin) - 1;
01127                logp += log(r);
01128             }
01129          }
01130       } // end of looping over bins
01131 
01132       // increase counter
01133       if (logp < logp_start)
01134          counter_pvalue++;
01135 
01136    } // end of looping over iterations
01137 
01138    // calculate p-value
01139    return double(counter_pvalue) / double(niter);
01140 }
01141 
01142 // ---------------------------------------------------------
01143 void BCTemplateFitter::MCMCUserIterationInterface()
01144 {
01145    // loop over all bins
01146    for (int ibin = 1; ibin <= fNBins; ++ibin) {
01147       // get bin content
01148       double bincontent = Expectation(ibin, fMCMCx);
01149 
01150       // set bin content
01151       fUncertaintyHistogramExp->Fill(fHistData.GetBinCenter(ibin), bincontent);
01152 
01153       // loop over bins in the other direction
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    // fill normalization
01163    fHistNorm.Fill(fNorm);
01164 
01165    // fill ratios
01166    int nratios = int( fIndicesRatios1D.size() );
01167 
01168    // loop over fractions to fill
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    // free memory
01208    delete c1;
01209    delete ps;
01210 }
01211 
01212 // ---------------------------------------------------------
01213 int BCTemplateFitter::SetTemplateEfficiency(const char * name, TH1D eff, TH1D efferr)
01214 {
01215    // get index
01216    int index = GetIndexTemplate(name);
01217 
01218    // check index
01219    if (index < 0) {
01220       BCLog::OutError("BCTemplateFitter::SetTemplateEfficiency : Could not find template.");
01221       return 0;
01222    }
01223 
01224    // check efficiency histogram
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    // set histogram style
01232    eff.SetXTitle((fHistData.GetXaxis())->GetTitle());
01233    eff.SetYTitle("Efficiency");
01234 
01235    efferr.SetXTitle((fHistData.GetXaxis())->GetTitle());
01236    efferr.SetYTitle("Efficiency uncertainty");
01237 
01238    // set efficiency histogram
01239    fEffHistogramContainer[index] = eff;
01240    fEffErrHistogramContainer[index] = efferr;
01241 
01242    // no error
01243    return 1;
01244 }
01245 
01246 // ---------------------------------------------------------
01247 int BCTemplateFitter::SetTemplateEfficiency(const char * name, double effmean, double effsigma)
01248 {
01249    // get index
01250    int index = GetIndexTemplate(name);
01251 
01252    // check index
01253    if (index < 0) {
01254       BCLog::OutError("BCTemplateFitter::SetTemplateEfficiency : Could not find template.");
01255       return 0;
01256    }
01257 
01258    // create histograms
01259    TH1D histeff = TH1D(fHistData);
01260     TH1D histefferr = TH1D(fHistData);
01261 
01262    // fill histograms
01263    for (int i = 1; i <= fNBins; ++i) {
01264       histeff.SetBinContent(i, effmean);
01265       histefferr.SetBinContent(i, effsigma);
01266    }
01267 
01268    // set histograms
01269    int err = SetTemplateEfficiency(name, histeff, histefferr);
01270 
01271    // return error code
01272    return err;
01273 }
01274 
01275 // ---------------------------------------------------------
01276 int BCTemplateFitter::ConstrainSum(std::vector<int> indices, double mean, double rms)
01277 {
01278    // add contraint to container(s)
01279    fConstraintSumIndices.push_back(indices);
01280    fConstraintSumMean.push_back(mean);
01281    fConstraintSumRMS.push_back(rms);
01282 
01283    // no error
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    // get number of sources of systematic uncertainty
01307    int nsyst = GetNSystErrors();
01308 
01309    // get index
01310    int index = GetIndexTemplate(name);
01311 
01312    // check index
01313    if (index < 0) {
01314       BCLog::OutError("BCTemplateFitter::PrintTemplate : Could not find template.");
01315       return 0;
01316    }
01317 
01318    // remember old directory
01319    TDirectory* dir = gDirectory;
01320 
01321    // create postscript
01322    TPostScript * ps = new TPostScript(filename);
01323 
01324    // create new canvas
01325    TCanvas * c1 = new TCanvas("", "", 700, 700);
01326 
01327    c1->Update();
01328    ps->NewPage();
01329    c1->cd();
01330 
01331    // create legend
01332    TLegend l1(0.18, 0.75, 0.85, 0.85);
01333    l1.SetBorderSize(0);
01334    l1.SetFillColor(kWhite);
01335 
01336    // draw histogram and uncertainties
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    // draw legend
01363    l1.Draw();
01364 
01365    // update ps
01366    c1->Update();
01367    ps->NewPage();
01368    c1->cd();
01369 
01370    // create legend
01371    TLegend l2(0.18, 0.75, 0.85, 0.85);
01372    l2.SetBorderSize(0);
01373    l2.SetFillColor(kWhite);
01374 
01375    // print uncertainties
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    // loop over all uncertainties
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    // draw legend
01408    l2.Draw();
01409 
01410    // close ps
01411    c1->Update();
01412    ps->Close();
01413 
01414    // change to old directory
01415    dir->cd();
01416 
01417    // free memory
01418    delete c1;
01419    delete ps;
01420 
01421    // no error
01422    return 1;
01423 }
01424 
01425 // ---------------------------------------------------------
01426 TH1D BCTemplateFitter::CreateErrorHist(TH1D hist, TH1D histerr)
01427 {
01428    // check histogram properties
01429    if (CompareHistogramProperties(fHistData, hist) != 1) {
01430       BCLog::OutError("BCTemplateFitter::CreateErrorHist : Histograms are incompatible.");
01431       return hist;
01432    }
01433 
01434    // copy histogram
01435    TH1D h = hist;
01436 
01437    // set style
01438    h.SetStats(kFALSE);
01439    h.SetFillColor(kYellow);
01440    h.SetFillStyle(1001);
01441 
01442    // get number of bins
01443    int nbins = hist.GetNbinsX();
01444 
01445    // loop over bins
01446    for (int i = 1; i <= nbins; ++i)
01447       h.SetBinError(i, histerr.GetBinContent(i) * hist.GetBinContent(i));
01448 
01449    // return histogram
01450    return h;
01451 }
01452 
01453 // ---------------------------------------------------------
01454 TH1D BCTemplateFitter::CombineUncertainties(const char * name)
01455 {
01456    // get number of sources of systematic uncertainty
01457    int nsyst = GetNSystErrors();
01458 
01459    // get template index
01460    int tempindex = GetIndexTemplate(name);
01461 
01462    // create new histogram
01463    //    TH1D hist = TH1D("", "", fNBins, fXmin, fXmax);
01464     TH1D hist = TH1D(fHistData);
01465 
01466    // fill histogram
01467    for (int ibin = 1; ibin <= fNBins; ++ibin) {
01468 
01469       // define total uncertainty
01470       double err = 0;
01471 
01472       // add efficiency uncertainty squared
01473       double erreff = fEffErrHistogramContainer.at(tempindex).GetBinContent(ibin);
01474       err += erreff * erreff;
01475 
01476       // add systematic uncertainty squared
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       // take square root
01483       err = sqrt(err);
01484 
01485       // set bin content
01486       hist.SetBinContent(ibin, err);
01487    }
01488 
01489    // return histogram
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    // return index
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    // return index
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    // return index
01547    return index;
01548 }
01549 
01550 // ---------------------------------------------------------
01551 int BCTemplateFitter::GetParIndexTemplate(int index)
01552 {
01553    // get number of templates
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    // return index
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    // return index
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    // return index
01600    return index;
01601 }
01602 
01603 // ---------------------------------------------------------
01604 int  BCTemplateFitter::PerformFit()
01605 {
01606    // initialize
01607    if (!Initialize()) {
01608       BCLog::OutError("BCTemplateFitter::PerformFit : Could not initialize template fitter.");
01609       return 0;
01610    }
01611 
01612    // run Markov Chains
01613    MarginalizeAll();
01614 
01615    // find global mode
01616    FindMode();
01617 
01618    // no error
01619    return 1;
01620 }
01621 
01622 // ---------------------------------------------------------
01623 int BCTemplateFitter::GetNTemplatesType(int templatetype)
01624 {
01625    // get number of templates
01626    int ntemplates = GetNTemplates();
01627 
01628    // initialize counter to zero
01629    int counter = 0;
01630 
01631    // loop over all templates
01632    for (int i = 0; i < ntemplates; ++i) {
01633       // increase counter if template of same type
01634       if (templatetype == fTemplateTypeContainer.at(i))
01635          counter++;
01636    }
01637 
01638    // return counter
01639    return counter;
01640 }
01641 
01642 // ---------------------------------------------------------

Generated by  doxygen 1.7.1