def PlotHistograms(datasetsMgr, histoName):
    # Get Histogram name and its kwargs
    saveName = histoName.rsplit("/")[-1]
    kwargs_  = GetHistoKwargs(saveName, opts)

    # Create the plotting object
    dataset = "FakeB"
    p = plots.PlotBase( [getHisto(datasetsMgr, dataset, histoName)], saveFormats=[])
    p.setLuminosity(opts.intLumi)

    #  Apply histogram style
    p.histoMgr.forHisto("histo_" + dataset, styles.getFakeBStyle())

    # Set drawing/legend style
    p.histoMgr.setHistoDrawStyle("histo_" + dataset, "AP")
    p.histoMgr.setHistoLegendStyle("histo_" + dataset, "LP")

    #  Customise legend labels
    p.histoMgr.setHistoLegendLabelMany({
            "histo_" + dataset: "Fake b (VR)",
            })
    
    # Draw and save the plot
    plots.drawPlot(p, saveName, **kwargs_) #the "**" unpacks the kwargs_ dictionary
    SavePlot(p, saveName, os.path.join(opts.saveDir, opts.optMode), [".png"])#, ".pdf"] )
    return
def PlotHistoGraphs(datasetsMgr, histoName, hideZeros=False):

    # Get Histogram name and its kwargs
    saveName = histoName.rsplit("/")[-1]
    kwargs_  = GetHistoKwargs(saveName, opts)
    kwargs_["ylabel"] = "Purity"

    # Create the plotting object
    dataset = opts.dataset
    p1 = plots.PlotBase( [getHisto(datasetsMgr, dataset, histoName)], saveFormats=[])
    p1.setLuminosity(opts.intLumi)

    # Convert to TGraph
    hPurity  = p1.histoMgr.getHisto("histo_" + dataset).getRootHisto()#.Clone(dataset + "_clone")
    hgPurity = convertHisto2TGraph(hPurity, printValues=False, hideZeros=hideZeros)
    hgPurity.SetName(dataset)

    # Create & draw the plot
    p = plots.PlotBase( [hgPurity], saveFormats=[])
    p.setLuminosity(opts.intLumi)

    #  Apply histogram style
    p.histoMgr.forHisto(dataset, styles.getFakeBStyle())

    # Set drawing/legend style
    p.histoMgr.setHistoDrawStyle(dataset, "P") #Do NOT use "AP"!!!
    p.histoMgr.setHistoLegendStyle(dataset, "LP")

    #  Customise legend labels
    p.histoMgr.setHistoLegendLabelMany({
            dataset: "Fake b (VR)",
            })

    # Draw and save the plot
    plots.drawPlot(p, histoName.replace(opts.folder, ""), **kwargs_)
    SavePlot(p, saveName, os.path.join(opts.saveDir, opts.optMode), [".png"])#, ".pdf"] )
    return
def DoPlots(datasetsMgr, histoName, analysisType="Inverted", bType="GenuineB"):

    # Sanity checks
    IsBaselineOrInverted(analysisType)
    IsGenuineOrFake(bType)

    # Definitions
    defaultFolder = ""
    if "FakeBPurity" in histoName:
        defaultFolder = "FakeBPurity"
    elif "ForFakeBMeasurement" + histoName:
        defaultFolder = "ForFakeBMeasurement"
    else:
        raise Exception("This should never happen")

    # Define folders for inclusive/genuine/fakes
    inclusiveFolder = defaultFolder
    genuineFolder = defaultFolder + "EWKGenuineB"
    fakeFolder = defaultFolder + "EWKFakeB"
    inclusiveHisto = histoName.replace(defaultFolder, inclusiveFolder)
    genuineHisto = histoName.replace(defaultFolder, genuineFolder)
    fakeHisto = histoName.replace(defaultFolder, fakeFolder)

    # Get the inclusive histograms
    p0 = plots.DataMCPlot(datasetsMgr, inclusiveHisto)
    Data = p0.histoMgr.getHisto("Data").getRootHisto().Clone("Data")

    # Get the genuine-b histograms
    p1 = plots.DataMCPlot(datasetsMgr, genuineHisto)
    EWKGenuineB = p1.histoMgr.getHisto("EWK").getRootHisto().Clone(
        "EWKGenuineB")
    QCDGenuineB = p1.histoMgr.getHisto("QCD").getRootHisto().Clone(
        "QCDGenuineB")

    # Get the fake-b histograms
    p2 = plots.DataMCPlot(datasetsMgr, fakeHisto)
    EWKFakeB = p2.histoMgr.getHisto("EWK").getRootHisto().Clone("EWKFakeB")
    QCDFakeB = p2.histoMgr.getHisto("QCD").getRootHisto().Clone("QCDFakeB")

    # Normalize histograms to unit area
    if 0:
        Data.Scale(1.0 / Data.Integral())
        EWKGenuineB.Scale(1.0 / EWKGenuineB.Integral())
        EWKFakeB.Scale(1.0 / EWKFakeB.Integral())
        QCDGenuineB.Scale(1.0 / QCDGenuineB.Integral())
        QCDFakeB.Scale(1.0 / EWKFakeB.Integral())

    # Create the final plot object
    comparisonList = [EWKGenuineB, QCDGenuineB, EWKFakeB, QCDFakeB]
    p = plots.ComparisonManyPlot(Data, comparisonList, saveFormats=[])
    p.setLuminosity(GetLumi(datasetsMgr))

    # Apply styles
    p.histoMgr.forHisto("Data", styles.getDataStyle())
    p.histoMgr.forHisto("EWKGenuineB",
                        styles.getAltEWKStyle())  #GenuineBStyle()
    p.histoMgr.forHisto("QCDGenuineB", styles.getQCDStyle())
    p.histoMgr.forHisto("EWKFakeB", styles.getGenuineBStyle())
    p.histoMgr.forHisto("QCDFakeB", styles.getFakeBStyle())

    # Set draw style
    p.histoMgr.setHistoDrawStyle("Data", "AP")
    p.histoMgr.setHistoDrawStyle("EWKGenuineB", "AP")
    p.histoMgr.setHistoDrawStyle("QCDGenuineB", "AP")
    p.histoMgr.setHistoDrawStyle("EWKFakeB", "AP")
    p.histoMgr.setHistoDrawStyle("QCDFakeB", "AP")

    # Set legend style
    p.histoMgr.setHistoLegendStyle("Data", "P")
    p.histoMgr.setHistoLegendStyle("EWKGenuineB", "P")
    p.histoMgr.setHistoLegendStyle("QCDGenuineB", "P")
    p.histoMgr.setHistoLegendStyle("EWKFakeB", "P")
    p.histoMgr.setHistoLegendStyle("QCDFakeB", "P")
    # p.histoMgr.setHistoLegendStyleAll("LP")

    # Set legend labels
    p.histoMgr.setHistoLegendLabelMany({
        "Data": "Data",
        "EWKGenuineB": "EWK-GenuineB",
        "QCDGenuineB": "QCD-GenuineB",
        "EWKFakeB": "EWK-FakeB",
        "QCDFakeB": "QCD-FakeB",
        #"Data"       : "Data (%s)"         % (analysisType),
        #"EWKGenuineB": "EWK-GenuineB (%s)" % (analysisType),
        #"QCDGenuineB": "QCD-GenuineB (%s)" % (analysisType),
        #"EWKFakeB"   : "EWK-FakeB (%s)"    % (analysisType),
        #"QCDFakeB"   : "QCD-FakeB (%s)"    % (analysisType),
    })

    # Draw the histograms
    _cutBox = None
    _rebinX = 1
    _opts = {"ymin": 1e0, "ymaxfactor": 2.0}
    _format = "%0.0f"
    _xlabel = None

    if "dijetm" in histoName.lower():
        _rebinX = 2
        _units = "GeV/c^{2}"
        _format = "%0.0f " + _units
        _xlabel = "m_{jj} (%s)" % (_units)
        _cutBox = {
            "cutValue": 80.399,
            "fillColor": 16,
            "box": False,
            "line": True,
            "greaterThan": True
        }
        _opts["xmax"] = 400.0
    if "trijetm" in histoName.lower():
        _rebinX = 5
        _units = "GeV/c^{2}"
        _format = "%0.0f " + _units
        _xlabel = "m_{jjb} (%s)" % _units
        _cutBox = {
            "cutValue": 173.21,
            "fillColor": 16,
            "box": False,
            "line": True,
            "greaterThan": True
        }
        _opts["xmax"] = 1500.0
    if "pt" in histoName.lower():
        _rebinX = 2
        _format = "%0.0f GeV/c"
    if "eta" in histoName.lower():
        _format = "%0.2f"
        _cutBox = {
            "cutValue": 0.,
            "fillColor": 16,
            "box": False,
            "line": True,
            "greaterThan": True
        }
        _opts["xmin"] = -3.0
        _opts["xmax"] = +3.0
    if "deltaeta" in histoName.lower():
        _format = "%0.2f"
        _opts["xmin"] = 0.0
        _opts["xmax"] = 6.0
    if "bdisc" in histoName.lower():
        _format = "%0.2f"
    if "tetrajetm" in histoName.lower():
        _rebinX = 10
        _units = "GeV/c^{2}"
        _format = "%0.0f " + _units
        _xlabel = "m_{jjjb} (%s)" % (_units)
        _opts["xmax"] = 3500.0
    if "ancestry" in histoName.lower():
        _rebinX = 1
        _units = ""
        _format = "%0.0f " + _units
        _opts["xmax"] = 32.0
    plots.drawPlot(
        p,
        histoName,
        xlabel=_xlabel,
        ylabel="Arbitrary Units / %s" % (_format),
        log=True,
        rebinX=_rebinX,
        cmsExtraText="Preliminary",
        createLegend={
            "x1": 0.62,
            "y1": 0.72,
            "x2": 0.92,
            "y2": 0.92
        },
        opts=_opts,
        opts2={
            "ymin": 0.0,
            "ymax": 1.5
        },  #{"ymin": 0.6, "ymax": 1.4},
        ratio=True,
        ratioInvert=False,
        ratioYlabel="Ratio",
        cutBox=_cutBox,
    )
    # Save plot in all formats
    SavePlot(p, histoName,
             os.path.join(opts.saveDir, "GenuineVsFake", opts.optMode))
    return
def PlotHistosAndCalculateTF(datasetsMgr, histoList, binLabels, opts):

    # Get the histogram customisations (keyword arguments)
    _kwargs = GetHistoKwargs(histoList[0])

    # Get the root histos for all datasets and Control Regions (CRs)
    regions = ["SR", "VR", "CRone", "CRtwo", "CRthree", "CRfour"]
    rhDict  = GetRootHistos(datasetsMgr, histoList, regions, binLabels)

    #=========================================================================================
    # Calculate the Transfer Factor (TF) and save to file
    #=========================================================================================
    manager = FakeBNormalization.FakeBNormalizationManager(binLabels, opts.mcrab, opts.optMode, verbose=False)
    if opts.inclusiveOnly:
        #manager.CalculateTransferFactor(binLabels[0], rhDict["CRone-FakeB"], rhDict["CRtwo-FakeB"])
        binLabel = "Inclusive"
        manager.CalculateTransferFactor("Inclusive", rhDict["FakeB-CRone-Inclusive"], rhDict["FakeB-CRtwo-Inclusive"], rhDict["FakeB-CRthree-Inclusive"], rhDict["FakeB-CRfour-Inclusive"])
    else:
        for bin in binLabels:
            manager.CalculateTransferFactor(bin, rhDict["FakeB-CRone-%s" % bin], rhDict["FakeB-CRtwo-%s" % bin], rhDict["FakeB-CRthree-%s" % bin], rhDict["FakeB-CRfour-%s" % bin])

    # Get unique a style for each region
    for k in rhDict:
        dataset = k.split("-")[0]
        region  = k.split("-")[1]
        styles.getABCDStyle(region).apply(rhDict[k])
        if "FakeB" in k:
            styles.getFakeBStyle().apply(rhDict[k])
        # sr.apply(rhDict[k])

    # =========================================================================================
    # Create the final plot object
    # =========================================================================================
    rData_SR        = rhDict["Data-SR-Inclusive"] 
    rEWKGenuineB_SR = rhDict["EWK-SR-Inclusive-EWKGenuineB"]
    rBkgSum_SR      = rhDict["FakeB-VR-Inclusive"].Clone("BkgSum-SR-Inclusive")
    rBkgSum_SR.Reset()

    if opts.inclusiveOnly:
        bin = "Inclusive"
        # Normalise the VR histogram with the Transfer Factor ( BkgSum = VR * (CR1/CR2) )
        binHisto_VR = rhDict["FakeB-VR-%s" % (bin)]
        VRtoSR_TF   = manager.GetTransferFactor(bin)
        Print("Applying TF = %s%0.6f%s to VR shape" % (ShellStyles.NoteStyle(), VRtoSR_TF, ShellStyles.NormalStyle()), True)
        binHisto_VR.Scale(VRtoSR_TF) 
        # Add the normalised histogram to the final Inclusive SR (predicted) histo
        rBkgSum_SR.Add(binHisto_VR, +1)
    else:
        # For-loop: All bins
        for i, bin in enumerate(binLabels, 1):
            if bin == "Inclusive":
                continue
            # Normalise the VR histogram with the Transfer Factor ( BkgSum = VR * (CR1/CR2) )
            binHisto_VR = rhDict["FakeB-VR-%s" % (bin)]
            VRtoSR_TF   = manager.GetTransferFactor(bin)
            Print("Applying TF = %s%0.6f%s to VR shape" % (ShellStyles.NoteStyle(), VRtoSR_TF, ShellStyles.NormalStyle()), i==1)
            binHisto_VR.Scale(VRtoSR_TF) 
            # Add the normalised histogram to the final Inclusive SR (predicted) histo
            rBkgSum_SR.Add(binHisto_VR, +1)

    #Print("Got Verification Region (VR) shape %s%s%s" % (ShellStyles.NoteStyle(), rFakeB_VR.GetName(), ShellStyles.NormalStyle()), True)

    # Normalise the VR histogram with the Transfer Factor ( BkgSum = VR * (CR1/CR2) )
    #VRtoSR_TF = manager.GetTransferFactor("Inclusive")
    #Print("Applying TF = %s%0.6f%s to VR shape" % (ShellStyles.NoteStyle(), VRtoSR_TF, ShellStyles.NormalStyle()), True)
    #rBkgSum_SR.Scale(VRtoSR_TF) 
    
    # Plot histograms    
    if opts.altPlot:
        # Add the SR EWK Genuine-b to the SR FakeB ( BkgSum = [FakeB] + [GenuineB-MC] = [VR * (CR1/CR2)] + [GenuineB-MC] )
        rBkgSum_SR.Add(rEWKGenuineB_SR, +1) 

        # Change style
        styles.getGenuineBStyle().apply(rBkgSum_SR)

        # Remove unsupported settings of kwargs
        _kwargs["stackMCHistograms"] = False
        _kwargs["addLuminosityText"] = False

        # Create the plot
        p = plots.ComparisonManyPlot(rData_SR, [rBkgSum_SR], saveFormats=[])

        # Set draw / legend style
        p.histoMgr.setHistoDrawStyle("Data-SR-Inclusive", "P")
        p.histoMgr.setHistoLegendStyle("Data-SR-Inclusive" , "LP")
        p.histoMgr.setHistoDrawStyle("BkgSum-SR-Inclusive", "HIST")
        p.histoMgr.setHistoLegendStyle("BkgSum-SR-Inclusive" , "F")

        # Set legend labels
        p.histoMgr.setHistoLegendLabelMany({
                "Data-SR"       : "Data",
                "BkgSum-SR"     : "Fake-b + Gen-b",
                })
    else:
        # Create empty histogram stack list
        myStackList = []
        
        # Add the FakeB data-driven background to the histogram list    
        hFakeB = histograms.Histo(rBkgSum_SR, "FakeB", "Fake-b")
        hFakeB.setIsDataMC(isData=False, isMC=True)
        myStackList.append(hFakeB)
        
        # Add the EWKGenuineB MC background to the histogram list
        hGenuineB = histograms.Histo(rEWKGenuineB_SR, "GenuineB", "EWK Genuine-b")
        hGenuineB.setIsDataMC(isData=False, isMC=True)
        myStackList.append(hGenuineB)

        # Add the collision datato the histogram list        
        hData = histograms.Histo(rData_SR, "Data", "Data")
        hData.setIsDataMC(isData=True, isMC=False)
        myStackList.insert(0, hData)
        
        p = plots.DataMCPlot2( myStackList, saveFormats=[])
        p.setLuminosity(opts.intLumi)
        p.setDefaultStyles()

    # Draw the plot and save it
    hName = opts.histoKey #"test"
    plots.drawPlot(p, hName, **_kwargs)
    SavePlot(p, hName, os.path.join(opts.saveDir, opts.optMode), saveFormats = [".png"])

    #=========================================================================================
    # Calculate the Transfer Factor (TF) and save to file
    #=========================================================================================
    Verbose("Write the normalisation factors to a python file", True)
    fileName = os.path.join(opts.mcrab, "FakeBTransferFactors%s.py"% ( getModuleInfoString(opts) ) )
    manager.writeTransferFactorsToFile(fileName, opts)
    return
def PlotHistosAndCalculateTF(datasetsMgr, histoList, binLabels, opts):

    # Get the histogram customisations (keyword arguments)
    _kwargs = GetHistoKwargs(histoList[0])

    # Get the root histos for all datasets and Control Regions (CRs)
    regions = ["SR", "VR", "CRone", "CRtwo"]
    rhDict = GetRootHistos(datasetsMgr, histoList, regions, binLabels)

    #=========================================================================================
    # Calculate the Transfer Factor (TF) and save to file
    #=========================================================================================
    manager = FakeBNormalization.FakeBNormalizationManager(binLabels,
                                                           opts.mcrab,
                                                           opts.optMode,
                                                           verbose=False)
    if opts.inclusiveOnly:
        #manager.CalculateTransferFactor(binLabels[0], rhDict["CRone-FakeB"], rhDict["CRtwo-FakeB"])
        binLabel = "Inclusive"
        manager.CalculateTransferFactor("Inclusive",
                                        rhDict["FakeB-CRone-Inclusive"],
                                        rhDict["FakeB-CRtwo-Inclusive"])
    else:
        for bin in binLabels:
            manager.CalculateTransferFactor(bin,
                                            rhDict["FakeB-CRone-%s" % bin],
                                            rhDict["FakeB-CRtwo-%s" % bin])

    # Get unique a style for each region
    for k in rhDict:
        dataset = k.split("-")[0]
        region = k.split("-")[1]
        styles.getABCDStyle(region).apply(rhDict[k])
        if "FakeB" in k:
            styles.getFakeBStyle().apply(rhDict[k])
        # sr.apply(rhDict[k])

    # =========================================================================================
    # Create the final plot object
    # =========================================================================================
    rData_SR = rhDict["Data-SR-Inclusive"]
    rEWKGenuineB_SR = rhDict["EWK-SR-Inclusive-EWKGenuineB"]
    rBkgSum_SR = rhDict["FakeB-VR-Inclusive"].Clone("BkgSum-SR-Inclusive")
    rBkgSum_SR.Reset()

    if opts.inclusiveOnly:
        bin = "Inclusive"
        # Normalise the VR histogram with the Transfer Factor ( BkgSum = VR * (CR1/CR2) )
        binHisto_VR = rhDict["FakeB-VR-%s" % (bin)]
        VRtoSR_TF = manager.GetTransferFactor(bin)
        Print(
            "Applying TF = %s%0.6f%s to VR shape" %
            (ShellStyles.NoteStyle(), VRtoSR_TF, ShellStyles.NormalStyle()),
            True)
        binHisto_VR.Scale(VRtoSR_TF)
        # Add the normalised histogram to the final Inclusive SR (predicted) histo
        rBkgSum_SR.Add(binHisto_VR, +1)
    else:
        # For-loop: All bins
        for i, bin in enumerate(binLabels, 1):
            if bin == "Inclusive":
                continue
            # Normalise the VR histogram with the Transfer Factor ( BkgSum = VR * (CR1/CR2) )
            binHisto_VR = rhDict["FakeB-VR-%s" % (bin)]
            VRtoSR_TF = manager.GetTransferFactor(bin)
            Print(
                "Applying TF = %s%0.6f%s to VR shape" %
                (ShellStyles.NoteStyle(), VRtoSR_TF,
                 ShellStyles.NormalStyle()), i == 1)
            binHisto_VR.Scale(VRtoSR_TF)
            # Add the normalised histogram to the final Inclusive SR (predicted) histo
            rBkgSum_SR.Add(binHisto_VR, +1)

    #Print("Got Verification Region (VR) shape %s%s%s" % (ShellStyles.NoteStyle(), rFakeB_VR.GetName(), ShellStyles.NormalStyle()), True)

    # Normalise the VR histogram with the Transfer Factor ( BkgSum = VR * (CR1/CR2) )
    #VRtoSR_TF = manager.GetTransferFactor("Inclusive")
    #Print("Applying TF = %s%0.6f%s to VR shape" % (ShellStyles.NoteStyle(), VRtoSR_TF, ShellStyles.NormalStyle()), True)
    #rBkgSum_SR.Scale(VRtoSR_TF)

    # Plot histograms
    if opts.altPlot:
        # Add the SR EWK Genuine-b to the SR FakeB ( BkgSum = [FakeB] + [GenuineB-MC] = [VR * (CR1/CR2)] + [GenuineB-MC] )
        rBkgSum_SR.Add(rEWKGenuineB_SR, +1)

        # Change style
        styles.getGenuineBStyle().apply(rBkgSum_SR)

        # Remove unsupported settings of kwargs
        _kwargs["stackMCHistograms"] = False
        _kwargs["addLuminosityText"] = False

        # Create the plot
        p = plots.ComparisonManyPlot(rData_SR, [rBkgSum_SR], saveFormats=[])

        # Set draw / legend style
        p.histoMgr.setHistoDrawStyle("Data-SR-Inclusive", "P")
        p.histoMgr.setHistoLegendStyle("Data-SR-Inclusive", "LP")
        p.histoMgr.setHistoDrawStyle("BkgSum-SR-Inclusive", "HIST")
        p.histoMgr.setHistoLegendStyle("BkgSum-SR-Inclusive", "F")

        # Set legend labels
        p.histoMgr.setHistoLegendLabelMany({
            "Data-SR": "Data",
            "BkgSum-SR": "Fake-b + Gen-b",
        })
    else:
        # Create empty histogram stack list
        myStackList = []

        # Signal
        p2 = plots.DataMCPlot(datasetsMgr,
                              "ForTestQGLR/QGLR_SR/QGLR_SRInclusive",
                              saveFormats=[])

        hSignal_800 = p2.histoMgr.getHisto(
            'ChargedHiggs_HplusTB_HplusToTB_M_800').getRootHisto()
        hhSignal_800 = histograms.Histo(
            hSignal_800, 'ChargedHiggs_HplusTB_HplusToTB_M_800',
            "H^{+} m_{H^+}=800 GeV")
        hhSignal_800.setIsDataMC(isData=False, isMC=True)
        myStackList.append(hhSignal_800)

        hSignal_250 = p2.histoMgr.getHisto(
            'ChargedHiggs_HplusTB_HplusToTB_M_250').getRootHisto()
        hhSignal_250 = histograms.Histo(
            hSignal_250, 'ChargedHiggs_HplusTB_HplusToTB_M_250',
            "H^{+} m_{H^+}=250 GeV"
        )  #plots._legendLabels['ChargedHiggs_HplusTB_HplusToTB_M_250'])
        hhSignal_250.setIsDataMC(isData=False, isMC=True)
        #myStackList.append(hhSignal_250)

        hSignal_500 = p2.histoMgr.getHisto(
            'ChargedHiggs_HplusTB_HplusToTB_M_500').getRootHisto()
        hhSignal_500 = histograms.Histo(
            hSignal_500, 'ChargedHiggs_HplusTB_HplusToTB_M_500',
            "H^{+} m_{H^+}=500 GeV"
        )  #plots._legendLabels['ChargedHiggs_HplusTB_HplusToTB_M_500'])
        hhSignal_500.setIsDataMC(isData=False, isMC=True)
        #myStackList.append(hhSignal_500)

        hSignal_1000 = p2.histoMgr.getHisto(
            'ChargedHiggs_HplusTB_HplusToTB_M_1000').getRootHisto()
        hhSignal_1000 = histograms.Histo(
            hSignal_1000, 'ChargedHiggs_HplusTB_HplusToTB_M_1000',
            "H^{+} m_{H^+}=1000 GeV"
        )  #plots._legendLabels['ChargedHiggs_HplusTB_HplusToTB_M_500'])
        hhSignal_1000.setIsDataMC(isData=False, isMC=True)
        #myStackList.append(hhSignal_1000)

        # Add the FakeB data-driven background to the histogram list
        hFakeB = histograms.Histo(rBkgSum_SR, "FakeB", "Fake-b")
        hFakeB.setIsDataMC(isData=False, isMC=True)
        myStackList.append(hFakeB)

        # Add the EWKGenuineB MC background to the histogram list
        hGenuineB = histograms.Histo(rEWKGenuineB_SR, "GenuineB",
                                     "EWK Genuine-b")
        hGenuineB.setIsDataMC(isData=False, isMC=True)
        myStackList.append(hGenuineB)

        # Add the collision datato the histogram list
        hData = histograms.Histo(rData_SR, "Data", "Data")
        hData.setIsDataMC(isData=True, isMC=False)
        myStackList.insert(0, hData)

        p = plots.DataMCPlot2(myStackList, saveFormats=[])
        p.setLuminosity(opts.intLumi)
        p.setDefaultStyles()

    # Draw the plot and save it
    hName = "test"
    plots.drawPlot(p, hName, **_kwargs)
    SavePlot(p,
             hName,
             os.path.join(opts.saveDir, opts.optMode),
             saveFormats=[".png", ".pdf"])

    #==========================================================================================
    # Calculate Cut-Flow Efficiency
    #==========================================================================================
    kwargs = {
        "rebinX": 1,
        "xlabel": "QGLR",
        "ylabel": "Significance / %.02f ",
        "opts": {
            "ymin": 0.0,
            "ymaxfactor": 1.3
        },
        "createLegend": {
            "x1": 0.55,
            "y1": 0.70,
            "x2": 0.92,
            "y2": 0.92
        },
        #            "cutBox"           : {"cutValue": 0.0, "fillColor" : 16, "box": False, "line": False, "greaterThan": True},
    }

    efficiencyList = []
    xValues = []

    yValues_250 = []
    yValues_500 = []
    yValues_800 = []
    yValues_1000 = []
    yValues_Bkg = []

    nBins = hSignal_250.GetNbinsX() + 1

    hBkg = p.histoMgr.getHisto(
        "ChargedHiggs_HplusTB_HplusToTB_M_800").getRootHisto().Clone("Bkg")
    hBkg.Reset()

    # Bkg: FakeB + Genuine B
    hBkg.Add(hFakeB.getRootHisto(), +1)
    hBkg.Add(hGenuineB.getRootHisto(), +1)

    for i in range(0, nBins):

        # Cut value
        cut = hSignal_250.GetBinCenter(i)

        passed_250 = hSignal_250.Integral(i, hSignal_250.GetXaxis().GetNbins())
        passed_500 = hSignal_500.Integral(i, hSignal_500.GetXaxis().GetNbins())
        passed_800 = hSignal_800.Integral(i, hSignal_800.GetXaxis().GetNbins())
        passed_1000 = hSignal_1000.Integral(i,
                                            hSignal_1000.GetXaxis().GetNbins())

        passed_Bkg = hBkg.Integral(i, hBkg.GetXaxis().GetNbins())

        total_250 = hSignal_250.Integral()
        total_500 = hSignal_500.Integral()
        total_800 = hSignal_800.Integral()
        total_1000 = hSignal_1000.Integral()
        total_Bkg = hBkg.Integral()

        eff_250 = float(passed_250) / total_250
        eff_500 = float(passed_500) / total_500
        eff_800 = float(passed_800) / total_800
        eff_1000 = float(passed_1000) / total_1000

        eff_Bkg = float(passed_Bkg) / total_Bkg

        xValues.append(cut)
        yValues_250.append(eff_250)
        yValues_500.append(eff_500)
        yValues_800.append(eff_800)
        yValues_1000.append(eff_1000)

        yValues_Bkg.append(eff_Bkg)

    # Create the Efficiency Plot
    tGraph_250 = ROOT.TGraph(len(xValues), array.array("d", xValues),
                             array.array("d", yValues_250))
    tGraph_500 = ROOT.TGraph(len(xValues), array.array("d", xValues),
                             array.array("d", yValues_500))
    tGraph_800 = ROOT.TGraph(len(xValues), array.array("d", xValues),
                             array.array("d", yValues_800))
    tGraph_1000 = ROOT.TGraph(len(xValues), array.array("d", xValues),
                              array.array("d", yValues_1000))
    tGraph_Bkg = ROOT.TGraph(len(xValues), array.array("d", xValues),
                             array.array("d", yValues_Bkg))

    styles.getSignalStyleHToTB_M("200").apply(tGraph_250)
    styles.getSignalStyleHToTB_M("500").apply(tGraph_500)
    styles.getSignalStyleHToTB_M("800").apply(tGraph_800)
    styles.getSignalStyleHToTB_M("1000").apply(tGraph_1000)
    styles.getQCDLineStyle().apply(tGraph_Bkg)

    drawStyle = "CPE"
    effGraph_250 = histograms.HistoGraph(tGraph_250,
                                         "H^{+} m_{H^{+}} = 250 GeV", "lp",
                                         drawStyle)
    effGraph_500 = histograms.HistoGraph(tGraph_500,
                                         "H^{+} m_{H^{+}} = 500 GeV", "lp",
                                         drawStyle)
    effGraph_800 = histograms.HistoGraph(tGraph_800,
                                         "H^{+} m_{H^{+}} = 800 GeV", "lp",
                                         drawStyle)
    effGraph_1000 = histograms.HistoGraph(tGraph_1000,
                                          "H^{+} m_{H^{+}} = 1000 GeV", "lp",
                                          drawStyle)
    effGraph_Bkg = histograms.HistoGraph(tGraph_Bkg, "Bkg", "lp", drawStyle)

    efficiencyList.append(effGraph_250)
    efficiencyList.append(effGraph_500)
    efficiencyList.append(effGraph_800)
    efficiencyList.append(effGraph_1000)
    efficiencyList.append(effGraph_Bkg)

    # Efficiency plot
    pE = plots.PlotBase(efficiencyList, saveFormats=["pdf"])
    pE.createFrame("QGLR_Efficiency")
    pE.setEnergy("13")
    pE.getFrame().GetYaxis().SetLabelSize(18)
    pE.getFrame().GetXaxis().SetLabelSize(20)

    pE.getFrame().GetYaxis().SetTitle("Efficiency / 0.01")
    pE.getFrame().GetXaxis().SetTitle("QGLR Cut")

    # Add Standard Texts to plot
    histograms.addStandardTexts()

    # Customise Legend
    moveLegend = {"dx": -0.50, "dy": -0.5, "dh": -0.1}
    pE.setLegend(histograms.moveLegend(histograms.createLegend(),
                                       **moveLegend))

    pE.draw()
    #    plots.drawPlot(pE, "QGLR_Efficiency", **kwargs)
    SavePlot(pE,
             "QGLR_Efficiency",
             os.path.join(opts.saveDir, opts.optMode),
             saveFormats=[".png", ".pdf"])

    #==========================================================================================
    # Calculate Significance
    #==========================================================================================

    SignalName = "ChargedHiggs_HplusTB_HplusToTB_M_800"

    hSignif_250 = p.histoMgr.getHisto(SignalName).getRootHisto().Clone(
        SignalName)
    hSignif_500 = p.histoMgr.getHisto(SignalName).getRootHisto().Clone(
        SignalName)
    hSignif_800 = p.histoMgr.getHisto(SignalName).getRootHisto().Clone(
        SignalName)
    hSignif_1000 = p.histoMgr.getHisto(SignalName).getRootHisto().Clone(
        SignalName)

    hSignif_250.Reset()
    hSignif_500.Reset()
    hSignif_800.Reset()
    hSignif_1000.Reset()

    hBkg = p.histoMgr.getHisto(SignalName).getRootHisto().Clone("Bkg")
    hBkg.Reset()

    # Bkg: FakeB + Genuine B
    hBkg.Add(hFakeB.getRootHisto(), +1)
    hBkg.Add(hGenuineB.getRootHisto(), +1)

    nBins = hSignif_250.GetNbinsX() + 1

    # For-loop: All histo bins
    for i in range(1, nBins + 1):

        sigmaB = ROOT.Double(0)

        b = hBkg.IntegralAndError(i, nBins, sigmaB)

        s_250 = hSignal_250.Integral(i, nBins)
        s_500 = hSignal_500.Integral(i, nBins)
        s_800 = hSignal_800.Integral(i, nBins)
        s_1000 = hSignal_1000.Integral(i, nBins)

        # Calculate significance
        signif_250 = stat.significance(s_250, b, sigmaB,
                                       option="Simple")  #Asimov")
        signif_500 = stat.significance(s_500, b, sigmaB,
                                       option="Simple")  #Asimov")
        signif_800 = stat.significance(s_800, b, sigmaB,
                                       option="Simple")  #Asimov")
        signif_1000 = stat.significance(s_1000, b, sigmaB,
                                        option="Simple")  #"Asimov")

        # Set signif for this bin
        hSignif_250.SetBinContent(i, signif_250)
        hSignif_500.SetBinContent(i, signif_500)
        hSignif_800.SetBinContent(i, signif_800)
        hSignif_1000.SetBinContent(i, signif_1000)

        # Apply style
        s_250 = styles.getSignalStyleHToTB_M("200")
        s_250.apply(hSignif_250)

        s_500 = styles.getSignalStyleHToTB_M("500")
        s_500.apply(hSignif_500)

        s_800 = styles.getSignalStyleHToTB_M("800")
        s_800.apply(hSignif_800)

        s_1000 = styles.getSignalStyleHToTB_M("1000")
        s_1000.apply(hSignif_1000)

        hList = []
        hList.append(hSignif_250)
        hList.append(hSignif_500)
        hList.append(hSignif_800)
        hList.append(hSignif_1000)

        hSignif_250.SetName("H^{+} m_{H^{+}} = 250 GeV")
        hSignif_500.SetName("H^{+} m_{H^{+}} = 500 GeV")
        hSignif_800.SetName("H^{+} m_{H^{+}} = 800 GeV")
        hSignif_1000.SetName("H^{+} m_{H^{+}} = 1000 GeV")

    pS = plots.PlotBase(hList, saveFormats=["png", "pdf"])
    pS.setLuminosity(opts.intLumi)

    # Drawing style
    pS.histoMgr.setHistoDrawStyleAll("HIST")
    pS.histoMgr.setHistoLegendStyleAll("L")
    pS.histoMgr.forEachHisto(lambda h: h.getRootHisto().SetMarkerSize(1.0))
    pS.histoMgr.forEachHisto(
        lambda h: h.getRootHisto().SetLineStyle(ROOT.kSolid))
    pS.histoMgr.forEachHisto(
        lambda h: h.getRootHisto().SetMarkerStyle(ROOT.kFullCircle))

    # Draw the plot
    name = "QGLR_Signif" + "GE"

    plots.drawPlot(pS, name, **kwargs)
    SavePlot(pS,
             name,
             os.path.join(opts.saveDir, opts.optMode),
             saveFormats=[".png", ".pdf"])

    #=========================================================================================
    # Calculate the Transfer Factor (TF) and save to file
    #=========================================================================================
    Verbose("Write the normalisation factors to a python file", True)
    fileName = os.path.join(
        opts.mcrab, "FakeBTransferFactors%s.py" % (getModuleInfoString(opts)))
    manager.writeNormFactorFile(fileName, opts)
    return
def PlotAndFitTemplates(datasetsMgr, histoName, inclusiveFolder, opts):
    Verbose("PlotAndFitTemplates()")

    # Variable definition
    bkgName = "QCD"
    genuineBFolder = inclusiveFolder + "EWKGenuineB"
    fakeBFolder = inclusiveFolder + "EWKFakeB"
    baselineHisto = "%s/%s" % (inclusiveFolder, "Baseline_" + histoName)
    invertedHisto = "%s/%s" % (inclusiveFolder, "Inverted_" + histoName)

    # Create the histograms
    pBaseline = plots.DataMCPlot(datasetsMgr, baselineHisto)
    pInverted = plots.DataMCPlot(datasetsMgr, invertedHisto)

    # Get the desired histograms (Baseline)
    Data_baseline = pBaseline.histoMgr.getHisto("Data").getRootHisto().Clone(
        "Baseline Data")  #also legend entry name
    FakeB_baseline = pBaseline.histoMgr.getHisto("Data").getRootHisto().Clone(
        "Baseline " + bkgName)
    EWK_baseline = pBaseline.histoMgr.getHisto("EWK").getRootHisto().Clone(
        "Baseline EWK")

    # Get the desired histograms (Inverted)
    # Data_inverted  = pInverted.histoMgr.getHisto("Data").getRootHisto().Clone("Inverted Data") #not needed
    FakeB_inverted = pInverted.histoMgr.getHisto("Data").getRootHisto().Clone(
        "Inverted " + bkgName)
    EWK_inverted = pInverted.histoMgr.getHisto("EWK").getRootHisto().Clone(
        "Inverted EWK")

    # Subtact EWK-M Cfrom Data (QCD = Data - EWK)
    FakeB_baseline.Add(EWK_baseline, -1)
    FakeB_inverted.Add(EWK_inverted, -1)

    # Rebin the EWK-MC histo (significant fit improvement - opposite effect for QCD fit)
    EWK_baseline.RebinX(2)
    EWK_inverted.RebinX(2)
    FakeB_inverted.RebinX(1)
    if 0:
        print "+" * 100
        Print("FIXME: Optimal is 1 (i.e. bin width of 10 GeV/c^{2})")
        print "+" * 100
        FakeB_inverted.RebinX(2)

    # Create the final plot object
    compareHistos = [EWK_baseline]
    p = plots.ComparisonManyPlot(FakeB_inverted, compareHistos, saveFormats=[])

    # Apply styles
    p.histoMgr.forHisto("Inverted " + bkgName, styles.getFakeBStyle())
    p.histoMgr.forHisto("Baseline EWK", styles.getAltEWKStyle())

    # Set draw style
    p.histoMgr.setHistoDrawStyle("Inverted " + bkgName, "P")
    p.histoMgr.setHistoDrawStyle("Baseline EWK", "AP")

    # Set legend style
    p.histoMgr.setHistoLegendStyle("Inverted " + bkgName, "P")
    p.histoMgr.setHistoLegendStyle("Baseline EWK", "LP")

    # Set legend labels
    p.histoMgr.setHistoLegendLabelMany({
        "Baseline EWK": "EWK",
        "Inverted " + bkgName: "QCD",
    })

    #=========================================================================================
    # Set Minimizer Options
    #=========================================================================================
    '''
    https://root.cern.ch/root/htmldoc/guides/users-guide/FittingHistograms.html#the-th1fit-method
    https://root.cern.ch/root/html/src/ROOT__Math__MinimizerOptions.h.html#a14deB
    '''
    if 0:
        ROOT.Math.MinimizerOptions.SetDefaultMinimizer("Minuit", "Migrad")
        ROOT.Math.MinimizerOptions.SetDefaultStrategy(
            1)  # Speed = 0, Balance = 1, Robustness = 2
        ROOT.Math.MinimizerOptions.SetDefaultMaxFunctionCalls(
            5000)  # set maximum of function calls
        ROOT.Math.MinimizerOptions.SetDefaultMaxIterations(
            5000
        )  # set maximum iterations (one iteration can have many function calls)
    if 0:
        ROOT.Math.MinimizerOptions.SetDefaultMinimizer("Minuit", "Simplex")
        ROOT.Math.MinimizerOptions.SetDefaultMinimizer("Minuit", "Minimize")
        ROOT.Math.MinimizerOptions.SetDefaultMinimizer("Minuit",
                                                       "MigradImproved")
        ROOT.Math.MinimizerOptions.SetDefaultMinimizer("Minuit", "Scan")
        ROOT.Math.MinimizerOptions.SetDefaultMinimizer("Minuit", "Seek")
        ROOT.Math.MinimizerOptions.SetDefaultErrorDef(
            1
        )  # error definition (=1. for getting 1 sigma error for chi2 fits)
        ROOT.Math.MinimizerOptions.SetDefaultMaxFunctionCalls(
            1000000)  # set maximum of function calls
        ROOT.Math.MinimizerOptions.SetDefaultMaxIterations(
            1000000
        )  # set maximum iterations (one iteration can have many function calls)
        ROOT.Math.MinimizerOptions.SetDefaultPrecision(
            -1
        )  # precision in the objective function calculation (value <= 0 means left to default)
        ROOT.Math.MinimizerOptions.SetDefaultPrintLevel(
            1
        )  # None = -1, Reduced = 0, Normal = 1, ExtraForProblem = 2, Maximum = 3
        ROOT.Math.MinimizerOptions.SetDefaultTolerance(
            1e-03
        )  # Minuit/Minuit2 converge when the EDM is less a given tolerance. (default 1e-03)
    if 1:
        hLine = "=" * 45
        title = "{:^45}".format("Minimizer Options")
        print "\t", hLine
        print "\t", title
        print "\t", hLine
        minOpt = ROOT.Math.MinimizerOptions()
        minOpt.Print()
        print "\t", hLine, "\n"

    #=========================================================================================
    # Start fit process
    #=========================================================================================
    binLabels = ["Inclusive"]
    moduleInfoString = opts.optMode  #opts.dataEra + "_" + opts.searchMode + "_" + opts.optMode

    #=========================================================================================
    # Create templates (EWK fakes, EWK genuine, QCD; data template is created by manager)
    #=========================================================================================
    manager = QCDNormalization.QCDNormalizationManagerDefault(
        binLabels, opts.mcrab, moduleInfoString)

    Print(
        "Creating the normalization templates with appropriate template names",
        True)
    template_EWKFakeB_Baseline = manager.createTemplate(
        "EWKFakeB_Baseline")  #fixme-unused
    template_EWKFakeB_Inverted = manager.createTemplate(
        "EWKFakeB_Inverted")  #fixme-unused

    template_EWKInclusive_Baseline = manager.createTemplate(
        "EWKInclusive_Baseline")
    template_EWKInclusive_Inverted = manager.createTemplate(
        "EWKInclusive_Inverted")

    template_FakeB_Baseline = manager.createTemplate("QCD_Baseline")
    template_FakeB_Inverted = manager.createTemplate("QCD_Inverted")

    #========================================================================================
    # EWK
    #=========================================================================================
    '''
    Optimal fit (Chi2/D.O.F = 3.2)
    FITMIN  ;  80
    FITMAX  : 800
    BinWidth:  10 GeV/c^2
    par3    : -3.9174e-01 (fixed)
    '''
    Print("Setting the fit-function to the EWK template", False)
    FITMIN_EWK = 80
    FITMAX_EWK = 800
    par0 = [+7.1817e-01, 0.0, 1.0]  # cb_norm
    par1 = [+1.7684e+02, 150.0, 200.0]  # cb_mean
    par2 = [+2.7287e+01, 20.0, 40.0]  # cb_sigma (fixed for chiSq=2)
    par3 = [-3.9174e-01, -1.0, 0.0]  # cb_alpha (fixed for chiSq=2)
    par4 = [+2.5104e+01, 0.0, 50.0]  # cb_n
    par5 = [+7.4724e-05, 0.0, 1.0]  # expo_norm
    par6 = [-4.6848e-02, -1.0, 0.0]  # expo_a
    par7 = [+2.1672e+02, 200.0, 250.0]  # gaus_mean (fixed for chiSq=2)
    par8 = [+6.3201e+01, 20.0, 80.0]  # gaus_sigma
    template_EWKInclusive_Baseline.setFitter(
        QCDNormalization.FitFunction("EWKFunction",
                                     boundary=0,
                                     norm=1,
                                     rejectPoints=0), FITMIN_EWK, FITMAX_EWK)
    template_EWKInclusive_Baseline.setDefaultFitParam(
        defaultInitialValue=None,
        defaultLowerLimit=[
            par0[1], par1[1], par2[1], par3[0], par4[1], par5[1], par6[1],
            par7[1], par8[1]
        ],
        defaultUpperLimit=[
            par0[2], par1[2], par2[2], par3[0], par4[2], par5[2], par6[2],
            par7[2], par8[2]
        ])

    #=========================================================================================
    # QCD
    #=========================================================================================
    '''
    Optimal fit (Chi2/D.O.F = 25.6)
    FITMIN  :   80
    FITMAX  : 1000
    BinWidth:  5 GeV/c^2
    f_{QCD} : ~0.75118 +/- 0.00740 (data-driven plots looked great with this value)
    '''
    Print("Setting the fit-function to the QCD template", False)
    FITMIN_QCD = 90  #  120
    FITMAX_QCD = 1000  # 1000
    bPtochos = False
    if bPtochos:
        par0 = [0.92, 0.0, 1.0]  # lognorm_norm
        par1 = [220.00, 180.0, 500.0]  # lognorm_mean
        par2 = [1.44, 0.4, 10.0]  # lognorm_shape
        par3 = [0.0, 0.0, 1.0]  # exp_const
        par4 = [-0.01, -2.0, 0.0]  # exp_coeff
        par5 = [220.00, 100.0, 400.0]  # gaus_mean
        par6 = [40.00, 0.0, 60.0]  # gaus_sigma
        template_FakeB_Inverted.setFitter(
            QCDNormalization.FitFunction("QCDFunction",
                                         boundary=0,
                                         norm=1,
                                         rejectPoints=0), FITMIN_QCD,
            FITMAX_QCD)
        template_FakeB_Inverted.setDefaultFitParam(
            defaultInitialValue=[
                par0[0], par1[0], par2[0], par3[0], par4[0], par5[0], par6[0]
            ],
            defaultLowerLimit=[
                par0[1], par1[1], par2[1], par3[1], par4[1], par5[1], par6[1]
            ],
            defaultUpperLimit=[
                par0[2], par1[2], par2[2], par3[2], par4[2], par5[2], par6[2]
            ])
    else:
        # par0 = [9.2578e-01,   0.0 ,    1.0] # lognorm_norm
        # par1 = [2.3662e+02, 200.0 , 1000.0] # lognorm_mean
        # par2 = [1.4436e+00,   0.5,    10.0] # lognorm_shape
        # par3 = [2.2575e+02, 100.0 ,  500.0] # gaus_mean
        # par4 = [3.6716e+01,   0.0 ,   60.0] # gaus_sigma
        par0 = [0.92, 0.0, 1.0]  # lognorm_norm
        par1 = [220.00, 180.0, 500.0]  # lognorm_mean
        par2 = [1.44, 0.4, 10.0]  # lognorm_shape
        par3 = [220.00, 100.0, 400.0]  # gaus_mean
        par4 = [40.00, 0.0, 60.0]  # gaus_sigma
        template_FakeB_Inverted.setFitter(
            QCDNormalization.FitFunction("QCDFunctionAlt",
                                         boundary=0,
                                         norm=1,
                                         rejectPoints=0), FITMIN_QCD,
            FITMAX_QCD)
        template_FakeB_Inverted.setDefaultFitParam(
            defaultInitialValue=[par0[0], par1[0], par2[0], par3[0], par4[0]],
            defaultLowerLimit=[par0[1], par1[1], par2[1], par3[1], par4[1]],
            defaultUpperLimit=[par0[2], par1[2], par2[2], par3[2], par4[2]])

    #=========================================================================================
    # Set histograms to the templates
    #=========================================================================================
    Print("Adding the appropriate histogram to each of the the templates",
          False)
    template_EWKFakeB_Baseline.setHistogram(EWK_baseline, "Inclusive")  #fixme
    template_EWKFakeB_Inverted.setHistogram(EWK_inverted, "Inclusive")  #fixme

    template_EWKInclusive_Baseline.setHistogram(EWK_baseline, "Inclusive")
    template_EWKInclusive_Inverted.setHistogram(EWK_inverted, "Inclusive")

    template_FakeB_Baseline.setHistogram(FakeB_baseline, "Inclusive")
    template_FakeB_Inverted.setHistogram(FakeB_inverted, "Inclusive")

    #=========================================================================================
    # Fit individual templates to histogram "Data_baseline", with custom fit options
    #=========================================================================================
    fitOptions = "R L W 0 Q"  #"R B L W 0 Q M"
    FITMIN_DATA = 80
    FITMAX_DATA = 1000
    manager.calculateNormalizationCoefficients(Data_baseline, fitOptions,
                                               FITMIN_DATA, FITMAX_DATA)

    Verbose("Write the normalisation factors to a python file", True)
    fileName = os.path.join(
        opts.mcrab,
        "QCDInvertedNormalizationFactors%s.py" % (getModuleInfoString(opts)))
    manager.writeNormFactorFile(fileName, opts)

    # Not really needed to plot the histograms again
    if 1:
        saveName = histoName
        plots.drawPlot(
            p, saveName,
            **GetHistoKwargs(histoName))  #the "**" unpacks the kwargs_
        SavePlot(p, saveName, os.path.join(opts.saveDir, "Fit", opts.optMode))
    return
Beispiel #7
0
def PlotHistosAndCalculateTF(runRange, datasetsMgr, histoList, binLabels,
                             opts):

    # Get the histogram customisations (keyword arguments)
    _kwargs = GetHistoKwargs(histoList[0])

    # Get the root histos for all datasets and Control Regions (CRs)
    regions = ["SR", "VR", "CRone", "CRtwo", "CRthree", "CRfour"]
    rhDict = GetRootHistos(datasetsMgr, histoList, regions, binLabels)

    #=========================================================================================
    # Calculate the Transfer Factor (TF) and save to file
    #=========================================================================================
    manager = FakeBNormalization.FakeBNormalizationManager(binLabels,
                                                           opts.mcrab,
                                                           opts.optMode,
                                                           verbose=False)
    if opts.inclusiveOnly:
        binLabel = "Inclusive"
        manager.CalculateTransferFactor("Inclusive",
                                        rhDict["FakeB-CRone-Inclusive"],
                                        rhDict["FakeB-CRtwo-Inclusive"],
                                        rhDict["FakeB-CRthree-Inclusive"],
                                        rhDict["FakeB-CRfour-Inclusive"])
    else:
        for bin in binLabels:
            manager.CalculateTransferFactor(bin,
                                            rhDict["FakeB-CRone-%s" % bin],
                                            rhDict["FakeB-CRtwo-%s" % bin],
                                            rhDict["FakeB-CRthree-%s" % bin],
                                            rhDict["FakeB-CRfour-%s" % bin])

    # Get unique a style for each region
    for k in rhDict:
        dataset = k.split("-")[0]
        region = k.split("-")[1]
        styles.getABCDStyle(region).apply(rhDict[k])
        if "FakeB" in k:
            styles.getFakeBStyle().apply(rhDict[k])
        # sr.apply(rhDict[k])

    # =========================================================================================
    # Create the final plot object
    # =========================================================================================
    rData_SR = rhDict["Data-SR-Inclusive"]
    rEWKGenuineB_SR = rhDict["EWK-SR-Inclusive-EWKGenuineB"]
    rBkgSum_SR = rhDict["FakeB-VR-Inclusive"].Clone("BkgSum-SR-Inclusive")
    rBkgSum_SR.Reset()

    if opts.inclusiveOnly:
        bin = "Inclusive"
        # Normalise the VR histogram with the Transfer Factor ( BkgSum = VR * (CR1/CR2) )
        binHisto_VR = rhDict["FakeB-VR-%s" % (bin)]
        VRtoSR_TF = manager.GetTransferFactor(bin)
        Verbose(
            "Applying TF = %s%0.6f%s to VR shape" %
            (ShellStyles.NoteStyle(), VRtoSR_TF, ShellStyles.NormalStyle()),
            True)
        binHisto_VR.Scale(VRtoSR_TF)
        # Add the normalised histogram to the final Inclusive SR (predicted) histo
        rBkgSum_SR.Add(binHisto_VR, +1)
    else:
        # For-loop: All bins
        for i, bin in enumerate(binLabels, 1):
            if bin == "Inclusive":
                continue
            # Normalise the VR histogram with the Transfer Factor ( BkgSum = VR * (CR1/CR2) )
            binHisto_VR = rhDict["FakeB-VR-%s" % (bin)]
            VRtoSR_TF = manager.GetTransferFactor(bin)
            Verbose(
                "Applying TF = %s%0.6f%s to VR shape" %
                (ShellStyles.NoteStyle(), VRtoSR_TF,
                 ShellStyles.NormalStyle()), i == 1)
            binHisto_VR.Scale(VRtoSR_TF)
            # Add the normalised histogram to the final Inclusive SR (predicted) histo
            rBkgSum_SR.Add(binHisto_VR, +1)

    # Plot histograms
    if opts.altPlot:
        # Add the SR EWK Genuine-b to the SR FakeB ( BkgSum = [FakeB] + [GenuineB-MC] = [VR * (CR1/CR2)] + [GenuineB-MC] )
        rBkgSum_SR.Add(rEWKGenuineB_SR, +1)

        # Change style
        styles.getGenuineBStyle().apply(rBkgSum_SR)

        # Remove unsupported settings of kwargs
        _kwargs["stackMCHistograms"] = False
        _kwargs["addLuminosityText"] = False

        # Create the plot
        p = plots.ComparisonManyPlot(rData_SR, [rBkgSum_SR], saveFormats=[])

        # Set draw / legend style
        p.histoMgr.setHistoDrawStyle("Data-SR-Inclusive", "P")
        p.histoMgr.setHistoLegendStyle("Data-SR-Inclusive", "LP")
        p.histoMgr.setHistoDrawStyle("BkgSum-SR-Inclusive", "HIST")
        p.histoMgr.setHistoLegendStyle("BkgSum-SR-Inclusive", "F")

        # Set legend labels
        p.histoMgr.setHistoLegendLabelMany({
            "Data-SR": "Data",
            "BkgSum-SR": "Fake-b + Gen-b",
        })
    else:
        # Create empty histogram stack list
        myStackList = []

        # Add the FakeB data-driven background to the histogram list
        hFakeB = histograms.Histo(rBkgSum_SR, "FakeB", "Fake-b")
        hFakeB.setIsDataMC(isData=False, isMC=True)
        myStackList.append(hFakeB)

        # Add the EWKGenuineB MC background to the histogram list
        hGenuineB = histograms.Histo(rEWKGenuineB_SR, "GenuineB",
                                     "EWK Genuine-b")
        hGenuineB.setIsDataMC(isData=False, isMC=True)
        myStackList.append(hGenuineB)

        # Add the collision datato the histogram list
        hData = histograms.Histo(rData_SR, "Data", "Data")
        hData.setIsDataMC(isData=True, isMC=False)
        myStackList.insert(0, hData)

        p = plots.DataMCPlot2(myStackList, saveFormats=[])
        p.setLuminosity(opts.intLumi)
        p.setDefaultStyles()

    # Draw the plot and save it
    hName = opts.histoKey
    plots.drawPlot(p, hName, **_kwargs)
    SavePlot(p,
             hName,
             os.path.join(opts.saveDir, opts.optMode),
             saveFormats=[".png"])

    #=========================================================================================
    # Calculate the Transfer Factor (TF) and save to file
    #=========================================================================================
    Verbose("Write the normalisation factors to a python file", True)
    fileName = os.path.join(opts.mcrab,
                            "FakeBTransferFactors_%s.py" % (runRange))
    manager.writeTransferFactorsToFile(fileName, opts)
    return
def PlotHistosAndCalculateTF(datasetsMgr, histoList, binLabels, opts):

    # Get the histogram customisations (keyword arguments)
    _kwargs = GetHistoKwargs(histoList[0])

    # Get the root histos for all datasets and Control Regions (CRs)
    regions = ["SR", "VR", "CRone", "CRtwo"]
    rhDict  = GetRootHistos(datasetsMgr, histoList, regions, binLabels)

    #=========================================================================================
    # Calculate the Transfer Factor (TF) and save to file
    #=========================================================================================
    manager = FakeBNormalization.FakeBNormalizationManager(binLabels, opts.mcrab, opts.optMode, verbose=False)
    if opts.inclusiveOnly:
        #manager.CalculateTransferFactor(binLabels[0], rhDict["CRone-FakeB"], rhDict["CRtwo-FakeB"])
        binLabel = "Inclusive"
        manager.CalculateTransferFactor("Inclusive", rhDict["FakeB-CRone-Inclusive"], rhDict["FakeB-CRtwo-Inclusive"])
    else:
        for bin in binLabels:
            manager.CalculateTransferFactor(bin, rhDict["FakeB-CRone-%s" % bin], rhDict["FakeB-CRtwo-%s" % bin])

    # Get unique a style for each region
    for k in rhDict:
        dataset = k.split("-")[0]
        region  = k.split("-")[1]
        styles.getABCDStyle(region).apply(rhDict[k])
        if "FakeB" in k:
            styles.getFakeBStyle().apply(rhDict[k])
        # sr.apply(rhDict[k])

    # =========================================================================================
    # Create the final plot object
    # =========================================================================================
    rData_SR        = rhDict["Data-SR-Inclusive"] 
    rEWKGenuineB_SR = rhDict["EWK-SR-Inclusive-EWKGenuineB"]
    rBkgSum_SR      = rhDict["FakeB-VR-Inclusive"].Clone("BkgSum-SR-Inclusive")
    rBkgSum_SR.Reset()

    if opts.inclusiveOnly:
        bin = "Inclusive"
        # Normalise the VR histogram with the Transfer Factor ( BkgSum = VR * (CR1/CR2) )
        binHisto_VR = rhDict["FakeB-VR-%s" % (bin)]
        VRtoSR_TF   = manager.GetTransferFactor(bin)
        Print("Applying TF = %s%0.6f%s to VR shape" % (ShellStyles.NoteStyle(), VRtoSR_TF, ShellStyles.NormalStyle()), True)
        binHisto_VR.Scale(VRtoSR_TF) 
                # Add the normalised histogram to the final Inclusive SR (predicted) histo
        rBkgSum_SR.Add(binHisto_VR, +1)
    else:
        # For-loop: All bins
        for i, bin in enumerate(binLabels, 1):
            if bin == "Inclusive":
                continue
            # Normalise the VR histogram with the Transfer Factor ( BkgSum = VR * (CR1/CR2) )
            binHisto_VR = rhDict["FakeB-VR-%s" % (bin)]
            VRtoSR_TF   = manager.GetTransferFactor(bin)
            Print("Applying TF = %s%0.6f%s to VR shape" % (ShellStyles.NoteStyle(), VRtoSR_TF, ShellStyles.NormalStyle()), i==1)
            binHisto_VR.Scale(VRtoSR_TF) 
            # Add the normalised histogram to the final Inclusive SR (predicted) histo
            rBkgSum_SR.Add(binHisto_VR, +1)

    #Print("Got Verification Region (VR) shape %s%s%s" % (ShellStyles.NoteStyle(), rFakeB_VR.GetName(), ShellStyles.NormalStyle()), True)

    # Normalise the VR histogram with the Transfer Factor ( BkgSum = VR * (CR1/CR2) )
    #VRtoSR_TF = manager.GetTransferFactor("Inclusive")
    #Print("Applying TF = %s%0.6f%s to VR shape" % (ShellStyles.NoteStyle(), VRtoSR_TF, ShellStyles.NormalStyle()), True)
    #rBkgSum_SR.Scale(VRtoSR_TF) 
    
    # Plot histograms    
    if opts.altPlot:
        # Add the SR EWK Genuine-b to the SR FakeB ( BkgSum = [FakeB] + [GenuineB-MC] = [VR * (CR1/CR2)] + [GenuineB-MC] )
        rBkgSum_SR.Add(rEWKGenuineB_SR, +1) 

        # Change style
        styles.getGenuineBStyle().apply(rBkgSum_SR)

        # Remove unsupported settings of kwargs
        _kwargs["stackMCHistograms"] = False
        _kwargs["addLuminosityText"] = False

        # Create the plot
        p = plots.ComparisonManyPlot(rData_SR, [rBkgSum_SR], saveFormats=[])

        # Set draw / legend style
        p.histoMgr.setHistoDrawStyle("Data-SR-Inclusive", "P")
        p.histoMgr.setHistoLegendStyle("Data-SR-Inclusive" , "LP")
        p.histoMgr.setHistoDrawStyle("BkgSum-SR-Inclusive", "HIST")
        p.histoMgr.setHistoLegendStyle("BkgSum-SR-Inclusive" , "F")

        # Set legend labels
        p.histoMgr.setHistoLegendLabelMany({
                "Data-SR"       : "Data",
                "BkgSum-SR"     : "Fake-b + Gen-b",
                })
    else:
        # Create empty histogram stack list
        myStackList = []
        
        # Signal
        p2 = plots.DataMCPlot(datasetsMgr, "ForTestQGLR/QGLR_SR/QGLR_SRInclusive", saveFormats=[])
        
        hSignal_800 = p2.histoMgr.getHisto('ChargedHiggs_HplusTB_HplusToTB_M_800').getRootHisto()
        hhSignal_800= histograms.Histo(hSignal_800, 'ChargedHiggs_HplusTB_HplusToTB_M_800', "H^{+} m_{H^+}=800 GeV")
        hhSignal_800.setIsDataMC(isData=False, isMC=True)
        myStackList.append(hhSignal_800)
        
        hSignal_250 = p2.histoMgr.getHisto('ChargedHiggs_HplusTB_HplusToTB_M_250').getRootHisto()
        hhSignal_250= histograms.Histo(hSignal_250, 'ChargedHiggs_HplusTB_HplusToTB_M_250', "H^{+} m_{H^+}=250 GeV")#plots._legendLabels['ChargedHiggs_HplusTB_HplusToTB_M_250'])
        hhSignal_250.setIsDataMC(isData=False, isMC=True)
        #myStackList.append(hhSignal_250)
                
        hSignal_500 = p2.histoMgr.getHisto('ChargedHiggs_HplusTB_HplusToTB_M_500').getRootHisto()
        hhSignal_500= histograms.Histo(hSignal_500, 'ChargedHiggs_HplusTB_HplusToTB_M_500', "H^{+} m_{H^+}=500 GeV")#plots._legendLabels['ChargedHiggs_HplusTB_HplusToTB_M_500'])
        hhSignal_500.setIsDataMC(isData=False, isMC=True)
        #myStackList.append(hhSignal_500)

        hSignal_1000 = p2.histoMgr.getHisto('ChargedHiggs_HplusTB_HplusToTB_M_1000').getRootHisto()
        hhSignal_1000= histograms.Histo(hSignal_1000, 'ChargedHiggs_HplusTB_HplusToTB_M_1000', "H^{+} m_{H^+}=1000 GeV")#plots._legendLabels['ChargedHiggs_HplusTB_HplusToTB_M_500'])
        hhSignal_1000.setIsDataMC(isData=False, isMC=True)
        #myStackList.append(hhSignal_1000)
        
        # Add the FakeB data-driven background to the histogram list    
        hFakeB = histograms.Histo(rBkgSum_SR, "FakeB", "Fake-b")
        hFakeB.setIsDataMC(isData=False, isMC=True)
        myStackList.append(hFakeB)
        
        # Add the EWKGenuineB MC background to the histogram list
        hGenuineB = histograms.Histo(rEWKGenuineB_SR, "GenuineB", "EWK Genuine-b")
        hGenuineB.setIsDataMC(isData=False, isMC=True)
        myStackList.append(hGenuineB)

        # Add the collision datato the histogram list        
        hData = histograms.Histo(rData_SR, "Data", "Data")
        hData.setIsDataMC(isData=True, isMC=False)
        myStackList.insert(0, hData)
        
        p = plots.DataMCPlot2( myStackList, saveFormats=[])
        p.setLuminosity(opts.intLumi)
        p.setDefaultStyles()

        
    # Draw the plot and save it
    hName = "test"
    plots.drawPlot(p, hName, **_kwargs)
    SavePlot(p, hName, os.path.join(opts.saveDir, opts.optMode), saveFormats = [".png", ".pdf"])
    
    #==========================================================================================
    # Calculate Cut-Flow Efficiency
    #==========================================================================================
    kwargs = {
        "rebinX" : 1,
        "xlabel" : "QGLR",
        "ylabel" : "Significance / %.02f ",
        "opts"   : {"ymin": 0.0, "ymaxfactor": 1.3},
        "createLegend": {"x1": 0.55, "y1": 0.70, "x2": 0.92, "y2": 0.92},
        #            "cutBox"           : {"cutValue": 0.0, "fillColor" : 16, "box": False, "line": False, "greaterThan": True},
        }
    
    
    efficiencyList = [] 
    xValues = []
    
    yValues_250 = []
    yValues_500 = []
    yValues_800 = []
    yValues_1000 = []
    yValues_Bkg = []


    nBins = hSignal_250.GetNbinsX()+1

    hBkg = p.histoMgr.getHisto("ChargedHiggs_HplusTB_HplusToTB_M_800").getRootHisto().Clone("Bkg")
    hBkg.Reset()

    # Bkg: FakeB + Genuine B
    hBkg.Add(hFakeB.getRootHisto(), +1)
    hBkg.Add(hGenuineB.getRootHisto(), +1)

    for i in range (0, nBins):
        
        # Cut value 
        cut = hSignal_250.GetBinCenter(i)
        
        passed_250  = hSignal_250.Integral(i, hSignal_250.GetXaxis().GetNbins())
        passed_500  = hSignal_500.Integral(i, hSignal_500.GetXaxis().GetNbins())
        passed_800  = hSignal_800.Integral(i, hSignal_800.GetXaxis().GetNbins())
        passed_1000 = hSignal_1000.Integral(i, hSignal_1000.GetXaxis().GetNbins())
        
        passed_Bkg  = hBkg.Integral(i, hBkg.GetXaxis().GetNbins())
        
        total_250   = hSignal_250.Integral()
        total_500   = hSignal_500.Integral()
        total_800   = hSignal_800.Integral()
        total_1000  = hSignal_1000.Integral()
        total_Bkg   = hBkg.Integral()
         
        eff_250  = float(passed_250)/total_250
        eff_500  = float(passed_500)/total_500
        eff_800  = float(passed_800)/total_800
        eff_1000 = float(passed_1000)/total_1000
        
        eff_Bkg = float(passed_Bkg)/total_Bkg
        
        xValues.append(cut)
        yValues_250.append(eff_250)
        yValues_500.append(eff_500)
        yValues_800.append(eff_800)
        yValues_1000.append(eff_1000)
        
        yValues_Bkg.append(eff_Bkg)
        
    # Create the Efficiency Plot
    tGraph_250 = ROOT.TGraph(len(xValues), array.array("d", xValues), array.array("d", yValues_250))
    tGraph_500 = ROOT.TGraph(len(xValues), array.array("d", xValues), array.array("d", yValues_500))
    tGraph_800 = ROOT.TGraph(len(xValues), array.array("d", xValues), array.array("d", yValues_800))
    tGraph_1000 = ROOT.TGraph(len(xValues), array.array("d", xValues), array.array("d", yValues_1000))
    tGraph_Bkg  = ROOT.TGraph(len(xValues), array.array("d", xValues), array.array("d", yValues_Bkg))

    styles.getSignalStyleHToTB_M("200").apply(tGraph_250)
    styles.getSignalStyleHToTB_M("500").apply(tGraph_500)
    styles.getSignalStyleHToTB_M("800").apply(tGraph_800)
    styles.getSignalStyleHToTB_M("1000").apply(tGraph_1000)
    styles.getQCDLineStyle().apply(tGraph_Bkg)
    
    drawStyle = "CPE"
    effGraph_250  = histograms.HistoGraph(tGraph_250, "H^{+} m_{H^{+}} = 250 GeV", "lp", drawStyle)
    effGraph_500  = histograms.HistoGraph(tGraph_500, "H^{+} m_{H^{+}} = 500 GeV", "lp", drawStyle)
    effGraph_800  = histograms.HistoGraph(tGraph_800, "H^{+} m_{H^{+}} = 800 GeV", "lp", drawStyle)
    effGraph_1000 = histograms.HistoGraph(tGraph_1000, "H^{+} m_{H^{+}} = 1000 GeV", "lp", drawStyle)
    effGraph_Bkg  = histograms.HistoGraph(tGraph_Bkg, "Bkg", "lp", drawStyle)
    
    efficiencyList.append(effGraph_250)
    efficiencyList.append(effGraph_500)
    efficiencyList.append(effGraph_800)
    efficiencyList.append(effGraph_1000)
    efficiencyList.append(effGraph_Bkg)
    
    # Efficiency plot
    pE = plots.PlotBase(efficiencyList, saveFormats=["pdf"])
    pE.createFrame("QGLR_Efficiency")
    pE.setEnergy("13")
    pE.getFrame().GetYaxis().SetLabelSize(18)
    pE.getFrame().GetXaxis().SetLabelSize(20)
    
    pE.getFrame().GetYaxis().SetTitle("Efficiency / 0.01")
    pE.getFrame().GetXaxis().SetTitle("QGLR Cut")
    
    # Add Standard Texts to plot
    histograms.addStandardTexts()
    
    # Customise Legend
    moveLegend = {"dx": -0.50, "dy": -0.5, "dh": -0.1}
    pE.setLegend(histograms.moveLegend(histograms.createLegend(), **moveLegend))
    
    pE.draw()
#    plots.drawPlot(pE, "QGLR_Efficiency", **kwargs)
    SavePlot(pE, "QGLR_Efficiency", os.path.join(opts.saveDir, opts.optMode), saveFormats=[".png", ".pdf"] )
    


    #==========================================================================================
    # Calculate Significance
    #==========================================================================================
                
    SignalName = "ChargedHiggs_HplusTB_HplusToTB_M_800"
    
    hSignif_250  = p.histoMgr.getHisto(SignalName).getRootHisto().Clone(SignalName)
    hSignif_500  = p.histoMgr.getHisto(SignalName).getRootHisto().Clone(SignalName)
    hSignif_800  = p.histoMgr.getHisto(SignalName).getRootHisto().Clone(SignalName)
    hSignif_1000 = p.histoMgr.getHisto(SignalName).getRootHisto().Clone(SignalName)
    
    hSignif_250.Reset()
    hSignif_500.Reset()
    hSignif_800.Reset()
    hSignif_1000.Reset()
    
    hBkg = p.histoMgr.getHisto(SignalName).getRootHisto().Clone("Bkg")
    hBkg.Reset()
    
    # Bkg: FakeB + Genuine B
    hBkg.Add(hFakeB.getRootHisto(), +1)
    hBkg.Add(hGenuineB.getRootHisto(), +1)
    
    nBins = hSignif_250.GetNbinsX()+1

    # For-loop: All histo bins
    for i in range (1, nBins+1):
    
        sigmaB = ROOT.Double(0)
        
        b = hBkg.IntegralAndError(i, nBins, sigmaB)
        
        s_250 = hSignal_250.Integral(i, nBins)
        s_500 = hSignal_500.Integral(i, nBins)
        s_800 = hSignal_800.Integral(i, nBins)
        s_1000 = hSignal_1000.Integral(i, nBins)
        
        # Calculate significance
        signif_250 = stat.significance(s_250, b, sigmaB, option="Simple")#Asimov")
        signif_500 = stat.significance(s_500, b, sigmaB, option="Simple")#Asimov")
        signif_800 = stat.significance(s_800, b, sigmaB, option="Simple")#Asimov")
        signif_1000 = stat.significance(s_1000, b, sigmaB, option="Simple")#"Asimov")

        # Set signif for this bin
        hSignif_250.SetBinContent(i, signif_250)
        hSignif_500.SetBinContent(i, signif_500)
        hSignif_800.SetBinContent(i, signif_800)
        hSignif_1000.SetBinContent(i, signif_1000)
        
        # Apply style
        s_250 = styles.getSignalStyleHToTB_M("200")
        s_250.apply(hSignif_250)
        
        s_500 = styles.getSignalStyleHToTB_M("500")
        s_500.apply(hSignif_500)
        
        s_800 = styles.getSignalStyleHToTB_M("800")
        s_800.apply(hSignif_800)

        s_1000 = styles.getSignalStyleHToTB_M("1000")
        s_1000.apply(hSignif_1000)
        
        hList = []
        hList.append(hSignif_250)
        hList.append(hSignif_500)
        hList.append(hSignif_800)
        hList.append(hSignif_1000)
        
        hSignif_250.SetName("H^{+} m_{H^{+}} = 250 GeV")
        hSignif_500.SetName("H^{+} m_{H^{+}} = 500 GeV")
        hSignif_800.SetName("H^{+} m_{H^{+}} = 800 GeV")
        hSignif_1000.SetName("H^{+} m_{H^{+}} = 1000 GeV")
        
    pS = plots.PlotBase(hList, saveFormats=["png", "pdf"])
    pS.setLuminosity(opts.intLumi)
        
    # Drawing style
    pS.histoMgr.setHistoDrawStyleAll("HIST")
    pS.histoMgr.setHistoLegendStyleAll("L")
    pS.histoMgr.forEachHisto(lambda h: h.getRootHisto().SetMarkerSize(1.0))
    pS.histoMgr.forEachHisto(lambda h: h.getRootHisto().SetLineStyle(ROOT.kSolid))
    pS.histoMgr.forEachHisto(lambda h: h.getRootHisto().SetMarkerStyle(ROOT.kFullCircle))
    
    # Draw the plot
    name = "QGLR_Signif" + "GE"
    
    plots.drawPlot(pS, name, **kwargs)
    SavePlot(pS, name, os.path.join(opts.saveDir, opts.optMode), saveFormats=[".png", ".pdf"] ) 
    

        


    #=========================================================================================
    # Calculate the Transfer Factor (TF) and save to file
    #=========================================================================================
    Verbose("Write the normalisation factors to a python file", True)
    fileName = os.path.join(opts.mcrab, "FakeBTransferFactors%s.py"% ( getModuleInfoString(opts) ) )
    manager.writeNormFactorFile(fileName, opts)
    return
def PlotHistos(noSF_datasetsMgr, withCR1SF_datasetsMgr, withCR2SF_datasetsMgr, num_histoList, den_histoList,  opts):    
    
    # Get the histogram customisations (keyword arguments)
    _kwargs = GetHistoKwargs(num_histoList[0])
    
    # Get the root histos for all datasets and Control Regions (CRs)
    regions = ["SR", "VR", "CR1", "CR2"]
    labels  = ["Genuine", "Fake", "Inclusive"]
    
    #==========================================================================================
    # Get Dictionaries
    #==========================================================================================
    rhDict_den_noSF      = GetRootHistos(noSF_datasetsMgr,      den_histoList, regions)
    rhDict_num_noSF      = GetRootHistos(noSF_datasetsMgr,      num_histoList, regions)
    rhDict_num_withCR1SF = GetRootHistos(withCR1SF_datasetsMgr, num_histoList, regions) # Scale Factors from CR1 are only applied in the Numerator on Fake TT
    rhDict_num_withCR2SF = GetRootHistos(withCR2SF_datasetsMgr, num_histoList, regions) # Scale Factors from CR2 are only applied in the Numerator on EWK+QCD+ST
    
    #==========================================================================================
    # Normalization Factors (see: getNormalization.py)
    #==========================================================================================
    f1 = 0.602756; f2=0.902921;

    # =========================================================================================
    # (A) Apply Normalization Factors (see: getNormalizations.py)
    # =========================================================================================
    
    # Normalize all histograms (QCD and TT) to normalization factors
    for re in regions:
        
        rhDict_den_noSF["NormQCD-"+re+"-Inclusive"] = rhDict_den_noSF["QCD-"+re+"-Inclusive"].Clone("NormQCD-"+re+"-Inclusive")
        rhDict_den_noSF["NormQCD-"+re+"-Inclusive"].Scale(f1)

        rhDict_num_noSF["NormQCD-"+re+"-Inclusive"] =rhDict_num_noSF["QCD-"+re+"-Inclusive"].Clone("NormQCD-"+re+"-Inclusive")
        rhDict_num_noSF["NormQCD-"+re+"-Inclusive"].Scale(f1)

        rhDict_num_withCR2SF["NormQCD-"+re+"-Inclusive"] = rhDict_num_withCR2SF["QCD-"+re+"-Inclusive"].Clone("NormQCD-"+re+"-Inclusive")
        rhDict_num_withCR2SF["NormQCD-"+re+"-Inclusive"].Scale(f1)
        
        for la in labels:
            
            rhDict_den_noSF["NormTT-"+re+"-"+la] = rhDict_den_noSF["TT-"+re+"-"+la].Clone("NormTT-"+re+"-"+la)
            rhDict_den_noSF["NormTT-"+re+"-"+la].Scale(f2)
            
            rhDict_num_noSF["NormTT-"+re+"-"+la] = rhDict_num_noSF["TT-"+re+"-"+la].Clone("NormTT-"+re+"-"+la)
            rhDict_num_noSF["NormTT-"+re+"-"+la].Scale(f2)
            
            rhDict_num_withCR1SF["NormTT-"+re+"-"+la] = rhDict_num_withCR1SF["TT-"+re+"-"+la].Clone("NormTT-"+re+"-"+la)
            rhDict_num_withCR1SF["NormTT-"+re+"-"+la].Scale(f2)
            
    # ==========================================================================================
    # (B) Make control plots with & without any SF applied in all regions
    # ==========================================================================================
    _kwargs["opts"] = {"xmax" : 800, "ymaxfactor" : 2.0}
    _kwargs["ratioYlabel"]  = "Data/MC"
    _kwargs["ratio"]        = True
    _kwargs["stackMCHistograms"] = True
    _kwargs["createLegend"]      = {"x1": 0.70, "y1": 0.75, "x2": 0.95, "y2": 0.92}
    
    # (B1) Denominator
    for re in regions:

        hName = "Denominator_"+re+"_StackedMC"

        h0_Data      = rhDict_den_noSF["Data-"+re+"-Inclusive"].Clone("Data")
        h0_QCD       = rhDict_den_noSF["NormQCD-"+re+"-Inclusive"].Clone("QCD")
        h0_GenuineTT = rhDict_den_noSF["NormTT-"+re+"-Genuine"].Clone("genuine t#bar{t}")
        h0_FakeTT    = rhDict_den_noSF["NormTT-"+re+"-Fake"].Clone("fake t#bar{t}")
        h0_EWK       = rhDict_den_noSF["EWK-"+re+"-Inclusive"].Clone("EWK")
        h0_ST        = rhDict_den_noSF["SingleTop-"+re+"-Inclusive"].Clone("ST")
        
        #print "------------------------------------------------"
        #print "             Region =  ", re
        #print "------------------------------------------------"
        #print "Data         = ", h0_Data.Integral()
        #print "Inclusive TT = ", rhDict_den_noSF["NormTT-"+re+"-Inclusive"].Integral()
        #print "Genuine TT   = ", h0_GenuineTT.Integral()
        #print "Fake TT      = ", h0_FakeTT.Integral()
        #print "ST           = ", h0_ST.Integral()
        #print "QCD          = ", h0_QCD.Integral()
        #print "EWK          = ", h0_EWK.Integral()
        
        styles.getFakeBStyle().apply(h0_FakeTT)
        styles.FakeBStyle6.apply(h0_GenuineTT)
        styles.ewkStyle.apply(h0_EWK)
        styles.genuineBAltStyle.apply(h0_ST)
        
        h0 = histograms.Histo(h0_Data, "Data", "Data")
        h1 = histograms.Histo(h0_GenuineTT, "t#bar{t} (genuine)", "TT")
        h2 = histograms.Histo(h0_FakeTT, "t#bar{t} (fake)", "TT")
        h3 = histograms.Histo(h0_EWK, "EWK", "EWK")
        h4 = histograms.Histo(h0_QCD, "QCD", "QCD")
        h5 = histograms.Histo(h0_ST, "ST", "ST")
        
        h0.setIsDataMC(isData=True,  isMC=False)
        h1.setIsDataMC(isData=False, isMC=True)
        h2.setIsDataMC(isData=False, isMC=True)
        h3.setIsDataMC(isData=False, isMC=True)
        h4.setIsDataMC(isData=False, isMC=True)
        h5.setIsDataMC(isData=False, isMC=True)
        
        myStackList = []
        myStackList.insert(0, h0)
        myStackList.append(h4)
        myStackList.append(h2)
        myStackList.append(h1)
        myStackList.append(h5)
        myStackList.append(h3)

        pDen = plots.DataMCPlot2(myStackList, saveFormats=[])
        pDen.setLuminosity(opts.intLumi)
        pDen.setDefaultStyles()
        ROOT.gStyle.SetNdivisions(8, "X")
        plots.drawPlot(pDen, hName, **_kwargs)
        SavePlot(pDen, hName, os.path.join(opts.saveDir, opts.optMode), saveFormats = [".png"])


    # (B2) Numerator
    for re in regions:
        
        hName = "Numerator_"+re+"_StackedMC_noSF"
        
        h1_Data      = rhDict_num_noSF["Data-"+re+"-Inclusive"].Clone("Data")
        h1_QCD       = rhDict_num_noSF["NormQCD-"+re+"-Inclusive"].Clone("QCD")
        h1_GenuineTT = rhDict_num_noSF["NormTT-"+re+"-Genuine"].Clone("genuine t#bar{t}")
        h1_FakeTT    = rhDict_num_noSF["NormTT-"+re+"-Fake"].Clone("fake t#bar{t}")
        h1_EWK       = rhDict_num_noSF["EWK-"+re+"-Inclusive"].Clone("EWK")
        h1_ST        = rhDict_num_noSF["SingleTop-"+re+"-Inclusive"].Clone("ST")
        
        styles.getFakeBStyle().apply(h1_FakeTT)
        styles.FakeBStyle6.apply(h1_GenuineTT)
        styles.ewkStyle.apply(h1_EWK)
        styles.genuineBAltStyle.apply(h1_ST)
        
        h0 = histograms.Histo(h1_Data, "Data", "Data")
        h1 = histograms.Histo(h1_GenuineTT, "t#bar{t} (genuine)", "TT")
        h2 = histograms.Histo(h1_FakeTT, "t#bar{t} (fake)", "TT")
        h3 = histograms.Histo(h1_EWK, "EWK", "EWK")
        h4 = histograms.Histo(h1_QCD, "QCD", "QCD")
        h5 = histograms.Histo(h1_ST, "ST", "ST")
        
        h0.setIsDataMC(isData=True,  isMC=False)
        h1.setIsDataMC(isData=False, isMC=True)
        h2.setIsDataMC(isData=False, isMC=True)
        h3.setIsDataMC(isData=False, isMC=True)
        h4.setIsDataMC(isData=False, isMC=True)
        h5.setIsDataMC(isData=False, isMC=True)

        myStackList = []
        myStackList.insert(0, h0)
        myStackList.append(h4)
        myStackList.append(h2)
        myStackList.append(h1)
        myStackList.append(h5)
        myStackList.append(h3)

        pNum = plots.DataMCPlot2(myStackList, saveFormats=[])
        pNum.setLuminosity(opts.intLumi)
        pNum.setDefaultStyles()
        ROOT.gStyle.SetNdivisions(8, "X")
        plots.drawPlot(pNum, hName, **_kwargs)
        SavePlot(pNum, hName, os.path.join(opts.saveDir, opts.optMode), saveFormats = [".png"])


    #print " "
    #print "Numerator:"
    
    # (C3) Numerator with SF
    for re in regions:
        
        hName = "Numerator_"+re+"_StackedMC_withSF"
        
        h2_Data      = rhDict_num_noSF["Data-"+re+"-Inclusive"].Clone("Data")
        h2_QCD       = rhDict_num_withCR2SF["NormQCD-"+re+"-Inclusive"].Clone("QCD")
        h2_GenuineTT = rhDict_num_withCR1SF["NormTT-"+re+"-Genuine"].Clone("genuine t#bar{t}")
        h2_FakeTT    = rhDict_num_withCR1SF["NormTT-"+re+"-Fake"].Clone("fake t#bar{t}")
        h2_EWK       = rhDict_num_withCR2SF["EWK-"+re+"-Inclusive"].Clone("EWK")
        h2_ST        = rhDict_num_withCR2SF["SingleTop-"+re+"-Inclusive"].Clone("ST")
        
        #print "------------------------------------------------"
        #print "             Region =  ", re
        #print "------------------------------------------------"
        #print "Data         = ", h2_Data.Integral()
        #print "Inclusive TT = ", rhDict_num_withCR1SF["NormTT-"+re+"-Inclusive"].Integral()
        #print "Genuine TT   = ", h2_GenuineTT.Integral()
        #print "Fake TT      = ", h2_FakeTT.Integral()
        #print "ST           = ", h2_ST.Integral()
        #print "QCD          = ", h2_QCD.Integral()
        #print "EWK          = ", h2_EWK.Integral()

        styles.getFakeBStyle().apply(h2_FakeTT)
        styles.FakeBStyle6.apply(h2_GenuineTT)
        styles.ewkStyle.apply(h2_EWK)
        styles.genuineBAltStyle.apply(h2_ST)
        
        h0 = histograms.Histo(h2_Data,      "Data"               , "Data")
        h1 = histograms.Histo(h2_GenuineTT, "t#bar{t} (genuine)" , "TT"  )
        h2 = histograms.Histo(h2_FakeTT,    "t#bar{t} (fake)"    , "TT"  )
        h3 = histograms.Histo(h2_EWK,       "EWK"                , "EWK" )
        h4 = histograms.Histo(h2_QCD,       "QCD"                , "QCD" )
        h5 = histograms.Histo(h2_ST,        "ST"                 , "ST"  )
        
        h0.setIsDataMC(isData=True,  isMC=False)
        h1.setIsDataMC(isData=False, isMC=True)
        h2.setIsDataMC(isData=False, isMC=True)
        h3.setIsDataMC(isData=False, isMC=True)
        h4.setIsDataMC(isData=False, isMC=True)
        h5.setIsDataMC(isData=False, isMC=True)

        myStackList = []
        myStackList.insert(0, h0)
        myStackList.append(h4)
        myStackList.append(h2)
        myStackList.append(h1)
        myStackList.append(h5)
        myStackList.append(h3)
        
        p1 = plots.DataMCPlot2(myStackList, saveFormats=[])
        p1.setLuminosity(opts.intLumi)
        p1.setDefaultStyles()
        ROOT.gStyle.SetNdivisions(8, "X")
        plots.drawPlot(p1, hName, **_kwargs)
        SavePlot(p1, hName, os.path.join(opts.saveDir, opts.optMode), saveFormats = [".png"])

    
    return
Beispiel #10
0
def PlotAndFitTemplates(datasetsMgr,
                        histoName,
                        folderName,
                        opts,
                        doFakeB=False):
    Verbose("PlotAndFitTemplates()")

    # Definitions
    inclusiveFolder = folderName
    genuineBFolder = folderName + "EWKGenuineB"
    fakeBFolder = folderName + "EWKFakeB"
    if doFakeB:
        ewkFolder = genuineBFolder
        bkgName = "FakeB"
    else:
        ewkFolder = inclusiveFolder
        bkgName = "QCD"

    # Create the plotters
    p1 = plots.DataMCPlot(datasetsMgr, "%s/%s" % (inclusiveFolder, histoName))
    p2 = plots.DataMCPlot(datasetsMgr, "%s/%s" % (ewkFolder, histoName))
    p3 = plots.DataMCPlot(datasetsMgr, "%s/%s" % (inclusiveFolder, histoName))
    p4 = plots.DataMCPlot(datasetsMgr, "%s/%s" % (ewkFolder, histoName))

    if 0:
        p1.histoMgr.forEachHisto(lambda h: h.getRootHisto().RebinX(2))
        p2.histoMgr.forEachHisto(lambda h: h.getRootHisto().RebinX(2))
        p3.histoMgr.forEachHisto(lambda h: h.getRootHisto().RebinX(2))
        p4.histoMgr.forEachHisto(lambda h: h.getRootHisto().RebinX(2))

    # Get the histograms
    Data_baseline = p1.histoMgr.getHisto("Data").getRootHisto().Clone(
        "Baseline Data")  #also legend entry name
    FakeB_baseline = p1.histoMgr.getHisto("Data").getRootHisto().Clone(
        "Baseline " + bkgName)
    EWK_baseline = p2.histoMgr.getHisto("EWK").getRootHisto().Clone(
        "Baseline EWK")
    Data_inverted = p3.histoMgr.getHisto("Data").getRootHisto().Clone(
        "Inverted Data")
    FakeB_inverted = p3.histoMgr.getHisto("Data").getRootHisto().Clone(
        "Inverted " + bkgName)
    EWK_inverted = p4.histoMgr.getHisto("EWK").getRootHisto().Clone(
        "Inverted EWK")

    # Create FakeB histos: FakeB = (Data - EWK)
    msg = "Disabled EWK subtraction (Use Case: Control Triggers)"
    Print(ShellStyles.WarningLabel() + msg, True)
    #FakeB_baseline.Add(EWK_baseline, -1)
    #FakeB_inverted.Add(EWK_inverted, -1)

    # Create the final plot object
    compareHistos = [EWK_baseline]
    p = plots.ComparisonManyPlot(FakeB_inverted, compareHistos, saveFormats=[])
    p.setLuminosity(GetLumi(datasetsMgr))

    # Apply styles
    p.histoMgr.forHisto("Inverted " + bkgName, styles.getFakeBStyle())
    p.histoMgr.forHisto("Baseline EWK", styles.getAltEWKStyle())

    # Set draw style
    p.histoMgr.setHistoDrawStyle("Inverted " + bkgName, "P")
    p.histoMgr.setHistoDrawStyle("Baseline EWK", "AP")

    # Set legend style
    p.histoMgr.setHistoLegendStyle("Inverted " + bkgName, "P")
    p.histoMgr.setHistoLegendStyle("Baseline EWK", "LP")
    # p.histoMgr.setHistoLegendStyleAll("LP")

    # Set legend labels
    if doFakeB:
        p.histoMgr.setHistoLegendLabelMany({
            "Baseline EWKGenuineB": "EWK (GenuineB)",
            "Inverted FakeB": "Fake-b",
        })
    else:
        p.histoMgr.setHistoLegendLabelMany({
            "Baseline EWK": "EWK",
            "Inverted " + bkgName: "QCD",
        })

    #=========================================================================================
    # Set Minimizer Options
    #=========================================================================================
    '''
    https://root.cern.ch/root/htmldoc/guides/users-guide/FittingHistograms.html#the-th1fit-method
    https://root.cern.ch/root/html/src/ROOT__Math__MinimizerOptions.h.html#a14deB
    '''
    if 0:
        ROOT.Math.MinimizerOptions.SetDefaultMinimizer("Minuit", "Migrad")
        ROOT.Math.MinimizerOptions.SetDefaultStrategy(
            2)  # Speed = 0, Balance = 1, Robustness = 2
        ROOT.Math.MinimizerOptions.SetDefaultMaxFunctionCalls(
            5000)  # set maximum of function calls
        ROOT.Math.MinimizerOptions.SetDefaultMaxIterations(
            5000
        )  # set maximum iterations (one iteration can have many function calls)
    if 0:
        ROOT.Math.MinimizerOptions.SetDefaultMinimizer("Minuit", "Simplex")
        ROOT.Math.MinimizerOptions.SetDefaultMinimizer("Minuit", "Minimize")
        ROOT.Math.MinimizerOptions.SetDefaultMinimizer("Minuit",
                                                       "MigradImproved")
        ROOT.Math.MinimizerOptions.SetDefaultMinimizer("Minuit", "Scan")
        ROOT.Math.MinimizerOptions.SetDefaultMinimizer("Minuit", "Seek")
        ROOT.Math.MinimizerOptions.SetDefaultErrorDef(
            1
        )  # error definition (=1. for getting 1 sigma error for chi2 fits)
        ROOT.Math.MinimizerOptions.SetDefaultMaxFunctionCalls(
            1000000)  # set maximum of function calls
        ROOT.Math.MinimizerOptions.SetDefaultMaxIterations(
            1000000
        )  # set maximum iterations (one iteration can have many function calls)
        ROOT.Math.MinimizerOptions.SetDefaultPrecision(
            -1
        )  # precision in the objective function calculation (value <= 0 means left to default)
        ROOT.Math.MinimizerOptions.SetDefaultPrintLevel(
            1
        )  # None = -1, Reduced = 0, Normal = 1, ExtraForProblem = 2, Maximum = 3
        ROOT.Math.MinimizerOptions.SetDefaultTolerance(
            1e-03
        )  # Minuit/Minuit2 converge when the EDM is less a given tolerance. (default 1e-03)
    if 1:
        hLine = "=" * 45
        title = "{:^45}".format("Minimzer Options")
        print "\t", hLine
        print "\t", title
        print "\t", hLine
        minOpt = ROOT.Math.MinimizerOptions()
        minOpt.Print()
        print "\t", hLine, "\n"

    #=========================================================================================
    # Start fit process
    #=========================================================================================
    binLabels = ["Inclusive"]
    FITMIN = 80
    FITMAX = 1000
    #moduleInfoString = opts.dataEra + "_" + opts.searchMode + "_" + opts.optMode
    moduleInfoString = opts.optMode

    #=========================================================================================
    # Create templates (EWK fakes, EWK genuine, QCD; data template is created by manager)
    #=========================================================================================
    manager = QCDNormalization.QCDNormalizationManagerDefault(
        binLabels, opts.mcrab, moduleInfoString)
    template_EWKFakeB_Baseline = manager.createTemplate("EWKFakeB_Baseline")
    template_EWKFakeB_Inverted = manager.createTemplate("EWKFakeB_Inverted")
    template_EWKInclusive_Baseline = manager.createTemplate(
        "EWKInclusive_Baseline")
    template_EWKInclusive_Inverted = manager.createTemplate(
        "EWKInclusive_Inverted")
    template_FakeB_Baseline = manager.createTemplate("QCD_Baseline")
    template_FakeB_Inverted = manager.createTemplate("QCD_Inverted")

    #======================================================================2==================
    # EWK
    #=========================================================================================
    par0 = [+7.1817e-01, 0.0, 1.0]  # cb_norm
    par1 = [+1.7684e+02, 150.0, 200.0]  # cb_mean
    par2 = [+2.7287e+01, 20.0, 40.0]  # cb_sigma (fixed for chiSq=2)
    par3 = [-3.9174e-01, -0.5, 0.0]  # cb_alpha (fixed for chiSq=2)
    par4 = [+2.5104e+01, 0.0, 50.0]  # cb_n
    par5 = [+7.4724e-05, 0.0, 1.0]  # expo_norm
    par6 = [-4.6848e-02, -1.0, 0.0]  # expo_a
    par7 = [+2.1672e+02, 200.0, 250.0]  # gaus_mean (fixed for chiSq=2)
    par8 = [+6.3201e+01, 20.0, 80.0]  # gaus_sigma

    template_EWKInclusive_Baseline.setFitter(
        QCDNormalization.FitFunction("EWKFunction",
                                     boundary=0,
                                     norm=1,
                                     rejectPoints=0), FITMIN, FITMAX)
    template_EWKInclusive_Baseline.setDefaultFitParam(
        defaultInitialValue=None,
        defaultLowerLimit=[
            par0[1], par1[1], par2[0], par3[0], par4[1], par5[1], par6[1],
            par7[0], par8[1]
        ],
        defaultUpperLimit=[
            par0[2], par1[2], par2[0], par3[0], par4[2], par5[2], par6[2],
            par7[0], par8[2]
        ])

    #=========================================================================================
    # FakeB/QCD
    #=========================================================================================
    par0 = [8.9743e-01, 0.0, 1.0]  # lognorm_norm
    par1 = [2.3242e+02, 300.0, 1000.0]  # lognorm_mean
    par2 = [1.4300e+00, 0.5, 10.0]  # lognorm_shape
    par3 = [2.2589e+02, 100.0, 500.0]  # gaus_mean
    par4 = [4.5060e+01, 0.0, 100.0]  # gaus_sigma

    template_FakeB_Inverted.setFitter(
        QCDNormalization.FitFunction("QCDFunctionAlt",
                                     boundary=0,
                                     norm=1,
                                     rejectPoints=0), FITMIN, FITMAX)
    template_FakeB_Inverted.setDefaultFitParam(
        defaultInitialValue=None,
        defaultLowerLimit=[par0[1], par1[1], par2[1], par3[1], par4[1]],
        defaultUpperLimit=[par0[2], par1[2], par2[2], par3[2], par4[2]])

    #=========================================================================================
    # Set histograms to the templates
    #=========================================================================================
    if doFakeB:
        template_EWKFakeB_Baseline.setHistogram(EWKGenuineB_baseline,
                                                "Inclusive")
        template_EWKFakeB_Inverted.setHistogram(EWKGenuineB_inverted,
                                                "Inclusive")
        template_EWKInclusive_Baseline.setHistogram(EWKGenuineB_baseline,
                                                    "Inclusive")
        template_EWKInclusive_Inverted.setHistogram(EWKGenuineB_inverted,
                                                    "Inclusive")
    else:
        template_EWKFakeB_Baseline.setHistogram(EWK_baseline, "Inclusive")
        template_EWKFakeB_Inverted.setHistogram(EWK_inverted, "Inclusive")
        template_EWKInclusive_Baseline.setHistogram(EWK_baseline, "Inclusive")
        template_EWKInclusive_Inverted.setHistogram(EWK_inverted, "Inclusive")
    template_FakeB_Baseline.setHistogram(FakeB_baseline, "Inclusive")
    template_FakeB_Inverted.setHistogram(FakeB_inverted, "Inclusive")

    #=========================================================================================
    # Make plots of templates
    #=========================================================================================
    manager.plotTemplates()

    #=========================================================================================
    # Fit individual templates to histogram "data_baseline", with custom fit options
    #=========================================================================================
    fitOptions = "R B L W 0 Q M"
    manager.calculateNormalizationCoefficients(Data_baseline, fitOptions,
                                               FITMIN, FITMAX)

    # Only for when the measurement is done in bins
    fileName = os.path.join(
        opts.mcrab,
        "QCDInvertedNormalizationFactors%s.py" % (getModuleInfoString(opts)))
    manager.writeNormFactorFile(fileName, opts)

    if 1:
        saveName = fileName.replace("/", "_")

        # Draw the histograms
        plots.drawPlot(
            p, saveName,
            **GetHistoKwargs(histoName))  #the "**" unpacks the kwargs_

        # Save plot in all formats
        SavePlot(p, saveName, os.path.join(opts.saveDir, "Fit"))
    return
Beispiel #11
0
def PlotTemplates(datasetsMgr, histoName):
    Verbose("Plotting EWK Vs QCD unity-normalised histograms")

    # FIXME - First pseudo-multicrab had the Fake/Genuine boolean REVERSED
    # FIXME - First pseudo-multicrab had the Fake/Genuine boolean REVERSED
    # FIXME - First pseudo-multicrab had the Fake/Genuine boolean REVERSED
    # FIXME - First pseudo-multicrab had the Fake/Genuine boolean REVERSED
    defaultFolder = "ForFakeBMeasurement"
    genuineBFolder = "ForFakeBMeasurementEWKFakeB"
    fakeBFolder = "ForFakeBMeasurementEWKGenuineB"

    # Create comparison plot
    p1 = plots.ComparisonPlot(
        getHisto(datasetsMgr, "Data", "%s" % histoName, "Baseline"),
        getHisto(datasetsMgr, "EWK",
                 "%s" % histoName.replace(defaultFolder, genuineBFolder),
                 "Baseline"))
    p1.histoMgr.normalizeMCToLuminosity(
        datasetsMgr.getDataset("Data").getLuminosity())

    p2 = plots.ComparisonPlot(
        getHisto(datasetsMgr, "Data", "%s" % histoName, "Inverted"),
        getHisto(datasetsMgr, "EWK",
                 "%s" % histoName.replace(defaultFolder, genuineBFolder),
                 "Inverted"))
    p2.histoMgr.normalizeMCToLuminosity(
        datasetsMgr.getDataset("Data").getLuminosity())

    p3 = plots.ComparisonPlot(
        getHisto(datasetsMgr, "Data", "%s" % histoName, "Baseline"),
        getHisto(datasetsMgr, "EWK",
                 "%s" % histoName.replace(defaultFolder, fakeBFolder),
                 "Baseline"))
    p3.histoMgr.normalizeMCToLuminosity(
        datasetsMgr.getDataset("Data").getLuminosity())

    p4 = plots.ComparisonPlot(
        getHisto(datasetsMgr, "Data", "%s" % histoName, "Inverted"),
        getHisto(datasetsMgr, "EWK",
                 "%s" % histoName.replace(defaultFolder, fakeBFolder),
                 "Inverted"))
    p4.histoMgr.normalizeMCToLuminosity(
        datasetsMgr.getDataset("Data").getLuminosity())

    # Get EWK histos
    EWKGenuineB_baseline = p1.histoMgr.getHisto(
        "Baseline-EWK").getRootHisto().Clone("Baseline-EWKGenuineB")
    EWKGenuineB_inverted = p2.histoMgr.getHisto(
        "Inverted-EWK").getRootHisto().Clone("Inverted-EWKGenuineB")
    EWKFakeB_baseline = p3.histoMgr.getHisto(
        "Baseline-EWK").getRootHisto().Clone("Baseline-EWKFakeB")
    EWKFakeB_inverted = p4.histoMgr.getHisto(
        "Inverted-EWK").getRootHisto().Clone("Inverted-EWKFakeB")

    # Data histos
    Data_baseline = p1.histoMgr.getHisto("Baseline-Data").getRootHisto().Clone(
        "Baseline-Data")
    Data_inverted = p2.histoMgr.getHisto("Inverted-Data").getRootHisto().Clone(
        "Inverted-Data")

    # Create FakeB (Data-EWK_GenuineB) histos
    FakeB_baseline = p1.histoMgr.getHisto(
        "Baseline-Data").getRootHisto().Clone("Baseline-FakeB")
    FakeB_inverted = p2.histoMgr.getHisto(
        "Inverted-Data").getRootHisto().Clone("Inverted-FakeB")
    FakeB_baseline.Add(EWKGenuineB_baseline, -1)
    FakeB_inverted.Add(EWKGenuineB_inverted, -1)

    # Normalize histograms to unit area
    if 1:
        Data_baseline.Scale(1.0 / Data_baseline.Integral())
        Data_inverted.Scale(1.0 / Data_inverted.Integral())
        EWKGenuineB_baseline.Scale(1.0 / EWKGenuineB_baseline.Integral())
        EWKGenuineB_inverted.Scale(1.0 / EWKGenuineB_inverted.Integral())
        EWKFakeB_baseline.Scale(1.0 / EWKFakeB_baseline.Integral())
        EWKFakeB_inverted.Scale(1.0 / EWKFakeB_inverted.Integral())
        FakeB_baseline.Scale(1.0 / FakeB_baseline.Integral())
        FakeB_inverted.Scale(1.0 / FakeB_inverted.Integral())

    # Create the final plot object
    compareHistos = [EWKGenuineB_baseline]
    # compareHistos = [EWKGenuineB_baseline, EWKGenuineB_inverted, EWKFakeB_inverted, Data_inverted]
    # compareHistos = [EWKGenuineB_inverted, EWKFakeB_inverted, Data_inverted]
    # compareHistos = [EWKGenuineB_baseline, EWKFakeB_baseline, EWKGenuineB_inverted, EWKFakeB_inverted]
    # compareHistos = [FakeB_baseline, EWKGenuineB_baseline, EWKFakeB_baseline, EWKGenuineB_inverted, EWKFakeB_inverted]
    p = plots.ComparisonManyPlot(FakeB_inverted, compareHistos, saveFormats=[])
    p.setLuminosity(GetLumi(datasetsMgr))

    # Apply styles
    p.histoMgr.forHisto("Inverted-FakeB", styles.getInvertedLineStyle())
    p.histoMgr.forHisto("Baseline-EWKGenuineB", styles.getBaselineLineStyle())
    if 0:
        p.histoMgr.forHisto("Baseline-FakeB", styles.getInvertedLineStyle())
        p.histoMgr.forHisto("Baseline-EWKFakeB", styles.getFakeBStyle())
        p.histoMgr.forHisto("Inverted-EWKGenuineB", styles.getGenuineBStyle())
        p.histoMgr.forHisto("Inverted-EWKFakeB", styles.getFakeBLineStyle())
        p.histoMgr.forHisto("Inverted-Data", styles.getDataStyle())

    # Set draw style
    p.histoMgr.setHistoDrawStyle("Inverted-FakeB", "HIST")
    p.histoMgr.setHistoDrawStyle("Baseline-EWKGenuineB", "HIST")
    if 0:
        p.histoMgr.setHistoDrawStyle("Baseline-FakeB", "AP")
        p.histoMgr.setHistoDrawStyle("Baseline-EWKFakeB", "HIST")
        p.histoMgr.setHistoDrawStyle("Inverted-EWKGenuineB", "AP")
        p.histoMgr.setHistoDrawStyle("Inverted-EWKFakeB", "HIST")
        p.histoMgr.setHistoDrawStyle("Inverted-Data", "AP")

    # Set legend style
    p.histoMgr.setHistoLegendStyle("Inverted-FakeB", "L")
    p.histoMgr.setHistoLegendStyle("Baseline-EWKGenuineB", "L")
    if 0:
        p.histoMgr.setHistoLegendStyle("Baseline-FakeB", "P")
        p.histoMgr.setHistoLegendStyle("Baseline-EWKFakeB", "FL")
        p.histoMgr.setHistoLegendStyle("Inverted-EWKGenuineB", "P")
        p.histoMgr.setHistoLegendStyle("Inverted-EWKFakeB", "L")
        p.histoMgr.setHistoLegendStyle("Inverted-Data", "LP")

    # Set legend labels
    p.histoMgr.setHistoLegendLabelMany({
        "Inverted-FakeB":
        "FakeB (Inverted)",  # (I)",
        #"Inverted-Data"       : "Data (I)",
        "Baseline-EWKGenuineB":
        "EWK (Baseline)",  #-GenuineB (B)",
        #"Baseline-FakeB"      : "FakeB",
        #"Baseline-EWKFakeB"   : "EWK-FakeB (B)",
        #"Inverted-EWKGenuineB": "EWK-GenuineB (I)",
        #"Inverted-EWKFakeB"   : "EWK-FakeB (I)",
    })

    # Append analysisType to histogram name
    saveName = histoName

    # Draw the histograms #alex
    plots.drawPlot(p, saveName,
                   **GetHistoKwargs(histoName))  #the "**" unpacks the kwargs_

    # Add text
    text = opts.optMode.replace("OptChiSqrCutValue", "#chi^{2} #leq ")
    histograms.addText(0.21, 0.85, text)

    # Save plot in all formats
    saveDir = os.path.join(opts.saveDir, "Test", opts.optMode)
    SavePlot(p, saveName, saveDir, saveFormats=[".png"])
    return
Beispiel #12
0
def DataMCHistograms(datasetsMgr):
    '''
    Create data-MC comparison plot, with the default:
    - legend labels (defined in plots._legendLabels)
    - plot styles (defined in plots._plotStyles, and in styles)
    - drawing styles ('HIST' for MC, 'EP' for data)
    - legend styles ('L' for MC, 'P' for data)
    '''
    Verbose("Plotting Data-MC Histograms")

    # Definitions
    histoNames = []
    histoKwargs = {}
    saveFormats = [".png"]  #[".C", ".png", ".pdf"]

    # General Settings
    if opts.mergeEWK:
        _moveLegend = {"dx": -0.1, "dy": -0.01, "dh": -0.12}
    else:
        _moveLegend = {"dx": -0.1, "dy": -0.01, "dh": 0.1}

    _kwargs = {
        "rebinX": 1,
        "rebinY": None,
        "ratioYlabel": "Data/MC",
        "ratio": True,
        "stackMCHistograms": True,
        "ratioInvert": False,
        "addMCUncertainty": False,
        "addLuminosityText": True,
        "addCmsText": True,
        "cmsExtraText": "Preliminary",
        "opts": {
            "ymin": 2e-1,
            "ymaxfactor": 10
        },  #1.2
        "opts2": {
            "ymin": 0.0,
            "ymax": 2.0
        },
        "log": True,
        "moveLegend": _moveLegend,
        "cutBox": {
            "cutValue": 7.0,
            "fillColor": 16,
            "box": False,
            "line": False,
            "greaterThan": True
        },
    }

    histoName = "ForDataDrivenCtrlPlots/Njets"
    kwargs = copy.deepcopy(_kwargs)
    kwargs["ylabel"] = "Events / %.0f GeV/c^{2}"
    kwargs["cutBox"] = {
        "cutValue": 7.0,
        "fillColor": 16,
        "box": False,
        "line": True,
        "greaterThan": True
    }
    histoNames.append(histoName)
    histoKwargs[histoName] = kwargs

    # For-loop: All histograms in list
    for histoName in histoNames:
        kwargs_ = histoKwargs[histoName]
        saveName = histoName.replace("/", "_")

        # Create the plotting object
        p = plots.DataMCPlot(datasetsMgr, histoName, saveFormats=[])

        # Apply QCD data-driven style
        dName = "QCD-Data"
        p.histoMgr.forHisto(dName, styles.getFakeBStyle())
        p.histoMgr.setHistoDrawStyle(dName, "HIST")
        p.histoMgr.setHistoLegendStyle(dName, "F")
        p.histoMgr.setHistoLegendLabelMany({
            #dName: "QCD (Data)",
            dName: "Fake b (data)",
        })

        # Draw and save the plot
        plots.drawPlot(p, saveName,
                       **kwargs_)  #the "**" unpacks the kwargs_ dictionary
        SavePlot(p, saveName, os.path.join(opts.saveDir, "Test", opts.optMode))
    return