//compare MC and data of BDT variables for B+->Kst+mumu
//david gerick
//Renata Kopecna

#include "../GlobalFunctions.hh"
#include "../nTrackWeights.cpp"
#include "../LHCbStyle.h"

//#include "MVA_b2kmm.cc"

using namespace std;
using namespace RooFit ;
#include <algorithm>    // std::max, min

//////////////////////////////////////////////////////
///  compareVariables()
/// compute and plot a desired variable for given year and subdecay channel
/// choose weither it is sWeighted, not weighted, weighted by nTracks or 2 * 1D reweighted by
/// nTracks and B_plus_PT. The data sample can be sweighted, so the weighting
/// only concerns the MC sample.
/// Choose, weither to print the plots to pdf and root files.
/// variables can be plotted in log(var) or log(1 - var), using the according booleans
///
///  compareAll***()
/// compare all variables given in the function and save the plots
///
///  compareTrackMultiplicities()
/// compare the distribution of different track types between Run I and Run II
/// use sWeights and normalize the samples!
///
///  compareAnglesInPHSP()
/// see the effects of re-weighting of PHSP MC on the angular distributions
///
///  compareAnglesInMC()
/// see the effects of re-weighting of MC on the angular distributions
///
///  compareAnglesInPHSPbeforeAndAfterBDTcut()
/// see the effect of the BDT cut on the angular distributions of PHSP MC
///
///

const bool CutInQ2 = false;
double minQ2 = 15.0;
double maxQ2 = 100.0;

const bool CutInMuPt = false;
double minPT = 1100.0; //2500
double maxPT = 2500.0; //10000

const bool separateCharge = false;
bool plusCharge = false;


int evalOperation(bool useTwoVars = false, int x = 0, int y = 0, std::string operation = "plus",bool bLogVar = false, bool bLog1minusVar = false){
    if (bLogVar){
        x = log(x);
        y = log(y);
    }
    else if (bLog1minusVar){
        x = log(1-x);
        y = log(1-y);
    }
    if (!useTwoVars) return x;

    if      (operation == "max")     return max(x,y);
    else if (operation == "min")     return min(x,y);
    else if (operation == "abs")     return abs(x-y);
    else if (operation == "plus")    return x+y;
    else if (operation == "minus")   return x-y;
    else{
        coutERROR("Wrong opetaion specified, returning 0!");
        return 0;
    }
}


double evalOperation(bool useTwoVars = false, double x = 0.0, double y = 0.0, std::string operation = "plus",bool bLogVar = false, bool bLog1minusVar = false){
    if (bLogVar){
        x = log(x);
        y = log(y);
    }
    else if (bLog1minusVar){
        x = log(1-x);
        y = log(1-y);
    }
    if (!useTwoVars) return x;

    if      (operation == "max")     return max(x,y);
    else if (operation == "min")     return min(x,y);
    else if (operation == "abs")     return abs(x-y);
    else if (operation == "plus")    return x+y;
    else if (operation == "minus")   return x-y;
    else{
        coutERROR("Wrong opetaion specified, returning 0!");
        return 0.;
    }
}

int compareVariables(int year = 2011, std::string variable = "B_plus_PT", bool sWeight = true, bool bWeighted = true, bool b2Dweighted = true,
                       bool bLogVar = false, bool bLog1minusVar = false, bool bPrint = true, bool KshortDecayInVelo = true, std::string weightBranch = "CB", bool useTwoVars = false, string operation = "", string variable2 = "" , string xAxis = "") {

    //if 2D weighted, set boolean for 1D weighting false
    if(b2Dweighted)bWeighted = false;

    //We don't use more than two variables; here are the option of what to do with the variables
    //Tried some fanc ystuff, was too complicated to quickly write
    // max(x,y)
    // min(x,y)
    //abs(x-y)
    //x-y
    //x+y
    //where x,y can be both in log if bLogVar is true

    gStyle -> SetOptStat(0);
    gROOT->SetBatch(kTRUE);
    LHCbStyle();
    //lhcbStyle->SetOptTitle(1);
    //lhcbStyle->SetTitleSize(0.1,"x");
    //lhcbStyle->SetTitleSize(0.1,"y");
    //lhcbStyle->SetTitleSize(0.1,"z");


    bool varIsInt = false;
    if(variable == "nTracks")           varIsInt = true;
    if(variable == "nSPDHits")          varIsInt = true;
    if(variable == "nLongTracks")       varIsInt = true;
    if(variable == "nVeloTracks")       varIsInt = true;
    if(variable == "nTTracks")          varIsInt = true;
    if(variable == "nDownstreamTracks") varIsInt = true;
    if(variable == "nUpstreamTracks")   varIsInt = true;
    if(variable == "nPV")               varIsInt = true;


    bool varIsInt2 = false;
    if(variable2 == "nTracks")           varIsInt2 = true;
    if(variable2 == "nSPDHits")          varIsInt2 = true;
    if(variable2 == "nLongTracks")       varIsInt2 = true;
    if(variable2 == "nVeloTracks")       varIsInt2 = true;
    if(variable2 == "nTTracks")          varIsInt2 = true;
    if(variable2 == "nDownstreamTracks") varIsInt2 = true;
    if(variable2 == "nUpstreamTracks")   varIsInt2 = true;
    if(variable2 == "nPV")               varIsInt2 = true;


    ///for now hardcoded, but might be possible to include in input parameters if comparison between data and reference MC is needed
    const bool ReferenceChannel = true;

    ///for writting only the ratio and superposition
    const bool minimumPlot = true;

    ///print the LHCb tag and the legend onto plots?
    const bool print_legend = true;

    if(bLogVar && bLog1minusVar){
        coutERROR( "Only Log( var ) or Log( 1 - var ) option possible, but both flags were set for variable: " + variable);
        if (useTwoVars) coutERROR(" and variable " + variable2);
        return 0;
    }

    //put both magnet polarities into one TChain
    TChain * treeData = new TChain("DecayTree");
    TChain * treeMC   = new TChain("DecayTreeTruthMatched");


    // Kst2Kpluspi0Resolved case
    if(Kst2Kpluspi0Resolved){
        if(ReferenceChannel){
            treeData->Add(Form("%s/Tuples/Data/%i_RefKplusPi0Resolved_BDTinput.root", path_to_output_KplusPizero.c_str(),  year));
            treeMC->Add(Form("%s/Tuples/MC/%i_RefKplusPi0Resolved_BDTinput.root",  path_to_output_KplusPizero.c_str(), year > 2016 ? 2016 : year));
        }
        else{            
            treeData->Add(Form("%s/Tuples/Data/%i_KplusPi0Resolved_BDTinput.root", path_to_output_KplusPizero.c_str(), year));
            treeMC->Add(Form("%s/Tuples/MC/%i_KplusPi0Resolved_BDTinput.root", path_to_output_KplusPizero.c_str(),  year == 2015 ? 2016 : year));
        }
    }

    // Kst2Kpluspi0Merged case
    else if(Kst2Kpluspi0Merged){
        if(ReferenceChannel){
            treeData->Add(Form("%s/Tuples/Data/%i_RefKplusPi0Merged_BDTinput.root", path_to_output_KplusPizero.c_str(), year));
            treeMC->Add(Form("%s/Tuples/MC/%i_KplusPi0MergedRef_BDTinput.root",  path_to_output_KplusPizero.c_str(), year));
        }
        else{
            treeData->Add(Form("%s/Tuples/Data/%i_KplusPi0Merged_BDTinput.root", path_to_output_KplusPizero.c_str(), year));
            treeMC->Add(Form("%s/Tuples/MC/%i_KplusPi0Merged_BDTinput.root", path_to_output_KplusPizero.c_str(),  year));
        }
    }

    // Kst2Kspiplus case
    else if(Kst2Kspiplus){
        if(ReferenceChannel){
            treeData->Add(Form("%s/Tuples/Data/%i_KshortPiplus_BDTinputRef.root",  path_to_output_KshortPiplus.c_str(), year));
            treeMC->Add(Form("%s/Tuples/MC/%i_RefKshortPiplusRef_BDTinput.root", path_to_output_KshortPiplus.c_str(), year));
        }
        else{
            if(AlwaysUseRefChannelData)
              treeData->Add(Form("%s/Tuples/Data/%i_RefKshortPiplus%s_BDTinput.root",  path_to_output_KshortPiplus.c_str(), year, (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "")));
            else
              treeData->Add(Form("%s/Tuples/Data/%i_KshortPiplus%s_BDTinput.root",  path_to_output_KshortPiplus.c_str(), year, (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "")));
            treeMC->Add(Form("%s/Tuples/MC/%i_KshortPiplus%s_BDTinput.root",  path_to_output_KshortPiplus.c_str(), year, (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "")));
        }
    }

    //initialize canvas for printing
//    TCanvas * c1 = new TCanvas("c1", "raw distributions");
    string varName = variable;
    string drawFormula;
    string drawFormTmp = "";
    if(bLogVar)             drawFormula = Form("log( %s )",  variable.c_str());
    else if(bLog1minusVar)  drawFormula = Form("log(1 - %s)",  variable.c_str());
    else                    drawFormula = variable;

    if (useTwoVars){
        if(bLogVar)             drawFormTmp = Form("log( %s )", variable2.c_str());
        else if(bLog1minusVar)  drawFormTmp = Form("log(1 - %s)",  variable2.c_str());
        else                    drawFormTmp = variable2;

        if (operation.find("max") != std::string::npos){
            varName = "max_" + variable + "_" + variable2 + "_";
            drawFormula = "max(" + drawFormula + "," + drawFormTmp + ")";
            operation = "max";
        }
        else if (operation.find("min") != std::string::npos)     {
            varName = "min_" + variable + "_" + variable2 + "_";
            drawFormula = "min(" + drawFormula + "," + drawFormTmp + ")";
            operation = "min";
        }
        else if (operation.find("abs") != std::string::npos)     {
            varName = "abs_" + variable + "_" + variable2 + "_";
            drawFormula = "abs(" + drawFormula + "-" + drawFormTmp + ")";
            operation = "abs";
        }
        else if (operation.find("plus") != std::string::npos)    {
            varName = variable + "+" + variable2;
            drawFormula = drawFormula + "+" + drawFormTmp;
            operation = "plus";
        }
        else if (operation.find("minus") != std::string::npos)   {
            varName = variable + "-" + variable2;
            drawFormula = drawFormula + "-" + drawFormTmp;
            operation = "minus";
        }
        else{
            coutERROR("Ivalid mathematical formula given: " + operation);
            return 0;
        }
    }

    std::string histName = Form("%i%s%s", year,(SplitDDandLL ? (KshortDecayInVelo ? "LL" : "DD") : ""),varName.c_str());
    cout << "[INFO]\t\tUsing name for histograms " << histName << endl;
    cout << "[INFO]\t\tUsing draw formula " << Form("%s>>%sData", drawFormula.c_str(),histName.c_str()) << endl;

    //data: initialize histograms into objects
    treeData->Draw(Form("%s>>%sData", drawFormula.c_str(),histName.c_str()), "");
    TH1 * hist0varData = (TH1*)gPad->GetPrimitive(Form("%sData",histName.c_str()));

    //MC: initialize histograms into objects
    treeMC  ->Draw(Form("%s>>%sMC", drawFormula.c_str(),histName.c_str()), "");
    TH1D * hist0varMC = (TH1D*)gPad->GetPrimitive(Form("%sMC",histName.c_str()));

    //Get min and max of x-range from both histograms:
    int nBins;
    double BinContent;
    int nBinMin, nBinMax;

    float Min;
    float Max;

    if(variable == "nTracks" || variable == "nSPDHits"){
        nBins= 60;
        Min = -0.5;
        Max = 599.5;
    }
    else if(variable == "nLongTracks" || variable == "nVeloTracks" || variable == "nTTracks" || variable == "nBackTracks"|| variable == "nMuonTracks"){
        nBins = 50;
        Min = -0.5;
        Max = 149.5;
    }
    else if(variable == "nDownstreamTracks" || variable == "nUpstreamTracks"){
        nBins = 50;
        Min = -0.5;
        Max = 49.5;
    }
    else if(variable == "nPV"){
        nBins = 8;
        Min = 0.5;
        Max = 8.5;
    }
    else {
        //get number of bins of both histograms and select larger number for new histogram
        int nBinsData = hist0varData->GetXaxis()->GetNbins();
        int nBinsMC = hist0varMC->GetXaxis()->GetNbins();

        if(nBinsData >= nBinsMC)nBins = nBinsData;
        else nBins = nBinsMC;

        //data
        nBinMin = 0;
        BinContent = 0.0;
        while(BinContent == 0.0){
            nBinMin++;
            BinContent = hist0varData->GetBinContent(nBinMin);
        }

        float MinData = hist0varData->GetXaxis()->GetBinLowEdge(nBinMin);

        nBinMax = nBinsData + 1;

        BinContent = 0.0;
        while(BinContent == 0.0){
            nBinMax--;
            BinContent = hist0varData->GetBinContent(nBinMax);
        }

        float MaxData = hist0varData->GetXaxis()->GetBinUpEdge(nBinMax);

        //MC
        nBinMin = 0;
        BinContent = 0.0;
        while(BinContent == 0.0){
            nBinMin++;
            BinContent = hist0varMC->GetBinContent(nBinMin);
        }
        float MinMC = hist0varMC->GetXaxis()->GetBinLowEdge(nBinMin);

        nBinMax = nBinsData + 1;
        BinContent = 0.0;
        while(BinContent == 0.0){
            nBinMax--;
            BinContent = hist0varMC->GetBinContent(nBinMax);
        }
        float MaxMC = hist0varMC->GetXaxis()->GetBinUpEdge(nBinMax);

        std::cout << "Found hist0varData bins: " << nBinsData << " from " << MinData << " to " << MaxData << std::endl;
        std::cout << "Found hist0varMC   bins: " << nBinsMC << " from " << MinMC << " to " << MaxMC << std::endl;

        if(MinData <= MinMC)Min = MinData;
        else Min = MinMC;

        if(MaxData >= MaxMC)Max = MaxData;
        else Max = MaxMC;

         nBins/=2;
    }

    //default axis lable is the variable name:
    std::string xaxistitle = (xAxis == "" ?  drawFormula : xAxis);


    //use MVA loader to get nicely formated variable name and units

    //manual intervention for ranges on X-axis
    if(Kst2Kspiplus){
            //B+
        if(strcmp(variable.c_str(), "B_plus_DIRA_OWNPV") == 0)Min = -20.;
        else if(strcmp(variable.c_str(), "B_plus_OWNPV_CHI2") == 0)Min = 1.;
        else if(strcmp(variable.c_str(), "B_plus_FD_OWNPV") == 0)Max = 150.;
        else if(strcmp(variable.c_str(), (UseDTF ? "B_plus_PT_DTF" : "B_plus_PT")) == 0)Max = 40000.;
        else if(strcmp(variable.c_str(), "B_plus_DOCA1") == 0)Max = 1000.;
        else if(strcmp(variable.c_str(), "B_plus_IP_OWNPV") == 0)Max = 0.12;
        else if(strcmp(variable.c_str(), "B_plus_NEW_ConePTasym") == 0)Max = 1.001;
        else if(strcmp(variable.c_str(), "B_plus_NEW_ConePT") == 0)Max = 40000.;
        else if(strcmp(variable.c_str(), "B_plus_NEW_ConePasym") == 0)Max = 1.001;
        else if(strcmp(variable.c_str(), "B_plus_NEW_ConeP") == 0)Max = 60000.;

        else if(strcmp(variable.c_str(), UseDTF ? "B_plus_ETA_DTF" :"B_plus_ETA" ) == 0)Max = 5.;
            //K*
        else if(strcmp(variable.c_str(), "K_star_plus_IPCHI2_OWNPV") == 0){
          Min = -5.;
          Max = 10.;
        }
        else if(strcmp(variable.c_str(), (UseDTF ? "K_star_plus_PT_DTF" : "K_star_plus_PT")) == 0)Max = 20000.;
        else if(strcmp(variable.c_str(), UseDTF ? "K_star_plus_ETA_DTF" :"K_star_plus_ETA" ) == 0)Max = 5.;
            //Ks0
        else if(strcmp(variable.c_str(), (UseDTF ? "K_short_PT_DTF" : "K_short_PT")) == 0)Max = 10000.;
        else if(strcmp(variable.c_str(), "K_short_FD_OWNPV") == 0 && SplitDDandLL && !KshortDecayInVelo)Max = 2500.;
        else if(strcmp(variable.c_str(), "K_short_FD_OWNPV") == 0 && SplitDDandLL && KshortDecayInVelo)Max = 700.;
            //pi+- from Ks0
        else if(strcmp(variable.c_str(), (UseDTF ? "Ks_pi_minus_PT_DTF" : "Ks_pi_minus_PT")) == 0)Max = 10000.;
        else if(strcmp(variable.c_str(), (UseDTF ? "Ks_pi_plus_PT_DTF" : "Ks_pi_plus_PT")) == 0)Max = 10000.;
            //pi+
        else if(strcmp(variable.c_str(), (UseDTF ? "pi_plus_PT_DTF" : "pi_plus_PT")) == 0)Max = 12000.;
        else if(strcmp(variable.c_str(), (UseDTF ? "pi_plus_ETA_DTF" : "pi_plus_ETA")) == 0)Max = 5.;

        else if(strcmp(variable.c_str(), "nLongTracks") == 0)Max = 110;

    }
    else{//Kplus pi0 channels
        if (Kst2Kpluspi0Merged){
                //B+
            if      (strcmp(variable.c_str(), "B_plus_DIRA_OWNPV") == 0)Min = -20.;
            else if (strcmp(variable.c_str(), "B_plus_OWNPV_CHI2") == 0)Min = 1.;
            else if (strcmp(variable.c_str(), "B_plus_FD_OWNPV") == 0)Max = 200.;
            else if (strcmp(variable.c_str(), (UseDTF ? "B_plus_PT_DTF" : "B_plus_PT")) == 0)Max = 60000.;
            else if (strcmp(variable.c_str(), "B_plus_DOCA1") == 0)Max = 1000.;
            else if (strcmp(variable.c_str(), "B_plus_IP_OWNPV") == 0)Max = 0.12;
            else if (strcmp(variable.c_str(), "B_plus_NEW_ConePTasym") == 0)Max = 1.001;
            else if(strcmp(variable.c_str(), UseDTF ? "B_plus_ETA_DTF" :"B_plus_ETA" ) == 0)Max = 5.;

                //K*
            else if (strcmp(variable.c_str(), (UseDTF ? "K_star_plus_PT_DTF" : "K_star_plus_PT_")) == 0)Max = 30000.;
            else if (strcmp(variable.c_str(), "K_star_plus_IPCHI2_OWNPV") == 0)Max = 60.;
            else if (strcmp(variable.c_str(), "K_star_plus_IPCHI2_OWNPV") == 0)Min = -10.;
            else if(strcmp(variable.c_str(), (UseDTF ? "K_star_plus_ETA_DTF" :"K_star_plus_ETA") ) == 0)Max = 5.;

                //K+
            else if (strcmp(variable.c_str(), "K_plus_IPCHI2_OWNPV") == 0)Max = 40000.;
            else if (strcmp(variable.c_str(), "K_plus_IPCHI2_OWNPV") == 0)Min = -5.;
            else if (strcmp(variable.c_str(), (UseDTF ? "K_plus_PT_DTF" : "K_plus_PT")) == 0)Max = 20000.;
            else if (strcmp(variable.c_str(), (UseDTF ? "K_plus_ETA_DTF" : "K_plus_ETA")) == 0)Max = 5.;

                //pi0
            else if (strcmp(variable.c_str(), "pi_zero_merged_ETA") == 0)Min = 1.;
            else if (strcmp(variable.c_str(), (UseDTF ? "pi_zero_merged_ETA_DTF" : "pi_zero_merged_ETA")) == 0)Max = 5.;


        }
        else if (Kst2Kpluspi0Resolved){
                //B+
            if      (strcmp(variable.c_str(), "B_plus_DIRA_OWNPV") == 0)Min = -20.;
            else if (strcmp(variable.c_str(), "B_plus_OWNPV_CHI2") == 0)Min = 1.;
            else if (strcmp(variable.c_str(), "B_plus_FD_OWNPV") == 0)Max = 200.;
            else if (!bLogVar && strcmp(variable.c_str(), (UseDTF ? "B_plus_PT_DTF" : "B_plus_PT")) == 0)Max = 60000.;
            else if (strcmp(variable.c_str(), "B_plus_DOCA1") == 0)Max = 1000.;
            else if (strcmp(variable.c_str(), "B_plus_IP_OWNPV") == 0)Max = 0.12;
            else if (strcmp(variable.c_str(), "B_plus_NEW_ConePTasym") == 0)Max = 1.001;
            else if (strcmp(variable.c_str(), (UseDTF ? "B_plus_ETA_DTF" :"B_plus_ETA" )) == 0)Max = 5.;

                //K*
            else if (strcmp(variable.c_str(), (UseDTF ? "K_star_plus_PT_DTF" : "K_star_plus_PT")) == 0)Max = 30000.;
            else if (strcmp(variable.c_str(), "K_star_plus_IPCHI2_OWNPV") == 0)Max = 60.;
            else if (strcmp(variable.c_str(), "K_star_plus_IPCHI2_OWNPV") == 0)Min = -60.;
            else if (strcmp(variable.c_str(), UseDTF ? "K_star_plus_ETA_DTF" :"K_star_plus_ETA" ) == 0)Max = 5.;

                //K+
            else if (strcmp(variable.c_str(), "K_plus_IPCHI2_OWNPV") == 0)Max = 40000.;
            else if (strcmp(variable.c_str(), "K_plus_IPCHI2_OWNPV") == 0)Min = 0.;
            else if (!bLogVar && strcmp(variable.c_str(), (UseDTF ? "K_plus_PT_DTF" : "K_plus_PT")) == 0)Max = 20000.;
            else if (strcmp(variable.c_str(), (UseDTF ? "K_plus_ETA_DTF" : "K_plus_ETA")) == 0)Max = 5.;

                //pi0
            else if (strcmp(variable.c_str(), (UseDTF ? "pi_zero_resolved_ETA_DTF" : "pi_zero_resolved_ETA")) == 0)Max = 5.;

                //gamma PT
            else if (strcmp(variable.c_str(), (UseDTF ? "gamma1_PT_DTF" : "gamma1_PT")) == 0) Max = 8.;
            else if (strcmp(variable.c_str(), (UseDTF ? "gamma2_PT_DTF" : "gamma2_PT")) == 0) Max = 8.;
                //mu
            //else if (strcmp(variable.c_str(),  "mu_minus_IPCHI2_OWNPV") == 0){ Min = 0.; Max = 20.; }
            //else if (strcmp(variable.c_str(),  "mu_plus_IPCHI2_OWNPV")  == 0){ Min = 0.; Max = 20.; }
            if (useTwoVars){
                if (operation == "abs" && variable=="pi_zero_resolved_ETA_DTF") Max = 1.5;
            }
        }
    }

    //create new histograms to fill data from tree by looping over tree
    //same number of bins and same range to be able to divide the histograms!

    hist0varData = new TH1D("hist0varData", Form("%s from data", histName.c_str()), nBins, Min, Max);
    hist0varMC   = new TH1D("hist0varMC",   Form("%s from MC",   histName.c_str()), nBins, Min, Max);

    std::cout << "Created hist0varData bins: " << nBins << " from " << Min << " to " << Max << std::endl;
    std::cout << "Created hist0varMC   bins: " << nBins << " from " << Min << " to " << Max << std::endl;

    //default type of variables is double, if variable is integer, add name to list in line 71
    double dVariable = 100., dVariable2 = 100.;
    int iVariable = 100,     iVariable2 = 100;
    double dSWeights = 1., MCWeights = 1.;
    double Q2 = 0.;
    double mu_minus_PT = 0.;
    double mu_minus_PT_MC = 0.;

    int B_plus_ID = 0;
    int B_plus_ID_MC = 0;

    double dVariable_oppCharge = 100.;
    int iVariable_oppCharge = 100;

    int TM = false;
    int TM_gammas = false;


    std::string variable_charge = variable;
    bool varIsMu = false;
    bool varIsKsPi = false;
    if (separateCharge){
        if (variable.find("mu") != std::string::npos){
            if (!replace(variable_charge, "plus","minus")){
                replace(variable_charge, "minus","plus");
                plusCharge = false;
            }
            else plusCharge = true;
            varIsMu = true;

        }
        if (variable.find("Ks_pi") != std::string::npos){
            if (!replace(variable_charge, "plus","minus")){
                replace(variable_charge, "minus","plus");
                plusCharge = false;
            }
            else plusCharge = true;
            varIsKsPi = true;
        }
        //add a string variable_charge with mu_oppCharge_XY
    }


    //deactivate all branches exept the one/two of interest!
    treeData->SetBranchStatus("*",0);
    treeData->SetBranchStatus("mu_minus_PT",1);
    treeData->SetBranchStatus(variable.c_str(),1);
    if (useTwoVars)treeData->SetBranchStatus(variable2.c_str(),1);
    if (sWeight) treeData->SetBranchStatus("N_Bplus_sw",1);
    if (separateCharge){
        treeData->SetBranchStatus("B_plus_ID",1);
    }

    treeMC->SetBranchStatus("*",0);
    treeMC->SetBranchStatus("Q2",1);
    treeMC->SetBranchStatus("mu_minus_PT",1);
    treeMC->SetBranchStatus(variable.c_str(),1);
    treeMC->SetBranchStatus("TMed",1);
    treeMC->SetBranchStatus("TM_gammas",1);

    if (useTwoVars)treeMC->SetBranchStatus(variable2.c_str(),1);
    if (separateCharge){
        treeMC->SetBranchStatus("B_plus_ID",1);
    }

    if(bWeighted)       treeMC  ->SetBranchStatus(Form("weight_%s",  weightBranch.c_str()),1);
    else if(b2Dweighted)treeMC  ->SetBranchStatus(Form("weight2D_%s",weightBranch.c_str()),1);
    
    //Data
    std::cout << "Loading " << treeData->GetEntries() << " data events!" << std::endl;
    if(varIsInt)treeData -> SetBranchAddress( variable.c_str() , &iVariable );
    else        treeData -> SetBranchAddress( variable.c_str() , &dVariable );
    if (useTwoVars){
        if(varIsInt2)treeData -> SetBranchAddress( variable2.c_str() , &iVariable2 );
        else         treeData -> SetBranchAddress( variable2.c_str() , &dVariable2 );
    }
    if (sWeight) treeData -> SetBranchAddress( "N_Bplus_sw" , &dSWeights );
    if(CutInMuPt)
      treeData -> SetBranchAddress( "mu_minus_PT" , &mu_minus_PT );
    if (separateCharge){ //TODO
        treeData -> SetBranchAddress( "B_plus_ID" , &B_plus_ID );
        if (varIsMu || varIsKsPi){ //load muplus/muminus branch too
            treeData->SetBranchStatus(variable_charge.c_str(),1);
            if(varIsInt2)   treeData->SetBranchAddress(variable_charge.c_str(), &iVariable_oppCharge);
            else            treeData->SetBranchAddress(variable_charge.c_str(), &dVariable_oppCharge);
        }
    }


    for(int i = 0; i < treeData->GetEntries(); i++){
        if(i%10000==0 && i != 0)std::cout << "Loading data event " << i << " / " << treeData->GetEntries() << std::endl;
        treeData->GetEntry(i);

        if(CutInMuPt){
          if(mu_minus_PT > maxPT || mu_minus_PT < minPT){
            continue;
          }
        }
        if (separateCharge){ //doesn't work for two variables!!!
            if (varIsMu || varIsKsPi){
                if (plusCharge && B_plus_ID == -521){
                    if(varIsInt) hist0varData->Fill( evalOperation(useTwoVars, iVariable_oppCharge,iVariable2,operation,bLogVar,bLog1minusVar), dSWeights);
                    else hist0varData->Fill( evalOperation(useTwoVars,dVariable_oppCharge,dVariable2,operation,bLogVar,bLog1minusVar), dSWeights);
                    continue;
                }
                if (!plusCharge && B_plus_ID == 521){
                    if(varIsInt) hist0varData->Fill( evalOperation(useTwoVars, iVariable_oppCharge,iVariable2,operation,bLogVar,bLog1minusVar), dSWeights);
                    else hist0varData->Fill( evalOperation(useTwoVars,dVariable_oppCharge,dVariable2,operation,bLogVar,bLog1minusVar), dSWeights);
                    continue;
                }
            }
            else {
                if (plusCharge && B_plus_ID == -521) continue;
                if (!plusCharge && B_plus_ID == 521) continue;
            }
        }

        if(varIsInt) hist0varData->Fill( evalOperation(useTwoVars, iVariable,iVariable2,operation,bLogVar,bLog1minusVar), dSWeights);
        else         hist0varData->Fill( evalOperation(useTwoVars,dVariable,dVariable2,operation,bLogVar,bLog1minusVar), dSWeights);

    }
    if (!sWeight) hist0varData->Sumw2(); //TODO: check

    if(hist0varData->GetEntries() == 0){
      std::cout << "No DATA events found" << std::endl;
      return 0;
    }
    if(hist0varData->Integral() == 0){
      std::cout << "No DATA events included in the pre-defined range!" << std::endl;
      return 0;
    }

    //MC
    std::cout << "Loading " << treeMC->GetEntries() << " MC events!" << std::endl;
    //TODO: is it smart to "re-set" branch adress to the same variable as in the data case?

    if(varIsInt)treeMC -> SetBranchAddress( variable.c_str() , &iVariable );
    else        treeMC -> SetBranchAddress( variable.c_str() , &dVariable );
    if (useTwoVars){
        if(varIsInt2)treeMC -> SetBranchAddress( variable2.c_str() , &iVariable2 );
        else         treeMC -> SetBranchAddress( variable2.c_str() , &dVariable2 );
    }

    if(bWeighted)       treeMC -> SetBranchAddress( Form("weight_%s",  weightBranch.c_str()) , &MCWeights );
    else if(b2Dweighted)treeMC -> SetBranchAddress( Form("weight2D_%s",weightBranch.c_str()) , &MCWeights );

    if(CutInQ2)
      treeMC -> SetBranchAddress( "Q2" , &Q2 );
    if(CutInMuPt)
      treeMC -> SetBranchAddress( "mu_minus_PT" , &mu_minus_PT_MC );
    if (separateCharge){
        treeMC -> SetBranchAddress( "B_plus_ID" , &B_plus_ID_MC );
        if (varIsMu || varIsKsPi){
            treeMC->SetBranchStatus(variable_charge.c_str(),1);
            if(varIsInt2)   treeMC->SetBranchAddress(variable_charge.c_str(), &iVariable_oppCharge);
            else            treeMC->SetBranchAddress(variable_charge.c_str(), &dVariable_oppCharge);
        }
    }

    treeMC->SetBranchAddress("TMed",&TM);
    treeMC->SetBranchAddress("TM_gammas",&TM_gammas);


    hist0varMC->Sumw2();
    for(int i = 0; i < treeMC->GetEntries(); i++){
        if(i%10000==0 && i != 0)std::cout << "Loading MC event " << i << " / " << treeMC->GetEntries() << std::endl;
        treeMC->GetEntry(i);
        if (!isTM("TMed",TM,false,TM_gammas)) continue;
        if(CutInQ2){
          if(Q2 > maxQ2*1.0e6 || Q2 < minQ2*1.0e6){
            continue;
          }
        }        
        if(CutInMuPt){
          if(mu_minus_PT_MC > maxPT || mu_minus_PT_MC < minPT){
            continue;
          }
        }
        if (separateCharge){ //doesn't work for two variables!!!
            if (varIsMu || varIsKsPi){
                if (plusCharge && B_plus_ID_MC == -521){ //TODO
                    if(varIsInt) hist0varMC->Fill( evalOperation(useTwoVars, iVariable_oppCharge,iVariable2,operation,bLogVar,bLog1minusVar), MCWeights);
                    else hist0varMC->Fill( evalOperation(useTwoVars,dVariable_oppCharge,dVariable2,operation,bLogVar,bLog1minusVar), MCWeights);
                    continue;
                }
                if (!plusCharge && B_plus_ID_MC == 521){ //TODO
                    if(varIsInt) hist0varMC->Fill( evalOperation(useTwoVars, iVariable_oppCharge,iVariable2,operation,bLogVar,bLog1minusVar), MCWeights);
                    else hist0varMC->Fill( evalOperation(useTwoVars,dVariable_oppCharge,dVariable2,operation,bLogVar,bLog1minusVar), MCWeights);
                    continue;
                }
            }
            else {
                if (plusCharge && B_plus_ID_MC == -521) continue;
                if (!plusCharge && B_plus_ID_MC == 521) continue;
            }
        }

        if(varIsInt) hist0varMC->Fill( evalOperation(useTwoVars, iVariable,iVariable2,operation,bLogVar,bLog1minusVar), MCWeights);
        else         hist0varMC->Fill( evalOperation(useTwoVars,dVariable,dVariable2,operation,bLogVar,bLog1minusVar), MCWeights);
    }
    if (!bWeighted && !b2Dweighted) hist0varMC->Sumw2();

    if(hist0varMC->GetEntries() == 0){
      std::cout << "No MC events found" << std::endl;
      return 0;
    }
    if(hist0varMC->Integral() == 0){
      std::cout << "No MC events included in the pre-defined range!" << std::endl;
      return 0;
    }

    std::cout << "Loaded all events: Data and MC" << std::endl;
    std::cout << "DATA: " << hist0varData->GetEntries() << " events with weights in range: " << hist0varData->Integral() << std::endl;
    std::cout << "MC  : " << hist0varMC->GetEntries() << " events with weights in range: " << hist0varMC->Integral() << std::endl;

    //make ratio:
    TH1D * hist0varDataClone = (TH1D*) hist0varData->Clone("hist0varDataClone");
    TH1D * hist0varMCclone = (TH1D*) hist0varMC->Clone("hist0varMCclone");
    TH1D * hist0ratio = (TH1D*) hist0varMC->Clone("hist0ratio");

    hist0varDataClone->SetTitle(Form("%i%s%s: data for %s [norm]",  year, TheDecay.c_str(), (SplitDDandLL && Kst2Kspiplus ? (KshortDecayInVelo ? " (LL)" : " (DD)") : ""), drawFormula.c_str()));
    hist0varMCclone  ->SetTitle(Form("%i%s%s: MC for %s [norm]",    year, TheDecay.c_str(), (SplitDDandLL && Kst2Kspiplus ? (KshortDecayInVelo ? " (LL)" : " (DD)") : ""), drawFormula.c_str()));
    hist0ratio       ->SetTitle(Form("%i%s%s: ratio MC/data for %s",year, TheDecay.c_str(), (SplitDDandLL && Kst2Kspiplus ? (KshortDecayInVelo ? " (LL)" : " (DD)") : ""), drawFormula.c_str()));


    //normalize the clones and the ratio histo
    hist0varDataClone->Scale(1 / hist0varDataClone->Integral());
    hist0ratio       ->Scale(1 / hist0ratio->Integral());
    hist0varMCclone  ->Scale(1 / hist0varMCclone->Integral());

    hist0ratio->Divide(hist0varDataClone);

    //set correct ranges for the histograms:
    double dNormalizedVariableMax = 0. , dRatioMax = 0., dNormalizedVariableMin = 100. , dRatioMin = 100.;
    for(int bin = 1; bin <= nBins; bin++){

    double dDataClone = hist0varDataClone->GetBinContent(bin);
    double dMCClone   = hist0varMCclone->GetBinContent(bin);
    double dRatio     = hist0ratio->GetBinContent(bin);

        if(dNormalizedVariableMax <= dDataClone)dNormalizedVariableMax = dDataClone;
        if(dNormalizedVariableMax <= dMCClone)  dNormalizedVariableMax = dMCClone;
        if(dRatioMax <= dRatio)                 dRatioMax = dRatio;

        if(dNormalizedVariableMin >= dDataClone)dNormalizedVariableMin = dDataClone;
        if(dNormalizedVariableMin >= dMCClone)  dNormalizedVariableMin = dMCClone;
        if(dRatioMin >= dRatio)                 dRatioMin = dRatio;

    }

    dNormalizedVariableMax *= 1.1;
    if(dNormalizedVariableMin < 0)dNormalizedVariableMin *= 1.1;
    else dNormalizedVariableMin = 0.001; //if minimum is positve, set minimum to just above 0 to remove label
    if(dRatioMax > 3.)dRatioMax = 3.;
    if(dRatioMax < 2.)dRatioMax = 2.;
    dRatioMax *= 1.1;

    std::cout << "[INFO]\t\tAll histograms and ratios created. Proceed with plotting to .eps and .root files!" << std::endl;

    //configurables for plotting
    float lowerPlotHeight = 0.6;

    //create two pads into one canvas
    TCanvas* c2= new TCanvas("c2", "ratio and superposition");
    float textsize = gStyle->GetTextSize();
    TPad *pad1 = new TPad("pad1", "ratio",0.0,lowerPlotHeight,1.0,1.0,0);
    TPad *pad2 = new TPad("pad2", "superposition",0.0,0.0,1.0,lowerPlotHeight,0);
    pad1->Draw();
    pad2->Draw();

    //modifiy pad for main plot
    pad1->Clear();
    pad1->SetBorderSize  (0);
    pad1->SetBottomMargin(1e-6);
    pad1->SetTopMargin(pad1->GetTopMargin() / ( 1 - lowerPlotHeight) );
    pad1->cd();

    //some axis-modifications on the main plot
    TGaxis::SetExponentOffset(1e+9,1e+9,"y");//offset = pad size * 1e+7
    hist0ratio->GetXaxis()->SetNoExponent(); //<-- spoils MaxDigits settings, so don't use it on other axis
    hist0ratio->GetXaxis()->SetLabelSize(0.0);//don't print labels
    hist0ratio->GetXaxis()->SetRangeUser(Min, Max);
    hist0ratio->GetXaxis()->SetTickLength(hist0ratio->GetXaxis()->GetTickLength()/(1-lowerPlotHeight));
    hist0ratio->GetXaxis()->SetNdivisions(gStyle->GetNdivisions("X"));

    hist0ratio->GetYaxis()->SetTitle("ratio MC/data");
    hist0ratio->GetYaxis()->SetTitleSize(textsize/(1-lowerPlotHeight));
    hist0ratio->GetYaxis()->SetLabelSize(textsize/(1-lowerPlotHeight));
    hist0ratio->GetYaxis()->SetTickLength(hist0ratio->GetYaxis()->GetTickLength());
    hist0ratio->GetYaxis()->SetNdivisions(gStyle->GetNdivisions("Y"));
    hist0ratio->GetYaxis()->SetTitleOffset(1.06*(1-lowerPlotHeight));
    hist0ratio->GetYaxis()->SetRangeUser(0.001, 3);
    hist0ratio->Draw("E1");

    TLine * unityline = new TLine(Min, 1, Max, 1);
    unityline->SetLineStyle(2);
    unityline->SetLineColor(4);
    unityline->Draw("SAME");

    pad2->Clear();
    pad2->SetBorderSize  (0);
    pad2->SetTopMargin   (1e-6);
    pad2->SetBottomMargin(pad2->GetBottomMargin() / lowerPlotHeight );
    pad2->cd();

    TGaxis::SetExponentOffset(1e+9,1e+9,"x");//offset = pad size * 1e+7
    hist0varDataClone->GetXaxis()->SetTitleOffset(1.05);
    hist0varDataClone->GetXaxis()->SetTitleSize  (textsize/lowerPlotHeight);
    hist0varDataClone->GetXaxis()->SetLabelSize  (textsize/lowerPlotHeight);
    hist0varDataClone->GetXaxis()->SetTickLength (hist0ratio->GetXaxis()->GetTickLength()/(lowerPlotHeight/(1-lowerPlotHeight)));
    hist0varDataClone->GetXaxis()->SetNdivisions (gStyle->GetNdivisions("X"));
    hist0varDataClone->GetXaxis()->SetTitle(xaxistitle.c_str());
    hist0varDataClone->GetXaxis()->SetRangeUser(Min, Max);


    hist0varDataClone->GetYaxis()->SetRangeUser(dNormalizedVariableMin, dNormalizedVariableMax);
    hist0varDataClone->GetYaxis()->SetTitle("weighted events");
    hist0varDataClone->GetYaxis()->SetLabelSize  (textsize/lowerPlotHeight);
    hist0varDataClone->GetYaxis()->SetTitleSize  (textsize/lowerPlotHeight);
    hist0varDataClone->GetYaxis()->SetTickLength(hist0ratio->GetYaxis()->GetTickLength());
    hist0varDataClone->GetYaxis()->SetNdivisions (gStyle->GetNdivisions("Y"));
    hist0varDataClone->GetYaxis()->SetTitleOffset(1.06*lowerPlotHeight);
    hist0varDataClone->Draw("E1");

    hist0varMCclone->SetLineColor(2);
    hist0varMCclone->SetMarkerColor(2);
    //hist0varMCclone->GetYaxis()->SetTitle("weighted events");
    hist0varMCclone->Draw("E1SAME");

    //Legend and position...
    float LegendXposition = 0.4;
    float LegendYposition = 0.62;

         if(strcmp(variable.c_str(), "pi_plus_ETA") == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), "B_plus_OWNPV_CHI2") == 0)LegendXposition = 0.2;
    else if(strcmp(variable.c_str(), "K_short_IPCHI2_OWNPV") == 0)LegendXposition = 0.2;
    else if(strcmp(variable.c_str(), "K_star_plus_IPCHI2_OWNPV") == 0)LegendXposition = 0.2;
    else if(strcmp(variable.c_str(), "mu_minus_IPCHI2_OWNPV") == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), "mu_plus_IPCHI2_OWNPV") == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), "pi_plus_IPCHI2_OWNPV") == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), "K_short_DIRA_OWNPV") == 0)LegendXposition = 0.2;
    else if(strcmp(variable.c_str(), "K_short_FD_OWNPV") == 0 && SplitDDandLL && !KshortDecayInVelo)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), (UseDTF ? "B_plus_ETA_DTF" :"B_plus_ETA" )) == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), (UseDTF ? "K_plus_ETA_DTF" :"K_plus_ETA")) == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), (UseDTF ? "K_star_plus_ETA_DTF" :"K_star_plus_ETA")) == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(),  (UseDTF ? "pi_zero_resolved_ETA_DTF" : "pi_zero_resolved_ETA")) == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(),  (UseDTF ? "pi_zero_merged_ETA_DTF" : "pi_zero_merged_ETA")) == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), "B_plus_NEW_ConePTasym") == 0)LegendXposition = 0.2;
    else if(strcmp(variable.c_str(), (UseDTF ? "gamma2_PT_DTF" : "gamma2_PT")) == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), (UseDTF ? "gamma1_PT_DTF" : "gamma1_PT")) == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), "gamma2_CL") == 0)LegendXposition = 0.2;
    else if(strcmp(variable.c_str(), "gamma1_CL") == 0)LegendXposition = 0.2;
    else if(strcmp(variable.c_str(), "K_plus_TRACK_CHI2NDOF") == 0)LegendXposition = 0.62;

    if(strcmp(variable.c_str(), "B_plus_DIRA_OWNPV") == 0)LegendXposition = 0.2;
    else if(strcmp(variable.c_str(), "B_plus_IPCHI2_OWNPV") == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), "K_star_plus_IPCHI2_OWNPV") == 0)LegendXposition = 0.2;
    else if(strcmp(variable.c_str(), "mu_minus_IPCHI2_OWNPV") == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), "mu_plus_IPCHI2_OWNPV") == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), (UseDTF ? "B_plus_ETA_DTF" :"B_plus_ETA" )) == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), (UseDTF ? "K_plus_ETA_DTF" :"K_plus_ETA")) == 0)LegendXposition = 0.52;
    else if(strcmp(variable.c_str(), (UseDTF ? "K_star_plus_ETA_DTF" :"K_star_plus_ETA")) == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), "B_plus_NEW_ConePTasym") == 0)LegendXposition = 0.2;

    if (variable.find("gamma1_PT") != std::string::npos){
        LegendXposition = 0.45;
        LegendYposition = 0.3;
    }
    else if (variable.find("mu_minus_IPCHI2_OWNPV") != std::string::npos){
        LegendXposition = 0.45;
        LegendYposition = 0.3;
    } else if (variable.find("_CL") != std::string::npos){
        LegendXposition = 0.3;
    }
    else if (variable.find("K_plus_PT") != std::string::npos){
        LegendXposition = 0.62;
    }
    else if (variable.find("B_plus_PT") != std::string::npos){
        LegendXposition = 0.62;
    }
    else if (variable.find("nLongTracks") != std::string::npos){
        LegendXposition = 0.62;
    }

    if(print_legend){
      TLegend * leg = new TLegend(LegendXposition,LegendYposition,LegendXposition + 0.25, LegendYposition + 0.18);
/*
      if(bLogVar)             leg->SetHeader(Form("Log( %s )", variable.c_str()));
      else if(bLog1minusVar)  leg->SetHeader(Form("Log( 1 - %s )", variable.c_str()));
     else                    leg->SetHeader(variable.c_str());
*/ 

      leg->AddEntry(hist0varDataClone,sWeight?"sWeighted data":"data", "lpe");
      if(b2Dweighted)   leg->AddEntry(hist0varMCclone,"2 x 1D reweighted MC", "lpe");
      else if(bWeighted)leg->AddEntry(hist0varMCclone,"reweighted MC", "lpe");
      else              leg->AddEntry(hist0varMCclone,"non-weighted MC", "lpe");
      leg->SetTextSize(0.04/lowerPlotHeight); // works fine
      leg->Draw("same");

      addLHCbtag(LegendXposition, LegendYposition + 0.27, "", 1, 1/lowerPlotHeight);

    }

    //Further plots, if needed!
    TCanvas * c3;
    TCanvas * c4;

    if (!minimumPlot){
        c3 = new TCanvas("c3", "ratio");
        c3->Clear();
        c3->cd();
        hist0ratio->GetYaxis()->SetRangeUser(0, dRatioMax);
        hist0ratio->GetYaxis()->SetTitle("ratio MC/data [norm.]");
        hist0ratio->Draw("E1");
        unityline->Draw("SAME");

        c4 = new TCanvas("c4", "overlay");
        c4->Clear();
        c4->cd();
        hist0varDataClone->GetYaxis()->SetRangeUser(0, dNormalizedVariableMax);
        hist0varDataClone->GetYaxis()->SetTitle("Weighted Decays / bin [norm.]");
        hist0varDataClone->Draw("E1");
        hist0varMCclone->SetLineColor(2);
        hist0varMCclone->SetMarkerColor(2);
        hist0varMCclone->GetYaxis()->SetTitle("Weighted Decays / bin [norm.]");
        hist0varMCclone->Draw("E1SAME");
    }

    std::string WeightingOptions = "";
    if(b2Dweighted)WeightingOptions.append("_2D_weighted");
    if(bWeighted)WeightingOptions.append("_weighted");
    if(ReferenceChannel)WeightingOptions.append("_Ref");
    if(!sWeight)WeightingOptions.append("_nosWeight");
    if (CutInQ2)WeightingOptions.append("_cutQ2"+to_string(minQ2)+"_"+to_string(maxQ2));
    if (CutInMuPt)WeightingOptions.append("_cutPT"+to_string(minPT)+"_"+to_string(maxPT));
    if (separateCharge){
        WeightingOptions.append("_actualCharge");
        if (plusCharge) WeightingOptions.append("Plus");
        else WeightingOptions.append("Minus");
    }


    if(bPrint){
        if (Kst2Kpluspi0Merged || Kst2Kpluspi0Resolved){
            c2->Print(Form("%s/ComparePlots/%i_%s_%s_MC_data%s_%s.eps", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), varName.c_str(), WeightingOptions.c_str(),weightBranch.c_str()));
            //c2->Print(Form("%s/ComparePlots/%i_%s_%s_MC_data%s.jpg", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), varName.c_str(), WeightingOptions.c_str()));
            //c2->SaveAs(Form("%s/ComparePlots/%i_%s_%s_MC_data%s.root", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), varName.c_str(), WeightingOptions.c_str()));
            if (!minimumPlot){
                c3->Print(Form("%s/ComparePlots/%i_%s_%s_MC_data_ratio%s_%s.eps", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), varName.c_str(), WeightingOptions.c_str(),weightBranch.c_str()));
                //c3->Print(Form("%s/ComparePlots/%i_%s_%s_MC_data_ratio%s.jpg", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), varName.c_str(), WeightingOptions.c_str()));
                //c3->SaveAs(Form("%s/ComparePlots/%i_%s_%s_MC_data_ratio%s.root", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), varName.c_str(), WeightingOptions.c_str()));
                c4->Print(Form("%s/ComparePlots/%i_%s_%s_MC_data_overlay%s_%s.eps", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), varName.c_str(), WeightingOptions.c_str(),weightBranch.c_str()));
                //c4->Print(Form("%s/ComparePlots/%i_%s_%s_MC_data_overlay%s.jpg", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), varName.c_str(), WeightingOptions.c_str()));
                //c4->SaveAs(Form("%s/ComparePlots/%i_%s_%s_MC_data_overlay%s.root", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), varName.c_str(), WeightingOptions.c_str()));
            }
        }
        if (Kst2Kspiplus){
            c2->Print(Form("%s/ComparePlots/%i_%s%s_%s_MC_data%s_%s.eps", path_to_output_KshortPiplus.c_str(), year, TheDecay.c_str(), (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), varName.c_str(), WeightingOptions.c_str(),weightBranch.c_str()));
            //c2->SaveAs(Form("%s/ComparePlots/%i_%s%s_%s_MC_data%s.root", path_to_output_KshortPiplus.c_str(), year, TheDecay.c_str(), (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), varName.c_str(), WeightingOptions.c_str()));
            if (!minimumPlot){
                c3->Print(Form("%s/ComparePlots/%i_%s%s_%s_MC_data_ratio%s_%s.eps", path_to_output_KshortPiplus.c_str(), year, TheDecay.c_str(), (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), varName.c_str(), WeightingOptions.c_str(),weightBranch.c_str()));
                 //c3->SaveAs(Form("%s/ComparePlots/%i_%s%s_%s_MC_data_ratio%s.root", path_to_output_KshortPiplus.c_str(), year, (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), TheDecay.c_str(), varName.c_str(), WeightingOptions.c_str()));
                c4->Print(Form("%s/ComparePlots/%i_%s%s_%s_MC_data_overlay%s_%s.eps", path_to_output_KshortPiplus.c_str(), year, (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), TheDecay.c_str(), varName.c_str(), WeightingOptions.c_str(),weightBranch.c_str()));
                 //c4->SaveAs(Form("%s/ComparePlots/%i_%s%s_%s_MC_data_overlay%s.root", path_to_output_KshortPiplus.c_str(), year, (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), TheDecay.c_str(), varName.c_str(), WeightingOptions.c_str()));
            }
        }
    }

    c2->Close();
    if (!minimumPlot){
        c3->Close();
        c4->Close();
    }

    delete c2;
    if (!minimumPlot){
        delete c3;
        delete c4;
    }

    delete hist0ratio;
    delete hist0varData;
    delete hist0varDataClone;
    delete hist0varMC;
    delete hist0varMCclone;

    delete treeData;
    delete treeMC;

    std::cout << "[INFO]\t\tAll done with variable: " << varName << std::endl;

    return 1;

}


int compareVariablesKplusKshort(int year = 2011, std::string variable = "B_plus_PT", bool sWeightKplus = false,bool sWeightKshort = true, bool bWeighted = true, bool b2Dweighted = true,
                                  bool bLogVar = false, bool bLog1minusVar = false, bool bPrint = true, bool KshortDecayInVelo = true, std::string weightBranch = firstMCweight ) {


    //if 2D weighted, set boolean for 1D weighting false
    if(b2Dweighted)bWeighted = false;

    gStyle -> SetOptStat(0);
    gROOT->SetBatch(kTRUE);
    LHCbStyle();
    //lhcbStyle->SetOptTitle(1);
    //lhcbStyle->SetTitleSize(0.1,"x");
    //lhcbStyle->SetTitleSize(0.1,"y");
    //lhcbStyle->SetTitleSize(0.1,"z");

    ///by default all variables are assumed to be doubles. If variable is an integer, add to the following list:
    bool varIsInt = false;
    if(variable == "nTracks")           varIsInt = true;
    if(variable == "nSPDHits")          varIsInt = true;
    if(variable == "nLongTracks")       varIsInt = true;
    if(variable == "nVeloTracks")       varIsInt = true;
    if(variable == "nTTracks")          varIsInt = true;
    if(variable == "nDownstreamTracks") varIsInt = true;
    if(variable == "nUpstreamTracks")   varIsInt = true;

    ///for now hardcoded, but might be possible to include in input parameters if comparison between data and reference MC is needed
    const bool ReferenceChannel = false;

    ///for writting only the ratio and superposition
    const bool minimumPlot = true;

    if(bLogVar && bLog1minusVar){
        coutERROR("Only Log( var ) or Log( 1 - var ) option possible, but both flags were set for variable: " + variable);
        return 0;
    }

    //put both magnet polarities into one TChain
    TChain * treeDataKplus = new TChain("DecayTree");
    TChain * treeMCKplus   = new TChain("DecayTreeTruthMatched");
    TChain * treeDataKshort = new TChain("DecayTree");
    TChain * treeMCKshort   = new TChain("DecayTreeTruthMatched");


    // Kst2Kpluspi0Resolved c
    if(ReferenceChannel){
        treeDataKplus->Add(Form("%s/data/%i_KplusPi0Resolved_BDTinputRef.root", path_to_output_KplusPizero.c_str(), year));
        treeMCKplus->Add(Form("%s/data/MC/%i_RefKplusPi0Resolved_BDTinput.root",  path_to_output_KplusPizero.c_str(), year));
    }
    else{
        treeDataKplus->Add(Form("%s/data/%i_KplusPi0Resolved_BDTinput.root", path_to_output_KplusPizero.c_str(), year));
        treeMCKplus->Add(Form("%s/data/MC/%i_KplusPi0Resolved_BDTinput.root", path_to_output_KplusPizero.c_str(),  year));
    }


    // Kst2Kspiplus
    if(ReferenceChannel){
        treeDataKshort->Add(Form("%s/data/%i_KshortPiplus_BDTinputRef.root",  path_to_output_KshortPiplus.c_str(), year));
        treeMCKshort->Add(Form("%s/data/MC/%i_RefKshortPiplusRef_BDTinput.root", path_to_output_KshortPiplus.c_str(), year));
    }
    else{
        treeDataKshort->Add(Form("%s/data/%i_KshortPiplus%s_BDTinput.root",  path_to_output_KshortPiplus.c_str(), year, (KshortDecayInVelo ? "_LL" : "_DD" )));
        treeMCKshort->Add(Form("%s/data/MC/%i_KshortPiplus%s_BDTinput.root",  path_to_output_KshortPiplus.c_str(), year, (KshortDecayInVelo ? "_LL" : "_DD")));
    }


    std::string histNameKplus = Form("%i%s%s", year,"",variable.c_str());
    std::string histNameKshort = Form("%i%s%s", year,((KshortDecayInVelo ? "LL" : "DD")),variable.c_str());

    //DataKplus: create histograms from trees
    if(bLogVar)             treeDataKplus->Draw(Form("TMath::Log( %s )>>%sDataKplus",  variable.c_str(),histNameKplus.c_str()), "");
    else if(bLog1minusVar)  treeDataKplus->Draw(Form("TMath::Log(1 - %s)>>%sDataKplus",variable.c_str(),histNameKplus.c_str()), "");
    else                    treeDataKplus->Draw(Form("%s>>%sDataKplus",                variable.c_str(),histNameKplus.c_str()), "");
    TH1 * hist0varDataKplus =  (TH1*)gDirectory->Get(Form("%sDataKplus", histNameKplus.c_str()));
    //DataKshort: initialize histograms into objects
    if(bLogVar)             treeDataKshort->Draw(Form("TMath::Log( %s )>>%sDataKshort",  variable.c_str(),histNameKshort.c_str()), "");
    else if(bLog1minusVar)  treeDataKshort->Draw(Form("TMath::Log(1 - %s)>>%sDataKshort",variable.c_str(),histNameKshort.c_str()), "");
    else                    treeDataKshort->Draw(Form("%s>>%sDataKshort",                variable.c_str(),histNameKshort.c_str()), "");
    TH1 * hist0varDataKshort = (TH1*)gDirectory->Get(Form("%sDataKshort",histNameKshort.c_str()));


    //MCKplus: create histograms from trees
    if(bLogVar)             treeMCKshort  ->Draw(Form("TMath::Log( %s )>>%sMCKplus",   variable.c_str(),histNameKshort.c_str()), "");
    else if(bLog1minusVar)  treeMCKshort  ->Draw(Form("TMath::Log(1 - %s)>>%sMCKplus", variable.c_str(),histNameKshort.c_str()), "");
    else                    treeMCKshort  ->Draw(Form("%s>>%sMCKplus",                 variable.c_str(),histNameKshort.c_str()), "");

    TH1D * hist0varMCKplus = (TH1D*)gDirectory->Get(Form("%sMCKplus",histNameKshort.c_str()));

    //MCKshort: create histograms from trees
    if(bLogVar)             treeMCKshort  ->Draw(Form("TMath::Log( %s )>>%sMCKshort",   variable.c_str(),histNameKshort.c_str()), "");
    else if(bLog1minusVar)  treeMCKshort  ->Draw(Form("TMath::Log(1 - %s)>>%sMCKshort", variable.c_str(),histNameKshort.c_str()), "");
    else                    treeMCKshort  ->Draw(Form("%s>>%sMCKshort",                 variable.c_str(),histNameKshort.c_str()), "");

    TH1D * hist0varMCKshort = (TH1D*)gDirectory->Get(Form("%sMCKshort",histNameKshort.c_str()));



    //Get min and max of x-range from both histograms:
    int nBinsData, nBinsMC;
    double BinContentData, BinContentMC;
    int nBinMinData, nBinMaxData;
    int nBinMinMC, nBinMaxMC;

    float MinData, MaxData;
    float MinMC, MaxMC;

    if(variable == "nTracks" || variable == "nSPDHits"){
        nBinsData = 60;
        nBinsMC = 60;
        MinData = -0.5;
        MinMC = -0.5;
        MaxData = 599.5;
        MaxMC = 599.5;
    }
    else if(variable == "nLongTracks" || variable == "nVeloTracks" || variable == "nTTracks" || variable == "nBackTracks"|| variable == "nMuonTracks"){
        nBinsData = 50;
        nBinsMC = 50;
        MinData = -0.5;
        MinMC = -0.5;
        MaxData = 149.5;
        MaxMC = 149.5;
    }
    else if(variable == "nDownstreamTracks" || variable == "nUpstreamTracks"){
        nBinsData = 50;
        nBinsMC = 50;
        MinData = -0.5;
        MinMC = -0.5;
        MaxData = 49.5;
        MaxMC = 49.5;
    }
    else {
        //get number of bins of both histograms and select larger number for new histogram
        int nBinsDataKplus =  hist0varDataKplus   ->GetXaxis()->GetNbins();
        int nBinsDataKshort = hist0varDataKshort  ->GetXaxis()->GetNbins();
        int nBinsMCKplus =    hist0varMCKplus     ->GetXaxis()->GetNbins();
        int nBinsMCKshort =   hist0varMCKshort    ->GetXaxis()->GetNbins();

        if(nBinsDataKplus >= nBinsDataKshort) nBinsData = nBinsDataKplus;
        else nBinsData = nBinsDataKshort;

        if(nBinsMCKplus >= nBinsMCKshort) nBinsMC = nBinsMCKplus;
        else nBinsMC = nBinsMCKshort;

        //DATA

        //Kplus
        nBinMinData = 0;
        BinContentData = 0;
        while(BinContentData == 0){
            nBinMinData++;
            BinContentData = hist0varDataKplus->GetBinContent(nBinMinData);
        }
        float MinDataKplus = hist0varDataKplus->GetXaxis()->GetBinLowEdge(nBinMinData);

        nBinMaxData = nBinsData + 1;
        BinContentData = 0;
        while(BinContentData == 0){
            nBinMaxData--;
            BinContentData = hist0varDataKplus->GetBinContent(nBinMaxData);
        }
        float MaxDataKplus = hist0varDataKplus->GetXaxis()->GetBinUpEdge(nBinMaxData);
        //Kshort
        nBinMinData = 0;
        BinContentData = 0;
        while(BinContentData == 0){
            nBinMinData++;
            BinContentData = hist0varDataKshort->GetBinContent(nBinMinData);
        }
        float MinDataKshort = hist0varDataKshort->GetXaxis()->GetBinLowEdge(nBinMinData);

        nBinMaxData = nBinsData + 1;
        BinContentData = 0;
        while(BinContentData == 0){
            nBinMaxData--;
            BinContentData = hist0varDataKshort->GetBinContent(nBinMaxData);
        }
        float MaxDataKshort = hist0varDataKshort->GetXaxis()->GetBinUpEdge(nBinMaxData);

        //MC

        //Kplus
        nBinMinMC = 0;
        BinContentMC = 0;
        while(BinContentMC == 0){
            nBinMinMC++;
            BinContentMC = hist0varMCKplus->GetBinContent(nBinMinMC);
        }
        float MinMCKplus = hist0varMCKplus->GetXaxis()->GetBinLowEdge(nBinMinMC);

        nBinMaxMC = nBinsMC + 1;
        BinContentMC = 0;
        while(BinContentMC == 0){
            nBinMaxMC--;
            BinContentMC = hist0varMCKplus->GetBinContent(nBinMaxMC);
        }
        float MaxMCKplus = hist0varMCKplus->GetXaxis()->GetBinUpEdge(nBinMaxMC);

        //Kshort
        nBinMinMC = 0;
        BinContentMC = 0;
        while(BinContentMC == 0){
            nBinMinMC++;
            BinContentMC = hist0varMCKshort->GetBinContent(nBinMinMC);
        }
        float MinMCKshort = hist0varMCKshort->GetXaxis()->GetBinLowEdge(nBinMinMC);

        nBinMaxMC = nBinsMC + 1;
        BinContentMC = 0;
        while(BinContentMC == 0){
            nBinMaxMC--;
            BinContentMC = hist0varMCKshort->GetBinContent(nBinMaxMC);
        }
        float MaxMCKshort = hist0varMCKshort->GetXaxis()->GetBinUpEdge(nBinMaxMC);


        std::cout << "Found hist0varDataKplus  bins: " << nBinsData << " from " << MinDataKplus  << " to " << MaxDataKplus  << std::endl;
        std::cout << "Found hist0varDataKshort bins: " << nBinsData << " from " << MinDataKshort << " to " << MaxDataKshort << std::endl;
        std::cout << "Found hist0varMCKplus    bins: " << nBinsMC   << " from " << MinMCKplus    << " to " << MaxMCKplus    << std::endl;
        std::cout << "Found hist0varMCKshort   bins: " << nBinsMC   << " from " << MinMCKshort   << " to " << MaxMCKshort   << std::endl;

        if(MinDataKplus <= MinDataKshort)MinData = MinDataKplus ;
        else MinData = MinDataKshort;

        if(MaxDataKplus  >= MaxDataKshort)MaxData = MaxDataKplus ;
        else MaxData = MaxDataKshort;

        if(MinMCKplus  <= MinMCKshort)MinMC = MinMCKplus ;
        else MinMC = MinMCKshort;

        if(MaxMCKplus >= MaxMCKshort)MaxMC = MaxMCKplus ;
        else MaxMC = MaxMCKshort;

        nBinsData/=2;
        nBinsMC/=2;

    }

    //default axis lable is the variable name:
    std::string xaxistitle = variable;

    //Load the MVA config from the txt file
    MVA_variables vars("");


    //rename xAxis for nTracks
    if(strcmp(variable.c_str(), "nTracks") == 0){
        xaxistitle = "Track Multiplicity";
        std::cout << "[INFO]\tUsing Axis Label: " << xaxistitle << std::endl;
    }


    //use MVA loader to get nicely formated variable name and units

    //manual intervention for ranges on X-axis
    //B+
    if(strcmp(variable.c_str(), "B_plus_DIRA_OWNPV") == 0)MinData = -20.;
    else if(strcmp(variable.c_str(), "B_plus_OWNPV_CHI2") == 0)MinData  = 1.;
    else if(strcmp(variable.c_str(), "B_plus_FD_OWNPV") == 0)MaxData  = 200.;
    else if(strcmp(variable.c_str(), (UseDTF ? "B_plus_PT_DTF" : "B_plus_PT")) == 0)MaxData  = 60000.;
    else if(strcmp(variable.c_str(), "B_plus_DOCA1") == 0)MaxData  = 1000.;
    else if(strcmp(variable.c_str(), "B_plus_IP_OWNPV") == 0)MaxData  = 0.12;
    else if(strcmp(variable.c_str(), "B_plus_NEW_ConePTasym") == 0)MaxData  = 1.;
    else if(strcmp(variable.c_str(), UseDTF ? "B_plus_ETA_DTF" :"B_plus_ETA" ) == 0)MaxData  = 5.;
    //K*
    else if(strcmp(variable.c_str(), "K_star_plus_IPCHI2_OWNPV") == 0)MinData  = -7.;
    else if(strcmp(variable.c_str(), "K_star_plus_IPCHI2_OWNPV") == 0)MaxData  = 60.;
    else if(strcmp(variable.c_str(), (UseDTF ? "K_star_plus_PT_DTF" : "K_star_plus_PT")) == 0)MaxData  = 20000.;
    else if(strcmp(variable.c_str(), UseDTF ? "K_star_plus_ETA_DTF" :"K_star_plus_ETA" ) == 0)MaxData  = 5.;


    //B+
    if      (strcmp(variable.c_str(), "B_plus_DIRA_OWNPV") == 0)MinMC = -20.;
    else if (strcmp(variable.c_str(), "B_plus_OWNPV_CHI2") == 0)MinMC = 1.;
    else if (strcmp(variable.c_str(), "B_plus_FD_OWNPV") == 0)MaxMC = 200.;
    else if (strcmp(variable.c_str(), (UseDTF ? "B_plus_PT_DTF" : "B_plus_PT")) == 0)MaxMC = 60000.;
    else if (strcmp(variable.c_str(), "B_plus_DOCA1") == 0)MaxMC = 1000.;
    else if (strcmp(variable.c_str(), "B_plus_IP_OWNPV") == 0)MaxMC = 0.12;
    else if (strcmp(variable.c_str(), "B_plus_NEW_ConePTasym") == 0)MaxMC = 1.;
    else if (strcmp(variable.c_str(), (UseDTF ? "B_plus_ETA_DTF" :"B_plus_ETA" )) == 0)MaxMC = 5.;

    //K*
    else if (strcmp(variable.c_str(), (UseDTF ? "K_star_plus_PT_DTF" : "K_star_plus_PT")) == 0)MaxMC = 30000.;
    else if (strcmp(variable.c_str(), "K_star_plus_IPCHI2_OWNPV") == 0)MaxMC = 60.;
    else if (strcmp(variable.c_str(), "K_star_plus_IPCHI2_OWNPV") == 0)MinMC = -60.;
    else if (strcmp(variable.c_str(), UseDTF ? "K_star_plus_ETA_DTF" :"K_star_plus_ETA" ) == 0)MaxMC = 5.;


    //create new histograms to fill data from tree by looping over tree
    //same number of bins and same range to be able to divide the histograms!


    hist0varDataKplus  = new TH1D("hist0varDataKplus ",Form("Kplus %s from data",  variable.c_str()), nBinsData, MinData, MaxData);
    hist0varDataKshort = new TH1D("hist0varDataKshort",Form("Kshort %s from data", variable.c_str()), nBinsData, MinData, MaxData);
    hist0varMCKplus    = new TH1D("hist0varMCKplus ",  Form("Kplus %s from MC",    variable.c_str()), nBinsMC, MinMC, MaxMC);
    hist0varMCKshort   = new TH1D("hist0varMCKshort",  Form("Kshort %s from MC",   variable.c_str()), nBinsMC, MinMC, MaxMC);

    std::cout << "Created hist0varDataKplus  bins: " << nBinsData << " from " << MinData << " to " << MaxData << std::endl;
    std::cout << "Created hist0varDataKshort bins: " << nBinsData << " from " << MinData << " to " << MaxData << std::endl;
    std::cout << "Created hist0varMCKplus    bins: " << nBinsMC   << " from " << MinMC   << " to " << MaxMC   << std::endl;
    std::cout << "Created hist0varMCKshort   bins: " << nBinsMC   << " from " << MinMC   << " to " << MaxMC   << std::endl;

    //default type of variables is double, if variable is integer, add name to list in line 71
    double dVariableKplusData;
    double dVariableKplusMC;
    int iVariableKplusData;
    int iVariableKplusMC;
    double dSWeightsKplus = 1., MCWeightsKplus = 1.;
    double dVariableKshortData;
    double dVariableKshortMC;
    int iVariableKshortData;
    int iVariableKshortMC;
    double dSWeightsKshort = 1., MCWeightsKshort = 1.;

    //deactivate all branches exept the one of intrest!
    treeDataKplus->SetBranchStatus("*",0);
    treeDataKplus->SetBranchStatus(variable.c_str(),1);
    if (sWeightKplus) treeDataKplus->SetBranchStatus("N_Bplus_sw",1);

    treeDataKshort->SetBranchStatus("*",0);
    treeDataKshort->SetBranchStatus(variable.c_str(),1);
    if (sWeightKshort) treeDataKshort->SetBranchStatus("N_Bplus_sw",1);


    treeMCKplus  ->SetBranchStatus("*",0);
    treeMCKplus  ->SetBranchStatus(variable.c_str(),1);
    if(bWeighted)       treeMCKplus  ->SetBranchStatus(Form("weight_%s",  weightBranch.c_str()),1);
    else if(b2Dweighted)treeMCKplus  ->SetBranchStatus(Form("weight2D_%s",weightBranch.c_str()),1);

    treeMCKshort  ->SetBranchStatus("*",0);
    treeMCKshort  ->SetBranchStatus(variable.c_str(),1);
    if(bWeighted)       treeMCKshort  ->SetBranchStatus(Form("weight_%s",  weightBranch.c_str()),1);
    else if(b2Dweighted)treeMCKshort  ->SetBranchStatus(Form("weight2D_%s",weightBranch.c_str()),1);

    //Data Kplus
    std::cout << "Loading " << treeDataKplus->GetEntries() << " data events!" << std::endl;
    if(varIsInt)treeDataKplus -> SetBranchAddress( variable.c_str() , &iVariableKplusData);
    else treeDataKplus-> SetBranchAddress( variable.c_str() , &dVariableKplusData );
    if (sWeightKplus) treeDataKplus -> SetBranchAddress( "N_Bplus_sw" , &dSWeightsKplus );


    for(int i = 0; i < treeDataKplus->GetEntries(); i++){
        if(i%10000==0 && i != 0)std::cout << "Loading data Kplus event " << i << " / " << treeDataKplus->GetEntries() << std::endl;
        treeDataKplus->GetEntry(i);
        if(varIsInt){
            if(bLogVar)         iVariableKplusData = TMath::Log(iVariableKplusData);
            else if(bLog1minusVar)  iVariableKplusData = TMath::Log(1-iVariableKplusData);
            hist0varDataKplus->Fill(iVariableKplusData, dSWeightsKplus);
        }
        else{
            if(bLogVar)         dVariableKplusData = TMath::Log(dVariableKplusData);
            else if(bLog1minusVar)  dVariableKplusData = TMath::Log(1-dVariableKplusData);
            hist0varDataKplus->Fill(dVariableKplusData, dSWeightsKplus);
        }
    }
    if (!sWeightKplus) hist0varDataKplus->Sumw2();

    //Data Kshort
    std::cout << "Loading " << treeDataKshort->GetEntries() << " data Kshort events!" << std::endl;
    if(varIsInt)treeDataKshort -> SetBranchAddress( variable.c_str() , &iVariableKshortData );
    else treeDataKshort-> SetBranchAddress( variable.c_str() , &dVariableKshortData );
    if (sWeightKshort) treeDataKshort -> SetBranchAddress( "N_Bplus_sw" , &dSWeightsKshort );

    for(int i = 0; i < treeDataKshort->GetEntries(); i++){
        if(i%10000==0 && i != 0)std::cout << "Loading data Kshort event " << i << " / " << treeDataKshort->GetEntries() << std::endl;
        treeDataKshort->GetEntry(i);
        if(varIsInt){
            if(bLogVar)         iVariableKshortData = TMath::Log(iVariableKshortData);
            else if(bLog1minusVar)  iVariableKshortData = TMath::Log(1-iVariableKshortData);
            hist0varDataKshort->Fill(iVariableKshortData, dSWeightsKshort);
        }
        else{
            if(bLogVar)         dVariableKshortData = TMath::Log(dVariableKshortData);
            else if(bLog1minusVar)  dVariableKshortData = TMath::Log(1-dVariableKshortData);
            hist0varDataKshort->Fill(dVariableKshortData, dSWeightsKshort);
        }
    }
    if (!sWeightKshort) hist0varDataKshort->Sumw2();


    //MC Kplus
    std::cout << "Loading " << treeMCKplus->GetEntries() << " MC Kplus events!" << std::endl;
    if(varIsInt)treeMCKplus -> SetBranchAddress( variable.c_str() , &iVariableKplusMC );
    else treeMCKplus -> SetBranchAddress( variable.c_str() , &dVariableKplusMC );
    if(bWeighted)       treeMCKplus -> SetBranchAddress( Form("weight_%s",   weightBranch.c_str()), &MCWeightsKplus );
    else if(b2Dweighted)treeMCKplus -> SetBranchAddress( Form("weight2D_%s", weightBranch.c_str()), &MCWeightsKplus );
    else hist0varMCKplus->Sumw2();

    for(int i = 0; i < treeMCKplus->GetEntries(); i++){
        if(i%10000==0 && i != 0)std::cout << "Loading MC Kplus event " << i << " / " << treeMCKplus->GetEntries() << std::endl;
        treeMCKplus->GetEntry(i);
        if(varIsInt){
            if(bLogVar)         iVariableKplusMC = TMath::Log(iVariableKplusMC);
            else if(bLog1minusVar)  iVariableKplusMC = TMath::Log(1-iVariableKplusMC);
            hist0varMCKplus->Fill(iVariableKplusMC, MCWeightsKplus);
        }
        else{
            if(bLogVar)         dVariableKplusMC = TMath::Log(dVariableKplusMC);
            else if(bLog1minusVar)  dVariableKplusMC = TMath::Log(1-dVariableKplusMC);
            hist0varMCKplus->Fill(dVariableKplusMC, MCWeightsKplus);
        }
    }

    //MC Kshort
    std::cout << "Loading " << treeMCKshort->GetEntries() << " MC Kshort events!" << std::endl;
    if(varIsInt)treeMCKshort -> SetBranchAddress( variable.c_str() , &iVariableKshortMC );
    else treeMCKshort -> SetBranchAddress( variable.c_str() , &dVariableKshortMC );
    if(bWeighted)       treeMCKplus -> SetBranchAddress( Form("weight_%s",   weightBranch.c_str()), &MCWeightsKshort );
    else if(b2Dweighted)treeMCKplus -> SetBranchAddress( Form("weight2D_%s", weightBranch.c_str()), &MCWeightsKshort );
    else hist0varMCKshort->Sumw2();

    for(int i = 0; i < treeMCKshort->GetEntries(); i++){
        if(i%10000==0 && i != 0)std::cout << "Loading MC Kshort event " << i << " / " << treeMCKshort->GetEntries() << std::endl;
        treeMCKshort->GetEntry(i);
        if(varIsInt){
            if(bLogVar)         iVariableKshortMC = TMath::Log(iVariableKshortMC);
            else if(bLog1minusVar)  iVariableKshortMC = TMath::Log(1-iVariableKshortMC);
            hist0varMCKshort->Fill(iVariableKshortMC, MCWeightsKshort);
        }
        else{
            if(bLogVar)         dVariableKshortMC = TMath::Log(dVariableKshortMC);
            else if(bLog1minusVar)  dVariableKshortMC = TMath::Log(1-dVariableKshortMC);
            hist0varMCKshort->Fill(dVariableKshortMC, MCWeightsKshort);
        }
    }

    //make ratio:
    TH1D * hist0varDataCloneKplus = (TH1D*)  hist0varDataKplus ->Clone("hist0varDataCloneKplus ");
    TH1D * hist0varDataCloneKshort = (TH1D*) hist0varDataKshort->Clone("hist0varDataCloneKshort");
    TH1D * hist0varMCcloneKplus = (TH1D*)  hist0varMCKplus ->Clone("hist0varMCcloneKplus ");
    TH1D * hist0varMCcloneKshort = (TH1D*) hist0varMCKshort->Clone("hist0varMCcloneKshort");
    TH1D * hist0ratioData = (TH1D*) hist0varDataKplus   ->Clone("hist0ratioData");
    TH1D * hist0ratioMC   = (TH1D*) hist0varMCKplus     ->Clone("hist0ratioMC");
    //Kplus
    if(bLogVar){
        hist0varDataCloneKplus ->SetTitle(Form("%i%s%s: data Kplus for Log(%s) [norm]", year, TheDecay.c_str(),  "", variable.c_str()));
        hist0varMCcloneKplus ->SetTitle(Form("%i%s%s: MC Kplus for Log(%s) [norm]", year, TheDecay.c_str(),  "", variable.c_str()));
        hist0ratioData ->SetTitle(Form("%i%s%s: ratio data Kplus/Kshort for Log(%s)", year, TheDecay.c_str(),  KshortDecayInVelo ? " (LL)" : " (DD)", variable.c_str()));
    }
    else if(bLog1minusVar){
        hist0varDataCloneKplus ->SetTitle(Form("%i%s%s: data Kplus for Log(1 - %s) [norm]", year, TheDecay.c_str(), (""), variable.c_str()));
        hist0varMCcloneKplus ->SetTitle(Form("%i%s%s: MC Kplus for Log(1 - %s) [norm]", year, TheDecay.c_str(), (""), variable.c_str()));
        hist0ratioData->SetTitle(Form("%i%s%s: ratio data Kplus/Kshort for Log(1 - %s)", year, TheDecay.c_str(), (KshortDecayInVelo ? " (LL)" : " (DD)"), variable.c_str()));
    }
    else{
        hist0varDataCloneKplus ->SetTitle(Form("%i%s%s: data Kplus for %s [norm]", year, TheDecay.c_str(), (""), variable.c_str()));
        hist0varMCcloneKplus ->SetTitle(Form("%i%s%s: MC Kplus for %s [norm]", year, TheDecay.c_str(), (""), variable.c_str()));
        hist0ratioData->SetTitle(Form("%i%s%s: ratio data Kplus/Kshort for %s", year, TheDecay.c_str(), (KshortDecayInVelo ? " (LL)" : " (DD)"), variable.c_str()));
    }

    //Kshort
    if(bLogVar){
        hist0varDataCloneKshort->SetTitle(Form("%i%s%s: data Kshort for Log(%s) [norm]", year, TheDecay.c_str(), ((KshortDecayInVelo ? " (LL)" : " (DD)") ), variable.c_str()));
        hist0varMCcloneKshort->SetTitle(Form("%i%s%s: MC Kshort for Log(%s) [norm]", year, TheDecay.c_str(), ( (KshortDecayInVelo ? " (LL)" : " (DD)")), variable.c_str()));
        hist0ratioMC->SetTitle(Form("%i%s%s: ratio MC/data for Log(%s)", year, TheDecay.c_str(), ((KshortDecayInVelo ? " (LL)" : " (DD)") ), variable.c_str()));
    }
    else if(bLog1minusVar){
        hist0varDataCloneKshort->SetTitle(Form("%i%s%s: data Kshort for Log(1 - %s) [norm]", year, TheDecay.c_str(), ( (KshortDecayInVelo ? " (LL)" : " (DD)") ), variable.c_str()));
        hist0varMCcloneKshort->SetTitle(Form("%i%s%s: MC Kshort for Log(1 - %s) [norm]", year, TheDecay.c_str(), ((KshortDecayInVelo ? " (LL)" : " (DD)") ), variable.c_str()));
        hist0ratioMC->SetTitle(Form("%i%s%s: ratio MC Kplus/Kshort for Log(1 - %s)", year, TheDecay.c_str(), ( (KshortDecayInVelo ? " (LL)" : " (DD)") ), variable.c_str()));
    }
    else{
        hist0varDataCloneKshort->SetTitle(Form("%i%s%s: data Kshort for %s [norm]", year, TheDecay.c_str(), (KshortDecayInVelo ? " (LL)" : " (DD)") , variable.c_str()));
        hist0varMCcloneKshort->SetTitle(Form("%i%s%s: MC Kshort for %s [norm]", year, TheDecay.c_str(),  (KshortDecayInVelo ? " (LL)" : " (DD)") , variable.c_str()));
        hist0ratioMC->SetTitle(Form("%i%s%s: ratio MC Kplus/Kshort for %s", year, TheDecay.c_str(), (KshortDecayInVelo ? " (LL)" : " (DD)") , variable.c_str()));
    }

    /// Sumw2 is already applied, so comment out the following 5 lines!
    //Sumw2 uncertainties of all histos
    //hist0varMC->Sumw2();
    //hist0varMCclone->Sumw2();
    //hist0varData->Sumw2();
    //hist0varDataClone->Sumw2();
    //hist0ratio->Sumw2();

    //normalize the clones and the ratio histo
    hist0varDataCloneKplus->Scale(1 / hist0varDataCloneKplus->Integral());
    hist0varDataCloneKshort->Scale(1 / hist0varDataCloneKshort->Integral());
    hist0ratioData       ->Scale(1 / hist0ratioData->Integral());

    hist0varMCcloneKplus  ->Scale(1 / hist0varMCcloneKplus->Integral());
    hist0varMCcloneKshort  ->Scale(1 / hist0varMCcloneKshort->Integral());
    hist0ratioMC       ->Scale(1 / hist0ratioMC->Integral());

    hist0ratioData->Divide(hist0varDataCloneKshort);
    hist0ratioMC->Divide(hist0varMCcloneKshort);

    //set correct ranges for the histograms:
    //Data
    double dNormalizedVariableMaxData = 0. , dRatioMaxData = 0., dNormalizedVariableMinData = 100. , dRatioMinData = 100.;
    for(int bin = 1; bin <= nBinsData; bin++){

        double dDataCloneKplus  = hist0varDataCloneKplus->GetBinContent(bin);
        double dDataCloneKshort = hist0varDataCloneKshort->GetBinContent(bin);
        double dRatioData       = hist0ratioData->GetBinContent(bin);

        if(dNormalizedVariableMaxData <= dDataCloneKplus)   dNormalizedVariableMaxData = dDataCloneKplus; //TODO (i nahore, fakt nechapu)
        if(dNormalizedVariableMaxData <= dDataCloneKshort)  dNormalizedVariableMaxData = dDataCloneKshort;
        if(dRatioMaxData <= dRatioData)                     dRatioMaxData = dRatioData;

        if(dNormalizedVariableMinData >= dDataCloneKplus)    dNormalizedVariableMinData = dDataCloneKplus;
        if(dNormalizedVariableMinData >= dDataCloneKshort)   dNormalizedVariableMinData = dDataCloneKshort;
        if(dRatioMinData >= dRatioData)                 dRatioMinData = dRatioData;

    }

    dNormalizedVariableMaxData *= 1.1;
    if(dNormalizedVariableMinData < 0)dNormalizedVariableMinData *= 1.1;
    else dNormalizedVariableMinData = 0.001; //if minimum is positve, set minimum to just above 0 to remove label
    if(dRatioMaxData > 3.)dRatioMaxData = 3.;
    if(dRatioMaxData < 2.)dRatioMaxData = 2.;
    dRatioMaxData *= 1.1;

    //set correct ranges for the histograms:
    //MC
    double dNormalizedVariableMaxMC = 0. , dRatioMaxMC = 0., dNormalizedVariableMinMC = 100. , dRatioMinMC = 100.;
    for(int bin = 1; bin <= nBinsMC; bin++){

        double dMCcloneKplus  = hist0varMCcloneKplus->GetBinContent(bin);
        double dMCcloneKshort = hist0varMCcloneKshort->GetBinContent(bin);
        double dRatioMC       = hist0ratioMC->GetBinContent(bin);

        if(dNormalizedVariableMaxMC <= dMCcloneKplus)   dNormalizedVariableMaxMC = dMCcloneKplus;
        if(dNormalizedVariableMaxMC <= dMCcloneKshort)  dNormalizedVariableMaxMC = dMCcloneKshort;
        if(dRatioMaxMC <= dRatioMC)                     dRatioMaxMC = dRatioMC;

        if(dNormalizedVariableMinMC >= dMCcloneKplus)    dNormalizedVariableMinMC = dMCcloneKplus;
        if(dNormalizedVariableMinMC >= dMCcloneKshort)   dNormalizedVariableMinMC = dMCcloneKshort;
        if(dRatioMinMC >= dRatioMC)                 dRatioMinMC = dRatioMC;

    }

    dNormalizedVariableMaxMC *= 1.1;
    if(dNormalizedVariableMinMC < 0)dNormalizedVariableMinMC *= 1.1;
    else dNormalizedVariableMinMC = 0.001; //if minimum is positve, set minimum to just above 0 to remove label
    if(dRatioMaxMC > 3.)dRatioMaxMC = 3.;
    if(dRatioMaxMC < 2.)dRatioMaxMC = 2.;
    dRatioMaxMC *= 1.1;

    //configurables for plotting
    float lowerPlotHeight = 0.6;

    /*********************************
     *********************************
     *
     *             DATA
     *
     *********************************
     *********************************/

    //create two pads into one canvas
    TCanvas* c2= new TCanvas("c2", "ratio and superposition");
    float textsize = gStyle->GetTextSize();
    TPad *pad1 = new TPad("pad1", "ratio",0.0,lowerPlotHeight,1.0,1.0,0);
    TPad *pad2 = new TPad("pad2", "superposition",0.0,0.0,1.0,lowerPlotHeight,0);
    pad1->Draw();
    pad2->Draw();

    //modifiy pad for main plot
    pad1->Clear();
    pad1->SetBorderSize  (0);
    pad1->SetBottomMargin(1e-6);
    pad1->SetTopMargin(pad1->GetTopMargin() / ( 1 - lowerPlotHeight) );
    pad1->cd();

    //some axis-modifications on the main plot
    TGaxis::SetExponentOffset(1e+9,1e+9,"y");//offset = pad size * 1e+7
    hist0ratioData->GetXaxis()->SetNoExponent(); //<-- spoils MaxDigits settings, so don't use it on other axis
    hist0ratioData->GetXaxis()->SetLabelSize(0.0);//don't print labels
    hist0ratioData->GetXaxis()->SetRangeUser(MinData, MaxData);
    hist0ratioData->GetXaxis()->SetTickLength(hist0ratioData->GetXaxis()->GetTickLength()/(1-lowerPlotHeight));
    hist0ratioData->GetXaxis()->SetNdivisions(gStyle->GetNdivisions("X"));

    hist0ratioData->GetYaxis()->SetTitle("ratio data Kplus/Kshort");
    hist0ratioData->GetYaxis()->SetTitleSize(textsize/(1-lowerPlotHeight));
    hist0ratioData->GetYaxis()->SetLabelSize(textsize/(1-lowerPlotHeight));
    hist0ratioData->GetYaxis()->SetTickLength(hist0ratioData->GetYaxis()->GetTickLength());
    hist0ratioData->GetYaxis()->SetNdivisions(gStyle->GetNdivisions("Y"));
    hist0ratioData->GetYaxis()->SetTitleOffset(1.06*(1-lowerPlotHeight));
    hist0ratioData->GetYaxis()->SetRangeUser(0.001, 3);
    hist0ratioData->Draw("E1");

    TLine * unityline = new TLine(MinData, 1, MaxData, 1);
    unityline->SetLineStyle(2);
    unityline->SetLineColor(4);
    unityline->Draw("SAME");

    pad2->Clear();
    pad2->SetBorderSize  (0);
    pad2->SetTopMargin   (1e-6);
    pad2->SetBottomMargin(pad2->GetBottomMargin() / lowerPlotHeight );
    pad2->cd();

    TGaxis::SetExponentOffset(1e+9,1e+9,"x");//offset = pad size * 1e+7
    hist0varDataCloneKplus->GetXaxis()->SetTitleOffset(1.05);
    hist0varDataCloneKplus->GetXaxis()->SetTitleSize  (textsize/lowerPlotHeight);
    hist0varDataCloneKplus->GetXaxis()->SetLabelSize  (textsize/lowerPlotHeight);
    hist0varDataCloneKplus->GetXaxis()->SetTickLength (hist0ratioData->GetXaxis()->GetTickLength()/(lowerPlotHeight/(1-lowerPlotHeight)));
    hist0varDataCloneKplus->GetXaxis()->SetNdivisions (gStyle->GetNdivisions("X"));
    hist0varDataCloneKplus->GetXaxis()->SetTitle(xaxistitle.c_str());
    hist0varDataCloneKplus->GetXaxis()->SetRangeUser(MinData, MaxData);


    hist0varDataCloneKplus->GetYaxis()->SetRangeUser(dNormalizedVariableMinData, dNormalizedVariableMaxData);
    hist0varDataCloneKplus->GetYaxis()->SetTitle("weighted events");
    hist0varDataCloneKplus->GetYaxis()->SetLabelSize  (textsize/lowerPlotHeight);
    hist0varDataCloneKplus->GetYaxis()->SetTitleSize  (textsize/lowerPlotHeight);
    hist0varDataCloneKplus->GetYaxis()->SetTickLength(hist0ratioData->GetYaxis()->GetTickLength());
    hist0varDataCloneKplus->GetYaxis()->SetNdivisions (gStyle->GetNdivisions("Y"));
    hist0varDataCloneKplus->GetYaxis()->SetTitleOffset(1.06*lowerPlotHeight);
    hist0varDataCloneKplus->Draw("E1");

    hist0varDataCloneKshort->SetLineColor(2);
    hist0varDataCloneKshort->SetMarkerColor(2);
    //hist0varMCclone->GetYaxis()->SetTitle("weighted events");
    hist0varDataCloneKshort->Draw("E1SAME");


    //Legend and position...
    float LegendXposition = 0.4;
    float LegendYposition = 0.62;

    if(strcmp(variable.c_str(), "B_plus_DIRA_OWNPV") == 0)LegendXposition = 0.2;
    else if(strcmp(variable.c_str(), "B_plus_IPCHI2_OWNPV") == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), "K_star_plus_IPCHI2_OWNPV") == 0)LegendXposition = 0.2;
    else if(strcmp(variable.c_str(), "mu_minus_IPCHI2_OWNPV") == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), "mu_plus_IPCHI2_OWNPV") == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), (UseDTF ? "B_plus_ETA_DTF" :"B_plus_ETA" )) == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), (UseDTF ? "K_plus_ETA_DTF" :"K_plus_ETA")) == 0)LegendXposition = 0.52;
    else if(strcmp(variable.c_str(), (UseDTF ? "K_star_plus_ETA_DTF" :"K_star_plus_ETA")) == 0)LegendXposition = 0.62;
    else if(strcmp(variable.c_str(), "B_plus_NEW_ConePTasym") == 0)LegendXposition = 0.2;

    if (variable.find("gamma1_PT") != std::string::npos){
        LegendXposition = 0.5;
        LegendYposition = 0.7;
    }
    else if (variable.find("mu_minus_IPCHI2_OWNPV") != std::string::npos){
        LegendXposition = 0.5;
        LegendYposition = 0.7;
    } else if (variable.find("_CL") != std::string::npos){
        LegendXposition = 0.3;
    }
    else if (variable.find("K_plus_PT") != std::string::npos){
        LegendXposition = 0.62;
    }
    else if (variable.find("B_plus_PT") != std::string::npos){
        LegendXposition = 0.62;
    }

    TLegend * leg = new TLegend(LegendXposition,LegendYposition,LegendXposition + 0.25, LegendYposition + 0.18);
/*
    if(bLogVar)             leg->SetHeader(Form("Log( %s )", variable.c_str()));
    else if(bLog1minusVar)  leg->SetHeader(Form("Log( 1 - %s )", variable.c_str()));
    else                    leg->SetHeader(variable.c_str());
*/

    leg->AddEntry(hist0varDataCloneKplus,sWeightKplus? "sWeighted Kplus  data" :" Kplus  data" , "lpe");
    leg->AddEntry(hist0varDataCloneKshort,sWeightKshort?"sWeighted Kshort  data":" Kshort  data", "lpe");
    /*
    if(b2Dweighted)   leg->AddEntry(hist0varDataCloneKshort,"2 x 1D reweighted MC", "lpe"); //TODO
    else if(bWeighted)leg->AddEntry(hist0varDataCloneKshort,"reweighted MC", "lpe");
    else              leg->AddEntry(hist0varDataCloneKshort,"non-weighted MC", "lpe");
    */
    leg->SetTextSize(0.04/lowerPlotHeight); // works fine
    leg->Draw("same");

    addLHCbtag(LegendXposition, LegendYposition + 0.27, "", 1, 1/lowerPlotHeight);

    //Further plots, if needed!

    TCanvas * c3;
    TCanvas * c4;

    if (!minimumPlot){
        c3 = new TCanvas("c3", "ratio");
        c3->Clear();
        c3->cd();
        hist0ratioData->GetYaxis()->SetRangeUser(0, dRatioMaxData);
        hist0ratioData->GetYaxis()->SetTitle("ratio MC/data [norm.]");
        hist0ratioData->Draw("E1");
        unityline->Draw("SAME");

        c4 = new TCanvas("c4", "overlay");
        c4->Clear();
        c4->cd();
        hist0varDataCloneKplus->GetYaxis()->SetRangeUser(0, dNormalizedVariableMaxData);
        hist0varDataCloneKplus->GetYaxis()->SetTitle("Weighted Decays / bin [norm.]");
        hist0varDataCloneKplus->Draw("E1");
        hist0varDataCloneKshort->SetLineColor(2);
        hist0varDataCloneKshort->SetMarkerColor(2);
        hist0varDataCloneKshort->GetYaxis()->SetTitle("Weighted Decays / bin [norm.]");
        hist0varDataCloneKshort->Draw("E1SAME");
    }

    std::string WeightingOptions = "";
    if(b2Dweighted)WeightingOptions.append("_2D_weighted");
    if(bWeighted)WeightingOptions.append("_weighted");
    if(ReferenceChannel)WeightingOptions.append("_Ref");
    if (!sWeightKshort) WeightingOptions.append("_nosWeightKshort");
    if (!sWeightKplus) WeightingOptions.append("_nosWeightKplus");
    WeightingOptions.append("_KshortComparison");

    if(bPrint){
        c2->Print(Form("%s/ComparePlots/%i_%s%s_%s_%s.eps", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), (KshortDecayInVelo ? "_LL" : "_DD"), variable.c_str(), WeightingOptions.c_str()));
        //c2->SaveAs(Form("%s/ComparePlots/%i_%s%s_%s_MC_data%s.root", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), variable.c_str(), WeightingOptions.c_str()));
        if (!minimumPlot){
            c3->Print(Form("%s/ComparePlots/%i_%s%s_%s_ratio%s.eps", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), (KshortDecayInVelo ? "_LL" : "_DD"), variable.c_str(), WeightingOptions.c_str()));
            //c3->SaveAs(Form("%s/ComparePlots/%i_%s%s_%s_MC_data_ratio%s.root", path_to_output_KplusPizero.c_str(), year, (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), TheDecay.c_str(), variable.c_str(), WeightingOptions.c_str()));
            c4->Print(Form("%s/ComparePlots/%i_%s%s_%s_overlay%s.eps", path_to_output_KplusPizero.c_str(), year, (KshortDecayInVelo ? "_LL" : "_DD"), TheDecay.c_str(), variable.c_str(), WeightingOptions.c_str()));
            //c4->SaveAs(Form("%s/ComparePlots/%i_%s%s_%s_MC_data_overlay%s.root", path_to_output_KplusPizero.c_str(), year, (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), TheDecay.c_str(), variable.c_str(), WeightingOptions.c_str()));
        }
    }

    c2->Close();
    if (!minimumPlot){
        c3->Close();
        c4->Close();
    }

    delete c2;
    if (!minimumPlot){
        delete c3;
        delete c4;
    }

    /*********************************
     *********************************
     *
     *             MC
     *
     *********************************
     *********************************/

    //create two pads into one canvas
    TCanvas* c2MC= new TCanvas("c2MC", "ratio and superposition");
    textsize = gStyle->GetTextSize();    
    c2MC->cd();
    TPad *pad1MC = new TPad("pad1MC", "ratio",0.0,lowerPlotHeight,1.0,1.0,0);
    TPad *pad2MC = new TPad("pad2MC", "superposition",0.0,0.0,1.0,lowerPlotHeight,0);
    pad1MC->Draw();
    pad2MC->Draw();

    //modifiy pad for main plot
    pad1MC->Clear();
    pad1MC->SetBorderSize  (0);
    pad1MC->SetBottomMargin(1e-6);
    pad1MC->SetTopMargin(pad1MC->GetTopMargin() / ( 1 - lowerPlotHeight) );
    pad1MC->cd();

    //some axis-modifications on the main plot
    TGaxis::SetExponentOffset(1e+9,1e+9,"y");//offset = pad size * 1e+7
    hist0ratioMC->GetXaxis()->SetNoExponent(); //<-- spoils MaxDigits settings, so don't use it on other axis
    hist0ratioMC->GetXaxis()->SetLabelSize(0.0);//don't print labels
    hist0ratioMC->GetXaxis()->SetRangeUser(MinMC, MaxMC);
    hist0ratioMC->GetXaxis()->SetTickLength(hist0ratioMC->GetXaxis()->GetTickLength()/(1-lowerPlotHeight));
    hist0ratioMC->GetXaxis()->SetNdivisions(gStyle->GetNdivisions("X"));

    hist0ratioMC->GetYaxis()->SetTitle("ratio MC Kplus/Kshort");
    hist0ratioMC->GetYaxis()->SetTitleSize(textsize/(1-lowerPlotHeight));
    hist0ratioMC->GetYaxis()->SetLabelSize(textsize/(1-lowerPlotHeight));
    hist0ratioMC->GetYaxis()->SetTickLength(hist0ratioMC->GetYaxis()->GetTickLength());
    hist0ratioMC->GetYaxis()->SetNdivisions(gStyle->GetNdivisions("Y"));
    hist0ratioMC->GetYaxis()->SetTitleOffset(1.06*(1-lowerPlotHeight));
    hist0ratioMC->GetYaxis()->SetRangeUser(0.001, 3);
    hist0ratioMC->Draw("E1");


    TLine * unitylineMC = new TLine(MinMC, 1, MaxMC, 1);
    unitylineMC->SetLineStyle(2);
    unitylineMC->SetLineColor(4);
    unitylineMC->Draw("SAME");

    pad2MC->Clear();
    pad2MC->SetBorderSize  (0);
    pad2MC->SetTopMargin   (1e-6);
    pad2MC->SetBottomMargin(pad2MC->GetBottomMargin() / lowerPlotHeight );
    pad2MC->cd();

    TGaxis::SetExponentOffset(1e+9,1e+9,"x");//offset = pad size * 1e+7
    hist0varMCcloneKplus->GetXaxis()->SetTitleOffset(1.05);
    hist0varMCcloneKplus->GetXaxis()->SetTitleSize  (textsize/lowerPlotHeight);
    hist0varMCcloneKplus->GetXaxis()->SetLabelSize  (textsize/lowerPlotHeight);
    hist0varMCcloneKplus->GetXaxis()->SetTickLength (hist0ratioMC->GetXaxis()->GetTickLength()/(lowerPlotHeight/(1-lowerPlotHeight)));
    hist0varMCcloneKplus->GetXaxis()->SetNdivisions (gStyle->GetNdivisions("X"));
    hist0varMCcloneKplus->GetXaxis()->SetTitle(xaxistitle.c_str());
    hist0varMCcloneKplus->GetXaxis()->SetRangeUser(MinMC, MaxMC);


    hist0varMCcloneKplus->GetYaxis()->SetRangeUser(dNormalizedVariableMinMC, dNormalizedVariableMaxMC);
    hist0varMCcloneKplus->GetYaxis()->SetTitle("weighted events");
    hist0varMCcloneKplus->GetYaxis()->SetLabelSize  (textsize/lowerPlotHeight);
    hist0varMCcloneKplus->GetYaxis()->SetTitleSize  (textsize/lowerPlotHeight);
    hist0varMCcloneKplus->GetYaxis()->SetTickLength(hist0ratioMC->GetYaxis()->GetTickLength());
    hist0varMCcloneKplus->GetYaxis()->SetNdivisions (gStyle->GetNdivisions("Y"));
    hist0varMCcloneKplus->GetYaxis()->SetTitleOffset(1.06*lowerPlotHeight);
    hist0varMCcloneKplus->Draw("E1");

    hist0varMCcloneKshort->SetLineColor(2);
    hist0varMCcloneKshort->SetMarkerColor(2);
    //hist0varMCclone->GetYaxis()->SetTitle("weighted events");
    hist0varMCcloneKshort->Draw("E1SAME");

    TLegend * legMC = new TLegend(LegendXposition,LegendYposition,LegendXposition + 0.25, LegendYposition + 0.18);
/*
    if(bLogVar)             legMC->SetHeader(Form("Log( %s )", variable.c_str()));
    else if(bLog1minusVar)  legMC->SetHeader(Form("Log( 1 - %s )", variable.c_str()));
    else                    legMC->SetHeader(variable.c_str());
*/

    legMC->AddEntry(hist0varMCcloneKplus, "Kplus  MC" , "lpe");
    legMC->AddEntry(hist0varMCcloneKshort,"Kshort  MC", "lpe");
    /*
    if(b2Dweighted)   legMC->AddEntry(hist0varMCcloneKshort,"2 x 1D reweighted MC", "lpe"); //TODO
    else if(bWeighted)legMC->AddEntry(hist0varMCcloneKshort,"reweighted MC", "lpe");
    else              legMC->AddEntry(hist0varMCcloneKshort,"non-weighted MC", "lpe");
    */
    legMC->SetTextSize(0.04/lowerPlotHeight); // works fine
    legMC->Draw("same");

    addLHCbtag(LegendXposition, LegendYposition + 0.27, "", 1, 1/lowerPlotHeight);

    //Further plots, if needed!

    TCanvas * c3MC;
    TCanvas * c4MC;

    if (!minimumPlot){
        c3MC = new TCanvas("c3MC", "ratio");
        c3MC->Clear();
        c3MC->cd();
        hist0ratioMC->GetYaxis()->SetRangeUser(0, dRatioMaxMC);
        hist0ratioMC->GetYaxis()->SetTitle("ratio MC Kplus/Kshort [norm.]");
        hist0ratioMC->Draw("E1");
        unitylineMC->Draw("SAME");

        c4MC = new TCanvas("c4MC", "overlay");
        c4MC->Clear();
        c4MC->cd();
        hist0varMCcloneKplus->GetYaxis()->SetRangeUser(0, dNormalizedVariableMaxMC);
        hist0varMCcloneKplus->GetYaxis()->SetTitle("Weighted Decays / bin [norm.]");
        hist0varMCcloneKplus->Draw("E1");
        hist0varMCcloneKshort->SetLineColor(2);
        hist0varMCcloneKshort->SetMarkerColor(2);
        hist0varMCcloneKshort->GetYaxis()->SetTitle("Weighted Decays / bin [norm.]");
        hist0varMCcloneKshort->Draw("E1SAME");
    }

    WeightingOptions = "";
    if(b2Dweighted)WeightingOptions.append("_2D_weighted");
    if(bWeighted)WeightingOptions.append("_weighted");
    if(ReferenceChannel)WeightingOptions.append("_Ref");
    WeightingOptions.append("_KshortComparison");

    if(bPrint){
        c2MC->Print(Form("%s/ComparePlots/%i_%s%s_%s_%s_MC.eps", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), (KshortDecayInVelo ? "_LL" : "_DD"), variable.c_str(), WeightingOptions.c_str()));
        //c2MC->SaveAs(Form("%s/ComparePlots/%i_%s%s_%s_MC_data%s.root", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), variable.c_str(), WeightingOptions.c_str()));
        if (!minimumPlot){
            c3MC->Print(Form("%s/ComparePlots/%i_%s%s_%s_ratio%s_MC.eps", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), (KshortDecayInVelo ? "_LL" : "_DD"), variable.c_str(), WeightingOptions.c_str()));
            //c3MC->SaveAs(Form("%s/ComparePlots/%i_%s%s_%s_MC_data_ratio%s.root", path_to_output_KplusPizero.c_str(), year, (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), TheDecay.c_str(), variable.c_str(), WeightingOptions.c_str()));
            c4MC->Print(Form("%s/ComparePlots/%i_%s%s_%s_overlay%s_MC.eps", path_to_output_KplusPizero.c_str(), year, (KshortDecayInVelo ? "_LL" : "_DD"), TheDecay.c_str(), variable.c_str(), WeightingOptions.c_str()));
            //c4MC->SaveAs(Form("%s/ComparePlots/%i_%s%s_%s_MC_data_overlay%s.root", path_to_output_KplusPizero.c_str(), year, (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), TheDecay.c_str(), variable.c_str(), WeightingOptions.c_str()));
        }
    }

    c2MC->Close();
    if (!minimumPlot){
        c3MC->Close();
        c4MC->Close();
    }

    delete c2MC;
    if (!minimumPlot){
        delete c3MC;
        delete c4MC;
    }


    delete hist0ratioData;
    delete hist0ratioMC;
    delete hist0varDataKplus;
    delete hist0varDataCloneKplus;
    delete hist0varDataKshort;
    delete hist0varDataCloneKshort;
    delete hist0varMCKplus;
    delete hist0varMCcloneKplus;
    delete hist0varMCKshort;
    delete hist0varMCcloneKshort;

    delete treeDataKshort;
    delete treeDataKplus;
    delete treeMCKplus;
    delete treeMCKshort;

    return 1;

}

/////////////////////////////////////////////////////
///
/// comparison of all Kshort variables:
///
/////////////////////////////////////////////////////

int compareAllKshorts(bool sWeight = true, bool bWeighted = true, bool b2DWeighted = true, int Run = 1, std::string weightBranch = firstMCweight){

    checkRun(Run);

    bool save2file = true;
    bool SplitIntoDDandLL = true;

    int nYear = (Run == 1 ? 2011 : 2015);

    while(nYear < (Run == 1 ? 2013 : 2019)){

        int iteration = 1;
        bool KshortDecayInVelo = true;

        while((SplitIntoDDandLL || iteration == 1) && iteration < 3){

            compareVariables(nYear, "nTracks",                          sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);

            compareVariables(nYear, "B_plus_DIRA_OWNPV",                sWeight, bWeighted, b2DWeighted, false, true,  save2file, KshortDecayInVelo, weightBranch);
          //compareVariables(nYear, "B_plus_OWNPV_CHI2",                sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, "B_plus_IPCHI2_OWNPV",              sWeight, bWeighted, b2DWeighted, true,  false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, "B_plus_ENDVERTEX_CHI2",            sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, "B_plus_FD_OWNPV",                  sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, "B_plus_IP_OWNPV",                  sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, UseDTF?"B_plus_PT_DTF":"B_plus_PT", sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);
          //compareVariables(nYear, "B_plus_DOCA1",                     sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, "B_plus_NEW_ConePTasym",            sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);
          //compareVariables(nYear, "B_plus_DTF_chi2",                  sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);

          //compareVariables(nYear, "K_star_plus_NEW_ConePTasym",                   sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, UseDTF?"K_star_plus_PT_DTF":"K_star_plus_PT",   sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, "K_star_plus_IPCHI2_OWNPV",                     sWeight, bWeighted, b2DWeighted, true,  false, save2file, KshortDecayInVelo, weightBranch);

            compareVariables(nYear, "mu_plus_IPCHI2_OWNPV",             sWeight, bWeighted, b2DWeighted, true,  false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, "mu_minus_IPCHI2_OWNPV",            sWeight, bWeighted, b2DWeighted, true,  false, save2file, KshortDecayInVelo, weightBranch);
          //compareVariables(nYear, "mu_plus_NEW_ConePTasym",           sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);
          //compareVariables(nYear, "mu_minus_NEW_ConePTasym",          sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);

            compareVariables(nYear, "K_short_IPCHI2_OWNPV",                 sWeight, bWeighted, b2DWeighted, true,  false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, "K_short_FD_OWNPV",                     sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, UseDTF?"K_short_PT_DTF":"K_short_PT",   sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, "K_short_DIRA_OWNPV",                   sWeight, bWeighted, b2DWeighted, false, true,  save2file, KshortDecayInVelo, weightBranch);

            compareVariables(nYear, "pi_plus_IPCHI2_OWNPV",                 sWeight, bWeighted, b2DWeighted, true,  false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, UseDTF?"pi_plus_PT_DTF":"pi_plus_PT",   sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);

          //compareVariables(nYear, "Ks_pi_plus_PT"+(UseDTF?"_DTF":""), sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);
          //compareVariables(nYear, "Ks_pi_minus_PT"+(UseDTF?"_DTF":""),sWeight, bWeighted, b2DWeighted, false, false, save2file, KshortDecayInVelo, weightBranch);

            KshortDecayInVelo = false;
            iteration++;

        }

        nYear++;

    }

    return 1;

}

int compareAllKshortsWeightedAndUnweighted(){

    //not weighted
    compareAllKshorts(false, false);

    //1D weighted
    compareAllKshorts(true, false);

    //2D weighted
    compareAllKshorts(true, true);

    return 1;

}

int compareKshortPreSelectionAndStrippingVariables(int Run = 1){
    checkRun(Run);
    bool sWeight          = true;
    bool bWeighted        = true;
    bool b2DWeighted      = true;
    bool save2file        = true;
    bool SplitIntoDDandLL = true;
    int nYear           = (Run == 1 ? 2011 : 2015);
    std::string weightBranch = "nTracks";

    while(nYear < (Run == 1 ? 2013 : 2019)){
        int iteration = 1;
        bool KshortDecayInVelo = true;
        while((SplitIntoDDandLL || iteration == 1) && iteration < 3){
            //pre selection PID cuts:
            compareVariables(nYear, "pi_plus_PIDK",      sWeight, bWeighted, b2DWeighted,  false, false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, "mu_plus_ProbNNmu",  sWeight, bWeighted, b2DWeighted,  false, false, save2file, KshortDecayInVelo, weightBranch);
            compareVariables(nYear, "mu_minus_ProbNNmu", sWeight, bWeighted, b2DWeighted,  false, false, save2file, KshortDecayInVelo, weightBranch);
          
            //stripping
         // compareVariables(nYear, "",                  sWeight,  bWeighted, b2DWeighted,  false, false, save2file, KshortDecayInVelo, weightBranch);
            KshortDecayInVelo = false;
            iteration++;
        }
        nYear++;
    }
    return 1;
}

int compareKshortMVAonly( bool sWeight = true, bool bWeighted = true, bool b2DWeighted = true, int Run = 1, std::string weightBranch = firstMCweight){

    checkRun(Run);

    bool save2file = true;
    bool runDDandLLforAllVariables = true;

    //Load the MVA config from the txt file
    MVA_variables varsDD("DD");
    MVA_variables varsLL("LL");

    std::cout << "Get compare plots for these variables: " << std::endl;
    std::cout << "DD tracks: " << std::endl;
    varsDD.print();
    std::cout << "LL tracks: " << std::endl;
    varsLL.print();

    bool bLogX = false, bLog1X = false;

    int nYear = (Run == 1 ? 2011 : 2015);

    while(nYear < (Run == 1 ? 2013 : 2019)){

        //DD tracks
        for(int i = 0, j = 0; i < varsDD.NumberOfVariables(); i++){

            bLogX = false;
            bLog1X = false;
            if(strcmp(varsDD.AllVariables.at(i).Formula.c_str(), "log(x)") == 0){
                bLogX = true;
                bLog1X = false;
            }
            else if(strcmp(varsDD.AllVariables.at(i).Formula.c_str(), "log(1-x)") == 0){
                bLogX = false;
                bLog1X = true;
            }

            if(compareVariables(nYear, varsDD.AllBranches.at(j),sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, false, weightBranch) == 0)return 0;
            if(runDDandLLforAllVariables)
              if(compareVariables(nYear, varsDD.AllBranches.at(j),sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, true, weightBranch) == 0)return 0;

            j += varsDD.AllVariables.at(i).NoBr;

        }

        //LL tracks
        for(int i = 0, j = 0; i < varsLL.NumberOfVariables(); i++){

            if(strcmp(varsLL.AllVariables.at(i).Formula.c_str(), "log(x)") == 0)bLogX = true;
            else if(strcmp(varsLL.AllVariables.at(i).Formula.c_str(), "log(1-x)") == 0)bLog1X = true;
            else{
                bLogX = false;
                bLog1X = false;
            }

            if(compareVariables(nYear, varsLL.AllBranches.at(j),sWeight,  bWeighted, b2DWeighted, bLogX, bLog1X, save2file, true, weightBranch) == 0)return 0;
            if(runDDandLLforAllVariables)
              if(compareVariables(nYear, varsLL.AllBranches.at(j),sWeight,  bWeighted, b2DWeighted, bLogX, bLog1X, save2file, false, weightBranch) == 0)return 0;

            j += varsLL.AllVariables.at(i).NoBr;

        }

        for(int ddll = 0; ddll < 2; ddll++){
          //also compare nPV and B_plus_PT (risk of running double, if used in MVA, but who cares :)
          if(compareVariables(nYear, "nPV", sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;
          if(compareVariables(nYear, "nLongTracks", sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;
          if(compareVariables(nYear, (UseDTF ? "B_plus_PT_DTF" : "B_plus_PT"), sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;

          ////also compare pT and eta of all daughters
          if(compareVariables(nYear, (UseDTF ? "Ks_pi_minus_PT_DTF" : "Ks_pi_minus_PT"), sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;
          if(compareVariables(nYear, (UseDTF ? "Ks_pi_plus_PT_DTF" : "Ks_pi_plus_PT"), sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;
          if(compareVariables(nYear, (UseDTF ? "K_star_plus_PT_DTF" : "K_star_plus_PT"), sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;
          if(compareVariables(nYear, (UseDTF ? "K_short_PT_DTF" : "K_short_PT"), sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;
          if(compareVariables(nYear, (UseDTF ? "pi_plus_PT_DTF" : "pi_plus_PT"), sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;
          if(compareVariables(nYear, (UseDTF ? "mu_plus_PT_DTF" : "mu_plus_PT"), sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;
          if(compareVariables(nYear, (UseDTF ? "mu_minus_PT_DTF" : "mu_minus_PT"), sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;


          if(compareVariables(nYear, (UseDTF ? "Ks_pi_minus_ETA_DTF" : "Ks_pi_minus_ETA"), sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;
          if(compareVariables(nYear, (UseDTF ? "Ks_pi_plus_ETA_DTF" : "Ks_pi_plus_ETA"), sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;
          if(compareVariables(nYear, (UseDTF ? "K_star_plus_ETA_DTF" : "K_star_plus_ETA"), sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;
          if(compareVariables(nYear, (UseDTF ? "K_short_ETA_DTF" : "K_short_ETA"), sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;
          if(compareVariables(nYear, (UseDTF ? "pi_plus_ETA_DTF" : "pi_plus_ETA"), sWeight, bWeighted, b2DWeighted, bLogX, bLog1X, save2file, ddll, weightBranch) == 0) return 0;
        }

        nYear++;

    }

    return 1;

}

/////////////////////////////////////////////////////
///
/// comparison of all Kplus variables:
///
/////////////////////////////////////////////////////

int compareMuIPKplusResolved(int Run = 1, std::string weightBranch = firstMCweight){

    checkRun(Run);
    bool save2file = true;

    vector<int>years = yearsVectorInt(true,false,false,Run);

    for (auto nYear: years){
       /// mu
       compareVariables(nYear, "mu_plus_IPCHI2_OWNPV",  true, true, true, 1, 0, save2file, false, weightBranch);
       compareVariables(nYear, "mu_minus_IPCHI2_OWNPV", true, true, true, 1, 0, save2file, false, weightBranch);
       nYear++;
       if (nYear==2013) nYear =2015;
    }
    return 1;
}

int compareAllKplusResolved(bool sWeight = true, bool bWeighted = true, bool b2DWeighted = false, int Run = 1, std::string weightBranch = firstMCweight){

    checkRun(Run);

    bool save2file = true;
    weightBranch = firstMCweight + "_TM_rndGamma";

    vector<int>years = yearsVectorInt(true,false,true,Run); //Set to PHSP, otherwise 2015 wouldn't be done

    for (auto nYear: years){ //Why is this not a vector is beyond me
       //Global
       compareVariables(nYear, "nTracks",                               sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "nLongTracks",                           sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "nVeloTracks",                           sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "nTTracks",                              sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "nUpstreamTracks",                       sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "nDownstreamTracks",                     sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);

       ///B+
       compareVariables(nYear, "B_plus_DIRA_OWNPV",                     sWeight, bWeighted, b2DWeighted, 0, 1, save2file, false, weightBranch);
       compareVariables(nYear, "B_plus_OWNPV_CHI2",                     sWeight, bWeighted, b2DWeighted, 1, 0, save2file, false, weightBranch);
       compareVariables(nYear, "B_plus_FD_OWNPV",                       sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, (UseDTF?"B_plus_PT_DTF":"B_plus_PT"),    sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "B_plus_IP_OWNPV",                       sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "B_plus_IPCHI2_OWNPV",                   sWeight, bWeighted, b2DWeighted, 1, 0, save2file, false, weightBranch);
     //compareVariables(nYear, "B_plus_DOCA1",                          sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "B_plus_NEW_ConePTasym",                 sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "B_plus_NEW_ConePT",                     sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "B_plus_NEW_ConePasym",                  sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "B_plus_NEW_ConeP",                      sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);

       compareVariables(nYear, (UseDTF ? "B_plus_ETA_DTF":"B_plus_ETA"),sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       /// K*
       compareVariables(nYear, (UseDTF ? "K_star_plus_PT_DTF":"K_star_plus_PT"),    sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, (UseDTF ? "K_star_plus_ETA_DTF":"K_star_plus_ETA"),  sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "K_star_plus_IPCHI2_OWNPV",                          sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       /// mu
       compareVariables(nYear, "mu_plus_IPCHI2_OWNPV",                  sWeight, bWeighted, b2DWeighted, 1, 0, save2file, false, weightBranch);
       compareVariables(nYear, "mu_minus_IPCHI2_OWNPV",                 sWeight, bWeighted, b2DWeighted, 1, 0, save2file, false, weightBranch);
       ///K+
       compareVariables(nYear, "K_plus_IPCHI2_OWNPV",                   sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "K_plus_TRACK_CHI2NDOF",                 sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, (UseDTF ? "K_plus_PT_DTF":"K_plus_PT"),  sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, (UseDTF ? "K_plus_ETA_DTF":"K_plus_ETA"),sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       /// pi0
       compareVariables(nYear, UseDTF ? "pi_zero_resolved_PT_DTF":"pi_zero_resolved_PT",    sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, UseDTF ? "pi_zero_resolved_ETA_DTF":"pi_zero_resolved_ETA",  sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "pi_zero_resolved_CL",                                       sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       //compareVariables(nYear, "K_plus_PI0_ETA",                                            sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch); //TODO: check!!!
       //gamma
       compareVariables(nYear, (UseDTF ? "gamma1_PT_DTF":"gamma1_PT"),  sWeight, bWeighted, b2DWeighted, 1, 0, save2file, false, weightBranch);
       compareVariables(nYear, (UseDTF ? "gamma2_PT_DTF":"gamma2_PT"),  sWeight, bWeighted, b2DWeighted, 1, 0, save2file, false, weightBranch);
       compareVariables(nYear, "gamma1_CL",                             sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "gamma2_CL",                             sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "open_angle",                            sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);

       nYear++;

    }

    return 1;
}

int compareAllKplusMerged(bool sWeight = true, bool bWeighted = true, bool b2DWeighted = false, int Run = 1, std::string weightBranch = firstMCweight){

    checkRun(Run);
    bool save2file = true;

    int nYear = (Run == 1 ? 2011 : 2015);

    while(nYear < (Run == 1 ? 2013 : 2018)){

            ///B+
       compareVariables(nYear, "B_plus_DIRA_OWNPV",                     sWeight, bWeighted, b2DWeighted, 0, 1, save2file, false, weightBranch);
       compareVariables(nYear, "B_plus_OWNPV_CHI2",                     sWeight, bWeighted, b2DWeighted, 1, 0, save2file, false, weightBranch);
       compareVariables(nYear, "B_plus_FD_OWNPV",                       sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, (UseDTF ? "B_plus_PT_DTF":"B_plus_PT"),  sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "B_plus_IP_OWNPV",                       sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
     //compareVariables(nYear, "B_plus_DOCA1",                          sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "B_plus_NEW_ConePTasym",                 sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, (UseDTF ? "B_plus_ETA_DTF":"B_plus_ETA"),sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
           /// K*
       compareVariables(nYear, (UseDTF ? "K_star_plus_PT_DTF":"K_star_plus_PT"),    sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, (UseDTF ? "K_star_plus_ETA_DTF":"K_star_plus_ETA"),  sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "K_star_plus_IPCHI2_OWNPV",                          sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
            /// mu
       compareVariables(nYear, "mu_plus_IPCHI2_OWNPV",      sWeight,   bWeighted, b2DWeighted, 1, 0, save2file, false, weightBranch);
       compareVariables(nYear, "mu_minus_IPCHI2_OWNPV",     sWeight,   bWeighted, b2DWeighted, 1, 0, save2file, false, weightBranch);
           ///K+
       compareVariables(nYear, "K_plus_IPCHI2_OWNPV",                    sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, "K_plus_TRACK_CHI2NDOF",                  sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, (UseDTF ? "K_plus_PT_DTF":"K_plus_PT"),   sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       compareVariables(nYear, (UseDTF ? "K_plus_ETA_DTF":"K_plus_ETA"), sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
            /// pi0
       compareVariables(nYear,  (UseDTF ? "pi_zero_merged_ETA_DTF" : "pi_zero_merged_ETA"), sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch);
       nYear++;

    }

    return 1;
}

int compareKplusResolvedMVAonly(bool sWeight = true, bool bWeighted = true, bool b2DWeighted = true, int Run = 1, std::string weightBranch = firstMCweight){

    checkRun(Run);
    bool save2file = true;
    weightBranch = firstMCweight + "_TM_rndGamma";

    //Load the MVA config from the txt file
    MVA_variables vars("");

    std::cout << "Get compare plots for these variables: " << std::endl;
    vars.print();

    string operation = "";
    bool bLogX = false, bLog1X = false;

    vector<int>years = yearsVectorInt(true,false,true,Run); //Set to PHSP in order to process also 2015
    for (auto nYear: years){

        int k = 0; //check for all branches actually used
        for(int i = 0; i < vars.NumberOfVariables(); i++){ //loop over used variables
            bLogX = false;
            bLog1X = false;
            operation = "";
            if ( vars.AllVariables.at(i).NoBr == 2){
                cout << "[INFO]\tPlotting variable: " <<  vars.AllVariables.at(i).LaTeXName << endl;
                if( vars.AllVariables.at(i).Formula.find("log(1")!= std::string::npos){
                    bLogX = false;
                    bLog1X = true;
                }
                else if( vars.AllVariables.at(i).Formula.find("log(x") != std::string::npos){
                    bLogX = true;
                    bLog1X = false;
                }

                if( vars.AllVariables.at(i).Formula.find("max") != std::string::npos) operation = "max";
                else if( vars.AllVariables.at(i).Formula.find("min") != std::string::npos) operation = "min";
                else if( vars.AllVariables.at(i).Formula.find("abs") != std::string::npos) operation = "abs";
                if(compareVariables(nYear, vars.AllBranches.at(k),sWeight,  bWeighted, b2DWeighted, bLogX, bLog1X, save2file, false, weightBranch, false, "","" , "") == 0)return 0;
                if(compareVariables(nYear, vars.AllBranches.at(k+1),sWeight,  bWeighted, b2DWeighted, bLogX, bLog1X, save2file, false, weightBranch, false, "","" , "" ) == 0)return 0;

                compareVariables(nYear, vars.AllBranches.at(k),sWeight,  bWeighted, b2DWeighted, bLogX, bLog1X, save2file, false, weightBranch, true, operation, vars.AllBranches.at(k+1), vars.AllVariables.at(i).LaTeXName);
                k+=2;
            }
            else{
                cout << "[INFO]\tPlotting variable: " <<  vars.AllBranches.at(k) << endl;
                if( vars.AllVariables.at(i).Formula.find("log(x)") != std::string::npos){
                    bLogX = true;
                    bLog1X = false;
                }
                else if( vars.AllVariables.at(i).Formula.find("log(1-x)")!= std::string::npos){
                    bLogX = false;
                    bLog1X = true;
                }
                if(compareVariables(nYear, vars.AllBranches.at(k),sWeight,  bWeighted, b2DWeighted, bLogX, bLog1X, save2file, false, weightBranch,false, "","", vars.AllVariables.at(i).LaTeXName) == 0)return 0;
                k++;
            }
        }
        //also compare nTracks and B_plus_PT (risk of running double, if used in MVA, but who cares :)
        if(compareVariables(nYear, firstMCweight, sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch) == 0)return 0;
        if(compareVariables(nYear, seconMCweight, sWeight, bWeighted, b2DWeighted, 0, 0, save2file, false, weightBranch) == 0)return 0;

        nYear++;

    }

    return 1;

}

int compareAllKplus(std::string weightBranch = firstMCweight){

    NtrackWeightAllKplus(false, false, true);
    if (compareAllKplusResolved     (true,  0, 0,  1, weightBranch)==0) return 0;
    if (compareAllKplusResolved     (true,  0, 1,  1, weightBranch)==0) return 0;
    if (compareAllKplusResolved     (true,  1, 0,  1, weightBranch)==0) return 0;
    if (compareAllKplusResolved     (true,  1, 1,  1, weightBranch)==0) return 0;

    if (compareAllKplusResolved     (true,  0, 0,  2, weightBranch)==0) return 0;
    if (compareAllKplusResolved     (true,  0, 1,  2, weightBranch)==0) return 0;
    if (compareAllKplusResolved     (true,  1, 0,  2, weightBranch)==0) return 0;
    if (compareAllKplusResolved     (true,  1, 1,  2, weightBranch)==0) return 0;


    if (compareKplusResolvedMVAonly (true,  0, 0,  1, weightBranch)==0) return 0;
    if (compareKplusResolvedMVAonly (true,  0, 1,  1, weightBranch)==0) return 0;
    if (compareKplusResolvedMVAonly (true,  1, 0,  1, weightBranch)==0) return 0;
    if (compareKplusResolvedMVAonly (true,  1, 1,  1, weightBranch)==0) return 0;

    if (compareKplusResolvedMVAonly (true,  0, 0,  2, weightBranch)==0) return 0;
    if (compareKplusResolvedMVAonly (true,  0, 1,  2, weightBranch)==0) return 0;
    if (compareKplusResolvedMVAonly (true,  1, 0,  2, weightBranch)==0) return 0;
    if (compareKplusResolvedMVAonly (true,  1, 1,  2, weightBranch)==0) return 0;

    return 1;
}

/////////////////////////////////////////////////////
///
/// comparison of all variables:
///
/////////////////////////////////////////////////////

int compareAll(int Run = 1){

    if(Kst2Kspiplus)        return compareKshortMVAonly(true,true, true, Run);
    if(Kst2Kpluspi0Resolved)return compareKplusResolvedMVAonly(true,true, true, Run);
    if(Kst2Kpluspi0Merged)  return compareAllKplusMerged(true,true,true, Run);

    coutERROR("Nothing processed! Incorrect decay string given!");
    return 0;

}

/////////////////////////////////////////////////////
///
/// comparison of track multiplicities between Run I and Run II
///
/////////////////////////////////////////////////////

int compareTrackMultiplicities(bool KshortDecaysInVelo = false, bool MC = false, std::string weightBranch = firstMCweight){

    //change hardcoded if the distributions should be compared unweighted, otherwise use 2 * 1D reweight in PT(B+) and nTracks
    bool reweightMC = true;
    bool sWeight = true;
    
    gStyle -> SetOptStat(0);
    gROOT->SetBatch(kTRUE);
    LHCbStyle();
    //lhcbStyle->SetOptTitle(1);


    //create one tree per Run and add all years and magnet polarities into the same tree
    TChain * treeRun1 = new TChain(MC ? "DecayTreeTruthMatched" : "DecayTree");
    TChain * treeRun2 = new TChain(MC ? "DecayTreeTruthMatched" : "DecayTree");

    // Kst2Kpluspi0Resolved case
    if(Kst2Kpluspi0Resolved){
        if(MC){
            treeRun1->Add(Form("%s/data/MC/2011_KplusPi0Resolved_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));
            treeRun1->Add(Form("%s/data/MC/2012_KplusPi0Resolved_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));

            treeRun2->Add(Form("%s/data/MC/2015_KplusPi0Resolved_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));
            treeRun2->Add(Form("%s/data/MC/2016_KplusPi0Resolved_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));
        }
        else{
            treeRun1->Add(Form("%s/data/2011_KplusPi0Resolved_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));
            treeRun1->Add(Form("%s/data/2012_KplusPi0Resolved_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));

            treeRun2->Add(Form("%s/data/2015_KplusPi0Resolved_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));
            treeRun2->Add(Form("%s/data/2016_KplusPi0Resolved_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));
        }
    }

    // Kst2Kpluspi0Merged case
    else if(Kst2Kpluspi0Merged){
        if(MC){

            coutERROR("No merged pi0 MC sample available!");
            return 0;

            treeRun1->Add(Form("%s/data/MC/2011_KplusPi0Merged_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));
            treeRun1->Add(Form("%s/data/MC/2012_KplusPi0Merged_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));

            treeRun2->Add(Form("%s/data/MC/2015_KplusPi0Merged_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));
            treeRun2->Add(Form("%s/data/MC/2016_KplusPi0Merged_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));
        }
        else{
            treeRun1->Add(Form("%s/data/2011_KplusPi0Merged_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));
            treeRun1->Add(Form("%s/data/2012_KplusPi0Merged_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));

            treeRun2->Add(Form("%s/data/2015_KplusPi0Merged_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));
            treeRun2->Add(Form("%s/data/2016_KplusPi0Merged_BDTinput%s.root", path_to_output_KplusPizero.c_str(), sWeight ? "" : "_nosWeight"));
        }
    }

    // Kst2Kspiplus case
    else if(Kst2Kspiplus){
        if(MC){
            if(SplitDDandLL){
                treeRun1->Add(Form("%s/data/MC/2011_KshortPiplus%s_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), KshortDecaysInVelo ? "_LL" : "_DD", sWeight ? "" : "_nosWeight"));
                treeRun1->Add(Form("%s/data/MC/2012_KshortPiplus%s_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), KshortDecaysInVelo ? "_LL" : "_DD", sWeight ? "" : "_nosWeight"));

                treeRun2->Add(Form("%s/data/MC/2015_KshortPiplus%s_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), KshortDecaysInVelo ? "_LL" : "_DD", sWeight ? "" : "_nosWeight"));
                treeRun2->Add(Form("%s/data/MC/2016_KshortPiplus%s_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), KshortDecaysInVelo ? "_LL" : "_DD", sWeight ? "" : "_nosWeight"));
            }
            else{
                treeRun1->Add(Form("%s/data/MC/2011_KshortPiplus_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), sWeight ? "" : "_nosWeight"));
                treeRun1->Add(Form("%s/data/MC/2012_KshortPiplus_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), sWeight ? "" : "_nosWeight"));

                treeRun2->Add(Form("%s/data/MC/2015_KshortPiplus_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), sWeight ? "" : "_nosWeight"));
                treeRun2->Add(Form("%s/data/MC/2016_KshortPiplus_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), sWeight ? "" : "_nosWeight"));
            }
        }
        else{
            if(SplitDDandLL){
                treeRun1->Add(Form("%s/data/2011_KshortPiplus%s_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), KshortDecaysInVelo ? "_LL" : "_DD", sWeight ? "" : "_nosWeight"));
                treeRun1->Add(Form("%s/data/2012_KshortPiplus%s_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), KshortDecaysInVelo ? "_LL" : "_DD", sWeight ? "" : "_nosWeight"));

                treeRun2->Add(Form("%s/data/2015_KshortPiplus%s_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), KshortDecaysInVelo ? "_LL" : "_DD", sWeight ? "" : "_nosWeight"));
                treeRun2->Add(Form("%s/data/2016_KshortPiplus%s_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), KshortDecaysInVelo ? "_LL" : "_DD", sWeight ? "" : "_nosWeight"));
            }
            else{
                treeRun1->Add(Form("%s/data/2011_KshortPiplus_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), sWeight ? "" : "_nosWeight"));
                treeRun1->Add(Form("%s/data/2012_KshortPiplus_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), sWeight ? "" : "_nosWeight"));

                treeRun2->Add(Form("%s/data/2015_KshortPiplus_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), sWeight ? "" : "_nosWeight"));
                treeRun2->Add(Form("%s/data/2016_KshortPiplus_BDTinput%s.root", path_to_output_KshortPiplus.c_str(), sWeight ? "" : "_nosWeight"));
            }
        }
    }
    else return 0;

    //create vector with all requested variables that are compared between Run1 and Run2
    std::vector<std::string> TrackTypes;
    TrackTypes.push_back("nTracks");
    TrackTypes.push_back("nLongTracks");
    TrackTypes.push_back("nBackTracks");
    TrackTypes.push_back("nDownstreamTracks");
    TrackTypes.push_back("nTTracks");
    TrackTypes.push_back("nUpstreamTracks");
    TrackTypes.push_back("nVeloTracks");

    std::vector<int> UpperLimits;
    UpperLimits.push_back(500);
    UpperLimits.push_back(125);
    UpperLimits.push_back(75);
    UpperLimits.push_back(75);
    UpperLimits.push_back(150);
    UpperLimits.push_back(45);
    UpperLimits.push_back(300);

    const unsigned int N = TrackTypes.size();

    if(UpperLimits.size() != N){
        coutWarning("Number of given upper limits for variable distributions does not match the number of varialbes!");
        while(UpperLimits.size() < N)UpperLimits.push_back(100);
    }

    int nTracksRun1[N];
    int nTracksRun2[N];

    TH1D * histosRun1[N];
    TH1D * histosRun2[N];

    for(unsigned int tt = 0; tt < N; tt++){

        //link all variables from TTree to the int:
        treeRun1->SetBranchAddress(TrackTypes.at(tt).c_str(), &nTracksRun1[tt]);
        treeRun2->SetBranchAddress(TrackTypes.at(tt).c_str(), &nTracksRun2[tt]);

        histosRun1[tt] = new TH1D(Form("%s_Run1", TrackTypes.at(tt).c_str()), "2011 + 2012", (UpperLimits.at(tt) > 200) ? 100 : UpperLimits.at(tt) + 1 , -0.5 , UpperLimits.at(tt) + 0.5 );
        histosRun2[tt] = new TH1D(Form("%s_Run2", TrackTypes.at(tt).c_str()), "2015 + 2016", (UpperLimits.at(tt) > 200) ? 100 : UpperLimits.at(tt) + 1 , -0.5 , UpperLimits.at(tt) + 0.5 );

        histosRun1[tt]->SetMarkerStyle(20);
        histosRun2[tt]->SetMarkerStyle(20);

        histosRun1[tt]->SetMarkerColor(2);
        histosRun2[tt]->SetMarkerColor(4);

        histosRun1[tt]->SetLineColor(2);
        histosRun2[tt]->SetLineColor(4);

        histosRun1[tt]->GetXaxis()->SetTitle(TrackTypes.at(tt).c_str());
        histosRun1[tt]->GetYaxis()->SetTitle("normalized events");
        histosRun2[tt]->GetXaxis()->SetTitle(TrackTypes.at(tt).c_str());
        histosRun2[tt]->GetYaxis()->SetTitle("normalized events");

    }

    //link weights!
    double wRun1 = 1.0;
    double wRun2 = 1.0;
    if(MC){
        if (reweightMC){ //if not, keep wRun1 and wRun2 = 1.0
            treeRun1->SetBranchAddress(Form("weight2D_%s",weightBranch.c_str()), &wRun1);
            treeRun2->SetBranchAddress(Form("weight2D_%s",weightBranch.c_str()), &wRun2);
        }
    }
    else if (sWeight){
        treeRun1->SetBranchAddress("N_Bplus_sw", &wRun1);
        treeRun2->SetBranchAddress("N_Bplus_sw", &wRun2);
    }

    std::cout << "[INFO]\t\tAll variables linked and histograms created!" << std::endl;

    unsigned int N_Run1 = treeRun1->GetEntries();
    unsigned int N_Run2 = treeRun2->GetEntries();

    std::cout << std::endl;
    std::cout << "= = = = = = = = = = = = = = = = " << std::endl;
    std::cout << std::endl;

    std::cout << "[INFO]\t\tStart looping over dataset of Run 1" << std::endl;
    std::cout << "[INFO]\t\tTotal of " << N_Run1 << " events!" << std::endl;

    //fill Run1 histograms:
    for(unsigned int i = 0; i < N_Run1; i++){

        treeRun1->GetEntry(i);

        if(i !=0 && i%1000 == 0)std::cout << "[LOOP]\t\tRun 1: Event [" << i + 1 << " / " << N_Run1 << "]" << std::endl;

        for(unsigned int tt = 0; tt < N; tt++){
            histosRun1[tt]->Fill(nTracksRun1[tt], wRun1);
        }

    }
    std::cout << std::endl;
    std::cout << "= = = = = = = = = = = = = = = = " << std::endl;
    std::cout << std::endl;

    std::cout << "[INFO]\t\tStart looping over dataset of Run 2" << std::endl;
    std::cout << "[INFO]\t\tTotal of " << N_Run2 << " events!" << std::endl;

    //fill Run2 histograms:
    for(unsigned int ii = 0; ii < N_Run2; ii++){

        treeRun2->GetEntry(ii);
        if(MC && !reweightMC)wRun2 = 1.;

        if(ii !=0 && ii%1000 == 0)std::cout << "[LOOP]\t\tRun 2: Event [" << ii + 1 << " / " << N_Run2 << "]" << std::endl;

        for(unsigned int tt = 0; tt < N; tt++){
            histosRun2[tt]->Fill(nTracksRun2[tt], wRun2);
        }

    }

    //normalize all histograms:
    for(unsigned int tt = 0; tt < N; tt++){
        //histosRun1[tt]->Sumw2();
        //histosRun2[tt]->Sumw2();
        histosRun1[tt]->Scale(1. / N_Run1);
        histosRun2[tt]->Scale(1. / N_Run2);
    }

    std::cout << std::endl;
    std::cout << "= = = = = = = = = = = = = = = = " << std::endl;
    std::cout << std::endl;

    std::cout << "[INFO]\t\tSave histograms to file!" << std::endl;

    //create new file for these comparison plots:
    TFile * fOutput = NULL;

    if(Kst2Kpluspi0Merged)          fOutput = new TFile(Form("%s/ComparePlots/%s%s%s.root", path_to_output_KplusPizero.c_str(), TheDecay.c_str(), MC ? "_MC" : "", sWeight ? "" : "_nosWeight"), "RECREATE");
    else if(Kst2Kpluspi0Resolved)   fOutput = new TFile(Form("%s/ComparePlots/%s%s%s.root", path_to_output_KplusPizero.c_str(), TheDecay.c_str(), MC ? "_MC" : "", sWeight ? "" : "_nosWeight"), "RECREATE");
    else if(Kst2Kspiplus){
        if(SplitDDandLL)            fOutput = new TFile(Form("%s/ComparePlots/%s%s%s%s.root", path_to_output_KshortPiplus.c_str(), TheDecay.c_str(), KshortDecaysInVelo ? "_LL" : "_DD", MC ? "_MC" : "", sWeight ? "" : "_nosWeight"), "RECREATE");
        else                        fOutput = new TFile(Form("%s/ComparePlots/%s%s%s%s.root", path_to_output_KshortPiplus.c_str(), TheDecay.c_str(), KshortDecaysInVelo ? "_LL" : "_DD", MC ? "_MC" : "", sWeight ? "" : "_nosWeight"), "RECREATE");
    }
    else return 0;

    if(fOutput == NULL){
        coutERROR("Initializing of output file was not successful. Exit program!");
        return 0;
    }

    TCanvas * c1;

    float maxBinContent = 0.;

    //plot Run1 and Run2 histograms into the same canvas and save to TFile
    for(unsigned int tt = 0; tt < N; tt++){

        maxBinContent = 0.;
        for(int bin = 1; bin <= histosRun1[tt]->GetNbinsX(); bin++){
            if(maxBinContent < histosRun1[tt]->GetBinContent(bin))maxBinContent = histosRun1[tt]->GetBinContent(bin);
        }
        for(int bin = 1; bin <= histosRun2[tt]->GetNbinsX(); bin++){
            if(maxBinContent < histosRun2[tt]->GetBinContent(bin))maxBinContent = histosRun2[tt]->GetBinContent(bin);
        }

        c1 = new TCanvas("c1", "c1");
        c1->Clear();
        c1->SetName(TrackTypes.at(tt).c_str());
        c1->SetTitle(TrackTypes.at(tt).c_str());
        histosRun1[tt]->GetYaxis()->SetRangeUser(0, maxBinContent * 1.1);
        histosRun1[tt]->Draw("E1");
        histosRun2[tt]->Draw("E1SAME");
        c1->BuildLegend(0.6, 0.7, 0.9, 0.9);
        fOutput->cd();
        c1->Write("",TObject::kWriteDelete);
        c1->Close();
    }

    fOutput->Close();

    return 1;

}

/////////////////////////////////////////////////////
///
/// comparison of the angles between (2D-)weighted and non-weighted PHSP MC
///
/////////////////////////////////////////////////////

int compareAnglesInPHSP(int year = 2011, bool sWeight = true, bool b2Dweighted = true, bool KshortDecayInVelo = true, std::string weightBranch = firstMCweight){

    gStyle -> SetOptStat(0);
    gROOT->SetBatch(kTRUE);
    LHCbStyle();

    //put both magnet polarities into one TChain
    TChain * treePHSP = new TChain("DecayTreeTruthMatched");

    if(Kst2Kpluspi0Resolved){
        treePHSP->Add(Form("%s/data/PHSP/%i_KplusPi0ResolvedPHSP_BDTinput%s.root", path_to_output_KplusPizero.c_str(), year, sWeight ? "" : "_nosWeight"));
    }
    else if(Kst2Kspiplus){
        treePHSP->Add(Form("%s/data/PHSP/%i_KshortPiplusPHSP%s_BDTinput%s.root",  path_to_output_KshortPiplus.c_str(), year, SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "", sWeight ? "" : "_nosWeight"));
    }

    int N = treePHSP->GetEntries();
    if(N == 0){
        std::cout << Form("[ERROR]\t\tNo events found in file data/PHSP/%i_%sPHSP%s_BDTinput.root", year, TheDecay.c_str(), (Kst2Kspiplus && SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "")) << std::endl;
        return 0;
    }

    //deactivate all branches exept the one of intrest!
    treePHSP->SetBranchStatus("*",0);
    treePHSP->SetBranchStatus("B_plus_ThetaK",1);
    treePHSP->SetBranchStatus("B_plus_ThetaL",1);
    treePHSP->SetBranchStatus("B_plus_Phi",1);
    treePHSP->SetBranchStatus(Form("weight_%s",weightBranch.c_str()),1);
    treePHSP->SetBranchStatus(Form("weight2D_%s",weightBranch.c_str()),1);

    double angle[3];//ctk, ctl, phi;
    double w, w2d;

    treePHSP->SetBranchAddress("B_plus_ThetaK",&angle[0]);
    treePHSP->SetBranchAddress("B_plus_ThetaL",&angle[1]);
    treePHSP->SetBranchAddress("B_plus_Phi",&angle[2]);
    treePHSP->SetBranchAddress(Form("weight_%s",weightBranch.c_str()),&w);
    treePHSP->SetBranchAddress(Form("weight2D_%s",weightBranch.c_str()),&w2d);

    //initialize histograms
    int bins = 100;
    double xLow[3] = {-1., -1., -TMath::Pi()};
    double xHigh[3] = {+1., +1., +TMath::Pi()};
    std::string theName[3] = {"cos(#theta_{K})", "cos(#theta_{L})", "#phi"};
    std::string leName[3] = {"ctk", "ctl", "phi"};

    TH1D * hRatio[3];
    TH1D * hWeighted[3];
    TH1D * hNoWeight[3];

    for(int h = 0; h < 3; h++){
        hRatio[h]    = new TH1D(Form("hRatio_%s",    leName[h].c_str()), Form("Ratio weighted to non-weighted (%s)", theName[h].c_str()),                       bins, xLow[h], xHigh[h]);
        hWeighted[h] = new TH1D(Form("hWeighted_%s", leName[h].c_str()), Form("%sWeighted distribution of %s", (b2Dweighted ? "2D-" : ""), theName[h].c_str()), bins, xLow[h], xHigh[h]);
        hNoWeight[h] = new TH1D(Form("hNoWeight_%s", leName[h].c_str()), Form("Non-weighted distribution of %s", theName[h].c_str()),                           bins, xLow[h], xHigh[h]);
    }

    //loop over events and save to histograms
    for(int i = 0; i < N; i++){
        if(i%10000==0 && i != 0)std::cout << "Loading data event " << i << " / " << N << std::endl;
        treePHSP->GetEntry(i);
        for(int a = 0; a < 3; a++){
            if(a == 0 || a == 1){ //convert theta to cos(theta)
                angle[a] = TMath::Cos(angle[a]);
            }
            hRatio[a]   ->Fill(angle[a], b2Dweighted ? w2d : w);
            hWeighted[a]->Fill(angle[a], b2Dweighted ? w2d : w);
            hNoWeight[a]->Fill(angle[a], 1.0);
        }
    }

    double varMax[3]   = {-1.0e8,-1.0e8,-1.0e8};
    double varMin[3]   = {+1.0e8,+1.0e8,+1.0e8};
    double ratioMax[3] = {-1.0e8,-1.0e8,-1.0e8};
    double ratioMin[3] = {+1.0e8,+1.0e8,+1.0e8};

    double val, weival, ratioval;
    for(int h = 0; h < 3; h++){

        //make ratio:
        hRatio[h]->Divide(hNoWeight[h]);

        //set correct ranges for the histograms:
        for(int bin = 1; bin <= bins; bin++){

            val      = hNoWeight[h]->GetBinContent(bin);
            weival   = hWeighted[h]->GetBinContent(bin);
            ratioval = hRatio[h]   ->GetBinContent(bin);

            if(varMax[h]   <= val)     varMax[h] = val;
            if(varMax[h]   <= weival)  varMax[h] = weival;
            if(ratioMax[h] <= ratioval)ratioMax[h] = ratioval;

            if(varMin[h]   >= val)     varMin[h] = val;
            if(varMin[h]   >= weival)  varMin[h] = weival;
            if(ratioMin[h] >= ratioval)ratioMin[h] = ratioval;

        }

        varMax[h] *= 1.1;
        if(varMin[h] < 0)varMin[h] *= 1.1;
        else varMin[h] = 0.001; //if minimum is positve, set minimum to just above 0 to remove label
    
        if(ratioMax[h] > 3.)ratioMax[h] = 3.;
        if(ratioMax[h] < 2.)ratioMax[h] = 2.;
        ratioMax[h] *= 1.1;

        //configurables for plotting
        float lowerPlotHeight = 0.6;

        //create two pads into one canvas
        TCanvas * theCanvas = new TCanvas(Form("theCanvas%s", leName[h].c_str()), Form("ratio and superposition of %s" , theName[h].c_str()));
        float textsize = gStyle->GetTextSize();
        TPad * pad1 = new TPad(Form("pad1%s", leName[h].c_str()), "ratio",0.0,lowerPlotHeight,1.0,1.0,0);
        TPad * pad2 = new TPad(Form("pad2%s", leName[h].c_str()), "superposition",0.0,0.0,1.0,lowerPlotHeight,0);
        pad1->Draw();
        pad2->Draw();

        //modifiy pad for main plot
        pad1->Clear();
        pad1->SetBorderSize  (0);
        pad1->SetBottomMargin(1e-6);
        pad1->SetTopMargin(pad1->GetTopMargin() / ( 1 - lowerPlotHeight) );
        pad1->cd();

        //some axis-modifications on the main plot
        TGaxis::SetExponentOffset(1e+9,1e+9,"y");//offset = pad size * 1e+7
        hRatio[h]->GetXaxis()->SetNoExponent(); //<-- spoils MaxDigits settings, so don't use it on other axis
        hRatio[h]->GetXaxis()->SetLabelSize(0.0);//don't print labels
        hRatio[h]->GetXaxis()->SetRangeUser(xLow[h], xHigh[h]);
        hRatio[h]->GetXaxis()->SetTickLength(hRatio[h]->GetXaxis()->GetTickLength()/(1-lowerPlotHeight));
        hRatio[h]->GetXaxis()->SetNdivisions(gStyle->GetNdivisions("X"));

        hRatio[h]->GetYaxis()->SetTitle("ratio (#omega / 1.0)");
        hRatio[h]->GetYaxis()->SetTitleSize(textsize/(1-lowerPlotHeight));
        hRatio[h]->GetYaxis()->SetLabelSize(textsize/(1-lowerPlotHeight));
        hRatio[h]->GetYaxis()->SetTickLength(hRatio[h]->GetYaxis()->GetTickLength());
        hRatio[h]->GetYaxis()->SetNdivisions(gStyle->GetNdivisions("Y"));
        hRatio[h]->GetYaxis()->SetTitleOffset(1.06*(1-lowerPlotHeight));
        hRatio[h]->GetYaxis()->SetRangeUser(0.5, 1.5);
        hRatio[h]->Draw("E1");

        TLine * unityline = new TLine(xLow[h], 1, xHigh[h], 1);
        unityline->SetLineStyle(2);
        unityline->SetLineColor(4);
        unityline->Draw("SAME");

        pad2->Clear();
        pad2->SetBorderSize  (0);
        pad2->SetTopMargin   (1e-6);
        pad2->SetBottomMargin(pad2->GetBottomMargin() / lowerPlotHeight );
        pad2->cd();

        TGaxis::SetExponentOffset(1e+9,1e+9,"x");//offset = pad size * 1e+7
        hNoWeight[h]->GetXaxis()->SetTitleOffset(1.05);
        hNoWeight[h]->GetXaxis()->SetTitleSize  (textsize/lowerPlotHeight);
        hNoWeight[h]->GetXaxis()->SetLabelSize  (textsize/lowerPlotHeight);
        hNoWeight[h]->GetXaxis()->SetTickLength (hRatio[h]->GetXaxis()->GetTickLength()/(lowerPlotHeight/(1-lowerPlotHeight)));
        hNoWeight[h]->GetXaxis()->SetNdivisions (gStyle->GetNdivisions("X"));
        hNoWeight[h]->GetXaxis()->SetTitle(theName[h].c_str());
        hNoWeight[h]->GetXaxis()->SetRangeUser(xLow[h], xHigh[h]);


        hNoWeight[h]->GetYaxis()->SetRangeUser(varMin[h], varMax[h]);
        hNoWeight[h]->GetYaxis()->SetTitle("events");
        hNoWeight[h]->GetYaxis()->SetLabelSize  (textsize/lowerPlotHeight);
        hNoWeight[h]->GetYaxis()->SetTitleSize  (textsize/lowerPlotHeight);
        hNoWeight[h]->GetYaxis()->SetTickLength(hRatio[h]->GetYaxis()->GetTickLength());
        hNoWeight[h]->GetYaxis()->SetNdivisions (gStyle->GetNdivisions("Y"));
        hNoWeight[h]->GetYaxis()->SetTitleOffset(1.06*lowerPlotHeight);
        hNoWeight[h]->Draw("E1");

        hWeighted[h]->SetLineColor(2);
        hWeighted[h]->SetMarkerColor(2);
        hWeighted[h]->Draw("E1SAME");

        //Legend and position...
        float LegendXposition = 0.4;
        float LegendYposition = 0.3;
        TLegend * leg = new TLegend(LegendXposition,LegendYposition,LegendXposition + 0.25, LegendYposition + 0.18);
        leg->AddEntry(hWeighted[h],Form("%sweighted PHSP MC",(b2Dweighted ? "2#upoint1D-" : "")), "lpe");
        leg->AddEntry(hNoWeight[h],"non-weighted PHSP MC", "lpe");
        leg->SetTextSize(0.04/lowerPlotHeight); // works fine
        leg->Draw("same");

        addLHCbtag(LegendXposition, LegendYposition + 0.27, "simulation", 1, 1/lowerPlotHeight);

        if (Kst2Kspiplus)theCanvas->Print(Form("%s/ComparePlots/%i_%s%s_Comparison%sWeights_%s%s.eps", path_to_output_KshortPiplus.c_str(), year, TheDecay.c_str(), (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), (b2Dweighted ? "2D" : ""), leName[h].c_str(), sWeight ? "" : "_nosWeight"));
        else             theCanvas->Print(Form("%s/ComparePlots/%i_%s_Comparison%sWeights_%s%s.eps", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), (b2Dweighted ? "2D" : ""), leName[h].c_str(), sWeight ? "" : "_nosWeight"));

        theCanvas->Close();
        delete theCanvas;

        delete hNoWeight[h];
        delete hWeighted[h];
        delete hRatio[h];

    }

    delete treePHSP;

    return 1;

}

int compareAllAnglesInPHSP(int Run = 1){

    bool b2Dweights = true;

    std::vector<int>years;
    if(Run == 1){
        years.push_back(2011);
        years.push_back(2012);
    }
    if(Run == 2){
        years.push_back(2015);
        years.push_back(2016);
        years.push_back(2017);
        years.push_back(2018);
    }

    for(int y = 0; y < years.size(); y++){

        if(compareAnglesInPHSP(years.at(y), true, b2Dweights, false, firstMCweight) == 0){
            coutERROR("Failed to compare angles for " + to_string(years.at(y)) + (Kst2Kspiplus && SplitDDandLL ? " (DD tracks)" : ""));
            return 0;
        }

        if(Kst2Kspiplus && SplitDDandLL){
            if(compareAnglesInPHSP(years.at(y), true, b2Dweights, true, firstMCweight) == 0){
                coutERROR("Failed to compare angles for " + to_string(years.at(y)) + " (LL tracks)");
                return 0;
            }
        }
    }

    return 1;

}

/////////////////////////////////////////////////////
///
/// comparison of the angles between (2D-)weighted and non-weighted signal MC
///
/////////////////////////////////////////////////////

int compareAnglesInMC(int year = 2011, bool sWeight = true, bool b2Dweighted = true, bool KshortDecayInVelo = true, std::string weightBranch = firstMCweight){

    gStyle -> SetOptStat(0);
    gROOT->SetBatch(kTRUE);
    LHCbStyle();

    //put both magnet polarities into one TChain
    TChain * treeMC = new TChain("DecayTreeTruthMatched");

    if(Kst2Kpluspi0Resolved){
        treeMC->Add(Form("%s/data/MC/%i_KplusPi0Resolved_BDTinput%s.root", path_to_output_KplusPizero.c_str(), year, sWeight ? "" : "_nosWeight"));
    }
    else if(Kst2Kspiplus){
        treeMC->Add(Form("%s/data/MC/%i_KshortPiplus%s_BDTinput%s.root",  path_to_output_KshortPiplus.c_str(), year, SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "", sWeight ? "" : "_nosWeight"));
    }

    int N = treeMC->GetEntries();
    if(N == 0){
        std::cout << Form("[ERROR]\t\tNo events found in file data/MC/%i_%s%s_BDTinput.root", year, TheDecay.c_str(), (Kst2Kspiplus && SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "")) << std::endl;
        return 0;
    }

    //deactivate all branches exept the one of intrest!
    treeMC->SetBranchStatus("*",0);
    treeMC->SetBranchStatus("B_plus_ThetaK",1);
    treeMC->SetBranchStatus("B_plus_ThetaL",1);
    treeMC->SetBranchStatus("B_plus_Phi",1);
    treeMC->SetBranchStatus(Form("weight_%s",weightBranch.c_str()),1);
    treeMC->SetBranchStatus(Form("weight2D_%s",weightBranch.c_str()),1);

    double angle[3];//ctk, ctl, phi;
    double w, w2d;

    treeMC->SetBranchAddress("B_plus_ThetaK",&angle[0]);
    treeMC->SetBranchAddress("B_plus_ThetaL",&angle[1]);
    treeMC->SetBranchAddress("B_plus_Phi",&angle[2]);
    treeMC->SetBranchAddress(Form("weight_%s",weightBranch.c_str()),&w);
    treeMC->SetBranchAddress(Form("weight2D_%s",weightBranch.c_str()),&w2d);

    //initialize histograms
    int bins = 100;
    double xLow[3] = {-1., -1., -TMath::Pi()};
    double xHigh[3] = {+1., +1., +TMath::Pi()};
    std::string theName[3] = {"cos(#theta_{K})", "cos(#theta_{L})", "#phi"};
    std::string leName[3] = {"ctk", "ctl", "phi"};

    TH1D * hRatio[3];
    TH1D * hWeighted[3];
    TH1D * hNoWeight[3];

    for(int h = 0; h < 3; h++){
        hRatio[h]    = new TH1D(Form("hRatio_%s",    leName[h].c_str()), Form("Ratio weighted to non-weighted (%s)", theName[h].c_str()),                       bins, xLow[h], xHigh[h]);
        hWeighted[h] = new TH1D(Form("hWeighted_%s", leName[h].c_str()), Form("%sre-weighted distribution of %s", (b2Dweighted ? "2D-" : ""), theName[h].c_str()), bins, xLow[h], xHigh[h]);
        hNoWeight[h] = new TH1D(Form("hNoWeight_%s", leName[h].c_str()), Form("Non-weighted distribution of %s", theName[h].c_str()),                           bins, xLow[h], xHigh[h]);
    }

    //loop over events and save to histograms
    for(int i = 0; i < N; i++){
        if(i%10000==0 && i != 0)std::cout << "Loading data event " << i << " / " << N << std::endl;
        treeMC->GetEntry(i);
        for(int a = 0; a < 3; a++){
            if(a == 0 || a == 1){ //convert theta to cos(theta)
                angle[a] = TMath::Cos(angle[a]);
            }
            hRatio[a]   ->Fill(angle[a], b2Dweighted ? w2d : w);
            hWeighted[a]->Fill(angle[a], b2Dweighted ? w2d : w);
            hNoWeight[a]->Fill(angle[a], 1.0);
        }
    }

    double varMax[3]   = {-1.0e8,-1.0e8,-1.0e8};
    double varMin[3]   = {+1.0e8,+1.0e8,+1.0e8};
    double ratioMax[3] = {-1.0e8,-1.0e8,-1.0e8};
    double ratioMin[3] = {+1.0e8,+1.0e8,+1.0e8};

    double val, weival, ratioval;
    for(int h = 0; h < 3; h++){

        //make ratio:
        hRatio[h]->Divide(hNoWeight[h]);

        //set correct ranges for the histograms:
        for(int bin = 1; bin <= bins; bin++){

            val      = hNoWeight[h]->GetBinContent(bin);
            weival   = hWeighted[h]->GetBinContent(bin);
            ratioval = hRatio[h]   ->GetBinContent(bin);

            if(varMax[h]   <= val)     varMax[h] = val;
            if(varMax[h]   <= weival)  varMax[h] = weival;
            if(ratioMax[h] <= ratioval)ratioMax[h] = ratioval;

            if(varMin[h]   >= val)     varMin[h] = val;
            if(varMin[h]   >= weival)  varMin[h] = weival;
            if(ratioMin[h] >= ratioval)ratioMin[h] = ratioval;

        }

        varMax[h] *= 1.1;
        if(varMin[h] < 0)varMin[h] *= 1.1;
        else varMin[h] = 0.001; //if minimum is positve, set minimum to just above 0 to remove label

        if(ratioMax[h] > 3.)ratioMax[h] = 3.;
        if(ratioMax[h] < 2.)ratioMax[h] = 2.;
        ratioMax[h] *= 1.1;

        //configurables for plotting
        float lowerPlotHeight = 0.6;

        //create two pads into one canvas
        TCanvas * theCanvas = new TCanvas(Form("theCanvas%s", leName[h].c_str()), Form("ratio and superposition of %s" , theName[h].c_str()));
        float textsize = gStyle->GetTextSize();
        TPad * pad1 = new TPad(Form("pad1%s", leName[h].c_str()), "ratio",0.0,lowerPlotHeight,1.0,1.0,0);
        TPad * pad2 = new TPad(Form("pad2%s", leName[h].c_str()), "superposition",0.0,0.0,1.0,lowerPlotHeight,0);
        pad1->Draw();
        pad2->Draw();

        //modifiy pad for main plot
        pad1->Clear();
        pad1->SetBorderSize  (0);
        pad1->SetBottomMargin(1e-6);
        pad1->SetTopMargin(pad1->GetTopMargin() / ( 1 - lowerPlotHeight) );
        pad1->cd();

        //some axis-modifications on the main plot
        TGaxis::SetExponentOffset(1e+9,1e+9,"y");//offset = pad size * 1e+7
        hRatio[h]->GetXaxis()->SetNoExponent(); //<-- spoils MaxDigits settings, so don't use it on other axis
        hRatio[h]->GetXaxis()->SetLabelSize(0.0);//don't print labels
        hRatio[h]->GetXaxis()->SetRangeUser(xLow[h], xHigh[h]);
        hRatio[h]->GetXaxis()->SetTickLength(hRatio[h]->GetXaxis()->GetTickLength()/(1-lowerPlotHeight));
        hRatio[h]->GetXaxis()->SetNdivisions(gStyle->GetNdivisions("X"));

        hRatio[h]->GetYaxis()->SetTitle("ratio (#omega / 1.0)");
        hRatio[h]->GetYaxis()->SetTitleSize(textsize/(1-lowerPlotHeight));
        hRatio[h]->GetYaxis()->SetLabelSize(textsize/(1-lowerPlotHeight));
        hRatio[h]->GetYaxis()->SetTickLength(hRatio[h]->GetYaxis()->GetTickLength());
        hRatio[h]->GetYaxis()->SetNdivisions(gStyle->GetNdivisions("Y"));
        hRatio[h]->GetYaxis()->SetTitleOffset(1.06*(1-lowerPlotHeight));
        hRatio[h]->GetYaxis()->SetRangeUser(0.5, 1.5);
        hRatio[h]->Draw("E1");

        TLine * unityline = new TLine(xLow[h], 1, xHigh[h], 1);
        unityline->SetLineStyle(2);
        unityline->SetLineColor(4);
        unityline->Draw("SAME");

        pad2->Clear();
        pad2->SetBorderSize  (0);
        pad2->SetTopMargin   (1e-6);
        pad2->SetBottomMargin(pad2->GetBottomMargin() / lowerPlotHeight );
        pad2->cd();

        TGaxis::SetExponentOffset(1e+9,1e+9,"x");//offset = pad size * 1e+7
        hNoWeight[h]->GetXaxis()->SetTitleOffset(1.05);
        hNoWeight[h]->GetXaxis()->SetTitleSize  (textsize/lowerPlotHeight);
        hNoWeight[h]->GetXaxis()->SetLabelSize  (textsize/lowerPlotHeight);
        hNoWeight[h]->GetXaxis()->SetTickLength (hRatio[h]->GetXaxis()->GetTickLength()/(lowerPlotHeight/(1-lowerPlotHeight)));
        hNoWeight[h]->GetXaxis()->SetNdivisions (gStyle->GetNdivisions("X"));
        hNoWeight[h]->GetXaxis()->SetTitle(theName[h].c_str());
        hNoWeight[h]->GetXaxis()->SetRangeUser(xLow[h], xHigh[h]);


        hNoWeight[h]->GetYaxis()->SetRangeUser(varMin[h], varMax[h]);
        hNoWeight[h]->GetYaxis()->SetTitle("events");
        hNoWeight[h]->GetYaxis()->SetLabelSize  (textsize/lowerPlotHeight);
        hNoWeight[h]->GetYaxis()->SetTitleSize  (textsize/lowerPlotHeight);
        hNoWeight[h]->GetYaxis()->SetTickLength(hRatio[h]->GetYaxis()->GetTickLength());
        hNoWeight[h]->GetYaxis()->SetNdivisions (gStyle->GetNdivisions("Y"));
        hNoWeight[h]->GetYaxis()->SetTitleOffset(1.06*lowerPlotHeight);
        hNoWeight[h]->Draw("E1");

        hWeighted[h]->SetLineColor(2);
        hWeighted[h]->SetMarkerColor(2);
        hWeighted[h]->Draw("E1SAME");

        //Legend and position...
        float LegendXposition = 0.4;
        float LegendYposition = 0.3;
        TLegend * leg = new TLegend(LegendXposition,LegendYposition,LegendXposition + 0.25, LegendYposition + 0.18);
        leg->AddEntry(hWeighted[h],Form("%sweighted signal MC",(b2Dweighted ? "2#upoint1D-" : "")), "lpe");
        leg->AddEntry(hNoWeight[h],"non-weighted signal MC", "lpe");
        leg->SetTextSize(0.04/lowerPlotHeight); // works fine
        leg->Draw("same");

        addLHCbtag(LegendXposition, LegendYposition + 0.27, "simulation", 1, 1/lowerPlotHeight);

        if (Kst2Kspiplus)theCanvas->Print(Form("%s/ComparePlots/%i_%s%s_Comparison_SignalMC%sWeights_%s%s.eps", path_to_output_KshortPiplus.c_str(), year, TheDecay.c_str(), (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), (b2Dweighted ? "2D" : ""), leName[h].c_str(), sWeight ? "" : "_nosWeight"));
        else             theCanvas->Print(Form("%s/ComparePlots/%i_%s_Comparison_SignalMC%sWeights_%s%s.eps", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), (b2Dweighted ? "2D" : ""), leName[h].c_str(), sWeight ? "" : "_nosWeight"));

        theCanvas->Close();
        delete theCanvas;

        delete hNoWeight[h];
        delete hWeighted[h];
        delete hRatio[h];

    }

    delete treeMC;

    return 1;

}

int compareAllAnglesInMC(int Run = 1){

    bool b2Dweights = true;

    std::vector<int>years = yearsVectorInt(true,false,false,Run);

    for(int y = 0; y < years.size(); y++){

        if(compareAnglesInMC(years.at(y), true, b2Dweights, false, firstMCweight) == 0){
            coutERROR("Failed to compare angles for " + to_string(years.at(y)) + (Kst2Kspiplus && SplitDDandLL ? " (DD tracks)" : ""));
            return 0;
        }

        if(Kst2Kspiplus && SplitDDandLL){
            if(compareAnglesInMC(years.at(y), true, b2Dweights, true, firstMCweight) == 0){
                coutERROR("Failed to compare angles for " + to_string(years.at(y)) + " (LL tracks)");
                return 0;
            }
        }
    }

    return 1;

}


/////////////////////////////////////////////////////
///
/// comparison of the angles in PHSP MC before and after the BDT cut
///
/////////////////////////////////////////////////////

int compareAnglesInPHSPbeforeAndAfterBDTcut(int year = 2011, bool bweighted = true, bool b2Dweighted = true, bool KshortDecayInVelo = true, std::string weightBranch = firstMCweight){

    gStyle -> SetOptStat(0);
    gROOT->SetBatch(kTRUE);
    LHCbStyle();

    bool NormalizedRatio = false;

    std::string weighzzz = "";
    if(bweighted){
      weighzzz = "weighted";
    }
    if(b2Dweighted){
      bweighted = true;
      weighzzz = "2*1D-weighted";
    }    

    //put both magnet polarities into one TChain
    TChain * treePHSP[2];
    treePHSP[0] = new TChain("DecayTreeTruthMatched");
    treePHSP[1] = new TChain("SelectionOutput");

    if(Kst2Kpluspi0Resolved){
        treePHSP[0]->Add(Form("%s/data/PHSP/%i_KplusPi0ResolvedPHSP_BDTinput.root", path_to_output_KplusPizero.c_str(), year));
        treePHSP[1]->Add(Form("%s/data/PHSP/KplusPi0Resolved_PHSP_BDToutputSelection_Run%i_%i.root", path_to_output_KplusPizero.c_str(), (year > 2012 ? 2 : 1), year));
    }
    else if(Kst2Kspiplus){
        treePHSP[0]->Add(Form("%s/data/PHSP/%i_KshortPiplusPHSP%s_BDTinput.root",  path_to_output_KshortPiplus.c_str(), year, (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "")));
        treePHSP[1]->Add(Form("%s/data/PHSP/KshortPiplus%s_PHSP_BDToutputSelection_Run%i_%i.root",  path_to_output_KshortPiplus.c_str(), (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), (year > 2012 ? 2 : 1), year));
    }

    int Nb = treePHSP[0]->GetEntries();
    int Na = treePHSP[1]->GetEntries();
    if(Nb == 0){
        std::cout << Form("[ERROR]\t\tNo events found in file data/PHSP/%i_%sPHSP%s_BDTinput.root", year, TheDecay.c_str(), (Kst2Kspiplus && SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "")) << std::endl;
        return 0;
    }
    if(Na == 0){
        std::cout << Form("[ERROR]\t\tNo events found in file data/PHSP/%s%sPHSP_BDToutputSelection_Run%i_%i.root", TheDecay.c_str(), (Kst2Kspiplus && SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), (year > 2012 ? 2 : 1), year) << std::endl;
        return 0;
    }

    double angle[3][2];//ctk, ctl, phi;
    double w[2], w2d[2];

    for(int i = 0; i < 2; i++){

      //deactivate all branches exept the one of intrest!
      treePHSP[i]->SetBranchStatus("*",0);
      treePHSP[i]->SetBranchStatus("B_plus_ThetaK",1);
      treePHSP[i]->SetBranchStatus("B_plus_ThetaL",1);
      treePHSP[i]->SetBranchStatus("B_plus_Phi",1);
      treePHSP[i]->SetBranchStatus(Form("weight_%s",weightBranch.c_str()),1);
      treePHSP[i]->SetBranchStatus(Form("weight2D_%s",weightBranch.c_str()),1);

      treePHSP[i]->SetBranchAddress("B_plus_ThetaK",&angle[0][i]);
      treePHSP[i]->SetBranchAddress("B_plus_ThetaL",&angle[1][i]);
      treePHSP[i]->SetBranchAddress("B_plus_Phi",&angle[2][i]);
      treePHSP[i]->SetBranchAddress(Form("weight_%s",weightBranch.c_str()),&w[i]);
      treePHSP[i]->SetBranchAddress(Form("weight2D_%s",weightBranch.c_str()),&w2d[i]);

    }

    //initialize histograms
    int bins = 40;//100;
    double xLow[3] = {-1., -1., -TMath::Pi()};
    double xHigh[3] = {+1., +1., +TMath::Pi()};
    std::string theName[3] = {"cos(#theta_{K})", "cos(#theta_{L})", "#phi"};
    std::string leName[3] = {"ctk", "ctl", "phi"};

    TH1D * hRatio[3];
    TH1D * hBefore[3];
    TH1D * hAfter[3];

    for(int h = 0; h < 3; h++){
        hRatio [h] = new TH1D(Form("hRatio_%s" , leName[h].c_str()), Form("Ratio of %s after/before%s", theName[h].c_str(), (bweighted ? (" ("+weighzzz+")").c_str() : "")), bins, xLow[h], xHigh[h]);
        hBefore[h] = new TH1D(Form("hBefore_%s", leName[h].c_str()), Form("%s before BDT%s", theName[h].c_str(), (bweighted ? (" ("+weighzzz+")").c_str() : "")),            bins, xLow[h], xHigh[h]);
        hAfter [h] = new TH1D(Form("hAfter_%s" , leName[h].c_str()), Form("%s after BDT%s", theName[h].c_str(), (bweighted ? (" ("+weighzzz+")").c_str() : "")),             bins, xLow[h], xHigh[h]);

        hRatio [h]->Sumw2();
        hBefore[h]->Sumw2();
        hAfter [h]->Sumw2();

    }

    //loop over events and save to histograms
    for(int i = 0; i < Na; i++){
        if(i%10000==0 && i != 0)std::cout << "Loading data event " << i << " / " << Na << std::endl;
        treePHSP[1]->GetEntry(i);
        for(int a = 0; a < 3; a++){
            if(a == 0 || a == 1){ //convert theta to cos(theta)
                angle[a][1] = TMath::Cos(angle[a][1]);
            }
            hRatio[a]->Fill(angle[a][1], bweighted ? (b2Dweighted ? w2d[1] : w[1]) : 1.);
            hAfter[a]->Fill(angle[a][1], bweighted ? (b2Dweighted ? w2d[1] : w[1]) : 1.);
        }
    }

    //loop over events and save to histograms
    for(int i = 0; i < Nb; i++){
        if(i%10000==0 && i != 0)std::cout << "Loading data event " << i << " / " << Nb << std::endl;
        treePHSP[0]->GetEntry(i);
        for(int a = 0; a < 3; a++){
            if(a == 0 || a == 1){ //convert theta to cos(theta)
                angle[a][0] = TMath::Cos(angle[a][0]);
            }
            hBefore[a]->Fill(angle[a][0], bweighted ? (b2Dweighted ? w2d[0] : w[0]) : 1.);
        }
    }

    double varMax[3]   = {-1.0e8,-1.0e8,-1.0e8};
    double varMin[3]   = {+1.0e8,+1.0e8,+1.0e8};
    double ratioMax[3] = {-1.0e8,-1.0e8,-1.0e8};
    double ratioMin[3] = {+1.0e8,+1.0e8,+1.0e8};

    double valb, vala, ratioval;
    for(int h = 0; h < 3; h++){

        if(NormalizedRatio)
          hRatio [h]->Scale(hBefore[h]->Integral()/hRatio[h]->Integral());

        //make ratio:
        hRatio[h]->Divide(hBefore[h]);

        //set correct ranges for the histograms:
        for(int bin = 1; bin <= bins; bin++){

            valb     = hBefore[h]->GetBinContent(bin);
            vala     = hAfter[h] ->GetBinContent(bin);
            ratioval = hRatio[h] ->GetBinContent(bin);

            if(varMax[h]   <= vala)    varMax[h] = vala;
            if(varMax[h]   <= valb)    varMax[h] = valb;
            if(ratioMax[h] <= ratioval)ratioMax[h] = ratioval;

            if(varMin[h]   >= vala)    varMin[h] = vala;
            if(varMin[h]   >= valb)    varMin[h] = valb;
            if(ratioMin[h] >= ratioval)ratioMin[h] = ratioval;

        }

        varMax[h] *= 1.1;
        if(varMin[h] < 0)varMin[h] *= 1.1;
        else varMin[h] = 0.001; //if minimum is positve, set minimum to just above 0 to remove label
    
        if(ratioMax[h] > 3.)ratioMax[h] = 3.;
        if(ratioMax[h] < 2.)ratioMax[h] = 2.;
        ratioMax[h] *= 1.1;

        //configurables for plotting
        float lowerPlotHeight = 0.6;

        //create two pads into one canvas
        TCanvas * theCanvas = new TCanvas(Form("theCanvas%s", leName[h].c_str()), Form("ratio and superposition of %s" , theName[h].c_str()));
        float textsize = gStyle->GetTextSize();
        TPad * pad1 = new TPad(Form("pad1%s", leName[h].c_str()), "ratio",0.0,lowerPlotHeight,1.0,1.0,0);
        TPad * pad2 = new TPad(Form("pad2%s", leName[h].c_str()), "superposition",0.0,0.0,1.0,lowerPlotHeight,0);
        pad1->Draw();
        pad2->Draw();

        //modifiy pad for main plot
        pad1->Clear();
        pad1->SetBorderSize  (0);
        pad1->SetBottomMargin(1e-6);
        pad1->SetTopMargin(pad1->GetTopMargin() / ( 1 - lowerPlotHeight) );
        pad1->cd();

        //some axis-modifications on the main plot
        TGaxis::SetExponentOffset(1e+9,1e+9,"y");//offset = pad size * 1e+7
        hRatio[h]->GetXaxis()->SetNoExponent(); //<-- spoils MaxDigits settings, so don't use it on other axis
        hRatio[h]->GetXaxis()->SetLabelSize(0.0);//don't print labels
        hRatio[h]->GetXaxis()->SetRangeUser(xLow[h], xHigh[h]);
        hRatio[h]->GetXaxis()->SetTickLength(hRatio[h]->GetXaxis()->GetTickLength()/(1-lowerPlotHeight));
        hRatio[h]->GetXaxis()->SetNdivisions(gStyle->GetNdivisions("X"));

        hRatio[h]->GetYaxis()->SetTitle("ratio");
        hRatio[h]->GetYaxis()->SetTitleSize(textsize/(1-lowerPlotHeight));
        hRatio[h]->GetYaxis()->SetLabelSize(textsize/(1-lowerPlotHeight));
        hRatio[h]->GetYaxis()->SetTickLength(hRatio[h]->GetYaxis()->GetTickLength());
        hRatio[h]->GetYaxis()->SetNdivisions(gStyle->GetNdivisions("Y"));
        hRatio[h]->GetYaxis()->SetTitleOffset(1.06*(1-lowerPlotHeight));
        if(NormalizedRatio)
          hRatio[h]->GetYaxis()->SetRangeUser(0.5, 1.5);
        else
          hRatio[h]->GetYaxis()->SetRangeUser(0.5, 1.0);
        hRatio[h]->Draw("E1");

        TLine * unityline = new TLine(xLow[h], 1, xHigh[h], 1);
        unityline->SetLineStyle(2);
        unityline->SetLineColor(4);
        if(NormalizedRatio)
          unityline->Draw("SAME");

        pad2->Clear();
        pad2->SetBorderSize  (0);
        pad2->SetTopMargin   (1e-6);
        pad2->SetBottomMargin(pad2->GetBottomMargin() / lowerPlotHeight );
        pad2->cd();

        TGaxis::SetExponentOffset(1e+9,1e+9,"x");//offset = pad size * 1e+7
        hBefore[h]->GetXaxis()->SetTitleOffset(1.05);
        hBefore[h]->GetXaxis()->SetTitleSize  (textsize/lowerPlotHeight);
        hBefore[h]->GetXaxis()->SetLabelSize  (textsize/lowerPlotHeight);
        hBefore[h]->GetXaxis()->SetTickLength (hRatio[h]->GetXaxis()->GetTickLength()/(lowerPlotHeight/(1-lowerPlotHeight)));
        hBefore[h]->GetXaxis()->SetNdivisions (gStyle->GetNdivisions("X"));
        hBefore[h]->GetXaxis()->SetTitle(theName[h].c_str());
        hBefore[h]->GetXaxis()->SetRangeUser(xLow[h], xHigh[h]);


        hBefore[h]->GetYaxis()->SetRangeUser(varMin[h], varMax[h]);
        hBefore[h]->GetYaxis()->SetTitle("events");
        hBefore[h]->GetYaxis()->SetLabelSize  (textsize/lowerPlotHeight);
        hBefore[h]->GetYaxis()->SetTitleSize  (textsize/lowerPlotHeight);
        hBefore[h]->GetYaxis()->SetTickLength(hRatio[h]->GetYaxis()->GetTickLength());
        hBefore[h]->GetYaxis()->SetNdivisions (gStyle->GetNdivisions("Y"));
        hBefore[h]->GetYaxis()->SetTitleOffset(1.06*lowerPlotHeight);
        hBefore[h]->Draw("E1");

        hAfter[h]->SetLineColor(2);
        hAfter[h]->SetMarkerColor(2);
        hAfter[h]->Draw("E1SAME");

        //Legend and position...
        float LegendXposition = 0.4;
        float LegendYposition = 0.3;
        TLegend * leg = new TLegend(LegendXposition,LegendYposition,LegendXposition + 0.25, LegendYposition + 0.18);
        leg->AddEntry(hAfter[h],"After BDT cut", "lpe");
        leg->AddEntry(hBefore[h],"Before BDT cut", "lpe");
        leg->SetTextSize(0.04/lowerPlotHeight); // works fine
        leg->Draw("same");

        addLHCbtag(LegendXposition, LegendYposition + 0.27, "simulation", 1, 1/lowerPlotHeight);

        if (Kst2Kspiplus)theCanvas->Print(Form("%s/ComparePlots/%i_%s%s_Comparison%sBeforeAndAfterBDTcut_%s.eps", path_to_output_KshortPiplus.c_str(), year, TheDecay.c_str(), (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), (b2Dweighted ? "2D" : ""), leName[h].c_str()));
        else             theCanvas->Print(Form("%s/ComparePlots/%i_%s_Comparison%sBeforeAndAfterBDTcut_%s.eps", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), (b2Dweighted ? "2D" : ""), leName[h].c_str()));

        theCanvas->Close();
        delete theCanvas;

        delete hAfter [h];
        delete hBefore[h];
        delete hRatio [h];

    }

    delete treePHSP[0];
    delete treePHSP[1];

    return 1;

}

int compareAllPHSPAnglesBeforeAndAfterBDT(int Run = 1){

    bool bWeights   = true;
    bool b2Dweights = true;

    std::vector<int>years =  yearsVectorInt(true,false,true,Run);

    for(int y = 0; y < years.size(); y++){

        if(compareAnglesInPHSPbeforeAndAfterBDTcut(years.at(y), bWeights, b2Dweights, false) == 0){
            coutERROR("Failed to compare angles for " + to_string(years.at(y)) + (Kst2Kspiplus && SplitDDandLL ? " (DD tracks)" : "") );
            return 0;
        }

        if(Kst2Kspiplus && SplitDDandLL){
            if(compareAnglesInPHSPbeforeAndAfterBDTcut(years.at(y), bWeights, b2Dweights, true) == 0){
                coutERROR("Failed to compare angles for " + to_string(years.at(y)) + " (LL tracks)" );
                return 0;
            }
        }
    }

    return 1;

}

/////////////////////////////////////////////////////
///
/// comparison of nTracks and B_plus_PT between signal and reference channel MC
///
/////////////////////////////////////////////////////

int compareNTracksAndBplusPT(int year = 2011, bool KshortDecayInVelo = true){

    gROOT->SetBatch(kTRUE);
    gStyle -> SetOptStat(0);
    LHCbStyle();

    bool NormalizedRatio = true;

    if(year > 2012){
      std::cout << "No Reference MC for Run II available. Abort!" << std::endl;
      return 0;
    }

    //put both magnet polarities into one TChain
    TChain * treeMC[2];
    treeMC[0] = new TChain("DecayTreeTruthMatched");
    treeMC[1] = new TChain("DecayTreeTruthMatched");

    if(Kst2Kpluspi0Resolved){
        treeMC[0]->Add(Form("%s/data/MC/%i_KplusPi0Resolved_BDTinput.root", path_to_output_KplusPizero.c_str(), year));
        treeMC[1]->Add(Form("%s/data/MC/%i_RefKplusPi0Resolved_BDTinput.root", path_to_output_KplusPizero.c_str(), year));
    }
    else if(Kst2Kspiplus){
        treeMC[0]->Add(Form("%s/data/MC/%i_KshortPiplus%s_BDTinput.root",  path_to_output_KshortPiplus.c_str(), year, (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "")));
        treeMC[1]->Add(Form("%s/data/MC/%i_KshortPiplusRef%s_BDTinput.root",  path_to_output_KshortPiplus.c_str(), year, (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "")));
    }

    int N[2];
    N[0] = treeMC[0]->GetEntries();
    N[1] = treeMC[1]->GetEntries();
    if(N[0] == 0){
        std::cout << Form("[ERROR]\t\tNo events found in file data/MC/%i_%s%s_BDTinput.root", year, TheDecay.c_str(), (Kst2Kspiplus && SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "")) << std::endl;
        return 0;
    }
    if(N[1] == 0){
        std::cout << Form("[ERROR]\t\tNo events found in file data/MC/%i_%sRef%s_BDTinput.root", year, TheDecay.c_str(), (Kst2Kspiplus && SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "")) << std::endl;
        return 0;
    }

    const int nVars = 2;

    double var[nVars][2];//nTracks, B_plus_PT;
    int varNtracks[2];
    std::string theName[nVars] = {"nTracks", "p_{T}(B^{+})"};
    std::string leName[nVars]  = {"nTracks", "B_plus_PT"};
    double xLow[nVars]  = {-0.5 , 0.};
    double xHigh[nVars] = {599.5, 60000.};

    for(int i = 0; i < 2; i++){

      //deactivate all branches exept the one of intrest!
      treeMC[i]->SetBranchStatus("*",0);
      treeMC[i]->SetBranchStatus("nTracks",1);
      treeMC[i]->SetBranchStatus(UseDTF ? "B_plus_PT_DTF" : "B_plus_PT",1);

      treeMC[i]->SetBranchAddress("nTracks",&varNtracks[i]);
      treeMC[i]->SetBranchAddress(UseDTF ? "B_plus_PT_DTF" : "B_plus_PT",&var[1][i]);

    }

    //initialize histograms
    int bins = 100;
    TH1D * hRatio[nVars];
    TH1D * hSignal[nVars];
    TH1D * hRefere[nVars];

    for(int h = 0; h < nVars; h++){
        hRatio [h] = new TH1D(Form("hRatio_%s" , leName[h].c_str()), Form("Ratio of %s signal/ref", theName[h].c_str()), bins, xLow[h], xHigh[h]);
        hSignal[h] = new TH1D(Form("hSignal_%s", leName[h].c_str()), Form("%s (Signal)", theName[h].c_str()), bins, xLow[h], xHigh[h]);
        hRefere[h] = new TH1D(Form("hRefere_%s", leName[h].c_str()), Form("%s (Ref)"   , theName[h].c_str()), bins, xLow[h], xHigh[h]);

        hRatio [h]->Sumw2();
        hSignal[h]->Sumw2();
        hRefere[h]->Sumw2();
    }

    //loop over events and save to histograms
    for(int n = 0; n < 2; n++){
      for(int i = 0; i < N[n]; i++){
        if(i%1000==0 && i != 0)std::cout << "Loading data event " << i << " / " << N[n] << std::endl;
        treeMC[n]->GetEntry(i);
        for(int v = 0; v < nVars; v++){
          if(v == 0){ //use int link to variable (only nTracks)
            if(n == 0){
              hRatio [v]->Fill(varNtracks[n], 1.);
              hSignal[v]->Fill(varNtracks[n], 1.);
            }
            else{
              hRefere[v]->Fill(varNtracks[n], 1.);
            }
          }
          else{ //use double link to variable
            if(n == 0){
              hRatio [v]->Fill(var[v][n], 1.);
              hSignal[v]->Fill(var[v][n], 1.);
            }
            else{
              hRefere[v]->Fill(var[v][n], 1.);
            }
          }
        }
      }
    }

    double varMax[3]   = {-1.0e8,-1.0e8,-1.0e8};
    double varMin[3]   = {+1.0e8,+1.0e8,+1.0e8};
    double ratioMax[3] = {-1.0e8,-1.0e8,-1.0e8};
    double ratioMin[3] = {+1.0e8,+1.0e8,+1.0e8};

    double valb, vala, ratioval;
    for(int h = 0; h < nVars; h++){

        if(NormalizedRatio){
          hSignal[h]->Scale(1./hSignal[h]->Integral());
          hRefere[h]->Scale(1./hRefere[h]->Integral());
          hRatio [h]->Scale(1./hRatio[h] ->Integral());
        }

        //make ratio:
        hRatio[h]->Divide(hRefere[h]);

        //set correct ranges for the histograms:
        for(int bin = 1; bin <= bins; bin++){

            valb     = hRefere[h]->GetBinContent(bin);
            vala     = hSignal[h]->GetBinContent(bin);
            ratioval = hRatio[h] ->GetBinContent(bin);

            if(varMax[h]   <= vala)    varMax[h] = vala;
            if(varMax[h]   <= valb)    varMax[h] = valb;
            if(ratioMax[h] <= ratioval)ratioMax[h] = ratioval;

            if(varMin[h]   >= vala)    varMin[h] = vala;
            if(varMin[h]   >= valb)    varMin[h] = valb;
            if(ratioMin[h] >= ratioval)ratioMin[h] = ratioval;

        }

        varMax[h] *= 1.1;
        if(varMin[h] < 0)varMin[h] *= 1.1;
        else varMin[h] = 0.001; //if minimum is positve, set minimum to just above 0 to remove label
    
        if(ratioMax[h] > 3.)ratioMax[h] = 3.;
        if(ratioMax[h] < 2.)ratioMax[h] = 2.;
        ratioMax[h] *= 1.1;

        //configurables for plotting
        float lowerPlotHeight = 0.6;

        //create two pads into one canvas
        TCanvas * theCanvas = new TCanvas(Form("theCanvas%s", leName[h].c_str()), Form("ratio and superposition of %s" , theName[h].c_str()));
        float textsize = gStyle->GetTextSize();
        TPad * pad1 = new TPad(Form("pad1%s", leName[h].c_str()), "ratio",0.0,lowerPlotHeight,1.0,1.0,0);
        TPad * pad2 = new TPad(Form("pad2%s", leName[h].c_str()), "superposition",0.0,0.0,1.0,lowerPlotHeight,0);
        pad1->Draw();
        pad2->Draw();

        //modifiy pad for main plot
        pad1->Clear();
        pad1->SetBorderSize  (0);
        pad1->SetBottomMargin(1e-6);
        pad1->SetTopMargin(pad1->GetTopMargin() / ( 1 - lowerPlotHeight) );
        pad1->cd();

        //some axis-modifications on the main plot
        TGaxis::SetExponentOffset(1e+9,1e+9,"y");//offset = pad size * 1e+7
        hRatio[h]->GetXaxis()->SetNoExponent(); //<-- spoils MaxDigits settings, so don't use it on other axis
        hRatio[h]->GetXaxis()->SetLabelSize(0.0);//don't print labels
        hRatio[h]->GetXaxis()->SetRangeUser(xLow[h], xHigh[h]);
        hRatio[h]->GetXaxis()->SetTickLength(hRatio[h]->GetXaxis()->GetTickLength()/(1-lowerPlotHeight));
        hRatio[h]->GetXaxis()->SetNdivisions(gStyle->GetNdivisions("X"));

        hRatio[h]->GetYaxis()->SetTitle("ratio");
        hRatio[h]->GetYaxis()->SetTitleSize(textsize/(1-lowerPlotHeight));
        hRatio[h]->GetYaxis()->SetLabelSize(textsize/(1-lowerPlotHeight));
        hRatio[h]->GetYaxis()->SetTickLength(hRatio[h]->GetYaxis()->GetTickLength());
        hRatio[h]->GetYaxis()->SetNdivisions(gStyle->GetNdivisions("Y"));
        hRatio[h]->GetYaxis()->SetTitleOffset(1.06*(1-lowerPlotHeight));
        if(NormalizedRatio)
          hRatio[h]->GetYaxis()->SetRangeUser(0.5, 1.5);
        else
          hRatio[h]->GetYaxis()->SetRangeUser(0.5, 1.0);
        hRatio[h]->Draw("E1");

        TLine * unityline = new TLine(xLow[h], 1, xHigh[h], 1);
        unityline->SetLineStyle(2);
        unityline->SetLineColor(4);
        if(NormalizedRatio)
          unityline->Draw("SAME");

        pad2->Clear();
        pad2->SetBorderSize  (0);
        pad2->SetTopMargin   (1e-6);
        pad2->SetBottomMargin(pad2->GetBottomMargin() / lowerPlotHeight );
        pad2->cd();

        TGaxis::SetExponentOffset(1e+9,1e+9,"x");//offset = pad size * 1e+7
        hRefere[h]->GetXaxis()->SetTitleOffset(1.05);
        hRefere[h]->GetXaxis()->SetTitleSize  (textsize/lowerPlotHeight);
        hRefere[h]->GetXaxis()->SetLabelSize  (textsize/lowerPlotHeight);
        hRefere[h]->GetXaxis()->SetTickLength (hRatio[h]->GetXaxis()->GetTickLength()/(lowerPlotHeight/(1-lowerPlotHeight)));
        hRefere[h]->GetXaxis()->SetNdivisions (gStyle->GetNdivisions("X"));
        hRefere[h]->GetXaxis()->SetTitle(theName[h].c_str());
        hRefere[h]->GetXaxis()->SetRangeUser(xLow[h], xHigh[h]);


        hRefere[h]->GetYaxis()->SetRangeUser(varMin[h], varMax[h]);
        hRefere[h]->GetYaxis()->SetTitle("events");
        hRefere[h]->GetYaxis()->SetLabelSize  (textsize/lowerPlotHeight);
        hRefere[h]->GetYaxis()->SetTitleSize  (textsize/lowerPlotHeight);
        hRefere[h]->GetYaxis()->SetTickLength(hRatio[h]->GetYaxis()->GetTickLength());
        hRefere[h]->GetYaxis()->SetNdivisions (gStyle->GetNdivisions("Y"));
        hRefere[h]->GetYaxis()->SetTitleOffset(1.06*lowerPlotHeight);
        hRefere[h]->Draw("E1");

        hSignal[h]->SetLineColor(2);
        hSignal[h]->SetMarkerColor(2);
        hSignal[h]->Draw("E1SAME");

        //Legend and position...
        float LegendXposition = 0.65;
        float LegendYposition = 0.35;
        TLegend * leg = new TLegend(LegendXposition,LegendYposition,LegendXposition + 0.25, LegendYposition + 0.18);
        leg->AddEntry(hSignal[h],"Signal", "lpe");
        leg->AddEntry(hRefere[h],"Referenz", "lpe");
        leg->SetTextSize(0.04/lowerPlotHeight); // works fine
        leg->Draw("same");

        addLHCbtag(LegendXposition, LegendYposition + 0.27, "simulation", 1, 1/lowerPlotHeight);

        if (Kst2Kspiplus)theCanvas->Print(Form("%s/ComparePlots/%i_%s%s_Comparison_Signal_vs_Ref_%s.eps", path_to_output_KshortPiplus.c_str(), year, TheDecay.c_str(), (SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : ""), leName[h].c_str()));
        else             theCanvas->Print(Form("%s/ComparePlots/%i_%s_Comparison_Signal_vs_Ref_%s.eps", path_to_output_KplusPizero.c_str(), year, TheDecay.c_str(), leName[h].c_str()));

        theCanvas->Close();
        delete theCanvas;

        delete hSignal [h];
        delete hRefere[h];
        delete hRatio [h];

    }

    delete treeMC[0];
    delete treeMC[1];

    std::cout << "ALL GOOD" << std::endl;

    return 1;

}

int compareAllNtracksAndBplusPT(int Run = 1){

    std::vector<int>years =  yearsVectorInt(true,false,false,Run);

    for(int y = 0; y < years.size(); y++){

        if(compareNTracksAndBplusPT(years.at(y), false) == 0){
            coutERROR("Failed to compare nTracks and B_plus_PT for " + to_string(years.at(y)) + (Kst2Kspiplus && SplitDDandLL ? " (DD tracks)" : "") );
            return 0;
        }

        if(Kst2Kspiplus && SplitDDandLL){
            if(compareNTracksAndBplusPT(years.at(y), true) == 0){
                coutERROR("Failed to compare nTracks and B_plus_PT for " + to_string(years.at(y)) + " (LL tracks)");
                return 0;
            }
        }
    }

    return 1;

}

/////////////////////////////////////////////////////
///
/// comparison Kplus and Kshort
///
/////////////////////////////////////////////////////

int compareAllKplusKshort(bool sWeightKplus = false,bool sWeightKshort = true, bool bWeighted = true, bool b2DWeighted = false, int Run = 1, bool KshortDecayInVelo = true, std::string weightBranch = "nTracks"){
    checkRun(Run);

    bool save2file = true;

    int nYear = (Run == 1 ? 2011 : 2015); //#TODO somehow 2011 throws out a segfault

    while(nYear < (Run == 1 ? 2013 : 2018)){

       //Global
       compareVariablesKplusKshort(nYear, "nTracks",                                sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 0, 0, save2file, KshortDecayInVelo, weightBranch);
       compareVariablesKplusKshort(nYear, "nLongTracks",                            sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 0, 0, save2file, KshortDecayInVelo, weightBranch);
       compareVariablesKplusKshort(nYear, "nVeloTracks",                            sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 0, 0, save2file, KshortDecayInVelo, weightBranch);
       compareVariablesKplusKshort(nYear, "nTTracks",                               sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 0, 0, save2file, KshortDecayInVelo, weightBranch);
       compareVariablesKplusKshort(nYear, "nUpstreamTracks",                        sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 0, 0, save2file, KshortDecayInVelo, weightBranch);
       compareVariablesKplusKshort(nYear, "nDownstreamTracks",                      sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 0, 0, save2file, KshortDecayInVelo, weightBranch);
       ///B+
       compareVariablesKplusKshort(nYear, (UseDTF?"B_plus_PT_DTF":"B_plus_PT"),     sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 0, 0, save2file, KshortDecayInVelo, weightBranch);
       compareVariablesKplusKshort(nYear, "B_plus_DIRA_OWNPV",                      sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 0, 1, save2file, KshortDecayInVelo, weightBranch);
       compareVariablesKplusKshort(nYear, "B_plus_OWNPV_CHI2",                      sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 1, 0, save2file, KshortDecayInVelo, weightBranch);
       compareVariablesKplusKshort(nYear, "B_plus_FD_OWNPV",                        sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 0, 0, save2file, KshortDecayInVelo, weightBranch);
       compareVariablesKplusKshort(nYear, "B_plus_IP_OWNPV",                        sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 0, 0, save2file, KshortDecayInVelo, weightBranch);
       compareVariablesKplusKshort(nYear, "B_plus_IPCHI2_OWNPV",                    sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 1, 0, save2file, KshortDecayInVelo, weightBranch);
       compareVariablesKplusKshort(nYear, (UseDTF ? "B_plus_ETA_DTF":"B_plus_ETA"), sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 0, 0, save2file, KshortDecayInVelo, weightBranch);
       /// K*
       compareVariablesKplusKshort(nYear, (UseDTF ? "K_star_plus_PT_DTF":"K_star_plus_PT"),    sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 0, 0, save2file, KshortDecayInVelo, weightBranch);
       compareVariablesKplusKshort(nYear, (UseDTF ? "K_star_plus_ETA_DTF":"K_star_plus_ETA"),  sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 0, 0, save2file, KshortDecayInVelo, weightBranch);
       compareVariablesKplusKshort(nYear, "K_star_plus_IPCHI2_OWNPV",                          sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 0, 0, save2file, KshortDecayInVelo, weightBranch);
       /// mu
       compareVariablesKplusKshort(nYear, "mu_plus_IPCHI2_OWNPV",                   sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 1, 0, save2file, KshortDecayInVelo, weightBranch);
       compareVariablesKplusKshort(nYear, "mu_minus_IPCHI2_OWNPV",                  sWeightKplus, sWeightKshort, bWeighted, b2DWeighted, 1, 0, save2file, KshortDecayInVelo, weightBranch);

       nYear++;

    }

    return 1;
}

int compareAllKplusAllRunsAndWeights(bool bWeighted = true, bool b2DWeighted = false){
    if (compareAllKplusKshort (true,  true,  bWeighted, b2DWeighted,  1, true)  ==0) return 0;
    if (compareAllKplusKshort (true,  true,  bWeighted, b2DWeighted,  1, false) ==0) return 0;
   // if (compareAllKplusKshort (true,  false, bWeighted, b2DWeighted,  1)==0) return 0;
   // if (compareAllKplusKshort (false, true,  bWeighted, b2DWeighted,  1)==0) return 0;
    if (compareAllKplusKshort (false, false, bWeighted, b2DWeighted,  1, true)  ==0) return 0;
    if (compareAllKplusKshort (false, false, bWeighted, b2DWeighted,  1, false) ==0) return 0;
    if (compareAllKplusKshort (true,  true,  bWeighted, b2DWeighted,  2)==0) return 0;
    if (compareAllKplusKshort (true,  true,  bWeighted, b2DWeighted,  2)==0) return 0;
   // if (compareAllKplusKshort (true,  false, bWeighted, b2DWeighted,  2)==0) return 0;
   // if (compareAllKplusKshort (false, true,  bWeighted, b2DWeighted,  2)==0) return 0;
    if (compareAllKplusKshort (false, false, bWeighted, b2DWeighted,  2, true)  ==0) return 0;
    if (compareAllKplusKshort (false, false, bWeighted, b2DWeighted,  2, false) ==0) return 0;
    return 1;
}

