def GetBinText(bin): #if bin == "Inclusive": # return "combined" #else: # return "bin-" + str(bin) if bin == "0": return "p_{T} < 80 GeV/c, |#eta| < 0.8" elif bin == "1": return "p_{T} = 80-200 GeV/c, |#eta| < 0.8" elif bin == "2": return "p_{T} > 200 GeV/c, |#eta| < 0.8" elif bin == "3": return "p_{T} < 80 GeV/c, |#eta| = 0.8-1.6" elif bin == "4": return "p_{T} = 80-200 GeV/c, |#eta| = 0.8-1.6" elif bin == "5": return "p_{T} > 200 GeV/c, |#eta| = 0.8-1.6" elif bin == "6": return "p_{T} < 80 GeV/c, |#eta| > 1.6" elif bin == "7": return "p_{T} = 80-200 GeV/c, |#eta| > 1.6" elif bin == "8": return "p_{T} > 200 GeV/c, |#eta| > 1.6" elif bin == "Inclusive": return "combined" else: raise Exception(ShellStyles.ErrorStyle() + "Unexpected bin %s" % (bin) + ShellStyles.NormalStyle())
def getNormFactorFileList(dirName, fileBaseName): scriptList = [] # For-loop: All items (files/dir) in directory for item in os.listdir(dirName): fullPath = os.path.join(dirName, item) # Skip directories if os.path.isdir(fullPath): continue # Find files matching the script "Base" name (without moduleInfoStrings) if item.startswith((fileBaseName).replace("%s.py", "")): if item.endswith(".py"): scriptList.append(item) if len(scriptList) < 1: msg = "ERROR! Found no normalization info files under dir %s. Did you generate them?" % dirName raise Exception(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle()) else: msg = "Found %s norm-factor file(s):\n\t%s" % ( len(scriptList), "\n\t".join( os.path.join([os.path.join(dirName, s) for s in scriptList]))) Verbose(ShellStyles.NoteLabel() + msg, True) return scriptList
def getDataDrivenQCDHistoForSplittedBin(self, binIndex): ''' Return the sum of data-ewk in a given phase space split bin at bin-index 0 you have the inclusive histogram! ''' if binIndex >= len(self._dataList): # FIXME: New addition to fix "optionUseInclusiveNorm" functionality (24-Mar-2018). Should not affect binned result! if self._optionUseInclusiveNorm: #new h = aux.Clone(self._dataList[0]) #new newName = h.GetName() + "_DataDriven" #new h.SetName(newName) #new return h #new msg = "Requested bin index %d out of range (0-%d)!" % ( binIndex, len(self._dataList)) raise Exception(ShellStyles.ErrorStyle() + msg, ShellStyles.NormalStyle()) # Clone the Data histos h = aux.Clone(self._dataList[binIndex]) newName = h.GetName() + "_DataDriven" h.SetName(newName) self.Verbose( "Cloned histo %s from histo %s" % (h.GetName(), self._dataList[0].GetName()), True) # Subtract the EWK histos self.Verbose( "Subtracting histo %s from histo %s (bin=%i)" % (self._ewkList[binIndex].GetName(), h.GetName(), binIndex), False) h.Add(self._ewkList[binIndex], -1.0) return h
def IsTH1(h, raiseExcept=False): if not isinstance(h, ROOT.TH1): msg = "Expected object of type ROOT.TH1, got \"%s\" instead" % (type(h)) if raiseExcept: raise Exception(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle()) return False else: return True
def _getAnalysisType(self, analysis): myAnalyses = ["HToTauNu", "HToTB"] if analysis not in myAnalyses: msg = "Unsupported analysis \"%s\". Please select one of the following: %s" % (analysis, ", ".join(myAnalyses)) raise Exception(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle() ) else: self.Print("Analysis type set to %s" % (sh_Note + analysis + sh_Normal), True) return analysis
def writeModuleToRootFile(self, rootfile): # Create module directory rootfile.cd("/") myModuleDir = rootfile.mkdir(self._moduleName) # Save shape information for h in self._shapes: h.SetDirectory(myModuleDir) # Save data-driven control plots myDDPlotsDirName = "ForDataDrivenCtrlPlots" myDDPlotsDir = myModuleDir.mkdir(myDDPlotsDirName) for h in self._dataDrivenControlPlots: h.SetDirectory(myDDPlotsDir) # Save counter histogram myCounterDir = myModuleDir.mkdir("counters") myWeightedCounterDir = myCounterDir.mkdir("weighted") self._hCounters = ROOT.TH1F("counter", "counter", len(self._counters), 0, len(self._counters)) i = 1 for key in self._counters.keys(): self._hCounters.GetXaxis().SetBinLabel(i, key) i += 1 self._hCounters.SetBinContent(i, self._counters[key]) self._hCounters.SetBinError(i, self._counterUncertainties[key]) self._hCounters.SetDirectory(myWeightedCounterDir) # Save splittedBinInfo hType = str(type(self._hSplittedBinInfo)).lower() if "none" not in hType: self._hSplittedBinInfo.SetDirectory(myModuleDir) else: msg = "WARNING! Unexpected problem with splitted bin info histogram. Type is %s" % ( hType) self.Print( ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(), True) # Save parameter set, code version and data version #myModuleDir.Add(self._psetInfo) # Create config info for the module myConfigInfoDir = myModuleDir.mkdir("configInfo") self._hConfigInfo = ROOT.TH1F( "configinfo", "configinfo", 2, 0, 2 ) # Have to store the histogram to keep it alive for writing self._hConfigInfo.GetXaxis().SetBinLabel(1,"control") self._hConfigInfo.GetXaxis().SetBinLabel(1, "control") self._hConfigInfo.SetBinContent(1, 1) #self._hConfigInfo.GetXaxis().SetBinLabel(2,"energy") #self._hConfigInfo.SetBinContent(2, self._energy) self._hConfigInfo.GetXaxis().SetBinLabel(2, "luminosity") self._hConfigInfo.SetBinContent(2, self._luminosity) self._hConfigInfo.SetDirectory(myConfigInfoDir) myConfigInfoDir.Add(self._dataVersion) #myConfigInfoDir.Add(self._codeVersion) #.SetDirectory(rootfile) #self._codeVersion.SetDirectory(rootfile) return
def _getAnalysisType(self, analysis): myAnalyses = ["HToTauNu", "HToTB", "HToHW", "HToHW_background"] if analysis not in myAnalyses: msg = "Unsupported analysis \"%s\". Please select one of the following: %s" % ( analysis, ", ".join(myAnalyses)) raise Exception(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle()) else: return analysis
def __init__(self, dataPath, ewkPath, dsetMgr, luminosity, moduleInfoString, normFactors, optionDoFakeBNormalisationSyst=True, normDataSrc=None, normEWKSrc=None, optionUseInclusiveNorm=False, keyList=[], verbose=False): self._verbose = verbose self._shapePlots = [] self._shapePlotLabels = [] self._QCDNormalizationSystPlots = [] self._QCDNormalizationSystPlotLabels = [] self._moduleInfoString = moduleInfoString self._useInclusiveNorm = optionUseInclusiveNorm if len(normFactors.keys()) == 1 and normFactors.keys()[0] == "Inclusive": self._useInclusiveNorm = True self._histoPathsData= self._GetHistoPaths(dsetMgr, "Data", dataPath, keyList) if ewkPath == dataPath: self._histoPathsEWK = self._histoPathsData else: self._histoPathsEWK = self._GetHistoPaths(dsetMgr, "EWK" , ewkPath , keyList) # Sanity check if len(self._histoPathsEWK) != len(self._histoPathsData): msg = "List of histograms for EWK does not match in size that of Data" raise Exception(ShellStyles.ErrorLabel() + msg + ShellStyles.NormalStyle()) # For-Loop: All plots to consider for i, plotName in enumerate(self._histoPathsData, 1): # Inform user of progress msg = "{:<9} {:>3} {:<1} {:<3} {:<80}".format("Histogram", "%i" % i, "/", "%s:" % (len(self._histoPathsData)), os.path.join(dataPath, plotName) ) self.PrintFlushed(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), False) if "JetEtaPhi_AfterAllSelections" in plotName: continue # Ensure that histograms exist && pass other sanity checks dataOk = self._sanityChecks(dsetMgr, dataPath, plotName) ewkOk = self._sanityChecks(dsetMgr, ewkPath , plotName) if dataOk*ewkOk == False: self.Print(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(), i==1) continue self.Verbose("Obtaining shape plots (the returned object is not owned)", True) myShapeHisto = self._obtainShapeHistograms(i, dataPath, ewkPath, dsetMgr, plotName, luminosity, normFactors) # Obtain plots for systematics coming from invariant mass shape difference if optionDoFakeBNormalisationSyst: if isinstance(myShapeHisto, ROOT.TH2): msg = "Skipping invariant mass shape uncertainty because histogram has more than 1 dimensions!" self.Print(ShellStyles.WarningLabel() + msg, True) else: self._obtainQCDNormalizationSystHistograms(myShapeHisto, dsetMgr, plotName, luminosity, normDataSrc, normEWKSrc) #iro: fixme (missing plots) msg = "Obtaining final shape from data path %s" % (ShellStyles.NoteStyle() + dataPath + ShellStyles.NormalStyle()) self.Verbose(msg, True) return
def getTransferFactorsSrcFilename(dirName, fileName): src = os.path.join(dirName, fileName) if not os.path.exists(src): msg = "Normalisation factors ('%s') not found!\nRun script \"./getABCD_TF.py\" to auto-generate the transfer factors (TFs) file." % src raise Exception(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle()) else: Print( "Importing transfer factors (TFs) from file %s" % (ShellStyles.NoteStyle() + os.path.basename(src) + ShellStyles.NormalStyle()), True) return src
def getListOfSystematics(self): if self._analysisType == "HToTauNu": return self.getSystematicsForHToTauNu() elif self._analysisType == "HToTB": return self.getSystematicsForHToTB() elif self._analysisType == "HToHW": return self.getSystematicsForHToHW() elif self._analysisType == "HToHW_background": return self.getSystematicsForHToHW_background() else: raise Exception(ShellStyles.ErrorStyle() + "This should never be reached" + ShellStyles.NormalStyle())
def getListOfSystematics(self): systList = None if self._analysisType == "HToTauNu": systList = self.getSystematicsForHToTauNu() elif self._analysisType == "HToTB": systList = self.getSystematicsForHToTB() else: raise Exception(ShellStyles.ErrorStyle() + "This should never be reached" + ShellStyles.NormalStyle() ) if len(systList) < 1: self.Print("Disabled systematics", False) else: self.Print("Enabled %d systematics (%s)" % (len(systList), sh_Note + ", ".join(systList) + sh_Normal), False) return systList
def ApplyBlinding(myObject, blindedRange = []): ''' myObject must be an instance of: h=histograms.Histo(rootHisto, "Label") and the rooHistos is an instance of: rootHisto = p.histoMgr.getHisto("HistoName").getRootHisto() ''' if len(blindedRange) != 2: msg = "Blinded range list requires exactly 2 values (got %s)" % len(blindedRange) raise Exception(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle()) # Definitions myMin = None myMax = None myHisto = myObject.getRootHisto() # For-loop: All histogram bins for i in range (1, myHisto.GetNbinsX()+1): myUpEdge = myHisto.GetXaxis().GetBinUpEdge(i) myLowEdge = myHisto.GetXaxis().GetBinLowEdge(i) # Define conditions c1 = (myLowEdge >= blindedRange[0] and myLowEdge <= blindedRange[1]) c2 = (myUpEdge >= blindedRange[0] and myUpEdge <= blindedRange[1]) c3 = (myLowEdge <= blindedRange[0] and myUpEdge >= blindedRange[1]) # Blind if any edge of the current bin is inside the blinded range or if bin spans over the blinded range if ( c1 or c2 or c3): if myMin == None or myLowEdge < myMin: myMin = myLowEdge if myMax == None or myUpEdge > myMax: myMax = myUpEdge # Blind data by setting bin content to -1.0 myHisto.SetBinContent(i, -1.0) myHisto.SetBinError(i, 0.0) if myMin == None: return None # Prepare blinding string for printing on canvas myMinFormat = "%" + "d" myMaxFormat = "%" + "d" if abs(myMin) < 1.0 and abs(myMin) > 0.00000001: myMinFormat = "%%.%df" % (abs(int(log10(myMin)))+1) if abs(myMax) < 1.0 and abs(myMax) > 0.00000001: myMaxFormat = "%%.%df" % (abs(int(log10(myMax)))+1) bString = myMinFormat%myMin+"-"+myMaxFormat%myMax return bString
def getBinningForTetrajetMass(binLevel=0, endValue=4000): ''' Currenty in Combine: myBins = [0,50,100,120,140,160,180,200,220,240,260,280,300,320,340,360,380,400,420,440,460,480,500,520,540,560,580,600,620,640,660,680,700,720,740, 760,780,800,820,840,860,880,900,920,940,960,980,1000,1020,1040,1060,1080,1100,1150,1200,1250,1300,1350,1400,1450,1500,1750,2000,2250,2500, 2750,3000,3250,3500,3750,4000] ''' myBins = [] if binLevel == -1: myBins = [0.0, 4000.0] elif binLevel == 0: #default binning for i in range(0, 1000, 50): myBins.append(i) for i in range(1000, 2000, 100): myBins.append(i) for i in range(2000, 3000, 500): myBins.append(i) for i in range(3000, endValue+1000, 1000): myBins.append(i) elif binLevel == 1: #finer binning for i in range(0, 1000, 25): myBins.append(i) for i in range(1000, 2000, 50): myBins.append(i) for i in range(2000, endValue+250, 250): myBins.append(i) elif binLevel == 2: for i in range(0, 1000, 20): myBins.append(i) for i in range(1000, 2000, 40): myBins.append(i) for i in range(2000, endValue+200, 200): myBins.append(i) elif binLevel == 3: for i in range(0, 1000, 10): myBins.append(i) for i in range(1000, 2000, 20): myBins.append(i) for i in range(2000, endValue+50, 50): myBins.append(i) else: raise Exception(ShellStyles.ErrorStyle() + "Please choose bin-level from -1 to 3" + ShellStyles.NormalStyle()) return myBins
def GetBinText(bin): return "bin-" + str(bin) #tmp if bin == "0": return "|#eta| < 0.4" elif bin == "1": return "0.4 < |#eta| < 0.8" elif bin == "2": return "0.8 < |#eta| < 1.6" elif bin == "3": return "1.6 < |#eta| < 1.8" elif bin == "4": return "1.8 < |#eta| < 2.0" elif bin == "5": return "2.0 < |#eta| < 2.2" elif bin == "6": return "|#eta| > 2.2" elif bin == "Inclusive": return bin else: raise Exception(ShellStyles.ErrorStyle() + "Unexpected bin %s" % (bin) + ShellStyles.NormalStyle())
def _generateDQMPlot(self): ''' Create a Data Quality Monitor (DQM) style plot to easily check the error for each transfer factor and whether it is within an acceptable relative error ''' # Define error warning/tolerance on relative errors okay = 1.0 / (len(self._BinLabelMap.keys())) warn = 0.5 * okay NEvts = [] # Check the uncertainties on the normalization factors for k in self._BinLabelMap: relErrorUp = abs(self._TF_Up[k]) / (self._TF[k]) relErrorDown = abs(self._TF_Down[k]) / (self._TF[k]) relError = self._TF_Error[k] / self._TF[k] if 0: print "bin = %s , relErrorUp = %s, relErrorDown = %s " % ( k, relErrorUp, relErrorDown) # Add DQM entries NCR1 = 0 NCR2 = 0 NCR3 = 0 NCR4 = 0 for j in self._NEvtsCR1: NCR1 += self._NEvtsCR1[j] NEvts.append(self._NEvtsCR1[j]) for j in self._NEvtsCR2: NCR2 += self._NEvtsCR2[j] NEvts.append(self._NEvtsCR2[j]) for j in self._NEvtsCR3: NCR3 += self._NEvtsCR3[j] NEvts.append(self._NEvtsCR3[j]) for j in self._NEvtsCR4: NCR4 += self._NEvtsCR4[j] NEvts.append(self._NEvtsCR4[j]) if 0: print "NCR1[%s] = %0.1f, NCR2[%s] = %0.1f, k = %s" % ( k, self._NEvtsCR1[k], k, self._NEvtsCR2[k], k) print "NCR1 = %s, NCR2 = %s, k = %s" % (NCR1, NCR2, k) print "error/NCR1[%s] = %0.2f, error/NCR2[%s] = %0.2f" % ( k, self._NEvtsCR1_Error[k] / self._NEvtsCR1[k], k, self._NEvtsCR2_Error[k] / self._NEvtsCR2[k]) # Add DQM plot entries self._addDqmEntry(self._BinLabelMap[k], "N_{CR1}", self._NEvtsCR1[k], NCR1 * okay, NCR1 * warn) self._addDqmEntry(self._BinLabelMap[k], "N_{CR2}", self._NEvtsCR2[k], NCR2 * okay, NCR2 * warn) self._addDqmEntry(self._BinLabelMap[k], "N_{CR3}", self._NEvtsCR3[k], NCR3 * okay, NCR3 * warn) self._addDqmEntry(self._BinLabelMap[k], "N_{CR4}", self._NEvtsCR4[k], NCR4 * okay, NCR4 * warn) # self._addDqmEntry(self._BinLabelMap[k], "#frac{#sigma_{CR1}}{N_{CR1}}", self._NEvtsCR1_Error[k]/NCR1, 0.05, 0.15) # self._addDqmEntry(self._BinLabelMap[k], "#frac{#sigma_{CR2}}{N_{CR2}}", self._NEvtsCR2_Error[k]/NCR2, 0.05, 0.15) # Construct the DQM histogram nBinsX = len(self._dqmKeys[self._dqmKeys.keys()[0]].keys()) nBinsY = len(self._dqmKeys.keys()) h = ROOT.TH2F("FakeB DQM", "FakeB DQM", nBinsX, 0, nBinsX, nBinsY, 0, nBinsY) # Customise axes h.GetXaxis().SetLabelSize(15) h.GetYaxis().SetLabelSize(10) # Set Min and Max of z-axis if 0: # red, yellow, green for DQM h.SetMinimum(0) h.SetMaximum(3) else: # pure entries instead of red, yellow, green h.SetMinimum(min(NEvts) * 0.25) h.SetMaximum(round(max(NCR1, NCR2, NCR3, NCR4))) h.SetContour(10) #h.SetContour(3) if 0: h.GetXaxis().LabelsOption("v") h.GetYaxis().LabelsOption("v") nWarnings = 0 nErrors = 0 # For-loop: All x-axis bins for i in range(h.GetNbinsX()): # For-loop: All y-axis bins for j in range(h.GetNbinsY()): ykey = self._dqmKeys.keys()[j] xkey = self._dqmKeys[ykey].keys()[i] # Set the bin content h.SetBinContent(i + 1, j + 1, self._dqmKeys[ykey][xkey]) h.GetXaxis().SetBinLabel(i + 1, xkey) h.GetYaxis().SetBinLabel(j + 1, ykey) if self._dqmKeys[ykey][xkey] > 2: nErrors += 1 elif self._dqmKeys[ykey][xkey] > 1: nWarnings += 1 # Apply TDR style style = tdrstyle.TDRStyle() style.setOptStat(False) style.setGridX(False) style.setGridY(False) style.setWide(True, 0.15) # Set the colour styling (red, yellow, green) if 0: palette = array.array("i", [ROOT.kGreen + 1, ROOT.kYellow, ROOT.kRed]) ROOT.gStyle.SetPalette(3, palette) else: # https://root.cern.ch/doc/master/classTColor.html ROOT.gStyle.SetPalette(ROOT.kLightTemperature) # ROOT.gStyle.SetPalette(ROOT.kColorPrintableOnGrey) #tdrstyle.setRainBowPalette() #tdrstyle.setDeepSeaPalette() # Create canvas c = ROOT.TCanvas() c.SetLogx(False) c.SetLogy(False) c.SetLogz(True) c.SetGridx() c.SetGridy() h.Draw("COLZ") #"COLZ TEXT" # Add CMS text and text with colour keys histograms.addStandardTexts(cmsTextPosition="outframe") if 0: histograms.addText(0.55, 0.80, "green < %.0f %%" % (okay * 100), size=20) histograms.addText(0.55, 0.84, "yellow < %.0f %%" % (warn * 100), size=20) histograms.addText(0.55, 0.88, "red > %.0f %%" % (warn * 100), size=20) # Save the canvas to a file backup = ROOT.gErrorIgnoreLevel ROOT.gErrorIgnoreLevel = ROOT.kWarning plotName = os.path.join(self._plotDirName, "FakeBNormalisationDQM") # For-loop: Save formats for ext in ["png", "C", "pdf"]: saveName = "%s.%s" % (plotName, ext) c.Print(saveName) ROOT.gErrorIgnoreLevel = backup ROOT.gStyle.SetPalette(1) msg = "Obtained %d warnings and %d errors for the normalisation" % ( nWarnings, nErrors) self.Verbose(msg) if nWarnings > 0: msg = "DQM has %d warnings and %d errors! Please have a look at %s.png." % ( nWarnings, nErrors, os.path.basename(plotName)) self.Verbose( ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(), True) #if nWarnings > 0 or nErrors > 0: if nErrors > 0: msg = "DQM has %d warnings and %d errors! Please have a look at %s.png." % ( nWarnings, nErrors, os.path.basename(plotName)) self.Verbose( ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(), True) return
import ROOT ROOT.gROOT.SetBatch(True) ROOT.PyConfig.IgnoreCommandLineOptions = True import HiggsAnalysis.NtupleAnalysis.tools.histograms as histograms import HiggsAnalysis.NtupleAnalysis.tools.tdrstyle as tdrstyle import HiggsAnalysis.NtupleAnalysis.tools.plots as plots import HiggsAnalysis.NtupleAnalysis.tools.styles as styles import HiggsAnalysis.Keras_ANN.results as _results import HiggsAnalysis.NtupleAnalysis.tools.ShellStyles as ShellStyles import HiggsAnalysis.NtupleAnalysis.tools.aux as aux #================================================================================================ # Shell Types #================================================================================================ sh_e = ShellStyles.ErrorStyle() sh_s = ShellStyles.SuccessStyle() sh_h = ShellStyles.HighlightStyle() sh_a = ShellStyles.HighlightAltStyle() sh_t = ShellStyles.NoteStyle() sh_n = ShellStyles.NormalStyle() sh_w = ShellStyles.WarningStyle() #================================================================================================ # Function definition #================================================================================================ def Verbose(msg, printHeader=False): ''' Calls Print() only if verbose options is set to true. '''
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) if 0: aux.PrintTH1Info(hhd.getRootHisto()) # 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) if 0: aux.PrintTH1Info(hhp.getRootHisto()) # 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 main(opts): # 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() # Apply TDR style style = tdrstyle.TDRStyle() style.setGridX(opts.gridX) style.setGridY(opts.gridY) style.setOptStat(False) # If user does not define optimisation mode do all of them if opts.optMode == None: optModes = optList else: optModes = [opts.optMode] # Define genuineB and fakeB datasets mergeMap = {"TT": "GenuineB", "QCD_HT50to100" : "FakeB", #v. poor stats! "QCD_HT200to300" : "FakeB", #v. poor stats! "QCD_HT100to200" : "FakeB", #v. poor stats! "QCD_HT200to300" : "FakeB", #v. poor stats! "QCD_HT300to500" : "FakeB", "QCD_HT500to700" : "FakeB", "QCD_HT700to1000" : "FakeB", "QCD_HT1000to1500": "FakeB", "QCD_HT1500to2000": "FakeB", "QCD_HT2000toInf" : "FakeB", "WJetsToQQ_HT_600ToInf": "FakeB" } # Definitions results = [] # For-loop: All optimisation modes for index, opt in enumerate(optModes, 1): opts.optMode = opt # Definitions genuineB = None fakeB = None # Setup & configure the dataset manager datasetsMgr = GetDatasetsFromDir(opts) datasetsMgr.updateNAllEventsToPUWeighted() datasetsMgr.loadLuminosities() # from lumi.json # Print datasets info ? if opts.verbose: datasetsMgr.PrintCrossSections() datasetsMgr.PrintLuminosities() # Remove unwanted datasets removeList = ["QCD_HT50to100", "QCD_HT100to200", "QCD_HT200to300", "QCD_HT200to300_ext1", "WJetsToQQ_HT_600ToInf"] for k, d in enumerate(datasetsMgr.getAllDatasets(), 1): if d.getName() in removeList: datasetsMgr.remove(d.getName()) Verbose(ShellStyles.ErrorStyle() + "Removing dataset %s" % d.getName() + ShellStyles.NormalStyle(), k==1) if index == 1: datasetsMgr.PrintInfo() # Merge datasets into two groups: Genuine-B and Fake-B datasetsMgr.mergeMany(mergeMap, addition=False) for d in datasetsMgr.getAllDatasets(): if d.getName() == "GenuineB": genuineB = d if d.getName() == "FakeB": fakeB = d # Merge histograms (see NtupleAnalysis/python/tools/plots.py) plots.mergeRenameReorderForDataMC(datasetsMgr) # Get integrated luminosity intLumi = datasetsMgr.getDataset("Data").getLuminosity() datasetsMgr.remove(filter(lambda name: "Data" in name, datasetsMgr.getAllDatasetNames())) # Print dataset information if index == 1: datasetsMgr.PrintInfo() # Do the plot name = GetPlotName(opts) myResults = doPlot(name, genuineB, fakeB, opts.errorlevel, opts.optMode, intLumi) # Save results and msgs results.extend(myResults) # For-loop: All points if opts.verbose: for item in results: print item # Print path of all saved plots msg = "All plots saved under directory %s" % (aux.convertToURL(opts.saveDir, opts.url)) Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), True) # Write results to a json file with open(opts.json, 'w') as outfile: json.dump(results, outfile) msg = "Wrote results to \"%s\"" % (opts.json) Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), True) return
def createSystHistograms(self, hRate, hSystUp, hSystDown, hSystUpFromVar, hSystDownFromVar, quietMode=True): ''' Uses the histogram "hSystUpFromVar" and "hSystDownFromVar" to account the systematic uncertainties related to the Transfer Factors (TF) from the Control (or Verification) Region (VR) to the Signal Region (SR). This sys. uncertainty should have both a Rate + Shape impact on final invariant mass distribution. The two aforementioned histograms correspond to the invariant massdistrubutions ("ForDataDrivenCtrlPlots/LdgTetrajetMass_AfterAllSelections") obtained by using applying the transfer factors (TF) of the FakeB measurement to shapes from the VR. Instead of the nominal TF however, the TF+TF_Error and TF-TF_Error are used instead, where TF_Error is the statistical error of the TF, calculated by using error propagation: TF = CR1/CR2 TF_Error = ErrorPropagationForDivision(TF) = sqrt((sigmaA/b)**2 + (a/(b**2)*sigmaB)**2) where: A = Integral of CR1 histogram (from ROOT) sigmaA = Integral Error for CR1 histogram (from ROOT) These histograms should be already in place (and correctly normalised) for the FakeB pseudodataset, after running the ./makePseudoMulticrab.py -m <FakeB-dir> script. The error is symmetric and it is basically defined as: hSystUp = Rate + 1sigma hSystDown = Rate - 1sigma where the rate is obtained from the filled histogram provided ("hRate") and sigma is the TF_Error as discussed above (error propagation on the division of CR1 and CR2) In this function we don't need to calculate the error propagation. The function assumes that the histograms provided already have the final variations in place (i.e. up = rate+error, down = rate-error) ''' # Get the (clean) histogram name fullName = hRate.GetName() cleanName = fullName.replace("_cloned", "") cleanName = cleanName.replace("_FakeBMeasurementTrijetMass", "") rebinX = systematics.getBinningForPlot(cleanName) # if hRate.GetNbinsX() != hSystUpFromVar.GetNbinsX(): if rebinX != None: self.Verbose( "Rebinning histogram \"%s\" (\"%s\")" % (cleanName, fullName), True) hRate = hRate.Rebin( len(rebinX) - 1, hRate.GetName(), array.array("d", rebinX)) hSystUpFromVar = hSystUpFromVar.Rebin( len(rebinX) - 1, hSystUpFromVar.GetName(), array.array("d", rebinX)) hSystDownFromVar = hSystDownFromVar.Rebin( len(rebinX) - 1, hSystDownFromVar.GetName(), array.array("d", rebinX)) ### hSystUp = hSystUp.Rebin(len(rebinX)-1, hSystUp.GetName(), array.array("d", rebinX)) #don't ! ### hSystDown = hSystDown.Rebin(len(rebinX)-1, hSystDown.GetName(), array.array("d", rebinX)) #don't ! # Constuct a summary table table = [] align = "{:>7} {:>15} {:>10} {:>12} {:>12} {:>12} {:>10}" header = align.format("Bin #", "Bin Centre", "Rate (Nom)", "Rate (Up)", "Rate (Down)", "% Up", "% Down") hLine = "=" * 85 table.append("{:^85}".format(cleanName)) table.append(hLine) table.append(header) table.append(hLine) # For-loop: All histogram bins for given data-driven control plot nBinsX = hRate.GetNbinsX() for i in range(1, nBinsX + 1): self.Verbose( "Calculating systematic for bin \"%d\" in histogram \"%s\"" % (i, hRate.GetName()), i == 1) # Calculate the systematics rateNominal = hRate.GetBinContent(i) rateSystUp = hSystUpFromVar.GetBinContent(i) rateSystDown = hSystDownFromVar.GetBinContent(i) binCentre = hRate.GetBinCenter(i) # Calculate percentage difference wrt nominal if rateNominal > 0.0: rateSystUpPerc = (rateSystUp - rateNominal) / (rateNominal) * 100 rateSystDownPerc = (rateSystDown - rateNominal) / (rateNominal) * 100 else: rateSystUpPerc = 0 rateSystDownPerc = 0 # Fill summary table for given bin row = align.format(i, binCentre, "%.1f" % rateNominal, "%.1f" % rateSystUp, "%.1f" % rateSystDown, "%.1f" % rateSystUpPerc, "%.1f" % rateSystDownPerc) table.append(row) self.Verbose( ShellStyles.ErrorStyle() + row + ShellStyles.NormalStyle(), i == 1) # Fill the up/down systematics histograms self.Verbose( "Setting the systematics values in the histograms SystUp and SystDown", False) hSystUp.SetBinContent(i, rateSystUp) hSystDown.SetBinContent(i, rateSystDown) # Append total uncertainty info table.extend( self.GetTotalUncertainyTable(hRate, hSystUpFromVar, hSystDownFromVar, hLine, align)) # Print summary table if quietMode == False or self._verbose == True: for i, row in enumerate(table, 1): self.Print(row, i == 1) 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)) # Inspect histogram contents? if opts.verbose: aux.PrintTH1Info(self.h_data) # 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)) if opts.verbose: aux.PrintTH1Info(histo) # Customise histogram template.SetFillColor(self.colors[hname]) template.SetLineWidth(0) self.histograms[hname] = template return
def main(opts): optModes = [""] if opts.optMode != None: optModes = [opts.optMode] # 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) style.setLogZ(opts.logZ) style.setWide(True, 0.15) # style.setPadRightMargin()#0.13) # 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() datasetsMgr.PrintInfo() # Merge histograms (see NtupleAnalysis/python/tools/plots.py) plots.mergeRenameReorderForDataMC(datasetsMgr) # Print merged datasets and MC samples if 0: datasetsMgr.PrintInfo() # Get Luminosity if opts.intLumi < 0: opts.intLumi = datasetsMgr.getDataset("Data").getLuminosity() # Merge EWK samples if opts.dataset == "EWK": datasetsMgr.merge("EWK", aux.GetListOfEwkDatasets()) plots._plotStyles["EWK"] = styles.getAltEWKStyle() # Re-order datasets (different for inverted than default=baseline) newOrder = [] for d in datasetsMgr.getAllDatasets(): if d.getName() == opts.dataset: newOrder.append(d.getName()) # Sanity check on selected dataset nDatasets = len(newOrder) if nDatasets < 1: msg = "Please select a valid dataset. Dataset \"%s\" does not exist!" % ( opts.dataset) Print(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(), True) datasetsMgr.PrintInfo() sys.exit() if nDatasets > 1: msg = "Please select only 1 valid dataset. Requested %i datasets for plotting!" % ( nDatasets) Print(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(), True) datasetsMgr.PrintInfo() sys.exit() # Select only given dataset datasetsMgr.selectAndReorder(newOrder) # Print dataset information msg = "Plotting for single dataset \"%s\". Integrated luminosity is %.2f 1/fb" % ( opts.dataset, opts.intLumi) Print(ShellStyles.NoteStyle() + msg + ShellStyles.NormalStyle(), True) datasetsMgr.PrintInfo() # Get list of histogram paths folder = opts.folder histoList = datasetsMgr.getDataset( datasetsMgr.getAllDatasetNames()[0]).getDirectoryContent(folder) histoPaths = [os.path.join(folder, h) for h in histoList] # For-loop: All histograms for h in histoPaths: if "_vs_" not in h.lower(): continue Plot2dHistograms(datasetsMgr, h) Print( "All plots saved under directory %s" % (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) + ShellStyles.NormalStyle()), True) 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 main(opts): # Suppress warnings about weight being re-applied ROOT.gErrorIgnoreLevel = ROOT.kError # 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] opts.optMode = "" mcrabName = opts.mcrab RunEra = mcrabName.split("_")[1] # Setup ROOT and style ROOT.gROOT.SetBatch(opts.batchMode) style = tdrstyle.TDRStyle() style.setOptStat(True) style.setGridX(True) style.setGridY(True) # Setup & configure the dataset manager datasetsMgr = GetDatasetsFromDir(opts) # Remove some QCD samples (the cross sections of these samples are not calculated) if 0: msg = "Removing following samples:" Print(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(), True) for d in getDatasetsToExclude(): Print(d, False) datasetsMgr.remove(d) # Get run-range minRunRange, maxRunRange, runRange = GetRunRange(datasetsMgr) # Get int lumi intLumi = GetLumi(datasetsMgr) # Update to PU & load luminosities datasetsMgr.updateNAllEventsToPUWeighted() datasetsMgr.loadLuminosities() #datasetsMgr.normalizeMCByLuminosity() # Print luminisoties and cross-sections datasetsMgr.PrintLuminosities() datasetsMgr.PrintCrossSections() # Default merging & ordering: "Data", "QCD", "SingleTop", "Diboson" plots.mergeRenameReorderForDataMC(datasetsMgr) # Get datasets datasetsMgr.mergeMC() dataset_Data = datasetsMgr.getDataDatasets() dataset_MC = datasetsMgr.getMCDatasets() # Define lists of Triggers to be plotted and Variables xVars = ["pt6thJet", "eta6thJet", "phi6thJet", "Ht", "nBTagJets", "pu", "JetMulti", "BJetMulti"] trgList = ["1BTag", "2BTag", "OR", "OR_PFJet450"] if opts.fast: trgList = ["OR_PFJet450"] xVars = ["pt6thJet", "Ht"] nPlots = len(trgList)*len(xVars) counter = 0 # For-loop: All signal triggers for i, trg in enumerate(trgList, 1): # For-loop: All x-variables for j, xVar in enumerate(xVars, 1): counter+=1 msg = "{:<9} {:>3} {:<1} {:<3} {:<50}".format("Histogram", "%i" % counter, "/", "%s:" % (nPlots), "%s Vs %s" % (trg, xVar)) Print(ShellStyles.SuccessStyle() + msg + ShellStyles.NormalStyle(), counter==1) # Define names hNumerator = "hNum_%s_RefTrg_OfflineSel_Signal%s" % (xVar, trg) hDenominator = "hDen_%s_RefTrg_OfflineSel" % (xVar) plotName = "Eff_%s_%s" % (xVar, trg) # Get Efficiency Plots _kwargs = GetHistoKwargs(xVar, opts) eff_Data = GetEfficiency(datasetsMgr, dataset_Data, hNumerator, hDenominator , **_kwargs) eff_MC = GetEfficiency(datasetsMgr, dataset_MC, hNumerator, hDenominator, **_kwargs) # Apply Styles styles.dataStyle.apply(eff_Data) styles.mcStyle.apply(eff_MC) # Create the plot p = plots.ComparisonPlot(histograms.HistoGraph(eff_Data, "eff_Data", "p", "P"), histograms.HistoGraph(eff_MC, "eff_MC" , "p", "P"), saveFormats=[]) # Define the legend entries p.histoMgr.setHistoLegendLabelMany( { "eff_Data": "Data", "eff_MC" : "Simulation" } ) # Draw and save the plot p.setLuminosity(intLumi) plots.drawPlot(p, plotName, **_kwargs) # Draw histograms.addText(0.65, 0.06, "Runs "+ runRange, 17) histograms.addText(0.65, 0.10, "2016", 17) # Save the canvas to a file SavePlot(p, plotName, os.path.join(opts.saveDir, opts.optMode), saveFormats=[".pdf", ".png", ".C"] ) Print("All plots saved under directory %s" % (ShellStyles.NoteStyle() + aux.convertToURL(opts.saveDir, opts.url) + ShellStyles.NormalStyle()), True) return
ROOT.gROOT.SetBatch(True) ROOT.PyConfig.IgnoreCommandLineOptions = True import datasets as datasetsTest import HiggsAnalysis.NtupleAnalysis.tools.dataset as dataset import HiggsAnalysis.NtupleAnalysis.tools.aux as aux import HiggsAnalysis.NtupleAnalysis.tools.git as git import HiggsAnalysis.NtupleAnalysis.tools.ShellStyles as ShellStyles #================================================================================================ # Global Definitions #================================================================================================ _debugMode = False _debugPUreweighting = False _debugMemoryConsumption = False sh_Error = ShellStyles.ErrorStyle() sh_Success = ShellStyles.SuccessStyle() sh_Note = ShellStyles.HighlightAltStyle() sh_Normal = ShellStyles.NormalStyle() #================================================================================================ # Function Definition #================================================================================================ def Verbose(msg, printHeader=False): ''' Calls Print() only if verbose options is set to true. ''' if not _debugMode: return Print(msg, printHeader)
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
from subprocess import Popen, PIPE import os import sys import datetime from optparse import OptionParser import HiggsAnalysis.NtupleAnalysis.tools.ShellStyles as ShellStyles #================================================================================================ # Variable definition #================================================================================================ ss = ShellStyles.SuccessStyle() ns = ShellStyles.NormalStyle() ts = ShellStyles.NoteStyle() hs = ShellStyles.HighlightAltStyle() es = ShellStyles.ErrorStyle() #================================================================================================ # Function Definitions #================================================================================================ def Verbose(msg, printHeader=False): if not VERBOSE: return if printHeader: print "=== submitCondor.py:" if msg != "": print "\t", msg return
def main(): # Save start time (epoch seconds) tStart = time.time() Verbose("Started @ " + str(tStart), True) # Require at least two arguments (script-name, path to multicrab) if len(sys.argv) < 2: Print( "Not enough arguments passed to script execution. Printing docstring & EXIT." ) print __doc__ sys.exit(0) else: pass # ================================================================================================ # Setup the process # ================================================================================================ maxEvents = {} maxEvents["All"] = opts.nEvts # maxEvents["2016"] = 1 # maxEvents["ZZTo4Q"] = -1 # maxEvents["ZJetsToQQ_HT600toInf"] = 1 # maxEvents["WZ_ext1"] = 1 # maxEvents["WZ"] = 1 # maxEvents["WWTo4Q"] = 1 # maxEvents["WJetsToQQ_HT_600ToInf"] = 1 # maxEvents["TTZToQQ"] = 1 # maxEvents["TTWJetsToQQ"] = 1 # maxEvents["TTTT"] = 1 # maxEvents["TT"] = 1 # maxEvents["ST_t_channel_top_4f_inclusiveDecays"] = 1 # maxEvents["ST_t_channel_antitop_4f_inclusiveDecays"] = 1 # maxEvents["ST_tW_top_5f_inclusiveDecays_ext1"] = 1 # maxEvents["ST_tW_top_5f_inclusiveDecays"] = 1 # maxEvents["ST_tW_antitop_5f_inclusiveDecays_ext1"] = 1 # maxEvents["ST_tW_antitop_5f_inclusiveDecays"] = 1 # maxEvents["ST_s_channel_4f_InclusiveDecays"] = 1 # maxEvents["QCD_HT700to1000_ext1"] = 1 # maxEvents["QCD_HT700to1000"] = 1 # maxEvents["QCD_HT50to100"] = 1 # maxEvents["QCD_HT500to700_ext1"] = 1 # maxEvents["QCD_HT500to700"] = 1 # maxEvents["QCD_HT300to500_ext1"] = 1 # maxEvents["QCD_HT300to500"] = 1 # maxEvents["QCD_HT200to300_ext1"] = 1 # maxEvents["QCD_HT200to300"] = 1 # maxEvents["QCD_HT2000toInf_ext1"] = 1 # maxEvents["QCD_HT2000toInf"] = 1 # maxEvents["QCD_HT1500to2000_ext1"] = 1 # maxEvents["QCD_HT1500to2000"] = 1 # maxEvents["QCD_HT100to200"] = 1 # maxEvents["QCD_HT1000to1500_ext1"] = 1 # maxEvents["QCD_HT1000to1500"] = 1 # maxEvents["JetHT_Run2016H_03Feb2017_ver3_v1_284036_284044"] = 1 # maxEvents["JetHT_Run2016H_03Feb2017_ver2_v1_281613_284035"] = 1 # maxEvents["JetHT_Run2016G_03Feb2017_v1_278820_280385"] = 1 # maxEvents["JetHT_Run2016F_03Feb2017_v1_278801_278808"] = 1 # maxEvents["JetHT_Run2016F_03Feb2017_v1_277932_278800"] = 1 # maxEvents["JetHT_Run2016E_03Feb2017_v1_276831_277420"] = 1 # maxEvents["JetHT_Run2016D_03Feb2017_v1_276315_276811"] = 1 # maxEvents["JetHT_Run2016C_03Feb2017_v1_275656_276283"] = 1 # maxEvents["JetHT_Run2016B_03Feb2017_ver2_v2_273150_275376"] = 1 # maxEvents["DYJetsToQQ_HT180"] = 1 # maxEvents["ChargedHiggs_HplusTB_HplusToTB_M_500"] = 1 process = Process(prefix, postfix, maxEvents) # ================================================================================================ # Add the datasets (according to user options) # ================================================================================================ if (opts.includeOnlyTasks): Verbose("Adding only dataset %s from multiCRAB directory %s" % (opts.includeOnlyTasks, opts.mcrab)) process.addDatasetsFromMulticrab( opts.mcrab, includeOnlyTasks=opts.includeOnlyTasks) elif (opts.excludeTasks): Verbose("Adding all datasets except %s from multiCRAB directory %s" % (opts.excludeTasks, opts.mcrab)) Print( "If collision data are present, then vertex reweighting is done according to the chosen data era (era=2015C, 2015D, 2015) etc..." ) process.addDatasetsFromMulticrab(opts.mcrab, excludeTasks=opts.excludeTasks) else: myBlackList = [ "M_180", "M_200", "M_220", "M_250", "M_300", "M_350", "M_400", "M_500", "M_650", "M_800", "M_1000", "M_1500", "M_2000", "M_2500", "M_3000", "M_5000", "M_7000", "M_10000", "QCD_b" ] Verbose("Adding all datasets from multiCRAB directory %s except %s" % (opts.mcrab, (",".join(myBlackList)))) Verbose( "Vertex reweighting is done according to the chosen data era (%s)" % (",".join(dataEras))) # process.addDatasetsFromMulticrab(opts.mcrab, blacklist=myBlackList) if len(myBlackList) > 0: regex = "|".join(myBlackList) process.addDatasetsFromMulticrab(opts.mcrab, excludeTasks=regex) else: process.addDatasetsFromMulticrab(opts.mcrab) # ================================================================================================ # Overwrite Default Settings # ================================================================================================ from HiggsAnalysis.NtupleAnalysis.parameters.hplus2tbAnalysis import allSelections allSelections.verbose = opts.verbose allSelections.histogramAmbientLevel = opts.histoLevel # Set splitting of phase-space (first bin is below first edge value and last bin is above last edge value) allSelections.CommonPlots.histogramSplitting = [ PSet(label="TetrajetBjetPt", binLowEdges=[60, 90, 160, 300], useAbsoluteValues=False), # Final PSet(label="TetrajetBjetEta", binLowEdges=[0.8, 1.4, 2.0], useAbsoluteValues=True), # Final # # PSet(label="TetrajsetBjetPt", binLowEdges=[60, 100, 150], useAbsoluteValues=False), # PSet(label="TetrajsetBjetPt", binLowEdges=[60, 150], useAbsoluteValues=False), # PSet(label="TetrajsetBjetPt", binLowEdges=[55, 110], useAbsoluteValues=False), # PSet(label="TetrajetBjetEta", binLowEdges=[0.8, 1.6], useAbsoluteValues=True), # PSet(label="TetrajetBjetEta", binLowEdges=[0.4, 0.8, 1.6, 2.0, 2.2], useAbsoluteValues=True), #AN v4 ] # Overwrite values # allSelections.TopSelectionBDT.CSV_bDiscCutDirection = ">=" allSelections.TopSelectionBDT.CSV_bDiscCutValue = 0.54 # allow CSVv2-L for inverted top # Testing if 0: msg = "WARNING! This is a simple testing of the FakeB measurement with only 1 CSVv2-M. Disable once done!" Print(ShellStyles.ErrorStyle() + msg + ShellStyles.NormalStyle(), True) allSelections.FakeBMeasurement.baselineBJetsCutValue = 0 #1 allSelections.FakeBMeasurement.baselineBJetsCutDirection = "==" # ================================================================================================ # Command Line Options # ================================================================================================ # from HiggsAnalysis.NtupleAnalysis.parameters.signalAnalysisParameters import applyAnalysisCommandLineOptions # applyAnalysisCommandLineOptions(sys.argv, allSelections) # ================================================================================================ # Build analysis modules # ================================================================================================ PrintOptions(opts) builder = AnalysisBuilder(prefix, dataEras, searchModes, usePUreweighting=opts.usePUreweighting, useTopPtReweighting=opts.useTopPtReweighting, doSystematicVariations=opts.doSystematics, analysisType="HToTB", verbose=opts.verbose) # Add variations (e.g. for optimisation) # builder.addVariation("BJetSelection.triggerMatchingApply", [True, False]) # At least 1 trg b-jet dR-matched to offline b-jets # builder.addVariation("FakeBMeasurement.prelimTopFitChiSqrCutValue", [100, 20]) # builder.addVariation("FakeBMeasurement.prelimTopFitChiSqrCutDirection", ["<=", "==", ">="]) # builder.addVariation("FakeBMeasurement.numberOfBJetsCutValue", [0, 1]) # builder.addVariation("FakeBMeasurement.numberOfBJetsCutDirection", ["=="]) # builder.addVariation("FakeBMeasurement.numberOfBJetsCutDirection", ["<=", "==", ">="]) # builder.addVariation("FakeBMeasurement.numberOfInvertedBJetsCutValue", [0, 1]) # builder.addVariation("FakeBMeasurement.numberOfInvertedBJetsCutDirection", [">="]) # builder.addVariation("FakeBMeasurement.invertedBJetDiscr", "") # builder.addVariation("FakeBMeasurement.invertedBJetDiscrWorkingPoint", "Loose") # builder.addVariation("FakeBMeasurement.invertedBJetsSortType", ["Random", "DescendingBDiscriminator"]) # builder.addVariation("FakeBMeasurement.invertedBJetsDiscrMaxCutValue", [0.82, 0.80, 0.75, 0.70]) # builder.addVariation("TopSelection.ChiSqrCutValue", [100]) # builder.addVariation("Trigger.triggerOR", [["HLT_PFHT450_SixJet40"], ["HLT_PFHT400_SixJet30"]]) # builder.addVariation("TopologySelection.FoxWolframMomentCutValue", [0.5, 0.7]) # builder.addVariation("Trigger.triggerOR", [["HLT_PFHT400_SixJet30_DoubleBTagCSV_p056"], ["HLT_PFHT450_SixJet40_BTagCSV_p056"]]) # builder.addVariation("Trigger.triggerOR", [["HLT_PFHT400_SixJet30_DoubleBTagCSV_p056", "HLT_PFHT450_SixJet40_BTagCSV_p056"]]) # Build the builder builder.build(process, allSelections) # ================================================================================================ # Example of adding an analyzer whose configuration depends on dataVersion # ================================================================================================ # def createAnalyzer(dataVersion): # a = Analyzer("ExampleAnalysis") # if dataVersion.isMC(): # a.tauPtCut = 10 # else: # a.tauPtCut = 20 # return a # process.addAnalyzer("test2", createAnalyzer) # ================================================================================================ # Pick events # ================================================================================================ # process.addOptions(EventSaver = PSet(enabled = True,pickEvents = True)) # ================================================================================================ # Run the analysis # ================================================================================================ # Run the analysis with PROOF? You can give proofWorkers=<N> as a parameter if opts.jCores: Print("Running process with PROOF (proofWorkes=%s)" % (str(opts.jCores))) process.run(proof=True, proofWorkers=opts.jCores) else: Print("Running process (no PROOF)") process.run() # Print total time elapsed tFinish = time.time() dt = int(tFinish) - int(tStart) days = divmod(dt, 86400) # days hours = divmod(days[1], 3600) # hours mins = divmod(hours[1], 60) # minutes secs = mins[1] # seconds Print( "Total elapsed time is %s days, %s hours, %s mins, %s secs" % (days[0], hours[0], mins[0], secs), True) return