ra4_macros  bede988c286599a3a84b77a4d788ac0a971e89f9
efficiency_map.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 import os, sys, re
3 import glob
4 import string
5 from array import array
6 from pprint import pprint
7 from get_xsec import signalCrossSection
8 from get_xsec_stop import stopCrossSection
9 from set_palette import set_palette
10 import math
11 import ROOT
12 from ROOT import TMath
13 import argparse
14 parser = argparse.ArgumentParser()
15 parser.add_argument("-b","--babydir")
16 parser.add_argument("-i","--input")
17 parser.add_argument("-o","--outfilename")
18 parser.add_argument("-f","--first")
19 parser.add_argument("-l","--last")
20 parser.add_argument("-t","--topology")
21 args = parser.parse_args()
22 
23 def get_weighted_entries(chain, cuts):
24  temphist = ROOT.TH1D("temp","temp",2,0,2)
25  chain.Project("temp","1","weight*("+cuts+")")
26  n = temphist.GetBinContent(2)
27  temphist.Delete()
28  return n
29 
30 
31 if (args.topology):
32  topo = args.topology
33 else: topo="T1tttt"
34 
35 if topo == "T5tttt":
36  print "Did you mean to use T5ttttDM175 ???"
37 
38 if (args.babydir):
39  outdir = args.babydir
40 else:
41  if topo == "T1tttt":
42  outdir = "/net/cms2/cms2r0/babymaker/babies/2016_01_11/mc/T1tttt/skim_abcd/"
43  elif topo == "T5ttttDM175":
44  outdir = "/net/cms2/cms2r0/babymaker/babies/2016_02_09/mc/T5tttt/skim_abcd/"
45  else:
46  sys.exit("Please provide a baby directory")
47 
48 
49 
50 #these options allow you to run on a subset of mass points for parallelization and to avoid the mysterious memory leak crash
51 #Just combined output rootfiles using hadd and feed back into this script to complete cosmetics
52 # Usage example: one job with -l 350 (no need to specify -f) and one job with -f 350 (no need to specify -l) to split roughly in half
53 
54 
55 
56 if (args.first):
57  minnum = int(args.first)
58 else: minnum=0
59 
60 if (args.last):
61  maxnum = int(args.last)
62 else: maxnum=9999
63 
64 print "starting with "+str(minnum)
65 print "until "+str(maxnum)
66 
67 
68 #To do cosmetic changes without recalculating the histograms, provide the output root file from a previous iteration in the input field
69 if (args.input):
70  skipcalc = True
71  infile = args.input
72 else:
73  skipcalc = False
74  print "Recalculating.."
75 
76 if (args.outfilename):
77  outfile = args.outfilename
78  if ".root" in outfile: outfile = outfile.split(".root")[0]
79 else: sys.exit("Please provide name for output root file")
80 
81 
82 ROOT.gROOT.SetBatch(ROOT.kTRUE) #prevent th1->Draw() from trying to open X11 window
83 ROOT.gStyle.SetCanvasDefW(600);
84 ROOT.gStyle.SetCanvasDefH(600);
85 ROOT.gStyle.SetTitleOffset(1.2,"x")
86 ROOT.gStyle.SetTitleOffset(1.7,"y")
87 ROOT.gStyle.SetTitleOffset(1.7,"z")
88 ROOT.gStyle.SetPadRightMargin(0.19)
89 ROOT.gStyle.SetPadLeftMargin(0.14)
90 ROOT.gStyle.SetPadBottomMargin(0.14)
91 ROOT.gStyle.SetPadTopMargin(0.08)
92 
93 
94 ROOT.gStyle.SetLabelFont(42)
95 ROOT.gStyle.SetLabelSize(0.04)
96 ROOT.gStyle.SetTitleFont(42)
97 ROOT.gStyle.SetTitleSize(0.05)
98 #ROOT.gStyle.SetTitleOffset(1.35,'y')
99 
100 
101 bdir = os.getcwd()
102 
103 lumi = 2.3
104 #outdir = os.path.join(bdir,'out',timestamp)
105 
106 print outdir
107 if not os.path.exists(outdir):
108  sys.exit("Can't find babies directory %s" %outdir)
109 
110 if not skipcalc and not os.path.exists("plots/maps"):
111  sys.exit("Can't find directory for output root file plots/maps")
112 
113 
114 ###### With the fake dataset names:
115 masspoints = set([x.split(topo+"_").pop().split("_Tune")[0] for x in glob.glob(outdir+"/baby_SMS-"+topo+"*.root")])
116 # Needs renormalized ABCD skim
117 #masspoints = masspoints - set(["mGluino-725_mLSP-425","mGluino-1850_mLSP-850","mGluino-1350_mLSP-750"]) ## remove points with weight NaN
118 #masspoints = ["mGluino-1550_mLSP-100","mGluino-1500_mLSP-700"]
119 
120 npoints = len(masspoints)
121 if npoints ==0:
122  sys.exit("Need to run on renormalized ABCD skim")
123 
124 bg = [3.5,0.5,2.7,0.5,0.8,0.1,1.3,0.3,0.5,0.1]
125 
126 #define all bins and cosmetic names
127 bindefs = ["njets<=8&&nbm==1&&met<=400","njets>=9&&nbm==1&&met<=400","njets<=8&&nbm==2&&met<=400","njets>=9&&nbm==2&&met<=400","njets<=8&&nbm>=3&&met<=400","njets>=9&&nbm>=3&&met<=400","njets<=8&&nbm==1&&met>400","njets>=9&&nbm==1&&met>400","njets<=8&&nbm>=2&&met>400","njets>=9&&nbm>=2&&met>400"]
128 cosmeticbindefs = [cut.replace("<="," #leq ").replace(">="," #geq ").replace(">"," > ").replace("=="," = ").replace("&&",", ").replace("met", "MET").replace("ht", "H_{T}").replace("njets","n_{jets}").replace("nleps","n_{lep}").replace("nbm","n_{b}") for cut in bindefs]
129 
130 glumass = []
131 lspmass = []
132 effs = [[] for i in range(2+len(bindefs))]
133 yields = [[] for i in range(2+len(bindefs))] # one for R4, one for R3, one for each R4 bin
134 sofar=0 #to count progress through mass points
135 if not skipcalc: # if not supplying root file
136 
137  #loop over mass points
138  for m in masspoints:
139  sofar+=1
140  #if sofar<=minnum: continue
141  ## if sofar>10: continue
142  print "m is " +m
143  ch = ROOT.TChain("tree")
144  #print "looking for file "+outdir+"/baby_SMS-"+topo+"_"+m+"_TuneCUETP8M1_13TeV-madgraphMLM-pythia8_RunIISpring15FSPremix-MCRUN2_74_V9*.root"
145  #ch.Add(outdir+"/baby_SMS-"+topo+"_"+m+"_TuneCUETP8M1_13TeV-madgraphMLM-pythia8_RunIISpring15FSPremix-MCRUN2_74_V9*.root")
146  print "looking for file "+outdir+"/baby_SMS-"+topo+"_"+m+"_TuneCUETP8M1*.root"
147  ch.Add(outdir+"/baby_SMS-"+topo+"_"+m+"_TuneCUETP8M1*.root")
148  print "nentries is " + str(ch.GetEntries())
149  glu = float(m.split("mGluino-").pop().split("_")[0])
150  lsp = float(m.split("mLSP-").pop().split("_")[0])
151 
152  glumass.append(glu)
153  lspmass.append(lsp)
154 
155  print "glu is " + str(glu)
156  print "lsp is " + str(lsp)
157 
158  if "T1" in topo or "T5" in topo:
159  tot = 1000.*signalCrossSection(glu)
160  elif "T2" in topo or "T6" in topo:
161  tot = 1000.*stopCrossSection(glu)
162  print "xsec is"+str(stopCrossSection(glu))
163  print "tot = "+str(tot)
164  #assume integral of weights was normalized correctly pre-skim
165 
166 
167  reg4 = float(get_weighted_entries(ch,"mj>400&&mt>140")) # ASSUMES ABCD SKIM!
168  reg3 = float(get_weighted_entries(ch,"mj<=400&&mt>140"))
169  # first vector in effs is R4 efficiency
170  effs[0].append(reg4/tot)
171  yields[0].append(lumi*reg4)
172  effs[-1].append(reg3/tot) # putting R3 at very end because it is convenient
173  yields[-1].append(lumi*reg3)
174  print "R4 is "+str(reg4)
175  print "eff = "+str(effs[0][-1])
176  print "completed "+str(sofar-1)+" out of "+str(npoints)
177  print m
178  for i,cut in enumerate(bindefs):
179  #subsequent vectors in effs are bin efficiencies
180  num = float(get_weighted_entries(ch,"mj>400&&mt>140&&"+cut)) # ASSUMES ABCD SKIM!
181  #print "num is " + str(num)
182  #print "frac is " +str(num/reg4)
183  if reg4 > 0:
184  effs[i+1].append(num/reg4)
185  else:
186  effs[i+1].append(0)
187  yields[i+1].append(lumi*num)
188  #num = num*2.1
189  # print "Bin: "+cut+", S: "+str(num)+", B: " + str(bg[i])+", S/rt(B): "+ str(num/math.sqrt(bg[i]))+", Q: " + str(2*(math.sqrt(num+bg[i])-math.sqrt(bg[i])))
190 
191  outputFile = ROOT.TFile("plots/maps/"+outfile+".root","recreate")
192  # convert lists into TGraphs
193  graphs = []
194  #for k in array("d",glumass):
195  #print str(k)
196  #for k in array("d",lspmass):
197  # print str(k)
198  #for k in array("d",effs[1]):
199  # print str(k)
200 
201 
202  for j,vec in enumerate(effs):
203  if j==0:
204  graphs.append(ROOT.TGraph2D("effmap","R4 Efficiency",len(glumass),array("d",glumass),array("d",lspmass),array("d",effs[j])))
205  graphs.append(ROOT.TGraph2D("yieldmap","R4 Yield",len(glumass),array("d",glumass),array("d",lspmass),array("d",yields[j])))
206  elif j-1 < len(cosmeticbindefs):
207  graphs.append(ROOT.TGraph2D(cosmeticbindefs[j-1],"Fraction of R4 efficiency with "+cosmeticbindefs[j-1],len(glumass),array("d",glumass),array("d",lspmass),array("d",effs[j])))
208  graphs.append(ROOT.TGraph2D(cosmeticbindefs[j-1]+"_yield","Yield in R4 with "+cosmeticbindefs[j-1],len(glumass),array("d",glumass),array("d",lspmass),array("d",yields[j])))
209  else:
210  graphs.append(ROOT.TGraph2D("effmapR3","R3 Efficiency",len(glumass),array("d",glumass),array("d",lspmass),array("d",effs[j])))
211  graphs.append(ROOT.TGraph2D("yieldmapR3","R3 Yield",len(glumass),array("d",glumass),array("d",lspmass),array("d",yields[j])))
212 
213  #Fix empty bottom-left corner with average of two closest points on axis
214  hist = graphs[-1].GetHistogram()
215  if("T1tttt" in topo):
216  val1 = hist.GetBinContent(hist.FindBin(700,0))
217  val2 = hist.GetBinContent(hist.FindBin(600,100))
218  #print val1
219  #print val2
220  #print (val1+val2)/2.
221  graphs[-1].SetPoint(graphs[-1].GetN(),ROOT.Double(600.),0.,(val1+val2)/2.)
222  hist = graphs[-2].GetHistogram()
223  val1 = hist.GetBinContent(hist.FindBin(700,0))
224  val2 = hist.GetBinContent(hist.FindBin(600,100))
225  graphs[-2].SetPoint(graphs[-2].GetN(),ROOT.Double(600.),0.,(val1+val2)/2.)
226 
227  graphs[-1].Write()
228  graphs[-2].Write()
229 
230 
231 
232 if skipcalc:
233  outputFile = ROOT.TFile(infile,"read")
234 
235 #### Get histograms from root file to allow reading of input to use same code for original calculation and cosmetic re-runs
236 
237 #make title list to facilitate cosmetics later
238 graphTitles = []
239 if("T2" not in topo):
240  graphTitles.append(["effmap","; m_{#tilde{g}} [GeV]; m_{#tilde{#chi}^{0}_{1}} [GeV]; Region 4 Efficiency"])
241  graphTitles.append(["yieldmap","; m_{#tilde{g}} [GeV]; m_{#tilde{#chi}^{0}_{1}} [GeV]; Region 4 Yield"])
242  for name in cosmeticbindefs:
243  graphTitles.append([name,"; m_{#tilde{g}} [GeV]; m_{#tilde{#chi}^{0}_{1}} [GeV]; Fraction of R4 efficiency from "+name])
244  graphTitles.append([name+"_yield","; m_{#tilde{g}} [GeV]; m_{#tilde{#chi}^{0}_{1}} [GeV]; R4 Yield with "+name])
245  graphTitles.append(["effmapR3","; m_{#tilde{g}} [GeV]; m_{#tilde{#chi}^{0}_{1}} [GeV]; Region 3 Efficiency"])
246  graphTitles.append(["yieldmapR3","; m_{#tilde{g}} [GeV]; m_{#tilde{#chi}^{0}_{1}} [GeV]; Region 3 Yield"])
247 
248 else:
249  graphTitles.append(["effmap","; m_{#tilde{t}} [GeV]; m_{#tilde{#chi}^{0}_{1}} [GeV]; Region 4 Efficiency"])
250  graphTitles.append(["yieldmap","; m_{#tilde{t}} [GeV]; m_{#tilde{#chi}^{0}_{1}} [GeV]; Region 4 Yield"])
251  for name in cosmeticbindefs:
252  graphTitles.append([name,"; m_{#tilde{t}} [GeV]; m_{#tilde{#chi}^{0}_{1}} [GeV]; Fraction of R4 efficiency from "+name])
253  graphTitles.append([name+"_yield","; m_{#tilde{t}} [GeV]; m_{#tilde{#chi}^{0}_{1}} [GeV]; R4 Yield with "+name])
254  graphTitles.append(["effmapR3","; m_{#tilde{t}} [GeV]; m_{#tilde{#chi}^{0}_{1}} [GeV]; Region 3 Efficiency"])
255  graphTitles.append(["yieldmapR3","; m_{#tilde{t}} [GeV]; m_{#tilde{#chi}^{0}_{1}} [GeV]; Region 3 Yield"])
256 
257 
258 # get max z-value
259 maxfrac = 0.
260 maxyield= 0.
261 for name,title in graphTitles:
262  if "map" in name: continue
263  #print name
264  graph = outputFile.Get(name)
265  if "yield" not in name:
266  if graph.GetHistogram().GetMaximum() > maxfrac: maxfrac = graph.GetHistogram().GetMaximum()
267  else:
268  if graph.GetHistogram().GetMaximum() > maxyield: maxyield = graph.GetHistogram().GetMaximum()
269 
270 
271 
272 set_palette()
273 if "T1" in topo or "T5" in topo:
274  frame = ROOT.TH2F("frame","",100,700,1950,152,0,1450)
275 if "T5tttt" in topo:
276  frame = ROOT.TH2F("frame","",100,700,1700,152,0,1300)
277 elif "T2" in topo or "T6" in topo:
278  frame = ROOT.TH2F("frame","",100,200,1000,152,0,500)
279 frame.SetStats(0)
280 frame.GetXaxis().SetNdivisions(506)
281 #ROOT.gStyle.SetPalette(56)
282 #frame = ROOT.TFrame(700,1950,0,1900)
283 #npx = int((max(glumass) - min(glumass))/5)
284 #npy = int((max(lspmass) - min(lspmass))/5)
285 npx = int((1950-700)/17.68)
286 npy = int(1450/17.68)
287 if "T5tttt" in topo: npy = int(1300/17.68)
288 #print "max frac is "+str(maxfrac)
289 for name,title in graphTitles:
290  graph = outputFile.Get(name)
291  graph.SetTitle(title)
292  frame.SetTitle(title)
293  graph.SetNpx(npx)
294  graph.SetNpy(npy)
295 
296  if "map" not in name: #standardize range for bin maps, not for inclusive map
297  if"yield" not in name:
298  graph.GetHistogram().SetMaximum(maxfrac)
299  graph.GetHistogram().SetMinimum(0)
300  else:
301  graph.GetHistogram().SetMaximum(maxyield)
302  graph.GetHistogram().SetMinimum(0.01)
303  # graph.GetZaxis().SetRangeUser(0,maxfrac)
304  # graph.SetMaximum(maxfrac)
305  # graph.SetMinimum(max)
306  c = ROOT.TCanvas()
307 
308  # hist.SetBinContent(hist.FindBin(600,0),(val1+val2)/2.)
309 
310  frame.Draw()
311  if("T1" in topo):
312  graph.GetHistogram().SetAxisRange(700,1950,"X")
313  graph.GetHistogram().SetAxisRange(0,1450,"Y")
314 
315  if("T5tttt" in topo):
316  # graph.GetHistogram().SetAxisRange(700,1600,"X")
317  graph.GetHistogram().GetXaxis().SetNdivisions(506)
318 
319 
320  graph.GetHistogram().Draw("colz same")
321  #graph.Draw("colz same")
322  frame.Draw("X axis same")
323 
324  tla = ROOT.TLatex()
325  tla.SetTextSize(0.038)
326  #if "yield" in name:
327  tla.DrawLatexNDC(0.14,0.93,"#font[62]{CMS} #scale[0.8]{#font[52]{Supplementary (Simulation)}}")
328  if "T1tttt" in topo: tla.DrawLatexNDC(0.17,0.87,"pp #rightarrow #tilde{g}#tilde{g}, #tilde{g} #rightarrow t#bar{t} #tilde{#chi}_{1}^{0}")
329  elif "T5tttt" in topo:
330  tla.DrawLatexNDC(0.17,0.87,"pp #rightarrow #tilde{g}#tilde{g}, #tilde{g} #rightarrow #tilde{t}#bar{t}, #tilde{t} #rightarrow t#tilde{#chi}_{1}^{0}")
331  tla.DrawLatexNDC(0.2,0.82,"m_{#tilde{t}} - m_{#tilde{#chi}_{1}^{0}} = 175 GeV")
332  elif "T5ZZ" in topo: tla.DrawLatexNDC(0.17,0.87,"pp #rightarrow #tilde{g}#tilde{g}, #tilde{g} #rightarrow q#bar{q} #tilde{#chi}_{1}^{0}, #tilde{#chi}_{1}^{0} #rightarrow Z^{0} #tilde{G}")
333  tla.SetTextFont(42)
334  if "yield" in name: tla.DrawLatexNDC(0.62,0.93, str(lumi)+" fb^{-1} (13 TeV)")
335  else: tla.DrawLatexNDC(0.75,0.93,"13 TeV")
336 
337 
338  if "yield" not in name:
339  outname =outfile+"efficiency_"+name.replace(" #leq","lte").replace(" #geq","gte").replace(" >","gt").replace(" =","").replace(", ","_").replace("H_{T}","ht").replace("n_{jets}","njets").replace("n_{lep}","nleps").replace("n_{b}","nbm").replace(" ","")
340  else:
341  outname =outfile+"yield_"+name.replace(" #leq","lte").replace(" #geq","gte").replace(" >","gt").replace(" =","").replace(", ","_").replace("H_{T}","ht").replace("n_{jets}","njets").replace("n_{lep}","nleps").replace("n_{b}","nbm").replace(" ","")
342  c.Print("plots/maps/"+outname+".pdf")
343  c.SetLogz(True)
344  c.Print("plots/maps/log_"+outname+".pdf")
345 
346 outputFile.Close()
347 
348 
349 
def signalCrossSection(glu_mass)
Definition: get_xsec.py:9
def get_weighted_entries(chain, cuts)
def stopCrossSection(stop_mass)
Definition: get_xsec_stop.py:9