#include "SignalPdf.hpp"
#include <boost/algorithm/string.hpp>

void SignalType::setSignalType(string sigType, bool FixParams, bool ConstrParams){ //construct from a string
    SingleGaussian = false;
    DoubleGaussian = false;
    DoubleCB = false;
    LeftCB = false;
    RightCB = false;
    OneCB = false;
    NoSig = false;

    FixParameters = FixParams;
    ConstrParameters = ConstrParams;

    boost::to_lower(sigType); //so far it doesn't complain about non-existing library
    coutDebug("Input signal type:" + sigType);
    if (sigType.find("nosig")<100){
        NoSig = true;
    }
    else{
        if (sigType.find("cb")<100){
            if (sigType.find("one")<100){
                OneCB = true;
            }
            else if (sigType.find("double")<100){
                DoubleCB = true;
            }
            else{
                if (sigType.find("left")<100) LeftCB = true;
                if (sigType.find("right")<100) RightCB = true;
            }
        }
        else if (sigType.find("gaus")<100){
            anyGaussain = true;
            if (sigType.find("double")<100) DoubleGaussian = true;
            else                        SingleGaussian = true;
        }
        else{
            coutERROR("Please specify which Signal shape is used: DoubleCB, OneCB, LeftCB, RightCB, SingleGaussian or DoubleGaussian!");
            NoSig = true;
        }
    }

    coutDebug("Final signal type(s):");
    coutDebug(SingleGaussian ? "SingleGaussian" : "");
    coutDebug(DoubleGaussian ? "DoubleGaussian" : "");
    coutDebug(DoubleCB  ? "DoubleCB" : "");
    coutDebug(LeftCB    ? "LeftCB"   : "");
    coutDebug(RightCB   ? "RightCB"  : "");
    coutDebug(OneCB     ? "OneCB"    : "");
    coutDebug(NoSig     ? "NoSig"    : "");

}

vector<string> SignalType::getSigListOfParams(){
    vector<string> tmp = {};
    for (auto var : SigRooVars) tmp.push_back(var->GetName());
    return tmp;
}

double SignalType::getEffSigmaFromResult(){ //Get effective sigma (return sigma or caclulate effective sigma for doubleCB/double gauss
    double sig = 0;
    double sig2 = 0;
    double f = 0;
    for (auto var : SigRooVars){
        string tmpName = var->GetName();
        if (tmpName == "sig_sigma") sig = var->getVal();
        else if (tmpName == "sig_sigma2") sig2 = var->getVal();
        else if (tmpName == "sig_f") f = var->getVal();
    }
    if (sig2 == 0) return sig; //left cb, gauss, one cb
    else{
        if (sig==0) return sig2; //right cb
        else{
            if (f==0){
                coutERROR("There are two sigmas but no fraction of signal components, super weird. Returning efective sigma 0");
                return 0;
            }
            else return TMath::Sqrt(f * TMath::Power(sig,2) + (1 - f) * TMath::Power(sig2, 2));
        }
    }
}
