//Definition of paths used for the Selection of the B+->K*+(K+pi0)mumu analysis
//Renata Kopecna

#ifndef PATHS_HPP
#define PATHS_HPP

#include "GlobalFunctions.hh"
#include "Utils.hpp"

////////////////////////////////////////////////////////////////////////
///
///         FILE NAMES
///
///     Function returning the string with adress to an input file,
///     either stripped or preselected for all years, polarities and data/MC/MCref/PHSP
///
/// GetInputFile(int/string year, string magnet, bool preSelected, bool MC,
///             bool ReferenceChannel, bool PHSP, bool smallSample)
///         Return fileName of selected options
///
///
/// GetInputFileBkg(int/string year, string magnet, bool preSelected,
///             bool ReferenceChannel, bool B0, bool K1, bool Inc)
///
///         Return fileName of selected options for PiZero background study
///
///
/// GetHistosFile(int/string year, string magnet, bool preSelected, bool MC,
///             bool ReferenceChannel, bool PHSP, bool smallSample)
///
///         Return histogram fileName of selected options
///
///
/// GetHistosFileBkg(int/string year, string magnet, bool preSelected,
///             bool ReferenceChannel, bool B0, bool K1, bool Inc)
///
///         Return histogram fileName of selected options for PiZero background study
///
///
/// GetBDTinputFile(int/string year, bool MC,
///                 bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo)
///
///         Return ROOTfile used as BDT input
///
///
/// GetBDToutputFile([int/string year,] int Run, bool Selection, bool MC,
///                 bool ReferenceChannel, bool PHSP, bool SplitInQ2, bool UseLowQ2Range)
///
///         Return ROOTfile used as BDT output
///
///
/// GetControlPlots(string year, bool ReferenceChannel, bool PHSP,bool KshortDecayInVelo, bool sWeightUse, int canvas)
///     Returns name of control plots for reweighting;
///     case canvas = 1: Distributions
///     case canvas = 2: firstMCweight
///     case canvas = 3: seconMCweight
///     case canvas = 4: weight Correlation
///
///string GetMassFitFile(year, magnet, Run,
///                      MC, Preselected, TM,
///                      UseOnlyJpsiEvents, UseOnlyMuMuEvents,
///                      GetShapeFromMC, SignalType, BckGndType, ConstrainParameters,
///                      KshortDecaysInVelo, UseLowQ2Range,
///                      TMVAcut,  randomSubset,
///                      fixedMassRegion, yieldOverFullRange)
///
///     returns the path of the MassFitFile based on the paramters
///
///     Overloaded with a simle version for quickFit and basic fits
///
///string GetMassFitFile(year, magnet, Run,
///                      Preselected, TM,
///                      UseOnlyJpsiEvents, UseOnlyMuMuEvents,
///                      GetShapeFromMC, SignalType, BckGndType, ConstrainParameters,
///                      KshortDecaysInVelo, UseLowQ2Range,
///                      TMVAcut,
///                      fixedMassRegion)
///     returns the path of MassFit files used for estimating efficiencies
///     based on GetMassFitFile
///
///
///string GetEfficiencyFile(effType , year, string, Run,
///                         UseOnlyJpsiEvents, UseOnlyMuMuEvents,
///                         KshortDecayInVelo, UseLowQ2Range,
///                         useFancyFit)
///
///     returns path to the file where efficiency information is stored
///
///     Overloaded with versions without run/year
///
/// string GetBDTScanFile(year, string, Run,
///                       KshortDecayInVelo, UseLowQ2Range,
///                       useFancyFit)
///
///     returns path to the file where BDT cut scanns are stored
///
///
////////////////////////////////////////////////////////////////////////

//Forward declarations from Utils.hpp
string correct_magnet_string(string magnet);
bool checkMC(bool &MC, bool ReferenceChannel, bool PHSP, bool mutuallyExclusive);
bool checkQ2Range(bool UseOnlyJpsi, bool UseOnlyMuMu);
bool checkTM(bool MC, bool &TM, bool &nonTM, bool Preselected);
bool checkKshort(bool &KshortDecaysInVelo);
bool checkRefYear(string year);
string getTMtag(string customTMbranch);
string getTMtag(string customTMbranch, bool gammaTM);

//get address of stripped data
string getOriginalFiles(string year, string magnet, bool MC, bool ReferenceChannel, bool PHSP, bool smallSample){
    string path = path_to_data + "/data/";
    string yearMag = year + magnet;
    string subDecay = Kst2Kspiplus ? "KshortPiplus" :"KplusPi0" ;

    if(!MC) return path + yearMag+ "/*B2Kstmumu*" + string(smallSample ? "13" : "") + ".root";
    else{
        yearMag = subDecay + "/" + yearMag;
        string folder = "MC/" + string(ReferenceChannel ? "Ref" : "");
        if (PHSP) folder = "PHSP/";
        string name = ReferenceChannel ? "/*B2KstJpsi" : "/*B2Kstmumu";
        return path + folder + yearMag + name+ string(UsePIDgen ? "PIDgen" : "") + string(smallSample ? "_0" : "_*")+".root";
    }
}

//Overloaded in case year is int or string
string GetInputFile(string year, string magnet, bool preSelected, bool MC, bool ReferenceChannel, bool PHSP, bool smallSample){

    //sanity checks
    if (!checkMC(MC,ReferenceChannel,PHSP,true)) return "";
    magnet = correct_magnet_string(magnet);
    if (preSelected && smallSample) smallSample = false;

    string subDecay = Kst2Kspiplus ? "KshortPiplus" : "KplusPi0Resolved";
    string yearMag = year + magnet;
    string name = Kst2Kspiplus ? "_piplus" : (Kst2Kpluspi0Resolved ? "_pi0Resolved" : "_pi0Merged");
    
    string folder = "/Tuples/" + string(ReferenceChannel ? "RefMC" : "MC");
    if (PHSP) folder = "/Tuples/PHSP/";

    if (!preSelected) return getOriginalFiles(year,magnet,MC,ReferenceChannel,PHSP,smallSample);
    else{ //get address of preselected data
        // Kst2Kpluspi0Resolved case
        if(!MC)  return thePath + "/Tuples/Data/" + yearMag + "/" + yearMag + name + ".root";
        else     return thePath + folder + "/" + yearMag + "/" + yearMag + name + ".root";
    }

    coutERROR("Something when wrong, returning and empty string.");
    return "";

}
string GetInputFile(int year, string magnet, bool preSelected, bool MC, bool ReferenceChannel, bool PHSP, bool smallSample){
    return GetInputFile(std::to_string(year), magnet, preSelected, MC, ReferenceChannel, PHSP, smallSample);
}

string GetInputFileBkg(string year, string magnet, bool preSelected, bool ReferenceChannel, bool B0, bool K1, bool Inc){

    //sanity checks
    if (B0+K1+Inc != 1){
        cout << B0+K1+Inc << endl;
        coutERROR("Chose only one from B0, K1 and Inclusive samples!");
        return "";  //select precisely one!
    }
    if (magnet == "Down") magnet = "down";
    if (magnet == "Up") magnet = "up";

    if (!preSelected){
        if(B0){
            if(ReferenceChannel) return path_to_output_KplusPizero + "/Tuples/MC/BackgroundSamples/B0toKstJpsi/" + year + magnet + "/*B0toKstJpsi*.root";
            else                 return path_to_output_KplusPizero + "/Tuples/MC/BackgroundSamples/B0toKstMuMu/" + year + magnet + "/*B0toKstMuMu*.root";
        }
        else if(K1){
            if(ReferenceChannel) return path_to_output_KplusPizero + "/Tuples/MC/BackgroundSamples/BtoK1Jpsi/" + year + magnet + "/*BtoK1Jpsi*.root";
            else                 return path_to_output_KplusPizero + "/Tuples/MC/BackgroundSamples/BtoK1MuMu/" + year + magnet + "/*BtoK1MuMu*.root";
        }
        else if(Inc){
            if(ReferenceChannel) return path_to_output_KplusPizero + "/Tuples/MC/BackgroundSamples/BtoXJpsi/" + year + magnet + "/*BtoXJpsi*.root";
            else                 return path_to_output_KplusPizero + "/Tuples/MC/BackgroundSamples/BtoXMuMu/" + year + magnet + "/*BtoXMuMu*.root";
        }
    }
    else {
        if(B0){
            if(ReferenceChannel) return path_to_output_KplusPizero + "/Tuples/MC/BackgroundSamples/B0toKstJpsi/" + year + magnet + "/" + year + magnet + "_pi0Resolved.root";
            else                 return path_to_output_KplusPizero + "/Tuples/MC/BackgroundSamples/B0toKstMuMu/" + year + magnet + "/" + year + magnet + "_pi0Resolved.root";
        }
        else if(K1){
            if(ReferenceChannel) return path_to_output_KplusPizero + "/Tuples/MC/BackgroundSamples/BtoK1Jpsi/" + year + magnet + "/" + year + magnet + "_pi0Resolved.root";
            else                 return path_to_output_KplusPizero + "/Tuples/MC/BackgroundSamples/BtoK1MuMu/" + year + magnet + "/" + year + magnet + "_pi0Resolved.root";
        }
        else if(Inc){
            if(ReferenceChannel) return path_to_output_KplusPizero + "/Tuples/MC/BackgroundSamples/BtoXJpsi/" + year + magnet + "/" + year + magnet + "_pi0Resolved.root";
            else                 return path_to_output_KplusPizero + "/Tuples/MC/BackgroundSamples/BtoXMuMu/" + year + magnet + "/" + year + magnet + "_pi0Resolved.root";
        }
    }

    return "";

}
string GetInputFileBkg(int year, string magnet, bool preSelected, bool ReferenceChannel,  bool B0, bool K1, bool Inc){

  return GetInputFileBkg(std::to_string(year), magnet, preSelected, ReferenceChannel, B0, K1, Inc);

}

string GetInputFile(string year, string magnet, bool preSelected, bool MC, bool ReferenceChannel, bool PHSP,  bool B0, bool K1, bool Inc, bool smallSample){
    if (B0 || K1 || Inc)
        return GetInputFileBkg(year, magnet, preSelected,  ReferenceChannel, B0, K1, Inc);
    else return GetInputFile(year, magnet, preSelected, MC,  ReferenceChannel, PHSP, smallSample);
}

string GetHistosFile(string year, string magnet, bool MC, bool ReferenceChannel, bool PHSP, bool smallSample){
    std::string inputName = GetInputFile(year, magnet, true, MC, ReferenceChannel, PHSP, smallSample);
    smallSample ? replace(inputName, "_small.root", "_histos_small.root") : replace(inputName, ".root", "_histos.root");
    return inputName;
}
string GetHistosFile(int year, string magnet, bool MC, bool ReferenceChannel, bool PHSP, bool smallSample){
    return GetHistosFile(std::to_string(year), magnet, MC, ReferenceChannel, PHSP, smallSample);
}

string GetHistosFileBkg(string year, string magnet, bool ReferenceChannel,  bool B0, bool K1, bool Inc){
    std::string inputName = GetInputFileBkg(year,magnet,true,ReferenceChannel,B0, K1, Inc);
    smallSample ? replace(inputName, "_small.root", "_histos_small.root") : replace(inputName, ".root", "_histos.root");
    return inputName;
}
string GetHistosFileBkg(int year, string magnet, bool ReferenceChannel,  bool B0, bool K1, bool Inc){
    return GetHistosFileBkg(std::to_string(year), magnet, ReferenceChannel, B0, K1, Inc);
}

////////////////////////////////////////////////////////////////////////
///
///         Generator level files
///
////////////////////////////////////////////////////////////////////////
string GetGenLevelFile(bool ReferenceChannel, bool PHSP){ //TODO
    string tag = string(ReferenceChannel ? "_RefChan" : "") + string(PHSP ? "_PHSP" : "");
    return thePath + string(PHSP ? "/Tuples/PHSP/EvtGen/" : "/Tuples/MC/EvtGen/") + "MCTruth" + tag + ".root";
}

////////////////////////////////////////////////////////////////////////
///
///         BDT files
///
////////////////////////////////////////////////////////////////////////
string GetBDTinputFile(string year, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo){

    //sanity checks
    if (PHSP) MC = true;  //if PHSP, set MC to true
                          //Carefull! Reference channel can be also in data, when reweighted by RefChannel
    string subDecay = Kst2Kspiplus ? "KshortPiplus" : "KplusPi0Resolved";

    //get address of preselected data
    string trackType = SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "";
    string folder    = MC ? string(PHSP ? "/Tuples/PHSP/" : "/Tuples/MC/") : "/Tuples/Data/";
    string tag       = string(ReferenceChannel ? "_Ref" : "_") + string(PHSP ? "PHSP" : "");

    return thePath + folder + year + tag + subDecay + trackType + "_BDTinput.root";

}
string GetBDTinputFile(int year, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo){
    return GetBDTinputFile(to_string(year),MC,ReferenceChannel,PHSP, KshortDecayInVelo);
}

//This file constains the BDTresponse branch. It is the output of the TMVAClassApp file. Does not contain any cut to the BDTresponse yet
string GetBDToutputFile(string year, int Run, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool UseLowQ2Range, bool reweighted){

    //sanity checks
    if (PHSP) MC = true; //if PHSP, set MC to true
                         // Carefull! Reference channel can be also in data, when reweighted by RefChannel

    if (MC && ReferenceChannel && !checkRefYear(year)) return "";

    string subDecay = Kst2Kspiplus ? "KshortPiplus" : "KplusPi0Resolved";
    if (!SplitInQ2 && UseLowQ2Range)  UseLowQ2Range = false; //Cannot use lowQ2 if it's not split

    //get address of BTD input data
    string stringSplitInQ2 = SplitInQ2? (UseLowQ2Range ? "_lowQ2" : "_highQ2") : "";

    //DD or LL track type string
    string trackType = SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "";

    string reweight = (MC && reweighted) ? "_withTMeffWeights" : "";
    string runYear = to_string(Run) + (year == "-1" ? "" : string("_" + year));
    //Set folder and tags correctly
    string folder    = MC ? string(PHSP ? "/Tuples/PHSP/" : "/Tuples/MC/") : "/Tuples/Data/";
    string tag       = PHSP ? "_PHSP" : (string(ReferenceChannel ? "_Ref" : "_") + string(MC ? "MC" : ""));

    return thePath + folder + subDecay + trackType + tag + "_BDToutput_Run" + runYear+ stringSplitInQ2+reweight+".root";

}
string GetBDToutputFile(int year, int Run, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool UseLowQ2Range, bool reweighted){
    return GetBDToutputFile(std::to_string(year), Run,MC,ReferenceChannel,PHSP,KshortDecayInVelo,UseLowQ2Range, reweighted);
}
string GetBDToutputFile(int Run, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool UseLowQ2Range, bool reweighted){
    return GetBDToutputFile(-1,Run,MC,ReferenceChannel,PHSP,KshortDecayInVelo,UseLowQ2Range, reweighted);
}

//this one is used in MVA.cpp to save the configuration of the TMVA
string GetBDTConfigFile(bool SplitYears, int year, int Run, bool KShortDecaysInVelo, int nConfiguration, bool UseLowQ2Range, string customTMbranch, bool gammaTM){

    string yr = string(SplitYears ? to_string(year) : "") ;
    string rn = string(SplitYears ? "" : string("_Run"+to_string(Run)));
    string KshortTag = string(SplitDDandLL ? (string(KShortDecaysInVelo ? "_LL" : "_DD")) : "");
    string q2Split = string(SplitInQ2 ? string(UseLowQ2Range ? "_lowQ2" : "_highQ2") : "");

    return thePath + "/Config/BDTout_" + yr + "_B2Kstmumu_" + TheDecay + q2Split + KshortTag + "_Config_" + to_string(nConfiguration) + rn + ".root" ;
}

////////////////////////////////////////////////////////////////////////
///
///         Final selection files
///
////////////////////////////////////////////////////////////////////////

//After the cut is applied, these files contain the final selection
string GetFinalOutputFile(string year, int Run, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool UseLowQ2Range){

    std::string output = GetBDToutputFile(stoi(year),Run,MC,ReferenceChannel,PHSP,KshortDecayInVelo,UseLowQ2Range,false);
    replace(output, "BDToutput", "BDToutputSelection");

    return output;

}
string GetFinalOutputFile(int year, int Run, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool UseLowQ2Range){
    return GetFinalOutputFile(std::to_string(year), Run, MC, ReferenceChannel, PHSP, KshortDecayInVelo, UseLowQ2Range);
}
string GetFinalOutputFile(int Run, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool UseLowQ2Range){
    return GetFinalOutputFile(-1, Run, MC, ReferenceChannel, PHSP, KshortDecayInVelo, UseLowQ2Range);
}


////////////////////////////////////////////////////////////////////////
///
///         Mass Fit files
///
////////////////////////////////////////////////////////////////////////
//Mass fit files
//Define path names outside fo functions; it is useful when one needs to access the information inside the canvas/rootfile, especially for the Bmass
string GetControlPlots(string year, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo, bool sWeightUse, int canvas){

    string trackType = SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "";

    std::string appendix;
    if ((canvas == 1 || canvas == 4) && (PHSP || ReferenceChannel))
        return "";
        // no need to reprint the nTrack distribution of data in the case of PHSP or RefChannel reweighting
         //save correlation plot p_T(B):nTracks (data tuple) only if Signal MC

    if (canvas == 2 || canvas == 3 ){
        if(ReferenceChannel)appendix.append("Ref");
        else if(PHSP)       appendix.append("PHSP");
        else                appendix.append("MC");
    }

    if (sWeightUse == false) appendix.append("_nosWeight");

    string canvasName = "";

    switch(canvas) {
        case 1 : canvasName = "_" + firstMCweight + "Distributions";
            break;
        case 2 :canvasName = "_" + firstMCweight + "Weights_";
            break;
        case 3 :canvasName = "_" + seconMCweight + "Weights_";
            break;
        case 4 :canvasName = "_" + firstMCweight + "_" + seconMCweight + "_Correlation";
            break;
    }

    return thePath + "/MassFits/weightPlots/" + year + "_" + TheDecay + trackType+ canvasName + appendix + "_" + ".root";

}


string GetMassFitFile(std::string year, string magnet, int Run,
                      bool MC,  bool Preselected, bool TM, bool PHSP, //input/output file selection
                      bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents,           //signal/reference
                      bool GetShapeFromMC, string SignalType, string BckGndType, bool ConstrainParameters, //shape from MC?
                      bool KshortDecaysInVelo, bool UseLowQ2Range, //LL/DD?    // q2 range
                      Double_t TMVAcut,  int randomSubset,      //TMVA options
                      bool fixedMassRegion, bool yieldOverFullRange,   //fit range options
                      string sExtraVar, int nExtraBin, //Efficiency in different variable, binned
                      bool removeMultiple, bool weighted, bool weightedFromPi0, string whichWeight, bool notTM, string customTMbranch, bool gammaTM, bool InclusiveSample
        ){
        //If Run==0, fit per year is done, otherwise whole Run is fitted
        //if TMVA cut  == -1.0, no cut is applied

        //sanity checks
        checkMC(MC,false,PHSP,false);
        if (!checkTM(MC,TM,notTM,Preselected)) return "";
        if (!checkQ2Range(UseOnlyJpsiEvents,UseOnlyMuMuEvents)) return "";
        magnet = correct_magnet_string(magnet);
        checkKshort(KshortDecaysInVelo);
        if (!SplitInQ2 && UseLowQ2Range)  UseLowQ2Range = false; //Cannot use lowQ2 if it's not split
        if (TMVAcut > -1.0 && !Preselected)Preselected = true;               //TMVA cut can be only aplied on preselected data

        string yearRun      = string((Run != 0) ? ("Run" + to_string(Run)) : (year));
        string polarity     = (magnet == "both" ? "" : ("_"+magnet));
        string trackType    = SplitDDandLL ? (KshortDecaysInVelo ? "_LL" : "_DD") : "";
        string resonance    = (UseOnlyJpsiEvents ? "_JpsiOnly" : (UseOnlyMuMuEvents ? "_mumu" : ""));
        string splitInQ2    = SplitInQ2? (UseLowQ2Range ? "_lowQ2" : "_highQ2") : "";
        string fitModel     = SignalType + "_" + BckGndType;
        string TMtype = "";
        if (MC) TMtype = string(TM ? "_TM" : (notTM ? "_notTM" : "_all")) + getTMtag(customTMbranch,gammaTM);
        coutDebug("TM type: " + TMtype);
        string dataType     = string(MC ? (InclusiveSample ? "_IncMC" : "_MC") : "") + string(UseDTF ? "_DTF" : "") + string(Preselected ? "" : "_stripped")+ TMtype +(PHSP ? "_PHSP" : "");

        string cutResponse  = (TMVAcut==-1) ? "" : ("_TMVA"+to_string(TMVAcut));
        string constrains   = string(ConstrainParameters ? "_constrained" : "") + string(GetShapeFromMC ? "_fixShape" : "");
        string fixedMRegion = fixedMassRegion ? "_fixedMassWindow" : "";
        string yieldRange   = yieldOverFullRange ? "_fullRangeYield" : "";
        string subset       = (randomSubset != 0 ? (randomSubset == -1 ? "_subset1" : "_subset2" ) : "");
        string extraVar     = (sExtraVar != "" ? ("_" + sExtraVar + "_" + to_string(nExtraBin)) : "");
        string removeMult   = removeMultiple ? "_removedMultiple" : "";
        string weight       = string(weighted ? "_weighted" : "") + string(weightedFromPi0 ? "_TMweight_"+whichWeight : "");

        string dir = thePath  + "/Efficiencies/MassFits/" + dataType + "/" + resonance + "/"+ yearRun + "/" + fitModel + "/" ;
        string command = "mkdir -p " + dir; //It's stupid but it shouldn't take too much time extra to create two folders instead of one
        system(command.c_str());
        replace(dir,"Efficiencies/MassFits", "MassFits");
        command = "mkdir -p " + dir;
        system(command.c_str());

        return dir + yearRun + polarity + "_" + TheDecay + trackType + resonance + splitInQ2 + "_BplusMassModel_"
                            + fitModel + dataType + TMtype + weight +removeMult + cutResponse + constrains + fixedMRegion + yieldRange +subset + extraVar + ".root";
}

//Simple version for quickFit
string GetMassFitFile(std::string year, bool MC, bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, bool KshortDecaysInVelo,
                      bool GetShapeFromMC, string SignalType, string BckGndType, bool ConstrainParameters, //shape from MC?
                      bool fixedMassRegion, bool weighted){    //fit range options

        return GetMassFitFile(year,"both",0,
                              MC,true, true,false,
                              UseOnlyJpsiEvents, UseOnlyMuMuEvents,
                              GetShapeFromMC, SignalType, BckGndType,ConstrainParameters,
                              KshortDecaysInVelo,false,
                              -1.0, 0,
                              fixedMassRegion, false,"",-1,false,weighted,false,"",false,"",true, false);
}

//Simple version for basic fits
string GetMassFitFile(std::string year, int Run, bool MC, bool PHSP,  //input/output file selection
                      bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, //signal/reference
                      bool GetShapeFromMC, string SignalType, string BckGndType, bool ConstrainParameters, //shape from MC?
                      bool KshortDecaysInVelo, bool UseLowQ2Range, //LL/DD?    // q2 range
                      Double_t TMVAcut,      //TMVA options
                      bool fixedMassRegion,  //fit range options
                      bool removeMultiple
        ){    //fit range options

        return GetMassFitFile(year,"both", Run,
                              MC, true, MC, PHSP,
                              UseOnlyJpsiEvents, UseOnlyMuMuEvents,
                              GetShapeFromMC, SignalType, BckGndType,ConstrainParameters,
                              KshortDecaysInVelo, UseLowQ2Range,
                              TMVAcut, 0, fixedMassRegion, false, "", -1, removeMultiple,
                              MC, false, "", //TODO: test if weighting works as it should
                              false, "", gammaTMdefault, false);
}


////////////////////////////////////////////////////////////////////////
///
///         Efficiency files
///
////////////////////////////////////////////////////////////////////////
string GetEfficiencyMassFitFile(std::string year, string magnet,int Run,
                            bool Preselected, bool TM, bool PHSP,                 //input/output file selection
                            bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents,           //signal/reference
                            bool GetShapeFromMC, string SignalType, string BckGndType, bool ConstrainParameters, //shape from MC?
                            bool KshortDecaysInVelo, bool UseLowQ2Range, //LL/DD?    // q2 range
                            Double_t TMVAcut, //TMVA options
                            bool fixedMassRegion,  //fit range options
                            string sExtraVar, int nExtraBin, //Efficiency in different variable, binned
                            bool removeMultiple, bool weighted, bool weightedFromPi0, string whichWeight,
                            string customTMbranch, bool gammaTM
              ){

    string filePath = GetMassFitFile(year,magnet, Run,
                                     true, Preselected, TM, PHSP,
                                     UseOnlyJpsiEvents, UseOnlyMuMuEvents,
                                     GetShapeFromMC, SignalType, BckGndType,ConstrainParameters,
                                     KshortDecaysInVelo, UseLowQ2Range,
                                     TMVAcut, 0,
                                     fixedMassRegion, false, sExtraVar, nExtraBin,
                                     removeMultiple, weighted, weightedFromPi0, whichWeight,
                                     false, customTMbranch, gammaTM, false);

    replace(filePath,"MassFits", "Efficiencies/MassFits");


    return filePath;
}

//The name is a bit stupid, but it's also used for the simultaneous B+ mass fit
string GetEfficiencyPi0MassFitFile(bool fromPi0, string year, string magnet, int Run,
                                   string customTMbranch, bool gammaTM,
                                   int nBins, bool fixSigma, bool fixMass,
                                   bool useFancyFit, bool simFit, bool binnedFit,
                                   bool UseOnlyMuMuEvents, bool PHSP, bool RemoveMultiple, bool weighted, bool weightedFromPi0, string whichWeight, string sExtraVar, int nExtraBin){


    string yearRun      = (Run != 0) ? ("Run" + to_string(Run)) : (year);
    string polarity     = (magnet == "both" ? "" : ("_"+magnet));
    string MCtype = string(PHSP? "PHSP" : (!UseOnlyMuMuEvents ? "RefMC" : "MC"));    //Possibly TODO
    string extraVar     = (sExtraVar != "" ? ("_" + sExtraVar + "_" + to_string(nExtraBin)) : "");
    string removeMult   = RemoveMultiple ? "_removedMultiple" : "";
    string weight       = string(weighted ? "_weighted" : "") + string(weightedFromPi0 ? "_TMweight_"+whichWeight : "");
    if (customTMbranch == "") customTMbranch = TMbranch; //TODO: think about this one, will change customTMbranch for usage also elsewhere, but if it's empty, TMbranch usage is assumed
    string binning      = "nBins_" + to_string(nBins);
    if (useFancyFit && !binnedFit) binning = "";
    string constrains   = string(fixMass ? "_fixMass" : "") + string(fixSigma ? "_fixSigma" : "");
    string customTMtag  = getTMtag(customTMbranch,gammaTM);
    string fitType      = string(useFancyFit ? "_fancyFit" + string(simFit ? "_simFit" : "") + string(binnedFit ? "_binnedFit" : "") : "");
    string TMdir = fromPi0 ? "TM_from_Pi0" : "TM_from_Bplus";
    string dir =thePath+"/Efficiencies/MassFits/"+TMdir+"/"+MCtype+"/"+yearRun+"/";
    string command = "mkdir -p " + dir;
    system(command.c_str());

    return dir + yearRun + polarity  + "_" + TheDecay + "_" + customTMtag + constrains + fitType + binning + "_Efficiency" + weight + removeMult +"_" + extraVar + ".root";

}

string GetEfficiencyFile(string effType, string year, string magnet, int Run, //input/output file selection
                         bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, bool PHSP, bool KshortDecayInVelo,
                         bool RemoveMultiple, bool weighted, bool weightedFromPi0, string whichWeight,
                         bool UseLowQ2Range, bool useFancyFit, string sExtraVar,
                         string customTMbranch, bool gammaTM,
                         int nBins, bool fixSigma, bool fixMass, bool simFit, bool binnedFit, bool sigEff){

   //TODO add an if in the path depending on splitting in Q2 bin
    string trackType = SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "";
    string resonance = (UseOnlyJpsiEvents ? "_JpsiOnly" : (UseOnlyMuMuEvents ? "_mumu" : ""));
    string phaseSpace= PHSP ? "_PHSP" : "";
    string splitInQ2 = SplitInQ2? (UseLowQ2Range ? "_lowQ2" : "_highQ2") : "";
    string polarity  = (magnet == "both" ? "" : ("_"+magnet));
    string yearRun   = (Run != 0) ? ("Run" + to_string(Run)) : (year);
    string extraVar  = (sExtraVar != "" ? "_" + sExtraVar : "");
    string remove    = RemoveMultiple ? "_AloneOnly_" : "" ;
    string weight       = string(weighted ? "_weighted" : "") + string(weightedFromPi0 ? "_TMweight_"+whichWeight : "");
    string binning      = (nBins == -1 ? "" : "_nBins" + to_string(nBins) );
    string constrains   = string(fixMass ? "_fixMass" : "") + string(fixSigma ? "_fixSigma" : "");
    string customTMtag  = getTMtag(customTMbranch,gammaTM);
    string isSigEff     = (sigEff ? "" : "_BKG/");

    string fitType      = string(useFancyFit ? "_fancy" + string(simFit ? "_simFit" : "") + string(binnedFit ? "_binnedFit" : "") : "");    

    string dir =thePath+"/Efficiencies/"+resonance+"/"+phaseSpace+"/"+effType+"/" + yearRun +"/" + isSigEff;
    string command = "mkdir -p " + dir;
    system(command.c_str());

    return dir + TheDecay + trackType + resonance + phaseSpace + customTMtag + constrains + binning + weight + splitInQ2+ "_" + effType + remove +"Efficiency_" + yearRun + polarity + fitType + extraVar + ".root";

}

string GetEfficiencyFileTM(string effType, string year, string magnet, int Run, //input/output file selection
                            bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, bool PHSP, bool KshortDecayInVelo,
                           bool RemoveMultiple, bool weighted,  bool weightedFromPi0, string whichWeight,
                           bool UseLowQ2Range,  bool useFancyFit, string sExtraVar, bool sigEff,
                           string customTMbranch, bool gammaTM){
    return GetEfficiencyFile(effType, year, magnet, Run, UseOnlyJpsiEvents, UseOnlyMuMuEvents, PHSP, KshortDecayInVelo, RemoveMultiple, weighted, weightedFromPi0, whichWeight, UseLowQ2Range, useFancyFit, sExtraVar, customTMbranch, gammaTM, -1, false, false, false, false, sigEff);
}

string GetEfficiencyFilePi0TM(string year, int Run, //input/output file selection
                            bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, bool PHSP,
                            bool weightedFromPi0, string whichWeight,
                            bool useFancyFit, string sExtraVar, bool sigEff){
    if (useFancyFit) return GetEfficiencyFile("TM_from_Pi0", year, "both", Run, UseOnlyJpsiEvents, UseOnlyMuMuEvents, PHSP, false, false, false, weightedFromPi0, whichWeight, false, useFancyFit, sExtraVar,"", gammaTMdefault, -1, true, true, true, false, sigEff);
    else             return GetEfficiencyFile("TM_from_Pi0", year, "both", Run, UseOnlyJpsiEvents, UseOnlyMuMuEvents, PHSP, false, false, false, weightedFromPi0, whichWeight, false, useFancyFit, sExtraVar,"", gammaTMdefault, 40,true,true, false, false, sigEff);
}

string GetEfficiencyFile(string effType, string year, string magnet, int Run, //input/output file selection
                            bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, bool PHSP,
                            bool KshortDecayInVelo, bool RemoveMultiple, bool weighted, bool UseLowQ2Range,
                            bool useFancyFit, string sExtraVar,
                            string customTMbranch, bool gammaTM
                         ){
    return GetEfficiencyFile(effType, year, magnet, Run,
                             UseOnlyJpsiEvents, UseOnlyMuMuEvents,
                             PHSP, KshortDecayInVelo, RemoveMultiple, weighted,
                             false, "",
                             UseLowQ2Range, useFancyFit, sExtraVar,
                             customTMbranch, gammaTM,
                             -1, false, false, false, false,true);
}

//Default efficiency files used in BDTcutScanner, for different year and run
string GetEfficiencyFile(string effType, string year, string magnet, int Run,
                            bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents, bool PHSP,
                            bool KshortDecayInVelo, bool RemoveMultiple, bool weighted, bool UseLowQ2Range,
                            bool useFancyFit, string sExtraVar
                         ){
    return GetEfficiencyFile(effType, year, magnet, Run,
                             UseOnlyJpsiEvents, UseOnlyMuMuEvents,
                             PHSP, KshortDecayInVelo, RemoveMultiple, weighted,
                             UseLowQ2Range, useFancyFit, sExtraVar, "", gammaTMdefault);
}

//Defualt efficiency files used in BDTcutScanner, for different year
string GetEfficiencyFile(string effType, string year, string magnet,
                            bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents,bool PHSP,
                            bool KshortDecayInVelo, bool RemoveMultiple, bool weighted, bool UseLowQ2Range,
                            bool useFancyFit, string sExtraVar){
    return GetEfficiencyFile(effType, year, magnet, 0,
                             UseOnlyJpsiEvents, UseOnlyMuMuEvents,
                             PHSP, KshortDecayInVelo, RemoveMultiple, weighted,
                             UseLowQ2Range, useFancyFit, sExtraVar, "", gammaTMdefault);
}

//Defualt efficiency files used in BDTcutScanner, for different run
string GetEfficiencyFile(string effType, string magnet, int Run,
                            bool UseOnlyJpsiEvents, bool UseOnlyMuMuEvents,bool PHSP,
                            bool KshortDecayInVelo, bool RemoveMultiple, bool weighted, bool UseLowQ2Range,
                            bool useFancyFit, string sExtraVar){
    return GetEfficiencyFile(effType, "", magnet, Run,
                             UseOnlyJpsiEvents, UseOnlyMuMuEvents,
                             PHSP, KshortDecayInVelo, RemoveMultiple, weighted,
                             UseLowQ2Range, useFancyFit, sExtraVar, "", gammaTMdefault);
}

string GetBDTScanFile(string year, string magnet, int Run, //input/output file selection
                      bool KshortDecayInVelo, bool UseLowQ2Range,
                      bool fineScan){
    string trackType = SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "";
    string splitInQ2 = SplitInQ2? (UseLowQ2Range ? "_lowQ2" : "_highQ2") : "";
    string polarity = (magnet == "both" ? "" : ("_"+magnet));
    string yearRun = (Run != 0) ? ("Run" + to_string(Run)) : (year);

    return thePath + "/Tuples/FinalSelection/" + TheDecay + "_BDTscan" + trackType + splitInQ2+ "_" + yearRun + polarity + (fineScan ? "_fine" : "") + ".root";

}


string GetBDTScanBackgroundFitFile(string year, int Run, //input/output file selection
                                   bool KshortDecayInVelo, bool UseLowQ2Range,
                                   double TMVAcut){

    string trackType = SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "";
    string splitInQ2 = SplitInQ2? (UseLowQ2Range ? "_lowQ2" : "_highQ2") : "";
    string yearRun = (Run != 0) ? ("Run" + to_string(Run)) : (year);
    string cutResponse  = (TMVAcut==-1) ? "" : ("_TMVA"+to_string(TMVAcut));

    string dir = thePath  + "/BkgFits/"+ yearRun + "/";
    string command = "mkdir -p " + dir; //It's stupid but it shouldn't take too much time extra to create two folders instead of one
    system(command.c_str());

    return dir + TheDecay + "_BkgFit" + trackType + splitInQ2+ "_" + yearRun + cutResponse + ".root";

}

string GetTMVAplotsFolder(int year, int Run, bool SplitYears, bool KshortDecaysInVelo,int nConfiguration, bool UseLowQ2Range, string customTMbranch, bool gammaTM){

    //string TMfolder = "";
    string TMfolder = getTMtag(customTMbranch,gammaTM);
    TMfolder.erase(TMfolder.begin()); //remove the _ at the beginning

    return thePath + "/TMVAplots/" + string(SplitYears ? to_string(year) : ("Run" + to_string(Run)))+"/"
            + string(SplitDDandLL ? (KshortDecaysInVelo ? "LL/" : "DD/") : "")
            + string(SplitInQ2 ? (UseLowQ2Range ? "LowQ2/" : "HighQ2/") : "")
            + "Config" + to_string(nConfiguration) + "/" + TMfolder + "/";
    //Ready for the file name
}

string GetTMVAplotsFolder(int year, int Run, bool SplitYears, bool KshortDecaysInVelo,int nConfiguration, bool UseLowQ2Range){

     return thePath + "/TMVAplots/" + string(SplitYears ? to_string(year) : ("Run" + to_string(Run)))+"/"
            + string(SplitDDandLL ? (KshortDecaysInVelo ? "LL/" : "DD/") : "")
            + string(SplitInQ2 ? (UseLowQ2Range ? "LowQ2/" : "HighQ2/") : "")
            + "Config" + to_string(nConfiguration) + "/";
    //Ready for the file name
}

string getResolutionFile(string year, int Run, bool TM, bool RemoveMultiple, double TMVAcut, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo){
         string trackType = SplitDDandLL ? (KshortDecayInVelo ? "_LL" : "_DD") : "";
         string cutResponse  = (TMVAcut==-1) ? "" : ("_TMVA"+to_string(TMVAcut));
         string MCtype = string(PHSP? "PHSP" : (ReferenceChannel ? "RefMC" : "MC"));
         string removeMult   = RemoveMultiple ? "_removedMultiple" : "";
         string sTM = string(TM ? "_TM" + getTMtag("",gammaTMdefault): "");

         return thePath + "/Resolution/"+MCtype +"/"+ year+ "/" + TheDecay + trackType + "_" + MCtype +"_Run" + to_string(Run) +"_" + year + sTM + cutResponse + removeMult + ".root";
}

string returnFileAddress(string year, int Run, string magnet, bool Preselected, bool BDTed, bool MC, bool ReferenceChannel, bool PHSP, bool KshortDecayInVelo){

    bool UseLowQ2Range = false; //keeping in case
    if (magnet == "both"){
        if (BDTed)  return GetFinalOutputFile(year,Run,MC,ReferenceChannel,PHSP,KshortDecayInVelo,UseLowQ2Range);
        else        return GetBDTinputFile(year,MC,ReferenceChannel,PHSP,KshortDecayInVelo);
    }
    else return   GetInputFile(year,magnet,Preselected,MC,ReferenceChannel,PHSP,false);

}


////////////////////////////////////////////////////////////////////////
///
///         TM control plots
///
////////////////////////////////////////////////////////////////////////

std::string dataTypeString(bool MC, bool Reference, bool PHSP, bool B0, bool K1, bool Inc){
    if (!MC) return "Data";
    else{
        if (PHSP) return "PHSP";
        else{
            if (B0) return Reference ? "B0toKstJpsi" : "B0toKstMuMu";
            else if (K1) return Reference ? "BtoK1Jpsi" : "BtoK1MuMu";
            else if (Inc) return Reference ? "BtoXJpsi" : "BtoXMuMu";
            else return Reference ? "RefMC" : "SigMC";
        }
    }
}

string getTMplotsFolder(string year, bool Reference, bool PHSP, bool B0, bool K1, bool Inc){
    string MCtype = dataTypeString(true,Reference, PHSP, B0, K1, Inc);
    string dir = thePath + "/TMplots/"+ MCtype +"/";
    string command = "mkdir -p " + dir;
    system(command.c_str());
    dir += year + "/";
    command = "mkdir -p " + dir;
    system(command.c_str());
    return dir;
}

string getTMplotsPath(string name, string year, bool Reference, bool PHSP, bool B0, bool K1, bool Inc){
    return getTMplotsFolder(year,Reference, PHSP, B0, K1, Inc) + year + "_" + TheDecay + "_" + name + ".eps";
}

////////////////////////////////////////////////////////////////////////
///
///      Restore preselected data from backups
///
////////////////////////////////////////////////////////////////////////

bool restore_from_backup(string year, string magnet, bool MC, bool ReferenceChannel, bool PHSP){
    string string_input = GetInputFile(year,magnet,true, MC, ReferenceChannel, PHSP, false);

    string backup_file = string_input;
    replace(backup_file,".root","_backup.root");
    if (MC) replace(backup_file,"_backup.root","_TMbackup.root");

    string command = "mv " + backup_file + " " + string_input;
    coutDebug(command);
    system(command.c_str());

    return 1;
}

bool restore_allYears_from_backup(bool MC, bool ReferenceChannel, bool PHSP){
    for (auto &year :yearsVector(MC,ReferenceChannel,PHSP,12) ){
        restore_from_backup(year,"down",MC,ReferenceChannel,PHSP);
        restore_from_backup(year,"up",MC,ReferenceChannel,PHSP);
    }
    return 1;
}

bool restore_allData_from_backup(){
    restore_allYears_from_backup(false,false,false);
    return 1;
}

int restore_allMCsig_from_backup(){
    restore_allYears_from_backup(true,false,false);
    return 1;
}
int restore_allMCref_from_backup(){
    restore_allYears_from_backup(true,true,false);
    return 1;
}
int restore_allPHSP_from_backup(){
    restore_allYears_from_backup(true,false,true);
    return 1;
}

int restore_allMC_from_backup(){
    restore_allYears_from_backup(true,false,false);
    restore_allYears_from_backup(true,true, false);
    restore_allYears_from_backup(true,false,true);
    return 1;
}

//Create backup

bool create_backup(string year, string magnet, bool MC, bool ReferenceChannel, bool PHSP){
    string string_input = GetInputFile(year,magnet,true, MC, ReferenceChannel, PHSP, false);

    string backup_file = string_input;
    replace(backup_file,".root","_backup.root");
    if (MC) replace(backup_file,"_backup.root","_TMbackup.root");

    string command = "cp " + string_input + " " + backup_file;
    coutDebug(command);
    system(command.c_str());

    return 1;
}

bool create_allYears_backup(bool MC, bool ReferenceChannel, bool PHSP){
    for (auto &year :yearsVector(MC,ReferenceChannel,PHSP,12) ){
        create_backup(year,"down",MC,ReferenceChannel,PHSP);
        create_backup(year,"up",MC,ReferenceChannel,PHSP);
    }
    return 1;
}


bool create_allData_backup(){
    create_allYears_backup(false,false,false);
    return 1;
}

int create_allMCsig_backup(){
    create_allYears_backup(true,false,false);
    return 1;
}

int create_allMCref_backup(){
    create_allYears_backup(true,true,false);
    return 1;
}

int create_allPHSP_backup(){
    create_allYears_backup(true,false,true);
    return 1;
}

int create_allMC_backup(){
    create_allYears_backup(true,false,false);
    create_allYears_backup(true,true, false);
    create_allYears_backup(true,false,true);
    return 1;
}


//TODO:check this
bool create_backup_MCsig(string year, string magnet){
    string string_input = GetInputFile(year,magnet,true,false,false,false,false);
    string command = "cp " + string_input + " ";
    replace(string_input,".root","_backup.root");
    command += string_input;
    coutDebug(command);
    system(command.c_str());

    return 1;
}
int create_backup_All_MCsig(){
    for (auto &year: yearsData(12)){
        create_backup_MCsig (year,"down");
        create_backup_MCsig (year,"up");
    }
    return 1;
}

#endif // PATHS_HPP

