#! /usr/bin/python

################# PlotMyNicePlots.py ############################
#                                                                   #
#    Author: Felicia Volle                                          #
#    Date:   21/06/2025                                             #
#    Description: For Joseph's Dark Photon internship               #
#    Usage:  python PlotMyNicePlots.py -f /path/to/my/file.root     #
#            -t Rho_Tuple_Prompt/DecayTree                          #
#                                                                   #
#####################################################################


################# IMPORT ############################################

import os, sys
from ROOT import TFile, TLatex, TH1F, TPaveText, TCanvas, TLegend, gROOT, gStyle, kBlue, kOrange, TMath
gROOT.SetBatch(True)
import argparse

################# VARIABLES AND DICTIONNARIES #######################

# Example selection requirement, to be adapted for Dark Photons
VetoDict = {'PhiVeto':'TMath::Abs(Phi_M -1020) > 12',
    }

################# FUNCTION DEFINITION ###############################


def get_args():
    parser = argparse.ArgumentParser(description='Plotting Options')
    parser.add_argument('-f', '--filename', type=str,
                        help='''What is the name of the file ?''',
                        required=True)
    parser.add_argument('-t', '--tree', type=str,
                        help='''What is the name of the tree ?''',
                        required=True)
    parser.add_argument('-p', '--path', type=str, 
                        help='''What is the path to VetoPlots ?''',
                        required=True)
    parser.add_argument('-a', '--angle', type=str,
                        help='''Plot which angle ?''', required=True)
    parser.add_argument('-s', '--selectionFile', type=str,
                        help='''Where is selection file ?''', 
                        required=False, 
                        default='1==1')
    return parser.parse_args()


def getCuts(cutsFile):
    """
    Read cuts from a .txt file and return a string
    Cuts on different lines in the file are concatenated
    with an && string.
    :cutsFile: type str
    Name of the file that contains the cuts
    """
    with open(cutsFile, 'r') as f:
        cuts = f.readlines()
        cuts = [c.strip() for c in cuts]
        cut_string = " && ".join(cuts)
    return cut_string


def get_correctExpression(x):
    # TLatex label has better quality, but no #ell, 
    # therefore use TMathText for cosTheta_lepton
    AngleDict={'Phi' : ['Phi', '#phi', 40, -TMath.Pi(), TMath.Pi()], 
               'cosTl':['cosTheta_lepton', '\\cos(\\theta_{\\ell})', 40, -1, 1], 
               'cosTp':['cosTheta_Lst', 'cos(#theta_{p})', 40, -1, 1]}
    return AngleDict[x]

def get_correctExpression_UCAS(x):
    # TLatex label has better quality, but no #ell, 
    # therefore use TMathText for cosTheta_lepton
    AngleDict={'Phi' : ['phi', '#phi', 40, -TMath.Pi(), TMath.Pi()], 
               'cosTl':['cos_theta_l', '\\cos(\\theta_{\\ell})', 40, -1, 1], 
               'cosTp':['cos_theta_Lz', 'cos(#theta_{p})', 40, -1, 1]}
    return AngleDict[x]


def drawAngles( a, inputTree, TriggerSel, year, name_of_bin, Path, pK, NicePK, nice_bin_name, qsq_bin_min, qsq_bin_max, mpKMin, mpKMax, GeV2ToMeV2, L1520):
    cName = TCanvas('c', 'c', 0, 0, 600, 450)
    xName, xAxis, xBins, xmin, xmax = get_correctExpression(a)
    x2Name, x2Axis, x2Bins, x2min, x2max = get_correctExpression_UCAS(a)
    BinWidth = (xmax - xmin)/xBins

    yAxis = 'Normalized entries / (%.2f)' % (BinWidth)

    
    qsq = "Jpsi_M*Jpsi_M"
    q2_cut = "({} >= {} && {} <= {})".format(qsq, qsq_bin_min*GeV2ToMeV2, qsq, qsq_bin_max*GeV2ToMeV2)

    MCperBin = 'B_BKGCAT <= 10 && '+q2_cut
    OnlyTrigger = MCperBin + " && " + TriggerSel
    Sel = OnlyTrigger

    # Apply JPsi Veto in rare mode
    if (name_of_bin != 'JPsi' and name_of_bin != 'Psi2S'):
        Sel = OnlyTrigger+' && TMath::Abs(LtoK_M - 3097)>35'

    pK, NicePK = '', ''
    if L1520 == True:
        Lst_Cut = f"(X_M >= {mpKMin} && X_M <= {mpKMax})" 
        Sel = Sel + " && " + Lst_Cut

    h1 = TH1F("h1", "Angle def Orsay", xBins, xmin, xmax)
    inputTree.Project("h1", xName, "( "+Sel+")*PIDweight")

    h2 = TH1F("h2", "Angle def UCAS", xBins, xmin, xmax)
    inputTree.Project("h2", x2Name, "( "+Sel+")*PIDweight")

    # Draw Normalized 
    h1.Scale(1.0/h1.Integral())
    h2.Scale(1.0/h2.Integral())

    h1.GetXaxis().SetTitle( xAxis )
    h1.GetYaxis().SetTitle( yAxis )
    h1.SetTitle("")

    maxi = h1.GetBinContent(h1.GetMaximumBin())
    if h2.GetBinContent(h2.GetMaximumBin()) > maxi :
        maxi = h2.GetBinContent(h2.GetMaximumBin())

    mini = h1.GetBinContent(h1.GetMinimumBin())
    if h2.GetBinContent(h2.GetMinimumBin()) < mini :
        mini = h2.GetBinContent(h2.GetMinimumBin())


    h1.SetMaximum(maxi+(maxi-mini)*0.5)
    h1.SetMinimum(mini-(maxi-mini)*0.7)

    h1.SetLineColor(kOrange-3)
    h1.SetMarkerColor(kOrange-3)

    h2.SetLineColor(kBlue+2)
    h2.SetMarkerColor(kBlue+2)

    #h1.Draw("AXIS") 
    h1.DrawCopy("L")
    h2.DrawCopy("L SAME")

    # LHCb label
    lhcbName = TPaveText(gStyle.GetPadLeftMargin() + 0.05,
                         0.87 - gStyle.GetPadTopMargin(),
                         gStyle.GetPadLeftMargin() + 0.20,
                         0.95 - gStyle.GetPadTopMargin(),
                         "BRNDC")
    lhcbName.AddText("LHCb unofficial")
    lhcbName.SetFillColor(0)
    lhcbName.SetTextAlign(12)
    lhcbName.SetTextSize(0.06)
    lhcbName.SetBorderSize(0)
    lhcbName.Draw()
 
    lhcbText = TLatex() 
    lhcbText.SetTextFont(132)
    lhcbText.SetTextSize(0.06)
    lhcbText.SetTextAlign(12)
    lhcbText.DrawLatexNDC(0.6, 0.91-gStyle.GetPadTopMargin(), nice_bin_name+NicePK) #0.85

    cName.Update()
    
    legend = TLegend(0.55, 0.17, 0.92, 0.35)

    legend.AddEntry(h1, "Angle def Orsay", "lep")
    legend.AddEntry(h2, "Angle def UCAS", "lep")

    legend.Draw()
    cName.Update()

    if not os.path.isdir(Path+'/VetoPlots/AngleComparison'):
        os.mkdir(Path+'/VetoPlots/AngleComparison')

    PlotName = Path+'/VetoPlots/AngleComparison/'+a+'_'+year+'_'+pK+'_'+name_of_bin+'.png'
    cName.SaveAs(PlotName)
    
    del h1
    del h2

    cName.Close()
    return PlotName


def getVariableList(a):
    aName = get_correctExpression(a)[0]
    uName = get_correctExpression_UCAS(a)[0]
    l = ['X_M', 'Jpsi_M', 'B_M']
    l.append(aName)
    l.append(uName)
    return l



################# MAIN ##############################################

if __name__ == '__main__':
    args  = get_args()
    fName = args.filename
    tree  = args.tree
    path  = args.path
    a     = args.angle
    sF    = args.selectionFile

    year  = fName.split("_")[-2]
    Scale = 1

    sys.path.insert(1, p)
    #sys.path.append(path)
    from setup import q2list, q2Dict, getMCcutstring, mpKMax, mpKMin, GeV2ToMeV2

    iF = TFile(fName, "READ")
    iT = iF.Get(tree)
    
    BranchList = getVariableList(a)
    for activeBranchName in BranchList:
        iT.SetBranchStatus(activeBranchName, 1)
    
    gROOT.LoadMacro(path+"/lhcbStyle.C")

    # Trigger and loose PID selection specified in FinalSelection.txt
    TrigSel = "1==1"
    if sF != 'FinalSelection':
        TrigSel = getCuts(path+sF)

    print(" <<< START PLOTTING ANGLE {} >>> ".format(a))
    print(" <<< TRIGGER SEL = {} >>> ".format(TrigSel))

    for name_of_bin in q2list: #loop over the bins
        print ('----------------------------------------------')
        qsq_bin_min, qsq_bin_max, nice_bin_name =  q2Dict[name_of_bin]
        print (f'---- qsq_bin_min {qsq_bin_min}  GeV2')
        print (f'---- qsq_bin_max {qsq_bin_max}  GeV2')

        tot_cut, pK, NicePK = getMCcutstring(name_of_bin, qsq_bin_min, qsq_bin_max, L1520=False, Truth=False, PID=True)
        # Once around L1520
        #c2 = drawAngles(a, iT, TrigSel, year, name_of_bin, path, pK, NicePK, nice_bin_name, qsq_bin_min, qsq_bin_max, mpKMin, mpKMax, GeV2ToMeV2, L1520=True)
        # Once all pK region
        c1 = drawAngles(a, iT, TrigSel, year, name_of_bin, path, pK, NicePK, nice_bin_name, qsq_bin_min, qsq_bin_max, mpKMin, mpKMax, GeV2ToMeV2, L1520=False)

    iF.Close()

#EOF