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
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
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
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
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