def plot_metrics(history, plot_directory): # Make sure the plot dir exists and copy index.php if not os.path.exists(plot_directory): os.makedirs(plot_directory) plot_helpers.copyIndexPHP(plot_directory) # Get all keys (only store strings without 'val_') keys = [] for key in history.history.keys(): if "val_" in key: continue else: keys.append(key) # Loop over keys for key in keys: # security check if 'val_' + key not in history.history.keys(): print '[ERROR] val_' + key + ' not in history.keys(). The ' + key + ' metric will not be plotted.' continue # Get the numbers data_train = history.history[key] data_val = history.history['val_' + key] N_epochs_train = len(data_train) N_epochs_val = len(data_val) # create graphs for train and validation sets graph_train = ROOT.TGraph(N_epochs_train) graph_val = ROOT.TGraph(N_epochs_val) for i in range(N_epochs_train): graph_train.SetPoint(i + 1, i + 1, data_train[i]) for i in range(N_epochs_val): graph_val.SetPoint(i + 1, i + 1, data_val[i]) # Plot c = ROOT.TCanvas(key, key, 600, 600) graph_train.SetLineWidth(3) graph_train.SetLineColor(ROOT.kRed - 3) graph_val.SetLineWidth(3) graph_val.SetLineColor(ROOT.kAzure - 7) graph_train.Draw( "AC") # has to be here for TGraph to have an axis object # Set Labels, range and draw again graph_train.GetXaxis().SetTitle("Epoch") graph_train.GetYaxis().SetTitle(key) maximum = max(data_train) if max(data_train) > max(data_val) else max( data_val) graph_train.GetYaxis().SetRangeUser(0., 1.8 * maximum) graph_train.Draw("AC") c.Update() graph_val.Draw("SAME C") # Legend leg = ROOT.TLegend(0.6, 0.65, 0.85, 0.9) leg.AddEntry(graph_train, "Training", "l") leg.AddEntry(graph_val, "Validation", "l") leg.SetBorderSize(0) leg.Draw() # Save plot c.Print(plot_directory + "/" + key + ".png")
def draw2D(plot, \ zRange = None, extensions = ["pdf", "png", "root"], plot_directory = ".", logX = False, logY = False, logZ = True, drawObjects = [], widths = {}, canvasModifications = [], histModifications = [], copyIndexPHP = False, ): ''' plot: a Plot2D instance zRange: None ( = ROOT default) or [low, high] extensions: ["pdf", "png", "root"] (default) logX: True/False (default), logY: True/False(default), logZ: True/False(default) drawObjects = [] Additional ROOT objects that are called by .Draw() widths = {} (default) to update the widths. Values are {'y_width':500, 'x_width':500, 'y_ratio_width':200} canvasModifications = [] could be used to pass on lambdas to modify the canvas. histModifications similar for histos. copyIndexPHP: whether or not to copy index.php to the plot directory ''' # FIXME -> Introduces CMSSW dependence ROOT.gROOT.LoadMacro("$CMSSW_BASE/src/RootTools/plot/scripts/tdrstyle.C") ROOT.setTDRStyle() # default_widths default_widths = {'y_width': 500, 'x_width': 500, 'y_ratio_width': 200} # Updating with width arguments default_widths.update(widths) # Adding up all components histos = plot.histos_added histo = histos[0][0].Clone() if len(histos) > 1: logger.warning("Adding %i histos for 2D plot %s", len(histos), plot.name) for h in histos[1:]: histo.Add(h[0]) ## Clone (including any attributes) and add up histos in stack #if hasattr(histo, "style"): # histo.style(histo) c1 = ROOT.TCanvas("ROOT.c1", "drawHistos", 200, 10, default_widths['x_width'], default_widths['y_width']) c1.SetBottomMargin(0.13) c1.SetLeftMargin(0.15) c1.SetTopMargin(0.07) c1.SetRightMargin(0.05) for modification in canvasModifications: modification(c1) drawOption = plot.drawOption if hasattr(plot, "drawOption") else "COLZ" c1.SetLogx(logX) c1.SetLogy(logY) c1.SetLogz(logZ) histo.GetXaxis().SetTitle(plot.texX) histo.GetYaxis().SetTitle(plot.texY) if zRange is not None: histo.GetZaxis().SetRangeUser(*zRange) # precision 3 fonts. see https://root.cern.ch/root/htmldoc//TAttText.html#T5 histo.GetXaxis().SetTitleFont(43) histo.GetYaxis().SetTitleFont(43) histo.GetXaxis().SetLabelFont(43) histo.GetYaxis().SetLabelFont(43) histo.GetXaxis().SetTitleSize(24) histo.GetYaxis().SetTitleSize(24) histo.GetXaxis().SetLabelSize(20) histo.GetYaxis().SetLabelSize(20) # should probably go into a styler ROOT.gROOT.LoadMacro( "$CMSSW_BASE/src/RootTools/plot/scripts/niceColorPalette.C") ROOT.niceColorPalette(255) #ROOT.gStyle.SetPalette(1) ROOT.gPad.SetRightMargin(0.15) for modification in histModifications: modification(histo) histo.Draw(drawOption) c1.RedrawAxis() for o in drawObjects: if o: o.Draw() else: logger.debug("drawObjects has something I can't Draw(): %r", o) if not os.path.exists(plot_directory): os.makedirs(plot_directory) if copyIndexPHP: plot_helpers.copyIndexPHP(plot_directory) for extension in extensions: filename = plot.name # if plot.name is not None else plot.variable.name #FIXME -> the replacement with variable.name should already be in the Plot constructors c1.Print(os.path.join(plot_directory, "%s.%s" % (filename, extension))) del c1
else: reco = {"pdgId": 22, "pt": -1, "eta": -1} histUnfoldMatrix.Fill(gen["pt"], reco["pt"], weight) histUnfoldInput.Fill(reco["pt"], weight) histDataTruth.Fill(gen["pt"], weight) pickle.dump(histUnfoldMatrix, file(filename_unfoldMatrix, "w")) pickle.dump(histUnfoldInput, file(filename_inputHisto, "w")) pickle.dump(histDataTruth, file(filename_datatruthHisto, "w")) del r plot_directory_ = os.path.join(plot_directory, 'unfolding', str(args.year)) if not os.path.isdir(plot_directory_): os.makedirs(plot_directory_) copyIndexPHP(plot_directory_) C1 = ROOT.TCanvas("output", "output", 900, 1250) C1.SetRightMargin(0.15) #C1.cd(1) C1.SetLogz() histUnfoldMatrix.GetXaxis().SetTitle("p^{gen}_{T}(#gamma) [GeV]") histUnfoldMatrix.GetYaxis().SetTitle("p^{reco}_{T}(#gamma) [GeV]") histUnfoldMatrix.Draw("colz") for ending in endings: C1.SaveAs(os.path.join(plot_directory_, "unfoldingMatrix" + ending)) C2 = ROOT.TCanvas("output2", "output2", 900, 1250) histUnfoldInput.GetXaxis().SetTitle("p^{reco}_{T}(#gamma) [GeV]") histUnfoldInput.Draw() for ending in endings:
def plot1D(dat, datExp, var, xmin, xmax, lumi_scale): # get TGraph from results data list xhist = toGraph(var, var, dat) func = ROOT.TF1("func", polString, xmin, xmax) xhist.Fit(func, "NO") # compensate for small rounding issues # profiled limits must be worse than non-profiled ones # however due to the fitting the value can be e.g. 0.1648 in the profiled one and 0.1651 in the non-profiled one # make the profiled one slightly worse to compensate for that # ugly but works x68min = func.GetX(0.989, xmin, 0) x68max = func.GetX(0.989, 0, xmax) x95min = func.GetX(3.84, xmin, 0) x95max = func.GetX(3.84, 0, xmax) print "68min", x68min print "68max", x68max print "95min", x95min print "95max", x95max # x68min = round( abs(x68min), 2 ) if x68min > 0 else -round( abs( x68min), 2 ) # x68max = round( abs(x68max), 2 ) if x68max > 0 else -round( abs( x68max), 2 ) # x95min = round( abs(x95min), 2 ) if x95min > 0 else -round( abs( x95min), 2 ) # x95max = round( abs(x95max), 2 ) if x95max > 0 else -round( abs( x95max), 2 ) xhist.SetLineWidth(0) func.SetFillColor(ROOT.kWhite) func.SetFillStyle(1001) func.SetLineWidth(3) func.SetLineColor(ROOT.kBlack) func.SetNpx(1000) xhistExp = toGraph(var, var, datExp) funcExp = ROOT.TF1("func", polStringExp, xmin, xmax) xhistExp.Fit(funcExp, "NO") xhist.SetLineWidth(0) func.SetFillColor(ROOT.kWhite) func.SetFillStyle(1001) func.SetLineWidth(3) func.SetLineColor(ROOT.kBlack) func.SetNpx(1000) funcExp.SetFillColor(ROOT.kWhite) funcExp.SetFillStyle(1001) funcExp.SetLineWidth(3) # funcExp.SetLineStyle(11) funcExp.SetLineColor(ROOT.kGray + 1) funcExp.SetNpx(1000) x68min = funcExp.GetX(0.989, xmin, 0) x68max = funcExp.GetX(0.989, 0, xmax) x95min = funcExp.GetX(3.84, xmin, 0) x95max = funcExp.GetX(3.84, 0, xmax) print "expected" print "68min", x68min print "68max", x68max print "95min", x95min print "95max", x95max ROOT.gStyle.SetPadLeftMargin(0.14) ROOT.gStyle.SetPadRightMargin(0.1) ROOT.gStyle.SetPadTopMargin(0.11) ROOT.gStyle.SetPadBottomMargin(0.11) # Plot cans = ROOT.TCanvas("cans", "cans", 500, 500) #if not None in args.zRange: xhist.GetYaxis().SetRangeUser(-0.01, 5.5) xhist.GetXaxis().SetRangeUser(xmin, xmax) # xhist.GetXaxis().SetLimits(xmin, xmax) func95 = ROOT.TF1("func95", polString, x95min, x95max) xhist.Fit(func95, "NO") func95.SetFillColor(ROOT.kOrange + 7) func95.SetFillStyle(1001) func95.SetLineWidth(0) func95.SetNpx(1000) func68 = ROOT.TF1("func68", polString, x68min, x68max) xhist.Fit(func68, "NO") func68.SetFillColor(ROOT.kSpring - 1) func68.SetFillStyle(1001) func68.SetLineWidth(0) func68.SetNpx(1000) func.GetXaxis().SetRangeUser(xmin, xmax) func68.GetXaxis().SetRangeUser(xmin, xmax) func95.GetXaxis().SetRangeUser(xmin, xmax) xhist.Draw("ALO") func.Draw("COSAME") func95.Draw("FOSAME") func68.Draw("FOSAME") # xhist.Draw("LSAME") funcExp.Draw("COSAME") func.Draw("COSAME") if args.plotData: xhist.Draw("*SAME") if args.plotData: xhistExp.Draw("*SAME") # dashed line at 1 line5 = ROOT.TLine(xmin, 0.989, xmax, 0.989) line5.SetLineWidth(1) line5.SetLineStyle(7) line5.SetLineColor(ROOT.kBlack) # dashed line at 4 line6 = ROOT.TLine(xmin, 3.84, xmax, 3.84) line6.SetLineWidth(1) line6.SetLineStyle(7) line6.SetLineColor(ROOT.kBlack) line5.Draw() line6.Draw() xhist.GetYaxis().SetTitle("-2 #Delta ln L") print x68min, x68max print x95min, x95max funcName = "" empt = ROOT.TObject() leg = ROOT.TLegend(0.35, 0.67, 0.73, 0.85) # leg = ROOT.TLegend(0.22,0.7,0.8,0.87) leg.SetNColumns(2) leg.SetBorderSize(0) leg.SetTextSize(0.037) leg.AddEntry(func, "Observed", "l") leg.AddEntry(func68, "68%s CL" % ("%"), "f") leg.AddEntry(funcExp, "Expected", "l") leg.AddEntry(func95, "95%s CL" % ("%"), "f") leg.AddEntry(empt, "profiled", "") leg.Draw() xTitle = var.replace("c", "c_{").replace("I", "}^{I").replace('p', '#phi') + '}' xhist.GetXaxis().SetTitle(xTitle + ' [(#Lambda/TeV)^{2}]') xhist.GetXaxis().SetTitleFont(42) xhist.GetYaxis().SetTitleFont(42) xhist.GetXaxis().SetLabelFont(42) xhist.GetYaxis().SetLabelFont(42) xhist.GetXaxis().SetTitleOffset(1.1) xhist.GetYaxis().SetTitleOffset(0.85) xhist.GetXaxis().SetTitleSize(0.042) xhist.GetYaxis().SetTitleSize(0.042) xhist.GetXaxis().SetLabelSize(0.04) xhist.GetYaxis().SetLabelSize(0.04) latex1 = ROOT.TLatex() latex1.SetNDC() latex1.SetTextSize(0.035) latex1.SetTextFont(42) latex1.SetTextAlign(11) latex2 = ROOT.TLatex() latex2.SetNDC() latex2.SetTextSize(0.05) latex2.SetTextFont(42) latex2.SetTextAlign(11) addon = "" # latex1.DrawLatex(0.15, 0.91, '#bf{CMS} #it{Preliminary} ' + addon), latex2.DrawLatex(0.15, 0.91, '#bf{CMS} ' + addon), if isinstance(lumi_scale, int): latex1.DrawLatex(0.67, 0.91, '#bf{%i fb^{-1} (13 TeV)}' % lumi_scale) else: latex1.DrawLatex(0.67, 0.91, '#bf{%3.1f fb^{-1} (13 TeV)}' % lumi_scale) # Redraw axis, otherwise the filled graphes overlay cans.RedrawAxis() plotname = "%s%s%s_profiled_wExp" % (var, "", "_%s" % args.tag if args.tag != "combined" else "") if args.withbkg: plotname += "_wBkg" if args.withEFTUnc: plotname += "_wEFTUnc" for e in [".png", ".pdf", ".root"]: cans.Print(plot_directory_ + "/%s%s" % (plotname, e)) copyIndexPHP(plot_directory_)
def draw(plot, \ yRange = "auto", extensions = ["pdf", "png", "root"], plot_directory = ".", logX = False, logY = True, ratio = None, scaling = {}, sorting = False, legend = "auto", drawObjects = [], widths = {}, canvasModifications = [], histModifications = [], copyIndexPHP = False, ): ''' yRange: 'auto' (default) or [low, high] where low/high can be 'auto' extensions: ["pdf", "png", "root"] (default) logX: True/False (default), logY: True(default)/False ratio: 'auto'(default) corresponds to {'histos':[(1,0)], 'logY':False, 'style':None, 'texY': 'Data / MC', 'yRange': (0.5, 1.5), 'drawObjects': []} scaling: {} (default). Scaling the i-th stack to the j-th is done by scaling = {i:j} with i,j integers sorting: True/False(default) Whether or not to sort the components of a stack wrt Integral legend: "auto" (default) or [x_low, y_low, x_high, y_high] or None. ([<legend_coordinates>], n) divides the legend into n columns. drawObjects = [] Additional ROOT objects that are called by .Draw() widths = {} (default) to update the widths. Values are {'y_width':500, 'x_width':500, 'y_ratio_width':200} canvasModifications = [] could be used to pass on lambdas to modify the canvas. histModifications similar for histos. copyIndexPHP: whether or not to copy index.php to the plot directory ''' # FIXME -> Introduces CMSSW dependence ROOT.gROOT.LoadMacro("$CMSSW_BASE/src/RootTools/plot/scripts/tdrstyle.C") ROOT.setTDRStyle() defaultRatioStyle = { 'histos': [(1, 0)], 'logY': False, 'style': None, 'texY': 'Data / MC', 'yRange': (0.5, 1.5), 'drawObjects': [] } if ratio is not None and not type(ratio) == type({}): raise ValueError( "'ratio' must be dict (default: {}). General form is '%r'." % defaultRatioStyle) # default_widths default_widths = {'y_width': 500, 'x_width': 500, 'y_ratio_width': 200} if ratio is not None: default_widths['x_width'] = 520 # Updating with width arguments default_widths.update(widths) if not isinstance(scaling, dict): raise ValueError( "'scaling' must be of the form {0:1, 2:3} which normalizes stack[0] to stack[1] etc. Got '%r'" % scaling) # Make sure ratio dict has all the keys by updating the default if ratio is not None: defaultRatioStyle.update(ratio) ratio = defaultRatioStyle # Clone (including any attributes) and add up histos in stack histos = map(lambda l: map(lambda h: helpers.clone(h), l), plot.histos) # Add overflow bins for 1D plots if isinstance(plot, Plot.Plot): if plot.addOverFlowBin is not None: for s in histos: for p in s: Plot.addOverFlowBin1D(p, plot.addOverFlowBin) for i, l in enumerate(histos): # recall the sample for use in the legend for j, h in enumerate(l): h.sample = plot.stack[i][j] if plot.stack is not None else None # Exectute style function on histo, therefore histo styler has precendence over stack styler if hasattr(h, "style"): h.style(h) # sort if sorting: l.sort(key=lambda h: -h.Integral()) # Add up stacks for j, h in enumerate(l): for k in range(j + 1, len(l)): l[j].Add(l[k]) # Scaling for source, target in scaling.iteritems(): if not (isinstance(source, int) and isinstance(target, int)): raise ValueError( "Scaling should be {0:1, 1:2, ...}. Expected ints, got %r %r" % (source, target)) source_yield = histos[source][0].Integral() if source_yield == 0: logger.warning("Requested to scale empty Stack? Do nothing.") continue factor = histos[target][0].Integral() / source_yield for h in histos[source]: h.Scale(factor) # Make canvas and if there is a ratio plot adjust the size of the pads if ratio is not None: default_widths['y_width'] += default_widths['y_ratio_width'] scaleFacRatioPad = default_widths['y_width'] / float( default_widths['y_ratio_width']) y_border = default_widths['y_ratio_width'] / float( default_widths['y_width']) # delete canvas if it exists if hasattr("ROOT", "c1"): del ROOT.c1 c1 = ROOT.TCanvas( str(uuid.uuid4()).replace('-', '_'), "drawHistos", 200, 10, default_widths['x_width'], default_widths['y_width']) if ratio is not None: c1.Divide(1, 2, 0, 0) topPad = c1.cd(1) topPad.SetBottomMargin(0) topPad.SetLeftMargin(0.15) topPad.SetTopMargin(0.07) topPad.SetRightMargin(0.05) topPad.SetPad(topPad.GetX1(), y_border, topPad.GetX2(), topPad.GetY2()) bottomPad = c1.cd(2) bottomPad.SetTopMargin(0) bottomPad.SetRightMargin(0.05) bottomPad.SetLeftMargin(0.15) bottomPad.SetBottomMargin(scaleFacRatioPad * 0.13) bottomPad.SetPad(bottomPad.GetX1(), bottomPad.GetY1(), bottomPad.GetX2(), y_border) else: topPad = c1 topPad.SetBottomMargin(0.13) topPad.SetLeftMargin(0.15) topPad.SetTopMargin(0.07) topPad.SetRightMargin(0.05) for modification in canvasModifications: modification(c1) topPad.cd() # Range on y axis: Start with default if not yRange == "auto" and not (type(yRange) == type( ()) and len(yRange) == 2): raise ValueError( "'yRange' must bei either 'auto' or (yMin, yMax) where yMin/Max can be 'auto'. Got: %r" % yRange) max_ = max(l[0].GetMaximum() for l in histos) min_ = min(l[0].GetMinimum() for l in histos) # If legend is in the form (tuple, int) then the number of columns is provided legendColumns = 1 if legend is not None and len(legend) == 2: legendColumns = legend[1] legend = legend[0] #Calculate legend coordinates in gPad coordinates if legend is not None: if legend == "auto": legendCoordinates = (0.50, 0.93 - 0.05 * sum(map(len, plot.histos)), 0.92, 0.93) else: legendCoordinates = legend if logY: yMax_ = 10**0.5 * max_ yMin_ = 0.7 else: yMax_ = 1.2 * max_ yMin_ = 0 if min_ > 0 else 1.2 * min_ if type(yRange) == type(()) and len(yRange) == 2: yMin_ = yRange[0] if not yRange[0] == "auto" else yMin_ yMax_ = yRange[1] if not yRange[1] == "auto" else yMax_ #Avoid overlap with the legend if (yRange == "auto" or yRange[1] == "auto") and (legend is not None): scaleFactor = 1 # Get x-range and y legendMaskedArea = getLegendMaskedArea(legendCoordinates, topPad) for i, l in enumerate(histos): histo = histos[i][0] for i_bin in range(1, 1 + histo.GetNbinsX()): # low/high bin edge in the units of the x axis xLowerEdge_axis, xUpperEdge_axis = histo.GetBinLowEdge( i_bin ), histo.GetBinLowEdge(i_bin) + histo.GetBinWidth(i_bin) # linear transformation to gPad system xLowerEdge = (xLowerEdge_axis - histo.GetXaxis().GetXmin()) / ( histo.GetXaxis().GetXmax() - histo.GetXaxis().GetXmin()) xUpperEdge = (xUpperEdge_axis - histo.GetXaxis().GetXmin()) / ( histo.GetXaxis().GetXmax() - histo.GetXaxis().GetXmin()) # maximum allowed fraction in given bin wrt to the legendMaskedArea: Either all (1) or legendMaskedArea['yLowerEdge'] maxFraction = legendMaskedArea[ 'yLowerEdge'] if xUpperEdge > legendMaskedArea[ 'xLowerEdge'] and xLowerEdge < legendMaskedArea[ 'xUpperEdge'] else 1 # Save 20% maxFraction *= 0.8 # Use: (y - yMin_) / (sf*yMax_ - yMin_) = maxFraction (and y->log(y) in log case). # Compute the maximum required scale factor s. y = histo.GetBinContent(i_bin) try: if logY: new_sf = yMin_ / yMax_ * (y / yMin_)**( 1. / maxFraction) if y > 0 else 1 else: new_sf = 1. / yMax_ * (yMin_ + (y - yMin_) / maxFraction) scaleFactor = new_sf if new_sf > scaleFactor else scaleFactor except ZeroDivisionError: pass # print i_bin, xLowerEdge, xUpperEdge, 'yMin', yMin_, 'yMax', yMax_, 'y', y, 'maxFraction', maxFraction, scaleFactor, new_sf # Apply scale factor to avoid legend yMax_ = scaleFactor * yMax_ # Draw the histos same = "" stuff = [] for i, l in enumerate(histos): for j, h in enumerate(l): # Get draw option. Neither Clone nor copy preserves attributes of histo drawOption = histos[i][j].drawOption if hasattr( histos[i][j], "drawOption") else "hist" topPad.SetLogy(logY) topPad.SetLogx(logX) h.GetYaxis().SetRangeUser(yMin_, yMax_) h.GetXaxis().SetTitle(plot.texX) h.GetYaxis().SetTitle(plot.texY) # precision 3 fonts. see https://root.cern.ch/root/htmldoc//TAttText.html#T5 h.GetXaxis().SetTitleFont(43) h.GetYaxis().SetTitleFont(43) h.GetXaxis().SetLabelFont(43) h.GetYaxis().SetLabelFont(43) h.GetXaxis().SetTitleSize(24) h.GetYaxis().SetTitleSize(24) h.GetXaxis().SetLabelSize(20) h.GetYaxis().SetLabelSize(20) if ratio is None: h.GetYaxis().SetTitleOffset(1.3) else: h.GetYaxis().SetTitleOffset(1.6) for modification in histModifications: modification(h) if drawOption == "e1" or drawOption == "e0": stuff.append(h) #dataHist = h h.Draw(drawOption + same) same = "same" if not drawOption == 'AH': topPad.RedrawAxis() # Make the legend if legend is not None: legend_ = ROOT.TLegend(*legendCoordinates) legend_.SetNColumns(legendColumns) legend_.SetFillStyle(0) # legend_.SetFillColor(0) legend_.SetShadowColor(ROOT.kWhite) legend_.SetBorderSize(0) # legend_.SetBorderSize(1) for l in histos: for h in l: if hasattr(h.sample, "notInLegend"): if h.sample.notInLegend: continue if hasattr(h, "texName"): legend_text = h.texName elif hasattr(h, "legendText"): legend_text = h.legendText elif h.sample is not None: legend_text = h.sample.texName if hasattr( h.sample, "texName") else h.sample.name else: continue #legend_text = "No title" if hasattr(h, "legendOption"): legend_option = h.legendOption legend_.AddEntry(h, legend_text, legend_option) else: legend_.AddEntry(h, legend_text) legend_.Draw() for o in drawObjects: if o: if type(o) in [ ROOT.TF1, ROOT.TGraph, ROOT.TEfficiency, ROOT.TH1F, ROOT.TH1D ]: if hasattr(o, 'drawOption'): o.Draw('same ' + o.drawOption) else: o.Draw('same') else: o.Draw() else: logger.debug("drawObjects has something I can't Draw(): %r", o) # re-draw the main objects (ratio histograms) after the objects, otherwise they might be hidden for h_main in stuff: drawOption = h_main.drawOption if hasattr(h_main, "drawOption") else "hist" h_main.Draw(drawOption + same) # Make a ratio plot if ratio is not None: bottomPad.cd() # Make all the ratio histograms same = '' stuff = [] for i_num, i_den in ratio['histos']: num = histos[i_num][0] den = histos[i_den][0] h_ratio = helpers.clone(num) stuff.append(h_ratio) # For a ratio of profiles, use projection (preserve attributes) if isinstance(h_ratio, ROOT.TProfile): attrs = h_ratio.__dict__ h_ratio = h_ratio.ProjectionX() h_ratio.__dict__.update(attrs) h_ratio.Divide(den.ProjectionX()) else: h_ratio.Divide(den) #if ratio['style'] is not None: ratio['style'](h_ratio) h_ratio.GetXaxis().SetTitle(plot.texX) h_ratio.GetYaxis().SetTitle(ratio['texY']) h_ratio.GetXaxis().SetTitleFont(43) h_ratio.GetYaxis().SetTitleFont(43) h_ratio.GetXaxis().SetLabelFont(43) h_ratio.GetYaxis().SetLabelFont(43) h_ratio.GetXaxis().SetTitleSize(24) h_ratio.GetYaxis().SetTitleSize(24) h_ratio.GetXaxis().SetLabelSize(20) h_ratio.GetYaxis().SetLabelSize(20) h_ratio.GetXaxis().SetTitleOffset(3.2) h_ratio.GetYaxis().SetTitleOffset(1.6) h_ratio.GetXaxis().SetTickLength(0.03 * 3) h_ratio.GetYaxis().SetTickLength(0.03 * 2) h_ratio.GetYaxis().SetRangeUser(*ratio['yRange']) h_ratio.GetYaxis().SetNdivisions(505) if ratio.has_key('histModifications'): for modification in ratio['histModifications']: modification(h_ratio) drawOption = h_ratio.drawOption if hasattr( h_ratio, "drawOption") else "hist" if drawOption == "e1" or drawOption == "e0": # hacking to show error bars within panel when central value is off scale graph = ROOT.TGraphAsymmErrors( h_ratio) # cloning in order to get layout graph.Set(0) for bin in range(1, h_ratio.GetNbinsX() + 1): # do not show error bars on hist h_ratio.SetBinError(bin, 0.0001) center = h_ratio.GetBinCenter(bin) val = h_ratio.GetBinContent(bin) errUp = num.GetBinErrorUp(bin) / den.GetBinContent( bin) if den.GetBinContent(bin) > 0 else 0 errDown = num.GetBinErrorLow(bin) / den.GetBinContent( bin) if den.GetBinContent(bin) > 0 else 0 graph.SetPoint(bin, center, val) graph.SetPointError(bin, 0, 0, errDown, errUp) h_ratio.Draw("e0" + same) graph.Draw("P0 same") graph.drawOption = "P0" stuff.append(graph) else: h_ratio.Draw(drawOption + same) same = 'same' bottomPad.SetLogx(logX) bottomPad.SetLogy(ratio['logY']) line = ROOT.TPolyLine(2) line.SetPoint(0, h_ratio.GetXaxis().GetXmin(), 1.) line.SetPoint(1, h_ratio.GetXaxis().GetXmax(), 1.) line.SetLineWidth(1) line.Draw() for o in ratio['drawObjects']: if o: if hasattr(o, 'drawOption'): o.Draw(o.drawOption) else: o.Draw() else: logger.debug( "ratio['drawObjects'] has something I can't Draw(): %r", o) # re-draw the main objects (ratio histograms) after the objects, otherwise they might be hidden for h_ratio in stuff: drawOption = h_ratio.drawOption if hasattr( h_ratio, "drawOption") else "hist" h_ratio.Draw(drawOption + same) if not os.path.exists(plot_directory): try: os.makedirs(plot_directory) except OSError: # Resolve rare race condition pass if copyIndexPHP: plot_helpers.copyIndexPHP(plot_directory) c1.cd() for extension in extensions: filename = plot.name # if plot.name is not None else plot.variable.name #FIXME -> the replacement with variable.name should already be in the Plot constructors ofile = os.path.join(plot_directory, "%s.%s" % (filename, extension)) c1.Print(ofile) del c1
def draw2D(plot, \ zRange = None, extensions = ["pdf", "png", "root"], plot_directory = ".", logX = False, logY = False, logZ = True, drawObjects = [], widths = {}, canvasModifications = [], histModifications = [], copyIndexPHP = False, ): ''' plot: a Plot2D instance zRange: None ( = ROOT default) or [low, high] extensions: ["pdf", "png", "root"] (default) logX: True/False (default), logY: True/False(default), logZ: True/False(default) drawObjects = [] Additional ROOT objects that are called by .Draw() widths = {} (default) to update the widths. Values are {'y_width':500, 'x_width':500, 'y_ratio_width':200} canvasModifications = [] could be used to pass on lambdas to modify the canvas. histModifications similar for histos. copyIndexPHP: whether or not to copy index.php to the plot directory ''' # FIXME -> Introduces CMSSW dependence ROOT.gROOT.LoadMacro("$CMSSW_BASE/src/RootTools/plot/scripts/tdrstyle.C") ROOT.setTDRStyle() # default_widths default_widths = {'y_width':500, 'x_width':500, 'y_ratio_width':200} # Updating with width arguments default_widths.update(widths) # Adding up all components histos = plot.histos_added histo = histos[0][0].Clone() if len(histos)>1: logger.warning( "Adding %i histos for 2D plot %s", len(histos), plot.name ) for h in histos[1:]: histo.Add( h[0] ) ## Clone (including any attributes) and add up histos in stack #if hasattr(histo, "style"): # histo.style(histo) c1 = ROOT.TCanvas("ROOT.c1", "drawHistos", 200,10, default_widths['x_width'], default_widths['y_width']) c1.SetBottomMargin(0.13) c1.SetLeftMargin(0.15) c1.SetTopMargin(0.07) c1.SetRightMargin(0.05) for modification in canvasModifications: modification(c1) drawOption = plot.drawOption if hasattr(plot, "drawOption") else "COLZ" c1.SetLogx(logX) c1.SetLogy(logY) c1.SetLogz(logZ) histo.GetXaxis().SetTitle(plot.texX) histo.GetYaxis().SetTitle(plot.texY) if zRange is not None: histo.GetZaxis().SetRangeUser( *zRange ) # precision 3 fonts. see https://root.cern.ch/root/htmldoc//TAttText.html#T5 histo.GetXaxis().SetTitleFont(43) histo.GetYaxis().SetTitleFont(43) histo.GetXaxis().SetLabelFont(43) histo.GetYaxis().SetLabelFont(43) histo.GetXaxis().SetTitleSize(24) histo.GetYaxis().SetTitleSize(24) histo.GetXaxis().SetLabelSize(20) histo.GetYaxis().SetLabelSize(20) # should probably go into a styler ROOT.gROOT.LoadMacro("$CMSSW_BASE/src/RootTools/plot/scripts/niceColorPalette.C") ROOT.niceColorPalette(255) #ROOT.gStyle.SetPalette(1) ROOT.gPad.SetRightMargin(0.15) for modification in histModifications: modification(histo) histo.Draw(drawOption) c1.RedrawAxis() for o in drawObjects: if o: o.Draw() else: logger.debug( "drawObjects has something I can't Draw(): %r", o) if not os.path.exists(plot_directory): os.makedirs(plot_directory) if copyIndexPHP: plot_helpers.copyIndexPHP( plot_directory ) for extension in extensions: filename = plot.name# if plot.name is not None else plot.variable.name #FIXME -> the replacement with variable.name should already be in the Plot constructors c1.Print( os.path.join( plot_directory, "%s.%s"%(filename, extension) ) ) del c1
def plot1D(dat, datIncl, var, xmin, xmax): # get TGraph from results data list xhist = toGraph(var, var, dat) xhistIncl = toGraph(var + "Incl", var, datIncl) # polStringIncl = "[0]+[1]*x+[2]*x**2+[3]*x**3+[4]*x**4+[5]*x**5+[6]*x**6+[7]*x**7+[8]*x**8" #+[7]*x**7+[8]*x**8" #+[5]*x**7+[6]*x**8"#+[7]*x**9+[8]*x**10+[9]*x**11+[10]*x**12" if args.expected: polString = "[0]*x**2+[1]*x**3+[2]*x**4+[3]*x**6" #+[7]*x**7+[8]*x**8" #+[5]*x**7+[6]*x**8"#+[7]*x**9+[8]*x**10+[9]*x**11+[10]*x**12" else: polString = "[0]+[1]*x+[2]*x**2+[3]*x**3+[4]*x**4+[5]*x**6" #+[7]*x**7+[8]*x**8" #+[5]*x**7+[6]*x**8"#+[7]*x**9+[8]*x**10+[9]*x**11+[10]*x**12" func = ROOT.TF1("func", polString, xmin, xmax) xhist.Fit(func, "NO") ym = func.GetMinimum(-0.6, 0.6) xm = func.GetX(ym, -0.6, 0.6) x68min = func.GetX(0.989, -0.6, xm) x68max = func.GetX(0.989, xm, 0.6) ym2 = func.GetMinimum(-0.6, 0) xm2 = func.GetX(ym2, -0.6, 0) x68pmin = func.GetX(0.989, -0.6, xm2) x68pmax = func.GetX(0.989, xm2, 0) if args.variables == "ctZI" and (args.year == 2018 or args.year == "RunII") and not args.expected: ym = func.GetMinimum(-0.6, 0) xm = func.GetX(ym, -0.6, 0) ym2 = func.GetMinimum(0, 0.6) xm2 = func.GetX(ym2, 0, 0.6) x68pmin = func.GetX(0.989, 0, xm2) x68pmax = func.GetX(0.989, xm2, 0.6) x68min = func.GetX(0.989, -0.6, xm) x68max = func.GetX(0.989, xm, 0) x95min = func.GetX(3.84, -0.6, xm) x95max = func.GetX(3.84, xm, 0.6) if (args.year == 2018 or (args.year == "RunII" and args.variables == "ctZ") ) and not args.expected and not args.withbkg: ym2 = func.GetMinimum(0.01, 0.6) xm2 = func.GetX(ym2, 0.01, 0.6) x95pmin = func.GetX(3.84, 0.01, xm2) x95pmax = func.GetX(3.84, xm2, 0.6) x95min = func.GetX(3.84, -0.6, xm) x95max = func.GetX(3.84, xm, 0.05) xhist.SetLineWidth(0) func.SetFillColor(ROOT.kWhite) func.SetFillStyle(1001) func.SetLineWidth(3) func.SetLineColor(ROOT.kBlack) func.SetNpx(1000) if args.expected: polStringIncl = "[0]*x**2+[1]*x**3+[2]*x**4+[3]*x**5+[4]*x**6" #+[7]*x**7+[8]*x**8" #+[5]*x**7+[6]*x**8"#+[7]*x**9+[8]*x**10+[9]*x**11+[10]*x**12" else: polStringIncl = "[0]+[1]*x+[2]*x**2+[3]*x**3+[4]*x**4+[5]*x**5+[6]*x**6" #+[7]*x**7+[8]*x**8" #+[5]*x**7+[6]*x**8"#+[7]*x**9+[8]*x**10+[9]*x**11+[10]*x**12" funcIncl = ROOT.TF1("funcIncl", polStringIncl, xmin, xmax) xhistIncl.Fit(funcIncl, "NO") xm = 0 x68minIncl = funcIncl.GetX(0.989, xmin, 0) x68maxIncl = funcIncl.GetX(0.989, 0, xmax) x95minIncl = funcIncl.GetX(3.84, xmin, 0) x95maxIncl = funcIncl.GetX(3.84, 0, xmax) xhistIncl.SetLineWidth(0) funcIncl.SetFillColor(ROOT.kWhite) funcIncl.SetFillStyle(1001) funcIncl.SetLineWidth(3) # funcIncl.SetLineStyle(11) funcIncl.SetLineColor(ROOT.kGray + 1) funcIncl.SetNpx(1000) ROOT.gStyle.SetPadLeftMargin(0.14) ROOT.gStyle.SetPadRightMargin(0.1) ROOT.gStyle.SetPadTopMargin(0.11) ROOT.gStyle.SetPadBottomMargin(0.11) # Plot cans = ROOT.TCanvas("cans", "cans", 500, 500) #if not None in args.zRange: xhist.GetYaxis().SetRangeUser(0, 5.5) xhist.GetXaxis().SetRangeUser(xmin, xmax) # xhist.GetXaxis().SetLimits(xmin, xmax) func95 = ROOT.TF1("func95", polString, x95min, x95max) xhist.Fit(func95, "NO") func95.SetFillColor(ROOT.kOrange + 7) func95.SetFillStyle(1001) func95.SetLineWidth(0) func95.SetNpx(1000) if (args.year == 2018 or (args.year == "RunII" and args.variables == "ctZ") ) and not args.expected and not args.withbkg: func95p = ROOT.TF1("func95p", polString, x95pmin, x95pmax) xhist.Fit(func95p, "NO") func95p.SetFillColor(ROOT.kOrange + 7) func95p.SetFillStyle(1001) func95p.SetLineWidth(0) func95p.SetNpx(1000) func68 = ROOT.TF1("func68", polString, x68min, x68max) xhist.Fit(func68, "NO") func68.SetFillColor(ROOT.kSpring - 1) func68.SetFillStyle(1001) func68.SetLineWidth(0) func68.SetNpx(1000) func68p = ROOT.TF1("func68p", polString, x68pmin, x68pmax) xhist.Fit(func68p, "NO") func68p.SetFillColor(ROOT.kSpring - 1) func68p.SetFillStyle(1001) func68p.SetLineWidth(0) func68p.SetNpx(1000) func.GetXaxis().SetRangeUser(-0.6, 0.6) func68.GetXaxis().SetRangeUser(-0.6, 0.6) if args.variables == "ctZI" and (args.year == 2018 or args.year == "RunII") and not args.expected: func68p.GetXaxis().SetRangeUser(-0.6, 0.6) func95.GetXaxis().SetRangeUser(-0.6, 0.6) if (args.year == 2018 or (args.year == "RunII" and args.variables == "ctZ") ) and not args.expected and not args.withbkg: func95p.GetXaxis().SetRangeUser(-0.6, 0.6) func95Incl = ROOT.TF1("func95Incl", polStringIncl, x95minIncl, x95maxIncl) xhistIncl.Fit(func95Incl, "NO") func95Incl.SetFillColor(ROOT.kGray + 2) func95Incl.SetFillStyle(1001) func95Incl.SetLineWidth(0) func95Incl.SetNpx(1000) func68Incl = ROOT.TF1("func68Incl", polStringIncl, x68minIncl, x68maxIncl) xhistIncl.Fit(func68Incl, "NO") func68Incl.SetFillColor(ROOT.kGray + 1) func68Incl.SetFillStyle(1001) func68Incl.SetLineWidth(0) func68Incl.SetNpx(1000) funcIncl.GetXaxis().SetRangeUser(xmin, xmax) func68Incl.GetXaxis().SetRangeUser(xmin, xmax) func95Incl.GetXaxis().SetRangeUser(xmin, xmax) xhist.Draw("ALO") # func95Incl.Draw("FOSAME") # func68Incl.Draw("FOSAME") func.Draw("COSAME") func95.Draw("FOSAME") if (args.year == 2018 or (args.year == "RunII" and args.variables == "ctZ") ) and not args.expected and not args.withbkg: func95p.Draw("FOSAME") func68.Draw("FOSAME") if args.variables == "ctZI" and (args.year == 2018 or args.year == "RunII") and not args.expected: func68p.Draw("FOSAME") # xhist.Draw("LSAME") funcIncl.Draw("COSAME") func.Draw("COSAME") if args.plotData: xhist.Draw("*SAME") if args.plotData: xhistIncl.Draw("*SAME") # dashed line at 1 line5 = ROOT.TLine(xmin, 0.989, xmax, 0.989) line5.SetLineWidth(1) line5.SetLineStyle(7) line5.SetLineColor(ROOT.kBlack) # dashed line at 4 line6 = ROOT.TLine(xmin, 3.84, xmax, 3.84) line6.SetLineWidth(1) line6.SetLineStyle(7) line6.SetLineColor(ROOT.kBlack) line5.Draw() line6.Draw() xhist.GetYaxis().SetTitle("-2 #Delta ln L") print x68min, x68max print x95min, x95max if "%.2f" % x68pmax == "%.2f" % x68min: x68min = x68pmin funcName = "Log-likelihood ratio" if args.variables == "ctZ" and args.year == 2016 and x68pmin != x68min and not args.expected: leg = ROOT.TLegend(0.17, 0.7, 0.85, 0.87) elif (args.year == 2018 or args.year == "RunII") and not args.expected: leg = ROOT.TLegend(0.17, 0.7, 0.85, 0.87) else: leg = ROOT.TLegend(0.22, 0.7, 0.8, 0.87) leg.SetBorderSize(0) leg.SetTextSize(0.03) leg.AddEntry(func, funcName + " (diff)", "l") leg.AddEntry(funcIncl, funcName + " (incl)", "l") if args.variables == "ctZI" and (args.year == 2018 or args.year == "RunII" ) and args.withbkg and not args.expected: leg.AddEntry( func68, "68%s CL (diff) [%.2f, %.2f], [%.2f, %.2f]" % ("%", x68min, x68max, x68pmin, x68pmax), "f") elif args.variables == "ctZI" and args.year == "RunII" and not args.withbkg and not args.expected: leg.AddEntry( func68, "68%s CL (diff) [%.2f, %.2f], [%.2f, %.2f]" % ("%", x68min, x68max, x68pmin, x68pmax), "f") else: leg.AddEntry(func68, "68%s CL (diff) [%.2f, %.2f]" % ("%", x68min, x68max), "f") if (args.year == 2018 or (args.year == "RunII" and args.variables == "ctZ") ) and not args.expected and not args.withbkg: leg.AddEntry( func95, "95%s CL (diff) [%.2f, %.2f], [%.2f, %.2f]" % ("%", x95min, x95max, x95pmin, x95pmax), "f") else: leg.AddEntry(func95, "95%s CL (diff) [%.2f, %.2f]" % ("%", x95min, x95max), "f") # leg.AddEntry( func68, "68%s CL (diff) [%.2f, %.2f]"%("%",x68min, x68max), "f") # leg.AddEntry( func95, "95%s CL (diff) [%.2f, %.2f]"%("%",x95min, x95max), "f") # leg.AddEntry( func68Incl, "68%s CL (incl) [%.2f, %.2f]"%("%",x68minIncl, x68maxIncl), "f") # leg.AddEntry( func95Incl, "95%s CL (incl) [%.2f, %.2f]"%("%",x95minIncl, x95maxIncl), "f") leg.Draw() xTitle = var.replace("c", "c_{").replace("I", "}^{I").replace('p', '#phi') + '}' xhist.GetXaxis().SetTitle(xTitle + ' [(#Lambda/TeV^{2})]') xhist.GetXaxis().SetTitleFont(42) xhist.GetYaxis().SetTitleFont(42) xhist.GetXaxis().SetLabelFont(42) xhist.GetYaxis().SetLabelFont(42) # xhist.GetXaxis().SetTitleOffset(1.3) # xhist.GetYaxis().SetTitleOffset(1.3) xhist.GetXaxis().SetTitleSize(0.042) xhist.GetYaxis().SetTitleSize(0.042) xhist.GetXaxis().SetLabelSize(0.04) xhist.GetYaxis().SetLabelSize(0.04) latex1 = ROOT.TLatex() latex1.SetNDC() latex1.SetTextSize(0.035) latex1.SetTextFont(42) latex1.SetTextAlign(11) addon = "" # latex1.DrawLatex(0.15, 0.91, '#bf{CMS} #it{Simulation Preliminary} ' + addon), latex1.DrawLatex(0.15, 0.91, '#bf{CMS} #it{Simulation} ' + addon), if isinstance(lumi_scale, int): latex1.DrawLatex(0.70, 0.91, '#bf{%i fb^{-1} (13 TeV)}' % lumi_scale) else: latex1.DrawLatex(0.68, 0.91, '#bf{%3.1f fb^{-1} (13 TeV)}' % lumi_scale) # Redraw axis, otherwise the filled graphes overlay cans.RedrawAxis() plotname = "%s%s%s_wIncl" % (var, "", "_%s" % args.tag if args.tag != "combined" else "") if args.withbkg: plotname += "_wBkg" if args.withEFTUnc: plotname += "_wEFTUnc" for e in [".png", ".pdf", ".root"]: cans.Print(plot_directory_ + "/%s%s" % (plotname, e)) copyIndexPHP(plot_directory_)
def draw(plot, \ yRange = "auto", extensions = ["pdf", "png", "root"], plot_directory = ".", logX = False, logY = True, ratio = None, scaling = {}, sorting = False, legend = "auto", drawObjects = [], widths = {}, canvasModifications = [], histModifications = [], copyIndexPHP = False, ): ''' yRange: 'auto' (default) or [low, high] where low/high can be 'auto' extensions: ["pdf", "png", "root"] (default) logX: True/False (default), logY: True(default)/False ratio: 'auto'(default) corresponds to {'histos':[(1,0)], 'logY':False, 'style':None, 'texY': 'Data / MC', 'yRange': (0.5, 1.5), 'drawObjects': []} scaling: {} (default). Scaling the i-th stack to the j-th is done by scaling = {i:j} with i,j integers sorting: True/False(default) Whether or not to sort the components of a stack wrt Integral legend: "auto" (default) or [x_low, y_low, x_high, y_high] or None. ([<legend_coordinates>], n) divides the legend into n columns. drawObjects = [] Additional ROOT objects that are called by .Draw() widths = {} (default) to update the widths. Values are {'y_width':500, 'x_width':500, 'y_ratio_width':200} canvasModifications = [] could be used to pass on lambdas to modify the canvas. histModifications similar for histos. copyIndexPHP: whether or not to copy index.php to the plot directory ''' # FIXME -> Introduces CMSSW dependence ROOT.gROOT.LoadMacro("$CMSSW_BASE/src/RootTools/plot/scripts/tdrstyle.C") ROOT.setTDRStyle() defaultRatioStyle = {'histos':[(1,0)], 'logY':False, 'style':None, 'texY': 'Data / MC', 'yRange': (0.5, 1.5), 'drawObjects':[]} if ratio is not None and not type(ratio)==type({}): raise ValueError( "'ratio' must be dict (default: {}). General form is '%r'." % defaultRatioStyle) # default_widths default_widths = {'y_width':500, 'x_width':500, 'y_ratio_width':200} if ratio is not None: default_widths['x_width'] = 520 # Updating with width arguments default_widths.update(widths) if not isinstance(scaling, dict): raise ValueError( "'scaling' must be of the form {0:1, 2:3} which normalizes stack[0] to stack[1] etc. Got '%r'" % scaling ) # Make sure ratio dict has all the keys by updating the default if ratio is not None: defaultRatioStyle.update(ratio) ratio = defaultRatioStyle # Clone (including any attributes) and add up histos in stack histos = map(lambda l:map(lambda h:helpers.clone(h), l), plot.histos) # Add overflow bins for 1D plots if isinstance(plot, Plot.Plot): if plot.addOverFlowBin is not None: for s in histos: for p in s: Plot.addOverFlowBin1D( p, plot.addOverFlowBin ) for i, l in enumerate(histos): # recall the sample for use in the legend for j, h in enumerate(l): h.sample = plot.stack[i][j] if plot.stack is not None else None # Exectute style function on histo, therefore histo styler has precendence over stack styler if hasattr(h, "style"): h.style(h) # sort if sorting: l.sort(key=lambda h: -h.Integral()) # Add up stacks for j, h in enumerate(l): for k in range(j+1, len(l) ): l[j].Add(l[k]) # Scaling for source, target in scaling.iteritems(): if not ( isinstance(source, int) and isinstance(target, int) ): raise ValueError( "Scaling should be {0:1, 1:2, ...}. Expected ints, got %r %r"%( source, target ) ) source_yield = histos[source][0].Integral() if source_yield == 0: logger.warning( "Requested to scale empty Stack? Do nothing." ) continue factor = histos[target][0].Integral()/source_yield for h in histos[source]: h.Scale( factor ) # Make canvas and if there is a ratio plot adjust the size of the pads if ratio is not None: default_widths['y_width'] += default_widths['y_ratio_width'] scaleFacRatioPad = default_widths['y_width']/float( default_widths['y_ratio_width'] ) y_border = default_widths['y_ratio_width']/float( default_widths['y_width'] ) # delete canvas if it exists if hasattr("ROOT","c1"): del ROOT.c1 c1 = ROOT.TCanvas(str(uuid.uuid4()).replace('-','_'), "drawHistos",200,10, default_widths['x_width'], default_widths['y_width']) if ratio is not None: c1.Divide(1,2,0,0) topPad = c1.cd(1) topPad.SetBottomMargin(0) topPad.SetLeftMargin(0.15) topPad.SetTopMargin(0.07) topPad.SetRightMargin(0.05) topPad.SetPad(topPad.GetX1(), y_border, topPad.GetX2(), topPad.GetY2()) bottomPad = c1.cd(2) bottomPad.SetTopMargin(0) bottomPad.SetRightMargin(0.05) bottomPad.SetLeftMargin(0.15) bottomPad.SetBottomMargin(scaleFacRatioPad*0.13) bottomPad.SetPad(bottomPad.GetX1(), bottomPad.GetY1(), bottomPad.GetX2(), y_border) else: topPad = c1 topPad.SetBottomMargin(0.13) topPad.SetLeftMargin(0.15) topPad.SetTopMargin(0.07) topPad.SetRightMargin(0.05) for modification in canvasModifications: modification(c1) topPad.cd() # Range on y axis: Start with default if not yRange=="auto" and not (type(yRange)==type(()) and len(yRange)==2): raise ValueError( "'yRange' must bei either 'auto' or (yMin, yMax) where yMin/Max can be 'auto'. Got: %r"%yRange ) max_ = max( l[0].GetMaximum() for l in histos ) min_ = min( l[0].GetMinimum() for l in histos ) # If legend is in the form (tuple, int) then the number of columns is provided legendColumns = 1 if legend is not None and len(legend) == 2: legendColumns = legend[1] legend = legend[0] #Calculate legend coordinates in gPad coordinates if legend is not None: if legend=="auto": legendCoordinates = (0.50,0.93-0.05*sum(map(len, plot.histos)),0.92,0.93) else: legendCoordinates = legend if logY: yMax_ = 10**0.5*max_ yMin_ = 0.7 else: yMax_ = 1.2*max_ yMin_ = 0 if min_>0 else 1.2*min_ if type(yRange)==type(()) and len(yRange)==2: yMin_ = yRange[0] if not yRange[0]=="auto" else yMin_ yMax_ = yRange[1] if not yRange[1]=="auto" else yMax_ #Avoid overlap with the legend if (yRange=="auto" or yRange[1]=="auto") and (legend is not None): scaleFactor = 1 # Get x-range and y legendMaskedArea = getLegendMaskedArea(legendCoordinates, topPad) for i, l in enumerate(histos): histo = histos[i][0] for i_bin in range(1, 1 + histo.GetNbinsX()): # low/high bin edge in the units of the x axis xLowerEdge_axis, xUpperEdge_axis = histo.GetBinLowEdge(i_bin), histo.GetBinLowEdge(i_bin)+histo.GetBinWidth(i_bin) # linear transformation to gPad system xLowerEdge = (xLowerEdge_axis - histo.GetXaxis().GetXmin())/(histo.GetXaxis().GetXmax() - histo.GetXaxis().GetXmin()) xUpperEdge = (xUpperEdge_axis - histo.GetXaxis().GetXmin())/(histo.GetXaxis().GetXmax() - histo.GetXaxis().GetXmin()) # maximum allowed fraction in given bin wrt to the legendMaskedArea: Either all (1) or legendMaskedArea['yLowerEdge'] maxFraction = legendMaskedArea['yLowerEdge'] if xUpperEdge>legendMaskedArea['xLowerEdge'] and xLowerEdge<legendMaskedArea['xUpperEdge'] else 1 # Save 20% maxFraction*=0.8 # Use: (y - yMin_) / (sf*yMax_ - yMin_) = maxFraction (and y->log(y) in log case). # Compute the maximum required scale factor s. y = histo.GetBinContent(i_bin) try: if logY: new_sf = yMin_/yMax_*(y/yMin_)**(1./maxFraction) if y>0 else 1 else: new_sf = 1./yMax_*(yMin_ + (y-yMin_)/maxFraction ) scaleFactor = new_sf if new_sf>scaleFactor else scaleFactor except ZeroDivisionError: pass # print i_bin, xLowerEdge, xUpperEdge, 'yMin', yMin_, 'yMax', yMax_, 'y', y, 'maxFraction', maxFraction, scaleFactor, new_sf # Apply scale factor to avoid legend yMax_ = scaleFactor*yMax_ # Draw the histos same = "" for i, l in enumerate(histos): for j, h in enumerate(l): # Get draw option. Neither Clone nor copy preserves attributes of histo drawOption = histos[i][j].drawOption if hasattr(histos[i][j], "drawOption") else "hist" topPad.SetLogy(logY) topPad.SetLogx(logX) h.GetYaxis().SetRangeUser(yMin_, yMax_) h.GetXaxis().SetTitle(plot.texX) h.GetYaxis().SetTitle(plot.texY) # precision 3 fonts. see https://root.cern.ch/root/htmldoc//TAttText.html#T5 h.GetXaxis().SetTitleFont(43) h.GetYaxis().SetTitleFont(43) h.GetXaxis().SetLabelFont(43) h.GetYaxis().SetLabelFont(43) h.GetXaxis().SetTitleSize(24) h.GetYaxis().SetTitleSize(24) h.GetXaxis().SetLabelSize(20) h.GetYaxis().SetLabelSize(20) if ratio is None: h.GetYaxis().SetTitleOffset( 1.3 ) else: h.GetYaxis().SetTitleOffset( 1.6 ) for modification in histModifications: modification(h) #if drawOption=="e1": dataHist = h h.Draw(drawOption+same) same = "same" topPad.RedrawAxis() # Make the legend if legend is not None: legend_ = ROOT.TLegend(*legendCoordinates) legend_.SetNColumns(legendColumns) legend_.SetFillStyle(0) # legend_.SetFillColor(0) legend_.SetShadowColor(ROOT.kWhite) legend_.SetBorderSize(0) # legend_.SetBorderSize(1) for l in histos: for h in l: if hasattr(h.sample, "notInLegend"): if h.sample.notInLegend: continue if hasattr(h, "texName"): legend_text = h.texName elif hasattr(h, "legendText"): legend_text = h.legendText elif h.sample is not None: legend_text = h.sample.texName if hasattr(h.sample, "texName") else h.sample.name else: continue #legend_text = "No title" legend_.AddEntry(h, legend_text) legend_.Draw() for o in drawObjects: if o: if type(o) in [ ROOT.TF1, ROOT.TGraph ]: o.Draw('same') else: o.Draw() else: logger.debug( "drawObjects has something I can't Draw(): %r", o) # Make a ratio plot if ratio is not None: bottomPad.cd() # Make all the ratio histograms same='' stuff=[] for i_num, i_den in ratio['histos']: num = histos[i_num][0] den = histos[i_den][0] h_ratio = helpers.clone( num ) stuff.append(h_ratio) # For a ratio of profiles, use projection (preserve attributes) if isinstance( h_ratio, ROOT.TProfile ): attrs = h_ratio.__dict__ h_ratio = h_ratio.ProjectionX() h_ratio.__dict__.update( attrs ) h_ratio.Divide( den.ProjectionX() ) else: h_ratio.Divide( den ) #if ratio['style'] is not None: ratio['style'](h_ratio) h_ratio.GetXaxis().SetTitle(plot.texX) h_ratio.GetYaxis().SetTitle(ratio['texY']) h_ratio.GetXaxis().SetTitleFont(43) h_ratio.GetYaxis().SetTitleFont(43) h_ratio.GetXaxis().SetLabelFont(43) h_ratio.GetYaxis().SetLabelFont(43) h_ratio.GetXaxis().SetTitleSize(24) h_ratio.GetYaxis().SetTitleSize(24) h_ratio.GetXaxis().SetLabelSize(20) h_ratio.GetYaxis().SetLabelSize(20) h_ratio.GetXaxis().SetTitleOffset( 3.2 ) h_ratio.GetYaxis().SetTitleOffset( 1.6 ) h_ratio.GetXaxis().SetTickLength( 0.03*3 ) h_ratio.GetYaxis().SetTickLength( 0.03*2 ) h_ratio.GetYaxis().SetRangeUser( *ratio['yRange'] ) h_ratio.GetYaxis().SetNdivisions(505) drawOption = h_ratio.drawOption if hasattr(h_ratio, "drawOption") else "hist" if drawOption == "e1": # hacking to show error bars within panel when central value is off scale graph = ROOT.TGraphAsymmErrors(h_ratio) # cloning in order to get layout graph.Set(0) for bin in range(1, h_ratio.GetNbinsX()+1): # do not show error bars on hist h_ratio.SetBinError(bin, 0.0001) center = h_ratio.GetBinCenter(bin) val = h_ratio.GetBinContent(bin) errUp = num.GetBinErrorUp(bin)/den.GetBinContent(bin) if val > 0 else 0 errDown = num.GetBinErrorLow(bin)/den.GetBinContent(bin) if val > 0 else 0 graph.SetPoint(bin, center, val) graph.SetPointError(bin, 0, 0, errDown, errUp) h_ratio.Draw("e0"+same) graph.Draw("P0 same") stuff.append( graph ) else: h_ratio.Draw(drawOption+same) same = 'same' bottomPad.SetLogx(logX) bottomPad.SetLogy(ratio['logY']) line = ROOT.TPolyLine(2) line.SetPoint(0, h_ratio.GetXaxis().GetXmin(), 1.) line.SetPoint(1, h_ratio.GetXaxis().GetXmax(), 1.) line.SetLineWidth(1) line.Draw() for o in ratio['drawObjects']: if o: o.Draw() else: logger.debug( "ratio['drawObjects'] has something I can't Draw(): %r", o) if not os.path.exists(plot_directory): try: os.makedirs(plot_directory) except OSError: # Resolve rare race condition pass if copyIndexPHP: plot_helpers.copyIndexPHP( plot_directory ) c1.cd() for extension in extensions: filename = plot.name# if plot.name is not None else plot.variable.name #FIXME -> the replacement with variable.name should already be in the Plot constructors ofile = os.path.join( plot_directory, "%s.%s"%(filename, extension) ) c1.Print( ofile ) del c1
def plot1D( dat, var, xmin, xmax ): # get TGraph from results data list xhist = toGraph( var, var, dat ) func = ROOT.TF1("func", polString, xmin, xmax ) xhist.Fit(func,"NO") x68min = func.GetX( 0.989, xmin, 0 ) x68max = func.GetX( 0.989, 0, xmax ) x95min = func.GetX( 3.84, xmin, 0 ) x95max = func.GetX( 3.84, 0, xmax ) xhist.SetLineWidth(0) func.SetFillColor(ROOT.kWhite) func.SetFillStyle(1001) func.SetLineWidth(3) func.SetLineColor(ROOT.kBlack) func.SetNpx(1000) ROOT.gStyle.SetPadLeftMargin(0.14) ROOT.gStyle.SetPadRightMargin(0.1) ROOT.gStyle.SetPadTopMargin(0.11) ROOT.gStyle.SetPadBottomMargin(0.11) # Plot cans = ROOT.TCanvas("cans","cans",500,500) #if not None in args.zRange: xhist.GetYaxis().SetRangeUser( -0.01, 5.5 ) xhist.GetXaxis().SetRangeUser( xmin, xmax ) func95 = ROOT.TF1("func95",polString, x95min,x95max ) xhist.Fit(func95,"NO") func95.SetFillColor(ROOT.kOrange+7) func95.SetFillStyle(1001) func95.SetLineWidth(0) func95.SetNpx(1000) func68 = ROOT.TF1("func68",polString, x68min,x68max ) xhist.Fit(func68,"NO") func68.SetFillColor(ROOT.kSpring-1) func68.SetFillStyle(1001) func68.SetLineWidth(0) func68.SetNpx(1000) func.GetXaxis().SetRangeUser( xmin, xmax ) func68.GetXaxis().SetRangeUser( xmin, xmax ) func95.GetXaxis().SetRangeUser( xmin, xmax ) xhist.Draw("ALO") func.Draw("COSAME") func95.Draw("FOSAME") func68.Draw("FOSAME") # xhist.Draw("LSAME") func.Draw("COSAME") if args.plotData: xhist.Draw("*SAME") # dashed line at 1 line5 = ROOT.TLine(xmin, 0.989, xmax, 0.989 ) line5.SetLineWidth(1) line5.SetLineStyle(7) line5.SetLineColor(ROOT.kBlack) # dashed line at 4 line6 = ROOT.TLine(xmin, 3.84, xmax, 3.84 ) line6.SetLineWidth(1) line6.SetLineStyle(7) line6.SetLineColor(ROOT.kBlack) line5.Draw() line6.Draw() xhist.GetYaxis().SetTitle("-2 #Delta ln L") print x68min, x68max print x95min, x95max funcName = "profiled log-likelihood ratio" leg = ROOT.TLegend(0.3,0.7,0.7,0.87) leg.SetBorderSize(0) leg.SetTextSize(0.035) leg.AddEntry( func, funcName ,"l") leg.AddEntry( func68, "68%s CL [%.2f, %.2f]"%("%",x68min, x68max), "f") leg.AddEntry( func95, "95%s CL [%.2f, %.2f]"%("%",x95min, x95max), "f") leg.Draw() xTitle = var.replace("c", "C_{").replace("I", "}^{[Im]").replace('p','#phi') + '}' xhist.GetXaxis().SetTitle( xTitle + ' (#Lambda/TeV)^{2}' ) xhist.GetXaxis().SetTitleFont(42) xhist.GetYaxis().SetTitleFont(42) xhist.GetXaxis().SetLabelFont(42) xhist.GetYaxis().SetLabelFont(42) # xhist.GetXaxis().SetTitleOffset(1.3) # xhist.GetYaxis().SetTitleOffset(1.3) xhist.GetXaxis().SetTitleSize(0.042) xhist.GetYaxis().SetTitleSize(0.042) xhist.GetXaxis().SetLabelSize(0.04) xhist.GetYaxis().SetLabelSize(0.04) latex1 = ROOT.TLatex() latex1.SetNDC() latex1.SetTextSize(0.035) latex1.SetTextFont(42) latex1.SetTextAlign(11) addon = "" latex1.DrawLatex(0.15, 0.91, '#bf{CMS} #it{Simulation Preliminary} ' + addon), latex1.DrawLatex(0.64, 0.91, '#bf{%3.1f fb{}^{-1} (13 TeV)}' % lumi_scale) # Redraw axis, otherwise the filled graphes overlay cans.RedrawAxis() plotname = "%s%s%s_profiled"%(var, "", "_%s"%args.tag if args.tag != "combined" else "") for e in [".png",".pdf",".root"]: cans.Print( plot_directory_ + "/%s%s"%(plotname, e) ) copyIndexPHP( plot_directory_ )
def plot1D(dat, datExp, var, xmin, xmax): # get TGraph from results data list xhist = toGraph(var, var, dat) xhistExp = toGraph(var + "Exp", var, datExp) # polStringExp = "[0]+[1]*x+[2]*x**2+[3]*x**3+[4]*x**4+[5]*x**5+[6]*x**6+[7]*x**7+[8]*x**8" #+[7]*x**7+[8]*x**8" #+[5]*x**7+[6]*x**8"#+[7]*x**9+[8]*x**10+[9]*x**11+[10]*x**12" polStringExp = "[0]*x**2+[1]*x**3+[2]*x**4+[3]*x**5+[4]*x**6" #+[7]*x**7+[8]*x**8" #+[5]*x**7+[6]*x**8"#+[7]*x**9+[8]*x**10+[9]*x**11+[10]*x**12" polString = "[0]+[1]*x+[2]*x**2+[3]*x**3+[4]*x**4+[5]*x**5+[6]*x**6" #+[7]*x**7+[8]*x**8" #+[5]*x**7+[6]*x**8"#+[7]*x**9+[8]*x**10+[9]*x**11+[10]*x**12" func = ROOT.TF1("func", polString, xmin, xmax) xhist.Fit(func, "NO") ym = func.GetMinimum(xmin, xmax) xm = func.GetX(ym, xmin, xmax) nDat = [] for (x, d) in dat: nDat.append((x, d - ym)) del xhist xhist = toGraph(var, var, nDat) # polString = "[0]*(x-%f)**2+[1]*(x-%f)**3+[2]*(x-%f)**4+[3]*(x-%f)**5+[4]*(x-%f)**6"%(xm,xm,xm,xm,xm) #+[7]*x**9+[8]*x**10+[9]*x**11+[10]*x**12" polString = "[0]*(x-%f)**2+[1]*(x-%f)**3+[2]*(x-%f)**4+[3]*(x-%f)**5+[4]*(x-%f)**6" % ( xm, xm, xm, xm, xm) #+[7]*x**9+[8]*x**10+[9]*x**11+[10]*x**12" del func dat = nDat func = ROOT.TF1("func", polString, xmin, xmax) xhist.Fit(func, "NO") x68min = func.GetX(0.989, xmin, xm) x68max = func.GetX(0.989, xm, xmax) ym2 = func.GetMinimum(xmin, 0) xm2 = func.GetX(ym2, xmin, 0) x68pmin = func.GetX(0.989, xmin, xm2) x68pmax = func.GetX(0.989, xm2, 0) if args.year == 2016 and args.inclRegion and (args.useChannels and args.useChannels[0] == "mu"): ym = func.GetMinimum(0, xmax) xm = func.GetX(ym, 0, xmax) x68min = func.GetX(0.989, 0, xm) x68max = func.GetX(0.989, xm, xmax) ym2 = func.GetMinimum(xmin, 0) xm2 = func.GetX(ym2, xmin, 0) x68pmin = func.GetX(0.989, xmin, xm2) x68pmax = func.GetX(0.989, xm2, 0) if args.variables == "ctZI" and (args.year == 2018 or args.year == "RunII") and not args.inclRegion: ym2 = func.GetMinimum(0, xmax) xm2 = func.GetX(ym2, 0, xmax) x68pmin = func.GetX(0.989, 0, xm2) x68pmax = func.GetX(0.989, xm2, xmax) x68min = func.GetX(0.989, xmin, xm) x68max = func.GetX(0.989, xm, 0) # x68maxNew = func.GetX( 0.989, x68max+0.005, xmax ) # ij = 0 # while x68maxNew != x68max and ij < 10: # ij +=1 # x68max = x68maxNew # x68maxNew = func.GetX( 0.989, x68max+0.005, xmax ) # x68max = x68maxNew x95min = func.GetX(3.84, xmin, xm) x95max = func.GetX(3.84, xm, xmax) if (args.year == 2018 or (args.year == "RunII" and args.variables == "ctZ") ) and not args.inclRegion and not args.withbkg: x95min = func.GetX(3.84, xmin, xm) x95max = func.GetX(3.84, xm, 0) ym2 = func.GetMinimum(0.01, xmax) xm2 = func.GetX(ym2, 0.01, xmax) x95pmin = func.GetX(3.84, 0.01, xm2) x95pmax = func.GetX(3.84, xm2, xmax) print "68min", x68min print "68max", x68max print "68min", x68pmin print "68max", x68pmax print "95min", x95min print "95max", x95max sys.exit() xhist.SetLineWidth(0) func.SetFillColor(ROOT.kWhite) func.SetFillStyle(1001) func.SetLineWidth(3) func.SetLineColor(ROOT.kBlack) func.SetNpx(1000) funcExp = ROOT.TF1("funcExp", polStringExp, xmin, xmax) xhistExp.Fit(funcExp, "NO") x68minExp = funcExp.GetX(0.989, xmin, 0) x68maxExp = funcExp.GetX(0.989, 0, xmax) x95minExp = funcExp.GetX(3.84, xmin, 0) x95maxExp = funcExp.GetX(3.84, 0, xmax) xhistExp.SetLineWidth(0) funcExp.SetFillColor(ROOT.kWhite) funcExp.SetFillStyle(1001) funcExp.SetLineWidth(3) # funcExp.SetLineStyle(11) funcExp.SetLineColor(ROOT.kGray + 1) funcExp.SetNpx(1000) ROOT.gStyle.SetPadLeftMargin(0.14) ROOT.gStyle.SetPadRightMargin(0.1) ROOT.gStyle.SetPadTopMargin(0.11) ROOT.gStyle.SetPadBottomMargin(0.11) # Plot cans = ROOT.TCanvas("cans", "cans", 500, 500) #if not None in args.zRange: xhist.GetYaxis().SetRangeUser(0, 5.5) xhist.GetXaxis().SetRangeUser(xmin, xmax) # xhist.GetXaxis().SetLimits(xmin, xmax) func95 = ROOT.TF1("func95", polString, x95min, x95max) xhist.Fit(func95, "NO") func95.SetFillColor(ROOT.kOrange + 7) func95.SetFillStyle(1001) func95.SetLineWidth(0) func95.SetNpx(1000) if (args.year == 2018 or (args.year == "RunII" and args.variables == "ctZ") ) and not args.inclRegion and not args.withbkg: func95p = ROOT.TF1("func95p", polString, x95pmin, x95pmax) xhist.Fit(func95p, "NO") func95p.SetFillColor(ROOT.kOrange + 7) func95p.SetFillStyle(1001) func95p.SetLineWidth(0) func95p.SetNpx(1000) func68 = ROOT.TF1("func68", polString, x68min, x68max) xhist.Fit(func68, "NO") func68.SetFillColor(ROOT.kSpring - 1) func68.SetFillStyle(1001) func68.SetLineWidth(0) func68.SetNpx(1000) func68p = ROOT.TF1("func68p", polString, x68pmin, x68pmax) xhist.Fit(func68p, "NO") func68p.SetFillColor(ROOT.kSpring - 1) func68p.SetFillStyle(1001) func68p.SetLineWidth(0) func68p.SetNpx(1000) func.GetXaxis().SetRangeUser(xmin, xmax) func68.GetXaxis().SetRangeUser(xmin, xmax) func68p.GetXaxis().SetRangeUser(xmin, xmax) func95.GetXaxis().SetRangeUser(xmin, xmax) if (args.year == 2018 or (args.year == "RunII" and args.variables == "ctZ") ) and not args.inclRegion and not args.withbkg: func95p.GetXaxis().SetRangeUser(xmin, xmax) func.GetYaxis().SetRangeUser(0, 5) func68.GetYaxis().SetRangeUser(0, 5) func68p.GetYaxis().SetRangeUser(0, 5) func95.GetYaxis().SetRangeUser(0, 5) func95Exp = ROOT.TF1("func95Exp", polStringExp, x95minExp, x95maxExp) xhistExp.Fit(func95Exp, "NO") func95Exp.SetFillColor(ROOT.kGray + 2) func95Exp.SetFillStyle(1001) func95Exp.SetLineWidth(0) func95Exp.SetNpx(1000) func68Exp = ROOT.TF1("func68Exp", polStringExp, x68minExp, x68maxExp) xhistExp.Fit(func68Exp, "NO") func68Exp.SetFillColor(ROOT.kGray + 1) func68Exp.SetFillStyle(1001) func68Exp.SetLineWidth(0) func68Exp.SetNpx(1000) funcExp.GetXaxis().SetRangeUser(xmin, xmax) func68Exp.GetXaxis().SetRangeUser(xmin, xmax) func95Exp.GetXaxis().SetRangeUser(xmin, xmax) funcExp.GetYaxis().SetRangeUser(0, 5) func68Exp.GetYaxis().SetRangeUser(0, 5) func95Exp.GetYaxis().SetRangeUser(0, 5) xhist.Draw("ALO") # func95Exp.Draw("FOSAME") # func68Exp.Draw("FOSAME") func.Draw("COSAME") func95.Draw("FOSAME") if (args.year == 2018 or (args.year == "RunII" and args.variables == "ctZ") ) and not args.inclRegion and not args.withbkg: func95p.Draw("FOSAME") func68.Draw("FOSAME") if args.variables == "ctZ" and args.year == 2016 and args.inclRegion: func68p.Draw("FOSAME") if args.year == 2016 and args.inclRegion and (args.useChannels and args.useChannels[0] == "mu"): func68p.Draw("FOSAME") if args.variables == "ctZI" and (args.year == 2018 or args.year == "RunII") and not args.inclRegion: func68p.Draw("FOSAME") xhist.Draw("LSAME") funcExp.Draw("COSAME") func.Draw("COSAME") if args.plotData: xhist.Draw("*SAME") if args.plotData: xhistExp.Draw("*SAME") # dashed line at 1 line5 = ROOT.TLine(xmin, 0.989, xmax, 0.989) line5.SetLineWidth(1) line5.SetLineStyle(7) line5.SetLineColor(ROOT.kBlack) # dashed line at 4 line6 = ROOT.TLine(xmin, 3.84, xmax, 3.84) line6.SetLineWidth(1) line6.SetLineStyle(7) line6.SetLineColor(ROOT.kBlack) line5.Draw() line6.Draw() xhist.GetYaxis().SetTitle("-2 #Delta ln L") print x68min, x68max print x95min, x95max if "%.2f" % x68pmax == "%.2f" % x68min: x68min = x68pmin # funcName = "Log-likelihood ratio" funcName = "" if args.variables == "ctZ" and args.year == 2016 and args.inclRegion and x68pmin != x68min: leg = ROOT.TLegend(0.17, 0.7, 0.85, 0.87) elif args.year == 2016 and args.inclRegion and ( args.useChannels and args.useChannels[0] == "mu"): leg = ROOT.TLegend(0.17, 0.7, 0.85, 0.87) elif (args.year == 2018 or args.year == "RunII") and not args.inclRegion: # leg = ROOT.TLegend(0.17,0.7,0.85,0.87) # if args.variables == "ctZ": # leg = ROOT.TLegend(0.23,0.7,0.85,0.889) # else: # leg = ROOT.TLegend(0.16,0.7,0.85,0.889) leg = ROOT.TLegend(0.35, 0.67, 0.73, 0.85) else: leg = ROOT.TLegend(0.32, 0.7, 0.8, 0.87) empt = ROOT.TObject() leg.SetNColumns(2) leg.SetBorderSize(0) leg.SetTextSize(0.037) leg.AddEntry(func, "Observed", "l") leg.AddEntry(func68, "68%s CL" % ("%"), "f") leg.AddEntry(funcExp, "Expected", "l") leg.AddEntry(func95, "95%s CL" % ("%"), "f") leg.AddEntry(empt, "individual", "") # if args.variables == "ctZ" and args.year == 2016 and args.inclRegion and x68pmin != x68min: # leg.AddEntry( func68, "68%s CL (observed) [%.2f, %.2f], [%.2f, %.2f]"%("%",x68pmin, x68pmax, x68min, x68max), "f") # elif args.year == 2016 and args.inclRegion and (args.useChannels and args.useChannels[0]=="mu"): # leg.AddEntry( func68, "68%s CL (observed) [%.2f, %.2f], [%.2f, %.2f]"%("%",x68pmin, x68pmax, x68min, x68max), "f") # elif args.variables == "ctZI" and (args.year == 2018 or args.year == "RunII") and not args.inclRegion: # leg.AddEntry( func68, "68%s CL (observed) [%.2f, %.2f], [%.2f, %.2f]"%("%",x68min, x68max, x68pmin, x68pmax), "f") # else: # leg.AddEntry( func68, "68%s CL (observed) [%.2f, %.2f]"%("%",x68min, x68max), "f") # if (args.year == 2018 or (args.year == "RunII" and args.variables == "ctZ")) and not args.inclRegion and not args.withbkg: # leg.AddEntry( func95, "95%s CL (observed) [%.2f, %.2f], [%.2f, %.2f]"%("%",x95min, x95max,x95pmin,x95pmax), "f") # else: # leg.AddEntry( func95, "95%s CL (observed) [%.2f, %.2f]"%("%",x95min, x95max), "f") # leg.AddEntry( func68Exp, "68%s CL (Exp) [%.2f, %.2f]"%("%",x68minExp, x68maxExp), "f") # leg.AddEntry( func95Exp, "95%s CL (Exp) [%.2f, %.2f]"%("%",x95minExp, x95maxExp), "f") # leg2 = ROOT.TLegend(0.17,0.7,0.85,0.889) # leg2.SetBorderSize(0) # leg2.Draw() leg.Draw() xTitle = var.replace("c", "c_{").replace("I", "}^{I").replace('p', '#phi') + '}' xhist.GetXaxis().SetTitle(xTitle + ' [(#Lambda/TeV^{2})]') xhist.GetXaxis().SetTitleFont(42) xhist.GetYaxis().SetTitleFont(42) xhist.GetXaxis().SetLabelFont(42) xhist.GetYaxis().SetLabelFont(42) xhist.GetXaxis().SetTitleOffset(1.1) xhist.GetYaxis().SetTitleOffset(0.85) xhist.GetXaxis().SetTitleSize(0.042) xhist.GetYaxis().SetTitleSize(0.042) xhist.GetXaxis().SetLabelSize(0.04) xhist.GetYaxis().SetLabelSize(0.04) latex1 = ROOT.TLatex() latex1.SetNDC() latex1.SetTextSize(0.035) latex1.SetTextFont(42) latex1.SetTextAlign(11) latex2 = ROOT.TLatex() latex2.SetNDC() latex2.SetTextSize(0.05) latex2.SetTextFont(42) latex2.SetTextAlign(11) addon = "" # latex2.DrawLatex(0.15, 0.91, '#bf{CMS} #it{Preliminary} ' + addon), latex2.DrawLatex(0.15, 0.91, '#bf{CMS} ' + addon), if isinstance(lumi_scale, int): latex1.DrawLatex(0.67, 0.91, '#bf{%i fb^{-1} (13 TeV)}' % lumi_scale) else: latex1.DrawLatex(0.65, 0.91, '#bf{%3.1f fb^{-1} (13 TeV)}' % lumi_scale) # Redraw axis, otherwise the filled graphes overlay cans.RedrawAxis() plotname = "%s%s%s_wExp" % (var, "", "_%s" % args.tag if args.tag != "combined" else "") if args.withbkg: plotname += "_wBkg" if args.withEFTUnc: plotname += "_wEFTUnc" for e in [".png", ".pdf", ".root"]: cans.Print(plot_directory_ + "/%s%s" % (plotname, e)) copyIndexPHP(plot_directory_)
return result # input analysis_results = '../workflow/results/' defFile = os.path.join(analysis_results, "%s.pkl"%options.signal) print defFile lumi = 137 plot_directory = os.path.abspath('/home/users/dspitzba/public_html/Stop_Run2/%s/v5/'%options.signal) plotDir = os.path.join(plot_directory,'limits') if options.smooth: plotDir += "_smooth_it%s_%s"%(options.iterations, options.smoothAlgo) import RootTools.plot.helpers as plot_helpers plot_helpers.copyIndexPHP( plotDir ) if not os.path.exists(plotDir): os.makedirs(plotDir) graphs = {} hists = {} #nbins = 50 #nbins = 210 nbins = 135 # bin size 10 GeV import pickle import pandas as pd import numpy as np results = pickle.load(file(defFile, 'r'))
def plot1D( dat, var, xmin, xmax ): # get TGraph from results data list xhist = toGraph( var, var, dat ) # polString = "[0]+[1]*x+[2]*x**2+[3]*x**3+[4]*x**4+[5]*x**5+[6]*x**6+[7]*x**7+[8]*x**8" #+[7]*x**7+[8]*x**8" #+[5]*x**7+[6]*x**8"#+[7]*x**9+[8]*x**10+[9]*x**11+[10]*x**12" # polString = "[0]+[1]*x+[2]*x**2+[3]*x**3+[4]*x**4+[5]*x**5+[6]*x**6" #+[7]*x**9+[8]*x**10+[9]*x**11+[10]*x**12" func = ROOT.TF1("func", polString, xmin, xmax ) xhist.Fit(func,"NO") ym = func.GetMinimum(xmin, xmax) xm = func.GetX(ym, xmin, xmax ) # nDat = [] # for (x,d) in dat: nDat.append((x,d-ym)) # del xhist # xhist = toGraph( var, var, nDat ) # polString = "[0]*(x-%f)**2+[1]*(x-%f)**3+[2]*(x-%f)**4+[3]*(x-%f)**5+[4]*(x-%f)**6"%(xm,xm,xm,xm,xm) #+[7]*x**9+[8]*x**10+[9]*x**11+[10]*x**12" # polString = "[0]*(x-%f)**2+[1]*(x-%f)**3+[2]*(x-%f)**4+[3]*(x-%f)**5+[4]*(x-%f)**6"%(xm,xm,xm,xm,xm) #+[7]*x**9+[8]*x**10+[9]*x**11+[10]*x**12" # del func # func = ROOT.TF1("func", polString, xmin, xmax ) # xhist.Fit(func,"NO") x68min = func.GetX( 0.989, xmin, xm ) x68max = func.GetX( 0.989, xm, xmax ) # x68max = func.GetX( 0.989, xm, xmax ) # x68maxNew = func.GetX( 0.989, x68max+0.01, xmax ) # print xmax # print x68maxNew # while x68maxNew != x68max: # x68max = x68maxNew # x68maxNew = func.GetX( 0.989, x68max, xmax ) # print x68maxNew # x68max = x68maxNew x95min = func.GetX( 3.84, xmin, xm ) x95max = func.GetX( 3.84, xm, xmax ) print xm, x68min, x68max xhist.SetLineWidth(0) func.SetFillColor(ROOT.kWhite) func.SetFillStyle(1001) func.SetLineWidth(3) func.SetLineColor(ROOT.kBlack) func.SetNpx(1000) ROOT.gStyle.SetPadLeftMargin(0.14) ROOT.gStyle.SetPadRightMargin(0.1) ROOT.gStyle.SetPadTopMargin(0.11) ROOT.gStyle.SetPadBottomMargin(0.11) # Plot cans = ROOT.TCanvas("cans","cans",500,500) #if not None in args.zRange: xhist.GetYaxis().SetRangeUser( 0, 15.5 ) xhist.GetXaxis().SetRangeUser( xmin, xmax ) # xhist.GetXaxis().SetLimits(xmin, xmax) func95 = ROOT.TF1("func95",polString, x95min,x95max ) xhist.Fit(func95,"NO") func95.SetFillColor(ROOT.kOrange+7) func95.SetFillStyle(1001) func95.SetLineWidth(0) func95.SetNpx(1000) func68 = ROOT.TF1("func68",polString, x68min,x68max ) xhist.Fit(func68,"NO") func68.SetFillColor(ROOT.kSpring-1) func68.SetFillStyle(1001) func68.SetLineWidth(0) func68.SetNpx(1000) func.GetXaxis().SetRangeUser( xmin, xmax ) func68.GetXaxis().SetRangeUser( xmin, xmax ) func95.GetXaxis().SetRangeUser( xmin, xmax ) xhist.Draw("ALO") func.Draw("COSAME") func95.Draw("FOSAME") func68.Draw("FOSAME") # xhist.Draw("LSAME") func.Draw("COSAME") if args.plotData: xhist.Draw("*SAME") # dashed line at 1 line5 = ROOT.TLine(xmin, 0.989, xmax, 0.989 ) line5.SetLineWidth(1) line5.SetLineStyle(7) line5.SetLineColor(ROOT.kBlack) # dashed line at 4 line6 = ROOT.TLine(xmin, 3.84, xmax, 3.84 ) line6.SetLineWidth(1) line6.SetLineStyle(7) line6.SetLineColor(ROOT.kBlack) line5.Draw() line6.Draw() xhist.GetYaxis().SetTitle("-2 #Delta ln L") print x68min, x68max print x95min, x95max funcName = "Log-likelihood ratio" leg = ROOT.TLegend(0.3,0.7,0.7,0.87) leg.SetBorderSize(0) leg.SetTextSize(0.035) leg.AddEntry( func, funcName ,"l") leg.AddEntry( func68, "68%s CL [%.2f, %.2f]"%("%",x68min, x68max), "f") leg.AddEntry( func95, "95%s CL [%.2f, %.2f]"%("%",x95min, x95max), "f") leg.Draw() xTitle = var.replace("c", "c_{").replace("I", "}^{I").replace('p','#phi') + '}' xhist.GetXaxis().SetTitle( xTitle + ' [(#Lambda/TeV)^{2}]' ) xhist.GetXaxis().SetTitleFont(42) xhist.GetYaxis().SetTitleFont(42) xhist.GetXaxis().SetLabelFont(42) xhist.GetYaxis().SetLabelFont(42) # xhist.GetXaxis().SetTitleOffset(1.3) # xhist.GetYaxis().SetTitleOffset(1.3) xhist.GetXaxis().SetTitleSize(0.042) xhist.GetYaxis().SetTitleSize(0.042) xhist.GetXaxis().SetLabelSize(0.04) xhist.GetYaxis().SetLabelSize(0.04) latex1 = ROOT.TLatex() latex1.SetNDC() latex1.SetTextSize(0.035) latex1.SetTextFont(42) latex1.SetTextAlign(11) addon = "" if args.expected: # latex1.DrawLatex(0.15, 0.91, '#bf{CMS} #it{Simulation Preliminary} ' + addon), latex1.DrawLatex(0.15, 0.91, '#bf{CMS} #it{Simulation} ' + addon), else: # latex1.DrawLatex(0.15, 0.91, '#bf{CMS} #it{Preliminary} ' + addon), latex1.DrawLatex(0.15, 0.91, '#bf{CMS} ' + addon), if isinstance(lumi_scale, int): latex1.DrawLatex(0.70, 0.91, '#bf{%i fb^{-1} (13 TeV)}' % lumi_scale) else: latex1.DrawLatex(0.68, 0.91, '#bf{%3.1f fb^{-1} (13 TeV)}' % lumi_scale) # Redraw axis, otherwise the filled graphes overlay cans.RedrawAxis() plotname = "%s%s%s"%(var, "", "_%s"%args.tag if args.tag != "combined" else "") if args.withbkg: plotname += "_wBkg" if args.withEFTUnc: plotname += "_wEFTUnc" for e in [".png",".pdf",".root"]: cans.Print( plot_directory_ + "/%s%s"%(plotname, e) ) copyIndexPHP( plot_directory_ )