1 |
import ROOT
|
2 |
ROOT.gROOT.SetBatch(True)
|
3 |
import sys,os
|
4 |
from BetterConfigParser import BetterConfigParser
|
5 |
import TdrStyles
|
6 |
from Ratio import getRatio
|
7 |
from HistoMaker import HistoMaker
|
8 |
|
9 |
class StackMaker:
|
10 |
def __init__(self, config, var,region,SignalRegion,setup=None):
|
11 |
section='Plot:%s'%region
|
12 |
self.var = var
|
13 |
self.SignalRegion=SignalRegion
|
14 |
self.normalize = eval(config.get(section,'Normalize'))
|
15 |
self.log = eval(config.get(section,'log'))
|
16 |
if config.has_option('plotDef:%s'%var,'log') and not self.log:
|
17 |
self.log = eval(config.get('plotDef:%s'%var,'log'))
|
18 |
self.blind = eval(config.get(section,'blind'))
|
19 |
if setup is None:
|
20 |
self.setup=config.get('Plot_general','setup')
|
21 |
if self.log:
|
22 |
self.setup=config.get('Plot_general','setupLog')
|
23 |
self.setup=self.setup.split(',')
|
24 |
else:
|
25 |
self.setup=setup
|
26 |
if not SignalRegion:
|
27 |
if 'ZH' in self.setup:
|
28 |
self.setup.remove('ZH')
|
29 |
if 'WH' in self.setup:
|
30 |
self.setup.remove('WH')
|
31 |
self.rebin = 1
|
32 |
if config.has_option(section,'rebin'):
|
33 |
self.rebin = eval(config.get(section,'rebin'))
|
34 |
if config.has_option(section,'nBins'):
|
35 |
self.nBins = int(eval(config.get(section,'nBins'))/self.rebin)
|
36 |
else:
|
37 |
self.nBins = int(eval(config.get('plotDef:%s'%var,'nBins'))/self.rebin)
|
38 |
print self.nBins
|
39 |
if config.has_option(section,'min'):
|
40 |
self.xMin = eval(config.get(section,'min'))
|
41 |
else:
|
42 |
self.xMin = eval(config.get('plotDef:%s'%var,'min'))
|
43 |
if config.has_option(section,'max'):
|
44 |
self.xMax = eval(config.get(section,'max'))
|
45 |
else:
|
46 |
self.xMax = eval(config.get('plotDef:%s'%var,'max'))
|
47 |
self.name = config.get('plotDef:%s'%var,'relPath')
|
48 |
self.mass = config.get(section,'Signal')
|
49 |
data = config.get(section,'Datas')
|
50 |
if '<mass>' in self.name:
|
51 |
self.name = self.name.replace('<mass>',self.mass)
|
52 |
print self.name
|
53 |
if config.has_option('Cuts',region):
|
54 |
cut = config.get('Cuts',region)
|
55 |
else:
|
56 |
cut = None
|
57 |
if config.has_option(section, 'Datacut'):
|
58 |
cut=config.get(section, 'Datacut')
|
59 |
if config.has_option(section, 'doFit'):
|
60 |
self.doFit=eval(config.get(section, 'doFit'))
|
61 |
else:
|
62 |
self.doFit = False
|
63 |
|
64 |
self.colorDict=eval(config.get('Plot_general','colorDict'))
|
65 |
self.typLegendDict=eval(config.get('Plot_general','typLegendDict'))
|
66 |
self.anaTag = config.get("Analysis","tag")
|
67 |
self.xAxis = config.get('plotDef:%s'%var,'xAxis')
|
68 |
self.options = {'var': self.name,'name':'','xAxis': self.xAxis, 'nBins': self.nBins, 'xMin': self.xMin, 'xMax': self.xMax,'pdfName': '%s_%s_%s.pdf'%(region,var,self.mass),'cut':cut,'mass': self.mass, 'data': data, 'blind': self.blind}
|
69 |
if config.has_option('Weights','weightF'):
|
70 |
self.options['weight'] = config.get('Weights','weightF')
|
71 |
else:
|
72 |
self.options['weight'] = None
|
73 |
self.plotDir = config.get('Directories','plotpath')
|
74 |
self.maxRatioUncert = 0.5
|
75 |
if self.SignalRegion:
|
76 |
self.maxRatioUncert = 1000.
|
77 |
self.config = config
|
78 |
self.datas = None
|
79 |
self.datatyps = None
|
80 |
self.overlay = None
|
81 |
self.lumi = None
|
82 |
self.histos = None
|
83 |
self.typs = None
|
84 |
self.AddErrors = None
|
85 |
print self.setup
|
86 |
|
87 |
@staticmethod
|
88 |
def myText(txt="CMS Preliminary",ndcX=0,ndcY=0,size=0.8):
|
89 |
ROOT.gPad.Update()
|
90 |
text = ROOT.TLatex()
|
91 |
text.SetNDC()
|
92 |
text.SetTextColor(ROOT.kBlack)
|
93 |
text.SetTextSize(text.GetTextSize()*size)
|
94 |
text.DrawLatex(ndcX,ndcY,txt)
|
95 |
return text
|
96 |
|
97 |
def doCompPlot(self,aStack,l):
|
98 |
c = ROOT.TCanvas(self.var+'Comp','',600,600)
|
99 |
c.SetFillStyle(4000)
|
100 |
c.SetFrameFillStyle(1000)
|
101 |
c.SetFrameFillColor(0)
|
102 |
k=len(self.histos)
|
103 |
l.Clear()
|
104 |
maximum = 0.
|
105 |
for j in range(0,k):
|
106 |
#print histos[j].GetBinContent(1)
|
107 |
i=k-j-1
|
108 |
self.histos[i].SetLineColor(int(self.colorDict[self.typs[i]]))
|
109 |
self.histos[i].SetFillColor(0)
|
110 |
self.histos[i].SetLineWidth(3)
|
111 |
if self.histos[i].Integral() > 0.:
|
112 |
self.histos[i].Scale(1./self.histos[i].Integral())
|
113 |
if self.histos[i].GetMaximum() > maximum:
|
114 |
maximum = self.histos[i].GetMaximum()
|
115 |
l.AddEntry(self.histos[j],self.typLegendDict[self.typs[j]],'l')
|
116 |
aStack.SetMinimum(0.)
|
117 |
aStack.SetMaximum(maximum*1.5)
|
118 |
aStack.GetXaxis().SetTitle(self.xAxis)
|
119 |
aStack.Draw('HISTNOSTACK')
|
120 |
if self.overlay:
|
121 |
if self.overlay.Integral() > 0.:
|
122 |
self.overlay.Scale(1./self.overlay.Integral())
|
123 |
self.overlay.Draw('hist,same')
|
124 |
l.AddEntry(self.overlay,self.typLegendDict['Overlay'],'L')
|
125 |
l.Draw()
|
126 |
name = '%s/comp_%s' %(self.plotDir,self.options['pdfName'])
|
127 |
c.Print(name)
|
128 |
|
129 |
def doPlot(self):
|
130 |
TdrStyles.tdrStyle()
|
131 |
histo_dict = HistoMaker.orderandadd([{self.typs[i]:self.histos[i]} for i in range(len(self.histos))],self.setup)
|
132 |
#sort
|
133 |
self.histos=[histo_dict[key] for key in self.setup]
|
134 |
self.typs=self.setup
|
135 |
|
136 |
c = ROOT.TCanvas(self.var,'', 600, 600)
|
137 |
c.SetFillStyle(4000)
|
138 |
c.SetFrameFillStyle(1000)
|
139 |
c.SetFrameFillColor(0)
|
140 |
|
141 |
#oben = ROOT.TPad('oben','oben',0,0.3 ,1.0,1.0)
|
142 |
oben = ROOT.TPad('oben','oben',0,0.5 ,1.0,1.0)
|
143 |
oben.SetBottomMargin(0)
|
144 |
oben.SetFillStyle(4000)
|
145 |
oben.SetFrameFillStyle(1000)
|
146 |
oben.SetFrameFillColor(0)
|
147 |
#unten = ROOT.TPad('unten1','unten1',0,0.0,1.0,0.17)
|
148 |
unten = ROOT.TPad('unten1','unten1',0,0.0,1.0,0.29)
|
149 |
unten.SetTopMargin(0.)
|
150 |
unten.SetBottomMargin(0.35)
|
151 |
unten.SetFillStyle(4000)
|
152 |
unten.SetFrameFillStyle(1000)
|
153 |
unten.SetFrameFillColor(0)
|
154 |
#unten1 = ROOT.TPad('unten2','unten2',0,0.17,1.0,0.3)
|
155 |
unten1 = ROOT.TPad('unten2','unten2',0,0.29,1.0,0.5)
|
156 |
unten1.SetTopMargin(0.)
|
157 |
unten1.SetBottomMargin(0.)
|
158 |
unten1.SetFillStyle(4000)
|
159 |
unten1.SetFrameFillStyle(1000)
|
160 |
unten1.SetFrameFillColor(0)
|
161 |
|
162 |
|
163 |
oben.Draw()
|
164 |
unten.Draw()
|
165 |
unten1.Draw()
|
166 |
|
167 |
oben.cd()
|
168 |
allStack = ROOT.THStack(self.var,'')
|
169 |
#l = ROOT.TLegend(0.68, 0.65,0.92,0.92)
|
170 |
l = ROOT.TLegend(0.68, 0.5,0.92,0.92)
|
171 |
l.SetLineWidth(2)
|
172 |
l.SetBorderSize(0)
|
173 |
l.SetFillColor(0)
|
174 |
l.SetFillStyle(4000)
|
175 |
l.SetTextFont(62)
|
176 |
#l.SetTextSize(0.035)
|
177 |
l.SetTextSize(0.052)
|
178 |
MC_integral=0
|
179 |
MC_entries=0
|
180 |
|
181 |
for histo in self.histos:
|
182 |
MC_integral+=histo.Integral()
|
183 |
print "\033[1;32m\n\tMC integral = %s\033[1;m"%MC_integral
|
184 |
|
185 |
#ORDER AND ADD TOGETHER
|
186 |
#print typs
|
187 |
#print setup
|
188 |
|
189 |
|
190 |
if not 'DYc' in self.typs: self.typLegendDict.update({'DYlight':self.typLegendDict['DYlc']})
|
191 |
print self.typLegendDict
|
192 |
|
193 |
k=len(self.histos)
|
194 |
|
195 |
for j in range(0,k):
|
196 |
#print histos[j].GetBinContent(1)
|
197 |
i=k-j-1
|
198 |
self.histos[i].SetFillColor(int(self.colorDict[self.typs[i]]))
|
199 |
self.histos[i].SetLineColor(1)
|
200 |
allStack.Add(self.histos[i])
|
201 |
|
202 |
d1 = ROOT.TH1F('noData','noData',self.nBins,self.xMin,self.xMax)
|
203 |
datatitle='Data'
|
204 |
addFlag = ''
|
205 |
if 'Zee' in self.datanames and 'Zmm' in self.datanames:
|
206 |
addFlag = 'Z(l^{-}l^{+})H(b#bar{b})'
|
207 |
elif 'Zee' in self.datanames:
|
208 |
addFlag = 'Z(e^{-}e^{+})H(b#bar{b})'
|
209 |
elif 'Zmm' in self.datanames:
|
210 |
addFlag = 'Z(#mu^{-}#mu^{+})H(b#bar{b})'
|
211 |
elif 'Znn' in self.datanames:
|
212 |
addFlag = 'Z(#nu#nu)H(b#bar{b})'
|
213 |
elif 'Wmn' in self.datanames:
|
214 |
addFlag = 'W(#mu#nu)H(b#bar{b})'
|
215 |
elif 'Wen' in self.datanames:
|
216 |
addFlag = 'W(e#nu)H(b#bar{b})'
|
217 |
elif 'Wtn' in self.datanames:
|
218 |
addFlag = 'W(#tau#nu)H(b#bar{b})'
|
219 |
else:
|
220 |
addFlag = 'pp #rightarrow VH; H #rightarrow b#bar{b}'
|
221 |
for i in range(0,len(self.datas)):
|
222 |
d1.Add(self.datas[i],1)
|
223 |
print "\033[1;32m\n\tDATA integral = %s\033[1;m"%d1.Integral()
|
224 |
flow = d1.GetEntries()-d1.Integral()
|
225 |
if flow > 0:
|
226 |
print "\033[1;31m\tU/O flow: %s\033[1;m"%flow
|
227 |
|
228 |
if self.overlay:
|
229 |
self.overlay.SetLineColor(2)
|
230 |
self.overlay.SetLineWidth(2)
|
231 |
self.overlay.SetFillColor(0)
|
232 |
self.overlay.SetFillStyle(4000)
|
233 |
self.overlay.SetNameTitle('Overlay','Overlay')
|
234 |
|
235 |
l.AddEntry(d1,datatitle,'P')
|
236 |
for j in range(0,k):
|
237 |
l.AddEntry(self.histos[j],self.typLegendDict[self.typs[j]],'F')
|
238 |
if self.overlay:
|
239 |
l.AddEntry(self.overlay,self.typLegendDict['Overlay'],'L')
|
240 |
|
241 |
if self.normalize:
|
242 |
if MC_integral != 0: stackscale=d1.Integral()/MC_integral
|
243 |
if self.overlay:
|
244 |
self.overlay.Scale(stackscale)
|
245 |
stackhists=allStack.GetHists()
|
246 |
for blabla in stackhists:
|
247 |
if MC_integral != 0: blabla.Scale(stackscale)
|
248 |
|
249 |
#if self.SignalRegion:
|
250 |
# allMC=allStack.GetStack().At(allStack.GetStack().GetLast()-1).Clone()
|
251 |
#else:
|
252 |
allMC=allStack.GetStack().Last().Clone()
|
253 |
bkgMC=allStack.GetStack().First().Clone()
|
254 |
|
255 |
sigRatio = allMC.Clone()
|
256 |
sigRatio.Divide(bkgMC)
|
257 |
|
258 |
allStack.SetTitle()
|
259 |
allStack.Draw("hist")
|
260 |
allStack.GetXaxis().SetTitle('')
|
261 |
yTitle = 'Entries'
|
262 |
if not '/' in yTitle:
|
263 |
yAppend = '%.2f' %(allStack.GetXaxis().GetBinWidth(1))
|
264 |
yTitle = '%s / %s' %(yTitle, yAppend)
|
265 |
allStack.GetYaxis().SetTitle(yTitle)
|
266 |
allStack.GetXaxis().SetRangeUser(self.xMin,self.xMax)
|
267 |
allStack.GetYaxis().SetRangeUser(0,20000)
|
268 |
allStack.GetYaxis().SetTitleSize(ROOT.gStyle.GetTitleSize()*1.3)
|
269 |
allStack.GetYaxis().SetLabelSize(ROOT.gStyle.GetLabelSize() * 1.3)
|
270 |
allStack.GetYaxis().SetTitleOffset(0.9)
|
271 |
theErrorGraph = ROOT.TGraphErrors(allMC)
|
272 |
theErrorGraph.SetFillColor(ROOT.kGray+3)
|
273 |
theErrorGraph.SetFillStyle(3013)
|
274 |
theErrorGraph.Draw('SAME2')
|
275 |
l.AddEntry(theErrorGraph,"B total uncert.","fl")
|
276 |
Ymax = max(allStack.GetMaximum(),d1.GetMaximum())*1.7
|
277 |
if self.log:
|
278 |
allStack.SetMinimum(0.1)
|
279 |
#Ymax = Ymax*ROOT.TMath.Power(10,1.2*(ROOT.TMath.Log(1.2*(Ymax/0.1))/ROOT.TMath.Log(10)))*(0.2*0.1)
|
280 |
Ymax = Ymax*ROOT.TMath.Power(10,0.9*(ROOT.TMath.Log(0.9*(Ymax/0.1))/ROOT.TMath.Log(10)))*(0.2*0.1)
|
281 |
ROOT.gPad.SetLogy()
|
282 |
allStack.SetMaximum(Ymax)
|
283 |
c.Update()
|
284 |
ROOT.gPad.SetTicks(1,1)
|
285 |
#allStack.Draw("hist")
|
286 |
l.SetFillColor(0)
|
287 |
l.SetBorderSize(0)
|
288 |
|
289 |
#if self.overlay:
|
290 |
# self.overlay.Draw('hist,same')
|
291 |
d1.Draw("E,same")
|
292 |
l.Draw()
|
293 |
|
294 |
#tPrel = self.myText("CMS",0.17,0.88,1.04)
|
295 |
#tLumi = self.myText("#sqrt{s} = %s, L = %.1f fb^{-1}"%('7TeV',(float(5000.)/1000.)),0.17,0.83)
|
296 |
#tLumi = self.myText("#sqrt{s} = %s, L = %.1f fb^{-1}"%(self.anaTag,(float(self.lumi)/1000.)),0.17,0.78)
|
297 |
#tAddFlag = self.myText(addFlag,0.17,0.78)
|
298 |
tPrel = self.myText("CMS",0.17,0.85,1.56)
|
299 |
tLumi = self.myText("#sqrt{s} = %s, L = %.1f fb^{-1}"%('7TeV',(float(5000.)/1000.)),0.17,0.77,1.2)
|
300 |
tLumi = self.myText("#sqrt{s} = %s, L = %.1f fb^{-1}"%(self.anaTag,(float(self.lumi)/1000.)),0.17,0.69,1.2)
|
301 |
tAddFlag = self.myText(addFlag,0.17,0.61,1.2)
|
302 |
|
303 |
unten.cd()
|
304 |
ROOT.gPad.SetTicks(1,1)
|
305 |
|
306 |
l2 = ROOT.TLegend(0.5, 0.82,0.92,0.95)
|
307 |
l2.SetLineWidth(2)
|
308 |
l2.SetBorderSize(0)
|
309 |
l2.SetFillColor(0)
|
310 |
l2.SetFillStyle(4000)
|
311 |
l2.SetTextFont(62)
|
312 |
#l2.SetTextSize(0.035)
|
313 |
l2.SetNColumns(2)
|
314 |
|
315 |
|
316 |
ratio, error = getRatio(d1,allMC,self.xMin,self.xMax,"",self.maxRatioUncert)
|
317 |
ksScore = d1.KolmogorovTest( allMC )
|
318 |
chiScore = d1.Chi2Test( allMC , "UWCHI2/NDF")
|
319 |
print ksScore
|
320 |
print chiScore
|
321 |
ratio.SetStats(0)
|
322 |
ratio.GetXaxis().SetTitle(self.xAxis)
|
323 |
ratioError = ROOT.TGraphErrors(error)
|
324 |
ratioError.SetFillColor(ROOT.kGray+3)
|
325 |
ratioError.SetFillStyle(3013)
|
326 |
ratio.Draw("E1")
|
327 |
if self.doFit:
|
328 |
fitData = ROOT.TF1("fData", "gaus",0.7, 1.3)
|
329 |
fitMC = ROOT.TF1("fMC", "gaus",0.7, 1.3)
|
330 |
print 'Fit on data'
|
331 |
d1.Fit(fitData,"R")
|
332 |
print 'Fit on simulation'
|
333 |
allMC.Fit(fitMC,"R")
|
334 |
|
335 |
|
336 |
if not self.AddErrors == None:
|
337 |
self.AddErrors.SetFillColor(5)
|
338 |
self.AddErrors.SetFillStyle(1001)
|
339 |
self.AddErrors.Draw('SAME2')
|
340 |
|
341 |
l2.AddEntry(self.AddErrors,"MC uncert. (stat. + syst.)","f")
|
342 |
|
343 |
#ksScore = d1.KolmogorovTest( self.AddErrors )
|
344 |
#chiScore = d1.Chi2Test( self.AddErrors , "UWCHI2/NDF")
|
345 |
|
346 |
|
347 |
l2.AddEntry(ratioError,"MC uncert. (stat.)","f")
|
348 |
|
349 |
#l2.Draw()
|
350 |
|
351 |
ratioError.Draw('SAME2')
|
352 |
#ratio.GetXaxis().SetTitleSize(ROOT.gStyle.GetTitleSize()*3.6)
|
353 |
ratio.GetXaxis().SetTitleSize(ROOT.gStyle.GetTitleSize()*2.6)
|
354 |
ratio.GetXaxis().SetTitleOffset(0.9)
|
355 |
#ratio.GetXaxis().SetLabelSize(ROOT.gStyle.GetLabelSize() * 3.6)
|
356 |
ratio.GetXaxis().SetLabelSize(ROOT.gStyle.GetLabelSize() * 2.6)
|
357 |
#ratio.GetYaxis().SetTitleSize(ROOT.gStyle.GetTitleSize()*2.8)
|
358 |
#ratio.GetYaxis().SetLabelSize(ROOT.gStyle.GetLabelSize() * 2.8)
|
359 |
ratio.GetYaxis().SetTitleSize(ROOT.gStyle.GetTitleSize()*2.0)
|
360 |
ratio.GetYaxis().SetLabelSize(ROOT.gStyle.GetLabelSize() * 2.0)
|
361 |
ratio.GetYaxis().SetTitleOffset(0.55)
|
362 |
ratio.Draw("E1SAME")
|
363 |
ratio.SetTitle("")
|
364 |
ratio.SetYTitle("#frac{Data}{MC(S+B)}")
|
365 |
m_one_line = ROOT.TLine(self.xMin,1,self.xMax,1)
|
366 |
m_one_line.SetLineStyle(ROOT.kDashed)
|
367 |
m_one_line.Draw("Same")
|
368 |
|
369 |
unten1.cd()
|
370 |
ROOT.gPad.SetTicks(1,1)
|
371 |
|
372 |
ratio1, error1 = getRatio(d1,bkgMC,self.xMin,self.xMax,"",self.maxRatioUncert)
|
373 |
ratio1.Draw("E1")
|
374 |
#l2.Draw()
|
375 |
|
376 |
ratioError1 = ROOT.TGraphErrors(error1)
|
377 |
ratioError1.SetFillColor(ROOT.kGray+3)
|
378 |
ratioError1.SetFillStyle(3013)
|
379 |
ratioError1.Draw('SAME2')
|
380 |
sigRatio.SetFillStyle(0)
|
381 |
sigRatio.SetLineColor(2)
|
382 |
sigRatio.SetLineWidth(2)
|
383 |
sigRatio.Draw('HISTSAME')
|
384 |
ratio1.Draw("E1SAME")
|
385 |
ratio1.SetTitle("")
|
386 |
ratio1.SetYTitle("#frac{Data}{MC(B)}")
|
387 |
#ratio1.GetYaxis().SetTitleSize(ROOT.gStyle.GetTitleSize()*3.7)
|
388 |
ratio1.GetYaxis().SetTitleSize(ROOT.gStyle.GetTitleSize()*2.7)
|
389 |
ratio1.GetYaxis().SetTitleOffset(0.4)
|
390 |
#ratio1.GetYaxis().SetLabelSize(ROOT.gStyle.GetLabelSize() * 3.7)
|
391 |
ratio1.GetYaxis().SetLabelSize(ROOT.gStyle.GetLabelSize() * 2.7)
|
392 |
|
393 |
m_one_line.Draw("Same")
|
394 |
|
395 |
#if not self.blind:
|
396 |
# tKsChi = self.myText("#chi_{#nu}^{2} = %.3f K_{s} = %.3f"%(chiScore,ksScore),0.17,0.9,1.5)
|
397 |
t0 = ROOT.TText()
|
398 |
t0.SetTextSize(ROOT.gStyle.GetLabelSize()*2.4)
|
399 |
t0.SetTextFont(ROOT.gStyle.GetLabelFont())
|
400 |
if not self.log:
|
401 |
t0.DrawTextNDC(0.1059,0.96, "0")
|
402 |
if not os.path.exists(self.plotDir):
|
403 |
os.makedirs(os.path.dirname(self.plotDir))
|
404 |
name = '%s/%s' %(self.plotDir,self.options['pdfName'])
|
405 |
c.Print(name)
|
406 |
fOut = ROOT.TFile.Open(name.replace('.pdf','.root'),'RECREATE')
|
407 |
for theHist in allStack.GetHists():
|
408 |
theHist.SetDirectory(fOut)
|
409 |
if theHist.GetName() == 'ZH' or theHist.GetName() == 'WH':
|
410 |
theHist.SetName('VH')
|
411 |
theHist.Write()
|
412 |
d1.SetName('data_obs')
|
413 |
d1.SetDirectory(fOut)
|
414 |
d1.Write()
|
415 |
fOut.Close()
|
416 |
#self.doCompPlot(allStack,l)
|