//Renata Kopecna

#include <bu2kstarmumu_plotter.hh>

#include <TH1D.h>
#include <TLegend.h>
#include <TColor.h>
#include <TROOT.h>
#include <TGaxis.h>
#include <TStyle.h>

#include <constants.hh>
#include <design.hh>
#include <funcs.hh>
#include <integrals.hh>
#include <helpers.hh>
#include <event.hh>

#include <spdlog.h>

//possible TODO when bored: This could be shortened even further, but I cannot be bothered at the moment

//Bkg plots were very flat resulting in the plots sometimes having too large minimum, so set manualy now
const double minBkg = 0.0;

using namespace fcnc;

bu2kstarmumu_plotter::bu2kstarmumu_plotter(options* o):
    opts(o)
{
    gROOT->SetStyle("Plain");

    TPad foo;
    const int NRGBs = 5;
    const int NCont = 250;

    double stops[NRGBs] = { 0.00, 0.45, 0.60, 0.74, 1.00 };
    double red[NRGBs]   = { 0.00, 0.00, 0.52, 1.00, 0.41 };
    double green[NRGBs] = { 0.00, 0.61, 1.00, 0.35, 0.00 };
    double blue[NRGBs]  = { 0.68, 1.00, 0.12, 0.00, 0.00 };

    TColor::CreateGradientColorTable(NRGBs, stops, red, green, blue, NCont);
    gStyle->SetNumberContours(NCont);
    gStyle->SetLabelFont(132, "xyz");
    gStyle->SetTitleFont(132, "xyz");
    gStyle->SetLegendFont(132);
    gStyle->SetStatFont(132);
    gStyle->SetEndErrorSize(10.0); //Sets the lenght of the tiny bars at the end of error bars

    //by default draw pulls underneath the 1D projections:
    this->pulls = true;

};

bu2kstarmumu_plotter::~bu2kstarmumu_plotter()
{
};


int bu2kstarmumu_plotter::plot_data(bu2kstarmumu_pdf* prob, bu2kstarmumu_parameters* params, std::vector<event>* events, std::string prefix, std::string postfix, bool signalregion){
    //Calls plot_m, plot_mkpi and plot_angle
    if(events->size() == 0){
        spdlog::error("Cannot plot empty event histograms!");
        return 404;
    }

    spdlog::debug("Plotting of projections started.");
    prob->update_cached_normalization(params);
    spdlog::trace("Normalization updated.");
    output = new TFile((opts->plot_folder+"projections_" + opts->name + ".root").c_str(), "UPDATE");
    spdlog::debug("Created file " + std::string(output->GetPath()));
    std::string logstr = std::string("log_")+postfix;
    spdlog::trace("TFile created.");

    //m(B)
    if(!opts->only_angles && !opts->only_mkpi){
        spdlog::debug("Plotting B mass.");
        plot_m(prob, params, events, prefix, postfix, false, false);
        plot_m(prob, params, events, prefix, logstr , true,  false);
    }

    //m(Kpi)
    if (opts->fit_mkpi || opts->use_mkpi){
        plot_mkpi(prob, params, events, prefix, postfix, signalregion, false, false);
    }

    //angles
    if(!opts->only_Bmass && !opts->only_mass2DFit && !opts->only_mkpi){
        spdlog::debug("Plotting angles.");
        plot_angle(prob, params, events, prefix, postfix, signalregion, "ctl", false);
        plot_angle(prob, params, events, prefix, postfix, signalregion, "ctk", false);
        plot_angle(prob, params, events, prefix, postfix, signalregion, "phi", false);
    }
    output->Close();
    delete output;
    return 0;
};


//Few functions making pretty TH1Ds

int design_pdfLine(TH1D *pdf, Color_t lineColor, Style_t lineStyle){
    pdf->SetLineWidth(2.0);
    pdf->SetLineColor(lineColor);
    pdf->SetLineStyle(lineStyle);
    pdf->GetXaxis()->SetNoExponent(kTRUE);
    return 0;
}

int design_pdfLine(TH1D *pdf, Color_t lineColor, Style_t lineStyle, int lineWidth){
    pdf->SetLineWidth(lineWidth);
    pdf->SetLineColor(lineColor);
    pdf->SetLineStyle(lineStyle);
    pdf->GetXaxis()->SetNoExponent(kTRUE);
    return 0;
}

int design_plot(TH1D *plot, int markerStyle, bool printC){
    plot->SetMarkerStyle(markerStyle);
    plot->SetMarkerSize(printC ? 1.0 : 2.0);
    plot->GetXaxis()->SetNoExponent(kTRUE);
    return 0;
}

TLatex *design_TLatex(double texsizelarge, double texsizesmall, double pullHeight, double pos,
                      bool pulls, std::string plot_label, std::string q2_label){

    TLatex *tex = getPrettyTex(texsizelarge,11);


    if(pulls) tex->SetTextSize(texsizelarge/(1 - pullHeight));
    tex->DrawLatexNDC(pos,(pulls ? (0.8 - pullHeight)/(1 - pullHeight) : 0.8),plot_label.c_str());

    if(PLOT_THISTHESIS_TAG){
        tex->DrawLatexNDC(0.7,(pulls ? (0.82 - pullHeight)/(1 - pullHeight) : 0.82),THISTHESIS_TAG.c_str());
    }

    tex->SetTextSize(texsizesmall);
    if(pulls) tex->SetTextSize(texsizesmall/(1 - pullHeight));
    tex->DrawLatexNDC(pos,(pulls ? (0.74 - pullHeight)/(1 - pullHeight) : 0.74),q2_label.c_str());

    return tex;
}

int bu2kstarmumu_plotter::design_pdf(TH1D *pdf, Color_t lineColor, Color_t fillColor,
                                     int fillStyle, double eff_pullHeight, bool doPull){
    pdf->SetLineWidth(2.0);
    pdf->SetLineColor(lineColor);
    pdf->SetFillStyle(fillStyle);
    pdf->SetFillColor(fillColor);
    pdf->GetXaxis()->SetNoExponent(kTRUE);
    if(doPull){
        Float_t textsize = gStyle->GetTextSize();
        design_pull_basic(pdf, textsize, eff_pullHeight);
        pdf->GetXaxis()->SetTickLength(pdf->GetXaxis()->GetTickLength()/eff_pullHeight);

        pdf->GetXaxis()->SetTitle("");
        pdf->GetXaxis()->SetLabelSize(0.0);//don't print labels
        pdf->GetYaxis()->SetNdivisions(gStyle->GetNdivisions("Y"));
    }
    return 0;
}


//Plot (log) mass
void bu2kstarmumu_plotter::plot_m(bu2kstarmumu_pdf* prob, bu2kstarmumu_parameters* params, std::vector<event>* events, std::string prefix, std::string postfix, bool logarithmic, bool printC)
{
    unsigned int m_bins = opts->plots_m_bins;
    double m_min = params->m_b.get_min();
    double m_max = params->m_b.get_max();
    double fsig = params->f_sig();
    if (opts->extended_ml){
        fsig = params->n_sig()/(params->n_sig()+params->n_bkg());
    }

    TCanvas *m_canvas = nullptr;
    std::string m_canvas_name = "Bplus Likelihood Analysis: #it{m}(#it" +latex_decay(opts->DTF) +") mass projection";
    if(printC) m_canvas = new TCanvas(("m_"+postfix).c_str(), m_canvas_name.c_str()) ;
    else       m_canvas = new TCanvas(("m_"+postfix).c_str(), m_canvas_name.c_str(),1600,1200);

    const double pullHeight = 0.27;
    const double pullFrameRange = 6.5;
    TPad *pad1 = new TPad("pad1", "plot",0.0,pullHeight,1.0,1.0,0);
    TPad *pad2 = new TPad("pad2", "pull",0.0,0.0,1.0,pullHeight,0);
    if(this->pulls){
        pad1->Draw();
        pad2->Draw();
        pad1->SetLogy(logarithmic);
        pad1->SetBorderSize  (0);
        pad1->SetMargin(0.125,0.1,1e-6,0.1/ (1 - pullHeight));
        pad1->SetTickx();
        pad1->SetTicky();
        pad1->cd();
    }
    else{
        m_canvas->cd()->SetMargin(0.125,0.1,0.125,0.1);
        m_canvas->SetLogy(logarithmic);
        m_canvas->SetTickx();
        m_canvas->SetTicky();
    }

    std::ostringstream sout;
    sout << ";#it{m}(" + latex_decay(opts->DTF) + ") ["+MeVc()+"];" << EVENTS_TAG << " / " << std::setprecision(2) << (m_max-m_min)/m_bins << " "+MeVc()+"";

    TH1D* m_plot_sig = new TH1D("msig", sout.str().c_str(), m_bins, m_min, m_max);
    TH1D* m_plot_bkg = new TH1D("mbkg", sout.str().c_str(), m_bins, m_min, m_max);
    TH1D* m_plot = new TH1D("m", sout.str().c_str(), m_bins, m_min, m_max);
    m_plot->Sumw2();
    std::ostringstream spulls;
    spulls << ";#it{m}(" + latex_decay(opts->DTF) + ") ["+MeVc()+"];" + latex_pull();


    TH1D* m_pulls = new TH1D("mpulls", spulls.str().c_str(), m_bins, m_min, m_max);
    spdlog::trace("Filling the histograms with {0:d} events.", events->size());
    double nevents = 0.0;
    for (auto evt: *events){
        double weight = 1.0;
        if(opts->weighted_fit) weight = evt.weight;
        if(evt.event_type == 0) m_plot_sig->Fill(evt.m, weight);
        else                    m_plot_bkg->Fill(evt.m, weight);
        m_plot->Fill(evt.m, weight);
        nevents += weight;
    }
    spdlog::trace("Filled.");
    const int bin_ratio = 20;
    unsigned int pdf_bins = m_bins*bin_ratio;
    if (pdf_bins == 0) spdlog::critical("No PDF bins!");
    double dm = (m_max-m_min)/pdf_bins;
    TH1D* pdf_sig = new TH1D("pdf_sig", sout.str().c_str(), pdf_bins, m_min, m_max);
    TH1D* pdf_bkg = new TH1D("pdf_bkg", sout.str().c_str(), pdf_bins, m_min, m_max);
    TH1D* pdf_tot = new TH1D("pdf_tot", sout.str().c_str(), pdf_bins, m_min, m_max);

    spdlog::trace("Getting parameter values...");
    double m_b     = params->m_b();
    double m_scale = params->m_scale();
    double f_res   = params->m_res_1();
    double sigma_1 = params->m_sigma_1();
    double sigma_2 = params->m_sigma_2();
    double alpha_1 = opts->crystalball || opts->twotailedcrystalball ? params->alpha_1() : 0.;
    double alpha_2 = opts->crystalball || opts->twotailedcrystalball ? params->alpha_2() : 0.;
    double n_1     = opts->crystalball || opts->twotailedcrystalball ? params->n_1() : 0.;
    double n_2     = opts->crystalball || opts->twotailedcrystalball ? params->n_2() : 0.;

    double prob_sig = 0.0, prob_bkg = 0.0, from = 0.0, to = 0.0;

    double integral1 = 1.0, integral2 = 1.0;
    spdlog::trace("Integrating...");
    if(opts->crystalball){
        integral1 = integrate_crystalball(m_b, m_scale*sigma_1, alpha_1, n_1, m_min, m_max);
        integral2 = integrate_crystalball(m_b, m_scale*sigma_2, alpha_2, n_2, m_min, m_max);
    }
    else if(opts->twotailedcrystalball){
        integral1 = integrate_twotailedcrystalball(m_b, m_scale*sigma_1, alpha_1, alpha_2, n_1, n_2, m_min, m_max);
    }
    else{
        integral1 = integrate_gauss(m_scale*sigma_1, m_b, m_min, m_max);
        integral2 = integrate_gauss(m_scale*sigma_2, m_b, m_min, m_max);
    }
    if (isnan(integral1) || isnan(integral2)){
        spdlog::critical("integral1 is NaN");
        return;
    }

    spdlog::trace("Getting signal prob...");
    for (unsigned int i = 0; i < pdf_bins; i++){
        from = m_min + i*dm;
        to   = m_min + (i+1)*dm;
        prob_sig = 0.0;
        if (opts->crystalball){
            prob_sig = integrate_crystalball(m_b, m_scale*sigma_1, alpha_1, n_1, from, to) / integral1;
            if (f_res != 1.0){
                prob_sig *= f_res;
                prob_sig += (1.0-f_res)
                        * integrate_crystalball(m_b, m_scale*sigma_2, alpha_2, n_2, from, to) / integral2;
            }
        }
        else if(opts->twotailedcrystalball){
            prob_sig = integrate_twotailedcrystalball(m_b, m_scale*sigma_1, alpha_1, alpha_2, n_1, n_2, from, to) / integral1;
        }
        else{
            prob_sig = integrate_gauss(m_scale*sigma_1, m_b, from, to) / integral1;
            if (f_res != 1.0){
                prob_sig *= f_res;
                prob_sig += (1.0 - f_res)
                        * integrate_gauss(m_scale*sigma_2, m_b, from, to) / integral2;
            }
        }
        if (isnan(prob_sig)){
            spdlog::critical("prob_sig is nan");
            spdlog::critical("pdf bin {0:d}, edges: {1:f}-{2:f}", i, pdf_sig->GetBinLowEdge(i+1), pdf_sig->GetBinLowEdge(i+2));
            return;
        }

        pdf_sig->SetBinContent(i+1, prob_sig);
        prob_bkg = prob->integral_m_bkg_prob(params, from, to);
        if (isnan(prob_bkg)){
            spdlog::error("prob_bkg is nan");
            spdlog::error("pdf bin {0:d}, edges: {1:f}-{2:f}", i, from, to);
            spdlog::error("Setting prob_bkg to ZERO!");
            prob_bkg = 0;
        }
        pdf_bkg->SetBinContent(i+1, prob_bkg);
    }

    pdf_sig->Scale(nevents * fsig       * double(pdf_bins) / double(m_bins));
    pdf_bkg->Scale(nevents * (1.0-fsig) * double(pdf_bins) / double(m_bins));
    pdf_tot->Add(pdf_sig, pdf_bkg);

    spdlog::trace("Making the plots pretty...");
    double maxpdf = (pdf_tot->GetMaximum() > m_plot->GetMaximum() ? pdf_tot->GetMaximum() : m_plot->GetMaximum());
    if(this->pulls){
        if (logarithmic) pdf_sig->SetMinimum(0.1001);
        else             pdf_sig->SetMinimum(0.001);
    }
    else{ //no pull distributions
        if (logarithmic) pdf_sig->SetMinimum(0.1);
        else             pdf_sig->SetMinimum(0.0);
    }
    pdf_sig->SetMaximum(1.45*maxpdf);

    pdf_bkg->SetTitleSize(0.06, "XY");
    pdf_bkg->SetLabelSize(0.05, "XY");
    pdf_bkg->SetTitleOffset(0.9, "XY");
    pdf_bkg->GetXaxis()->SetNoExponent(kTRUE);
    TGaxis::SetMaxDigits(3);

    design_pdf(pdf_sig, kAzure, kAzure-5, 1001, 1-pullHeight, this->pulls);
    if(pdf_sig->Integral() > 0.0)  pdf_sig->Draw("hist C");

    design_pdf(pdf_bkg, kOrange+10, kOrange+8, 3354, 1-pullHeight, pdf_sig->Integral() <= 0.0 );
    if(pdf_sig->Integral() > 0.0){
        pdf_bkg->Draw("hist same C");
    }
    else{
        pdf_bkg->SetMaximum(1.45*maxpdf);
        pdf_bkg->SetMinimum(minBkg);
        pdf_bkg->Draw("hist C");
    }

    design_pdfLine(pdf_tot,kBlack,2.0);
    pdf_tot->Draw("hist same C");

    design_plot(m_plot,20,printC);
    m_plot->Draw("same e1");
    if (m_plot_bkg->Integral() != 0){
        design_pdfLine(m_plot_sig,4,kSolid);
        m_plot_sig->Draw("esame");        
        design_pdfLine(m_plot_bkg,2,kSolid);
        if (params->f_sig() != 1.0) m_plot_bkg->Draw("esame");
    }

    //draw legend    
    spdlog::trace("Drawing legend...");
    TLegend* m_leg = new TLegend(0.675,0.45,0.875,0.65);
    m_leg->SetBorderSize(0);
    m_leg->SetTextFont(132);
    m_leg->SetFillColor(0);
    m_leg->AddEntry(m_plot, "data", "le");
    m_leg->AddEntry(pdf_tot, "total PDF", "l");
    m_leg->AddEntry(pdf_sig, "signal PDF", "l");
    m_leg->AddEntry(pdf_bkg, "bkg PDF", "l");
    //m_leg->Draw();
    TLatex *tex = design_TLatex(texsizelarge,texsizesmall, pullHeight, 0.47,
                                this->pulls, opts->plot_label, opts->q2_label);
    if(this->pulls){        
        spdlog::trace("Drawing pulls...");
        assert(pdf_bins == m_bins*bin_ratio);

        //calculate pulls from fit and data points:
        for(UInt_t b = 1; b <= m_bins; b++){
            double p;
            if(m_plot->GetBinError(b) == 0) p = 0.;
            else{
                if(bin_ratio == 1){
                    p = (m_plot->GetBinContent(b) - pdf_tot->GetBinContent(b))/m_plot->GetBinError(b);
                }
                //for odd ratio, take central bin from pdf w.r.t to m_bin:
                else if(bin_ratio%2 != 0){
                    p = (m_plot->GetBinContent(b) - pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2))/m_plot->GetBinError(b);
                }
                //else, average the two central bins from pdf w.r.t. to angle_bin:
                else{
                    p = (m_plot->GetBinContent(b) - (pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2)+pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2 + 1))/2. ) / m_plot->GetBinError(b); //take central of 10 pdfbins
                }
            }
            m_pulls->SetBinContent(b, p);
        }
        pad2->Clear();
        pad2->SetMargin(0.125,0.1,0.125/ pullHeight, 1e-6);
        pad2->SetTickx();
        pad2->cd();

        design_pull(m_pulls, kBlack,kGray+2,pullHeight,pullFrameRange);
        m_pulls->Draw();

        //add two 3-sigma lines:
        TLine * lUp  = threeSigmaLine(m_min, m_max, true);
        TLine * lLow = threeSigmaLine(m_min, m_max, false);
        lUp->Draw("same");
        lLow->Draw("same");
    }

    std::string mname = prefix + "m_" + postfix;
    spdlog::debug("Writting into " + mname);
    saveTCanvas(m_canvas,mname,opts->getAllPlotTypes());

    output->cd();
    m_canvas->Write();

    delete m_plot;
    delete m_plot_sig;
    delete m_plot_bkg;
    delete pdf_sig;
    delete pdf_bkg;
    delete pdf_tot;
    delete m_pulls;
    delete m_canvas;
    delete tex;
};

void bu2kstarmumu_plotter::plot_mkpi(bu2kstarmumu_pdf* prob, bu2kstarmumu_parameters* params, std::vector<event>* events, std::string prefix, std::string postfix, bool signalregion, bool logarithmic, bool printC)
{
    double ma = params->m_b() - B_MASS_TIGHT_WINDOW;
    double mb = params->m_b() + B_MASS_TIGHT_WINDOW;
    double fsig = params->f_sig();
    if(opts->extended_ml){
        fsig = params->n_sig() / (params->n_sig()+params->n_bkg());
    }
    if(signalregion){
        double rsig = prob->integral_m_sig_prob(params, ma, mb);
        double rbkg = prob->integral_m_bkg_prob(params, ma, mb);
        fsig = fsig*rsig/(fsig*rsig + (1.0-fsig)*rbkg);
    }

    unsigned int mkpi_bins = opts->plots_mkpi_bins;
    double mkpi_min = opts->mkpi_min/1.0e+3;
    double mkpi_max = opts->mkpi_max/1.0e+3;

    TCanvas *mkpi_canvas = nullptr;
    std::string mkpi_canvas_name = "B plus Likelihood Analysis: #it{m}(#it"+ latex_Kst_decay(opts->DTF) +") ["+GeVc()+"]";
    if(printC){
        mkpi_canvas = new TCanvas(("mkpi_"+postfix).c_str(), mkpi_canvas_name.c_str());
    }
    else{
        mkpi_canvas = new TCanvas(("mkpi_"+postfix).c_str(), mkpi_canvas_name.c_str(),1600,1200) ;
    }
    const double pullHeight = 0.27;
    const double pullFrameRange = 6.5;
    TPad *pad1 = new TPad("pad1", "plot",0.0,pullHeight,1.0,1.0,0);
    TPad *pad2 = new TPad("pad2", "pull",0.0,0.0,1.0,pullHeight,0);
    if(this->pulls){
        pad1->Draw();
        pad2->Draw();
        pad1->SetLogy(logarithmic);
        pad1->SetBorderSize  (0);
        pad1->SetMargin(0.125,0.1,1e-6,0.1/ (1 - pullHeight));
        pad1->SetTickx();
        pad1->SetTicky();
        pad1->cd();
    }
    else{
        mkpi_canvas->cd()->SetMargin(0.125,0.1,0.125,0.1);
        mkpi_canvas->SetTickx();
        mkpi_canvas->SetTicky();
    }

    std::ostringstream sout;
    sout << ";#it{m}(#it{K}^{+}#pi^{-}) ["+GeVc()+"];" << EVENTS_TAG << " / " << std::setprecision(2) << (mkpi_max-mkpi_min)/mkpi_bins << " GeV^{2}/#it{c}^{4}";
    TH1D* mkpi_plot_sig = new TH1D("mkpi_sig", sout.str().c_str(), mkpi_bins, mkpi_min, mkpi_max);
    TH1D* mkpi_plot_bkg = new TH1D("mkpi_bkg", sout.str().c_str(), mkpi_bins, mkpi_min, mkpi_max);
    TH1D* mkpi_plot = new TH1D("mkpi", sout.str().c_str(), mkpi_bins, mkpi_min, mkpi_max);

    mkpi_plot->Sumw2();
    std::string spulls = ";#it{m}("+ latex_Kst_decay(opts->DTF) +") ["+GeVc()+"];" + latex_pull();

    TH1D* mkpi_pulls = new TH1D("mkpipulls", spulls.c_str(), mkpi_bins, mkpi_min, mkpi_max);
    double nevents = 0.0;

    for (auto evt: *events){
        if (!signalregion || (evt.m > ma && evt.m < mb)){
            double weight = 1.0;
            double mkpi = evt.mkpi/1.0e+3;
            if (opts->weighted_fit){
                weight = evt.weight;
                mkpi_plot->Fill(mkpi, weight);
            }
            else mkpi_plot->Fill(mkpi);

            if(evt.event_type == 0) mkpi_plot_sig->Fill(mkpi, weight);
            else                              mkpi_plot_bkg->Fill(mkpi, weight);
            nevents += weight;
        }
    }

    const UInt_t bin_ratio = PLOT_NBINS_RATIO;
    unsigned int pdf_bins = mkpi_bins*bin_ratio;
    double dm = (mkpi_max-mkpi_min)/pdf_bins;
    TH1D* pdf_sig = new TH1D("pdf_sig", sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
    TH1D* pdf_swave = new TH1D("pdf_swave", sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
    TH1D* pdf_pwave = new TH1D("pdf_pwave", sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
    TH1D* pdf_interference = new TH1D("pdf_interference", sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
    TH1D* pdf_bkg = new TH1D("pdf_bkg", sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
    TH1D* pdf_tot = new TH1D("pdf_tot", sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);

    double gammakstar = params->gammakstar();
    double mkstar = params->mkstar();
    double asphase = params->asphase();
    double a = params->a();
    double r = params->r();
    double R = params->R();

    double gammakstarplus = params->gammakstarplus();
    double mkstarplus = params->mkstarplus();
    double gammaf800 = params->gammaf800();
    double mf800 = params->mf800();
    double f800mag = params->f800mag();
    double f800phase = params->f800phase();

    double normbkg=0.0;
    std::vector<double> ch_mkpi(5, 0.0);
    ch_mkpi.at(0) = params->cbkgmkpi0();
    ch_mkpi.at(1) = params->cbkgmkpi1();
    ch_mkpi.at(2) = params->cbkgmkpi2();
    ch_mkpi.at(3) = params->cbkgmkpi3();
    ch_mkpi.at(4) = params->cbkgmkpi4();
    std::vector<double> poly_mkpi(ch_mkpi.size(), 0.0);
    chebyshev_to_poly(ch_mkpi, poly_mkpi);
    std::vector<double> poly_corr_mkpi(ch_mkpi.size(), 0.0);
    correct_poly(poly_mkpi, poly_corr_mkpi, mkpi_min, mkpi_max);

    if (opts->mkpi_threshold){
        normbkg = fcnc::int_threshold(mkpi_min, mkpi_max, 0.633, params->nthreshold());
    }
    else{
        for (unsigned int i=0; i<poly_mkpi.size(); i++){
            normbkg += poly_corr_mkpi.at(i)*(pow(mkpi_max,i+1)-pow(mkpi_min,i+1))/(i+1.0);
        }
    }

    double q2 = params->eff_q2();
    double rangednormkstarplus, rangednormkstar;

    if (opts->simple_mkpi){
        rangednormkstarplus = int_mkpi_simple_kstarzero_amp_squared(mkpi_min, mkpi_max, q2,
                                                                    f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus);
        rangednormkstar = int_mkpi_simple_bw_kstar_amp_squared(mkpi_min, mkpi_max, q2, gammakstar, mkstar);
    }
    else if(opts->isobar){
        rangednormkstarplus = int_mkpi_kstarzero_isobar_amp_squared(mkpi_min, mkpi_max, q2,
                                                                    f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus, R);
        rangednormkstar = int_mkpi_bw_kstar_amp_squared(mkpi_min, mkpi_max, q2, gammakstar, mkstar, R);
    }
    else{
        rangednormkstarplus = int_mkpi_kstarzero_lass_amp_squared(mkpi_min, mkpi_max, q2, asphase, a, r, gammakstarplus, mkstarplus, R);
        rangednormkstar = int_mkpi_bw_kstar_amp_squared(mkpi_min, mkpi_max, q2, gammakstar, mkstar, R);
    }

    double sxi1, sxi2, sxi3, sxi4, sxi5, sxi6;

    //weighted fit and fit without acceptance
    if (opts->use_angular_acc)prob->swave_integrated_fj_chebyshev(sxi1, sxi2, sxi3, sxi4, sxi5, sxi6, q2);
    else                      prob->swave_integrated_fj_noacc(sxi1, sxi2, sxi3, sxi4, sxi5, sxi6);

    double xi1, xi2, xi3, xi4, xi5, xi6, xi7, xi8, xi9, xi10, xi11, xi12;
    if (opts->use_angular_acc){
        prob->integrated_fj_chebyshev(xi1, xi2, xi3, xi4, xi5, xi6,
                                      xi7, xi8, xi9, xi10, xi11, xi12, q2);
    }
    else{//weighted fit and fit without acceptance
        prob->integrated_fj_noacc(xi1, xi2, xi3, xi4, xi5, xi6,
                                  xi7, xi8, xi9, xi10, xi11, xi12);
    }

    double s1s = params->J1s();
    double s1c = params->J1c();
    double s2s = params->J2s();
    double s2c = params->J2c();
    double s3 = params->J3();
    double s4 = params->J4();
    double s5 = params->J5();
    double s6s = params->J6s();
    double s6c = params->J6c();
    double s7 = params->J7();
    double s8 = params->J8();
    double s9 = params->J9();
    double fs = params->FS();
    double ss1 = params->SS1();
    double ss2 = params->SS2();
    double ss3 = params->SS3();
    double ss4 = params->SS4();
    double ss5 = params->SS5();

    double norm =
            (1-fs)*(xi1*s1s + xi2*s1c + xi3*s2s + xi4*s2c + xi5*s3 + xi6*s4
                    + xi7*s5 + xi8*s6s + xi9*s6c + xi10*s7 + xi11*s8 + xi12*s9)
            +(sxi1*fs + sxi2*ss1 + sxi3*ss2 + sxi4*ss3 + sxi5*ss4 + sxi6*ss5);
    double A = (xi1*s1s + xi2*s1c + xi3*s2s + xi4*s2c + xi5*s3 + xi6*s4
                + xi7*s5 + xi8*s6s + xi9*s6c + xi10*s7 + xi11*s8 + xi12*s9)/norm;
    double B = sxi1/norm;
    double C = (sxi2*ss1 + sxi3*ss2 + sxi4*ss3)/norm;
    double D = (sxi5*ss4 + sxi6*ss5)/norm;

    double prob_bkg = 0.0, from = 0.0, to = 0.0;
    for (unsigned int i = 0; i < pdf_bins; i++){

        from = mkpi_min + i*dm;
        to = mkpi_min + (i+1)*dm;

        double swavesq, pwavesq;
        std::complex<double> stimespwave;

        if (opts->simple_mkpi){
            swavesq = fcnc::int_mkpi_simple_kstarzero_amp_squared(from, to, q2,
                                                                  f800mag, f800phase, gammaf800, mf800,
                                                                  gammakstarplus, mkstarplus);
            pwavesq = fcnc::int_mkpi_simple_bw_kstar_amp_squared(from, to, q2, gammakstar, mkstar);
            stimespwave = fcnc::int_mkpi_simple_bw_kstar_amp_bar_kstarzero_amp(from, to, q2,
                                                                               gammakstar, mkstar, asphase,
                                                                               f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus);
        }
        else if (opts->isobar){
            swavesq = fcnc::int_mkpi_kstarzero_isobar_amp_squared(from, to, q2,
                                                                  f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus, R);
            pwavesq = fcnc::int_mkpi_bw_kstar_amp_squared(from, to, q2, gammakstar, mkstar, R);
            stimespwave = fcnc::int_mkpi_bw_kstar_amp_bar_kstarzero_isobar_amp(from, to, q2,
                                                                               gammakstar, mkstar, asphase,
                                                                               f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus, R);
        }
        else{//nominal lass
            swavesq = fcnc::int_mkpi_kstarzero_lass_amp_squared(from, to, q2, asphase, a, r, gammakstarplus, mkstarplus, R);
            pwavesq = fcnc::int_mkpi_bw_kstar_amp_squared(from, to, q2, gammakstar, mkstar, R);
            stimespwave = fcnc::int_mkpi_bw_kstar_amp_bar_kstarzero_lass_amp(from, to, q2,
                                                                             gammakstar, mkstar,
                                                                             asphase, a, r, gammakstarplus, mkstarplus, R);
        }

        prob_bkg = 0.0;
        if (opts->mkpi_threshold){
            prob_bkg = fcnc::int_threshold(from, to, 0.633, params->nthreshold());
        }
        else{
            for (unsigned int i=0; i<ch_mkpi.size(); i++) prob_bkg += poly_corr_mkpi.at(i)*integrate_x_to_n(from, to, i);
        }
        prob_bkg /= normbkg;

        double pwave = A*pwavesq/(rangednormkstar);
        double swave = B*swavesq/(rangednormkstarplus);

        double interference = C*(stimespwave.real()/sqrt(rangednormkstarplus)/sqrt(rangednormkstar))
                + D*(stimespwave.imag()/sqrt(rangednormkstarplus)/sqrt(rangednormkstar));

        pdf_sig->SetBinContent(i+1, (1.0-fs)*pwave + fs*swave + interference);
        pdf_bkg->SetBinContent(i+1, prob_bkg);
        pdf_swave->SetBinContent(i+1, swave);
        pdf_pwave->SetBinContent(i+1, pwave);
        pdf_interference->SetBinContent(i+1, interference);
        pdf_tot->SetBinContent(i+1,
                               fsig*((1.0-fs)*pwave + fs*swave + interference)
                               + (1.0-fsig)*prob_bkg);
    }

    pdf_sig  ->Scale(nevents * fsig * double(pdf_bins) / double(mkpi_bins));
    pdf_swave->Scale(nevents * fs*fsig * double(pdf_bins) / double(mkpi_bins));
    pdf_pwave->Scale(nevents * (1.0-fs)*fsig * double(pdf_bins) / double(mkpi_bins));
    pdf_interference->Scale(nevents * fsig * double(pdf_bins) / double(mkpi_bins));
    pdf_bkg  ->Scale(nevents * (1.0-fsig) * double(pdf_bins) / double(mkpi_bins));
    pdf_tot  ->Scale(nevents * double(pdf_bins) / double(mkpi_bins));

    double maxpdf = (pdf_tot->GetMaximum() > mkpi_plot->GetMaximum() ? pdf_tot->GetMaximum() : mkpi_plot->GetMaximum());
    if(this->pulls){
        if (logarithmic) pdf_sig->SetMinimum(0.1001);
        else             pdf_sig->SetMinimum(0.001);
    }
    else{ //no pull distributions
        if (logarithmic) pdf_sig->SetMinimum(0.1);
        else             pdf_sig->SetMinimum(0.0);
    }

    pdf_sig->SetMaximum(1.45*maxpdf);
    design_pdf(pdf_sig,kAzure, kAzure-5, 1001, 1-pullHeight, this->pulls);
    if(pdf_sig->Integral() > 0.0) pdf_sig->Draw("hist C");

    design_pdf(pdf_bkg,kOrange+10,kOrange+8, 3354, 1-pullHeight,pdf_sig->Integral() <= 0.0 );

    if(pdf_sig->Integral() > 0.0){
        pdf_bkg->Draw("hist same C");
    }
    else{
        pdf_bkg->SetMaximum(1.45*maxpdf);
        pdf_bkg->SetMinimum(0.5);
        pdf_bkg->Draw("hist C");
    }

    design_pdfLine(pdf_pwave, pWaveColor, kDashed);
    if(opts->swave)  pdf_pwave->Draw("hist same C");

    design_pdfLine(pdf_swave, sWaveColor, kDotted);
    if(opts->swave)  pdf_swave->Draw("hist same C");

    design_pdfLine(pdf_interference, psInterferenceColor, kDashDotted);
    if(opts->swave)  pdf_interference->Draw("hist same C");

    design_pdfLine(pdf_tot, kBlack, kSolid);
    pdf_tot->Draw("hist same C");

    design_plot(mkpi_plot, 20, printC);
    design_pdfLine(mkpi_plot, kBlack, kSolid, 1.0);
    mkpi_plot->Draw("same e1");

    //draw legend
    TLegend* mkpi_leg = new TLegend(0.675,0.45,0.875,0.65);
    mkpi_leg->SetBorderSize(0);
    mkpi_leg->SetTextFont(132);
    mkpi_leg->SetFillColor(0);
    mkpi_leg->AddEntry(mkpi_plot, "data", "le");
    mkpi_leg->AddEntry(pdf_tot, "total PDF", "l");
    mkpi_leg->AddEntry(pdf_sig, "signal PDF", "l");
    mkpi_leg->AddEntry(pdf_bkg, "bkg PDF", "l");
    if(opts->swave){
        mkpi_leg->AddEntry(pdf_pwave, "P-wave PDF", "l");
        mkpi_leg->AddEntry(pdf_swave, "S-wave PDF", "l");
        mkpi_leg->AddEntry(pdf_interference, "interference PDF", "l");
    }

    TLatex *tex = design_TLatex(texsizelarge,texsizesmall, pullHeight, 0.67,
                                this->pulls, opts->plot_label,opts->q2_label);

    if(this->pulls){
        assert(pdf_bins == mkpi_bins*bin_ratio);

        //calculate pulls from fit and data points:
        for(UInt_t b = 1; b <= mkpi_bins; b++){
            double p;
            if(mkpi_plot->GetBinError(b) == 0){
                p = 0.;
            }
            else{
                if(bin_ratio == 1){
                    p = (mkpi_plot->GetBinContent(b) - pdf_tot->GetBinContent(b))/mkpi_plot->GetBinError(b);
                }
                //for odd ratio, take central bin from pdf w.r.t to m_bin:
                else if(bin_ratio%2 != 0){
                    p = (mkpi_plot->GetBinContent(b) - pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2))/mkpi_plot->GetBinError(b);
                }
                //else, average the two central bins from pdf w.r.t. to angle_bin:
                else{
                    p = (mkpi_plot->GetBinContent(b) - (pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2)+pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2 + 1))/2. ) / mkpi_plot->GetBinError(b); //take central of 10 pdfbins
                }
            }
            mkpi_pulls->SetBinContent(b, p);
        }
        pad2->Clear();
        pad2->SetMargin(0.125,0.1,0.125/ pullHeight, 1e-6);
        pad2->SetTickx();
        pad2->cd();

        design_pull(mkpi_pulls, kBlack,kGray+2,pullHeight,pullFrameRange);
        mkpi_pulls->Draw();

        //add two 3-sigma lines:        
        TLine * lUp  = threeSigmaLine(mkpi_min, mkpi_max, true);
        TLine * lLow = threeSigmaLine(mkpi_min, mkpi_max, false);
        lUp->Draw("same");
        lLow->Draw("same");
    }

    std::string mkpiname = prefix + "mkpi_" + postfix;
    saveTCanvas(mkpi_canvas, mkpiname, opts->getAllPlotTypes());

    output->cd();
    mkpi_canvas->Write();

    delete mkpi_plot;
    delete mkpi_plot_sig;
    delete mkpi_plot_bkg;
    delete pdf_sig;
    delete pdf_swave;
    delete pdf_pwave;
    delete pdf_interference;
    delete pdf_bkg;
    delete pdf_tot;
    delete mkpi_pulls;
    delete mkpi_canvas;
    delete tex;
};

void bu2kstarmumu_plotter::plot_angle(bu2kstarmumu_pdf* prob, bu2kstarmumu_parameters* params, std::vector<event>* events, std::string prefix, std::string postfix, bool signalregion, std::string angle, bool printC){ //signal region: plots only stuff within B_MASS_TIGHT_WINDOW MeV B mass window

    bool is_ctl = false, is_ctk = false, is_phi = false;
    std::string angle_name = latex_angle(angle, is_ctl, is_ctk, is_phi);
    spdlog::debug("angle:{0:s}\tctl:{1:d}\tctk:{2:d}\tphi:{3:d}",angle, is_ctl, is_ctk, is_phi);
    if(!is_ctl && !is_ctk && !is_phi)spdlog::error("Invalid angle name is given: " + angle);
    assert(is_ctl || is_ctk || is_phi);

    double ma = params->m_b() - B_MASS_TIGHT_WINDOW;
    double mb = params->m_b() + B_MASS_TIGHT_WINDOW;
    double fsig = params->f_sig();
    if(opts->extended_ml) fsig = params->n_sig() / (params->n_sig()+params->n_bkg());

    if (signalregion){
        double rsig = prob->integral_m_sig_prob(params, ma, mb);
        double rbkg = prob->integral_m_bkg_prob(params, ma, mb);
        fsig = fsig*rsig/(fsig*rsig + (1.0-fsig)*rbkg);
    }
    unsigned int angle_bins = 0;
    double angle_min = 0.;
    double angle_max = 0.;

    if(is_ctl){
        angle_bins = opts->plots_costhetal_bins;
        angle_min = opts->ctl_min;
        angle_max = opts->ctl_max;
        if(!opts->full_angular && opts->folding != 0) angle_bins /= 2;
    }
    else if(is_ctk){
        angle_bins = opts->plots_costhetak_bins;
        angle_min = opts->ctk_min;
        angle_max = opts->ctk_max;
    }
    else if(is_phi){
        angle_bins = opts->plots_phi_bins;
        angle_min = opts->phi_min;
        angle_max = opts->phi_max;
        if(!opts->full_angular) angle_bins /= 2;
    }

    assert(angle_min != 0. || angle_max != 0.);

    TCanvas *angle_canvas = nullptr;
    if(printC) angle_canvas = new TCanvas((angle+"_"+postfix).c_str(), ("B+ Likelihood Analysis: "+angle_name+" projection").c_str());
    else       angle_canvas = new TCanvas((angle+"_"+postfix).c_str(), ("B+ Likelihood Analysis: "+angle_name+" projection").c_str(),1600,1200);
    const double pullHeight = 0.27;
    const double pullFrameRange = 6.5;
    TPad *pad1 = new TPad(("pad1_"+angle).c_str(), "plot",0.0,pullHeight,1.0,1.0,0);
    TPad *pad2 = new TPad(("pad2_"+angle).c_str(), "pull",0.0,0.0,1.0,pullHeight,0);
    if(this->pulls){
        pad1->Draw();
        pad2->Draw();
        pad1->SetBorderSize  (0);
        pad1->SetMargin(0.125,0.1,1e-6,0.1/ (1 - pullHeight));
        pad1->SetTickx();
        pad1->SetTicky();
        pad1->cd();
    }
    else{
        angle_canvas->cd()->SetMargin(0.125,0.1,0.125,0.1);
        angle_canvas->SetTickx();
        angle_canvas->SetTicky();
    }
    std::ostringstream sout;
    sout << ";" << angle_name << ";" << EVENTS_TAG << " / " << std::setprecision(2) << (angle_max-angle_min)/angle_bins;
    TH1D* angle_plot_sig = new TH1D((angle+"_sig").c_str(), sout.str().c_str(), angle_bins, angle_min, angle_max);
    TH1D* angle_plot_bkg = new TH1D((angle+"_bkg").c_str(), sout.str().c_str(), angle_bins, angle_min, angle_max);
    TH1D* angle_plot = new TH1D((angle+"_plot").c_str(), sout.str().c_str(), angle_bins, angle_min, angle_max);
    angle_plot->Sumw2();
    std::ostringstream spulls;
    spulls << ";" << angle_name << ";" + latex_pull();
    TH1D* angle_pulls = new TH1D((angle+"_pulls").c_str(), spulls.str().c_str(), angle_bins, angle_min, angle_max);
    TH1D* angle_averaged = new TH1D((angle+"_averaged").c_str(), (angle+"_averaged").c_str(), angle_bins, angle_min, angle_max);

    bool sWeighted = false;
    double nevents = 0.0;
    for (auto evt: *events){
        if (!signalregion || (evt.m > ma && evt.m < mb)){
            double weight = 1.0, value = -100.0;
            if (opts->weighted_fit){
                weight = evt.weight;
            }
            if(evt.sweight != 1.0){
                sWeighted = true;
                weight *= evt.sweight;
            }

            if      (is_phi)value = evt.phi;
            else if (is_ctk)value = evt.costhetak;
            else if (is_ctl)value = evt.costhetal;
            else return;

            if (evt.event_type == 0) angle_plot_sig->Fill(value, weight);
            else                     angle_plot_bkg->Fill(value, weight);

            angle_plot->Fill(value, weight);
            nevents += weight;
        }
    }
    if(sWeighted) fsig = 1.0;

    const UInt_t bin_ratio = PLOT_NBINS_RATIO/2;
    unsigned int pdf_bins = angle_bins * bin_ratio;
    double dangle = (angle_max-angle_min)/pdf_bins;
    TH1D* pdf_sig = new TH1D((angle+"_pdf_sig").c_str(), sout.str().c_str(), pdf_bins, angle_min, angle_max);
    TH1D* pdf_swave = new TH1D((angle+"_pdf_swave").c_str(), sout.str().c_str(), pdf_bins, angle_min, angle_max);
    TH1D* pdf_pwave = new TH1D((angle+"_pdf_pwave").c_str(), sout.str().c_str(), pdf_bins, angle_min, angle_max);
    TH1D* pdf_interference = new TH1D((angle+"_pdf_interference").c_str(), sout.str().c_str(), pdf_bins, angle_min, angle_max);
    TH1D* pdf_bkg = new TH1D((angle+"_pdf_bkg").c_str(), sout.str().c_str(), pdf_bins, angle_min, angle_max);
    TH1D* pdf_tot = new TH1D((angle+"_pdf_tot").c_str(), sout.str().c_str(), pdf_bins, angle_min, angle_max);
    double prob_sig=0.0, prob_bkg=0.0, prob_pwave=0.0, prob_swave=0.0, prob_interference=0.0;
    double ctk_from = 0.0, ctk_to = 0.0, ctl_from=0.0, ctl_to=0.0, phi_from=0.0, phi_to=0.0;

    const double q2 = params->eff_q2();
    const double j1s = params->J1s();
    const double j1c = params->J1c();
    const double j2s = params->J2s();
    const double j2c = params->J2c();
    const double j3 = params->J3();
    const double j4 = params->J4();
    const double j5 = params->J5();
    const double j6s = params->J6s();
    const double j6c = params->J6c();
    const double j7 = params->J7();
    const double j8 = params->J8();
    const double j9 = params->J9();

    double f1=0.0, f2=0.0, f3=0.0,  f4=0.0,  f5=0.0,  f6=0.0,
            f7=0.0, f8=0.0, f9=0.0, f10=0.0, f11=0.0, f12=0.0;

    for (unsigned int i = 0; i < pdf_bins; i++){
        if(is_ctk){
            ctk_from = angle_min + i*dangle;
            ctk_to   = angle_min + (i+1)*dangle;
            ctl_from = opts->ctl_min;
            ctl_to   = opts->ctl_max;
            phi_from = opts->phi_min;
            phi_to   = opts->phi_max;
        }
        else if(is_ctl){
            ctk_from = opts->ctk_min;
            ctk_to   = opts->ctk_max;
            ctl_from = angle_min + i*dangle;
            ctl_to = angle_min + (i+1)*dangle;
            phi_from = opts->phi_min;
            phi_to   = opts->phi_max;
        }
        else if(is_phi){
            ctk_from = opts->ctk_min;
            ctk_to   = opts->ctk_max;
            ctl_from = opts->ctl_min;
            ctl_to   = opts->ctl_max;
            phi_from = angle_min + i*dangle;
            phi_to = angle_min + (i+1)*dangle;
        }
        else return;

        if (opts->full_angular){
            if (opts->use_angular_acc){
                prob->integrated_fj_chebyshev(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                              f1, f2, f3, f4, f5, f6,
                                              f7, f8, f9, f10, f11, f12, q2);
            }
            else{
                prob->integrated_fj_noacc(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                          f1, f2, f3, f4, f5, f6,
                                          f7, f8, f9, f10, f11, f12);
            }
            prob_sig = (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4

                        + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9)/prob->fnorm_sig;
            prob_pwave = prob_sig;
            if (opts->swave){
                const double fs = params->FS();
                const double js1 = params->SS1();
                const double js2 = params->SS2();
                const double js3 = params->SS3();
                const double js4 = params->SS4();
                const double js5 = params->SS5();

                double fs1=0.0, fs2=0.0, fs3=0.0, fs4=0.0, fs5=0.0, fs6=0.0;

                if (opts->use_angular_acc)
                    prob->swave_integrated_fj_chebyshev(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                                        fs1, fs2, fs3, fs4, fs5, fs6, q2);
                else
                    prob->swave_integrated_fj_noacc(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                                    fs1, fs2, fs3, fs4, fs5, fs6);

                prob_sig = ((1-fs)*(f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
                                    + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9)
                            +(fs1*fs + fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5))/prob->fnorm_sig;
                prob_pwave = ((1-fs)*(f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
                                      + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9))/prob->fnorm_sig;
                prob_swave = fs1*fs/prob->fnorm_sig;
                prob_interference = (fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5)/prob->fnorm_sig;
            }
        }
        else {
            if (opts->use_angular_acc){
                prob->folded_integrated_fj_chebyshev(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                                     f1, f2, f3, f4, f5, f6,
                                                     f7, f8, f9, f10, f11, f12, q2);
            }
            else{
                prob->folded_integrated_fj_noacc(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                                 f1, f2, f3, f4, f5, f6,
                                                 f7, f8, f9, f10, f11, f12);
            }
            //Calculated probability for all foldings
            //non-active coefficients are return 0 by 'folded'-functions in the lines above!
            prob_sig = (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3  + f6*j4
                        + f7*j5  + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9)/prob->fnorm_sig;
            prob_pwave = prob_sig;
            if(opts->swave){
                const double fs = params->FS();
                const double js1 = params->SS1();
                const double js2 = params->SS2();
                const double js3 = params->SS3();
                const double js4 = params->SS4();
                const double js5 = params->SS5();

                double fs1=0.0, fs2=0.0, fs3=0.0, fs4=0.0, fs5=0.0, fs6=0.0;

                if (opts->use_angular_acc){
                    prob->folded_swave_integrated_fj_chebyshev(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                                               fs1, fs2, fs3, fs4, fs5, fs6, q2);
                }
                else{
                    prob->folded_swave_integrated_fj_noacc(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                                           fs1, fs2, fs3, fs4, fs5, fs6);
                }

                prob_sig = ((1-fs)*(f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
                                    + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9)
                            +(fs1*fs + fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5))/prob->fnorm_sig;
                prob_pwave = ((1-fs)*(f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
                                      + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9))/prob->fnorm_sig;
                prob_swave = fs1*fs/prob->fnorm_sig;
                prob_interference = (fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5)/prob->fnorm_sig;
            }
        }
        pdf_sig->SetBinContent(i+1, prob_sig);
        pdf_interference->SetBinContent(i+1, prob_interference);
        pdf_pwave->SetBinContent(i+1, prob_pwave);
        pdf_swave->SetBinContent(i+1, prob_swave);

        if(opts->use_angular_acc && opts->use_weighted_bkg){
            if(opts->fit_full_angular_bkg && !opts->flat_bkg && !opts->full_angular){
                double pi = TMath::Pi();
                if(opts->folding == 0){
                    prob_bkg = (prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2)
                                + prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from-pi, phi_to-pi, q2)) /prob->fnorm_bkg;
                }
                else if(opts->folding == 1){
                    prob_bkg = (prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2)
                                + prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, -phi_to, -phi_from, q2)
                                + prob->integral_bkg_chebyshev(params, -ctl_to, -ctl_from, ctk_from, ctk_to, pi-phi_to, pi-phi_from, q2)
                                + prob->integral_bkg_chebyshev(params, -ctl_to, -ctl_from, ctk_from, ctk_to, -pi+phi_from, -pi+phi_to, q2)) /prob->fnorm_bkg;
                }
                else if(opts->folding == 2){
                    prob_bkg = (prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2)
                                + prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, -phi_to, -phi_from, q2)
                                + prob->integral_bkg_chebyshev(params, -ctl_to, -ctl_from, ctk_from, ctk_to, phi_from, phi_to, q2)
                                + prob->integral_bkg_chebyshev(params, -ctl_to, -ctl_from, ctk_from, ctk_to, -phi_to, -phi_from, q2)) /prob->fnorm_bkg;
                }
                else if(opts->folding == 3){
                    if((phi_from <= 0.0 && phi_to <= 0.0) || (phi_from >= 0.0 && phi_to >= 0.0)){
                        prob_bkg = (prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2)
                                    + prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, (phi_from < 0.0 ? -pi - phi_to : pi - phi_to), (phi_to < 0.0 ? -pi - phi_from : pi - phi_from), q2)
                                    + prob->integral_bkg_chebyshev(params, -ctl_to, -ctl_from, ctk_from, ctk_to, phi_from, phi_to, q2)
                                    + prob->integral_bkg_chebyshev(params, -ctl_to, -ctl_from, ctk_from, ctk_to, (phi_from < 0.0 ? -pi - phi_to : pi - phi_to), (phi_to < 0.0 ? -pi - phi_from : pi - phi_from), q2)) /prob->fnorm_bkg;
                    }
                    else{ //when phi_from < 0.0 and phi_to > 0.0:
                        assert(phi_to > phi_from);
                        prob_bkg = (prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2)
                                    + prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, -pi,         -pi - phi_from, q2)
                                    + prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to,  pi - phi_to, pi, q2)
                                    + prob->integral_bkg_chebyshev(params, -ctl_to, -ctl_from, ctk_from, ctk_to, phi_from, phi_to, q2)
                                    + prob->integral_bkg_chebyshev(params, -ctl_to, -ctl_from, ctk_from, ctk_to, -pi,        -pi - phi_from, q2)
                                    + prob->integral_bkg_chebyshev(params, -ctl_to, -ctl_from, ctk_from, ctk_to, pi - phi_to, pi, q2)) /prob->fnorm_bkg;
                    }
                }
                else if(opts->folding == 4){
                    if((phi_from <= 0.0 && phi_to <= 0.0) || (phi_from >= 0.0 && phi_to >= 0.0)){
                        prob_bkg = (prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2)
                                    + prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, (phi_from < 0.0 ? -pi - phi_to : pi - phi_to), (phi_to < 0.0 ? -pi - phi_from : pi - phi_from), q2)
                                    + prob->integral_bkg_chebyshev(params, -ctl_to, -ctl_from, -ctk_to, -ctk_from, phi_from, phi_to, q2)
                                    + prob->integral_bkg_chebyshev(params, -ctl_to, -ctl_from, -ctk_to, -ctk_from, (phi_from < 0.0 ? -pi - phi_to : pi - phi_to), (phi_to < 0.0 ? -pi - phi_from : pi - phi_from), q2)) /prob->fnorm_bkg;
                    }
                    else{ //when phi_from < 0.0 and phi_to > 0.0:
                        assert(phi_to > phi_from);
                        prob_bkg = (prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2)
                                    + prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, -pi,         -pi - phi_from, q2)
                                    + prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to,  pi - phi_to, pi, q2)
                                    + prob->integral_bkg_chebyshev(params, -ctl_to, -ctl_from, -ctk_to, -ctk_from, phi_from, phi_to, q2)
                                    + prob->integral_bkg_chebyshev(params, -ctl_to, -ctl_from, -ctk_to, -ctk_from, -pi,         -pi - phi_from, q2)
                                    + prob->integral_bkg_chebyshev(params, -ctl_to, -ctl_from, -ctk_to, -ctk_from,  pi - phi_to, pi, q2)) /prob->fnorm_bkg;
                    }
                }
            }
            else{
                prob_bkg = prob->integral_bkg_chebyshev(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2) /prob->fnorm_bkg;
            }
        }
        else{
            if(opts->fit_full_angular_bkg && !opts->flat_bkg && !opts->full_angular){
                if(opts->folding == 0){
                    prob_bkg = (prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to)
                                + prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from-MY_PI, phi_to-MY_PI)) /prob->fnorm_bkg;
                }
                else if(opts->folding == 1){
                    prob_bkg = (prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to)
                                + prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, -phi_to, -phi_from)
                                + prob->integral_bkg(params, -ctl_to, -ctl_from, ctk_from, ctk_to, MY_PI-phi_to, MY_PI-phi_from)
                                + prob->integral_bkg(params, -ctl_to, -ctl_from, ctk_from, ctk_to, -MY_PI+phi_from, -MY_PI+phi_to)) /prob->fnorm_bkg;
                }
                else if(opts->folding == 2){
                    prob_bkg = (prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to)
                                + prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, -phi_to, -phi_from)
                                + prob->integral_bkg(params, -ctl_to, -ctl_from, ctk_from, ctk_to, phi_from, phi_to)
                                + prob->integral_bkg(params, -ctl_to, -ctl_from, ctk_from, ctk_to, -phi_to, -phi_from)) /prob->fnorm_bkg;
                }
                else if(opts->folding == 3){
                    if((phi_from <= 0.0 && phi_to <= 0.0) || (phi_from >= 0.0 && phi_to >= 0.0)){
                        prob_bkg = (prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to)
                                    + prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, (phi_from < 0.0 ? -MY_PI - phi_to : MY_PI - phi_to), (phi_to < 0.0 ? -MY_PI - phi_from : MY_PI - phi_from))
                                    + prob->integral_bkg(params, -ctl_to, -ctl_from, ctk_from, ctk_to, phi_from, phi_to)
                                    + prob->integral_bkg(params, -ctl_to, -ctl_from, ctk_from, ctk_to, (phi_from < 0.0 ? -MY_PI - phi_to : MY_PI - phi_to), (phi_to < 0.0 ? -MY_PI - phi_from : MY_PI - phi_from))) /prob->fnorm_bkg;
                    }
                    else{ //when phi_from < 0.0 and phi_to > 0.0:
                        assert(phi_to > phi_from);
                        prob_bkg = (prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to)
                                    + prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, -MY_PI,         -MY_PI - phi_from)
                                    + prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to,  MY_PI - phi_to, MY_PI)
                                    + prob->integral_bkg(params, -ctl_to, -ctl_from, ctk_from, ctk_to, phi_from, phi_to)
                                    + prob->integral_bkg(params, -ctl_to, -ctl_from, ctk_from, ctk_to, -MY_PI,        -MY_PI - phi_from)
                                    + prob->integral_bkg(params, -ctl_to, -ctl_from, ctk_from, ctk_to, MY_PI - phi_to, MY_PI)) /prob->fnorm_bkg;
                    }
                }
                else if(opts->folding == 4){
                    if((phi_from <= 0.0 && phi_to <= 0.0) || (phi_from >= 0.0 && phi_to >= 0.0)){
                        prob_bkg = (prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to)
                                    + prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, (phi_from < 0.0 ? -MY_PI - phi_to : MY_PI - phi_to), (phi_to < 0.0 ? -MY_PI - phi_from : MY_PI - phi_from))
                                    + prob->integral_bkg(params, -ctl_to, -ctl_from, -ctk_to, -ctk_from, phi_from, phi_to)
                                    + prob->integral_bkg(params, -ctl_to, -ctl_from, -ctk_to, -ctk_from, (phi_from < 0.0 ? -MY_PI - phi_to : MY_PI - phi_to), (phi_to < 0.0 ? -MY_PI - phi_from : MY_PI - phi_from))) /prob->fnorm_bkg;
                    }
                    else{ //when phi_from < 0.0 and phi_to > 0.0:
                        assert(phi_to > phi_from);
                        prob_bkg = (prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to)
                                    + prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, -MY_PI,         -MY_PI - phi_from)
                                    + prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to,  MY_PI - phi_to, MY_PI)
                                    + prob->integral_bkg(params, -ctl_to, -ctl_from, -ctk_to, -ctk_from, phi_from, phi_to)
                                    + prob->integral_bkg(params, -ctl_to, -ctl_from, -ctk_to, -ctk_from, -MY_PI,         -MY_PI - phi_from)
                                    + prob->integral_bkg(params, -ctl_to, -ctl_from, -ctk_to, -ctk_from,  MY_PI - phi_to, MY_PI)) /prob->fnorm_bkg;
                    }
                }
            }
            else{
                prob_bkg = prob->integral_bkg(params, ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to) /prob->fnorm_bkg;
            }
        }
        pdf_bkg->SetBinContent(i+1, prob_bkg);
    }

    pdf_sig->Scale(nevents * fsig * double(pdf_bins) / double(angle_bins));
    pdf_pwave->Scale(nevents * fsig * double(pdf_bins) / double(angle_bins));
    pdf_swave->Scale(nevents * fsig * double(pdf_bins) / double(angle_bins));
    pdf_interference->Scale(nevents * fsig * double(pdf_bins) / double(angle_bins));

    pdf_bkg->Scale(nevents * (1.0-fsig) * double(pdf_bins) / double(angle_bins));

    pdf_tot->Add(pdf_sig, pdf_bkg);

    double maxpdf = (pdf_tot->GetMaximum() > angle_plot->GetMaximum() ? pdf_tot->GetMaximum() : angle_plot->GetMaximum());
    if(this->pulls) pdf_sig->SetMinimum(0.1001);
    else            pdf_sig->SetMinimum(0.0);

    pdf_sig->SetMaximum(1.45*maxpdf);
    pdf_sig->SetTitleSize(0.06, "XY");
    pdf_sig->SetLabelSize(0.05, "XY");
    pdf_sig->SetTitleOffset(0.9, "XY");
    pdf_sig->GetXaxis()->SetNoExponent(kTRUE);
    TGaxis::SetMaxDigits(3);
    spdlog::debug("Designing PDF...");
    design_pdf(pdf_sig, kAzure, kAzure-5, 1001, 1-pullHeight, this->pulls);
    if(pdf_sig->Integral() > 0.0)  pdf_sig->Draw("hist C");

    design_pdf(pdf_bkg,kOrange+10,kOrange+8, 3354, 1-pullHeight,pdf_sig->Integral() <= 0.0 );

    if(pdf_sig->Integral() > 0.0){
        pdf_bkg->Draw("hist same C");
    }
    else{
        pdf_bkg->SetMinimum(minBkg);
        pdf_bkg->SetMaximum(1.45*maxpdf);
        pdf_bkg->Draw("hist C");
    }
    /////

    spdlog::debug("Designing PDF lines...");
    design_pdfLine(pdf_pwave, pWaveColor, kDashed);
    if(opts->swave) pdf_pwave->Draw("hist same C");

    design_pdfLine(pdf_swave, sWaveColor, kDotted);
    if(opts->swave) pdf_swave->Draw("hist same C");

    design_pdfLine(pdf_interference, psInterferenceColor, kDashDotted);
    if(opts->swave) pdf_interference->Draw("hist same C");

    design_pdfLine(pdf_tot, kBlack, kSolid);
    pdf_tot->Draw("hist same C");

    design_plot(angle_plot,20,printC);
    design_pdfLine(angle_plot,kBlack,kSolid,1.0);
    angle_plot->Draw("same e1");
    if (false && angle_plot_bkg->Integral() != 0){
        angle_plot_sig->SetLineColor(4);
        angle_plot_sig->GetXaxis()->SetNoExponent(kTRUE);
        angle_plot_sig->Draw("esame");
        angle_plot_bkg->SetLineColor(2);
        angle_plot_bkg->GetXaxis()->SetNoExponent(kTRUE);
        if (params->f_sig() != 1.0)
            angle_plot_bkg->Draw("esame");
    }

    TLegend* angle_leg = new TLegend(0.675,0.45,0.875,0.65);
    angle_leg->SetBorderSize(0);
    angle_leg->SetTextFont(132);
    angle_leg->SetFillColor(0);
    angle_leg->AddEntry(angle_plot, "data", "le");
    angle_leg->AddEntry(pdf_tot, "total PDF", "l");
    angle_leg->AddEntry(pdf_sig, "signal PDF", "l");
    angle_leg->AddEntry(pdf_bkg, "bkg PDF", "l");
    if(opts->swave){
        angle_leg->AddEntry(pdf_pwave, "P-wave PDF", "l");
        angle_leg->AddEntry(pdf_swave, "S-wave PDF", "l");
        angle_leg->AddEntry(pdf_interference, "interference PDF", "l");
    }
    //angle_leg->Draw("same");

    spdlog::debug("plotter: getting a TLatex...");
    TLatex *tex = design_TLatex(texsizelarge,texsizesmall, pullHeight, 0.47,
                                this->pulls, opts->plot_label,opts->q2_label);
    assert(pdf_bins == angle_bins*bin_ratio);
    assert(bin_ratio >= 1);

    //calculate pulls from fit and data points:

    spdlog::debug("plotter: calculate pulls from fit and data points");
    for(UInt_t b = 1; b <= angle_bins; b++){
        double p;
        if(bin_ratio == 1){
            p = pdf_tot->GetBinContent(b);
        }
        //for odd ratio, take central bin from pdf w.r.t to angle_bin:
        else if(bin_ratio%2 != 0){
            p = pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2);
        }
        //else, average the two central bins from pdf w.r.t. to angle_bin:
        else{
            p = (pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2)+pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2 + 1))/2.; //take central of 10 pdfbins
        }

        angle_averaged->SetBinContent(b, p);

        if(angle_plot->GetBinError(b) == 0){
            angle_pulls->SetBinContent(b, 0.0);
        }
        else{
            angle_pulls->SetBinContent(b, (angle_plot->GetBinContent(b) - p)/angle_plot->GetBinError(b));
        }
    }

    Double_t angle_chi2 = 0.0;
    Int_t angle_ndf = 0, angle_Good = 0;

    spdlog::debug("plotter: plotting chi2");
    if(opts->plot_chi2){
        angle_averaged->Chi2TestX(angle_plot, angle_chi2, angle_ndf, angle_Good, "WW");
        tex->SetTextColor(kBlack);
        tex->DrawLatexNDC(0.5,(this->pulls ? (0.85 - pullHeight)/(1 - pullHeight) : 0.85),("#chi^{2}: "+std::to_string(angle_chi2 / angle_ndf)).c_str());
    }

    if(this->pulls){
        spdlog::debug("plotter: Designing pulls...");

        pad2->Clear();
        pad2->SetMargin(0.125,0.1,0.125/ pullHeight, 1e-6);
        pad2->SetTickx();
        pad2->cd();        

        design_pull(angle_pulls, kBlack,kGray+2,pullHeight,pullFrameRange);
        angle_pulls->Draw();

        //add two 3-sigma lines:
        TLine * lUp  = threeSigmaLine(angle_min, angle_max, true);
        TLine * lLow = threeSigmaLine(angle_min, angle_max, false);
        lUp->Draw("same");
        lLow->Draw("same");
    }
    spdlog::debug("plotter: Saving...");

    std::string anglename = prefix + angle + "_" + postfix;
    saveTCanvas(angle_canvas,anglename,opts->getAllPlotTypes());

    output->cd();
    angle_canvas->Write();

    spdlog::debug("plotter: Deleting stuff");
    delete angle_plot;
    delete angle_plot_sig;
    delete angle_plot_bkg;
    delete angle_pulls;
    delete angle_averaged;
    delete pdf_sig;
    delete pdf_pwave;
    delete pdf_swave;
    delete pdf_interference;
    delete pdf_bkg;
    delete pdf_tot;
    delete angle_canvas;
};

void bu2kstarmumu_plotter::plot_added_pdfs(std::vector<bu2kstarmumu_pdf*> * probs,
                                           std::vector<bu2kstarmumu_parameters*> * params,
                                           std::vector<std::vector<event>* > * events,
                                           std::string prefix, std::string postfix,
                                           bool signalregion){

    if (probs->size() != params->size()){
        spdlog::critical("probs size != params size!\t {0:d} \t != \t {1:d}", probs->size(), params->size());
        assert(0);
    }
    if (probs->size() != events->size()){
        spdlog::critical("probs size != events size!\t {0:d} \t != \t {1:d}", probs->size(), events->size());
        assert(0);
    }

    for(UInt_t e = 0; e < events->size(); e++){
        if(events->at(e)->size() == 0){
            spdlog::error("Cannot plot empty event histograms! Events for PDF {0:d} are empty!", e);
            return;
        }
        probs->at(e)->update_cached_normalization(params->at(e));
    }

    output = new TFile((prefix +"projections_addedPDFS" + opts->name + ".root").c_str(), "UPDATE");
    std::string logstr = std::string("log_")+postfix;

    //m(B)
    if(!opts->only_angles && !opts->only_mkpi){
        plot_m_added_pdfs(probs, params, events, prefix, postfix, false, false);
        plot_m_added_pdfs(probs, params, events, prefix, logstr , true,  false);
    }

    //m(Kpi)
    if (opts->fit_mkpi || opts->use_mkpi){
        plot_mkpi_added_pdfs(probs, params, events, prefix, postfix, signalregion, false, false);
    }

    //angles
    if(!opts->only_Bmass && !opts->only_mass2DFit && !opts->only_mkpi){
        plot_angle_added_pdfs(probs, params, events, prefix, postfix, signalregion, "ctl", false);
        plot_angle_added_pdfs(probs, params, events, prefix, postfix, signalregion, "ctk", false);
        plot_angle_added_pdfs(probs, params, events, prefix, postfix, signalregion, "phi", false);
    }
    output->Close();
    delete output;
};

void bu2kstarmumu_plotter::plot_m_added_pdfs(std::vector<bu2kstarmumu_pdf*> * probs, std::vector<bu2kstarmumu_parameters*> * params, std::vector<std::vector<event>*> * events, std::string prefix, std::string postfix, bool logarithmic, bool printC){

    unsigned int m_bins = opts->plots_m_bins;
    double m_min = params->at(0)->m_b.get_min();
    double m_max = params->at(0)->m_b.get_max();
    spdlog::debug("Mass range: {0:f} - {1:f}", m_min, m_max);

    //create canvas
    TCanvas *m_canvas = nullptr;    
    std::string m_canvas_name = "Bplus Likelihood Analysis: #it{m}(#it" +latex_decay(opts->DTF) +") mass projection";
    if(printC) m_canvas = new TCanvas(("m_"+postfix).c_str(), m_canvas_name.c_str());
    else       m_canvas = new TCanvas(("m_"+postfix).c_str(), m_canvas_name.c_str(),1600,1200);

    const double pullHeight = 0.27;
    const double pullFrameRange = 6.5;
    TPad *pad1 = new TPad("pad1", "plot",0.0,pullHeight,1.0,1.0,0);
    TPad *pad2 = new TPad("pad2", "pull",0.0,0.0,1.0,pullHeight,0);
    if(this->pulls){
        pad1->Draw();
        pad2->Draw();
        pad1->SetLogy(logarithmic);
        pad1->SetBorderSize  (0);
        pad1->SetMargin(0.125,0.1,1e-6,0.1/ (1 - pullHeight));
        pad1->SetTickx();
        pad1->SetTicky();
        pad1->cd();
    }
    else{
        m_canvas->cd()->SetMargin(0.125,0.1,0.125,0.1);
        m_canvas->SetLogy(logarithmic);
        m_canvas->SetTickx();
        m_canvas->SetTicky();
    }

    //create histograms
    std::ostringstream sout;
    sout << ";#it{m}(" + latex_decay(opts->DTF) + ") ["+MeVc()+"];" << EVENTS_TAG << " / " << std::setprecision(2) << (m_max-m_min)/m_bins << " "+MeVc()+"";

    std::string spulls = ";#it{m}(" + latex_decay(opts->DTF) + ") ["+MeVc()+"];" + latex_pull();

    const UInt_t bin_ratio = PLOT_NBINS_RATIO;
    unsigned int pdf_bins = m_bins*bin_ratio;
    double dm = (m_max-m_min)/pdf_bins;

    TH1D* m_plot  = new TH1D("m",       sout.str().c_str(), m_bins, m_min, m_max);
    TH1D* m_pulls = new TH1D("mpulls",  spulls.c_str(),     m_bins, m_min, m_max);
    TH1D* pdf_sig = new TH1D("pdf_sig", sout.str().c_str(), pdf_bins, m_min, m_max);
    TH1D* pdf_bkg = new TH1D("pdf_bkg", sout.str().c_str(), pdf_bins, m_min, m_max);
    TH1D* pdf_tot = new TH1D("pdf_tot", sout.str().c_str(), pdf_bins, m_min, m_max);

    m_plot->Sumw2();

    //loop over all PDFs
    for(UInt_t k = 0; k < params->size(); k++){

        double fsig = params->at(k)->f_sig();
        if (opts->extended_ml){
            fsig = params->at(k)->n_sig()/(params->at(k)->n_sig()+params->at(k)->n_bkg());
        }

        TH1D* tmp_m = new TH1D(("tmp_m"+std::to_string(k)).c_str(), sout.str().c_str(), m_bins, m_min, m_max);
        TH1D* tmp_sig = new TH1D(("tmp_sig"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, m_min, m_max);
        TH1D* tmp_bkg = new TH1D(("tmp_bkg"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, m_min, m_max);
        TH1D* tmp_tot = new TH1D(("tmp_tot"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, m_min, m_max);

        double nevents = 0.0;
        for (unsigned int i = 0; i < events->at(k)->size(); i++)
        {
            double weight = 1.0;
            if (opts->weighted_fit) weight = events->at(k)->at(i).weight;
            tmp_m->Fill(events->at(k)->at(i).m, weight);
            nevents += weight;
        }
        double m_b     = params->at(k)->m_b();
        double m_scale = params->at(k)->m_scale();
        double f_res   = params->at(k)->m_res_1();
        double sigma_1 = params->at(k)->m_sigma_1();
        double sigma_2 = params->at(k)->m_sigma_2();
        double alpha_1 = opts->crystalball || opts->twotailedcrystalball ? params->at(k)->alpha_1() : 0.;
        double alpha_2 = opts->crystalball || opts->twotailedcrystalball ? params->at(k)->alpha_2() : 0.;
        double n_1     = opts->crystalball || opts->twotailedcrystalball ? params->at(k)->n_1() : 0.;
        double n_2     = opts->crystalball || opts->twotailedcrystalball ? params->at(k)->n_2() : 0.;

        double prob_sig = 0.0, prob_bkg = 0.0, from = 0.0, to = 0.0;

        double integral1 = 1.0, integral2 = 2.0;
        if(opts->crystalball){
            integral1 = integrate_crystalball(m_b, m_scale*sigma_1, alpha_1, n_1, m_min, m_max);
            integral2 = integrate_crystalball(m_b, m_scale*sigma_2, alpha_2, n_2, m_min, m_max);
        }
        else if(opts->twotailedcrystalball){
            integral1 = integrate_twotailedcrystalball(m_b, m_scale*sigma_1, alpha_1, alpha_2, n_1, n_2, m_min, m_max);
        }
        else{
            integral1 = integrate_gauss(m_scale*sigma_1, m_b, m_min, m_max);
            integral2 = integrate_gauss(m_scale*sigma_2, m_b, m_min, m_max);
        }

        for (unsigned int i = 0; i < pdf_bins; i++){
            from = m_min + i*dm;
            to = m_min + (i+1)*dm;
            prob_sig = 0.0;
            if (opts->crystalball){
                prob_sig = integrate_crystalball(m_b, m_scale*sigma_1, alpha_1, n_1, from, to) / integral1;
                if (f_res != 1.0){
                    prob_sig *= f_res;
                    prob_sig += (1.0-f_res)
                            * integrate_crystalball(m_b, m_scale*sigma_2, alpha_2, n_2, from, to) / integral2;
                }
            }
            else if(opts->twotailedcrystalball){
                prob_sig = integrate_twotailedcrystalball(m_b, m_scale*sigma_1, alpha_1, alpha_2, n_1, n_2, from, to) / integral1;
            }
            else{
                prob_sig = integrate_gauss(m_scale*sigma_1, m_b, from, to) / integral1;
                if (f_res != 1.0){
                    prob_sig *= f_res;
                    prob_sig += (1.0 - f_res)
                            * integrate_gauss(m_scale*sigma_2, m_b, from, to) / integral2;
                }
            }

            tmp_sig->SetBinContent(i+1, prob_sig);

            prob_bkg = probs->at(k)->integral_m_bkg_prob(params->at(k), from, to);

            tmp_bkg->SetBinContent(i+1, prob_bkg);
        }

        tmp_sig->Scale(nevents * fsig * double(pdf_bins) / double(m_bins));
        tmp_bkg->Scale(nevents * (1.0-fsig) * double(pdf_bins) / double(m_bins));
        tmp_tot->Add(tmp_sig, tmp_bkg);

        m_plot->Add(tmp_m);
        pdf_sig->Add(tmp_sig);
        pdf_bkg->Add(tmp_bkg);
        pdf_tot->Add(tmp_tot);

        delete tmp_m;
        delete tmp_sig;
        delete tmp_bkg;
        delete tmp_tot;

    }

    double maxpdf= (pdf_tot->GetMaximum() > m_plot->GetMaximum() ? pdf_tot->GetMaximum() : m_plot->GetMaximum());
    if(this->pulls){
        if (logarithmic) pdf_sig->SetMinimum(0.1001);
        else             pdf_sig->SetMinimum(0.001);
    }
    else{ //no pull distributions
        if (logarithmic) pdf_sig->SetMinimum(0.1);
        else             pdf_sig->SetMinimum(0.0);
    }
    pdf_sig->SetMaximum(1.45*maxpdf);


    pdf_bkg->SetTitleSize(0.06, "XY");
    pdf_bkg->SetLabelSize(0.05, "XY");
    pdf_bkg->SetTitleOffset(0.9, "XY");
    pdf_bkg->GetXaxis()->SetNoExponent(kTRUE);
    TGaxis::SetMaxDigits(3); //TODO: check

    design_pdf(pdf_sig,kAzure, kAzure-5, 1001, 1-pullHeight, this->pulls);
    if(pdf_sig->Integral() > 0.0) pdf_sig->Draw("hist C");
    design_pdf(pdf_bkg,kOrange+10,kOrange+8, 3354, 1-pullHeight,pdf_sig->Integral() <= 0.0 );

    if(pdf_sig->Integral() > 0.0){
        pdf_bkg->Draw("hist same C");
    }
    else{
        pdf_bkg->SetMaximum(1.45*maxpdf);
        pdf_bkg->SetMinimum(minBkg);
        pdf_bkg->Draw("hist C");
    }

    pdf_tot->SetFillStyle(0);
    design_pdfLine(pdf_tot,kBlack,kSolid,2.0);
    pdf_tot->Draw("hist same C");

    design_plot(m_plot, 20, printC);
    design_pdfLine(m_plot,kBlack,kSolid,1.0);
    m_plot->Draw("same e1");

    //draw legend
    TLegend* m_leg = new TLegend(0.675,0.45,0.875,0.65);
    m_leg->SetBorderSize(0);
    m_leg->SetTextFont(132);
    m_leg->SetFillColor(0);
    m_leg->AddEntry(m_plot, "data", "le");
    m_leg->AddEntry(pdf_tot, "total PDF", "l");
    m_leg->AddEntry(pdf_sig, "signal PDF", "l");
    m_leg->AddEntry(pdf_bkg, "bkg PDF", "l");
    //m_leg->Draw();

    TLatex *tex = design_TLatex(texsizelarge,texsizesmall, pullHeight, 0.47,
                                this->pulls, opts->plot_label,opts->q2_label);

    assert(pdf_bins == m_bins*bin_ratio);
    assert(bin_ratio >= 1);

    if(this->pulls){

        //calculate pulls from fit and data points:
        for(UInt_t b = 1; b <= m_bins; b++){
            double p;
            if(bin_ratio == 1){
                p = pdf_tot->GetBinContent(b);
            }
            //for odd ratio, take central bin from pdf w.r.t to m_bin:
            else if(bin_ratio%2 != 0){
                p = pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2);
            }
            //else, average the two central bins from pdf w.r.t. to angle_bin:
            else{
                p = (pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2)+pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2 + 1))/2.; //take central of 10 pdfbins
            }

            if(m_plot->GetBinError(b) == 0) m_pulls->SetBinContent(b, 0.0);
            else                            m_pulls->SetBinContent(b, (m_plot->GetBinContent(b) - p)/m_plot->GetBinError(b));
        }

        pad2->Clear();
        pad2->SetMargin(0.125,0.1,0.125/ pullHeight, 1e-6);
        pad2->SetTickx();
        pad2->cd();

        design_pull(m_pulls, kBlack,kGray+2,pullHeight,pullFrameRange);
        m_pulls->Draw();

        //add two 3-sigma lines:
        TLine * lUp  = threeSigmaLine(m_min, m_max, true);
        TLine * lLow = threeSigmaLine(m_min, m_max, false);
        lUp->Draw("same");
        lLow->Draw("same");
    }

    std::string mname = prefix + "m_" + postfix + "_AllPDFs";
    saveTCanvas(m_canvas,mname,opts->getAllPlotTypes());

    output->cd();
    m_canvas->Write();

    delete m_plot;
    delete pdf_sig;
    delete pdf_bkg;
    delete pdf_tot;
    delete m_pulls;
    delete m_canvas;    
    delete tex;

}

void bu2kstarmumu_plotter::plot_mkpi_added_pdfs(std::vector<bu2kstarmumu_pdf*> * probs, std::vector<bu2kstarmumu_parameters*> * params, std::vector<std::vector<event>*> * events, std::string prefix, std::string postfix, bool signalregion, bool logarithmic, bool printC){

    unsigned int mkpi_bins = opts->plots_m_bins;
    double mkpi_min = opts->mkpi_min/1.0e+3;//0.7959*0.7959;//(0.892-0.100)*(0.892-0.100);//opts->m_min;
    double mkpi_max = opts->mkpi_max/1.0e+3;//0.9959*0.9959;//(0.892+0.100)*(0.892+0.100);//opts->m_max;

    TCanvas *mkpi_canvas = nullptr;
    std::string mpki_canvas_name = "B plus Likelihood Analysis: #it{m}(#it"+ latex_Kst_decay(opts->DTF) +") ["+GeVc()+"]";
    if(printC)mkpi_canvas = new TCanvas(("mkpi_"+postfix).c_str(), mpki_canvas_name.c_str());
    else      mkpi_canvas = new TCanvas(("mkpi_"+postfix).c_str(),  mpki_canvas_name.c_str(),1600,1200);


    const double pullHeight = 0.27;
    const double pullFrameRange = 6.5;
    TPad *pad1 = new TPad("pad1", "plot",0.0,pullHeight,1.0,1.0,0);
    TPad *pad2 = new TPad("pad2", "pull",0.0,0.0,1.0,pullHeight,0);
    if(this->pulls){
        pad1->Draw();
        pad2->Draw();
        pad1->SetLogy(logarithmic);
        pad1->SetBorderSize  (0);
        pad1->SetMargin(0.125,0.1,1e-6,0.1/ (1 - pullHeight));
        pad1->SetTickx();
        pad1->SetTicky();
        pad1->cd();
    }
    else{
        mkpi_canvas->cd()->SetMargin(0.125,0.1,0.125,0.1);
        mkpi_canvas->SetTickx();
        mkpi_canvas->SetTicky();
    }

    std::ostringstream sout;
    sout << ";#it{m}(#it{K}^{+}#pi^{-}) ["+GeVc()+"];" << EVENTS_TAG << " / " << std::setprecision(2) << (mkpi_max-mkpi_min)/mkpi_bins << " GeV^{2}/#it{c}^{4}";
    std::string spulls =  ";#it{m}("+ latex_Kst_decay(opts->DTF) +") ["+MeVc()+"];" + latex_pull();

    const UInt_t bin_ratio = PLOT_NBINS_RATIO;
    unsigned int pdf_bins = mkpi_bins*bin_ratio;
    double dm = (mkpi_max-mkpi_min)/pdf_bins;

    TH1D* mkpi_plot = new TH1D("m",         sout.str().c_str(), mkpi_bins, mkpi_min, mkpi_max);
    TH1D* mkpi_pulls= new TH1D("mkpipulls", spulls.c_str(),     mkpi_bins, mkpi_min, mkpi_max);
    TH1D* pdf_sig   = new TH1D("pdf_sig",   sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
    TH1D* pdf_swave = new TH1D("pdf_swave", sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
    TH1D* pdf_pwave = new TH1D("pdf_pwave", sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
    TH1D* pdf_interference = new TH1D("pdf_interference", sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
    TH1D* pdf_bkg   = new TH1D("pdf_bkg",   sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
    TH1D* pdf_tot   = new TH1D("pdf_tot",   sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);

    mkpi_plot->Sumw2();

    for(UInt_t k = 0; k < params->size(); k++){

        double ma = params->at(k)->m_b() - B_MASS_TIGHT_WINDOW;
        double mb = params->at(k)->m_b() + B_MASS_TIGHT_WINDOW;

        double fsig = params->at(k)->f_sig();
        if(opts->extended_ml){
            fsig = params->at(k)->n_sig() / (params->at(k)->n_sig()+params->at(k)->n_bkg());
        }
        if(signalregion){
            double rsig = probs->at(k)->integral_m_sig_prob(params->at(k), ma, mb);
            double rbkg = probs->at(k)->integral_m_bkg_prob(params->at(k), ma, mb);
            fsig = fsig*rsig/(fsig*rsig + (1.0-fsig)*rbkg);
        }

        TH1D* tmp_mkpi = new TH1D(("tmp_mkpi"+std::to_string(k)).c_str(), sout.str().c_str(), mkpi_bins, mkpi_min, mkpi_max);
        TH1D* tmp_sig = new TH1D(("tmp_sig"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
        TH1D* tmp_swave = new TH1D(("tmp_swave"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
        TH1D* tmp_pwave = new TH1D(("tmp_pwave"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
        TH1D* tmp_interference = new TH1D(("tmp_interference"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
        TH1D* tmp_bkg = new TH1D(("tmp_bkg"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);
        TH1D* tmp_tot = new TH1D(("tmp_tot"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, mkpi_min, mkpi_max);

        double nevents = 0.0;

        for (unsigned int i = 0; i < events->at(k)->size(); i++){
            if (!signalregion || (events->at(k)->at(i).m > ma && events->at(k)->at(i).m < mb)){
                double weight = 1.0;
                double mkpi = events->at(k)->at(i).mkpi/1.0e+3;
                if (opts->weighted_fit) weight = events->at(k)->at(i).weight;
                tmp_mkpi->Fill(mkpi, weight);
                nevents += weight;
            }
        }

        double gammakstar = params->at(k)->gammakstar();
        double mkstar = params->at(k)->mkstar();
        double asphase = params->at(k)->asphase();
        double a = params->at(k)->a();
        double r = params->at(k)->r();
        double R = params->at(k)->R();

        double gammakstarplus = params->at(k)->gammakstarplus();
        double mkstarplus = params->at(k)->mkstarplus();
        double gammaf800 = params->at(k)->gammaf800();
        double mf800 = params->at(k)->mf800();
        double f800mag = params->at(k)->f800mag();
        double f800phase = params->at(k)->f800phase();

        double normbkg=0.0;
        std::vector<double> ch_mkpi(5, 0.0);
        ch_mkpi.at(0) = params->at(k)->cbkgmkpi0();
        ch_mkpi.at(1) = params->at(k)->cbkgmkpi1();
        ch_mkpi.at(2) = params->at(k)->cbkgmkpi2();
        ch_mkpi.at(3) = params->at(k)->cbkgmkpi3();
        ch_mkpi.at(4) = params->at(k)->cbkgmkpi4();
        std::vector<double> poly_mkpi(ch_mkpi.size(), 0.0);
        chebyshev_to_poly(ch_mkpi, poly_mkpi);
        std::vector<double> poly_corr_mkpi(ch_mkpi.size(), 0.0);
        correct_poly(poly_mkpi, poly_corr_mkpi, mkpi_min, mkpi_max);

        if (opts->mkpi_threshold){
            normbkg = fcnc::int_threshold(mkpi_min, mkpi_max, 0.633, params->at(k)->nthreshold());
        }
        else{
            for (unsigned int i=0; i<poly_mkpi.size(); i++){
                normbkg += poly_corr_mkpi.at(i)*(pow(mkpi_max,i+1)-pow(mkpi_min,i+1))/(i+1.0);
            }
        }

        double q2 = params->at(k)->eff_q2();
        double rangednormkstarplus, rangednormkstar;

        if (opts->simple_mkpi){
            rangednormkstarplus = int_mkpi_simple_kstarzero_amp_squared(mkpi_min, mkpi_max, q2,
                                                                        f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus);
            rangednormkstar = int_mkpi_simple_bw_kstar_amp_squared(mkpi_min, mkpi_max, q2, gammakstar, mkstar);
        }
        else if(opts->isobar){
            rangednormkstarplus = int_mkpi_kstarzero_isobar_amp_squared(mkpi_min, mkpi_max, q2,
                                                                        f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus, R);
            rangednormkstar = int_mkpi_bw_kstar_amp_squared(mkpi_min, mkpi_max, q2, gammakstar, mkstar, R);
        }
        else{
            rangednormkstarplus = int_mkpi_kstarzero_lass_amp_squared(mkpi_min, mkpi_max, q2, asphase, a, r, gammakstarplus, mkstarplus, R);
            rangednormkstar = int_mkpi_bw_kstar_amp_squared(mkpi_min, mkpi_max, q2, gammakstar, mkstar, R);
        }

        double sxi1, sxi2, sxi3, sxi4, sxi5, sxi6;
        if (opts->use_angular_acc){
            probs->at(k)->swave_integrated_fj_chebyshev(sxi1, sxi2, sxi3, sxi4, sxi5, sxi6, q2);
        }
        else{//weighted fit and fit without acceptance
            probs->at(k)->swave_integrated_fj_noacc(sxi1, sxi2, sxi3, sxi4, sxi5, sxi6);
        }
        double xi1, xi2, xi3, xi4, xi5, xi6,
                xi7, xi8, xi9, xi10, xi11, xi12;
        //double q2 = peffq2->get_value();
        if (opts->use_angular_acc){
            probs->at(k)->integrated_fj_chebyshev(xi1, xi2, xi3, xi4, xi5, xi6,
                                                  xi7, xi8, xi9, xi10, xi11, xi12, q2);
        }
        else{//weighted fit and fit without acceptance
            probs->at(k)->integrated_fj_noacc(xi1, xi2, xi3, xi4, xi5, xi6,
                                              xi7, xi8, xi9, xi10, xi11, xi12);
        }

        double s1s = params->at(k)->J1s();
        double s1c = params->at(k)->J1c();
        double s2s = params->at(k)->J2s();
        double s2c = params->at(k)->J2c();
        double s3 = params->at(k)->J3();
        double s4 = params->at(k)->J4();
        double s5 = params->at(k)->J5();
        double s6s = params->at(k)->J6s();
        double s6c = params->at(k)->J6c();
        double s7 = params->at(k)->J7();
        double s8 = params->at(k)->J8();
        double s9 = params->at(k)->J9();
        double fs = params->at(k)->FS();
        double ss1 = params->at(k)->SS1();
        double ss2 = params->at(k)->SS2();
        double ss3 = params->at(k)->SS3();
        double ss4 = params->at(k)->SS4();
        double ss5 = params->at(k)->SS5();

        double norm =
                (1-fs)*(xi1*s1s + xi2*s1c + xi3*s2s + xi4*s2c + xi5*s3 + xi6*s4
                        + xi7*s5 + xi8*s6s + xi9*s6c + xi10*s7 + xi11*s8 + xi12*s9)
                +(sxi1*fs + sxi2*ss1 + sxi3*ss2 + sxi4*ss3 + sxi5*ss4 + sxi6*ss5);
        double A = (xi1*s1s + xi2*s1c + xi3*s2s + xi4*s2c + xi5*s3 + xi6*s4
                    + xi7*s5 + xi8*s6s + xi9*s6c + xi10*s7 + xi11*s8 + xi12*s9)/norm;
        double B = sxi1/norm;
        double C = (sxi2*ss1 + sxi3*ss2 + sxi4*ss3)/norm;
        double D = (sxi5*ss4 + sxi6*ss5)/norm;


        double prob_bkg = 0.0, from = 0.0, to = 0.0;
        for (unsigned int i = 0; i < pdf_bins; i++){

            from = mkpi_min + i*dm;
            to = mkpi_min + (i+1)*dm;

            double swavesq, pwavesq;
            std::complex<double> stimespwave;

            if (opts->simple_mkpi){
                swavesq = fcnc::int_mkpi_simple_kstarzero_amp_squared(from, to, q2,
                                                                      f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus);
                pwavesq = fcnc::int_mkpi_simple_bw_kstar_amp_squared(from, to, q2, gammakstar, mkstar);
                stimespwave = fcnc::int_mkpi_simple_bw_kstar_amp_bar_kstarzero_amp(from, to, q2,
                                                                                   gammakstar, mkstar, asphase,
                                                                                   f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus);
            }
            else if (opts->isobar){
                swavesq = fcnc::int_mkpi_kstarzero_isobar_amp_squared(from, to, q2,
                                                                      f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus, R);
                pwavesq = fcnc::int_mkpi_bw_kstar_amp_squared(from, to, q2, gammakstar, mkstar, R);
                stimespwave = fcnc::int_mkpi_bw_kstar_amp_bar_kstarzero_isobar_amp(from, to, q2,
                                                                                   gammakstar, mkstar, asphase,
                                                                                   f800mag, f800phase, gammaf800, mf800, gammakstarplus, mkstarplus, R);
            }
            else{//nominal lass
                swavesq = fcnc::int_mkpi_kstarzero_lass_amp_squared(from, to, q2, asphase, a, r, gammakstarplus, mkstarplus, R);
                pwavesq = fcnc::int_mkpi_bw_kstar_amp_squared(from, to, q2, gammakstar, mkstar, R);
                stimespwave = fcnc::int_mkpi_bw_kstar_amp_bar_kstarzero_lass_amp(from, to, q2,
                                                                                 gammakstar, mkstar,
                                                                                 asphase, a, r, gammakstarplus, mkstarplus, R);
            }

            prob_bkg = 0.0;
            if (opts->mkpi_threshold){
                prob_bkg = fcnc::int_threshold(from, to, 0.633, params->at(k)->nthreshold());
            }
            else{
                for (unsigned int i=0; i<ch_mkpi.size(); i++){
                    prob_bkg += poly_corr_mkpi.at(i)*(pow(to,i+1)-pow(from,i+1))/(i+1.0);
                }
            }
            prob_bkg /= normbkg;
            double pwave = A*pwavesq/(rangednormkstar);
            double swave = B*swavesq/(rangednormkstarplus);
            //double swave = probswave;

            //double interference = 0.0;
            double interference = C*(stimespwave.real()/sqrt(rangednormkstarplus)/sqrt(rangednormkstar))
                    + D*(stimespwave.imag()/sqrt(rangednormkstarplus)/sqrt(rangednormkstar));

            tmp_sig->SetBinContent(i+1, (1.0-fs)*pwave + fs*swave + interference);
            tmp_bkg->SetBinContent(i+1, prob_bkg);
            tmp_swave->SetBinContent(i+1, swave);
            tmp_pwave->SetBinContent(i+1, pwave);
            tmp_interference->SetBinContent(i+1, interference);
            tmp_tot->SetBinContent(i+1,
                                   fsig*((1.0-fs)*pwave + fs*swave + interference)
                                   + (1.0-fsig)*prob_bkg);
        }

        tmp_sig->Scale(nevents * fsig * double(pdf_bins) / double(mkpi_bins));
        tmp_swave->Scale(nevents * fs*fsig * double(pdf_bins) / double(mkpi_bins));
        tmp_pwave->Scale(nevents * (1.0-fs)*fsig * double(pdf_bins) / double(mkpi_bins));
        tmp_interference->Scale(nevents * fsig * double(pdf_bins) / double(mkpi_bins));
        tmp_bkg->Scale(nevents * (1.0-fsig) * double(pdf_bins) / double(mkpi_bins));
        tmp_tot->Scale(nevents * double(pdf_bins) / double(mkpi_bins));

        mkpi_plot->Add(tmp_mkpi);
        pdf_sig->Add(tmp_sig);
        pdf_swave->Add(tmp_swave);
        pdf_pwave->Add(tmp_pwave);
        pdf_interference->Add(tmp_interference);
        pdf_bkg->Add(tmp_bkg);
        pdf_tot->Add(tmp_tot);

        delete tmp_mkpi;
        delete tmp_sig;
        delete tmp_swave;
        delete tmp_pwave;
        delete tmp_interference;
        delete tmp_bkg;
        delete tmp_tot;

    }

    double maxpdf = (pdf_tot->GetMaximum() > mkpi_plot->GetMaximum() ? pdf_tot->GetMaximum() : mkpi_plot->GetMaximum());
    if(this->pulls){
        if (logarithmic) pdf_sig->SetMinimum(0.1001);
        else             pdf_sig->SetMinimum(0.001);
    }
    else{ //no pull distributions
        if (logarithmic) pdf_sig->SetMinimum(0.1);
        else             pdf_sig->SetMinimum(0.0);
    }

    pdf_sig->SetMaximum(1.45*maxpdf);

    design_pdf(pdf_sig,kAzure, kAzure-5, 1001, 1-pullHeight, this->pulls);
    if(pdf_sig->Integral() > 0.0) pdf_sig->Draw("hist C");

    design_pdf(pdf_bkg,kOrange+10,kOrange+8, 3354, 1-pullHeight,pdf_sig->Integral() <= 0.0 );

    if(pdf_sig->Integral() > 0.0){
        pdf_bkg->Draw("hist same C");
    }
    else{
        pdf_bkg->SetMaximum(1.45*maxpdf);
        pdf_bkg->SetMinimum(minBkg);
        pdf_bkg->Draw("hist C");
    }


    if(opts->swave){
        design_pdfLine(pdf_pwave, pWaveColor, kDashed);
        pdf_pwave->Draw("hist same C");
        design_pdfLine(pdf_swave, sWaveColor, kDotted);
        pdf_swave->Draw("hist same C");
        design_pdfLine(pdf_interference, psInterferenceColor, kDashDotted);
        pdf_interference->Draw("hist same C");
    }


    design_pdfLine(pdf_tot, kBlack, kSolid);
    pdf_tot->Draw("hist same C");
    design_plot(mkpi_plot, 20, printC);
    mkpi_plot->Draw("same e1");

    //draw legend
    TLegend* mkpi_leg = new TLegend(0.675,0.45,0.875,0.65);
    mkpi_leg->SetBorderSize(0);
    mkpi_leg->SetTextFont(132);
    mkpi_leg->SetFillColor(0);
    mkpi_leg->AddEntry(mkpi_plot, "data", "le");
    mkpi_leg->AddEntry(pdf_tot, "total PDF", "l");
    mkpi_leg->AddEntry(pdf_sig, "signal PDF", "l");
    mkpi_leg->AddEntry(pdf_bkg, "bkg PDF", "l");
    if(opts->swave){
        mkpi_leg->AddEntry(pdf_pwave, "P-wave PDF", "l");
        mkpi_leg->AddEntry(pdf_swave, "S-wave PDF", "l");
        mkpi_leg->AddEntry(pdf_interference, "interference PDF", "l");
    }
    //mkpi_leg->Draw();

    TLatex *tex = design_TLatex(texsizelarge,texsizesmall, pullHeight, 0.47,
                                this->pulls, opts->plot_label,opts->q2_label);

    if(this->pulls){
        assert(pdf_bins == mkpi_bins*bin_ratio);

        //calculate pulls from fit and data points:
        for(UInt_t b = 1; b <= mkpi_bins; b++){
            double p;
            if(mkpi_plot->GetBinError(b) == 0){
                p = 0.;
            }
            else{
                if(bin_ratio == 1){
                    p = (mkpi_plot->GetBinContent(b) - pdf_tot->GetBinContent(b))/mkpi_plot->GetBinError(b);
                }
                //for odd ratio, take central bin from pdf w.r.t to m_bin:
                else if(bin_ratio%2 != 0){
                    p = (mkpi_plot->GetBinContent(b) - pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2))/mkpi_plot->GetBinError(b);
                }
                //else, average the two central bins from pdf w.r.t. to angle_bin:
                else{
                    p = (mkpi_plot->GetBinContent(b) - (pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2)+pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2 + 1))/2. ) / mkpi_plot->GetBinError(b); //take central of 10 pdfbins
                }
            }
            mkpi_pulls->SetBinContent(b, p);
        }
        pad2->Clear();
        pad2->SetMargin(0.125,0.1,0.125/ pullHeight, 1e-6);
        pad2->SetTickx();
        pad2->cd();

        design_pull(mkpi_pulls, kBlack,kGray+2,pullHeight,pullFrameRange);
        mkpi_pulls->Draw();

        //add two 3-sigma lines:
        TLine * lUp  = threeSigmaLine(mkpi_min, mkpi_max, true);
        TLine * lLow = threeSigmaLine(mkpi_min, mkpi_max, false);
        lUp->Draw("same");
        lLow->Draw("same");
    }

    std::string mkpiname = prefix + "mkpi_" + postfix + "_AllPDFs";
    saveTCanvas(mkpi_canvas, mkpiname, opts->getAllPlotTypes());

    output->cd();
    mkpi_canvas->Write();

    delete mkpi_plot;
    delete pdf_sig;
    delete pdf_swave;
    delete pdf_pwave;
    delete pdf_interference;
    delete pdf_bkg;
    delete pdf_tot;
    delete mkpi_pulls;
    delete mkpi_canvas;    
    delete tex;

}

void bu2kstarmumu_plotter::plot_angle_added_pdfs(std::vector<bu2kstarmumu_pdf*> * probs, std::vector<bu2kstarmumu_parameters*> * params, std::vector<std::vector<event>*> * events, std::string prefix, std::string postfix, bool signalregion, std::string angle, bool printC){

    bool is_ctl = false, is_ctk = false, is_phi = false;
    std::string angle_name = latex_angle(angle, is_ctl, is_ctk, is_phi);
    if(!is_ctl && !is_ctk && !is_phi) spdlog::error("Invalid angle name is given: " + angle );
    assert(is_ctl || is_ctk || is_phi);


    unsigned int angle_bins = 0;
    double angle_min = 0.;
    double angle_max = 0.;

    if(is_ctl){
        angle_bins = opts->plots_costhetal_bins;
        angle_min = opts->ctl_min;
        angle_max = opts->ctl_max;
        if(!opts->full_angular && opts->folding != 0)
            angle_bins /= 2;
    }
    else if(is_ctk){
        angle_bins = opts->plots_costhetak_bins;
        angle_min = opts->ctk_min;
        angle_max = opts->ctk_max;
    }
    else if(is_phi){
        angle_bins = opts->plots_phi_bins;
        angle_min = opts->phi_min;
        angle_max = opts->phi_max;
        if(!opts->full_angular)
            angle_bins /= 2;
    }

    assert(angle_min != 0. || angle_max != 0.);

    TCanvas *angle_canvas = nullptr;
    if(printC){
        angle_canvas = new TCanvas((angle+"_"+postfix).c_str(), ("B+ Likelihood Analysis: "+angle_name+" projection").c_str());
    }
    else{
        angle_canvas = new TCanvas((angle+"_"+postfix).c_str(), ("B+ Likelihood Analysis: "+angle_name+" projection").c_str(),1600,1200);
    }

    const double pullHeight = 0.27;
    const double pullFrameRange = 6.5;
    TPad *pad1 = new TPad(("pad1_"+angle).c_str(), "plot",0.0,pullHeight,1.0,1.0,0);
    TPad *pad2 = new TPad(("pad2_"+angle).c_str(), "pull",0.0,0.0,1.0,pullHeight,0);
    if(this->pulls){
        pad1->Draw();
        pad2->Draw();
        pad1->SetBorderSize  (0);
        pad1->SetMargin(0.125,0.1,1e-6,0.1/ (1 - pullHeight));
        pad1->SetTickx();
        pad1->SetTicky();
        pad1->cd();
    }
    else{
        angle_canvas->cd()->SetMargin(0.125,0.1,0.125,0.1);
        angle_canvas->SetTickx();
        angle_canvas->SetTicky();
    }
    std::ostringstream sout;
    sout << ";" << angle_name << ";" << EVENTS_TAG << " / " << std::setprecision(2) << (angle_max-angle_min)/angle_bins;
    std::ostringstream spulls;
    spulls << ";" << angle_name << ";" + latex_pull();
    TH1D* angle_pulls = new TH1D("angle_pulls", spulls.str().c_str(), angle_bins, angle_min, angle_max);


    const UInt_t bin_ratio = PLOT_NBINS_RATIO/2;
    unsigned int pdf_bins = angle_bins * bin_ratio;
    double dangle = (angle_max-angle_min)/pdf_bins;

    TH1D* angle_plot = new TH1D("m", sout.str().c_str(), angle_bins, angle_min, angle_max);
    TH1D* pdf_sig = new TH1D("pdf_sig", sout.str().c_str(), pdf_bins, angle_min, angle_max);
    TH1D* pdf_swave = new TH1D("pdf_swave", sout.str().c_str(), pdf_bins, angle_min, angle_max);
    TH1D* pdf_pwave = new TH1D("pdf_pwave", sout.str().c_str(), pdf_bins, angle_min, angle_max);
    TH1D* pdf_interference = new TH1D("pdf_interference", sout.str().c_str(), pdf_bins, angle_min, angle_max);
    TH1D* pdf_bkg = new TH1D("pdf_bkg", sout.str().c_str(), pdf_bins, angle_min, angle_max);
    TH1D* pdf_tot = new TH1D("pdf_tot", sout.str().c_str(), pdf_bins, angle_min, angle_max);
    double prob_sig=0.0, prob_bkg=0.0, prob_pwave=0.0, prob_swave=0.0, prob_interference=0.0;
    double ctk_from = 0.0, ctk_to = 0.0, ctl_from=0.0, ctl_to=0.0, phi_from=0.0, phi_to=0.0;

    angle_plot->Sumw2();

    for(UInt_t k = 0; k < params->size(); k++){

        TH1D* tmp_angle = new TH1D(("tmp_angle"+std::to_string(k)).c_str(), sout.str().c_str(), angle_bins, angle_min, angle_max);
        TH1D* tmp_sig = new TH1D(("tmp_sig"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, angle_min, angle_max);
        TH1D* tmp_swave = new TH1D(("tmp_swave"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, angle_min, angle_max);
        TH1D* tmp_pwave = new TH1D(("tmp_pwave"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, angle_min, angle_max);
        TH1D* tmp_interference = new TH1D(("tmp_interference"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, angle_min, angle_max);
        TH1D* tmp_bkg = new TH1D(("tmp_bkg"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, angle_min, angle_max);
        TH1D* tmp_tot = new TH1D(("tmp_tot"+std::to_string(k)).c_str(), sout.str().c_str(), pdf_bins, angle_min, angle_max);

        double ma = params->at(k)->m_b() - B_MASS_TIGHT_WINDOW;
        double mb = params->at(k)->m_b() + B_MASS_TIGHT_WINDOW;

        double fsig = params->at(k)->f_sig();
        if(opts->extended_ml){
            fsig = params->at(k)->n_sig() / (params->at(k)->n_sig()+params->at(k)->n_bkg());
        }
        if (signalregion){
            double rsig = probs->at(k)->integral_m_sig_prob(params->at(k), ma, mb);
            double rbkg = probs->at(k)->integral_m_bkg_prob(params->at(k), ma, mb);
            fsig = fsig*rsig/(fsig*rsig + (1.0-fsig)*rbkg);
        }

        double nevents = 0.0;
        for (unsigned int i = 0; i < events->at(k)->size(); i++){
            if (!signalregion || (events->at(k)->at(i).m > ma && events->at(k)->at(i).m < mb)){
                double weight = 1.0, value = -100.0;
                if (opts->weighted_fit)
                    weight = events->at(k)->at(i).weight;
                if(is_phi)value = events->at(k)->at(i).phi;
                else if (is_ctk)value = events->at(k)->at(i).costhetak;
                else if (is_ctl)value = events->at(k)->at(i).costhetal;
                else return;
                tmp_angle->Fill(value, weight);
                nevents += weight;
            }
        }

        const double q2 = params->at(k)->eff_q2();
        const double j1s = params->at(k)->J1s();
        const double j1c = params->at(k)->J1c();
        const double j2s = params->at(k)->J2s();
        const double j2c = params->at(k)->J2c();
        const double j3 = params->at(k)->J3();
        const double j4 = params->at(k)->J4();
        const double j5 = params->at(k)->J5();
        const double j6s = params->at(k)->J6s();
        const double j6c = params->at(k)->J6c();
        const double j7 = params->at(k)->J7();
        const double j8 = params->at(k)->J8();
        const double j9 = params->at(k)->J9();

        double f1=0.0, f2=0.0, f3=0.0,  f4=0.0,  f5=0.0,  f6=0.0,
                f7=0.0, f8=0.0, f9=0.0, f10=0.0, f11=0.0, f12=0.0;

        for (unsigned int i = 0; i < pdf_bins; i++){
            if(is_ctk){
                ctk_from = angle_min + i*dangle;
                ctk_to   = angle_min + (i+1)*dangle;
                ctl_from = opts->ctl_min;
                ctl_to   = opts->ctl_max;
                phi_from = opts->phi_min;
                phi_to   = opts->phi_max;
            }
            else if(is_ctl){
                ctk_from = opts->ctk_min;
                ctk_to   = opts->ctk_max;
                ctl_from = angle_min + i*dangle;
                ctl_to = angle_min + (i+1)*dangle;
                phi_from = opts->phi_min;
                phi_to   = opts->phi_max;
            }
            else if(is_phi){
                ctk_from = opts->ctk_min;
                ctk_to   = opts->ctk_max;
                ctl_from = opts->ctl_min;
                ctl_to   = opts->ctl_max;
                phi_from = angle_min + i*dangle;
                phi_to = angle_min + (i+1)*dangle;
            }
            else return;

            if (opts->full_angular){

                if (opts->use_angular_acc){
                    probs->at(k)->integrated_fj_chebyshev(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                                          f1, f2, f3, f4, f5, f6,
                                                          f7, f8, f9, f10, f11, f12, q2);
                }
                else{
                    probs->at(k)->integrated_fj_noacc(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                                      f1, f2, f3, f4, f5, f6,
                                                      f7, f8, f9, f10, f11, f12);
                }
                prob_sig = (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
                            + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9)/probs->at(k)->fnorm_sig;
                prob_pwave = prob_sig;
                if (opts->swave){
                    const double fs = params->at(k)->FS();
                    const double js1 = params->at(k)->SS1();
                    const double js2 = params->at(k)->SS2();
                    const double js3 = params->at(k)->SS3();
                    const double js4 = params->at(k)->SS4();
                    const double js5 = params->at(k)->SS5();

                    double fs1=0.0, fs2=0.0, fs3=0.0, fs4=0.0, fs5=0.0, fs6=0.0;

                    if (opts->use_angular_acc)
                        probs->at(k)->swave_integrated_fj_chebyshev(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                                                    fs1, fs2, fs3, fs4, fs5, fs6, q2);
                    else
                        probs->at(k)->swave_integrated_fj_noacc(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                                                fs1, fs2, fs3, fs4, fs5, fs6);

                    prob_sig = ((1-fs)*(f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
                                        + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9)
                                +(fs1*fs + fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5))/probs->at(k)->fnorm_sig;
                    prob_pwave = ((1-fs)*(f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
                                          + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9))/probs->at(k)->fnorm_sig;
                    prob_swave = fs1*fs/probs->at(k)->fnorm_sig;
                    prob_interference = (fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5)/probs->at(k)->fnorm_sig;
                }
            }
            else { //folding
                if (opts->use_angular_acc) probs->at(k)->folded_integrated_fj_chebyshev(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                                                                       f1, f2, f3, f4, f5, f6,
                                                                                       f7, f8, f9, f10, f11, f12, q2);
                else                       probs->at(k)->folded_integrated_fj_noacc(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                                                                    f1, f2, f3, f4, f5, f6,
                                                                                    f7, f8, f9, f10, f11, f12);
                //Calculated probability for all foldings
                //non-active coefficients are return 0 by 'folded'-functions in the lines above!
                prob_sig = (f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3  + f6*j4
                            + f7*j5  + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9)/probs->at(k)->fnorm_sig;
                prob_pwave = prob_sig;
                if(opts->swave){
                    const double fs = params->at(k)->FS();
                    const double js1 = params->at(k)->SS1();
                    const double js2 = params->at(k)->SS2();
                    const double js3 = params->at(k)->SS3();
                    const double js4 = params->at(k)->SS4();
                    const double js5 = params->at(k)->SS5();

                    double fs1=0.0, fs2=0.0, fs3=0.0, fs4=0.0, fs5=0.0, fs6=0.0;

                    if (opts->use_angular_acc)
                        probs->at(k)->folded_swave_integrated_fj_chebyshev(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                                                           fs1, fs2, fs3, fs4, fs5, fs6, q2);
                    else
                        probs->at(k)->folded_swave_integrated_fj_noacc(ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to,
                                                                       fs1, fs2, fs3, fs4, fs5, fs6);

                    prob_sig = ((1-fs)*(f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
                                        + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9)
                                +(fs1*fs + fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5))/probs->at(k)->fnorm_sig;
                    prob_pwave = ((1-fs)*(f1*j1s + f2*j1c + f3*j2s + f4*j2c + f5*j3 + f6*j4
                                          + f7*j5 + f8*j6s + f9*j6c + f10*j7 + f11*j8 + f12*j9))/probs->at(k)->fnorm_sig;
                    prob_swave = fs1*fs/probs->at(k)->fnorm_sig;
                    prob_interference = (fs2*js1 + fs3*js2 + fs4*js3 + fs5*js4 + fs6*js5)/probs->at(k)->fnorm_sig;
                }
            }
            tmp_sig->SetBinContent(i+1, prob_sig);
            tmp_interference->SetBinContent(i+1, prob_interference);
            tmp_pwave->SetBinContent(i+1, prob_pwave);
            if (opts->swave) tmp_swave->SetBinContent(i+1, prob_swave);

            if(opts->use_angular_acc && opts->use_weighted_bkg){
                if(opts->fit_full_angular_bkg && !opts->flat_bkg && !opts->full_angular){
                    double pi = TMath::Pi();
                    if(opts->folding == 0){
                        prob_bkg = (probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2)
                                    + probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from-pi, phi_to-pi, q2)) /probs->at(k)->fnorm_bkg;
                    }
                    else if(opts->folding == 1){
                        prob_bkg = (probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2)
                                    + probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, -phi_to, -phi_from, q2)
                                    + probs->at(k)->integral_bkg_chebyshev(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, pi-phi_to, pi-phi_from, q2)
                                    + probs->at(k)->integral_bkg_chebyshev(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, -pi+phi_from, -pi+phi_to, q2)) /probs->at(k)->fnorm_bkg;
                    }
                    else if(opts->folding == 2){
                        prob_bkg = (probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2)
                                    + probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, -phi_to, -phi_from, q2)
                                    + probs->at(k)->integral_bkg_chebyshev(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, phi_from, phi_to, q2)
                                    + probs->at(k)->integral_bkg_chebyshev(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, -phi_to, -phi_from, q2)) /probs->at(k)->fnorm_bkg;
                    }
                    else if(opts->folding == 3){
                        if((phi_from <= 0.0 && phi_to <= 0.0) || (phi_from >= 0.0 && phi_to >= 0.0)){
                            prob_bkg = (probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, (phi_from < 0.0 ? -pi - phi_to : pi - phi_to), (phi_to < 0.0 ? -pi - phi_from : pi - phi_from), q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, phi_from, phi_to, q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, (phi_from < 0.0 ? -pi - phi_to : pi - phi_to), (phi_to < 0.0 ? -pi - phi_from : pi - phi_from), q2)) /probs->at(k)->fnorm_bkg;
                        }
                        else{ //when phi_from < 0.0 and phi_to > 0.0:
                            assert(phi_to > phi_from);
                            prob_bkg = (probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, -pi,         -pi - phi_from, q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to,  pi - phi_to, pi, q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, phi_from, phi_to, q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, -pi,        -pi - phi_from, q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, pi - phi_to, pi, q2)) /probs->at(k)->fnorm_bkg;
                        }
                    }
                    else if(opts->folding == 4){
                        if((phi_from <= 0.0 && phi_to <= 0.0) || (phi_from >= 0.0 && phi_to >= 0.0)){
                            prob_bkg = (probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, (phi_from < 0.0 ? -pi - phi_to : pi - phi_to), (phi_to < 0.0 ? -pi - phi_from : pi - phi_from), q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), -ctl_to, -ctl_from, -ctk_to, -ctk_from, phi_from, phi_to, q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), -ctl_to, -ctl_from, -ctk_to, -ctk_from, (phi_from < 0.0 ? -pi - phi_to : pi - phi_to), (phi_to < 0.0 ? -pi - phi_from : pi - phi_from), q2)) /probs->at(k)->fnorm_bkg;
                        }
                        else{ //when phi_from < 0.0 and phi_to > 0.0:
                            assert(phi_to > phi_from);
                            prob_bkg = (probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, -pi,         -pi - phi_from, q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to,  pi - phi_to, pi, q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), -ctl_to, -ctl_from, -ctk_to, -ctk_from, phi_from, phi_to, q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), -ctl_to, -ctl_from, -ctk_to, -ctk_from, -pi,         -pi - phi_from, q2)
                                        + probs->at(k)->integral_bkg_chebyshev(params->at(k), -ctl_to, -ctl_from, -ctk_to, -ctk_from,  pi - phi_to, pi, q2)) /probs->at(k)->fnorm_bkg;
                        }
                    }
                }
                else{
                    prob_bkg = probs->at(k)->integral_bkg_chebyshev(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to, q2) /probs->at(k)->fnorm_bkg;
                }
            }
            else{
                if(opts->fit_full_angular_bkg && !opts->flat_bkg && !opts->full_angular){
                    double pi = TMath::Pi();
                    if(opts->folding == 0){
                        prob_bkg = (probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to)
                                    + probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from-pi, phi_to-pi)) /probs->at(k)->fnorm_bkg;
                    }
                    else if(opts->folding == 1){
                        prob_bkg = (probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to)
                                    + probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, -phi_to, -phi_from)
                                    + probs->at(k)->integral_bkg(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, pi-phi_to, pi-phi_from)
                                    + probs->at(k)->integral_bkg(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, -pi+phi_from, -pi+phi_to)) /probs->at(k)->fnorm_bkg;
                    }
                    else if(opts->folding == 2){
                        prob_bkg = (probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to)
                                    + probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, -phi_to, -phi_from)
                                    + probs->at(k)->integral_bkg(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, phi_from, phi_to)
                                    + probs->at(k)->integral_bkg(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, -phi_to, -phi_from)) /probs->at(k)->fnorm_bkg;
                    }
                    else if(opts->folding == 3){
                        if((phi_from <= 0.0 && phi_to <= 0.0) || (phi_from >= 0.0 && phi_to >= 0.0)){
                            prob_bkg = (probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to)
                                        + probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, (phi_from < 0.0 ? -pi - phi_to : pi - phi_to), (phi_to < 0.0 ? -pi - phi_from : pi - phi_from))
                                        + probs->at(k)->integral_bkg(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, phi_from, phi_to)
                                        + probs->at(k)->integral_bkg(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, (phi_from < 0.0 ? -pi - phi_to : pi - phi_to), (phi_to < 0.0 ? -pi - phi_from : pi - phi_from))) /probs->at(k)->fnorm_bkg;
                        }
                        else{ //when phi_from < 0.0 and phi_to > 0.0:
                            assert(phi_to > phi_from);
                            prob_bkg = (probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to)
                                        + probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, -pi,         -pi - phi_from)
                                        + probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to,  pi - phi_to, pi)
                                        + probs->at(k)->integral_bkg(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, phi_from, phi_to)
                                        + probs->at(k)->integral_bkg(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, -pi,        -pi - phi_from)
                                        + probs->at(k)->integral_bkg(params->at(k), -ctl_to, -ctl_from, ctk_from, ctk_to, pi - phi_to, pi)) /probs->at(k)->fnorm_bkg;
                        }
                    }
                    else if(opts->folding == 4){
                        if((phi_from <= 0.0 && phi_to <= 0.0) || (phi_from >= 0.0 && phi_to >= 0.0)){
                            prob_bkg = (probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to)
                                        + probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, (phi_from < 0.0 ? -pi - phi_to : pi - phi_to), (phi_to < 0.0 ? -pi - phi_from : pi - phi_from))
                                        + probs->at(k)->integral_bkg(params->at(k), -ctl_to, -ctl_from, -ctk_to, -ctk_from, phi_from, phi_to)
                                        + probs->at(k)->integral_bkg(params->at(k), -ctl_to, -ctl_from, -ctk_to, -ctk_from, (phi_from < 0.0 ? -pi - phi_to : pi - phi_to), (phi_to < 0.0 ? -pi - phi_from : pi - phi_from))) /probs->at(k)->fnorm_bkg;
                        }
                        else{ //when phi_from < 0.0 and phi_to > 0.0:
                            assert(phi_to > phi_from);
                            prob_bkg = (probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to)
                                        + probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, -pi,         -pi - phi_from)
                                        + probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to,  pi - phi_to, pi)
                                        + probs->at(k)->integral_bkg(params->at(k), -ctl_to, -ctl_from, -ctk_to, -ctk_from, phi_from, phi_to)
                                        + probs->at(k)->integral_bkg(params->at(k), -ctl_to, -ctl_from, -ctk_to, -ctk_from, -pi,         -pi - phi_from)
                                        + probs->at(k)->integral_bkg(params->at(k), -ctl_to, -ctl_from, -ctk_to, -ctk_from,  pi - phi_to, pi)) /probs->at(k)->fnorm_bkg;
                        }
                    }
                }
                else{
                    prob_bkg = probs->at(k)->integral_bkg(params->at(k), ctl_from, ctl_to, ctk_from, ctk_to, phi_from, phi_to) /probs->at(k)->fnorm_bkg;
                }
            }
            tmp_bkg->SetBinContent(i+1, prob_bkg);
        }

        tmp_sig->Scale(nevents * fsig * double(pdf_bins) / double(angle_bins));
        tmp_pwave->Scale(nevents * fsig * double(pdf_bins) / double(angle_bins));
        if (opts->swave) tmp_swave->Scale(nevents * fsig * double(pdf_bins) / double(angle_bins));
        tmp_interference->Scale(nevents * fsig * double(pdf_bins) / double(angle_bins));

        tmp_bkg->Scale(nevents * (1.0-fsig) * double(pdf_bins) / double(angle_bins));

        tmp_tot->Add(tmp_sig, tmp_bkg);

        angle_plot->Add(tmp_angle);
        pdf_sig->Add(tmp_sig);
        if (opts->swave) pdf_swave->Add(tmp_swave);
        pdf_pwave->Add(tmp_pwave);
        pdf_interference->Add(tmp_interference);
        pdf_bkg->Add(tmp_bkg);
        pdf_tot->Add(tmp_tot);

        delete tmp_angle;
        delete tmp_sig;
        delete tmp_swave;
        delete tmp_pwave;
        delete tmp_interference;
        delete tmp_bkg;
        delete tmp_tot;

    }

    double maxpdf = (pdf_tot->GetMaximum() > angle_plot->GetMaximum() ? pdf_tot->GetMaximum() : angle_plot->GetMaximum());
    if(this->pulls) pdf_sig->SetMinimum(0.1001);
    else            pdf_sig->SetMinimum(0.0);

    pdf_sig->SetMaximum(1.45*maxpdf);
    pdf_sig->SetTitleSize(0.06, "XY");
    pdf_sig->SetLabelSize(0.05, "XY");
    pdf_sig->SetTitleOffset(0.9, "XY");
    pdf_sig->GetXaxis()->SetNoExponent(kTRUE);
    TGaxis::SetMaxDigits(3);
    design_pdf(pdf_sig,kAzure, kAzure-5, 1001, 1-pullHeight, this->pulls);
    if(pdf_sig->Integral() > 0.0) pdf_sig->Draw("hist C");

    design_pdf(pdf_bkg,kOrange+10,kOrange+8, 3354, 1-pullHeight,pdf_sig->Integral() <= 0.0 );

    if(pdf_sig->Integral() > 0.0){
        pdf_bkg->Draw("hist same C");
    }
    else{
        pdf_bkg->SetMaximum(1.45*maxpdf);
        pdf_bkg->SetMinimum(minBkg);
        pdf_bkg->Draw("hist C");
    }

    /////

    design_pdfLine(pdf_pwave, pWaveColor, kDashed);
    if(opts->swave)  pdf_pwave->Draw("hist same C");

    design_pdfLine(pdf_swave, sWaveColor, kDotted);
    if(opts->swave)  pdf_swave->Draw("hist same C");

    design_pdfLine(pdf_interference, psInterferenceColor, kDashDotted);
    if(opts->swave)  pdf_interference->Draw("hist same C");

    design_pdfLine(pdf_tot, kBlack, kSolid);
    pdf_tot->Draw("hist same C");

    design_plot(angle_plot, 20, printC);
    angle_plot->Draw("same e1");

    TLegend* angle_leg = new TLegend(0.675,0.45,0.875,0.65);
    angle_leg->SetBorderSize(0);
    angle_leg->SetTextFont(132);
    angle_leg->SetFillColor(0);
    angle_leg->AddEntry(angle_plot, "data", "le");
    angle_leg->AddEntry(pdf_tot, "total PDF", "l");
    angle_leg->AddEntry(pdf_sig, "signal PDF", "l");
    angle_leg->AddEntry(pdf_bkg, "bkg PDF", "l");
    if(opts->swave){
        angle_leg->AddEntry(pdf_pwave, "P-wave PDF", "l");
        angle_leg->AddEntry(pdf_swave, "S-wave PDF", "l");
        angle_leg->AddEntry(pdf_interference, "interference PDF", "l");
    }
    //angle_leg->Draw("same");

    TLatex *tex = design_TLatex(texsizelarge,texsizesmall, pullHeight, 0.47,
                                this->pulls, opts->plot_label,opts->q2_label);

    if(this->pulls){
        assert(pdf_bins == angle_bins*bin_ratio);

        //calculate pulls from fit and data points:
        for(UInt_t b = 1; b <= angle_bins; b++){
            double p;
            if(angle_plot->GetBinError(b) == 0)
                p = 0.;
            else{
                if(bin_ratio == 1){
                    p = (angle_plot->GetBinContent(b) - pdf_tot->GetBinContent(b))/angle_plot->GetBinError(b);
                }
                //for odd ratio, take central bin from pdf w.r.t to angle_bin:
                else if(bin_ratio%2 != 0){
                    p = (angle_plot->GetBinContent(b) - pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2))/angle_plot->GetBinError(b);
                }
                //else, average the two central bins from pdf w.r.t. to angle_bin:
                else{
                    p = (angle_plot->GetBinContent(b) - (pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2)+pdf_tot->GetBinContent(b*bin_ratio - bin_ratio/2 + 1))/2. ) / angle_plot->GetBinError(b); //take central of 10 pdfbins
                }
            }
            angle_pulls->SetBinContent(b, p);
        }
        pad2->Clear();
        pad2->SetMargin(0.125,0.1,0.125/ pullHeight, 1e-6);
        pad2->SetTickx();
        pad2->cd();

        design_pull(angle_pulls, kBlack,kGray+2,pullHeight,pullFrameRange);
        angle_pulls->Draw();

        //add two 3-sigma lines:
        TLine * lUp  = threeSigmaLine(angle_min, angle_max, true);
        TLine * lLow = threeSigmaLine(angle_min, angle_max, false);
        lUp->Draw("same");
        lLow->Draw("same");
    }

    std::string anglename = prefix + angle + "_" + postfix+ "_AllPDFs";
    saveTCanvas(angle_canvas, anglename, opts->getAllPlotTypes());

    output->cd();
    angle_canvas->Write();

    delete angle_plot;
    delete angle_pulls;
    delete pdf_sig;
    delete pdf_pwave;
    delete pdf_swave;
    delete pdf_interference;
    delete pdf_bkg;
    delete pdf_tot;
    delete angle_canvas;
    delete tex;
}

void bu2kstarmumu_plotter::SetPulls(bool drawpulls){
    this->pulls = drawpulls;
}

int bu2kstarmumu_plotter::plotYieldInQ2(bool fixRange,  std::vector<parameters*> fitParams[], std::vector<pdf *> pdf[], int nPDFs, std::vector<UInt_t>nEvts[],  std::string prefix, std::string plotName){

    // CMS [1 - 8.68], [10.09 - 12.86],  [14.18 - 19.00]
    double CMS_X[3]  = {4.84, 11.475, 16.59};
    double CMS_EX[3] = {3.84, 1.385,  2.41};
    double CMS_Y[3]  = {2.7, 4.1, 5.6};
    double CMS_EY[3] = {0.0, 0.0, 0.0};
    double CMS_sig[3]   = {22.1,25.9,45.1};
    double CMS_sig_E[3] = {8.1,6.3,8.0};
    double CMS_bkg[3]   = {49.0,14.0,20.0};
    double CMS_bkg_E[3] = {0.0,0.0,0.0};

    TGraphErrors *graphSignificanceCMS = new TGraphErrors(3,CMS_X,CMS_Y,CMS_EX,CMS_EY);
    //Not used, but keep it in case
    TGraphErrors *graphSigCMS = new TGraphErrors(3,CMS_X,CMS_sig,CMS_EX,CMS_sig_E);
    TGraphErrors *graphBkgCMS = new TGraphErrors(3,CMS_X,CMS_bkg,CMS_EX,CMS_bkg_E);
    graphSigCMS->SetTitle("SigCMS");
    graphBkgCMS->SetTitle("BkgCMS");

    //Protection against the 1.1-6.0 bin
    const int nBins = opts->get_nQ2bins()==5 ? 4 : opts->get_nQ2bins();

    double bkg_yield_tot[nBins];
    double sig_yield_tot[nBins];
    for (int n = 0; n < nPDFs; n++){
        TGraphErrors *tmpSig = new TGraphErrors();
        TGraphErrors *tmpBkg = new TGraphErrors();
        TGraphErrors *tmpSignificance = new TGraphErrors();

        for (int b = 0; b < nBins; b++){

            double binCenter = bin_center_q2(opts,b);
            double binError  = bin_halfWidth_q2(opts,b);

            //TODO: add couts
            //First get the measured mean
            double measured_m =((fcnc::bu2kstarmumu_parameters *)fitParams[b].at(n))->m_b.get_value();
            //Then get the fraction of signal
            double f_sig =((fcnc::bu2kstarmumu_parameters *)fitParams[b].at(n))->f_sig.get_value();

            //If fixed window, use B_MASS_TIGHT_WINDOW
            //Otherwise use 2*sigma //TODO: for now only one sigma
            double window = 0.0;
            if (fixRange) window = B_MASS_TIGHT_WINDOW;
            else          window = 2*((fcnc::bu2kstarmumu_parameters *)fitParams[b].at(n))->m_sigma_1.get_value();

            //Get the probabilities
            double sig_prob = ((fcnc::bu2kstarmumu_pdf*) pdf[b].at(n))->integral_m_sig_prob((fcnc::bu2kstarmumu_parameters*)fitParams[b].at(n),measured_m-window, measured_m+window);

            double bkg_prob = ((fcnc::bu2kstarmumu_pdf*) pdf[b].at(n))->integral_m_bkg_prob((fcnc::bu2kstarmumu_parameters*)fitParams[b].at(n),measured_m-window, measured_m+window);

            double bkg_yield = bkg_prob * nEvts[b].at(n)*(1.0-f_sig);
            double sig_yield = sig_prob * nEvts[b].at(n)*f_sig;
            bkg_yield_tot[b] += bkg_yield;
            sig_yield_tot[b] += sig_yield;

            spdlog::debug("Bkg yield: {0:f}", bkg_yield);
            spdlog::debug("Sig yield: {0:f}", sig_yield);
            //TODO: add yield errors!
            double significance = sig_yield/sqrt(sig_yield+bkg_yield);

            //Signal
            tmpSig->SetPoint(tmpSig->GetN(), binCenter, sig_yield);
            tmpSig->SetPointError(tmpSig->GetN()-1, binError, 0.0);
            //Background
            tmpBkg->SetPoint(tmpBkg->GetN(), binCenter,  bkg_yield);
            tmpBkg->SetPointError(tmpBkg->GetN()-1, binError, 0.0);
            //Significance
            tmpSignificance->SetPoint(tmpSignificance->GetN(), binCenter, significance);
            tmpSignificance->SetPointError(tmpSignificance->GetN()-1,binError,0.0);
        }
        std::string tmpPlotName = prefix+ plotName  + "_significance_Run" + std::to_string(n+1);
        //TODO: n+1 is run, so this should be fixed to pdf_idx
        design_YieldInQ2(n+1, tmpSig, tmpBkg, tmpSignificance, graphSignificanceCMS, fixRange, tmpPlotName,opts->getAllPlotTypes());
        design_SignificanceInQ2(n+1,tmpSignificance,graphSignificanceCMS,fixRange, std::string(tmpPlotName+"_noYields"),opts->getAllPlotTypes());

    }

    //Make a Run 1+2 plot
    TGraphErrors *totSig = new TGraphErrors();
    TGraphErrors *totBkg = new TGraphErrors();
    TGraphErrors *totSignificance = new TGraphErrors();

    for (int b = 0; b < nBins; b++){
        double significance =  sig_yield_tot[b]/sqrt( sig_yield_tot[b]+ bkg_yield_tot[b]);

        double binCenter = bin_center_q2(opts,b);
        double binError  = bin_halfWidth_q2(opts,b);

        //Signal
        totSig->SetPoint(totSig->GetN(), binCenter, sig_yield_tot[b]);
        totSig->SetPointError(totSig->GetN()-1, binError, 0.0);
        //Background
        totBkg->SetPoint(totBkg->GetN(), binCenter,  bkg_yield_tot[b]);
        totBkg->SetPointError(totBkg->GetN()-1, binError, 0.0);
        //Significance
        totSignificance->SetPoint(totSignificance->GetN(), binCenter, significance);
        totSignificance->SetPointError(totSignificance->GetN()-1,binError,0.0);

    }
    std::string tmpPlotName = prefix+ plotName  + "_significance_Run" + std::to_string(12);
    design_YieldInQ2(12, totSig, totBkg, totSignificance, graphSignificanceCMS, fixRange, tmpPlotName,opts->getAllPlotTypes());
    design_SignificanceInQ2(12, graphSignificanceCMS, graphSignificanceCMS, fixRange, std::string(tmpPlotName+"_noYields"),opts->getAllPlotTypes());

    return 0;
}


