import ROOT as r import json import numpy as np import copy import os import sys import Dumbledraw.styles as styles r.gROOT.SetBatch() r.gStyle.SetOptStat(0) styles.ModTDRStyle() r.gStyle.SetTitleSize(0.045, 'XYZ') era = sys.argv[1] outfoldername = sys.argv[2] f = r.TFile.Open("shapes_mm_recoil_%s.root" % era) if not os.path.exists(outfoldername): os.mkdir(outfoldername) fout = r.TFile.Open("%s/Type1_PFMET_%s.root" % (outfoldername, era), "recreate") foutpuppi = r.TFile.Open("%s/Type1_PuppiMET_%s.root" % (outfoldername, era), "recreate") r.gROOT.SetBatch() hist_names = sorted([ k.GetName() for k in f.GetListOfKeys() if "_ss" not in k.GetName() and "output_tree" not in k.GetName()
def main(args): styles.ModTDRStyle(l=0.14, b=0.12) # Read in input root file. if not os.path.exists(args.input): print("Input file {} does not exist.".format(args.input)) raise ValueError infile = ROOT.TFile(args.input, "read") # Load the fit results if args.separate_nominal_fit is None: fit_nominal = infile.Get("fit_nominal") else: if not os.path.exists(args.separate_nominal_fit): print("Input file {} for separate fit does not exist.".format(args.input)) raise ValueError infile_separate = ROOT.TFile(args.separate_nominal_fit, "read") fit_nominal = infile_separate.Get("fit_nominal") fit_alternate = infile.Get("fit_alternate") # Get POI result RooFit object res_poi = fit_nominal.floatParsFinal().find(args.poi) # Get number of channels from fit result prefix = "_ChannelCompatibilityCheck_{}_".format(args.poi) parameters = fit_alternate.floatParsFinal() num_pars = parameters.getSize() channels = [parameters.at(x).GetName() for x in range(num_pars) if parameters.at(x).GetName().startswith(prefix)] num_chans = len(channels) print(channels) if '_pt_' in channels[1]: styles.ModTDRStyle(l=0.22, b=0.12) canv = ROOT.TCanvas("canv") # Create the plot object. axis_label = "#sigma#font[42]{{({}#phi)}}#font[52]{{B}}#font[42]{{(#phi#rightarrow#tau#tau)}} (pb)".format("gg" if "gg" in args.poi else "bb") frame = ROOT.TH2F("frame", ";{};".format(axis_label), 1, # res_poi.getVal() + 5*res_poi.getAsymErrorLo(), args.frame_range[0], args.frame_range[1], num_chans, 0, num_chans ) print("Nominal fit: {} {}/+{}".format(res_poi.getVal(), res_poi.getAsymErrorLo(), res_poi.getAsymErrorHi())) # Fill TGraphAsymmErrors with fit values. points = ROOT.TGraphAsymmErrors(num_chans) if "htt" in channels[0]: chan_it = sorted(channels) else: chan_it = reversed(sorted(channels)) if '_pt_' in channels[1]: channels_sorted = range(5) for c in channels: if 'btag' in c: channels_sorted[4] = c if '0to50' in c: channels_sorted[3] = c if '50to100' in c: channels_sorted[2] = c if '100to200' in c: channels_sorted[1] = c if 'GT200' in c: channels_sorted[0] = c chan_it = channels_sorted for i, ch_ in enumerate(chan_it): ri = parameters.find(ch_) points.SetPoint(i, ri.getVal(), i+0.5) points.SetPointError(i, -ri.getAsymErrorLo(), ri.getAsymErrorHi(), 0, 0) print("Alternate fit: ", ch_, ri.getVal()) frame.GetYaxis().SetBinLabel(i+1, label_dict[ch_.replace(prefix, "")]) if "htt" not in channels[0] and '_pt_' not in channels[1]: frame.GetYaxis().SetRangeUser(0, num_chans+0.5) points.SetLineColor(ROOT.kBlack) points.SetLineWidth(3) points.SetMarkerStyle(20) points.SetMarkerSize(1.3) # frame.GetXaxis().SetNdivisions(505) frame.GetXaxis().SetTitleSize(0.05) frame.GetXaxis().SetLabelSize(0.04) if '_pt_' in channels[1]: frame.GetYaxis().SetLabelSize(0.04) else: frame.GetYaxis().SetLabelSize(0.06) frame.Draw() # ROOT.gStyle.SetOptStat(0) globalFitBand = ROOT.TBox(res_poi.getVal()+res_poi.getAsymErrorLo(), 0, res_poi.getVal()+res_poi.getAsymErrorHi(), num_chans) globalFitBand.SetFillStyle(1001) # globalFitBand.SetFillColor(17) # globalFitBand.SetFillColor(ROOT.TColor.GetColor("#034732")) globalFitBand.SetFillColor(ROOT.TColor.GetColor("#73a3d4")) globalFitBand.SetLineStyle(0) globalFitBand.SetLineColor(ROOT.TColor.GetColor("#73a3d4")) globalFitBand.Draw("same") globalFitLine = ROOT.TLine(res_poi.getVal(), 0, res_poi.getVal(), num_chans) globalFitLine.SetLineWidth(3) # globalFitLine.SetLineColor(12) globalFitLine.SetLineColor(ROOT.TColor.GetColor("#1d3d5e")) globalFitLine.Draw("same") points.Draw("0PZ SAME") ROOT.gPad.SetTickx() ROOT.gPad.SetTicky() ROOT.gPad.RedrawAxis() if "htt" not in channels[0] and '_pt_' not in channels[1]: # l = 0.14, r = 0.04 legend = ROOT.TLegend(0.25, 0.80, 0.85, 0.88) elif '_pt_' in channels[1]: legend = ROOT.TLegend(0.24, 0.77, 0.46, 0.92) legend.SetFillStyle(0) else: if args.legend_position == 0: legend = ROOT.TLegend(0.18, 0.77, 0.48, 0.92) elif args.legend_position == 1: legend = ROOT.TLegend(0.65, 0.77, 0.95, 0.92) elif args.legend_position == 2: legend = ROOT.TLegend(0.65, 0.13, 0.95, 0.28) else: legend = ROOT.TLegend(0.18, 0.13, 0.48, 0.28) legend.AddEntry(globalFitLine, "Global Best Fit", "l") legend.AddEntry(globalFitBand, "Global Best Fit #pm 1 #sigma", "f") legend.SetTextSize(0.032) if "htt" not in channels[0] and '_pt_' not in channels[1]: legend.SetNColumns(2) legend.Draw() extra_ts = 0.030 limit_tree = infile.Get("limit") limit_tree.GetEntry(0) latex2 = ROOT.TLatex() latex2.SetNDC() latex2.SetTextAngle(0) latex2.SetTextColor(ROOT.kBlack) latex2.SetTextSize(extra_ts) begin_left = 0.200 begin_right = 0.68 up_pos = 0.690 spacing = 0.04 low_pos = 0.470 # latex2.DrawLatex(begin_left, 0.360, "#chi^{{2}}-like = {:.3f}".format(limit_tree.limit)) # latex2.DrawLatex(begin_left, 0.640, "#chi^{{2}}-like = {:.3f}".format(limit_tree.limit)) # test_stat = "-2 ln #frac{L(n|#hat{#mu})}{L(n|{#hat{#mu}_{k}})}" # if args.legend_position == 0: # latex2.DrawLatex(begin_left, up_pos-spacing, "{} = {:.2f}".format(test_stat, limit_tree.limit)) # elif args.legend_position == 1: # latex2.DrawLatex(begin_right, up_pos-spacing, "{} = {:.2f}".format(test_stat, limit_tree.limit)) # elif args.legend_position == 2: # latex2.DrawLatex(begin_right, low_pos-spacing, "{} = {:.2f}".format(test_stat, limit_tree.limit)) # else: # latex2.DrawLatex(begin_left, low_pos-spacing, "{} = {:.2f}".format(test_stat, limit_tree.limit)) # Draw mass of Higgs boson outside of frame if args.mass is not None: mass_label = "#font[42]{m_{#phi} = %s GeV}" % args.mass if '_pt_' in channels[1]: latex2.DrawLatex(0.26, up_pos, mass_label) elif args.legend_position == 0: latex2.DrawLatex(begin_left, up_pos, mass_label) elif args.legend_position == 1: latex2.DrawLatex(begin_right, up_pos, mass_label) elif args.legend_position == 2: latex2.DrawLatex(begin_right, low_pos, mass_label) elif args.legend_position == 3: latex2.DrawLatex(begin_left, low_pos, mass_label) if args.toy_json is not None: if args.mass is None: raise ValueError("Mass needs to be given for readout of json") with open(args.toy_json, "r") as fi: res = json.load(fi)["{}.0".format(args.mass)] label = "#font[42]{{p-value = {:.2f}}}".format(res["p"]) if '_pt_' in channels[1]: latex2.DrawLatex(0.26, up_pos-1*spacing, label) elif args.legend_position == 0: latex2.DrawLatex(begin_left, up_pos-1*spacing, label) elif args.legend_position == 1: latex2.DrawLatex(begin_right, up_pos-1*spacing, label) elif args.legend_position == 2: latex2.DrawLatex(begin_right, low_pos-1*spacing, label) elif args.legend_position == 3: latex2.DrawLatex(begin_left, low_pos-1*spacing, label) # Draw CMS logo in upper left corner cms_outside = True if cms_outside: styles.DrawCMSLogo(canv, 'CMS', 'Supplementary', 0, 0.095, 0.05, 1.0, '', 0.6) else: styles.DrawCMSLogo(canv, 'CMS', 'Supplementary', 11, 0.045, 0.05, 1.0, '', 0.6) # Draw luminosity label styles.DrawTitle(canv, "138 fb^{-1} (13 TeV)", 3, 0.6) canv.Print(args.output + ".png", "png") canv.Print(args.output + ".pdf", "pdf") return