ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/VHbb/python/scaleFactorPlot.py
Revision: 1.4
Committed: Fri Apr 5 12:42:21 2013 UTC (12 years, 1 month ago) by bortigno
Content type: text/x-python
Branch: MAIN
Changes since 1.3: +64 -54 lines
Log Message:
@UPDATE

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