ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/VHbb/python/stack_from_dc.py
Revision: 1.14
Committed: Wed Jan 16 16:22:47 2013 UTC (12 years, 3 months ago) by peller
Content type: text/x-python
Branch: MAIN
CVS Tags: workingVersionAfterHCP
Changes since 1.13: +10 -14 lines
Log Message:
reorganized the whole repository. Macros im myutils, config files in subdirectories. Config file split in parts. Path config file restructured. Moved all path options to the path config. Changed the code accordingly.

File Contents

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