ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/VHbb/python/scaleFactorPlot.py
Revision: 1.5
Committed: Fri Apr 5 14:28:28 2013 UTC (12 years, 1 month ago) by bortigno
Content type: text/x-python
Branch: MAIN
CVS Tags: lhcp_UnblindFix, hcp_Unblind, lhcp_11April, LHCP_PreAppFixAfterFreeze, HEAD
Changes since 1.4: +27 -5 lines
Log Message:
@UPDATE style

File Contents

# User Rev Content
1 bortigno 1.1 #!/usr/bin/env python
2     import re
3     from sys import argv, stdout, stderr, exit
4 bortigno 1.5 from myutils import StackMaker
5 bortigno 1.1 from optparse import OptionParser
6 bortigno 1.3 from HiggsAnalysis.CombinedLimit.DatacardParser import *
7     from HiggsAnalysis.CombinedLimit.ShapeTools import *
8     from copy import copy,deepcopy
9 bortigno 1.4 from numpy import matrix
10 bortigno 1.3
11    
12 bortigno 1.5 def conversion_y(y):
13     u = (y-ROOT.gPad.GetY1())/(ROOT.gPad.GetY2()-ROOT.gPad.GetY1())
14     return u;
15    
16     def conversion_x(x):
17     u = (x-ROOT.gPad.GetX1())/(ROOT.gPad.GetX2()-ROOT.gPad.GetX1())
18     return u;
19    
20    
21 bortigno 1.4 def trunc(f, n):
22     '''Truncates/pads a float f to n decimal places without rounding'''
23     slen = len('%.*f' % (n, f))
24     return str(f)[:slen]
25    
26 bortigno 1.3
27     def removeDouble(seq):
28     seen = set()
29     seen_add = seen.add
30     return [ x for x in seq if x not in seen and not seen_add(x)]
31    
32    
33     def getInputSigma(options):
34     opts = copy(options)
35    
36     file = open(opts.dc, "r")
37     # os.chdir(os.path.dirname(opts.dc))
38     opts.bin = True
39     opts.noJMax = None
40     opts.nuisancesToExclude = []
41     opts.stat = False
42     opts.excludeSyst = ['SF']
43     DC = parseCard(file, opts)
44    
45     theSyst = {}
46     nuiVar = {}
47     # if not opts.bin in DC.bins: raise RuntimeError, "Cannot open find %s in bins %s of %s" % (opts.bin,DC.bins,opts.dc)
48     b = DC.bins[0]
49     exps = {}
50     expNui = {}
51     for (p,e) in DC.exp[b].items(): # so that we get only self.DC.processes contributing to this bin
52     exps[p] = [ e, [] ]
53     expNui[p] = [ e, [] ]
54     # print DC.systs
55     for (lsyst,nofloat,pdf,pdfargs,errline) in DC.systs:
56     if pdf in ('param', 'flatParam'): continue
57     # begin skip systematics
58     skipme = False
59     for xs in opts.excludeSyst:
60     if not re.search(xs, lsyst):
61     skipme = True
62     if skipme: continue
63     # end skip systematics
64     counter = 0
65     for p in DC.exp[b].keys(): # so that we get only self.DC.processes contributing to this bin
66     if errline[b][p] == 0: continue
67     if p == 'QCD': continue
68     if pdf == 'gmN':
69     exps[p][1].append(1/sqrt(pdfargs[0]+1));
70     elif pdf == 'gmM':
71     exps[p][1].append(errline[b][p]);
72     elif type(errline[b][p]) == list:
73     kmax = max(errline[b][p][0], errline[b][p][1], 1.0/errline[b][p][0], 1.0/errline[b][p][1]);
74     exps[p][1].append(kmax-1.);
75     elif pdf == 'lnN':
76     exps[p][1].append(max(errline[b][p], 1.0/errline[b][p])-1.);
77     return exps
78    
79    
80    
81 bortigno 1.4 def get_scale_factors(channel,labels,shift,v_b,input_sigma,nuisances):
82     print 'Channel ' + channel
83 bortigno 1.3 sf=[]
84     sf_e=[]
85 bortigno 1.4 # correspondency_dictionary = {"TT":"TT","s_Top":"s_Top","Zj0b":"Z0b","Zj1b":"Z1b","Zj2b":"Z2b","Wj0b":"Wj0b","Wj1b":"Wj1b","Wj2b":"Wj2b","Zj1HF":"Z1b","Zj2HF":"Z2b","ZjLF":"Z0b"}
86     # correspondency_dictionary = {"TT":"TT","s_Top":"s_Top","Zj0b":"Zj0b","Zj1b":"Zj1b","Zj2b":"Zj2b","Wj0b":"Wj0b","Wj1b":"Wj1b","Wj2b":"Wj2b","Zj1HF":"Z1b","Zj2HF":"Z2b","ZjLF":"Z0b","s_Top":"s_Top"}
87 bortigno 1.3 correspondency_dictionary = {"TT":"TT","s_Top":"s_Top","Zj0b":"Zj0b","Zj1b":"Zj1b","Zj2b":"Zj2b","Wj0b":"Wj0b","Wj1b":"Wj1b","Wj2b":"Wj2b","Zj1HF":"Z1b","Zj2HF":"Z2b","ZjLF":"Z0b","s_Top":"s_Top"}
88     # print input_sigma
89     # print input_sigma['TT'][1][0]
90     # initial_uncertainty=0.2 # initial uncertainty. @TO FIX: this can go in a config or as input arg
91     count=0
92     print labels
93 bortigno 1.4 # channels = ['high','High','low','Low','Med','med']
94     # channels = ['Zee','Zmm']
95     channels = ['Zll']
96 bortigno 1.3 for i in v_b:
97     print 'Nuisances ' + nuisances[count]
98     for h in channels:
99     if h in channel and h in re.sub('M','m',re.sub('L','l',re.sub('H','h',nuisances[count]))):
100     print count
101     try:
102     print 'Label : ' + str(labels[count])
103     print 'Relative SF : ' + i[0]
104     print 'Relative Error : ' + i[1]
105     print 'Correspondance : ' + str(correspondency_dictionary[labels[count]])
106     print 'Input sigma list : ' + str(input_sigma[correspondency_dictionary[labels[count]]])
107     print 'Input sigma value : ' + str(input_sigma[correspondency_dictionary[labels[count]]][1][0])
108     sf.append(1+input_sigma[correspondency_dictionary[labels[count]]][1][0]*eval(i[0])) # calculate the actual value for the scale factors
109     sf_e.append(input_sigma[correspondency_dictionary[labels[count]]][1][0]*eval(i[1])) # calculate the actula value for the uncertainties
110     print sf
111     print sf_e
112     except:
113     print 'Problem evaluating the SF or the SF errors'
114     count+=1
115     print sf
116     print sf_e
117 bortigno 1.4 return [sf,sf_e]
118    
119    
120    
121     def getGraph(channel,labels,shift,v_b,input_sigma,x_position,y_position,nuisances):
122 bortigno 1.3
123 bortigno 1.4 sf = get_scale_factors(channel,labels,shift,v_b,input_sigma,nuisances)[0]
124     sf_e = get_scale_factors(channel,labels,shift,v_b,input_sigma,nuisances)[1]
125 bortigno 1.3 d = numpy.array(sf) # store scale factors in array
126     e = numpy.array(sf_e) # store scale factors errors in array
127     p = numpy.array(y_position)
128     zero = numpy.array(x_position)
129    
130     # for i in range(len(labels)):
131     # print 'CMSSW_vhbb_'+labels[i]+'_Zll_SF_8TeV '+ str(d[i]) + ' +/- ' + str(e[i])
132    
133     markerStyle = 20
134     if ('high' in channel or 'High' in channel ):
135     markerStyle = 21
136     if ('med' in channel or 'Med' in channel ):
137     markerStyle = 22
138 bortigno 1.4 if ('Zee' in channel ):
139     markerStyle = 21
140 bortigno 1.3
141     for i in range(len(p)): p[i] = p[i]+shift
142     print 'POSITIONS: '
143     print p
144     g = ROOT.TGraphErrors(n,d,p,e,zero)
145     g.SetFillColor(0)
146     g.SetLineColor(2)
147     g.SetLineWidth(3)
148     g.SetMarkerStyle(markerStyle)
149 bortigno 1.4 print 'Ok'
150 bortigno 1.3 return g
151    
152    
153    
154 bortigno 1.1
155     # import ROOT with a fix to get batch mode (http://root.cern.ch/phpBB3/viewtopic.php?t=3198)
156     hasHelp = False
157     for X in ("-h", "-?", "--help"):
158     if X in argv:
159     hasHelp = True
160     argv.remove(X)
161     argv.append( '-b-' )
162     import ROOT
163     ROOT.gROOT.SetBatch(True)
164     ROOT.gSystem.Load("libHiggsAnalysisCombinedLimit.so")
165     argv.remove( '-b-' )
166     if hasHelp: argv.append("-h")
167    
168     parser = OptionParser(usage="usage: %prog [options] in.root \nrun with --help to get list of options")
169     parser.add_option("--vtol", "--val-tolerance", dest="vtol", default=0.30, type="float", help="Report nuisances whose value changes by more than this amount of sigmas")
170     parser.add_option("--stol", "--sig-tolerance", dest="stol", default=0.10, type="float", help="Report nuisances whose sigma changes by more than this amount")
171     parser.add_option("--vtol2", "--val-tolerance2", dest="vtol2", default=2.0, type="float", help="Report severely nuisances whose value changes by more than this amount of sigmas")
172     parser.add_option("--stol2", "--sig-tolerance2", dest="stol2", default=0.50, type="float", help="Report severely nuisances whose sigma changes by more than this amount")
173     parser.add_option("-a", "--all", dest="all", default=False, action="store_true", help="Print all nuisances, even the ones which are unchanged w.r.t. pre-fit values.")
174     parser.add_option("-A", "--absolute", dest="abs", default=False, action="store_true", help="Report also absolute values of nuisance values and errors, not only the ones normalized to the input sigma")
175     parser.add_option("-p", "--poi", dest="poi", default="r", type="string", help="Name of signal strength parameter (default is 'r' as per text2workspace.py)")
176     parser.add_option("-f", "--format", dest="format", default="text", type="string", help="Output format ('text', 'latex', 'twiki'")
177     parser.add_option("-g", "--histogram", dest="plotfile", default=None, type="string", help="If true, plot the pulls of the nuisances to the given file.")
178     parser.add_option("--sf", "--scale-factor", dest="plotsf", default=None, type="string", help="If true, plot the scale factors in a histograms.")
179 bortigno 1.3 parser.add_option("-D", "--datacard", dest="dc", default="", help="Datacard to be plotted")
180 bortigno 1.1
181     (options, args) = parser.parse_args()
182     if len(args) == 0:
183     parser.print_usage()
184     exit(1)
185    
186     file = ROOT.TFile(args[0])
187     if file == None: raise RuntimeError, "Cannot open file %s" % args[0]
188     fit_s = file.Get("fit_s")
189     fit_b = file.Get("fit_b")
190     prefit = file.Get("nuisances_prefit")
191     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]
192     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]
193     if prefit == None or prefit.ClassName() != "RooArgSet": raise RuntimeError, "File %s does not contain the prefit nuisances 'nuisances_prefit'" % args[0]
194    
195     isFlagged = {}
196     table = {}
197     fpf_b = fit_b.floatParsFinal()
198     fpf_s = fit_s.floatParsFinal()
199     pulls = []
200 bortigno 1.4
201     correlation_matrix_name=[]
202     correlation_matrix=[[]]
203    
204 bortigno 1.1 for i in range(fpf_s.getSize()):
205     nuis_s = fpf_s.at(i)
206     name = nuis_s.GetName();
207     nuis_b = fpf_b.find(name)
208     nuis_p = prefit.find(name)
209 bortigno 1.4 if( name.find('SF') > 0. ):
210     correlation_matrix_name.append(name)
211 bortigno 1.1 row = []
212     flag = False;
213     mean_p, sigma_p = 0,0
214     if nuis_p == None:
215     if not options.abs: continue
216     row += [ "[%.2f, %.2f]" % (nuis_s.getMin(), nuis_s.getMax()) ]
217     else:
218     mean_p, sigma_p = (nuis_p.getVal(), nuis_p.getError())
219     if options.abs: row += [ "%.2f +/- %.2f" % (nuis_p.getVal(), nuis_p.getError()) ]
220     for fit_name, nuis_x in [('b', nuis_b), ('s',nuis_s)]:
221     if nuis_x == None:
222     row += [ " n/a " ]
223     else:
224     row += [ "%+.2f +/- %.2f" % (nuis_x.getVal(), nuis_x.getError()) ]
225     if nuis_p != None:
226     valShift = (nuis_x.getVal() - mean_p)/sigma_p
227     if fit_name == 'b':
228     pulls.append(valShift)
229     sigShift = nuis_x.getError()/sigma_p
230 bortigno 1.3 # print name
231     # print nuis_x.getError()
232     # print nuis_p.getVal()
233     # print sigShift
234 bortigno 1.1 if options.abs:
235     row[-1] += " (%+4.2fsig, %4.2f)" % (valShift, sigShift)
236     else:
237     row[-1] = " %+4.2f, %4.2f" % (valShift, sigShift)
238     if (abs(valShift) > options.vtol2 or abs(sigShift-1) > options.stol2):
239     isFlagged[(name,fit_name)] = 2
240     flag = True
241     elif (abs(valShift) > options.vtol or abs(sigShift-1) > options.stol):
242     if options.all: isFlagged[(name,fit_name)] = 1
243     flag = True
244     elif options.all:
245     flag = True
246     row += [ "%+4.2f" % fit_s.correlation(name, options.poi) ]
247     if flag or options.all: table[name] = row
248 bortigno 1.4 # filling correlation table
249     correlation_matrix_line=[]
250     for j in range(fpf_b.getSize()):
251     _nuis_b = fpf_b.at(j)
252     _name = _nuis_b.GetName();
253     if name.find('SF') > 0 and ( _name.find('SF') > 0 or options.all ) :
254     # print name + ' __CORR__ ' + _name
255     # print fit_b.correlation(name,_name)
256     # print _nuis_b.getError()
257     # print fit_b.correlation(name,_name)*_nuis_b.getError()
258     print name
259     print _name
260     print fit_b.correlation(name,_name)
261     correlation_matrix_line.append(trunc(fit_b.correlation(name,_name),2))
262     if len(correlation_matrix_line) > 0:
263     correlation_matrix.append(correlation_matrix_line)
264    
265     print correlation_matrix_name
266     print correlation_matrix[1]
267     print correlation_matrix[2]
268     print correlation_matrix[3]
269     print correlation_matrix[4]
270 bortigno 1.1
271     fmtstring = "%-40s %15s %15s %10s"
272     highlight = "*%s*"
273     morelight = "!%s!"
274     pmsub, sigsub = None, None
275     if options.format == 'text':
276     if options.abs:
277     fmtstring = "%-40s %15s %30s %30s %10s"
278     print fmtstring % ('name', 'pre fit', 'b-only fit', 's+b fit', 'rho')
279     else:
280     print fmtstring % ('name', 'b-only fit', 's+b fit', 'rho')
281     elif options.format == 'latex':
282     pmsub = (r"(\S+) \+/- (\S+)", r"$\1 \\pm \2$")
283     sigsub = ("sig", r"$\\sigma$")
284     highlight = "\\textbf{%s}"
285     morelight = "{{\\color{red}\\textbf{%s}}}"
286     if options.abs:
287     fmtstring = "%-40s & %15s & %30s & %30s & %6s \\\\"
288     print "\\begin{tabular}{|l|r|r|r|r|} \\hline ";
289     print (fmtstring % ('name', 'pre fit', '$b$-only fit', '$s+b$ fit', r'$\rho(\theta, \mu)$')), " \\hline"
290     else:
291     fmtstring = "%-40s & %15s & %15s & %6s \\\\"
292     print "\\begin{tabular}{|l|r|r|r|} \\hline ";
293     #what = r"$(x_\text{out} - x_\text{in})/\sigma_{\text{in}}$, $\sigma_{\text{out}}/\sigma_{\text{in}}$"
294     what = r"\Delta x/\sigma_{\text{in}}$, $\sigma_{\text{out}}/\sigma_{\text{in}}$"
295     print fmtstring % ('', '$b$-only fit', '$s+b$ fit', '')
296     print (fmtstring % ('name', what, what, r'$\rho(\theta, \mu)$')), " \\hline"
297     elif options.format == 'twiki':
298     pmsub = (r"(\S+) \+/- (\S+)", r"\1 ± \2")
299     sigsub = ("sig", r"σ")
300     highlight = "<b>%s</b>"
301     morelight = "<b style='color:red;'>%s</b>"
302     if options.abs:
303     fmtstring = "| <verbatim>%-40s</verbatim> | %-15s | %-30s | %-30s | %-15s |"
304     print "| *name* | *pre fit* | *b-only fit* | *s+b fit* | "
305     else:
306     fmtstring = "| <verbatim>%-40s</verbatim> | %-15s | %-15s | %-15s |"
307     print "| *name* | *b-only fit* | *s+b fit* | *corr.* |"
308     elif options.format == 'html':
309     pmsub = (r"(\S+) \+/- (\S+)", r"\1 &plusmn; \2")
310     sigsub = ("sig", r"&sigma;")
311     highlight = "<b>%s</b>"
312     morelight = "<strong>%s</strong>"
313     print """
314     <html><head><title>Comparison of nuisances</title>
315     <style type="text/css">
316     td, th { border-bottom: 1px solid black; padding: 1px 1em; }
317     td { font-family: 'Consolas', 'Courier New', courier, monospace; }
318     strong { color: red; font-weight: bolder; }
319     </style>
320     </head><body style="font-family: 'Verdana', sans-serif; font-size: 10pt;"><h1>Comparison of nuisances</h1>
321     <table>
322     """
323     if options.abs:
324     print "<tr><th>nuisance</th><th>pre fit</th><th>background fit </th><th>signal fit</th><th>correlation</th></tr>"
325     fmtstring = "<tr><td><tt>%-40s</tt> </td><td> %-15s </td><td> %-30s </td><td> %-30s </td><td> %-15s </td></tr>"
326     else:
327     what = "&Delta;x/&sigma;<sub>in</sub>, &sigma;<sub>out</sub>/&sigma;<sub>in</sub>";
328     print "<tr><th>nuisance</th><th>background fit<br/>%s </th><th>signal fit<br/>%s</th><th>&rho;(&mu;, &theta;)</tr>" % (what,what)
329     fmtstring = "<tr><td><tt>%-40s</tt> </td><td> %-15s </td><td> %-15s </td><td> %-15s </td></tr>"
330    
331     names = table.keys()
332     names.sort()
333     highlighters = { 1:highlight, 2:morelight };
334     for n in names:
335     v = table[n]
336     if options.format == "latex": n = n.replace(r"_", r"\_")
337     if pmsub != None: v = [ re.sub(pmsub[0], pmsub[1], i) for i in v ]
338     if sigsub != None: v = [ re.sub(sigsub[0], sigsub[1], i) for i in v ]
339     if (n,'b') in isFlagged: v[-3] = highlighters[isFlagged[(n,'b')]] % v[-3]
340     if (n,'s') in isFlagged: v[-2] = highlighters[isFlagged[(n,'s')]] % v[-2]
341     if options.abs:
342     print fmtstring % (n, v[0], v[1], v[2], v[3])
343     else:
344     print fmtstring % (n, v[0], v[1], v[2])
345    
346     if options.format == "latex":
347     print " \\hline\n\end{tabular}"
348     elif options.format == "html":
349     print "</table></body></html>"
350    
351     if options.plotfile:
352     import ROOT
353     ROOT.gROOT.SetStyle("Plain")
354     ROOT.gStyle.SetOptFit(1)
355     histogram = ROOT.TH1F("pulls", "Pulls", 60, -3, 3)
356     for pull in pulls:
357     histogram.Fill(pull)
358     canvas = ROOT.TCanvas("asdf", "asdf", 800, 800)
359     histogram.GetXaxis().SetTitle("pull")
360     histogram.SetTitle("Post-fit nuisance pull distribution")
361     histogram.SetMarkerStyle(20)
362     histogram.SetMarkerSize(2)
363     #histogram.Fit("gaus")
364     histogram.Draw("pe")
365     canvas.SaveAs(options.plotfile)
366    
367    
368 bortigno 1.2 ########### SCALE FACTOR PLOT ###############
369     ## If you fit scale factors this part of ##
370     ## will create a plt reading from the ##
371     ## nuisances. All the nuisance cointaning ##
372     ## "SF" in their name will be plotted ##
373     #############################################
374    
375 bortigno 1.1 import numpy
376 bortigno 1.3 if options.plotsf and options.dc:
377 bortigno 1.1 n=0
378     labels=[]
379 bortigno 1.2 v_s=[] # dX/sigma_in values
380     v_b=[] # sigma_out/sigma_in values
381     rho=[] # rho
382     sys=[] # systematics. Not properly filled yet
383     x_position=[] # x position in the plot, basically the SF value
384     y_position=[] # y position in the plot. @TO IMPLEMENT: According to the number of entries per background the spacing is different.
385 bortigno 1.3 #!! loop on all the nuisances
386 bortigno 1.1 for name in names:
387 bortigno 1.3 #!! take only the nuisances which have SF in their name
388 bortigno 1.1 if ('SF' in name ):
389     print name
390     labels.append(name)
391     n+=1
392 bortigno 1.3 #!! take the values
393     #!! the usual order is: dX/sigma_in for background only - sigma_out/sigma_in for background only - dX/sigma_in for background+signal - sigma_out/sigma_in for background+signal - rho
394 bortigno 1.2 v = table[name]
395 bortigno 1.3 #!! forget about the flag
396 bortigno 1.1 v = [ re.sub('!','',i) for i in v ]
397 bortigno 1.3 v = [ re.sub('\*','',i) for i in v ]
398 bortigno 1.1 if pmsub != None: v = [ re.sub(pmsub[0], pmsub[1], i) for i in v ]
399     if sigsub != None: v = [ re.sub(sigsub[0], sigsub[1], i) for i in v ]
400     v_b.append(v[0].split(','))
401     v_s.append(v[1].split(','))
402     rho.append(v[2].split(','))
403     x_position.append(0.)
404 bortigno 1.2 y_position.append(n-1.)
405 bortigno 1.3 sys.append(0.1) #@TO FIX: need to decide how to quote the systematics and where to take them from
406 bortigno 1.2
407     # count the number of different channels
408 bortigno 1.3 channels = [0.,0.,0.,0.,0.]
409 bortigno 1.4 ch={'Zll':0.,'Zll low Pt':0.,'Zll high Pt':0.,'Wln':0.,'Wln low Pt':0.,'Wln high Pt':0.,'Znn':0.,'Znn low Pt':0.,'Znn high Pt':0.,'Znn med Pt':0.,'Zee':0.,'Zmm':0.}
410 bortigno 1.2 print labels
411     for label in labels:
412 bortigno 1.3 #!! create channel list and labels for legend
413 bortigno 1.4 if label.find('Zee') > 0. :
414     ch['Zee'] = 1.
415     if label.find('Zmm') > 0. :
416     ch['Zmm'] = 1.
417 bortigno 1.3 if label.find('Zll') > 0. :
418     if label.find('lowPt') > 0.:
419     ch['Zll low Pt'] = 1.
420     elif label.find('highPt') > 0.:
421     ch['Zll high Pt'] = 1.
422     else:
423     ch['Zll'] = 1.
424     if label.find('Wln') > 0. :
425     if label.find('lowPt') > 0.:
426     ch['Wln low Pt'] = 1.
427     elif label.find('highPt') > 0.:
428     ch['Wln high Pt'] = 1.
429     else:
430     ch['Wln'] = 1.
431     if label.find('Znunu') > 0. :
432     if label.find('LowPt') > 0.:
433     ch['Znunu low Pt'] = 1.
434     elif label.find('MedPt') > 0.:
435     ch['Znunu med Pt'] = 1.
436     elif label.find('HighPt') > 0.:
437     ch['Znunu high Pt'] = 1.
438     else:
439     ch['Znunu'] = 1.
440    
441 bortigno 1.2 # calculate the shift on the y position
442     shift=0.
443 bortigno 1.3 for channel,active in ch.iteritems(): shift+=active;
444 bortigno 1.2 shift=1./(shift+1)
445 bortigno 1.3
446 bortigno 1.2 #shift the elements in the array
447 bortigno 1.3 # for i in range(0,len(y_position)): y_position[i]+=shift
448    
449     print 'Y_POSITION'
450 bortigno 1.2 print y_position
451 bortigno 1.3 # clean the labels
452     nuisances = labels
453 bortigno 1.2 labels = [re.sub('CMS_vhbb_','',label) for label in labels ]
454     try:
455 bortigno 1.3 labels = [re.sub('_Zll_SF_','',label) for label in labels ]
456     labels = [re.sub('_Wln_SF_','',label) for label in labels ]
457 bortigno 1.4 labels = [re.sub('_Zee_SF_','',label) for label in labels ]
458     labels = [re.sub('_Zmm_SF_','',label) for label in labels ]
459 bortigno 1.3 labels = [re.sub('_SF_Znunu','',label) for label in labels ]
460     labels = [re.sub('lowPt_8TeV','',label) for label in labels ]
461     labels = [re.sub('highPt_8TeV','',label) for label in labels ]
462     labels = [re.sub('medPt_8TeV','',label) for label in labels ]
463     labels = [re.sub('_Zll_lowPt_SF_8TeV','',label) for label in labels ]
464     labels = [re.sub('_Zll_highPt_SF_8TeV','',label) for label in labels ]
465 bortigno 1.4 labels = [re.sub('_LowPt','',label) for label in labels ]
466     labels = [re.sub('_HighPt','',label) for label in labels ]
467 bortigno 1.3 labels = [re.sub('LowPt_8TeV','',label) for label in labels ]
468     labels = [re.sub('MedPt_8TeV','',label) for label in labels ]
469     labels = [re.sub('HighPt_8TeV','',label) for label in labels ]
470     labels = [re.sub('8TeV','',label) for label in labels ]
471     labels = [re.sub('8TeV','',label) for label in labels ]
472 bortigno 1.2 except:
473     print '@WARNING: No usual naming for datacard scale factors nuisances'
474     print labels
475    
476     #CMS_vhbb_TT_Zll_SF_8TeV ! +0.56, 0.13! ! +0.54, 0.13! -0.00
477     #CMS_vhbb_ZjHF_Zll_SF_8TeV +1.79, 1.14 +1.80, 1.13 +0.00
478     #CMS_vhbb_ZjLF_Zll_SF_8TeV ! +3.51, 0.94! ! +3.42, 0.95! -0.00
479    
480 bortigno 1.1 print n
481     print labels
482     print v_s
483     print v_b
484     print rho
485 bortigno 1.3
486     label_dictionary = {"TT":"t#bar{t}","ZjHF":"Z+bX","ZjLF":"Z+udscg","Zj1HF":"Z+b","Zj2HF":"Z+b#bar{b}","Wj0b":"W+light","Wj1b":"W+b","Wj2b":"W+b#bar{b}","Zj0b":"Z+light","Zj1b":"Z+b","Zj2b":"Z+b#bar{b}","s_Top":"t"}
487 bortigno 1.1 c = ROOT.TCanvas("c","c",600,600)
488    
489 bortigno 1.3 input_sigma = getInputSigma(options)
490     print 'Input sigma'
491     print input_sigma
492    
493     graphs={}
494 bortigno 1.5 latex={}
495 bortigno 1.3 j=1
496     for channel,active in ch.iteritems():
497     print channel
498     print active
499     if active > 0.:
500     graphs[channel] = getGraph(channel,labels,j*shift,v_b,input_sigma,x_position,y_position,nuisances) # create the graph with the scale factors
501 bortigno 1.5 sf = get_scale_factors(channel,labels,shift,v_b,input_sigma,nuisances)[0]
502     sf_e = get_scale_factors(channel,labels,shift,v_b,input_sigma,nuisances)[1]
503     for i in range(0,len(sf)):
504     latex[labels[i]] = [labels[i],sf[i],sf_e[i],y_position[i]+0.35*shift]
505     print "%s %s pm %s" %(labels[i],sf[i],sf_e[i])
506 bortigno 1.3 j+=1
507    
508     print graphs
509    
510 bortigno 1.5 xmin = 0.25
511     xmax = 2.5
512 bortigno 1.3 labels = removeDouble(labels)
513     n= len(labels)
514 bortigno 1.5 h2 = ROOT.TH2F("h2","",1,xmin,xmax,n,0,n) # x min - max values.
515 bortigno 1.1 h2.GetXaxis().SetTitle("Scale factor")
516    
517     for i in range(n):
518 bortigno 1.2 h2.GetYaxis().SetBinLabel(i+1,label_dictionary[labels[i]])
519 bortigno 1.1
520 bortigno 1.3
521     drawSys=False
522     if(drawSys):
523     #for the moment just random systematics
524     sys_e = numpy.array(sys)
525     #!! Create the graph for the systematics, if any. It will show only error brackets, no points
526     g2 = ROOT.TGraphErrors(n,d,p,sys_e,zero)
527     g2.SetFillColor(0)
528     g2.SetLineWidth(3);
529 bortigno 1.1
530     h2.Draw(); ROOT.gStyle.SetOptStat(0);
531     h2.GetXaxis().SetTitleSize(0.04);
532     h2.GetXaxis().SetLabelSize(0.04);
533     h2.GetYaxis().SetLabelSize(0.06);
534     #h2.SetFillStyle(4000)
535     c.SetFillStyle(4000)
536    
537     globalFitBand = ROOT.TBox(1.0, 0., 1.5, n);
538     globalFitBand.SetFillStyle(3013);
539     globalFitBand.SetFillColor(65);
540     globalFitBand.SetLineStyle(0);
541     #globalFitBand.Draw("same");
542 bortigno 1.2 globalFitLine = ROOT.TLine(1.0, 0., 1.0, n);
543 bortigno 1.1 globalFitLine.SetLineWidth(2);
544     globalFitLine.SetLineColor(214);#214
545     globalFitLine.Draw("same");
546 bortigno 1.3
547     #!! Legend
548 bortigno 1.5 l2 = ROOT.TLegend(0.68, 0.80,0.80,0.85)
549 bortigno 1.1 l2.SetLineWidth(2)
550     l2.SetBorderSize(0)
551     l2.SetFillColor(0)
552     l2.SetFillStyle(4000)
553     l2.SetTextFont(62)
554 bortigno 1.3 for channel,g in graphs.iteritems():
555     print channel
556 bortigno 1.5 l2.AddEntry(g,'ZH, Z#rightarrowl^{+}l^{-}',"pl")
557     # l2.AddEntry(g,channel,"pl")
558 bortigno 1.3 #l2.AddEntry(g,"Stat.","l")
559     if(drawSys) : l2.AddEntry(g2,"Syst.","l")
560 bortigno 1.1 l2.SetTextSize(0.035)
561 bortigno 1.3 # l2.SetNColumns(3)
562 bortigno 1.1 l2.Draw("same")
563 bortigno 1.4 for channel,g in graphs.iteritems():
564     print channel
565     g.Draw("P same")
566 bortigno 1.5 for label in labels:
567     StackMaker.myText("%.2f #pm %.2f" %(latex[label][1],latex[label][2]),conversion_x(xmin)-0.02,conversion_y(latex[label][3]),0.5)
568 bortigno 1.3 if(drawSys) : g2.Draw("[] same")
569 bortigno 1.5 StackMaker.myText("CMS Preliminary",conversion_x(xmin)+0.1,0.95,0.6)
570     StackMaker.myText("#sqrt{s} = 8TeV, L = 19.0 fb^{-1}",conversion_x(xmin)+0.1,0.92,0.6)
571    
572 bortigno 1.1 ROOT.gPad.SetLeftMargin(0.2)
573     ROOT.gPad.Update()
574     c.Print("histo.pdf")
575    
576 bortigno 1.3
577    
578