def _doCalculate2D(self, nSplitBins, shape, normFactors, optionPrintPurityByBins, optionDoNQCDByBinHistograms, myUncertaintyLabels): ''' Calculates the result for 2D histograms ''' # Intialize counters for purity calculation in final shape binning myShapeDataSum = [] myShapeDataSumUncert = [] myShapeEwkSum = [] myShapeEwkSumUncert = [] myList = [] for k in range(1,self._resultShape.GetNbinsY()+1): myList.append(0.0) for j in range(1,self._resultShape.GetNbinsX()+1): myShapeDataSum.append(myList[:]) myShapeDataSumUncert.append(myList[:]) myShapeEwkSum.append(myList[:]) myShapeEwkSumUncert.append(myList[:]) # Calculate results separately for each phase-space bin, and then combine them to get inclusive result for i in range(0, nSplitBins): # Get data-driven QCD, data, and MC EWK shape histogram for the phase space bin h = shape.getDataDrivenQCDHistoForSplittedBin(i) hData = shape.getDataHistoForSplittedBin(i) hEwk = shape.getEwkHistoForSplittedBin(i) # Get normalization factor wQCDLabel = shape.getPhaseSpaceBinFileFriendlyTitle(i) if self._optionUseInclusiveNorm: wQCDLabel = "Inclusive" wQCD = 0.0 if not wQCDLabel in normFactors.keys(): msg = "No normalization factors available for bin '%s' when accessing histogram %s! Ignoring this bin..." % (wQCDLabel, shape.getHistoName()) print ShellStyles.WarningLabel() + msg else: wQCD = normFactors[wQCDLabel] # Loop over bins in the shape histogram for j in range(1,h.GetNbinsX()+1): for k in range(1,h.GetNbinsY()+1): myResult = 0.0 myStatDataUncert = 0.0 myStatEwkUncert = 0.0 if abs(h.GetBinContent(j,k)) > 0.00001: # Ignore zero bins # Calculate result myResult = h.GetBinContent(j,k) * wQCD # Calculate abs. stat. uncert. for data and for MC EWK myStatDataUncert = hData.GetBinError(j,k) * wQCD myStatEwkUncert = hEwk.GetBinError(j,k) * wQCD #errorPropagation.errorPropagationForProduct(hLeg1.GetBinContent(j), hLeg1Data.GetBinError(j), myEffObject.value(), myEffObject.uncertainty("statData")) # Do not calculate here MC EWK syst. myCountObject = extendedCount.ExtendedCount(myResult, [myStatDataUncert, myStatEwkUncert], myUncertaintyLabels) self._resultCountObject.add(myCountObject) if optionDoNQCDByBinHistograms: self._histogramsList[i].SetBinContent(j, k, myCountObject.value()) self._histogramsList[i].SetBinError(j, k, myCountObject.statUncertainty()) self._resultShape.SetBinContent(j, k, self._resultShape.GetBinContent(j, k) + myCountObject.value()) self._resultShape.SetBinError(j, k, self._resultShape.GetBinError(j, k) + myCountObject.statUncertainty()**2) # Sum squared # Sum items for purity calculation myShapeDataSum[j-1][k-1] += hData.GetBinContent(j,k)*wQCD myShapeDataSumUncert[j-1][k-1] += (hData.GetBinError(j,k)*wQCD)**2 myShapeEwkSum[j-1][k-1] += hEwk.GetBinContent(j,k)*wQCD myShapeEwkSumUncert[j-1][k-1] += (hEwk.GetBinError(j,k)*wQCD)**2 h.Delete() hData.Delete() hEwk.Delete() # Take square root of uncertainties for j in range(1,self._resultShape.GetNbinsX()+1): for k in range(1,self._resultShape.GetNbinsY()+1): self._resultShape.SetBinError(j, k, math.sqrt(self._resultShape.GetBinError(j, k))) # Print result print "NQCD Integral(%s) = %s "%(shape.getHistoName(), self._resultCountObject.getResultStringFull("%.1f")) # Print purity as function of final shape bins if optionPrintPurityByBins: print "Purity of shape %s"%shape.getHistoName() print "shapeBin purity purityUncert" for j in range (1,self._resultShape.GetNbinsX()+1): for k in range(1,self._resultShape.GetNbinsY()+1): myPurity = 0.0 myPurityUncert = 0.0 if abs(myShapeDataSum[j-1][k-1]) > 0.000001: myPurity = 1.0 - myShapeEwkSum[j-1][k-1] / myShapeDataSum[j-1][k-1] myPurityUncert = errorPropagation.errorPropagationForDivision(myShapeEwkSum[j-1][k-1], math.sqrt(myShapeEwkSumUncert[j-1][k-1]), myShapeDataSum[j-1][k-1], math.sqrt(myShapeDataSumUncert[j-1][k-1])) # Store MC EWK content self._resultShapeEWK.SetBinContent(j, k, myShapeEwkSum[j-1][k-1]) self._resultShapeEWK.SetBinError(j, k, math.sqrt(myShapeEwkSumUncert[j-1][k-1])) self._resultShapePurity.SetBinContent(j, k, myPurity) self._resultShapePurity.SetBinError(j, k, myPurityUncert) # Print purity info of final shape if optionPrintPurityByBins: myString = "" if j < self._resultShape.GetNbinsX(): myString = "%d..%d, "%(self._resultShape.GetXaxis().GetBinLowEdge(j),self._resultShape.GetXaxis().GetBinUpEdge(j)) else: myString = ">%d, "%(self._resultShape.GetXaxis().GetBinLowEdge(j)) if k < self._resultShape.GetNbinsY(): myString = "%d..%d"%(self._resultShape.GetYaxis().GetBinLowEdge(k),self._resultShape.GetYaxis().GetBinUpEdge(k)) else: myString = ">%d"%(self._resultShape.GetYaxis().GetBinLowEdge(k)) myString += " %.3f %.3f"%(myPurity, myPurityUncert) print myString return
def main(count, runRange, dsetList, opts): # Apply TDR style style = tdrstyle.TDRStyle() style.setOptStat(True) style.setGridX(True) style.setGridY(True) # Obtain dsetMgrCreator and register it to module selector dsetMgrCreator = dataset.readFromMulticrabCfg(directory=opts.mcrab) # Get list of eras, modes, and optimisation modes erasList = dsetMgrCreator.getDataEras() modesList = dsetMgrCreator.getSearchModes() optList = dsetMgrCreator.getOptimizationModes() sysVarList = dsetMgrCreator.getSystematicVariations() sysVarSrcList = dsetMgrCreator.getSystematicVariationSources() # If user does not define optimisation mode do all of them if opts.optMode == None: if len(optList) < 1: optList.append("") optModes = optList else: optModes = [opts.optMode] # For-loop: All opt Mode for opt in optModes: opts.optMode = opt # Setup & configure the dataset manager datasetsMgr = GetDatasetsFromDir(opts) datasetsMgr.updateNAllEventsToPUWeighted() datasetsMgr.loadLuminosities() # from lumi.json if opts.verbose: datasetsMgr.PrintCrossSections() datasetsMgr.PrintLuminosities() # Remove datasets removeList = ["QCD-b", "Charged", "QCD", "ZJetsToQQ_HT600toInf"] opts.intLumi = 0.0 # For-loop: All datasets in the manager for d in datasetsMgr.getAllDatasets(): if d.isMC(): continue # Inclusive data if len(dsetList) == 1 and dsetList[0] == "Run2016": Verbose("Inclusive data. Will not remove anything", True) opts.intLumi += GetLumi(datasetsMgr) break # Special combinations for rr in dsetList: if rr not in d.getName(): Verbose( "\"%s\" is not in dataset name \"%s\"" % (rr, d.getName()), False) if d.getName() not in removeList: # Ensure dataset to be removed is not in the dsetList if not any(rr in d.getName() for rr in dsetList): removeList.append(d.getName()) else: Verbose( "\"%s\" is in dataset name \"%s\"" % (rr, d.getName()), False) # Get luminosity if a value is not specified opts.intLumi += d.getLuminosity() # For-loop: All dataset names to be removed for i, d in enumerate(removeList, 0): Verbose( ShellStyles.HighlightAltStyle() + "Removing dataset %s" % d + ShellStyles.NormalStyle(), False) datasetsMgr.remove( filter(lambda name: d in name, datasetsMgr.getAllDatasetNames())) # Inform user of dataset and corresponding integrated lumi Print("%d) %s (%.1f 1/pb)" % (count, runRange, opts.intLumi), count == 1) #Print("%d) %s (%.1f 1/pb)" % (count, ", ".join(dsetList), opts.intLumi), count==1) # Merge histograms (see NtupleAnalysis/python/tools/plots.py) plots.mergeRenameReorderForDataMC(datasetsMgr) # Print dataset information if 0: datasetsMgr.PrintInfo() # Merge EWK samples datasetsMgr.merge("EWK", aux.GetListOfEwkDatasets()) # Do the fit on the histo after ALL selections (incl. topology cuts) folderList = datasetsMgr.getDataset( datasetsMgr.getAllDatasetNames()[0]).getDirectoryContent( opts.folder) folderList1 = [h for h in folderList if opts.histoKey in h] folderList2 = [ h for h in folderList1 if "VR" in h or "SR" in h or "CRone" in h or "CRtwo" in h or "CRthree" in h or "CRfour" in h ] # For-loop: All folders histoPaths = [] for f in folderList2: folderPath = os.path.join(opts.folder, f) histoList = datasetsMgr.getDataset( datasetsMgr.getAllDatasetNames()[0]).getDirectoryContent( folderPath) pathList = [os.path.join(folderPath, h) for h in histoList] histoPaths.extend(pathList) binLabels = GetBinLabels("CRone", histoPaths) PlotHistosAndCalculateTF(runRange, datasetsMgr, histoPaths, binLabels, opts) return
def fetchHistograms(self, fINdata, fINpost, fINsignal): histoName = "data_obs" histoData = fINdata.Get(histoName) Verbose("Getting data histogram \"%s\" from ROOT file \"%s\" (Integral = %.1f)" % (histoName, fINdata.GetName(), histoData.Integral()), True) self.h_data = histoData.Clone("Data") # Inspect histogram contents? if opts.verbose: aux.PrintTH1Info(self.h_data) nbins = 0 binning = [] # For-loop: All bins for iBin in range(self.h_data.GetNbinsX()+1): binLowEdge = self.h_data.GetBinLowEdge(iBin) if binLowEdge >= opts.xMinRebin and binLowEdge < opts.xMaxRebin: nbins += 1 binning.append(binLowEdge) binning.append(min(self.optsLogx["xmax"], opts.xMaxRebin)) n = len(binning)-1 self.h_data.SetBins(nbins, array.array("d", binning) ) # Define signal histogram styles # if len(opts.masses) > 3: # raise Exception("Cannot plot more than 3 signal mass points (got %s)." % (opts.masses) ) # lineStyles = [ROOT.kSolid, ROOT.kDashed, ROOT.kDotted] # lineColours = [ROOT.kRed, ROOT.kAzure+6, ROOT.kGreen] # Add signal self.h_signal = [] for i, m in enumerate(opts.masses, 0): hName = "Hp%s" % m histo = fINsignal[m].Get(hName) Verbose("Getting signal histogram \"%s\" from ROOT file \"%s\" (Integral = %.1f)" % (hName, fINsignal[m].GetName(), histo.Integral()), False) if 0: histo.SetLineColor(lineColours[i]) histo.SetLineStyle(lineStyles[i]) histo.SetLineWidth(3) histo.SetTitle("H^{#pm} (%s GeV)" % m) histo.SetBins(nbins, array.array("d", binning) ) self.h_signal.append(histo.Clone(hName)) # Inspect histogram contents? if opts.verbose: aux.PrintTH1Info(self.h_signal) # For-loop: All histos for i, hname in enumerate(self.histonames, 1): Verbose("Getting histogram \"%s\" from ROOT file \"%s\"" % (histoName, fINpost.GetName()), i==1) template = self.h_data.Clone(hname) template.Reset() n = len(binning)-1 template.SetBins(n, array.array("d",binning) ) if opts.prefit: histoName = os.path.join("shapes_prefit", self.name, hname) else: histoName = os.path.join("shapes_fit_b", self.name, hname) # Get the histograms histo = fINpost.Get(histoName) # Safety net for empty histos (if datasset integral is zero corresponding histo will not exist) if "TH1" in str(type(histo)): # print "type(histo) = ", type(histo) pass else: # Histograms to ignore because dataset yield is zero (hack) msg = "Skipping %s. Not a histogram!" % (histoName) Print(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(), True) opts.empty.append(histoName.split("/")[-1]) continue Verbose("Getting bkg histogram \"%s\" from ROOT file \"%s\" (Integral = %.1f)" % (histoName, fINpost.GetName(), histo.Integral()), i==1) # For-loop: All bins for iBin in range(0, histo.GetNbinsX()+1): template.SetBinContent(iBin, histo.GetBinContent(iBin) ) template.SetBinError(iBin, histo.GetBinError(iBin) ) # Customise histogram template.SetFillColor(self.colors[hname]) template.SetLineWidth(0) self.histograms[hname] = template return
def main(opts): # Apply TDR style style = tdrstyle.TDRStyle() style.setOptStat(False) style.setGridX(True) #opts.gridX) style.setGridY(True) #opts.gridY) style.setLogX(False) #opts.logX) style.setLogY(False) #opts.logY) # Obtain dsetMgrCreator and register it to module selector dsetMgrCreator = dataset.readFromMulticrabCfg(directory=opts.mcrab) # Get list of eras, modes, and optimisation modes erasList = dsetMgrCreator.getDataEras() modesList = dsetMgrCreator.getSearchModes() optList = dsetMgrCreator.getOptimizationModes() sysVarList = dsetMgrCreator.getSystematicVariations() sysVarSrcList = dsetMgrCreator.getSystematicVariationSources() # If user does not define optimisation mode do all of them if opts.optMode == None: if len(optList) < 1: optList.append("") else: pass optModes = optList else: optModes = [opts.optMode] # For-loop: All optimisation modes for opt in optModes: opts.optMode = opt # Setup & configure the dataset manager datasetsMgr = GetDatasetsFromDir(opts) datasetsMgr.updateNAllEventsToPUWeighted() datasetsMgr.loadLuminosities() # from lumi.json if 0: datasetsMgr.printSelections() # Set/Overwrite cross-sections for d in datasetsMgr.getAllDatasets(): if "ChargedHiggs" in d.getName(): datasetsMgr.getDataset(d.getName()).setCrossSection(1.0) if opts.verbose: datasetsMgr.PrintCrossSections() datasetsMgr.PrintLuminosities() # Custom Filtering of datasets if 0: datasetsMgr.remove( filter(lambda name: "Charged" in name and not "M_500" in name, datasetsMgr.getAllDatasetNames())) # ZJets and DYJets overlap! if "ZJetsToQQ_HT600toInf" in datasetsMgr.getAllDatasetNames( ) and "DYJetsToQQ_HT180" in datasetsMgr.getAllDatasetNames(): Print( "Cannot use both ZJetsToQQ and DYJetsToQQ due to duplicate events? Investigate. Removing ZJetsToQQ datasets for now ..", True) datasetsMgr.remove( filter(lambda name: "ZJetsToQQ" in name, datasetsMgr.getAllDatasetNames())) # Merge histograms (see NtupleAnalysis/python/tools/plots.py) plots.mergeRenameReorderForDataMC(datasetsMgr) datasetsMgr.PrintInfo() # Get Luminosity if opts.intLumi < 0.0: if "Data" in datasetsMgr.getAllDatasetNames(): opts.intLumi = datasetsMgr.getDataset("Data").getLuminosity() else: opts.intLumi = 1.0 # Merge EWK samples if opts.dataset == "EWK": datasetsMgr.merge("EWK", aux.GetListOfEwkDatasets()) plots._plotStyles["EWK"] = styles.getAltEWKStyle() # Print dataset information datasetsMgr.PrintInfo() # Get all histogram names in the given ROOT folder histoNames = datasetsMgr.getAllDatasets()[0].getDirectoryContent( opts.folder) histoList = [ os.path.join(opts.folder, h) for h in histoNames if "_SR" in h ] # For-loop: All histos in SR nHistos = len(histoList) for i, h in enumerate(histoList, 1): msg = "{:<9} {:>3} {:<1} {:<3} {:<50}".format( "Histogram", "%i" % i, "/", "%s:" % (nHistos), h) Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), i == 1) PlotHistograms(datasetsMgr, h) # Inform user where the plots where saved Print( "All plots saved under directory %s" % (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) + ShellStyles.NormalStyle()), True) return
def main(opts): # Apply TDR style style = tdrstyle.TDRStyle() style.setGridX(False) style.setGridY(False) style.setOptStat(False) # Obtain dsetMgrCreator and register it to module selector dsetMgrCreator = dataset.readFromMulticrabCfg(directory=opts.mcrab) # Get list of eras, modes, and optimisation modes erasList = dsetMgrCreator.getDataEras() modesList = dsetMgrCreator.getSearchModes() optList = dsetMgrCreator.getOptimizationModes() sysVarList = dsetMgrCreator.getSystematicVariations() sysVarSrcList = dsetMgrCreator.getSystematicVariationSources() # If user does not define optimisation mode do all of them if opts.optMode == None: optModes = optList else: optModes = [opts.optMode] # For-loop: All optimisation modes for opt in optModes: opts.optMode = opt # Setup & configure the dataset manager datasetsMgr = GetDatasetsFromDir(opts) datasetsMgr.updateNAllEventsToPUWeighted() datasetsMgr.loadLuminosities() # from lumi.json if 0: datasetsMgr.printSelections() # PrintPSet("BJetSelection", datasetsMgr) # PrintPSet("TopSelectionBDT", datasetsMgr) # PrintPSet("FakeBMeasurement", datasetsMgr) sys.exit() # Print dataset info? if opts.verbose: datasetsMgr.PrintCrossSections() datasetsMgr.PrintLuminosities() # Set signal cross-section if 0: datasetsMgr.getDataset(opts.signal).setCrossSection(1.0) # Remove unwanted datasets if 0: datasetsMgr.remove( filter(lambda name: "QCD-b" in name, datasetsMgr.getAllDatasetNames())) # Merge histograms (see NtupleAnalysis/python/tools/plots.py) plots.mergeRenameReorderForDataMC(datasetsMgr) # Get Luminosity opts.intLumi = datasetsMgr.getDataset("Data").getLuminosity() # Merge EWK samples datasetsMgr.merge("EWK", aux.GetListOfEwkDatasets()) plots._plotStyles["EWK"] = styles.getAltEWKStyle() # Print dataset information datasetsMgr.PrintInfo() # Get all the histograms and their paths (e.g. ForFakeBMeasurement/Baseline_DeltaRLdgTrijetBJetTetrajetBJet_AfterCRSelections) hList = datasetsMgr.getDataset( datasetsMgr.getAllDatasetNames()[0]).getDirectoryContent( opts.folder) hPaths = [os.path.join(opts.folder, h) for h in hList] # Create two lists of paths: one for "Baseline" (SR) and one for "Inverted" (CR) path_SR = [] # baseline, _AfterAllSelections path_CR1 = [] # baseline, _AfterCRSelections path_VR = [] # inverted, _AfterAllSelections path_CR2 = [] # inverted, _AfterCRSelections # For-loop: All histogram paths for p in hPaths: if "AfterStandardSelections" in p: #print p continue if "Baseline" in p: if "AllSelections" in p: path_SR.append(p) if "CRSelections" in p: path_CR1.append(p) if "Inverted" in p: if "AllSelections" in p: path_VR.append(p) if "CRSelections" in p: path_CR2.append(p) # For-loop: All histogram pairs for hVR, hCR2, hCR1 in zip(path_VR, path_CR2, path_CR1): break # not needed now if "IsGenuineB" in hVR: continue PlotComparison(datasetsMgr, hVR, hCR2, "VRvCR2") # For-loop: All histogram pairs counter = 1 for hCR1, hCR2 in zip(path_CR1, path_CR2): if "IsGenuineB" in hCR1: continue hName = hCR1.replace("_AfterCRSelections", "_CR1vCR2").replace( "ForFakeBMeasurement/Baseline_", "") msg = "{:<9} {:>3} {:<1} {:<3} {:<50}".format( "Histogram", "%i" % counter, "/", "%s:" % (len(path_CR1)), hName) Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), counter == 1) PlotComparison(datasetsMgr, hCR1, hCR2, "CR1vCR2") counter += 1 # For-loop: All histogram pairs for hSR, hVR in zip(path_SR, path_VR): break Print("UNBLINDING SR! Are you nuts ? BREAK!", False) if "IsGenuineB" in hSR: continue PlotComparison(datasetsMgr, hSR, hVR, "SRvVR") # # For-loop: All histogram pairs # for hSR, hCR1 in zip(path_SR, path_CR1): # #break # Print("UNBLINDING SR! Are you nuts ? BREAK!", False) # raw_input("Press any key to continue") # if "IsGenuineB" in hSR: # continue # PlotComparison(datasetsMgr, hSR, hCR1, "SRvCR1") Print( "All plots saved under directory %s" % (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) + ShellStyles.NormalStyle()), True) return
def GetScaleFactors(datasetsMgr, num_pathList, den_pathList, intLumi): # Get kwargs _kwargs = GetHistoKwargs(num_pathList[0], opts) _kwargs["stackMCHistograms"] = False _kwargs["opts2"] = {"ymin": 0.50, "ymax": 1.50} _kwargs["ratioType"] = "errorScale" # Get the root histos for all datasets and Control Regions (CRs) regions = ["SR", "VR", "CR1", "CR2"] # Get Dictionaries rhDict_num = GetRootHistos(datasetsMgr, num_pathList, regions) rhDict_den = GetRootHistos(datasetsMgr, den_pathList, regions) # ---------------------------------------------------------------------------- # Get the QCD in Data (Data - EWK - TT - Single Top) and MC in all regions # ---------------------------------------------------------------------------- for re in regions: rhDict_den["QCDinData-" + re + "-Inclusive"] = rhDict_den[ "Data-" + re + "-Inclusive"].Clone("QCDinData-" + re + "-Inclusive") rhDict_den["QCDinData-" + re + "-Inclusive"].Add( rhDict_den["EWK-" + re + "-Inclusive"], -1) rhDict_den["QCDinData-" + re + "-Inclusive"].Add( rhDict_den["TT-" + re + "-Inclusive"], -1) rhDict_den["QCDinData-" + re + "-Inclusive"].Add( rhDict_den["SingleTop-" + re + "-Inclusive"], -1) # ---------------------------------------------------------------------------- # (1) Plot QCD (Data Vs MC) before any normalization in all regions # ---------------------------------------------------------------------------- for re in regions: hName = "QCD_" + re + "_Before_Normalization" h0 = rhDict_den["QCDinData-" + re + "-Inclusive"].Clone("QCD (Data)") h1 = rhDict_den["QCD-" + re + "-Inclusive"].Clone("QCD (MC)") # Get Histos h_QCDinData = histograms.Histo(h0, "QCD (Data)", "Data") h_QCDinData.setIsDataMC(isData=True, isMC=False) h_QCDinMC = histograms.Histo(h1, "QCD (MC)", "MC") h_QCDinMC.setIsDataMC(isData=False, isMC=True) # Create plot pQCD = plots.ComparisonManyPlot(h_QCDinMC, [h_QCDinData], saveFormats=[]) pQCD.setLuminosity(intLumi) pQCD.setDefaultStyles() plots.drawPlot(pQCD, hName, **_kwargs) SavePlot(pQCD, hName, os.path.join(opts.saveDir, opts.optMode), saveFormats=[".png", ".C", ".pdf"]) # Reset histograms h0.Reset() h1.Reset() # ------------------------------------------------------------------------------ # (2) Find the normalization factor using CR2 # ------------------------------------------------------------------------------ n_QCDinData = rhDict_den["QCDinData-CR2-Inclusive"].Integral() n_QCDinMC = rhDict_den["QCD-CR2-Inclusive"].Integral() f1 = float(n_QCDinData) / float(n_QCDinMC) Print( "QCD Normalization factor: = %s%0.6f%s in CR2" % (ShellStyles.NoteStyle(), f1, ShellStyles.NormalStyle()), True) # ------------------------------------------------------------------------------ # (3) Normalize QCD (MC) in all regions # ------------------------------------------------------------------------------- for re in regions: rhDict_den["NormQCD-" + re + "-Inclusive"] = rhDict_den["QCD-" + re + "-Inclusive"].Clone("NormQCD-" + re + "-Inclusive") rhDict_den["NormQCD-" + re + "-Inclusive"].Scale(f1) rhDict_num["NormQCD-" + re + "-Inclusive"] = rhDict_num["QCD-" + re + "-Inclusive"].Clone("NormQCD-" + re + "-Inclusive") rhDict_num["NormQCD-" + re + "-Inclusive"].Scale(f1) # ------------------------------------------------------------------------------ # (4) Plot all regions after applying the normalization factor # ------------------------------------------------------------------------------ regions2 = ["CR2"] for re in regions2: # Reset histograms h0.Reset() h1.Reset() h0 = rhDict_den["QCDinData-" + re + "-Inclusive"].Clone("QCD (Data)") h1 = rhDict_den["NormQCD-" + re + "-Inclusive"].Clone("F1*QCD (MC)") h_QCDinData = histograms.Histo(h0, "QCD (Data)", "Data") h_QCDinData.setIsDataMC(isData=True, isMC=False) h_QCDinMC_After = histograms.Histo(h1, "QCD (MC)", "QCD") h_QCDinMC_After.setIsDataMC(isData=False, isMC=True) p0 = plots.ComparisonManyPlot(h_QCDinMC_After, [h_QCDinData], saveFormats=[]) p0.setLuminosity(intLumi) p0.setDefaultStyles() # Draw the plot and save it hName = "QCD_" + re + "_After_Normalization" plots.drawPlot(p0, hName, **_kwargs) SavePlot(p0, hName, os.path.join(opts.saveDir, opts.optMode), saveFormats=[".png", ".C", ".pdf"]) #======================================================================================== # Get TT in Data (Data - EWK - QCD*f1 - Single Top) in all regions #========================================================================================= for re in regions: rhDict_den["TTinData-" + re + "-Inclusive"] = rhDict_den["Data-" + re + "-Inclusive"].Clone("TTinData-" + re + "-Inclusive") rhDict_den["TTinData-" + re + "-Inclusive"].Add( rhDict_den["EWK-" + re + "-Inclusive"], -1) rhDict_den["TTinData-" + re + "-Inclusive"].Add( rhDict_den["NormQCD-" + re + "-Inclusive"], -1) rhDict_den["TTinData-" + re + "-Inclusive"].Add( rhDict_den["SingleTop-" + re + "-Inclusive"], -1) # ---------------------------------------------------------------------------- # (1) Plot inclusive TT (Data Vs MC) before any normalization in all regions # ---------------------------------------------------------------------------- for re in regions: hName = "TT_" + re + "_Before_Normalization" h0.Reset() h1.Reset() h0 = rhDict_den["TTinData-" + re + "-Inclusive"].Clone("t#bar{t} (Data)") h1 = rhDict_den["TT-SR-Inclusive"].Clone("t#bar{t} (MC)") h_TTinData = histograms.Histo(h0, "t#bar{t} (Data)", "TT") h_TTinData.setIsDataMC(isData=True, isMC=False) h_TTinMC = histograms.Histo(h1, "t#bar{t} (MC)", "TT") h_TTinMC.setIsDataMC(isData=False, isMC=True) pTT = plots.ComparisonManyPlot(h_TTinMC, [h_TTinData], saveFormats=[]) pTT.setLuminosity(intLumi) pTT.setDefaultStyles() plots.drawPlot(pTT, hName, **_kwargs) SavePlot(pTT, hName, os.path.join(opts.saveDir, opts.optMode), saveFormats=[".png", ".C", ".pdf"]) # ------------------------------------------------------------------------------ # (2) Find the normalization factor using SR # ------------------------------------------------------------------------------ n_TTinData = rhDict_den["TTinData-SR-Inclusive"].Integral() n_TTinMC = rhDict_den["TT-SR-Inclusive"].Integral() f2 = float(n_TTinData) / float(n_TTinMC) Print( "TT Normalization factor: = %s%0.6f%s in SR" % (ShellStyles.NoteStyle(), f2, ShellStyles.NormalStyle()), True) # ------------------------------------------------------------------------------ # (3) Normalize TT (MC) in all regions # ------------------------------------------------------------------------------- labels = ["Inclusive", "Fake", "Genuine"] for la in labels: for re in regions: rhDict_den["NormTT-" + re + "-" + la] = rhDict_den["TT-" + re + "-" + la].Clone("NormTT-" + re + "-" + la) rhDict_den["NormTT-" + re + "-" + la].Scale(f2) rhDict_num["NormTT-" + re + "-" + la] = rhDict_num["TT-" + re + "-" + la].Clone("NormTT-" + re + "-" + la) rhDict_num["NormTT-" + re + "-" + la].Scale(f2) # ------------------------------------------------------------------------------ # (4) Plot all regions after applying the normalization factor # ------------------------------------------------------------------------------ for re in regions: hName = "TT_" + re + "_After_Normalization" # Reset histograms h0.Reset() h1.Reset() h0 = rhDict_den["TTinData-" + re + "-Inclusive"].Clone("t#bar{t} (Data)") h1 = rhDict_den["NormTT-" + re + "-Inclusive"].Clone("t#bar{t} (MC)") h_TTinData = histograms.Histo(h0, "t#bar{t} (Data)", "TT") h_TTinData.setIsDataMC(isData=True, isMC=False) h_TTinMC_After = histograms.Histo(h1, "t#bar{t} (MC)", "TT") h_TTinMC_After.setIsDataMC(isData=False, isMC=True) p1 = plots.ComparisonManyPlot(h_TTinMC_After, [h_TTinData], saveFormats=[]) p1.setLuminosity(intLumi) p1.setDefaultStyles() plots.drawPlot(p1, hName, **_kwargs) SavePlot(p1, hName, os.path.join(opts.saveDir, opts.optMode), saveFormats=[".png", ".C", ".pdf"]) return
def doPlot(opts, mass, nameList, allShapeNuisances, luminosity, myDatacardPattern, rootFilePattern, signalTable): fName = rootFilePattern % mass f = ROOT.TFile.Open(fName) content = f.GetListOfKeys() # Suppress the warning message of missing dictionary for some iterator backup = ROOT.gErrorIgnoreLevel ROOT.gErrorIgnoreLevel = ROOT.kError diriter = content.MakeIterator() ROOT.gErrorIgnoreLevel = backup # Find the datacard and nuisance names myCardReader = DatacardReader.DataCardReader(".", mass, myDatacardPattern, rootFilePattern) myDatasetNames = myCardReader.getDatasetNames() # Find the name stem and the name of the uncertainties datasets = [] shapes = [] for d in myDatasetNames: myLabel = d myStatus = not d in nameList if d == myDatasetNames[0]: myStatus = True if not str(mass) in d: myLabel = "%sm%d" % (d, mass) myShapeNuisanceNames = myCardReader.getShapeNuisanceNames(d) myFilteredShapeNuisances = [] for n in myShapeNuisanceNames: if not "statBin" in n and not n.endswith( "_statUp") and not n.endswith("_statDown"): myFilteredShapeNuisances.append(n) if myStatus: myDataset = DatasetContainer(column=d, label=myLabel, nuisances=myFilteredShapeNuisances, cardReader=myCardReader, verbose=opts.verbose) datasets.append(myDataset) nameList.append(d) for n in myFilteredShapeNuisances: if not n in shapes: shapes.append(n) rebinList = None if opts.h2tb: rebinList = systematics._dataDrivenCtrlPlotBinning[ "LdgTetrajetMass_AfterAllSelections"] ## Do the actual plots for i, d in enumerate(datasets, 1): if opts.verbose: d.debug() msg = "{:>10}, {:<20}".format("m = %d GeV" % (mass), d.GetName()) if i < len(datasets): Print( ShellStyles.HighlightAltStyle() + msg + ShellStyles.NormalStyle(), False) else: Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), False) d.doPlot(opts, shapes, f, mass, luminosity, signalTable, rebinList) Verbose("Closing ROOT file %s" % (fName), True) f.Close()
def main(opts): # Apply TDR style style = tdrstyle.TDRStyle() style.setOptStat(False) style.setGridX(False) style.setGridY(False) # If user does not define optimisation mode do all of them if opts.optMode == None: if len(optList) < 1: optList.append("") else: pass optModes = optList else: optModes = [opts.optMode] # For-loop: All optimisation modes for opt in optModes: opts.optMode = opt # Setup & configure the dataset manager datasetsMgr = GetDatasetsFromDir(opts) datasetsMgr.updateNAllEventsToPUWeighted() datasetsMgr.loadLuminosities() # from lumi.json if opts.verbose: datasetsMgr.PrintCrossSections() datasetsMgr.PrintLuminosities() # Set/Overwrite cross-sections for d in datasetsMgr.getAllDatasets(): if "ChargedHiggs" in d.getName(): datasetsMgr.getDataset(d.getName()).setCrossSection(1.0) # Merge histograms (see NtupleAnalysis/python/tools/plots.py) if 0: plots.mergeRenameReorderForDataMC(datasetsMgr) # Print dataset information before removing anything? if 0: datasetsMgr.PrintInfo() # Print datasets info summary datasetsMgr.PrintInfo() # Re-order datasets datasetOrder = [] haveQCD = False for d in datasetsMgr.getAllDatasets(): if "QCD" in d.getName(): haveQCD = True datasetOrder.append(d.getName()) # Append signal datasets datasetsMgr.selectAndReorder(datasetOrder) Numerator = [ "AllTopQuarkPt_MatchedBDT", "TrijetFakePt_BDT", "AllTopQuarkPt_MatchedBDT", "AllTopQuarkPt_Matched", ] Denominator = [ "AllTopQuarkPt_Matched", "TrijetFakePt", "TopQuarkPt", "TopQuarkPt", ] eff_def = [ "genuineTop", "fakeTop", "inclusiveTop", "matching", ] # Merge histograms (see NtupleAnalysis/python/tools/plots.py) plots.mergeRenameReorderForDataMC(datasetsMgr) datasetsMgr.PrintInfo() counter = 0 opts.nDatasets = len(datasetsMgr.getAllDatasets()) nPlots = len(Numerator) # For-loop: All numerator-denominator pairs #for var in VariableList: for i in range(len(Numerator)): numerator = os.path.join(opts.folder, Numerator[i]) denominator = os.path.join(opts.folder, Denominator[i]) counter += 1 msg = "{:<9} {:>3} {:<1} {:<3} {:<50} {:<2} {:<50}".format( "Histogram", "%i" % counter, "/", "%s:" % (nPlots), "%s" % (numerator), "/", "%s" % (denominator)) Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), counter == 1) PlotEfficiency(datasetsMgr, numerator, denominator, eff_def[i]) if 0: hNumerator = "AllTopQuarkPt_MatchedBDT" hDenominator = "AllTopQuarkPt_Matched" numerator = os.path.join(opts.folder, hNumerator) denFolder = opts.folder #denFolder = denFolder.replace("Genuine", "") #print "denFolder", denFolder denominator = os.path.join(denFolder, hDenominator) PlotEfficiency(datasetsMgr, numerator, denominator) Print( "All plots saved under directory %s" % (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) + ShellStyles.NormalStyle()), True) return
def main(opts): #optModes = ["", "OptChiSqrCutValue50", "OptChiSqrCutValue100"] optModes = [""] if opts.optMode != None: optModes = [opts.optMode] # For-loop: All opt Mode for opt in optModes: opts.optMode = opt # Setup & configure the dataset manager datasetsMgr = GetDatasetsFromDir(opts) datasetsMgr.updateNAllEventsToPUWeighted() datasetsMgr.loadLuminosities() # from lumi.json # Set/Overwrite cross-sections datasetsToRemove = ["QCD-b"]#, "QCD_HT50to100", "QCD_HT100to200"]#, "QCD_HT200to300"]#, "QCD_HT300to500"] for d in datasetsMgr.getAllDatasets(): if "ChargedHiggs" in d.getName(): datasetsMgr.getDataset(d.getName()).setCrossSection(1.0) # ATLAS 13 TeV H->tb exclusion limits if d.getName() != opts.signal: datasetsToRemove.append(d.getName()) if opts.verbose: datasetsMgr.PrintCrossSections() datasetsMgr.PrintLuminosities() # Custom Filtering of datasets for i, d in enumerate(datasetsToRemove, 0): msg = "Removing dataset %s" % d Print(ShellStyles.WarningLabel() + msg + ShellStyles.NormalStyle(), i==0) datasetsMgr.remove(filter(lambda name: d in name, datasetsMgr.getAllDatasetNames())) if opts.verbose: datasetsMgr.PrintInfo() # ZJets and DYJets overlap if "ZJetsToQQ_HT600toInf" in datasetsMgr.getAllDatasetNames() and "DYJetsToQQ_HT180" in datasetsMgr.getAllDatasetNames(): Print("Cannot use both ZJetsToQQ and DYJetsToQQ due to duplicate events? Investigate. Removing ZJetsToQQ datasets for now ..", True) datasetsMgr.remove(filter(lambda name: "ZJetsToQQ" in name, datasetsMgr.getAllDatasetNames())) # Merge histograms (see NtupleAnalysis/python/tools/plots.py) plots.mergeRenameReorderForDataMC(datasetsMgr) # Get Luminosity intLumi = datasetsMgr.getDataset("Data").getLuminosity() # Re-order datasets (different for inverted than default=baseline) newOrder = [] # For-loop: All MC datasets for d in datasetsMgr.getMCDatasets(): newOrder.append(d.getName()) # Move signal to top if opts.signal in newOrder: s = newOrder.pop( newOrder.index(opts.signal) ) newOrder.insert(0, s) # Add Data to list of samples! if not opts.onlyMC: newOrder.insert(0, "Data") # Apply new dataset order! datasetsMgr.selectAndReorder(newOrder) # Merge EWK samples if opts.mergeEWK: datasetsMgr.merge("EWK", aux.GetListOfEwkDatasets()) plots._plotStyles["EWK"] = styles.getAltEWKStyle() # Print dataset information datasetsMgr.PrintInfo() # Apply TDR style style = tdrstyle.TDRStyle() style.setOptStat(True) style.setGridX(opts.gridX) style.setGridY(opts.gridY) # Do Data-MC histograms with DataDriven QCD folder = opts.folder histoList = datasetsMgr.getDataset(datasetsMgr.getAllDatasetNames()[0]).getDirectoryContent(folder) histoPaths1 = [os.path.join(folder, h) for h in histoList] histoPaths2 = [h for h in histoPaths1]# if "jet" not in h.lower()] nHistos = len(histoPaths2) # For-loop: All histograms for i, h in enumerate(histoPaths2, 1): msg = "{:<9} {:>3} {:<1} {:<3} {:<50}".format("Histogram", "%i" % i, "/", "%s:" % (nHistos), h) Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), i==1) PlotHistograms(datasetsMgr, h, intLumi) Print("All plots saved under directory %s" % (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) + ShellStyles.NormalStyle()), True) return
def importNormFactors(era, searchMode, optimizationMode, multicrabDirName): # Obtain suffix suffix = "" s = multicrabDirName.split("_") if s[len(s) - 1].endswith("pr") or s[len(s) - 1].endswith("prong"): suffix = "_" + s[len(s) - 1] # Find candidates for normalisation scripts fileList = os.listdir(multicrabDirName) scriptList = [] for item in fileList: if item.startswith( (_generalOptions["normalizationFactorSource"] % "").replace( ".py", "")): scriptList.append(item) moduleInfoString = "_%s_%s" % (era, searchMode) if len(optimizationMode) > 0: moduleInfoString += "_%s" % (optimizationMode) # Construct source file name src = os.path.join( multicrabDirName, _generalOptions["normalizationFactorSource"] % moduleInfoString) if not os.path.exists(src): if len(scriptList): print "Found following normalization info files:" for item in scriptList: print " ", item else: print "Found no normalization info files!" raise Exception( ShellStyles.ErrorLabel() + "Normalisation factors ('%s') not found!\nRun script QCDMeasurementNormalization.py to generate the normalization factors." % src) print "Reading normalisation factors from:", src # Check if normalization coefficients are suitable for era s = src.replace(".py", "").split("/") if len(s) > 1: # Insert the directory where the norm.coeff. files reside into the path so that they are found sys.path.insert( 0, os.path.join(os.getenv("PWD"), "/".join(map(str, s[:(len(s) - 1)])))) normFactorsImport = __import__(s[len(s) - 1]) myNormFactorsSafetyCheck = getattr(normFactorsImport, "QCDInvertedNormalizationSafetyCheck") # Check that the era, searchMode, optimizationMode info matches myNormFactorsSafetyCheck(era, searchMode, optimizationMode) # Obtain normalization factors myNormFactorsImport = getattr(normFactorsImport, "QCDNormalization") myNormFactorsImportSystVarFakeWeightingDown = getattr( normFactorsImport, "QCDPlusEWKFakeTausNormalizationSystFakeWeightingVarDown") myNormFactorsImportSystVarFakeWeightingUp = getattr( normFactorsImport, "QCDPlusEWKFakeTausNormalizationSystFakeWeightingVarUp") myNormFactors = {} myNormFactors["nominal"] = myNormFactorsImport myNormFactors[ "FakeWeightingDown"] = myNormFactorsImportSystVarFakeWeightingDown myNormFactors[ "FakeWeightingUp"] = myNormFactorsImportSystVarFakeWeightingUp return myNormFactors
def main(opts): # Apply TDR style style = tdrstyle.TDRStyle() style.setOptStat(False) style.setGridX(opts.gridX) style.setGridY(opts.gridY) style.setLogX(opts.logX) style.setLogY(opts.logY) # Setup & configure the dataset manager datasetsMgr = GetDatasetsFromDir(opts) datasetsMgr.updateNAllEventsToPUWeighted() datasetsMgr.loadLuminosities() # from lumi.json plots.mergeRenameReorderForDataMC(datasetsMgr) opts.intLumi = datasetsMgr.getDataset("Data").getLuminosity() # Do the plot moduleDict = {} moduleNames = list( filter( lambda x: "FakeBTransferFactors" in x and x.endswith(".py") and not x.startswith("#"), os.listdir(opts.mcrab))) sKeys = [] Verbose( "Found %d import files:%s%s%s" % (len(moduleNames), hs, "\n\t" + "\n\t".join(moduleNames), ns), True) # For-loop: All module files to be imported for i, m in enumerate(moduleNames, 1): # This is the default file (inclusive). But another inclusive one (.._Run2016.py) is also inclded (=>duplicate) if "80to1000" in str(m): continue if not opts.verbose: Print( "Importing module %s" % (hs + os.path.join(opts.mcrab, m) + ns), i == 1) else: Print( "Importing module %s" % (hs + os.path.join(opts.mcrab, m) + ns), True) # Define the path to the .py file (module Path) and the name to be imported as (module name) mPath = os.path.join(os.getcwd(), opts.mcrab, m) mName = m.split("_")[-1].replace(".py", "") sKeys.append(mName) mObj = imp.load_source(mName, mPath) moduleDict[mName] = mObj # Debugging Verbose(moduleDict[mName].FakeBNormalisation_Value.keys(), False) Verbose(moduleDict[mName].FakeBNormalisation_Value.values(), False) gList = [] gListR = [] # For-loop: All modules imported for i, k in enumerate(sorted(sKeys, key=natural_keys), 0): g = PlotTFs(i, k, moduleDict[k]) gList.extend(g) gListR.extend(g) # Make sure you use correct graph as reference refPos = 0 for i, g in enumerate(gList, 0): if g.getName() == opts.refHisto: refPos = i break # Reference histograph gList.insert(0, gList.pop(refPos)) gListR.insert(0, gListR.pop(refPos)) # Create comparison plot PlotTFsCompare("transferFactors", sKeys, gList) # Create comparison ratio plot gListR = [ divideGraph(g, gListR[0], errorY=True, invRatio=False) for g in gListR ] PlotTFsCompare("transferFactorsR", sKeys, gListR, isRatio=True) Print( "All plots saved under directory %s" % (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) + ShellStyles.NormalStyle()), True) return
action="store_true", default=False, help="Make short test by limiting number of syst. variations") # Add here parser options, if necessary, following line is an example #parser.add_option("--showcard", dest="showDatacard", action="store_true", default=False, help="Print datacards also to screen") # Parse options (opts, args) = parser.parse_args() # Obtain multicrab directory myMulticrabDir = "." if opts.multicrabDir != None: myMulticrabDir = opts.multicrabDir if not os.path.exists("%s/multicrab.cfg" % myMulticrabDir): raise Exception( ShellStyles.ErrorLabel() + "No multicrab directory found at path '%s'! Please check path or specify it with --mdir!" % (myMulticrabDir) + ShellStyles.NormalStyle()) if len(opts.shape) == 0: raise Exception( ShellStyles.ErrorLabel() + "Provide a shape identifierwith --shape (for example MT)!" + ShellStyles.NormalStyle()) # Set EWK source depending on calculation mode if opts.qcdonly: _generalOptions["EWKsource"] = _generalOptions["ewkSourceForQCDOnly"] else: _generalOptions["EWKsource"] = _generalOptions[ "ewkSourceForQCDPlusFakeTaus"]
def main(opts): # Apply TDR style style = tdrstyle.TDRStyle() style.setOptStat(True) style.setGridX(True) style.setGridY(True) # Obtain dsetMgrCreator and register it to module selector dsetMgrCreator = dataset.readFromMulticrabCfg(directory=opts.mcrab) # Get list of eras, modes, and optimisation modes erasList = dsetMgrCreator.getDataEras() modesList = dsetMgrCreator.getSearchModes() optList = dsetMgrCreator.getOptimizationModes() sysVarList = dsetMgrCreator.getSystematicVariations() sysVarSrcList = dsetMgrCreator.getSystematicVariationSources() # If user does not define optimisation mode do all of them if opts.optMode == None: if len(optList) < 1: optList.append("") optModes = optList else: optModes = [opts.optMode] # For-loop: All opt Mode for opt in optModes: opts.optMode = opt # Setup & configure the dataset manager datasetsMgr = GetDatasetsFromDir(opts) datasetsMgr.updateNAllEventsToPUWeighted() datasetsMgr.loadLuminosities() # from lumi.json if opts.verbose: datasetsMgr.PrintCrossSections() datasetsMgr.PrintLuminosities() # Get the PSets: if 0: datasetsMgr.printSelections() #PrintPSet("BJetSelection", datasetsMgr, depth=150) # ZJets and DYJets overlap! if "ZJetsToQQ_HT600toInf" in datasetsMgr.getAllDatasetNames( ) and "DYJetsToQQ_HT180" in datasetsMgr.getAllDatasetNames(): Print( "Cannot use both ZJetsToQQ and DYJetsToQQ due to duplicate events? Investigate. Removing ZJetsToQQ datasets for now ..", True) datasetsMgr.remove( filter(lambda name: "ZJetsToQQ" in name, datasetsMgr.getAllDatasetNames())) # Merge histograms (see NtupleAnalysis/python/tools/plots.py) plots.mergeRenameReorderForDataMC(datasetsMgr) # Get luminosity if a value is not specified if opts.intLumi < 0: opts.intLumi = datasetsMgr.getDataset("Data").getLuminosity() # Remove datasets removeList = ["QCD-b", "Charged"] if not opts.useMC: removeList.append("QCD") for i, d in enumerate(removeList, 0): msg = "Removing dataset %s" % d Verbose( ShellStyles.WarningLabel() + msg + ShellStyles.NormalStyle(), i == 0) datasetsMgr.remove( filter(lambda name: d in name, datasetsMgr.getAllDatasetNames())) # Print summary of datasets to be used if 0: datasetsMgr.PrintInfo() # Merge EWK samples datasetsMgr.merge("EWK", aux.GetListOfEwkDatasets()) # Print dataset information datasetsMgr.PrintInfo() # Do the fit on the histo after ALL selections (incl. topology cuts) folderList = datasetsMgr.getDataset( datasetsMgr.getAllDatasetNames()[0]).getDirectoryContent( opts.folder) #folderList1 = [h for h in folderList if "TetrajetPt" in h] #folderList1 = [h for h in folderList if "TetrajetMass" in h] #folderList1 = [h for h in folderList if "MET" in h] #folderList1 = [h for h in folderList if "TetrajetBJetPt" in h] folderList1 = [h for h in folderList if "TetrajetBJetEta" in h] folderList2 = [ h for h in folderList1 if "VR" in h or "SR" in h or "CRone" in h or "CRtwo" in h or "CRthree" in h or "CRfour" in h ] # For-loop: All folders histoPaths = [] for f in folderList2: folderPath = os.path.join(opts.folder, f) histoList = datasetsMgr.getDataset( datasetsMgr.getAllDatasetNames()[0]).getDirectoryContent( folderPath) pathList = [os.path.join(folderPath, h) for h in histoList] histoPaths.extend(pathList) binLabels = GetBinLabels("CRone", histoPaths) PlotHistosAndCalculateTF(datasetsMgr, histoPaths, binLabels, opts) return
def _obtainShapeHistograms(self, i, dataPath, ewkPath, dsetMgr, plotName, luminosity, normFactors): self.Verbose("_obtainShapeHistograms()", True) if self._verbose: self.PrintShapeInputSummary(dataPath, ewkPath, dsetMgr, plotName, luminosity, normFactors) self.Verbose("Obtain the (pre-normFactor) shape %s as \"DataDrivenQCDShape\" type object" % (plotName), True) myShape = dataDrivenQCDCount.DataDrivenQCDShape(dsetMgr, "Data", "EWK", plotName, dataPath, ewkPath, luminosity, self._useInclusiveNorm, self._verbose) if self._verbose: msg = "Printing TH1s (before NormFactors) of \"Data\", \"Data-Driven QCD\", \"EWK\", and \"Bin-by\Bin Purity\" and \"Integrated Purity\"" self.Print(msg, True) PrintTH1Info(myShape.getIntegratedDataHisto()) PrintTH1Info(myShape.getIntegratedDataDrivenQCDHisto()) #Data-EWK. NormFactor not applied PrintTH1Info(myShape.getIntegratedEwkHisto()) PrintTH1Info(myShape.getPurityHisto()) # Splitted-bin (disabled for Inclusive mode) PrintTH1Info(myShape.getIntegratedPurityForShapeHisto()) self.PrintShapePuritySummary(myShape) self.Verbose("Obtain the (post-normFactor) shape %s as \"QCDInvertedShape\" type object (Takes \"DataDrivenQCDShape\" type object as argument)" % (plotName), True) moduleInfo = self._moduleInfoString + "_" + plotName myPlot= QCDInvertedShape(myShape, moduleInfo, normFactors, optionUseInclusiveNorm=self._useInclusiveNorm) myPlot.PrintSettings(printHistos=self._verbose, verbose=self._verbose) # Define histogram name as will be written in the ROOT file self.Verbose("%sDefining the name of histogram objects, as they will appear in the ROOT file%s" % (ShellStyles.WarningStyle(), ShellStyles.NormalStyle()), True) hName = plotName + "%d" %i hTitle = plotName.replace("CRSelections", "AllSelections").replace("Baseline_", "").replace("Inverted_", "")#FIXME: not elegant! # DataDriven myShape.delete() myPlotHisto = aux.Clone(myPlot.getResultShape(), "ctrlPlotShapeInManager") myPlot.delete() myPlotHisto.SetName(hName) myPlotHisto.SetTitle(hTitle) self._shapePlots.append(myPlotHisto) self._shapePlotLabels.append(myPlotHisto.GetTitle())# this is the name the object will have in the ROOT file # MC EWK hName = plotName + "%d_MCEWK" %i myPlotMCEWKHisto = aux.Clone(myPlot.getResultMCEWK(), "ctrlPlotMCEWKInManager") myPlotMCEWKHisto.SetName(hName) myPlotMCEWKHisto.SetTitle(hTitle + "_MCEWK") self._shapePlots.append(myPlotMCEWKHisto) self._shapePlotLabels.append(myPlotMCEWKHisto.GetTitle())# this is the name the object will have in the ROOT file # Purity hName = plotName + "%d_Purity" %i #self.Print("myPlot.getResultPurity().GetName() = %s" % myPlot.getResultPurity().GetName(), True) #self.Print("myPlot.getResultPurity().GetIntegral() = %s" % myPlot.getResultPurity().Integral(), True) myPlotPurityHisto = aux.Clone(myPlot.getResultPurity(), "ctrlPlotPurityInManager") myPlotPurityHisto.SetName(hName) myPlotPurityHisto.SetTitle(hTitle + "_Purity") self._shapePlots.append(myPlotPurityHisto) self._shapePlotLabels.append(myPlotPurityHisto.GetTitle())# this is the name the object will have in the ROOT file return myPlotHisto
def main(opts): # Apply TDR style style = tdrstyle.TDRStyle() style.setOptStat(False) style.setGridX(opts.gridX) style.setGridY(opts.gridY) optModes = [""] if opts.optMode != None: optModes = [opts.optMode] # For-loop: All opt Mode for opt in optModes: opts.optMode = opt # Setup & configure the dataset manager datasetsMgr = GetDatasetsFromDir(opts) datasetsMgr.updateNAllEventsToPUWeighted() #datasetsMgr.loadLuminosities() # from lumi.json if opts.verbose: datasetsMgr.PrintCrossSections() datasetsMgr.PrintLuminosities() if 1: datasetsMgr.printSelections() sys.exit() # Merge histograms (see NtupleAnalysis/python/tools/plots.py) plots.mergeRenameReorderForDataMC(datasetsMgr) # Get the luminosity if opts.intLumi < 0: opts.intLumi = 35.8 #fixme # opts.intLumi = datasetsMgr.getDataset("Data").getLuminosity() # Set/Overwrite cross-sections for i, d in enumerate(datasetsMgr.getAllDatasets(), 0): if "FakeB" not in d.getName(): msg = "Removing dataset %s" % d.getName() Verbose(ShellStyles.NoteStyle() + msg + ShellStyles.NormalStyle(), i==0) datasetsMgr.remove(d.getName()) # Re-order datasets (different for inverted than default=baseline) if 0: newOrder = ["FakeB"] datasetsMgr.selectAndReorder(newOrder) # Print dataset information datasetsMgr.PrintInfo() # Get histograms under given folder in ROOT file hList = datasetsMgr.getDataset(opts.dataset).getDirectoryContent(opts.folder) hPaths1 = [os.path.join(opts.folder, h) for h in hList] hPaths2 = [h for h in hPaths1 if "Purity" in h] keepHistos = ["Njets", "MET", "MVAmax1", "MVAmax2", "LdgTetrajetPt", "LdgTetrajetMass", "TetrajetBJetPt", "TetrajetBJetEta", "TetrajetBJetBdisc", "DeltaEtaLdgTrijetBJetTetrajetBJet", "DeltaPhiLdgTrijetBJetTetrajetBJet", "DeltaRLdgTrijetBJetTetrajetBJet", "LdgTrijetPt", "LdgTrijetM", "LdgTrijetBJetBdisc"] allHistos = ["NBjets", "Bjet1Pt", "Bjet2Pt", "Bjet3Pt", "Bjet1Eta", "Bjet2Eta", "Bjet3Eta", "Bjet1Bdisc", "Bjet2Bdisc", "Bjet3Bdisc", "Njets", "Jet1Pt", "Jet2Pt", "Jet3Pt", "Jet4Pt", "Jet5Pt", "Jet6Pt", "Jet7Pt", "Jet1Eta", "Jet2Eta", "Jet3Eta", "Jet4Eta", "Jet5Eta", "Jet6Eta", "Jet7Eta", "Jet1Bdisc", "Jet2Bdisc", "Jet3Bdisc", "Jet4Bdisc", "Jet5Bdisc", "Jet6Bdisc", "Jet7Bdisc", "MET", "MVAmax1", "MVAmax2", "LdgTetrajetPt", "LdgTetrajetMass", "TetrajetBJetPt", "TetrajetBJetEta", "TetrajetBJetBdisc", "DeltaEtaLdgTrijetBJetTetrajetBJet", "DeltaPhiLdgTrijetBJetTetrajetBJet", "DeltaRLdgTrijetBJetTetrajetBJet", "LdgTrijetPt", "LdgTrijetM", "LdgTrijetBJetBdisc", "SubLdgTrijetPt", "SubLdgTrijetM", "SubLdgTrijetBJetBdisc", "LdgDijetPt", "LdgDijetM", "SubLdgDijetPt", "SubLdgDijetM"] # For-loop: All histograms for i, h in enumerate(hPaths2, 1): hName = h.split("/")[1].replace("_AfterAllSelections_Purity", "") if hName not in keepHistos: Verbose("Skipping %s" % (ShellStyles.ErrorStyle() + h + ShellStyles.NormalStyle()), i==1) continue else: Verbose("Plotting %s" % (ShellStyles.NoteStyle() + h + ShellStyles.NormalStyle()), True) if opts.doHistos: PlotHistograms(datasetsMgr, h) else: PlotHistoGraphs(datasetsMgr, h, hideZeros=True) return
def main(opts): # Apply TDR style style = tdrstyle.TDRStyle() style.setOptStat(False) style.setGridX(False) style.setGridY(False) # If user does not define optimisation mode do all of them if opts.optMode == None: if len(optList) < 1: optList.append("") else: pass optModes = optList else: optModes = [opts.optMode] # For-loop: All optimisation modes for opt in optModes: opts.optMode = opt # Setup & configure the dataset manager for pseudo-multicrab with default matching definition datasetsMgr_default = GetDatasetsFromDir(opts, opts.mcrab) datasetsMgr_default.updateNAllEventsToPUWeighted() datasetsMgr_default.loadLuminosities() datasetsMgr_second = GetDatasetsFromDir(opts, opts.mcrab2) datasetsMgr_second.updateNAllEventsToPUWeighted() datasetsMgr_second.loadLuminosities() if opts.verbose: datasetsMgr_default.PrintCrossSections() datasetsMgr_default.PrintLuminosities() # Print datasets info summary datasetsMgr_default.PrintInfo() datasetsMgr_second.PrintInfo() Numerator = ["AllTopQuarkPt_MatchedBDT", "TrijetFakePt_BDT", "AllTopQuarkPt_MatchedBDT", "AllTopQuarkPt_Matched", ] Denominator = ["AllTopQuarkPt_Matched", "TrijetFakePt", "TopQuarkPt", "TopQuarkPt", ] eff_def = ["genuineTop", "fakeTop", "inclusiveTop", "matching", ] # Merge histograms (see NtupleAnalysis/python/tools/plots.py) plots.mergeRenameReorderForDataMC(datasetsMgr_default) plots.mergeRenameReorderForDataMC(datasetsMgr_default) counter = 0 opts.nDatasets = len(datasetsMgr_default.getAllDatasets()) nPlots = len(Numerator) # For-loop: All numerator-denominator pairs for i in range(len(Numerator)): numerator = os.path.join(opts.folder, Numerator[i]) denominator = os.path.join(opts.folder, Denominator[i]) counter+=1 msg = "{:<9} {:>3} {:<1} {:<3} {:<50} {:<2} {:<50}".format("Histogram", "%i" % counter, "/", "%s:" % (nPlots), "%s" % (numerator), "/", "%s" % (denominator)) Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), counter==1) PlotEfficiency(datasetsMgr_default, datasetsMgr_second, numerator, denominator, eff_def[i]) Print("All plots saved under directory %s" % (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) + ShellStyles.NormalStyle()), True) return
def main(opts): # Apply TDR style style = tdrstyle.TDRStyle() style.setGridX(False) style.setGridY(False) optModes = [""] # For-loop: All opt Mode for opt in optModes: opts.optMode = opt # Numerator & Denominator dataset manager noSF_datasetsMgr = GetDatasetsFromDir(opts, opts.noSFcrab) withCR2SF_datasetsMgr = GetDatasetsFromDir(opts, opts.withCR2SFcrab) # Update all events to PU weighting noSF_datasetsMgr.updateNAllEventsToPUWeighted() withCR2SF_datasetsMgr.updateNAllEventsToPUWeighted() # Load Luminosities noSF_datasetsMgr.loadLuminosities() withCR2SF_datasetsMgr.loadLuminosities() if 0: noSF_datasetsMgr.PrintCrossSections() noSF_datasetsMgr.PrintLuminosities() # Merge histograms (see NtupleAnalysis/python/tools/plots.py) plots.mergeRenameReorderForDataMC(noSF_datasetsMgr) plots.mergeRenameReorderForDataMC(withCR2SF_datasetsMgr) # Get luminosity if a value is not specified if opts.intLumi < 0: opts.intLumi = noSF_datasetsMgr.getDataset("Data").getLuminosity() # Remove datasets removeList = [] for i, d in enumerate(removeList, 0): msg = "Removing dataset %s" % d Print(ShellStyles.WarningLabel() + msg + ShellStyles.NormalStyle(), i == 0) noSF_datasetsMgr.remove( filter(lambda name: d in name, noSF_datasetsMgr.getAllDatasetNames())) withCR2SF_datasetsMgr.remove( filter(lambda name: d in name, withCR2SF_datasetsMgr.getAllDatasetNames())) # Print summary of datasets to be used if 0: noSF_datasetsMgr.PrintInfo() withCR2SF_datasetsMgr.PrintInfo() # Merge EWK samples EwkDatasets = ["Diboson", "DYJetsToLL", "WJetsHT"] noSF_datasetsMgr.merge("EWK", EwkDatasets) withCR2SF_datasetsMgr.merge("EWK", EwkDatasets) # Get histosgram names folderListIncl = withCR2SF_datasetsMgr.getDataset( withCR2SF_datasetsMgr.getAllDatasetNames()[0]).getDirectoryContent( opts.folder) folderList = [ h for h in folderListIncl if "AfterAllSelections_LeadingTrijet_Pt" in h ] # For-loop: All histo paths for h in folderList: if "lowMET" in h: folderList.remove(h) folderPath = os.path.join(opts.folder, "") folderPathGen = os.path.join(opts.folder + "Genuine") folderPathFake = os.path.join(opts.folder + "Fake") histoList = folderList num_pathList = [os.path.join(folderPath, h) for h in histoList] num_pathList.extend( [os.path.join(folderPathGen, h) for h in histoList]) num_pathList.extend( [os.path.join(folderPathFake, h) for h in histoList]) # Denominator Histogram (To be used in the estimation of QCD Data-Driven) histoList = [ h for h in folderListIncl if "AfterStandardSelections_LeadingTrijet_Pt" in h ] den_pathList = [os.path.join(folderPath, h) for h in histoList] den_pathList.extend( [os.path.join(folderPathGen, h) for h in histoList]) den_pathList.extend( [os.path.join(folderPathFake, h) for h in histoList]) # For-loop: All histo paths for h in den_pathList: if "lowMET" in h: den_pathList.remove(h) # Do the histograms PlotHistos(noSF_datasetsMgr, withCR2SF_datasetsMgr, num_pathList, den_pathList, opts) return
import ROOT ROOT.gROOT.SetBatch(True) import HiggsAnalysis.NtupleAnalysis.tools.statisticalFunctions as statisticalFunctions import HiggsAnalysis.NtupleAnalysis.tools.plots as plots import HiggsAnalysis.NtupleAnalysis.tools.histograms as histograms import HiggsAnalysis.NtupleAnalysis.tools.styles as styles import HiggsAnalysis.NtupleAnalysis.tools.ShellStyles as ShellStyles import HiggsAnalysis.NtupleAnalysis.tools.aux as aux #================================================================================================ # Shell Type #================================================================================================ sh_e = ShellStyles.ErrorStyle() sh_s = ShellStyles.SuccessStyle() sh_h = ShellStyles.HighlightStyle() sh_a = ShellStyles.HighlightAltStyle() sh_l = ShellStyles.AltStyle() sh_t = ShellStyles.NoteStyle() sh_n = ShellStyles.NormalStyle() sh_w = ShellStyles.WarningStyle() #================================================================================================ # Function definitions #================================================================================================ def cleanGraph(graph, massPoint): ''' Remove mass points lower than 100
def drawAllInOne(self, myAllShapeNuisances, luminosity): myMaxSize = len(myAllShapeNuisances) # Create pads canvasHeight = _cHeaderHeight + _cBodyHeight * myMaxSize + _cFooterHeight c = ROOT.TCanvas("", "", 600, canvasHeight) c.Divide(1, myMaxSize) myHeightBefore = canvasHeight myHeightAfter = canvasHeight for i in range(0, myMaxSize): myHeightBefore = myHeightAfter p = c.cd(i + 1) myTopMargin = 0.0 myBottomMargin = 0.0 if i == 0: # Top histogram with header myHeightAfter -= _cHeaderHeight + _cBodyHeight myTopMargin = float(_cHeaderHeight) / float(_cHeaderHeight + _cBodyHeight) elif i == myMaxSize - 1: # Bottom histogram with x axis label and title myHeightAfter -= _cFooterHeight + _cBodyHeight myBottomMargin = float(_cFooterHeight) / float(_cFooterHeight + _cBodyHeight) else: # Middle histogram, only body myHeightAfter -= _cBodyHeight (xlow, ylow, xup, yup) = [ROOT.Double(x) for x in [0.0] * 4] p.GetPadPar(xlow, ylow, xup, yup) p.SetPad(xlow, float(myHeightAfter) / float(canvasHeight), xup, float(myHeightBefore) / float(canvasHeight)) p.SetBorderMode(0) p.SetFillStyle(4000) p.SetTopMargin(myTopMargin) p.SetBottomMargin(myBottomMargin) # Draw plots if len(self._ratioPlotList) == 0: self.Verbose("No ratioplots in list. Cannot draw all-in-one plot!", False) return o = self._ratioPlotList[0].getFrame2() myEmptyPlot = aux.Clone( o) # Keep the clone if it is needed to draw the x axis # For-loop: All nuisances for i in range(0, myMaxSize): p = c.cd(i + 1) # Find plot myPlotIndex = None for j in range(0, len(self._systNameList)): if myAllShapeNuisances[i] == self._systNameList[j]: myPlotIndex = j plot = None if myPlotIndex != None: plot = self._ratioPlotList[myPlotIndex].getFrame2() else: if i == myMaxSize - 1: plot = myEmptyPlot # Use this to draw the x axis else: plot = self._ratioPlotList[0].getFrame2( ) # Only the empty frame matters # Draw plot if i == myMaxSize - 1: # Bottom histogram plot.GetXaxis().SetTitleOffset(0.6 * myMaxSize + 0.6) # 6.6/10, 3.6/5 else: plot.GetXaxis().SetTitleSize(0) plot.GetXaxis().SetLabelSize(0) plot.GetYaxis().SetLabelSize(26) plot.GetYaxis().SetTitleOffset(0.34 * myMaxSize + 0.1) # 3.5/10, 1.8/5 plot.SetMinimum(0.601) # 0.001 plot.SetMaximum(1.399) # 1.999 # Plot frame for every nuisance plot.Draw() # Plot content only if affected if myPlotIndex != None: self._ratioPlotList[myPlotIndex].ratioHistoMgr.draw() self._ratioPlotList[0].ratioLine.Draw("L") p.RedrawAxis() # Labels for shape nuisance and dataset myHeight = 0.82 if i == 0: myHeight = myHeight * float(_cBodyHeight) / float( _cHeaderHeight + _cBodyHeight) elif i == myMaxSize - 1: myHeight = (myHeight * float(_cBodyHeight) + float(_cFooterHeight)) / float(_cFooterHeight + _cBodyHeight) histograms.addText(x=0.18, y=myHeight, text=myAllShapeNuisances[i], size=30) myHeight = 0.08 if i == 0: myHeight = myHeight * float(_cBodyHeight) / float( _cHeaderHeight + _cBodyHeight) elif i == myMaxSize - 1: myHeight = (myHeight * float(_cBodyHeight) + float(_cFooterHeight)) / float(_cFooterHeight + _cBodyHeight) histograms.addText(x=0.93, y=myHeight, text=self._dsetName, size=30, align="right") # Header labels if i == 0: histograms.addStandardTexts(lumi=luminosity, cmsTextPosition="outframe") # Labels for non-existing nuisances if myPlotIndex == None: myHeight = 0.44 if i == 0: myHeight = myHeight * float(_cBodyHeight) / float( _cHeaderHeight + _cBodyHeight) elif i == myMaxSize - 1: myHeight = (myHeight * float(_cBodyHeight) + float(_cFooterHeight)) / float(_cFooterHeight + _cBodyHeight) histograms.addText(x=0.555, y=myHeight, text="Not affected", size=30, align="center") # Save plot plotName = "shapeSystRatioOnlyAll_%s" % (self._dsetName) saveName = os.path.join(opts.dirName, plotName) backup = ROOT.gErrorIgnoreLevel ROOT.gErrorIgnoreLevel = ROOT.kError # For-loop: All formats to save for i, ext in enumerate([".png", ".C", ".eps"], 1): fName = saveName + ext c.Print(fName) msg = "Created file %s" % (ShellStyles.SuccessStyle() + fName + ShellStyles.NormalStyle()) self.Verbose(msg, i == 1) ROOT.gErrorIgnoreLevel = backup return
def main(opts): # Apply TDR style style = tdrstyle.TDRStyle() style.setGridX(False) style.setGridY(False) style.setOptStat(False) # Obtain dsetMgrCreator and register it to module selector dsetMgrCreator = dataset.readFromMulticrabCfg(directory=opts.mcrab) # Get list of eras, modes, and optimisation modes erasList = dsetMgrCreator.getDataEras() modesList = dsetMgrCreator.getSearchModes() optList = dsetMgrCreator.getOptimizationModes() sysVarList = dsetMgrCreator.getSystematicVariations() sysVarSrcList = dsetMgrCreator.getSystematicVariationSources() # If user does not define optimisation mode do all of them if opts.optMode == None: if len(optList) < 1: optList.append("") else: pass optModes = optList else: optModes = [opts.optMode] # For-loop: All optimisation modes for opt in optModes: opts.optMode = opt # Setup & configure the dataset manager datasetsMgr = GetDatasetsFromDir(opts) datasetsMgr.updateNAllEventsToPUWeighted() datasetsMgr.loadLuminosities() # from lumi.json if 0: datasetsMgr.printSelections() # Print PSets used for FakeBMeasurement if 0: datasetsMgr.printSelections() PrintPSet("BJetSelection", datasetsMgr) PrintPSet("TopSelectionBDT", datasetsMgr) PrintPSet("FakeBMeasurement", datasetsMgr) sys.exit() # Set/Overwrite cross-sections for d in datasetsMgr.getAllDatasets(): if "ChargedHiggs" in d.getName(): datasetsMgr.getDataset(d.getName()).setCrossSection(1.0) if opts.verbose: datasetsMgr.PrintCrossSections() datasetsMgr.PrintLuminosities() datasetsMgr.PrintInfo() # Filter the datasets datasetsMgr.remove(filter(lambda name: "Charged" in name, datasetsMgr.getAllDatasetNames())) # datasetsMgr.remove(filter(lambda name: "Charged" in name and not "M_500" in name, datasetsMgr.getAllDatasetNames())) # ZJets and DYJets overlap! if "ZJetsToQQ_HT600toInf" in datasetsMgr.getAllDatasetNames() and "DYJetsToQQ_HT180" in datasetsMgr.getAllDatasetNames(): Print("Cannot use both ZJetsToQQ and DYJetsToQQ due to duplicate events? Investigate. Removing ZJetsToQQ datasets for now ..", True) datasetsMgr.remove(filter(lambda name: "ZJetsToQQ" in name, datasetsMgr.getAllDatasetNames())) # Merge histograms (see NtupleAnalysis/python/tools/plots.py) plots.mergeRenameReorderForDataMC(datasetsMgr) # Get Luminosity if opts.intLumi < 0: if "Data" in datasetsMgr.getAllDatasetNames(): opts.intLumi = datasetsMgr.getDataset("Data").getLuminosity() else: opts.intLumi = 1.0 # Re-order datasets (different for inverted than default=baseline) if 0: newOrder = ["Data"] newOrder.extend(aux.GetListOfEwkDatasets()) datasetsMgr.selectAndReorder(newOrder) # Print post-merged data dataset summary if 0: datasetsMgr.PrintInfo() # Merge EWK samples datasetsMgr.merge("EWK", aux.GetListOfEwkDatasets()) plots._plotStyles["EWK"] = styles.getAltEWKStyle() # Print post EWK-merge dataset summary if 1: datasetsMgr.PrintInfo() # Get all histograms from the in the selected folder inside the ROOT files allHistos = datasetsMgr.getAllDatasets()[0].getDirectoryContent(opts.folder) hList = [h for h in allHistos if "CRSelections" in h and "_Vs" not in h] hList.extend([h for h in allHistos if "AllSelections" in h and "_Vs" not in h]) # hList.extend([h for h in allHistos if "StandardSelections" in h and "_Vs" not in h]) # Create a list with strings included in the histogram names you want to plot myHistos = ["LdgTrijetPt", "LdgTrijetMass", "TetrajetBJetPt", "TetrajetBJetEta", "LdgTetrajetPt", "LdgTetrajetMass", "MVAmax2", "MVAmax1", "HT", "MET"] # For-loop: All histos for i, h in enumerate(myHistos, 1): hGraphList = [] for b in ["Baseline_", "Inverted_"]: for r in [ "_AfterCRSelections", "_AfterAllSelections"]: histoName = b + h + r hgQCD, kwargs = GetPurityHistoGraph(datasetsMgr, opts.folder, histoName) # Do not draw SR in multigraph plot! if GetControlRegionLabel(histoName) != "SR": hGraphList.append(hgQCD) # Plot individual purity graphs? if 0: PlotHistoGraph(hgQCD, kwargs) msg = "{:<9} {:>3} {:<1} {:<3} {:<50}".format("Histogram", "%i" % i, "/", "%s:" % (len(myHistos)), h) Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), i==1) PlotHistoGraphs(hGraphList, kwargs) Print("All plots saved under directory %s" % (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) + ShellStyles.NormalStyle()), True) return
def main(opts): # Apply TDR style style = tdrstyle.TDRStyle() style.setGridX(opts.gridx) style.setGridY(opts.gridy) style.setLogX(opts.logx) style.setLogY(opts.logy) # Create legend and set style histograms.createLegend.moveDefaults(dx=-0.1, dh=-0.15) histograms.uncertaintyMode.set(histograms.Uncertainty.StatOnly) styles.ratioLineStyle.append(styles.StyleLine(lineColor=13)) # Define some variables nameList = [] allShapeNuisances = [] signalTable = {} myDatacardPattern = "" myRootfilePattern = "" # Find out the mass points if opts.cardPattern == None: mySettings = limitTools.GeneralSettings(".", []) myDatacardPattern = mySettings.getDatacardPattern( limitTools.LimitProcessType.TAUJETS) myRootfilePattern = mySettings.getRootfilePattern( limitTools.LimitProcessType.TAUJETS) else: myDatacardPattern = opts.cardPattern.replace("MMM", "M%s").replace( "MM", "%s") myRootfilePattern = opts.rootfilePattern.replace("MMM", "M%s").replace( "MM", "%s") # Get mass points to consider massPoints = DatacardReader.getMassPointsForDatacardPattern( ".", myDatacardPattern) Print( "The following masses will be considered: %s" % (ShellStyles.HighlightAltStyle() + ", ".join(massPoints) + ShellStyles.NormalStyle()), True) # For-loop: All mass points for i, m in enumerate(massPoints, 1): # Obtain luminosity from the datacard myLuminosity = float( limitTools.readLuminosityFromDatacard(".", myDatacardPattern % m)) # Do the plots doPlot(opts, int(m), nameList, allShapeNuisances, myLuminosity, myDatacardPattern, myRootfilePattern, signalTable) # Print signal table Print("Max contracted uncertainty for signal:", True) table = [] align = "{:>15} {:>15} {:>15}" hLine = "=" * 50 table.append(hLine) table.append(align.format("Systematic", "Minimum", "Maximum")) table.append(hLine) # For-loop: All signal for i, k in enumerate(signalTable.keys(), 1): # Print("Key = %s" % (k), False) minVal = "%.3f" % (signalTable[k]["min"]) maxVal = "%.3f" % (signalTable[k]["max"]) msg = align.format(k, minVal, maxVal) table.append(msg) table.append(hLine) for row in table: Print(row, False) msg = "All results under directory %s" % ( ShellStyles.SuccessStyle() + opts.dirName + ShellStyles.NormalStyle()) Print(msg, True) return
def __init__(self, opts, config, dirname, luminosity, observation, datasetGroups): plots._legendLabels["MCStatError"] = "Bkg. stat." plots._legendLabels["MCStatSystError"] = "Bkg. stat.#oplussyst." plots._legendLabels["BackgroundStatError"] = "Bkg. stat. unc" plots._legendLabels["BackgroundStatSystError"] = "Bkg. stat.#oplussyst. unc." if config.ControlPlots == None: return myStyle = tdrstyle.TDRStyle() myStyle.setOptStat(False) self._opts = opts self._config = config if config.OptionSqrtS == None: raise Exception(ShellStyles.ErrorLabel()+"Please set the parameter OptionSqrtS = <integer_value_in_TeV> in the config file!"+ShellStyles.NormalStyle()) self._dirname = dirname self._luminosity = luminosity self._observation = observation self._datasetGroups = datasetGroups #myEvaluator = SignalAreaEvaluator() # Make control plots print "\n"+ShellStyles.HighlightStyle()+"Generating control plots"+ShellStyles.NormalStyle() # Loop over mass points for m in self._config.MassPoints: print "... mass = %d GeV"%m # Initialize flow plot selectionFlow = SelectionFlowPlotMaker(self._opts, self._config, m) myBlindedStatus = False for i in range(0,len(self._config.ControlPlots)): if observation.getControlPlotByIndex(i) != None: myCtrlPlot = self._config.ControlPlots[i] print "......", myCtrlPlot.title myMassSuffix = "_M%d"%m # Initialize histograms hSignal = None hQCD = None hEmbedded = None hEWKfake = None hData = None # Loop over dataset columns to find histograms myStackList = [] for c in self._datasetGroups: if c.isActiveForMass(m,self._config) and not c.typeIsEmptyColumn() and not c.getControlPlotByIndex(i) == None: h = c.getControlPlotByIndex(i)["shape"].Clone() if c.typeIsSignal(): #print "signal:",c.getLabel() # Scale light H+ signal if m < 179: if c.getLabel()[:2] == "HH": h.Scale(self._config.OptionBr**2) elif c.getLabel()[:2] == "HW": h.Scale(2.0*self._config.OptionBr*(1.0-self._config.OptionBr)) if hSignal == None: hSignal = h.Clone() else: hSignal.Add(h) elif c.typeIsQCD(): #print "QCD:",c.getLabel(),h.getRootHisto().Integral(0,h.GetNbinsX()+2) if hQCD == None: hQCD = h.Clone() else: hQCD.Add(h) elif c.typeIsEWK(): #print "EWK genuine:",c.getLabel(),h.getRootHisto().Integral(0,h.GetNbinsX()+2) if not self._config.OptionGenuineTauBackgroundSource == "DataDriven": myHisto = histograms.Histo(h,c._datasetMgrColumn) myHisto.setIsDataMC(isData=False, isMC=True) myStackList.append(myHisto) else: if hEmbedded == None: hEmbedded = h.Clone() else: hEmbedded.Add(h) elif c.typeIsEWKfake(): #print "EWK fake:",c.getLabel(),h.getRootHisto().Integral(0,h.GetNbinsX()+2) if hEWKfake == None: hEWKfake = h.Clone() else: hEWKfake.Add(h) if len(myStackList) > 0 or self._config.OptionGenuineTauBackgroundSource == "DataDriven": if hQCD != None: myHisto = histograms.Histo(hQCD,"QCD",legendLabel=_legendLabelQCD) myHisto.setIsDataMC(isData=False, isMC=True) myStackList.insert(0, myHisto) if hEmbedded != None: myHisto = histograms.Histo(hEmbedded,"Embedding",legendLabel=_legendLabelEmbedding) myHisto.setIsDataMC(isData=False, isMC=True) myStackList.append(myHisto) if hEWKfake != None: myHisto = histograms.Histo(hEWKfake,"EWKfakes",legendLabel=_legendLabelEWKFakes) myHisto.setIsDataMC(isData=False, isMC=True) myStackList.append(myHisto) hData = observation.getControlPlotByIndex(i)["shape"].Clone() hDataUnblinded = hData.Clone() # Apply blinding myBlindingString = None if self._config.BlindAnalysis: if len(myCtrlPlot.blindedRange) > 0: myBlindingString = self._applyBlinding(hData,myCtrlPlot.blindedRange) if self._config.OptionBlindThreshold != None: for k in xrange(1, hData.GetNbinsX()+1): myExpValue = 0.0 for item in myStackList: myExpValue += item.getRootHisto().GetBinContent(k) if hSignal.getRootHisto().GetBinContent(k) >= myExpValue * self._config.OptionBlindThreshold: hData.getRootHisto().SetBinContent(k, -1.0) hData.getRootHisto().SetBinError(k, 0.0) # Data myDataHisto = histograms.Histo(hData,"Data") myDataHisto.setIsDataMC(isData=True, isMC=False) myStackList.insert(0, myDataHisto) # Add signal mySignalLabel = "TTToHplus_M%d"%m if m > 179: mySignalLabel = "HplusTB_M%d"%m myHisto = histograms.Histo(hSignal,mySignalLabel) myHisto.setIsDataMC(isData=False, isMC=True) myStackList.insert(1, myHisto) # Add data to selection flow plot #if myBlindedStatus: # selectionFlow.addColumn(myCtrlPlot.flowPlotCaption,None,myStackList[1:]) #else: selectionFlow.addColumn(myCtrlPlot.flowPlotCaption,hDataUnblinded,myStackList[1:]) if len(myCtrlPlot.blindedRange) > 0: myBlindedStatus = True else: myBlindedStatus = False # Make plot myStackPlot = None myParams = myCtrlPlot.details.copy() #if not isinstance(hData, ROOT.TH2): #for j in range(1,myStackList[0].getRootHisto().GetNbinsY()+1): #for i in range(1,myStackList[0].getRootHisto().GetNbinsX()+1): #mySum = 0.0 #for h in range(2, len(myStackList)): #mySum += myStackList[h].getRootHisto().GetBinContent(i,j) #if mySum > 0.0: #myStackList[0].getRootHisto().SetBinContent(i,j,myStackList[0].getRootHisto().GetBinContent(i,j) / mySum) #else: #myStackList[0].getRootHisto().SetBinContent(i,j,-10.0) #myStackList[0].getRootHisto().SetMinimum(-1.0) #myStackList[0].getRootHisto().SetMaximum(1.0) #myStackList = [myStackList[0]] #myStackPlot = plots.PlotBase(myStackList) #if "ylabelBinInfo" in myParams: #del myParams["ylabelBinInfo"] #del myParams["unit"] #drawPlot2D(myStackPlot, "%s/DataDrivenCtrlPlot_M%d_%02d_%s"%(self._dirname,m,i,myCtrlPlot.title), **myParams) myStackPlot = plots.DataMCPlot2(myStackList) myStackPlot.setLuminosity(self._luminosity) myStackPlot.setEnergy("%d"%self._config.OptionSqrtS) myStackPlot.setDefaultStyles() # Tweak paramaters if not "unit" in myParams.keys(): myParams["unit"] = "" if myParams["unit"] != "": myParams["xlabel"] = "%s (%s)"%(myParams["xlabel"],myParams["unit"]) ylabelBinInfo = True if "ylabelBinInfo" in myParams: ylabelBinInfo = myParams["ylabelBinInfo"] del myParams["ylabelBinInfo"] if ylabelBinInfo: myMinWidth = 10000.0 myMaxWidth = 0.0 for j in range(1,hData.getRootHisto().GetNbinsX()+1): w = hData.getRootHisto().GetBinWidth(j) if w < myMinWidth: myMinWidth = w if w > myMaxWidth: myMaxWidth = w myWidthSuffix = "" myMinWidthString = "%d"%myMinWidth myMaxWidthString = "%d"%myMaxWidth if myMinWidth < 1.0: myFormat = "%%.%df"%(abs(int(log10(myMinWidth)))+1) myMinWidthString = myFormat%myMinWidth if myMaxWidth < 1.0: myFormat = "%%.%df"%(abs(int(log10(myMaxWidth)))+1) myMaxWidthString = myFormat%myMaxWidth myWidthSuffix = "%s-%s"%(myMinWidthString,myMaxWidthString) if abs(myMinWidth-myMaxWidth) < 0.001: myWidthSuffix = "%s"%(myMinWidthString) if not (myParams["unit"] == "" and myWidthSuffix == "1"): myParams["ylabel"] = "%s / %s %s"%(myParams["ylabel"],myWidthSuffix,myParams["unit"]) if myBlindingString != None: if myParams["unit"] != "" and myParams["unit"][0] == "^": myParams["blindingRangeString"] = "%s%s"%(myBlindingString, myParams["unit"]) else: myParams["blindingRangeString"] = "%s %s"%(myBlindingString, myParams["unit"]) if "legendPosition" in myParams.keys(): # FIXME: there is a mixup of east and west here if myParams["legendPosition"] == "NW": myParams["moveLegend"] = {"dx": -0.22, "dy": 0.00} elif myParams["legendPosition"] == "SW": myParams["moveLegend"] = {"dx": -0.22, "dy": -0.45} elif myParams["legendPosition"] == "SE": myParams["moveLegend"] = {"dx": -0.53, "dy": -0.45} elif myParams["legendPosition"] == "NE": myParams["moveLegend"] = {"dx": -0.53, "dy": 0.00} else: raise Exception("Unknown value for option legendPosition: %s!", myParams["legendPosition"]) del myParams["legendPosition"] elif not "moveLegend" in myParams: myParams["moveLegend"] = {"dx": -0.22, "dy": 0.00} if "ratioLegendPosition" in myParams.keys(): if myParams["ratioLegendPosition"] == "left": myParams["ratioMoveLegend"] = {"dx": -0.51, "dy": 0.03} elif myParams["ratioLegendPosition"] == "right": myParams["ratioMoveLegend"] = {"dx": 0.00, "dy": 0.03} elif myParams["ratioLegendPosition"] == "SE": myParams["ratioMoveLegend"] = {"dx": -0.06, "dy": -0.33} else: raise Exception("Unknown value for option ratioLegendPosition: %s!", myParams["ratioLegendPosition"]) del myParams["ratioLegendPosition"] else: if not "ratioMoveLegend" in myParams: myParams["ratioMoveLegend"] = {"dx": -0.51, "dy": 0.03} # Remove non-dientified keywords del myParams["unit"] # Ratio axis if not "opts2" in myParams.keys(): myParams["opts2"] = {"ymin": 0.5, "ymax": 1.5} # Do plotting drawPlot(myStackPlot, "%s/DataDrivenCtrlPlot_M%d_%02d_%s"%(self._dirname,m,i,myCtrlPlot.title), **myParams) # Do selection flow plot selectionFlow.makePlot(self._dirname,m,len(self._config.ControlPlots),self._luminosity) #myEvaluator.save(dirname) print "Control plots done"
import os import re import time import getpass import sys import datetime import string from optparse import OptionParser import HiggsAnalysis.NtupleAnalysis.tools.aux as aux import HiggsAnalysis.NtupleAnalysis.tools.ShellStyles as ShellStyles #================================================================================================ # Variable definition #================================================================================================ ss = ShellStyles.SuccessStyle() ns = ShellStyles.NormalStyle() ts = ShellStyles.NoteStyle() hs = ShellStyles.HighlightAltStyle() ls = ShellStyles.HighlightStyle() es = ShellStyles.ErrorStyle() cs = ShellStyles.CaptionStyle() #================================================================================================ # Function definition #================================================================================================ def Verbose(msg, printHeader=False): ''' Calls Print() only if verbose options is set to true. '''
# Do calculation manager.calculateCombinedNormalizationCoefficient(qcdMt, ewkFakeTausMt) #===== Save normalization outFileName = "QCDNormalizationFactors_%s_%s.py"%(HISTONAME, moduleInfoString) outFileFullName = os.path.join(argv[1],outFileName) manager.writeScaleFactorFile(outFileFullName, moduleInfoString) if __name__ == "__main__": # Check parameters if len(sys.argv) < 2: usage() # Find out the era/search mode/optimization mode combinations and run each of them myModuleSelector = analysisModuleSelector.AnalysisModuleSelector() dsetMgrCreator = dataset.readFromMulticrabCfg(directory=sys.argv[1]) myModuleSelector.setPrimarySource("analysis", dsetMgrCreator) myModuleSelector.doSelect(None) #myModuleSelector.printSelectedCombinationCount() for era in myModuleSelector.getSelectedEras(): for searchMode in myModuleSelector.getSelectedSearchModes(): for optimizationMode in myModuleSelector.getSelectedOptimizationModes(): print ShellStyles.HighlightStyle()+"\nCalculating normalization for module %s/%s/%s%s"%(era, searchMode, optimizationMode, ShellStyles.NormalStyle()) # Construct info string for the module moduleInfoString = "%s_%s"%(era, searchMode) if len(optimizationMode) > 0: moduleInfoString += "_%s"%(optimizationMode) # Create dataset manager dsetMgr = dsetMgrCreator.createDatasetManager(dataEra=era,searchMode=searchMode,optimizationMode=optimizationMode) main(sys.argv, dsetMgr, moduleInfoString) dsetMgrCreator.close()
# "Run2016H" : ["Run2016H"], ### Custom-tailor dataset sets (3 groups) # "Run2016BCD": ["Run2016B", "Run2016C", "Run2016D"], # "Run2016EF" : ["Run2016E", "Run2016F"], # "Run2016GH" : ["Run2016G", "Run2016H"], ### Custom-tailor dataset sets (4 groups) "Run2016BC": ["Run2016B", "Run2016C"], "Run2016DE": ["Run2016D", "Run2016E"], "Run2016FG": ["Run2016F", "Run2016G"], "Run2016H": ["Run2016H"], } # Do partial data dataset (closure attempt) for i, rr in enumerate(dsetSets, 1): opts.saveDir = aux.getSaveDirPath(opts.mcrab, prefix="", postfix="TransferFactor_%s" % rr) dsetList = dsetSets[rr] Verbose("%d) %s" % (i, ", ".join(dsetList)), i == 1) main(i, rr, dsetList, opts) Print( "%sAll plots saved under %s%s" % (ShellStyles.SuccessStyle(), opts.saveDir, ShellStyles.NormalStyle()), True) if not opts.batchMode: raw_input( "=== plot_FakeBInPartialDataset.py: Press any key to quit ROOT ..." )
def main(opts): #optModes = ["", "OptChiSqrCutValue50", "OptChiSqrCutValue100"] optModes = [""] if opts.optMode != None: optModes = [opts.optMode] # For-loop: All opt Mode for opt in optModes: opts.optMode = opt # Setup & configure the dataset manager datasetsMgr = GetDatasetsFromDir(opts) datasetsMgr.updateNAllEventsToPUWeighted() datasetsMgr.loadLuminosities() # from lumi.json if 0: datasetsMgr.printSelections() sys.exit() # Define datasets to remove by default QCD_list = ["QCD_HT700to1000", "QCD_HT50to100", "QCD_HT500to700", "QCD_HT300to500", "QCD_HT200to300", "QCD_HT2000toInf", "QCD_HT1500to2000", "QCD_HT100to200", "QCD_HT1000to1500"] QCDExt_list = [x+"_ext1" for x in QCD_list] datasetsToRemove = ["QCD-b"] # datasetsToRemove.extend(QCD_list) # datasetsToRemove.extend(QCDExt_list) # ZJets and DYJets overlap if "ZJetsToQQ_HT600toInf" in datasetsMgr.getAllDatasetNames() and "DYJetsToQQ_HT180" in datasetsMgr.getAllDatasetNames(): Print("Cannot use both ZJetsToQQ and DYJetsToQQ due to duplicate events? Investigate. Removing ZJetsToQQ datasets for now ..", True) datasetsMgr.remove(filter(lambda name: "ZJetsToQQ" in name, datasetsMgr.getAllDatasetNames())) #datasetsMgr.remove(filter(lambda name: "DYJetsToQQ" in name, datasetsMgr.getAllDatasetNames())) # Set/Overwrite cross-sections for d in datasetsMgr.getAllDatasets(): if "ChargedHiggs" in d.getName(): datasetsMgr.getDataset(d.getName()).setCrossSection(1.0) # ATLAS 13 TeV H->tb exclusion limits if d.getName() != opts.signal: datasetsToRemove.append(d.getName()) if opts.verbose: datasetsMgr.PrintCrossSections() datasetsMgr.PrintLuminosities() # Merge histograms (see NtupleAnalysis/python/tools/plots.py) plots.mergeRenameReorderForDataMC(datasetsMgr) # Custom Filtering of datasets for i, d in enumerate(datasetsToRemove, 0): msg = "Removing dataset %s" % d Verbose(ShellStyles.WarningLabel() + msg + ShellStyles.NormalStyle(), i==0) datasetsMgr.remove(filter(lambda name: d == name, datasetsMgr.getAllDatasetNames())) if opts.verbose: datasetsMgr.PrintInfo() # Re-order datasets (different for inverted than default=baseline) newOrder = ["Data"] for i, d in enumerate(datasetsMgr.getAllDatasets(), 0): if d.isData(): continue else: newOrder.append(d.getName()) # Re-arrange dataset order? if 0: s = newOrder.pop( newOrder.index("noTop") ) newOrder.insert(len(newOrder), s) #after "Data" # Move signal to top if opts.signal in newOrder: s = newOrder.pop( newOrder.index(opts.signal) ) newOrder.insert(1, s) datasetsMgr.selectAndReorder(newOrder) # Merge EWK samples if opts.mergeEWK: datasetsMgr.merge("EWK", aux.GetListOfEwkDatasets()) plots._plotStyles["EWK"] = styles.getAltEWKStyle() # Print dataset information datasetsMgr.PrintInfo() # Apply TDR style style = tdrstyle.TDRStyle() style.setOptStat(True) style.setGridX(opts.gridX) style.setGridY(opts.gridY) # Do Data-MC histograms with DataDriven QCD folder = opts.folder histoList = datasetsMgr.getDataset(datasetsMgr.getAllDatasetNames()[0]).getDirectoryContent(folder) histoPaths = [os.path.join(folder, h) for h in histoList] ignoreList = ["Aplanarity", "Planarity", "Sphericity", "FoxWolframMoment", "Circularity", "ThirdJetResolution", "Centrality", "_Vs_"] myHistos = [] for h in histoPaths: skip = False # Skip unwanted histos for i in ignoreList: if i in h: skip = True if skip: continue else: myHistos.append(h) for i, h in enumerate(myHistos, 1): # Plot the histograms! msg = "{:<9} {:>3} {:<1} {:<3} {:<50}".format("Histogram", "%i" % i, "/", "%s:" % (len(myHistos)), h) Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), i==1) DataMCHistograms(datasetsMgr, h) Print("All plots saved under directory %s" % (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) + ShellStyles.NormalStyle()), True) 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 GetHistoKwargs(h, opts): # Common bin settings myBins = [] vtxBins = [] ptBins = [] yMax = 1.04 bWidth = 2 for i in range(0, 40, bWidth): vtxBins.append(i) bWidth = 10 #25 for i in range(40, 100+bWidth, bWidth): vtxBins.append(i) _kwargs = { "ylabel" : "Purity / %.0f ", #"rebinX" : 1, # cannot rebin unless i divide new purity value by rebinX value! #"rebinY" : None, "addMCUncertainty" : False, "addLuminosityText": True, "addCmText" : True, "cmsExtraText" : "Preliminary", "opts" : {"ymin": 0.0, "ymax": yMax}, "log" : False, "moveLegend" : {"dx": -0.05, "dy": -0.15, "dh": -0.1}, "cutBoxY" : {"cutValue": 1.0, "fillColor": 16, "box": False, "line": True, "greaterThan": True, "mainCanvas": True, "ratioCanvas": False} } kwargs = copy.deepcopy(_kwargs) if "deltaphi" in h.lower(): units = "rads" kwargs["xlabel"] = "#Delta#phi (%s)" % units kwargs["ylabel"] = "Purity / %.2f " + units elif "deltaeta" in h.lower(): units = "" kwargs["xlabel"] = "#Delta#eta" kwargs["ylabel"] = "Purity / %.2f " + units kwargs["opts"] = {"xmin": 0.0 ,"xmax": 5.0, "ymin": 0.0, "ymax": yMax} elif "deltar" in h.lower(): units = "" kwargs["xlabel"] = "#DeltaR" kwargs["ylabel"] = "Purity / %.2f " + units kwargs["opts"] = {"xmin": 0.0 ,"xmax": 6.0, "ymin": 0.0, "ymax": yMax} elif "mvamax" in h.lower(): units = "" kwargs["xlabel"] = "top-tag discriminant" kwargs["ylabel"] = "Purity / %.2f " + units kwargs["cutBox"] = {"cutValue": 0.85, "fillColor": 16, "box": False, "line": True, "greaterThan": True} kwargs["opts"] = {"xmin": 0.55 ,"xmax": 1.0, "ymin": 0.0, "ymax": yMax} if "max1" in h.lower(): pass else: pass elif "bdisc" in h.lower(): units = "" kwargs["xlabel"] = "b-tag discriminant" kwargs["ylabel"] = "Purity / %.2f " + units kwargs["cutBox"] = {"cutValue": 0.8484, "fillColor": 16, "box": False, "line": True, "greaterThan": True} kwargs["opts"] = {"xmin": 0.0 ,"xmax": 1.0, "ymin": 0.0, "ymax": yMax} elif "pt" in h.lower(): ROOT.gStyle.SetNdivisions(8, "X") units = "GeV/c" kwargs["xlabel"] = "p_{T} (%s)" % units kwargs["ylabel"]+= units # kwargs["cutBox"] = {"cutValue": 40.0, "fillColor": 16, "box": True, "line": True, "greaterThan": True} kwargs["opts"] = {"xmin": 0.0 ,"xmax": 500.0, "ymin": 0.0, "ymax": yMax} if "tetrajet" in h.lower(): kwargs["opts"] = {"xmin": 0.0 ,"xmax": 800.0, "ymin": 0.0, "ymax": yMax} elif "mass" in h.lower() or "jetM" in h: units = "GeV/c^{2}" kwargs["xlabel"] = "m_{jjb}^{ldg} (%s)" % units kwargs["ylabel"] += units if "trijet" in h.lower(): kwargs["opts"] = {"xmin": 50.0 ,"xmax": 300.0, "ymin": 0.0, "ymax": yMax} kwargs["cutBox"] = {"cutValue": 173.21, "fillColor": 16, "box": False, "line": True, "greaterThan": True} if "tetrajet" in h.lower(): kwargs["opts"] = {"xmin": 0.0 ,"xmax": 3000.0, "ymin": 0.0, "ymax": yMax} kwargs["cutBox"] = {"cutValue": 173.21, "fillColor": 16, "box": False, "line": False, "greaterThan": True} elif "MET" in h: units = "GeV" kwargs["xlabel"] = "E_{T}^{miss} (%s)" % units kwargs["ylabel"] += units elif "Njets" in h: units = "" kwargs["xlabel"] = "jet multiplicity" #kwargs["ylabel"] += units kwargs["opts"] = {"xmin": 6.0 ,"xmax": 18.0, "ymin": 0.0, "ymax": yMax} kwargs["cutBox"] = {"cutValue": 7.0, "fillColor": 16, "box": False, "line": True, "greaterThan": True} elif "HT" in h: units = "GeV" kwargs["xlabel"] = "H_{T} (%s)" % units kwargs["ylabel"] = "Purity / %.0f " + units kwargs["cutBox"] = {"cutValue": 500.0, "fillColor": 16, "box": True, "line": True, "greaterThan": True} kwargs["opts"]["xmax"] = 3000.0 elif "eta" in h.lower(): units = "" kwargs["xlabel"] = "#eta" kwargs["ylabel"] = "Purity / %.2f " + units kwargs["cutBox"] = {"cutValue": 0.0, "fillColor": 16, "box": False, "line": True, "greaterThan": True} kwargs["opts"] = {"xmin": -2.5 ,"xmax": 2.5, "ymin": 0.0, "ymax": yMax} if "trijet" in h.lower(): pass if "bjet" in h.lower(): pass else: Print("Could not customise kwargs for %s" % (ShellStyles.ErrorStyle() + h + ShellStyles.NormalStyle()), True) return kwargs
def plot(self): style = tdrstyle.TDRStyle() ROOT.gStyle.SetErrorX(0.5) #required for x-axis error bars! (must be called AFTER tdrstyle.TDRStyle()) histolist = [] #styles.dataStyle.apply(self.h_data) hhd = histograms.Histo(self.h_data,"Data", legendStyle="PL", drawStyle="E1P") hhd.setIsDataMC(isData=True, isMC=False) histolist.append(hhd) # For-loop: All signal histo for i, hsignal in enumerate(self.h_signal, 1): mass = hsignal.GetName().replace("Hp", "") Verbose( "Customing signal histogram for Mass = \"%s\"" % (mass), i==1) hhs = histograms.Histo(hsignal,hsignal.GetTitle(), legendStyle="L", drawStyle="HIST") hhs.setIsDataMC(isData=False, isMC=True) signalStyle = styles.getSignalStyleHToTB_M(mass) signalStyle.apply(hhs.getRootHisto()) histolist.append(hhs) # For-loop: All bkg histos for i, hname in enumerate(self.histonames, 1): # Safety net for empty histos if hname in opts.empty: msg = "Skipping %s. Not a histogram!" % (hname) Print(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(), True) continue else: #print hname pass myLabel = self.labels[hname] myHisto = self.histograms[hname] Verbose("Creating histogram \"%s\" from ROOT file \"%s\" (Integral = %.1f)" % (hname, myHisto.GetName(), myHisto.Integral()), i==1) hhp = histograms.Histo(myHisto, hname, legendStyle="F", drawStyle="HIST", legendLabel=myLabel) hhp.setIsDataMC(isData=False,isMC=True) histolist.append(hhp) # Sanity check for i, h in enumerate(histolist, 1): hName = h.getRootHisto().GetName() Verbose(hName, i==1) # Do the plot p = plots.DataMCPlot2(histolist) p.setDefaultStyles() p.stackMCHistograms() p.setLuminosity(opts.lumi) if opts.fitUncert: p.addMCUncertainty(postfit=not opts.prefit) # boolean changes only the legend if opts.prefit: p.setLegendHeader("Pre-Fit") else: p.setLegendHeader("Post-Fit") # Customise histogram units = "GeV" #(GeV/c^{2}) myParams = {} myParams["xlabel"] = "m_{jjbb} (%s)" % (units) myParams["ylabel"] = "< Events / " + units + " >" myParams["ratio"] = True myParams["ratioYlabel"] = "Data/Bkg. " myParams["logx"] = self.gOpts.logX myParams["log"] = self.gOpts.logY myParams["ratioType"] = "errorScale" myParams["ratioErrorOptions"] = {"numeratorStatSyst": False, "denominatorStatSyst": True} myParams["opts"] = self.opts myParams["optsLogx"] = self.optsLogx myParams["opts2"] = self.opts2 myParams["divideByBinWidth"] = True #not opts.fitUncert # Error when used for "TGraphAsymmErrors" (uncert.) myParams["errorBarsX"] = True myParams["xlabelsize"] = 25 myParams["ylabelsize"] = 25 myParams["addMCUncertainty"] = True myParams["addLuminosityText"] = True myParams["moveLegend"] = self.moveLegend #myParams["saveFormats"] = [] # Draw the plot if not os.path.exists(opts.saveDir): os.makedirs(opts.saveDir) plots.drawPlot(p, os.path.join(opts.saveDir, self.gOpts.saveName), **myParams) # Save the plot (not needed - drawPlot saves the canvas already) SavePlot(p, self.gOpts.saveName, opts.saveDir, saveFormats = [".png", ".pdf", ".C"]) return
def _doCalculate(self, shape, moduleInfoString, normFactors, optionPrintPurityByBins, optionDoNQCDByBinHistograms): ''' Calculates the result ''' self.Verbose("Calculate final shape in signal region (shape * w_QCD) & initialize result containers", True) nSplitBins = shape.getNumberOfPhaseSpaceSplitBins() self.Verbose("The phase-space of shape %s is split into %i bin(s)" % (shape.getDataDrivenQCDHistoForSplittedBin(0).GetName(), nSplitBins), True) self.Verbose("Create Data-Driven Shape", True) self._resultShape = aux.Clone(shape.getDataDrivenQCDHistoForSplittedBin(0)) self._resultShape.Reset() self._resultShape.SetTitle("FakeB_Total_%s"%moduleInfoString) self._resultShape.SetName("FakeB_Total_%s"%moduleInfoString) self.Verbose("Create EWK shape", True) self._resultShapeEWK = aux.Clone(shape.getDataDrivenQCDHistoForSplittedBin(0)) self._resultShapeEWK.Reset() self._resultShapeEWK.SetTitle("FakeB_EWK_%s"%moduleInfoString) self._resultShapeEWK.SetName("FakeB_EWK_%s"%moduleInfoString) self.Verbose("Create Purity shape", True) self._resultShapePurity = aux.Clone(shape.getDataDrivenQCDHistoForSplittedBin(0)) self._resultShapePurity.Reset() self._resultShapePurity.SetTitle("FakeB_Purity_%s"%moduleInfoString) self._resultShapePurity.SetName("FakeB_Purity_%s"%moduleInfoString) self._histogramsList = [] myUncertaintyLabels = ["statData", "statEWK"] self._resultCountObject = extendedCount.ExtendedCount(0.0, [0.0, 0.0], myUncertaintyLabels) if optionDoNQCDByBinHistograms: for i in range(0, nSplitBins): hBin = aux.Clone(self._resultShape) hBin.SetTitle("FakeB_%s_%s"%(shape.getPhaseSpaceBinFileFriendlyTitle(i).replace(" ",""), moduleInfoString)) hBin.SetName("FakeB_%s_%s"%(shape.getPhaseSpaceBinFileFriendlyTitle(i).replace(" ",""), moduleInfoString)) self._histogramsList.append(hBin) if isinstance(self._resultShape, ROOT.TH2): self.Verbose("Skippings TH2 histogram with name '%s'. The 2d function needs validation first!" % (self._resultShape.GetName()), False) # self._doCalculate2D(nSplitBins, shape, normFactors, optionPrintPurityByBins, optionDoNQCDByBinHistograms, myUncertaintyLabels) return # Intialize counters for purity calculation in final shape binning myShapeDataSum = [] myShapeDataSumUncert = [] myShapeEwkSum = [] myShapeEwkSumUncert = [] # For-loop: All histogram bins for j in range(1, self._resultShape.GetNbinsX()+1): myShapeDataSum.append(0.0) myShapeDataSumUncert.append(0.0) myShapeEwkSum.append(0.0) myShapeEwkSumUncert.append(0.0) # FIXME: New addition to fix "optionUseInclusiveNorm" functionality (24-Mar-2018). Should not affect binned result! if self._optionUseInclusiveNorm: nSplitBins = 1 self.Verbose("Calculate results separately for each phase-space bin and then combine", True) # For-loop: All measurement bins (e.g. tetrajetBejt eta and/or pT bins for h2tb) for i in range(0, nSplitBins): # The zeroth bin (i==0) is the "Inclusive" bin msg = "{:<10} {:>3} {:<1} {:<3} {:<30}".format("Splitted-Bin", "%i" % i, "/", "%s" % (nSplitBins), "") self.Verbose(ShellStyles.HighlightStyle() + msg + ShellStyles.NormalStyle(), False) hName = shape.getDataDrivenQCDHistoForSplittedBin(i).GetName() self.Verbose("Get data-driven Fake-b, data, and EWK MC shape histogram %s for the phase-space bin #%i" % (hName, i), i==0) h = shape.getDataDrivenQCDHistoForSplittedBin(i) hData = shape.getDataHistoForSplittedBin(i) hEwk = shape.getEwkHistoForSplittedBin(i) self.Verbose("Get normalization factor", True) wQCDLabel = "%s" % i #shape.getPhaseSpaceBinFileFriendlyTitle(i) if self._optionUseInclusiveNorm: wQCDLabel = "Inclusive" wQCD = 0.0 if not wQCDLabel in normFactors.keys(): msg = "No normalization factors available for bin '%s' when accessing histogram %s! Ignoring this bin..." % (wQCDLabel, shape.getHistoName()) self.Print(ShellStyles.WarningLabel() + msg, True) else: wQCD = normFactors[wQCDLabel] msg = "Weighting bin \"%i\" (label=\"%s\") with normFactor \"%s\"" % (i, wQCDLabel, wQCD) self.Verbose(ShellStyles.NoteLabel() + msg, True) # Construct info table (debugging) table = [] align = "{:>6} {:^10} {:^15} {:>10} {:>10} {:>10} {:^3} {:^12} {:^3} {:^12}" header = align.format("Bin", "Width", "Range", "Content", "NormFactor", "FakeB", "+/-", "Stat. Data", "+/-", "Stat. EWK") hLine = "="*100 table.append("{:^100}".format(shape.getHistoName())) table.append(hLine) table.append(header) table.append(hLine) binSum = 0.0 nBins = h.GetNbinsX() binWidth = hData.GetBinWidth(0) xMin = hData.GetXaxis().GetBinCenter(0) xMax = hData.GetXaxis().GetBinCenter(nBins+1) # For-Loop (nested): All bins in the shape histogram for j in range(1, nBins+1): # Initialise values myResult = 0.0 myStatDataUncert = 0.0 myStatEwkUncert = 0.0 # Ignore zero bins if abs(h.GetBinContent(j)) > 0.00001: # self.Verbose("Bin %i: Calculating the result" % (j) , j==0) binContent = h.GetBinContent(j) binRange = "%.1f -> %.1f" % (h.GetXaxis().GetBinLowEdge(j), h.GetXaxis().GetBinUpEdge(j) ) binWidth = GetTH1BinWidthString(h, j) binSum += binContent myResult = binContent * wQCD #apply normalisation factor (transfer from CR to SR) self.Verbose("Bin %i: BinContent = %.3f x %.3f = %.3f" % (j, binContent, wQCD, myResult), False) # self.Verbose("Calculate abs. stat. uncert. for data and for MC EWK (Do not calculate here MC EWK syst.)", True) myStatDataUncert = hData.GetBinError(j) * wQCD myStatEwkUncert = hEwk.GetBinError(j) * wQCD table.append(align.format(j, binWidth, binRange, "%0.1f" % binContent, wQCD, "%.1f" % myResult, "+/-", "%.1f" % myStatDataUncert, "+/-", "%.1f" % myStatEwkUncert)) # Get count object myCountObject = extendedCount.ExtendedCount(myResult, [myStatDataUncert, myStatEwkUncert], myUncertaintyLabels) self._resultCountObject.add(myCountObject) if optionDoNQCDByBinHistograms: self.Verbose("Setting bin content \"%i\"" % (j), True) self._histogramsList[i].SetBinContent(j, myCountObject.value()) self._histogramsList[i].SetBinError(j, myCountObject.statUncertainty()) binContent = self._resultShape.GetBinContent(j) + myCountObject.value() binError = self._resultShape.GetBinError(j) + myCountObject.statUncertainty()**2 self.Verbose("Setting bin %i to content %0.1f +/- %0.1f" % (j, binContent, binError), j==0) self._resultShape.SetBinContent(j, binContent) self._resultShape.SetBinError(j, binError) # Sum squared (take sqrt outside loop on final squared sum) self.Verbose("Sum items for purity calculation", True) myShapeDataSum[j-1] += hData.GetBinContent(j)*wQCD myShapeDataSumUncert[j-1] += (hData.GetBinError(j)*wQCD)**2 myShapeEwkSum[j-1] += hEwk.GetBinContent(j)*wQCD myShapeEwkSumUncert[j-1] += (hEwk.GetBinError(j)*wQCD)**2 # Delete the shape histograms h.Delete() hData.Delete() hEwk.Delete() # For-loop: All histogram bins for j in range(1,self._resultShape.GetNbinsX()+1): # Take square root of uncertainties self._resultShape.SetBinError(j, math.sqrt(self._resultShape.GetBinError(j))) # Print detailed results in a formatted table qcdResults = self._resultCountObject.getResultAndStatErrorsDict() bins = "%0.f-%.0f" % (1, nBins) binRange = "%.1f -> %.1f" % (xMin, xMax) binSum = "%.1f" % binSum nQCD = "%.1f" % qcdResults["value"] dataStat = "%.1f" % qcdResults["statData"] ewkStat = "%.1f" % qcdResults["statEWK"] table.append(align.format(bins, binWidth, binRange, binSum, wQCD, nQCD, "+/-", dataStat, "+/-", ewkStat)) table.append(hLine) # For-loop: All lines in table for i, line in enumerate(table): if i == len(table)-2: self.Verbose(ShellStyles.TestPassedStyle()+line+ShellStyles.NormalStyle(), i==1) else: self.Verbose(line, i==0) # Calculate the Purity histograms self.CalculatePurity(nBins, shape, myShapeDataSum, myShapeDataSumUncert, myShapeEwkSum, myShapeEwkSumUncert, verbose=optionPrintPurityByBins) return