ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/VHbb/python/stack_from_dc.py
Revision: 1.2
Committed: Tue Nov 6 13:51:05 2012 UTC (12 years, 6 months ago) by nmohr
Content type: text/x-python
Branch: MAIN
Changes since 1.1: +4 -4 lines
Log Message:
Add bin for plot

File Contents

# User Rev Content
1 nmohr 1.1 #!/usr/bin/env python
2     import pickle
3     import ROOT
4     from BetterConfigParser import BetterConfigParser
5     import sys, os
6     from optparse import OptionParser
7     from copy import copy,deepcopy
8     from StackMaker import StackMaker
9     from math import sqrt
10     import math
11     from HiggsAnalysis.CombinedLimit.DatacardParser import *
12     from HiggsAnalysis.CombinedLimit.ShapeTools import *
13    
14     ROOT.gROOT.SetBatch(True)
15     ROOT.gSystem.Load("libHiggsAnalysisCombinedLimit.so")
16    
17     #CONFIGURE
18     argv = sys.argv
19     parser = OptionParser()
20     parser.add_option("-D", "--datacard", dest="dc", default="",
21     help="Datacard to be plotted")
22     parser.add_option("-B", "--bin", dest="bin", default="",
23     help="DC bin to plot")
24     parser.add_option("-M", "--mlfit", dest="mlfit", default="",
25     help="mlfit file for nuisances")
26     parser.add_option("-F", "--fitresult", dest="fit", default="s",
27     help="Fit result to be used, 's' (signal+background) or 'b' (background only), default is 's'")
28     parser.add_option("-C", "--config", dest="config", default=[], action="append",
29     help="configuration file")
30     (opts, args) = parser.parse_args(argv)
31    
32    
33     def readBestFit(theFile):
34     file = ROOT.TFile(theFile)
35     if file == None: raise RuntimeError, "Cannot open file %s" % args[0]
36     fit_s = file.Get("fit_s")
37     fit_b = file.Get("fit_b")
38     prefit = file.Get("nuisances_prefit")
39     if fit_s == None or fit_s.ClassName() != "RooFitResult": raise RuntimeError, "File %s does not contain the output of the signal fit 'fit_s'" % args[0]
40     if fit_b == None or fit_b.ClassName() != "RooFitResult": raise RuntimeError, "File %s does not contain the output of the background fit 'fit_b'" % args[0]
41     if prefit == None or prefit.ClassName() != "RooArgSet": raise RuntimeError, "File %s does not contain the prefit nuisances 'nuisances_prefit'" % args[0]
42    
43     isFlagged = {}
44     table = {}
45     fpf_b = fit_b.floatParsFinal()
46     fpf_s = fit_s.floatParsFinal()
47     nuiVariation = {}
48     for i in range(fpf_s.getSize()):
49     nuis_s = fpf_s.at(i)
50     name = nuis_s.GetName();
51     nuis_b = fpf_b.find(name)
52     nuis_p = prefit.find(name)
53     if nuis_p != None:
54     mean_p, sigma_p = (nuis_p.getVal(), nuis_p.getError())
55     for fit_name, nuis_x in [('b', nuis_b), ('s',nuis_s)]:
56     if nuis_p != None:
57     valShift = (nuis_x.getVal() - mean_p)/sigma_p
58     #sigShift = nuis_x.getError()/sigma_p
59     print fit_name, name
60     print valShift
61     nuiVariation['%s_%s'%(fit_name,name)] = valShift
62     #print valShift
63     return nuiVariation
64    
65    
66     def drawFromDC():
67     config = BetterConfigParser()
68     config.read(opts.config)
69     print config.sections()
70     region = 'BDT'
71     var = 'BDT'
72     ws_var = config.get('plotDef:%s'%var,'relPath')
73     blind = eval(config.get('Plot:%s'%region,'blind'))
74     Stack=StackMaker(config,var,region,True)
75    
76     dataname = ''
77     if 'Zmm' in opts.bin: dataname = 'Zmm'
78     elif 'Zee' in opts.bin: dataname = 'Zee'
79     elif 'Wmn' in opts.bin: dataname = 'Wmn'
80     elif 'Wen' in opts.bin: dataname = 'Wen'
81     elif 'Znn' in opts.bin: dataname = 'Znn'
82    
83     log = eval(config.get('Plot:%s'%region,'log'))
84    
85     setup = config.get('Plot_general','setup').split(',')
86     Dict = eval(config.get('LimitGeneral','Dict'))
87     lumi = eval(config.get('Plot_general','lumi'))
88    
89     options = copy(opts)
90     options.dataname = "data_obs"
91     options.mass = 0
92     options.format = "%8.3f +/- %6.3f"
93 nmohr 1.2 options.channel = opts.bin
94 nmohr 1.1 options.excludeSyst = []
95     options.norm = False
96     options.stat = False
97     options.bin = True # fake that is a binary output, so that we parse shape lines
98     options.out = "tmp.root"
99     options.fileName = args[0]
100     options.cexpr = False
101     options.fixpars = False
102     options.libs = []
103     options.verbose = 0
104     options.poisson = 0
105     options.nuisancesToExclude = []
106     options.noJMax = None
107    
108     file = open(opts.dc, "r")
109     os.chdir(os.path.dirname(opts.dc))
110     DC = parseCard(file, options)
111     if not DC.hasShapes: DC.hasShapes = True
112     MB = ShapeBuilder(DC, options)
113     theShapes = {}
114     theSyst = {}
115     if opts.mlfit:
116     nuiVar = readBestFit(opts.mlfit)
117     for b in DC.bins:
118     if options.channel != None and (options.channel != b): continue
119     exps = {}
120     expNui = {}
121     shapeNui = {}
122     for (p,e) in DC.exp[b].items(): # so that we get only self.DC.processes contributing to this bin
123     exps[p] = [ e, [] ]
124     expNui[p] = [ e, [] ]
125     for (lsyst,nofloat,pdf,pdfargs,errline) in DC.systs:
126     if pdf in ('param', 'flatParam'): continue
127     # begin skip systematics
128     skipme = False
129     for xs in options.excludeSyst:
130     if re.search(xs, lsyst):
131     skipme = True
132     if skipme: continue
133     # end skip systematics
134     counter = 0
135     for p in DC.exp[b].keys(): # so that we get only self.DC.processes contributing to this bin
136     if errline[b][p] == 0: continue
137     if pdf == 'gmN':
138     exps[p][1].append(1/sqrt(pdfargs[0]+1));
139     elif pdf == 'gmM':
140     exps[p][1].append(errline[b][p]);
141     elif type(errline[b][p]) == list:
142     kmax = max(errline[b][p][0], errline[b][p][1], 1.0/errline[b][p][0], 1.0/errline[b][p][1]);
143     exps[p][1].append(kmax-1.);
144     elif pdf == 'lnN':
145     exps[p][1].append(max(errline[b][p], 1.0/errline[b][p])-1.);
146     if not nuiVar.has_key('%s_%s'%(opts.fit,lsyst)):
147     nui = 0.
148     else:
149     nui= nuiVar['%s_%s'%(opts.fit,lsyst)]
150     expNui[p][1].append(abs(1-errline[b][p])*nui);
151     elif ("shape" in pdf) and not 'CMS_vhbb_stats_' in lsyst:
152     s0 = MB.getShape(b,p)
153     sUp = MB.getShape(b,p,lsyst+"Up")
154     sDown = MB.getShape(b,p,lsyst+"Down")
155     if (s0.InheritsFrom("RooDataHist")):
156     s0 = ROOT.RooAbsData.createHistogram(s0,ws_var)
157     s0.SetName(p)
158     sUp = ROOT.RooAbsData.createHistogram(sUp,ws_var)
159     sUp.SetName(p+lsyst+'Up')
160     sDown = ROOT.RooAbsData.createHistogram(sDown,ws_var)
161     sDown.SetName(p+lsyst+'Down')
162     theShapes[p] = s0.Clone()
163     theShapes[p+lsyst+'Up'] = sUp.Clone()
164     theShapes[p+lsyst+'Down'] = sDown.Clone()
165     if not nuiVar.has_key('%s_%s'%(opts.fit,lsyst)):
166     nui = 0.
167     else:
168     nui= nuiVar['%s_%s'%(opts.fit,lsyst)]
169     shapeNui[p] = nui
170     if counter == 0:
171     theSyst[lsyst] = s0.Clone()
172     theSyst[lsyst+'Up'] = sUp.Clone()
173     theSyst[lsyst+'Down'] = sDown.Clone()
174     else:
175     theSyst[lsyst].Add(s0)
176     theSyst[lsyst+'Up'].Add(sUp.Clone())
177     theSyst[lsyst+'Down'].Add(sDown.Clone())
178     counter += 1
179     procs = DC.exp[b].keys(); procs.sort()
180     fmt = ("%%-%ds " % max([len(p) for p in procs]))+" "+options.format;
181     #Compute norm uncertainty and best fit
182     theNormUncert = {}
183     theBestFit = {}
184     for p in procs:
185     relunc = sqrt(sum([x*x for x in exps[p][1]]))
186     print fmt % (p, exps[p][0], exps[p][0]*relunc)
187     theNormUncert[p] = relunc
188     absBestFit = sum([x for x in expNui[p][1]])
189     theBestFit[p] = 1.+absBestFit
190    
191     histos = []
192     typs = []
193    
194     setup2=copy(setup)
195    
196     shapesUp = [[] for _ in range(0,len(setup2))]
197     shapesDown = [[] for _ in range(0,len(setup2))]
198    
199     for p in procs:
200 nmohr 1.2 b = opts.bin
201 nmohr 1.1 for s in setup:
202     if not Dict[s] == p: continue
203     if 'ZH' == s:
204     Overlay=copy(theShapes[Dict[s]])
205     else:
206     histos.append(theShapes[Dict[s]])
207     typs.append(s)
208     print s
209     for (lsyst,nofloat,pdf,pdfargs,errline) in DC.systs:
210     if errline[b][p] == 0: continue
211     if ("shape" in pdf) and not 'CMS_vhbb_stats_' in lsyst:
212     print 'syst %s'%lsyst
213     shapesUp[setup2.index(s)].append(theShapes[Dict[s]+lsyst+'Up'])
214     shapesDown[setup2.index(s)].append(theShapes[Dict[s]+lsyst+'Down'])
215    
216     #-------------
217     #Compute absolute uncertainty from shapes
218     counter = 0
219     for (lsyst,nofloat,pdf,pdfargs,errline) in DC.systs:
220     if ("shape" in pdf) and not 'CMS_vhbb_stats_' in lsyst:
221     theSystUp = theSyst[lsyst+'Up'].Clone()
222     theSystUp.Add(theSyst[lsyst].Clone(),-1.)
223     theSystUp.Multiply(theSystUp)
224     theSystDown = theSyst[lsyst+'Down'].Clone()
225     theSystDown.Add(theSyst[lsyst].Clone(),-1.)
226     theSystDown.Multiply(theSystDown)
227     if counter == 0:
228     theAbsSystUp = theSystUp.Clone()
229     theAbsSystDown = theSystDown.Clone()
230     else:
231     theAbsSystUp.Add(theSystUp.Clone())
232     theAbsSystDown.Add(theSystDown.Clone())
233     counter +=1
234    
235     #-------------
236     #Best fit for shapes
237     for p in procs:
238     counter = 0
239     nom = theShapes[p].Clone()
240     for (lsyst,nofloat,pdf,pdfargs,errline) in DC.systs:
241     if errline[b][p] == 0: continue
242     if ("shape" in pdf) and not 'CMS_vhbb_stats_' in lsyst and not 'CMS_vhbb_model_VV' in lsyst:
243     if shapeNui > 0.:
244     theVari = 'Up'
245     else:
246     theVari = 'Down'
247     bestNuiVar = theShapes[p+lsyst+theVari].Clone()
248     bestNuiVar.Add(nom,-1.)
249     bestNuiVar.Scale(abs(shapeNui[p]))
250     if counter == 0:
251     bestNui = bestNuiVar.Clone()
252     else:
253     bestNui.Add(bestNuiVar)
254     counter +=1
255     nom.Add(bestNui)
256 nmohr 1.2 nom.Scale(theShapes[p].Integral()/nom.Integral())
257 nmohr 1.1 nBins = nom.GetNbinsX()
258     for bin in range(1,nBins+1):
259     nom.SetBinError(bin,theShapes[p].GetBinError(bin))
260     theShapes['%s_%s'%(opts.fit,p)] = nom.Clone()
261     histos = []
262     typs = []
263     for s in setup:
264     if 'ZH' == s:
265     Overlay=copy(theShapes[Dict[s]])
266     else:
267     histos.append(theShapes['%s_%s'%(opts.fit,Dict[s])])
268     typs.append(s)
269    
270     counter = 0
271     errUp=[]
272     total=[]
273     errDown=[]
274     nBins = histos[0].GetNbinsX()
275     print 'total bins %s'%nBins
276     Error = ROOT.TGraphAsymmErrors(histos[0])
277     theTotalMC = histos[0].Clone()
278     for h in range(1,len(histos)):
279     theTotalMC.Add(histos[h])
280    
281     total = [[]]*nBins
282     errUp = [[]]*nBins
283     errDown = [[]]*nBins
284     for bin in range(1,nBins+1):
285     binError = theTotalMC.GetBinError(bin)
286     if math.isnan(binError):
287     binError = 0.
288     total[bin-1]=theTotalMC.GetBinContent(bin)
289     #Stat uncertainty of the MC outline
290     errUp[bin-1] = [binError]
291     errDown[bin-1] = [binError]
292     #Relative norm uncertainty of the individual MC
293     for h in range(0,len(histos)):
294     errUp[bin-1].append(histos[h].GetBinContent(bin)*theNormUncert[histos[h].GetName()])
295     errDown[bin-1].append(histos[h].GetBinContent(bin)*theNormUncert[histos[h].GetName()])
296     #Shape uncertainty of the MC
297     for bin in range(1,nBins+1):
298     #print sqrt(theSystUp.GetBinContent(bin))
299     errUp[bin-1].append(sqrt(theAbsSystUp.GetBinContent(bin)))
300     errDown[bin-1].append(sqrt(theAbsSystDown.GetBinContent(bin)))
301    
302    
303     #Add all in quadrature
304     totErrUp=[sqrt(sum([x**2 for x in bin])) for bin in errUp]
305     totErrDown=[sqrt(sum([x**2 for x in bin])) for bin in errDown]
306    
307     #Make TGraph with errors
308     for bin in range(1,nBins+1):
309     if not total[bin-1] == 0:
310     point=histos[0].GetXaxis().GetBinCenter(bin)
311     Error.SetPoint(bin-1,point,1)
312     Error.SetPointEYlow(bin-1,totErrDown[bin-1]/total[bin-1])
313     print 'down %s'%(totErrDown[bin-1]/total[bin-1])
314     Error.SetPointEYhigh(bin-1,totErrUp[bin-1]/total[bin-1])
315     print 'up %s'%(totErrUp[bin-1]/total[bin-1])
316    
317     #-----------------------
318     #Read data
319 nmohr 1.2 data0 = MB.getShape(opts.bin,'data_obs')
320 nmohr 1.1 if (data0.InheritsFrom("RooDataHist")):
321     data0 = ROOT.RooAbsData.createHistogram(data0,ws_var)
322     data0.SetName('data_obs')
323     datas=[data0]
324     datatyps = [None]
325     datanames=[dataname]
326    
327    
328     if blind:
329     for bin in range(10,datas[0].GetNbinsX()+1):
330     datas[0].SetBinContent(bin,0)
331    
332     histos.append(copy(Overlay))
333     typs.append('ZH')
334    
335     Stack.histos = histos
336     Stack.typs = typs
337     Stack.datas = datas
338     Stack.datatyps = datatyps
339     Stack.datanames= datanames
340     Stack.overlay = Overlay
341     Stack.AddErrors=Error
342     Stack.lumi = lumi
343     Stack.doPlot()
344    
345     print 'i am done!\n'
346     #-------------------------------------------------
347    
348    
349     if __name__ == "__main__":
350     drawFromDC()
351     sys.exit(0)