def makestack(lep_, reg_, variabile_, samples_, cut_tag_, syst_, lumi): os.system('set LD_PRELOAD=libtcmalloc.so') if variabile_._name == 'WprAK8_tau2/WprAK8_tau1': variabile_._name = 'WprAK8_tau21' elif variabile_._name == 'WprAK8_tau3/WprAK8_tau2': variabile_._name = 'WprAK8_tau32' blind = False infile = {} histo = [] tmp = ROOT.TH1F() h = ROOT.TH1F() hdata = ROOT.TH1F('h', 'h', variabile_._nbins, variabile_._xmin, variabile_._xmax) h_sig = [] h_err = ROOT.TH1F() h_bkg_err = ROOT.TH1F() print "Variabile:", variabile_._name ROOT.gROOT.SetStyle('Plain') ROOT.gStyle.SetPalette(1) ROOT.gStyle.SetOptStat(0) ROOT.TH1.SetDefaultSumw2() if (cut_tag_ == ""): histoname = "h_" + reg_ + "_" + variabile_._name stackname = "stack_" + reg_ + "_" + variabile_._name canvasname = "stack_" + reg_ + "_" + variabile_._name + "_" + lep_ + "_" + str( samples_[0].year) else: histoname = "h_" + reg_ + "_" + variabile_._name + "_" + cut_tag_ stackname = "stack_" + reg_ + "_" + variabile_._name + "_" + cut_tag_ canvasname = "stack_" + reg_ + "_" + variabile_._name + "_" + cut_tag_ + "_" + lep_ + "_" + str( samples_[0].year) if ("selection_AND_best_Wpjet_isbtag_AND_best_topjet_isbtag" in cut_tag_ ) or ("selection_AND_best_topjet_isbtag_AND_best_Wpjet_isbtag" in cut_tag_): blind = True stack = ROOT.THStack(stackname, variabile_._name) leg_stack = ROOT.TLegend(0.33, 0.62, 0.91, 0.87) signal = False print samples_ for s in samples_: if ('WP' in s.label): signal = True if (syst_ == ""): outfile = plotrepo + "stack_" + str(lep_).strip('[]') + ".root" infile[s.label] = ROOT.TFile.Open(plotrepo + "plot/" + lep + "/" + s.label + "_" + lep + ".root") else: outfile = plotrepo + "stack_" + syst_ + "_" + str(lep_).strip( '[]') + ".root" infile[s.label] = ROOT.TFile.Open(plotrepo + "plot/" + lep + "/" + s.label + "_" + lep + "_" + syst_ + ".root") i = 0 for s in samples_: infile[s.label].cd() print "opening file: ", infile[s.label].GetName() if ('Data' in s.label): if ("GenPart" in variabile_._name) or ("MC_" in variabile_._name): continue tmp = (ROOT.TH1F)(infile[s.label].Get(histoname)) tmp.SetLineColor(ROOT.kBlack) tmp.SetName(s.leglabel) if ('Data' in s.label): if ("GenPart" in variabile_._name) or ("MC_" in variabile_._name): continue hdata.Add(ROOT.TH1F(tmp.Clone(""))) hdata.SetMarkerStyle(20) hdata.SetMarkerSize(0.9) if (i == 0 and not blind): # trick to add Data flag to legend only once leg_stack.AddEntry(hdata, "Data", "ep") i += 1 elif ('WP' in s.label): #tmp.SetLineStyle(9) if opt.tostack: tmp.SetLineColor(s.color) else: tmp.SetLineColor(s.color) #tmp.SetLineWidth(3) tmp.SetMarkerSize(0.) tmp.SetMarkerColor(s.color) h_sig.append(ROOT.TH1F(tmp.Clone(""))) else: tmp.SetOption("HIST SAME") tmp.SetTitle("") if opt.tostack: tmp.SetFillColor(s.color) else: tmp.SetLineColor(s.color) histo.append(tmp.Clone("")) stack.Add(tmp.Clone("")) tmp.Reset("ICES") for hist in reversed(histo): if not ('Data' in hist.GetName()): leg_stack.AddEntry(hist, hist.GetName(), "f") #style options print "Is it blind? " + str(blind) leg_stack.SetNColumns(2) leg_stack.SetFillColor(0) leg_stack.SetFillStyle(0) leg_stack.SetTextFont(42) leg_stack.SetBorderSize(0) leg_stack.SetTextSize(0.05) c1 = ROOT.TCanvas(canvasname, "c1", 50, 50, 700, 600) c1.SetFillColor(0) c1.SetBorderMode(0) c1.SetFrameFillStyle(0) c1.SetFrameBorderMode(0) c1.SetLeftMargin(0.12) c1.SetRightMargin(0.9) c1.SetTopMargin(1) c1.SetBottomMargin(-1) c1.SetTickx(1) c1.SetTicky(1) c1.cd() pad1 = ROOT.TPad("pad1", "pad1", 0, 0.31, 1, 1) pad1.SetTopMargin(0.1) pad1.SetBottomMargin(0.02) pad1.SetLeftMargin(0.12) pad1.SetRightMargin(0.05) pad1.SetBorderMode(0) pad1.SetTickx(1) pad1.SetTicky(1) pad1.Draw() pad1.cd() if not blind: maximum = max(stack.GetMaximum(), hdata.GetMaximum()) else: maximum = stack.GetMaximum() logscale = True # False # if (logscale): pad1.SetLogy() stack.SetMaximum(maximum * 1000) else: stack.SetMaximum(maximum * 1.6) stack.SetMinimum(0.01) if opt.tostack: stack.Draw("HIST") else: stack.Draw("HIST NOSTACK") step = float(variabile_._xmax - variabile_._xmin) / float( variabile_._nbins) print str(step) if "GeV" in variabile_._title: if step.is_integer(): ytitle = "Events / %.0f GeV" % step else: ytitle = "Events / %.2f GeV" % step else: if step.is_integer(): ytitle = "Events / %.0f units" % step else: ytitle = "Events / %.2f units" % step stack.GetYaxis().SetTitle(ytitle) stack.GetYaxis().SetTitleFont(42) stack.GetXaxis().SetLabelOffset(1.8) stack.GetYaxis().SetTitleOffset(0.85) stack.GetXaxis().SetLabelSize(0.15) stack.GetYaxis().SetLabelSize(0.07) stack.GetYaxis().SetTitleSize(0.07) stack.SetTitle("") if (signal): for hsig in h_sig: #hsig.Scale(1000) hsig.Draw("same") leg_stack.AddEntry(hsig, hsig.GetName(), "l") h_err = stack.GetStack().Last().Clone("h_err") h_err.SetLineWidth(100) h_err.SetFillStyle(3154) h_err.SetMarkerSize(0) h_err.SetFillColor(ROOT.kGray + 2) h_err.Draw("e2same0") leg_stack.AddEntry(h_err, "Stat. Unc.", "f") if not blind: print(hdata.Integral()) hdata.Draw("eSAMEpx0") else: hdata = stack.GetStack().Last().Clone("h_data") leg_stack.Draw("same") CMS_lumi.writeExtraText = 1 CMS_lumi.extraText = "" if str(lep_).strip('[]') == "muon": lep_tag = "#mu+" elif str(lep_).strip('[]') == "electron": lep_tag = "e+" lumi_sqrtS = "%s fb^{-1} (13 TeV)" % (lumi) iPeriod = 0 iPos = 11 CMS_lumi(pad1, lumi_sqrtS, iPos, lep_tag + str(reg_)) hratio = stack.GetStack().Last() c1.cd() pad2 = ROOT.TPad("pad2", "pad2", 0, 0.01, 1, 0.30) pad2.SetTopMargin(0.05) pad2.SetBottomMargin(0.45) pad2.SetLeftMargin(0.12) pad2.SetRightMargin(0.05) ROOT.gStyle.SetHatchesSpacing(2) ROOT.gStyle.SetHatchesLineWidth(2) c1.cd() pad2.Draw() pad2.cd() ratio = hdata.Clone("ratio") ratio.SetLineColor(ROOT.kBlack) ratio.SetMaximum(2) ratio.SetMinimum(0) ratio.Sumw2() ratio.SetStats(0) ratio.Divide(hratio) ratio.SetMarkerStyle(20) ratio.SetMarkerSize(0.9) ratio.Draw("epx0e0") ratio.SetTitle("") h_bkg_err = hratio.Clone("h_err") h_bkg_err.Reset() h_bkg_err.Sumw2() for i in range(1, hratio.GetNbinsX() + 1): h_bkg_err.SetBinContent(i, 1) if (hratio.GetBinContent(i)): h_bkg_err.SetBinError( i, (hratio.GetBinError(i) / hratio.GetBinContent(i))) else: h_bkg_err.SetBinError(i, 10 ^ (-99)) h_bkg_err.SetLineWidth(100) h_bkg_err.SetMarkerSize(0) h_bkg_err.SetFillColor(ROOT.kGray + 1) h_bkg_err.Draw("e20same") f1 = ROOT.TLine(variabile_._xmin, 1., variabile_._xmax, 1.) f1.SetLineColor(ROOT.kBlack) f1.SetLineStyle(ROOT.kDashed) f1.Draw("same") ratio.GetYaxis().SetTitle("Data / MC") ratio.GetYaxis().SetNdivisions(503) ratio.GetXaxis().SetLabelFont(42) ratio.GetYaxis().SetLabelFont(42) ratio.GetXaxis().SetTitleFont(42) ratio.GetYaxis().SetTitleFont(42) ratio.GetXaxis().SetTitleOffset(1.1) ratio.GetYaxis().SetTitleOffset(0.35) ratio.GetXaxis().SetLabelSize(0.15) ratio.GetYaxis().SetLabelSize(0.15) ratio.GetXaxis().SetTitleSize(0.16) ratio.GetYaxis().SetTitleSize(0.16) ratio.GetYaxis().SetRangeUser(0., 2.0) ratio.GetXaxis().SetTitle(variabile_._title) ratio.GetXaxis().SetLabelOffset(0.04) ratio.GetYaxis().SetLabelOffset(0.02) ratio.Draw("epx0e0same") c1.cd() #ROOT.TGaxis.SetMaxDigits(3) c1.RedrawAxis() pad2.RedrawAxis() c1.Update() c1.Print(plotrepo + "stack/" + canvasname + ".png") c1.Print(plotrepo + "stack/" + canvasname + ".pdf") del histo tmp.Delete() h.Delete() del tmp del h del h_sig h_err.Delete() del h_err h_bkg_err.Delete() del h_bkg_err hratio.Delete() del hratio stack.Delete() del stack pad1.Delete() del pad1 pad2.Delete() del pad2 c1.Delete() del c1 for s in samples_: infile[s.label].Close() infile[s.label].Delete() os.system('set LD_PRELOAD=libtcmalloc.so')
def run(model,m1,res,lumi): filepath = 'dispjets_jsons/' rootfile = ROOT.TFile(filepath+"plot_m"+m1+"_r"+str(res)+"_L"+str(lumi)+".root","RECREATE") rootfile.cd() #m2 = [1, 3, 10, 30, 100, 300, 1000, 3000] m2 = [1,10,100,1000,10000] wgt = 0.001/13.19 #0.001 b/c i injected this xsec in analysis.cpp 13.19 divided b/c theo presents limits in terms of BR # read in theoretical xsec if (model=="2HDM"): xsecfile = open('crosssectionZp2HDM.txt','r') if (model=="BARY"): xsecfile = open('crosssectionZpBaryonic.txt','r') if (model=="DISP"): xsecfile = open('crosssectionDispJets.txt','r') mZ = [] mA = [] mstr = [] xsecs = {} xsec = [] for line in xsecfile: line = line.rstrip('\n') line = line.split(' ') mZ.append(line[0]) mA.append(line[1]) massstr = line[0]+'_'+line[1] mstr.append(massstr) xsecs[massstr] = float(line[2]) xsec = array( 'd' ) mass = array( 'd' ) exp_raw = array( 'd' ) obs_raw = array( 'd' ) up1_raw = array( 'd' ) do1_raw = array( 'd' ) up2_raw = array( 'd' ) do2_raw = array( 'd' ) # pick up jsons with limits for m in m2: newmassstr = str(m)+'_'+m1 if newmassstr not in mstr: continue # make correct array of xsecs mass.append(m) xsec.append(xsecs[str(m)+'_'+m1]) if (model=="2HDM"): filename=filepath+'Zprime'+str(m)+'A'+m1+'.json' if (model=="BARY"): filename=filepath+'Zprime'+str(m)+'DM'+m1+'.json' if (model=="DISP"): filename=filepath+'datacard_dispjets_ct'+str(m)+'mm_res'+res+'_lumi'+lumi+'pb.json' print filename if os.path.isfile(filename): with open(filename) as jsonfile: data = json.load(jsonfile) for key in data: exp_raw.append(data[key][u'exp0']) obs_raw.append(data[key][u'obs']) up1_raw.append(data[key][u'exp+1']) do1_raw.append(data[key][u'exp-1']) up2_raw.append(data[key][u'exp+2']) do2_raw.append(data[key][u'exp-2']) print data[key][u'exp0'] else: print 'File '+filename+' NOT found' exp = scaleBR(exp_raw,wgt) obs = scaleBR(obs_raw,wgt) up1 = scaleBR(up1_raw,wgt) do1 = scaleBR(do1_raw,wgt) up2 = scaleBR(up2_raw,wgt) do2 = scaleBR(do2_raw,wgt) numpts = len(mass) print numpts print xsec limitPlotExp = ROOT.TGraph(numpts,mass,exp) limitPlotObs = ROOT.TGraph(numpts,mass,obs) limitPlotXsc = ROOT.TGraph(numpts,mass,xsec) limitPlot1sig = ROOT.TGraph(2*numpts) limitPlot2sig = ROOT.TGraph(2*numpts) for i in range(0,numpts): limitPlot1sig.SetPoint(i,mass[i],up1[i]) limitPlot1sig.SetPoint(numpts+i,mass[numpts-i-1],do1[numpts-i-1]) limitPlot2sig.SetPoint(i,mass[i],up2[i]) limitPlot2sig.SetPoint(numpts+i,mass[numpts-i-1],do2[numpts-i-1]) ROOT.gStyle.SetOptStat(0) c = ROOT.TCanvas('','') c.SetLogx(1) c.SetLogy(1) c.SetGrid(); limitPlotObs.SetTitle("") limitPlotObs.GetXaxis().SetTitle("LL particle c#tau [mm]") limitPlotObs.GetYaxis().SetTitle("BR(H#rightarrowXX)") # styling limitPlotXsc.SetLineColor(4) limitPlotXsc.SetLineStyle(7) limitPlotXsc.SetLineWidth(2) limitPlotExp.SetLineStyle(7) limitPlotExp.SetLineWidth(2) limitPlotObs.SetLineWidth(2) limitPlot1sig.SetFillColor(5) limitPlot1sig.SetFillStyle(3013) limitPlot2sig.SetFillColor(8) limitPlot2sig.SetFillStyle(3013) limitPlotObs.SetMaximum(10) limitPlotObs.SetMinimum(0.0000001) limitPlotObs.Draw("ACP") limitPlot2sig.Draw("F SAME") limitPlot1sig.Draw("F SAME") limitPlotExp.Draw("CP SAME") limitPlotObs.Draw("CP SAME") limitPlotXsc.Draw("CP SAME") limitPlotExp.SetName("expected_curve") limitPlotExp.Write() CMS_lumi(c,4,0) c.RedrawAxis() c.Print("~/www/DispJets/Limits/lim1D_m"+m1+"_r"+res+"_L"+lumi+".pdf") c.Print("~/www/DispJets/Limits/lim1D_m"+m1+"_r"+res+"_L"+lumi+".png")
def run(model, m1, res, lumi): filepath = 'dispjets_jsons/' #m2 = [1, 3, 10, 30, 100, 300, 1000, 3000] m2 = [100] wgt = 1 # read in theoretical xsec if (model == "2HDM"): xsecfile = open('crosssectionZp2HDM.txt', 'r') if (model == "BARY"): xsecfile = open('crosssectionZpBaryonic.txt', 'r') if (model == "DISP"): xsecfile = open('crosssectionDispJets.txt', 'r') mZ = [] mA = [] mstr = [] xsecs = {} xsec = [] for line in xsecfile: line = line.rstrip('\n') line = line.split(' ') mZ.append(line[0]) mA.append(line[1]) massstr = line[0] + '_' + line[1] mstr.append(massstr) xsecs[massstr] = float(line[2]) xsec = array('d') mass = array('d') exp_raw = array('d') obs_raw = array('d') up1_raw = array('d') do1_raw = array('d') up2_raw = array('d') do2_raw = array('d') # pick up jsons with limits for m in m2: newmassstr = str(m) + '_' + m1 if newmassstr not in mstr: continue # make correct array of xsecs mass.append(m) xsec.append(xsecs[str(m) + '_' + m1]) if (model == "2HDM"): filename = filepath + 'Zprime' + str(m) + 'A' + m1 + '.json' if (model == "BARY"): filename = filepath + 'Zprime' + str(m) + 'DM' + m1 + '.json' if (model == "DISP"): filename = filepath + 'XXto4Q_M' + m1 + '_CT' + str( m) + '_r' + res + '_L' + lumi + '.json' if os.path.isfile(filename): with open(filename) as jsonfile: data = json.load(jsonfile) for key in data: exp_raw.append(data[key][u'exp0']) obs_raw.append(data[key][u'obs']) up1_raw.append(data[key][u'exp+1']) do1_raw.append(data[key][u'exp-1']) up2_raw.append(data[key][u'exp+2']) do2_raw.append(data[key][u'exp-2']) else: print 'File ' + filename + ' NOT found' exp = scaleBR(exp_raw, wgt) obs = scaleBR(obs_raw, wgt) up1 = scaleBR(up1_raw, wgt) do1 = scaleBR(do1_raw, wgt) up2 = scaleBR(up2_raw, wgt) do2 = scaleBR(do2_raw, wgt) numpts = len(mass) limitPlotExp = ROOT.TGraph(numpts, mass, exp) limitPlotObs = ROOT.TGraph(numpts, mass, obs) limitPlotXsc = ROOT.TGraph(numpts, mass, xsec) limitPlot1sig = ROOT.TGraph(2 * numpts) limitPlot2sig = ROOT.TGraph(2 * numpts) for i in range(0, numpts): limitPlot1sig.SetPoint(i, mass[i], up1[i]) limitPlot1sig.SetPoint(numpts + i, mass[numpts - i - 1], do1[numpts - i - 1]) limitPlot2sig.SetPoint(i, mass[i], up2[i]) limitPlot2sig.SetPoint(numpts + i, mass[numpts - i - 1], do2[numpts - i - 1]) ROOT.gStyle.SetOptStat(0) c = ROOT.TCanvas('', '') c.SetLogx(1) c.SetLogy(1) c.SetGrid() limitPlotObs.SetTitle("") limitPlotObs.GetXaxis().SetTitle("LL particle c#tau [mm]") limitPlotObs.GetYaxis().SetTitle("#sigma [pb]") # styling limitPlotXsc.SetLineColor(4) limitPlotXsc.SetLineStyle(7) limitPlotXsc.SetLineWidth(2) limitPlotExp.SetLineStyle(7) limitPlotExp.SetLineWidth(2) limitPlotObs.SetLineWidth(2) limitPlot1sig.SetFillColor(5) limitPlot1sig.SetFillStyle(3013) limitPlot2sig.SetFillColor(8) limitPlot2sig.SetFillStyle(3013) limitPlotObs.SetMaximum(10) limitPlotObs.SetMinimum(0.1) limitPlotObs.Draw("ACP") limitPlot2sig.Draw("F SAME") limitPlot1sig.Draw("F SAME") limitPlotExp.Draw("CP SAME") limitPlotObs.Draw("CP SAME") limitPlotXsc.Draw("CP SAME") CMS_lumi(c, 4, 0) c.RedrawAxis() c.Print("~/www/Plots/DispJets/GenLevelPlots/Limits/lim1D_m" + m1 + "_r" + res + "_L" + lumi + ".pdf") c.Print("~/www/Plots/DispJets/GenLevelPlots/Limits/lim1D_m" + m1 + "_r" + res + "_L" + lumi + ".png")
def run(model, m1): filepath = 'gg_BARY_results/' m2 = [ 10, 20, 30, 40, 50, 75, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000, 1100 ] wgt = 1 # read in theoretical xsec if (model == "2HDM"): xsecfile = open('crosssectionZp2HDM.txt', 'r') if (model == "BARY"): xsecfile = open('crosssectionZpBaryonic.txt', 'r') mZ = [] mA = [] mstr = [] xsecs = {} xsec = [] for line in xsecfile: line = line.rstrip('\n') line = line.split(' ') mZ.append(line[0]) mA.append(line[1]) massstr = line[0] + '_' + line[1] mstr.append(massstr) xsecs[massstr] = float(line[2]) xsec = array('d') mass = array('d') exp_raw = array('d') obs_raw = array('d') up1_raw = array('d') do1_raw = array('d') up2_raw = array('d') do2_raw = array('d') # pick up jsons with limits for m in m2: newmassstr = str(m) + '_' + m1 if newmassstr not in mstr: continue # make correct array of xsecs mass.append(m) xsec.append(xsecs[str(m) + '_' + m1]) if (model == "2HDM"): filename = filepath + 'Zprime' + str(m) + 'A' + m1 + '.json' if (model == "BARY"): filename = filepath + 'Zprime' + str(m) + 'DM' + m1 + '.json' if os.path.isfile(filename): with open(filename) as jsonfile: data = json.load(jsonfile) for key in data: exp_raw.append(data[key][u'exp0']) obs_raw.append(data[key][u'obs']) up1_raw.append(data[key][u'exp+1']) do1_raw.append(data[key][u'exp-1']) up2_raw.append(data[key][u'exp+2']) do2_raw.append(data[key][u'exp-2']) else: print 'File ' + filename + ' NOT found' exp = scaleBR(exp_raw, wgt) obs = scaleBR(obs_raw, wgt) up1 = scaleBR(up1_raw, wgt) do1 = scaleBR(do1_raw, wgt) up2 = scaleBR(up2_raw, wgt) do2 = scaleBR(do2_raw, wgt) numpts = len(mass) limitPlotExp = ROOT.TGraph(numpts, mass, exp) limitPlotObs = ROOT.TGraph(numpts, mass, obs) limitPlotXsc = ROOT.TGraph(numpts, mass, xsec) limitPlot1sig = ROOT.TGraph(2 * numpts) limitPlot2sig = ROOT.TGraph(2 * numpts) for i in range(0, numpts): limitPlot1sig.SetPoint(i, mass[i], up1[i]) limitPlot1sig.SetPoint(numpts + i, mass[numpts - i - 1], do1[numpts - i - 1]) limitPlot2sig.SetPoint(i, mass[i], up2[i]) limitPlot2sig.SetPoint(numpts + i, mass[numpts - i - 1], do2[numpts - i - 1]) ROOT.gStyle.SetOptStat(0) c = ROOT.TCanvas('', '') c.SetLogx(1) c.SetLogy(1) c.SetGrid() limitPlotObs.SetTitle("") limitPlotObs.GetXaxis().SetTitle("M_{Z'} [GeV]") limitPlotObs.GetYaxis().SetTitle("#sigma(Z' #rightarrow#chi#chi h) [pb]") # styling limitPlotXsc.SetLineColor(4) limitPlotXsc.SetLineStyle(7) limitPlotXsc.SetLineWidth(2) limitPlotExp.SetLineStyle(7) limitPlotExp.SetLineWidth(2) limitPlotObs.SetLineWidth(2) limitPlot1sig.SetFillColor(5) limitPlot1sig.SetFillStyle(3013) limitPlot2sig.SetFillColor(8) limitPlot2sig.SetFillStyle(3013) limitPlotObs.SetMaximum(10) limitPlotObs.SetMinimum(0.1) limitPlotObs.Draw("ACP") limitPlot2sig.Draw("F SAME") limitPlot1sig.Draw("F SAME") limitPlotExp.Draw("CP SAME") limitPlotObs.Draw("CP SAME") limitPlotXsc.Draw("CP SAME") CMS_lumi(c, 4, 0) c.RedrawAxis() c.Print("~/www/Plots/13TeV_v80X_moriond17/MonoHCombo/test_1Dlimit.pdf") c.Print("~/www/Plots/13TeV_v80X_moriond17/MonoHCombo/test_1Dlimit.png")
def doTheMassFit(ws, data=None, CandTypes=None, showResult=False, outD='unfolded', postfixForOutputs=''): #fit the mass spectrum ws.pdf('model').fitTo(data, ROOT.RooFit.Extended()) if not showResult: return #get the main parameters of the fit nsig = ws.var("nsig").getVal() nsigErr = ws.var("nsig").getError() nbkg = ws.var("nbkg").getVal() nbkgErr = ws.var("nbkg").getError() mass = ws.var("sig_mu").getVal() massErr = ws.var("sig_mu").getError() try: width = ws.var("sig_sigma").getVal() widthErr = ws.var("sig_sigma").getError() except: width = ws.var("sig_Gauss1_sigma").getVal() widthErr = ws.var("sig_Gauss1_sigma").getError() #show result of the fit cfit = ROOT.TCanvas("cfit", "cfit", 500, 500) cfit.cd() frame = ws.var("mass").frame() #ROOT.RooFit.Bins(50)) data.plotOn(frame, ROOT.RooFit.DrawOption("p"), ROOT.RooFit.MarkerStyle(20), ROOT.RooFit.Name("data")) ws.pdf("model").plotOn(frame, ROOT.RooFit.FillStyle(0), ROOT.RooFit.MoveToBack(), ROOT.RooFit.Name("total")) # ws.pdf("model").plotOn(frame, # ROOT.RooFit.Components('sig_model'), # ROOT.RooFit.LineColor(5), # ROOT.RooFit.LineWidth(1), # ROOT.RooFit.FillStyle(1001), # ROOT.RooFit.FillColor(5), # ROOT.RooFit.DrawOption("LF"), # ROOT.RooFit.MoveToBack(), # ROOT.RooFit.Name("sig")) ws.pdf("model").plotOn(frame, ROOT.RooFit.Components('bkg_model'), ROOT.RooFit.LineColor(1), ROOT.RooFit.LineWidth(2), ROOT.RooFit.FillStyle(1001), ROOT.RooFit.FillColor(920), ROOT.RooFit.DrawOption("LF"), ROOT.RooFit.MoveToBack(), ROOT.RooFit.Name("bkg")) frame.Draw() try: bkg_lambda = ws.var('bkg_lambda').getVal() ymin = nbkg * math.exp(frame.GetXaxis().GetXmax() * bkg_lambda) * 0.2 ymax = 1.4 * frame.GetMaximum() except TypeError: ymin = 0 ymax = 1.1 * frame.GetMaximum() frame.GetYaxis().SetRangeUser(ymin, ymax) frame.GetYaxis().SetTitle("Candidates") frame.GetYaxis().SetTitleOffset(1.6) if '411' in str(CandTypes): frame.GetXaxis().SetTitle(XAXIS['Dpm']) if '421' in str(CandTypes): frame.GetXaxis().SetTitle(XAXIS['D0']) if '443' in str(CandTypes): frame.GetXaxis().SetTitle(XAXIS['JPsi']) if '413' in str(CandTypes): frame.GetXaxis().SetTitle(XAXIS['Dsm']) frame.GetXaxis().SetTitleOffset(0.9) frame.GetYaxis().SetTitleSize(0.05) frame.GetYaxis().SetLabelSize(0.04) frame.GetXaxis().SetTitleSize(0.05) frame.GetXaxis().SetLabelSize(0.04) cfit.Modified() cfit.Update() #build a legend leg = ROOT.TLegend(0.7, 0.79, 0.9, 0.94, "", "brNDC") # leg=ROOT.TLegend(0.7,0.72,0.9,0.95,"","brNDC") leg.SetFillStyle(0) leg.SetBorderSize(0) leg.SetTextFont(42) leg.SetTextSize(0.04) leg.AddEntry("data", "Data", "p") leg.AddEntry("bkg", "Background", "f") # leg.AddEntry("sig", "Signal", "f") leg.AddEntry("total", "Total", "f") leg.Draw() #display fit results on the canvas CMS_lumi(cfit, 2, 10) if not '413' in str(CandTypes): pt = ROOT.TPaveText(0.17, 0.85, 0.5, 0.6, "brNDC") else: pt = ROOT.TPaveText(0.50, 0.77, 0.89, 0.52, "brNDC") pt.SetFillStyle(0) pt.SetBorderSize(0) pt.SetTextFont(42) pt.SetTextAlign(12) pt.SetTextSize(0.04) if not '413' in str(CandTypes): pt.AddText("m = %3.4f #pm %3.4f GeV" % (mass, massErr)) pt.AddText("#sigma = %3.4f #pm %3.4f GeV" % (width, widthErr)) pt.AddText("N_{signal} = %3.0f #pm %3.0f" % (nsig, nsigErr)) pt.AddText("N_{bkg} = %3.0f #pm %3.0f" % (nbkg, nbkgErr)) else: pt.AddText("dm = %3.2f #pm %3.2f MeV" % (mass * 1000, massErr * 1000)) pt.AddText("#sigma = %3.2f #pm %3.2f MeV" % (width * 1000, widthErr * 1000)) pt.AddText("N_{signal} = %3.0f #pm %3.0f" % (nsig, nsigErr)) pt.AddText("N_{bkg} = %3.0f #pm %3.0f" % (nbkg, nbkgErr)) pt.Draw() #save to file outF = 'cfit%s' % postfixForOutputs for ext in ['.pdf', '.png', '.C']: #for ext in ['.pdf']: cfit.SaveAs(os.path.join(outD, outF + ext))
#limitPlotDown2.Draw("CONT3 SAME") limitPlotObsCopy = limitPlotObs.Clone() limitPlotObsCopy.SetMinimum(1) limitPlotObsCopy.SetContour(1) limitPlotObsCopy.SetLineWidth(2) limitPlotObsCopy.Draw("CONT3 SAME") limitPlot.SetMinimum(1) limitPlot.SetContour(1) limitPlot.SetLineStyle(7) limitPlot.SetLineWidth(3) limitPlot.Draw("CONT3 SAME") leg = ROOT.TLegend(.35, .75, .90, .90) leg.SetBorderSize(0) leg.SetFillColor(0) leg.SetFillStyle(0) leg.SetTextFont(42) leg.SetTextSize(0.030) leg.AddEntry(limitPlotObsCopy, "Observed Limit (95% CL)", "L") leg.AddEntry(limitPlot, "Expected Limit (95% CL)", "L") leg.AddEntry(limitPlotUp, "Expected Limit +/- 1 \sigma", "L") #leg.AddEntry(limitPlotUp2,"Expected Limit +/- 2\sigma r = 1 (95% CL)","L") leg.Draw() CMS_lumi(canv, 4, 0) limitPlot.SaveAs("test.root") canv.Print("test.pdf")
def run(opts): # --- read in options model = opts.model which = opts.which outdir = opts.outdir do90 = opts.do90 dowgt = opts.dowgt dosmth = opts.dosmth smthfnc = opts.smthfnc #if dosmth: addtxt = '_smth' # --- read in files indir = '/eos/cms/store/group/phys_exotica/MonoHgg/MonoH-COMBO-2016/' + model + '_jsons/' if dowgt: wfile = '' else: wfile = '_weighted' if do90: indir += which + '_' + model + wfile + '_results_90CL/' else: indir += which + '_' + model + wfile + '_results/' # --- options for plot averaging doFillAvgLow = True # do averaging below mMed = 2*mDM line doFillAvgHigh = True # do averaging above mMed = 2*mDM line if model == "2HDM": doFillAvgLow = False if model == "2HDM": doFillAvgHigh = False doFillAvgRest = True # do averaging at line or average normally doFillAvgAll = True # do averaging for all plots not just observed # --- setup general style ROOT.gROOT.SetBatch(ROOT.kTRUE) ROOT.gStyle.SetOptStat(0) plot.ModTDRStyle() canv = ROOT.TCanvas() canv.SetLogz() canv.SetTicks() canv.SetRightMargin(0.16) # allow enough space for z axis label canv.cd() # --- setup palette ROOT.gStyle.SetPalette(57) # palette normal InvertPalette() # palette inverted ROOT.gStyle.SetNumberContours(255) A = [] Z = [] # --- mass points if model == "2HDM": A = [ 300, 325, 350, 375, 400, 425, 450, 475, 500, 525, 550, 575, 600, 625, 650, 675 ] Z = [ 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500, 1550, 1600, 1650, 1700, 1750, 1800, 1850, 1900, 1950 ] if model == "BARY": A = [ 1, 35, 100, 125, 150, 175, 200, 225, 250, 275, 300, 325, 350, 375, 400, 425, 450, 475, 500, 525, 550, 575, 600, 625, 650, 675, 700, 725, 750, 775, 800, 825, 850, 875, 900, 925, 950, 975, 1000 ] Z = [ 10, 50, 100, 200, 250, 300, 350, 400, 450, 500, 550, 600, 675, 750, 800, 850, 900, 950, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000 ] # --- binning for BARY model # Y axis BinningA = [0.5, 1.5] BinAAxis = [1.0, 47.5] for i in range(1, len(A) - 1): BinningA.append((A[i] + A[i + 1]) / 2.0) BinAAxis.append((A[i] + A[i + 1]) / 2.0) BinningA.append((A[-1] + A[-1] - ((A[-1] + A[-2]) / 2.0))) BinAAxis.append((A[-1] + A[-1] - ((A[-1] + A[-2]) / 2.0))) # X axis BinningZ = [9, 11] BinZAxis = [10, 75] for i in range(1, len(Z) - 1): BinningZ.append((Z[i] + Z[i + 1]) / 2.0) BinZAxis.append((Z[i] + Z[i + 1]) / 2.0) BinningZ.append((Z[-1] + Z[-1] - ((Z[-1] + Z[-2]) / 2.0))) BinZAxis.append((Z[-1] + Z[-1] - ((Z[-1] + Z[-2]) / 2.0))) # --- setup histograms (different models have different binning) if model == "2HDM": limitPlotAxis = ROOT.TH2F("lplotAxis", "lplotAxis", len(Z), Z[0], Z[-1] + 50, len(A), A[0], A[-1] + 25) limitPlot = ROOT.TH2F("lplot", "lplot", len(Z), Z[0] - 25, Z[-1] + 50, len(A), A[0] - 12.5, A[-1] + 25) limitPlotObs = ROOT.TH2F("lplotObs", "lplotObs", len(Z), Z[0] - 25, Z[-1] + 50, len(A), A[0] - 12.5, A[-1] + 25) limitPlotUp = ROOT.TH2F("lplotU", "lplotU", len(Z), Z[0] - 25, Z[-1] + 50, len(A), A[0] - 12.5, A[-1] + 25) limitPlotDown = ROOT.TH2F("lplotDown", "lplotDown", len(Z), Z[0] - 25, Z[-1] + 50, len(A), A[0] - 12.5, A[-1] + 25) limitPlotUp2 = ROOT.TH2F("lplotU2", "lplotU2", len(Z), Z[0] - 25, Z[-1] + 50, len(A), A[0] - 12.5, A[-1] + 25) limitPlotDown2 = ROOT.TH2F("lplotDown2", "lplotDown2", len(Z), Z[0] - 25, Z[-1] + 50, len(A), A[0] - 12.5, A[-1] + 25) if model == "BARY": # variable binning limitPlotAxis = ROOT.TH2F("lplotAxis", "lplotAxis", len(Z) - 1, array('d', BinZAxis), len(A) - 1, array('d', BinAAxis)) limitPlot = ROOT.TH2F("lplot", "lplot", len(BinningZ) - 1, array('d', BinningZ), len(BinningA) - 1, array('d', BinningA)) limitPlotObs = ROOT.TH2F("lplotObs", "lplotObs", len(BinningZ) - 1, array('d', BinningZ), len(BinningA) - 1, array('d', BinningA)) limitPlotUp = ROOT.TH2F("lplotU", "lplotU", len(BinningZ) - 1, array('d', BinningZ), len(BinningA) - 1, array('d', BinningA)) limitPlotDown = ROOT.TH2F("lplotDown", "lplotDown", len(BinningZ) - 1, array('d', BinningZ), len(BinningA) - 1, array('d', BinningA)) limitPlotUp2 = ROOT.TH2F("lplotU2", "lplotU2", len(BinningZ) - 1, array('d', BinningZ), len(BinningA) - 1, array('d', BinningA)) limitPlotDown2 = ROOT.TH2F("lplotDown2", "lplotDown2", len(BinningZ) - 1, array('d', BinningZ), len(BinningA) - 1, array('d', BinningA)) # --- read in json files for a in A: for z in Z: data = {} filename = indir + 'Zprime' + str(z) + 'A' + str(a) + '.json' if which == 'gg' and model == 'BARY': # BARY gg ONLY has DM instead of A in filename filename = indir + 'Zprime' + str(z) + 'DM' + str(a) + '.json' scale = 1. if dowgt: scale = scaleXS(model, z, a) if os.path.isfile(filename) and scale != "99999": with open(filename) as jsonfile: data = json.load(jsonfile) for key in data: # fill plots from json limitPlot.SetBinContent( limitPlot.GetXaxis().FindBin(float(z)), limitPlot.GetYaxis().FindBin(float(a)), float(scale) * data[key][u'exp0']) limitPlotUp.SetBinContent( limitPlotUp.GetXaxis().FindBin(float(z)), limitPlot.GetYaxis().FindBin(float(a)), float(scale) * data[key][u'exp+1']) limitPlotDown.SetBinContent( limitPlotDown.GetXaxis().FindBin(float(z)), limitPlot.GetYaxis().FindBin(float(a)), float(scale) * data[key][u'exp-1']) limitPlotUp2.SetBinContent( limitPlotUp2.GetXaxis().FindBin(float(z)), limitPlot.GetYaxis().FindBin(float(a)), float(scale) * data[key][u'exp+2']) limitPlotDown2.SetBinContent( limitPlotDown2.GetXaxis().FindBin(float(z)), limitPlot.GetYaxis().FindBin(float(a)), float(scale) * data[key][u'exp-2']) limitPlotObs.SetBinContent( limitPlotObs.GetXaxis().FindBin(float(z)), limitPlot.GetYaxis().FindBin(float(a)), float(scale) * data[key][u'obs']) # --- average plots to make smooth contours fillAvg(limitPlotObs, A, Z, doFillAvgLow, False, False) fillAvg(limitPlotObs, A, Z, False, doFillAvgHigh, False) fillAvg(limitPlotObs, A, Z, False, False, doFillAvgRest) if doFillAvgAll: fillAvg(limitPlot, A, Z, doFillAvgLow, False, False) fillAvg(limitPlotUp, A, Z, doFillAvgLow, False, False) fillAvg(limitPlotDown, A, Z, doFillAvgLow, False, False) fillAvg(limitPlotUp2, A, Z, doFillAvgLow, False, False) fillAvg(limitPlotDown2, A, Z, doFillAvgLow, False, False) fillAvg(limitPlot, A, Z, False, doFillAvgHigh, False) fillAvg(limitPlotUp, A, Z, False, doFillAvgHigh, False) fillAvg(limitPlotDown, A, Z, False, doFillAvgHigh, False) fillAvg(limitPlotUp2, A, Z, False, doFillAvgHigh, False) fillAvg(limitPlotDown2, A, Z, False, doFillAvgHigh, False) fillAvg(limitPlot, A, Z, False, False, doFillAvgRest) fillAvg(limitPlotUp, A, Z, False, False, doFillAvgRest) fillAvg(limitPlotDown, A, Z, False, False, doFillAvgRest) fillAvg(limitPlotUp2, A, Z, False, False, doFillAvgRest) fillAvg(limitPlotDown2, A, Z, False, False, doFillAvgRest) # --- axis labels limitPlotAxis.GetXaxis().SetTitle("m_{Z'} [GeV]") limitPlotObs.GetZaxis().SetTitle("#sigma_{95% CL}/#sigma_{th}") if model == "2HDM": limitPlotAxis.GetYaxis().SetTitle("m_{A} [GeV]") if model == "BARY": limitPlotAxis.GetYaxis().SetTitle("m_{#chi} [GeV]") # --- clone obs to get contour limitPlotObsCopy = limitPlotObs.Clone() # --- set up min and max of z axis limitPlotObs.SetMaximum(100) limitPlotObs.SetMinimum(0.3) # --- set range of x and y axis if model == "BARY": limitPlotObs.GetXaxis().SetRangeUser(10, 2001) if model == "BARY": limitPlotObs.GetYaxis().SetRangeUser(1, 1001) if model == "2HDM": limitPlotObs.GetXaxis().SetRangeUser(450, 2000) if model == "2HDM": limitPlotObs.GetYaxis().SetRangeUser(300, 700) # --- style plot limitPlotObs.GetYaxis().SetTitleOffset(0.95) # format axis labels limitPlotObs.GetZaxis().SetTitleOffset(0.95) limitPlotObs.GetXaxis().SetLabelSize(0.035) # format axis ticks limitPlotObs.GetYaxis().SetLabelSize(0.035) if model == "2HDM": limitPlotAxis.GetXaxis().SetNdivisions(9) if model == "2HDM": limitPlotAxis.GetYaxis().SetNdivisions(8) if model == "BARY": limitPlotAxis.GetXaxis().SetNdivisions(10) if model == "BARY": limitPlotAxis.GetYaxis().SetNdivisions(16) # --- get and style each contour # 1 sigma up limitPlotUp.SetMinimum(1) limitPlotUp.SetContour(1) limitPlotUp.SetLineWidth(1) # 1 sigma down limitPlotDown.SetMinimum(1) limitPlotDown.SetContour(1) limitPlotDown.SetLineWidth(1) # observed limitPlotObs.SetLineWidth(3) limitPlotObs.SetLineColor(2) limitPlotObsCopy.SetMinimum(1) limitPlotObsCopy.SetContour(1) limitPlotObsCopy.SetLineWidth(3) limitPlotObsCopy.SetLineColor(2) # expected limitPlot.SetMinimum(1) limitPlot.SetContour(1) limitPlot.SetLineStyle(7) limitPlot.SetLineWidth(3) # --- smooth if dosmth: limitPlot.Smooth(1, smthfnc) #limitPlotObs.Smooth(1,smthfnc) limitPlotObsCopy.Smooth(1, smthfnc) limitPlotUp.Smooth(1, smthfnc) limitPlotDown.Smooth(1, smthfnc) # --- draw plots limitPlotAxis.Draw("COLZ") limitPlotObs.Draw("COLZ SAME") limitPlotUp.Draw("CONT3 SAME") limitPlotDown.Draw("CONT3 SAME") limitPlotObsCopy.Draw("CONT3 SAME") limitPlot.Draw("CONT3 SAME") # --- legend and extra text box x1 = 0.18 y1 = 0.65 x2 = x1 + 0.45 y2 = y1 + 0.25 # --- latex if model == "2HDM": txt1 = "#bf{Z'-2HDM}" if model == "BARY": txt1 = "#bf{Baryonic Z'}" txt1 += "#bf{, Z' #rightarrow DM + h" if which == 'gg': txt1 += "(#gamma#gamma)}" if which == 'tt': txt1 += "(#tau#tau)} " if which == 'combo': txt1 += "(#gamma#gamma + #tau#tau)}" if model == "2HDM": txt2 = "#bf{Dirac DM, m_{#chi} = 100 GeV, g_{Z'} = 0.8, g_{#chi} = 1.0}" if model == "BARY": txt2 = "#bf{Dirac DM, g_{q} = 0.25, g_{#chi} = 1.0 }" txt = ROOT.TPaveText(x1, y1 + 0.15, x2, y2, "NDC") txt.AddText(txt1) txt.AddText(txt2) txt.SetFillColor(0) txt.SetTextAlign(12) txt.SetTextSize(0.03) txt.Draw("SAME") # --- legend leg = ROOT.TLegend(x1, y1, x2, y1 + 0.15) #leg.SetHeader(text) leg.SetBorderSize(0) leg.SetFillColor(0) #leg.SetFillStyle(0) leg.SetTextFont(42) leg.SetTextSize(0.030) leg.AddEntry(limitPlotObs, "Observed 95% CL", "L") leg.AddEntry(limitPlot, "Expected 95% CL", "L") leg.AddEntry(limitPlotUp, "#pm 1 s.d.", "L") leg.Draw() canv.cd() canv.Update() CMS_lumi(canv, 4, 0) canv.RedrawAxis() canv.Update() # --- save outname = outdir + 'contours_' if do90: outname += '90CL' else: outname += '95CL' outname += '_' + model + '_' + which + '.root' outfile = ROOT.TFile(outname, 'RECREATE') outfile.cd() limitPlot.Write() limitPlotObs.Write() if do90: canv.Print(outdir + 'limits2D_' + model + '_' + which + '_90CL.pdf') canv.Print(outdir + 'limits2D_' + model + '_' + which + '_90CL.png') else: canv.Print(outdir + 'limits2D_' + model + '_' + which + '.pdf') canv.Print(outdir + 'limits2D_' + model + '_' + which + '.png')