1 |
import ROOT
|
2 |
import sys,os
|
3 |
from HistoMaker import orderandadd
|
4 |
from BetterConfigParser import BetterConfigParser
|
5 |
import TdrStyles
|
6 |
from Ratio import getRatio
|
7 |
|
8 |
class StackMaker:
|
9 |
def __init__(self, config, var,region,SignalRegion):
|
10 |
section='Plot:%s'%region
|
11 |
self.var = var
|
12 |
self.SignalRegion=SignalRegion
|
13 |
self.normalize = eval(config.get(section,'Normalize'))
|
14 |
self.log = eval(config.get(section,'log'))
|
15 |
if config.has_option('plotDef:%s'%var,'log') and not self.log:
|
16 |
self.log = eval(config.get('plotDef:%s'%var,'log'))
|
17 |
self.blind = eval(config.get(section,'blind'))
|
18 |
if self.blind: blindopt='blind'
|
19 |
else: blindopt = 'noblind'
|
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 |
if not SignalRegion: self.setup.remove('ZH')
|
25 |
self.rebin = 1
|
26 |
if config.has_option(section,'rebin'):
|
27 |
self.rebin = eval(config.get(section,'rebin'))
|
28 |
if config.has_option(section,'nBins'):
|
29 |
self.nBins = int(eval(config.get(section,'nBins'))/self.rebin)
|
30 |
else:
|
31 |
self.nBins = int(eval(config.get('plotDef:%s'%var,'nBins'))/self.rebin)
|
32 |
print self.nBins
|
33 |
if config.has_option(section,'min'):
|
34 |
self.xMin = eval(config.get(section,'min'))
|
35 |
else:
|
36 |
self.xMin = eval(config.get('plotDef:%s'%var,'min'))
|
37 |
if config.has_option(section,'max'):
|
38 |
self.xMax = eval(config.get(section,'max'))
|
39 |
else:
|
40 |
self.xMax = eval(config.get('plotDef:%s'%var,'max'))
|
41 |
self.name = config.get('plotDef:%s'%var,'relPath')
|
42 |
self.mass = config.get(section,'Signal')
|
43 |
data = config.get(section,'Datas')
|
44 |
if '<mass>' in self.name:
|
45 |
self.name = self.name.replace('<mass>',self.mass)
|
46 |
print self.name
|
47 |
if config.has_option(section, 'Datacut'):
|
48 |
datacut=config.get(section, 'Datacut')
|
49 |
else:
|
50 |
datacut = region
|
51 |
self.colorDict=eval(config.get('Plot_general','colorDict'))
|
52 |
self.typLegendDict=eval(config.get('Plot_general','typLegendDict'))
|
53 |
self.anaTag = config.get("Analysis","tag")
|
54 |
self.xAxis = config.get('plotDef:%s'%var,'xAxis')
|
55 |
self.options = [self.name,'',self.xAxis,self.nBins,self.xMin,self.xMax,'%s_%s_%s.pdf'%(region,var,self.mass),region,datacut,self.mass,data,blindopt]
|
56 |
#self.xAxis = config.get('plotDef:%s'%var,'xAxis')
|
57 |
#self.options = [self.name,'',self.xAxis,self.nBins,self.xMin,self.xMax,'%s_%s.pdf'%(region,var),region,datacut,self.mass,data,blindopt]
|
58 |
self.plotDir = config.get('Directories','plotpath')
|
59 |
self.maxRatioUncert = 0.5
|
60 |
if self.SignalRegion:
|
61 |
self.maxRatioUncert = 1000.
|
62 |
self.config = config
|
63 |
self.datas = None
|
64 |
self.datatyps = None
|
65 |
self.overlay = None
|
66 |
self.lumi = None
|
67 |
self.histos = None
|
68 |
self.typs = None
|
69 |
self.AddErrors = None
|
70 |
print self.setup
|
71 |
|
72 |
def myText(self,txt="CMS Preliminary",ndcX=0,ndcY=0,size=0.8):
|
73 |
ROOT.gPad.Update()
|
74 |
text = ROOT.TLatex()
|
75 |
text.SetNDC()
|
76 |
text.SetTextColor(ROOT.kBlack)
|
77 |
text.SetTextSize(text.GetTextSize()*size)
|
78 |
text.DrawLatex(ndcX,ndcY,txt)
|
79 |
return text
|
80 |
|
81 |
|
82 |
def doPlot(self):
|
83 |
TdrStyles.tdrStyle()
|
84 |
self.histos, self.typs = orderandadd(self.histos,self.typs,self.setup)
|
85 |
|
86 |
c = ROOT.TCanvas(self.var,'', 600, 600)
|
87 |
c.SetFillStyle(4000)
|
88 |
c.SetFrameFillStyle(1000)
|
89 |
c.SetFrameFillColor(0)
|
90 |
|
91 |
oben = ROOT.TPad('oben','oben',0,0.3 ,1.0,1.0)
|
92 |
oben.SetBottomMargin(0)
|
93 |
oben.SetFillStyle(4000)
|
94 |
oben.SetFrameFillStyle(1000)
|
95 |
oben.SetFrameFillColor(0)
|
96 |
unten = ROOT.TPad('unten','unten',0,0.0,1.0,0.3)
|
97 |
unten.SetTopMargin(0.)
|
98 |
unten.SetBottomMargin(0.35)
|
99 |
unten.SetFillStyle(4000)
|
100 |
unten.SetFrameFillStyle(1000)
|
101 |
unten.SetFrameFillColor(0)
|
102 |
|
103 |
oben.Draw()
|
104 |
unten.Draw()
|
105 |
|
106 |
oben.cd()
|
107 |
allStack = ROOT.THStack(self.var,'')
|
108 |
l = ROOT.TLegend(0.63, 0.55,0.92,0.92)
|
109 |
l.SetLineWidth(2)
|
110 |
l.SetBorderSize(0)
|
111 |
l.SetFillColor(0)
|
112 |
l.SetFillStyle(4000)
|
113 |
l.SetTextFont(62)
|
114 |
l.SetTextSize(0.035)
|
115 |
MC_integral=0
|
116 |
MC_entries=0
|
117 |
|
118 |
for histo in self.histos:
|
119 |
MC_integral+=histo.Integral()
|
120 |
print "\033[1;32m\n\tMC integral = %s\033[1;m"%MC_integral
|
121 |
|
122 |
#ORDER AND ADD TOGETHER
|
123 |
#print typs
|
124 |
#print setup
|
125 |
|
126 |
|
127 |
if not 'DYc' in self.typs: self.typLegendDict.update({'DYlight':self.typLegendDict['DYlc']})
|
128 |
print self.typLegendDict
|
129 |
|
130 |
k=len(self.histos)
|
131 |
|
132 |
for j in range(0,k):
|
133 |
#print histos[j].GetBinContent(1)
|
134 |
i=k-j-1
|
135 |
self.histos[i].SetFillColor(int(self.colorDict[self.typs[i]]))
|
136 |
self.histos[i].SetLineColor(1)
|
137 |
allStack.Add(self.histos[i])
|
138 |
|
139 |
d1 = ROOT.TH1F('noData','noData',self.nBins,self.xMin,self.xMax)
|
140 |
datatitle='Data'
|
141 |
addFlag = ''
|
142 |
if 'Zee' in self.datanames and 'Zmm' in self.datanames:
|
143 |
addFlag = 'Z(l^{-}l^{+})H(b#bar{b})'
|
144 |
elif 'Zee' in self.datanames:
|
145 |
addFlag = 'Z(e^{-}e^{+})H(b#bar{b})'
|
146 |
elif 'Zmm' in self.datanames:
|
147 |
addFlag = 'Z(#mu^{-}#mu^{+})H(b#bar{b})'
|
148 |
elif 'Znn' in self.datanames:
|
149 |
addFlag = 'Z(#nu#nu)H(b#bar{b})'
|
150 |
elif 'Wmn' in self.datanames:
|
151 |
addFlag = 'W(#mu#nu)H(b#bar{b})'
|
152 |
elif 'Wen' in self.datanames:
|
153 |
addFlag = 'W(e#nu)H(b#bar{b})'
|
154 |
for i in range(0,len(self.datas)):
|
155 |
d1.Add(self.datas[i],1)
|
156 |
print "\033[1;32m\n\tDATA integral = %s\033[1;m"%d1.Integral()
|
157 |
flow = d1.GetEntries()-d1.Integral()
|
158 |
if flow > 0:
|
159 |
print "\033[1;31m\tU/O flow: %s\033[1;m"%flow
|
160 |
|
161 |
if self.overlay:
|
162 |
self.overlay.SetLineColor(2)
|
163 |
self.overlay.SetLineWidth(2)
|
164 |
self.overlay.SetFillColor(0)
|
165 |
self.overlay.SetFillStyle(4000)
|
166 |
self.overlay.SetNameTitle('Overlay','Overlay')
|
167 |
|
168 |
l.AddEntry(d1,datatitle,'P')
|
169 |
for j in range(0,k):
|
170 |
l.AddEntry(self.histos[j],self.typLegendDict[self.typs[j]],'F')
|
171 |
if self.overlay:
|
172 |
l.AddEntry(self.overlay,self.typLegendDict['Overlay'],'L')
|
173 |
|
174 |
if self.normalize:
|
175 |
if MC_integral != 0: stackscale=d1.Integral()/MC_integral
|
176 |
if self.overlay:
|
177 |
self.overlay.Scale(stackscale)
|
178 |
stackhists=allStack.GetHists()
|
179 |
for blabla in stackhists:
|
180 |
if MC_integral != 0: blabla.Scale(stackscale)
|
181 |
|
182 |
#if self.SignalRegion:
|
183 |
# allMC=allStack.GetStack().At(allStack.GetStack().GetLast()-1).Clone()
|
184 |
#else:
|
185 |
allMC=allStack.GetStack().Last().Clone()
|
186 |
|
187 |
allStack.SetTitle()
|
188 |
allStack.Draw("hist")
|
189 |
allStack.GetXaxis().SetTitle('')
|
190 |
yTitle = 'Entries'
|
191 |
if not '/' in yTitle:
|
192 |
yAppend = '%.2f' %(allStack.GetXaxis().GetBinWidth(1))
|
193 |
yTitle = '%s / %s' %(yTitle, yAppend)
|
194 |
allStack.GetYaxis().SetTitle(yTitle)
|
195 |
allStack.GetXaxis().SetRangeUser(self.xMin,self.xMax)
|
196 |
allStack.GetYaxis().SetRangeUser(0,20000)
|
197 |
theErrorGraph = ROOT.TGraphErrors(allMC)
|
198 |
theErrorGraph.SetFillColor(ROOT.kGray+3)
|
199 |
theErrorGraph.SetFillStyle(3013)
|
200 |
theErrorGraph.Draw('SAME2')
|
201 |
l.AddEntry(theErrorGraph,"MC uncert. (stat.)","fl")
|
202 |
Ymax = max(allStack.GetMaximum(),d1.GetMaximum())*1.7
|
203 |
if self.log:
|
204 |
allStack.SetMinimum(0.1)
|
205 |
Ymax = Ymax*ROOT.TMath.Power(10,1.2*(ROOT.TMath.Log(1.2*(Ymax/0.1))/ROOT.TMath.Log(10)))*(0.2*0.1)
|
206 |
ROOT.gPad.SetLogy()
|
207 |
allStack.SetMaximum(Ymax)
|
208 |
c.Update()
|
209 |
ROOT.gPad.SetTicks(1,1)
|
210 |
#allStack.Draw("hist")
|
211 |
l.SetFillColor(0)
|
212 |
l.SetBorderSize(0)
|
213 |
|
214 |
if self.overlay:
|
215 |
self.overlay.Draw('hist,same')
|
216 |
d1.Draw("E,same")
|
217 |
l.Draw()
|
218 |
|
219 |
tPrel = self.myText("CMS Preliminary",0.17,0.88,1.04)
|
220 |
tLumi = self.myText("#sqrt{s} = %s, L = %s fb^{-1}"%(self.anaTag,(float(self.lumi)/1000.)),0.17,0.83)
|
221 |
tAddFlag = self.myText(addFlag,0.17,0.78)
|
222 |
|
223 |
unten.cd()
|
224 |
ROOT.gPad.SetTicks(1,1)
|
225 |
|
226 |
l2 = ROOT.TLegend(0.5, 0.82,0.92,0.95)
|
227 |
l2.SetLineWidth(2)
|
228 |
l2.SetBorderSize(0)
|
229 |
l2.SetFillColor(0)
|
230 |
l2.SetFillStyle(4000)
|
231 |
l2.SetTextFont(62)
|
232 |
#l2.SetTextSize(0.035)
|
233 |
l2.SetNColumns(2)
|
234 |
|
235 |
|
236 |
ratio, error = getRatio(d1,allMC,self.xMin,self.xMax,"",self.maxRatioUncert)
|
237 |
ksScore = d1.KolmogorovTest( allMC )
|
238 |
chiScore = d1.Chi2Test( allMC , "UWCHI2/NDF")
|
239 |
print ksScore
|
240 |
print chiScore
|
241 |
ratio.SetStats(0)
|
242 |
ratio.GetXaxis().SetTitle(self.xAxis)
|
243 |
ratioError = ROOT.TGraphErrors(error)
|
244 |
ratioError.SetFillColor(ROOT.kGray+3)
|
245 |
ratioError.SetFillStyle(3013)
|
246 |
ratio.Draw("E1")
|
247 |
|
248 |
|
249 |
|
250 |
if not self.AddErrors == None:
|
251 |
self.AddErrors.SetFillColor(5)
|
252 |
self.AddErrors.SetFillStyle(1001)
|
253 |
self.AddErrors.Draw('SAME2')
|
254 |
|
255 |
l2.AddEntry(self.AddErrors,"MC uncert. (stat. + syst.)","f")
|
256 |
|
257 |
#ksScore = d1.KolmogorovTest( self.AddErrors )
|
258 |
#chiScore = d1.Chi2Test( self.AddErrors , "UWCHI2/NDF")
|
259 |
|
260 |
|
261 |
l2.AddEntry(ratioError,"MC uncert. (stat.)","f")
|
262 |
|
263 |
l2.Draw()
|
264 |
|
265 |
ratioError.Draw('SAME2')
|
266 |
ratio.Draw("E1SAME")
|
267 |
ratio.SetTitle("")
|
268 |
m_one_line = ROOT.TLine(self.xMin,1,self.xMax,1)
|
269 |
m_one_line.SetLineStyle(ROOT.kDashed)
|
270 |
m_one_line.Draw("Same")
|
271 |
|
272 |
if not self.blind:
|
273 |
tKsChi = self.myText("#chi_{#nu}^{2} = %.3f K_{s} = %.3f"%(chiScore,ksScore),0.17,0.9,1.5)
|
274 |
t0 = ROOT.TText()
|
275 |
t0.SetTextSize(ROOT.gStyle.GetLabelSize()*2.4)
|
276 |
t0.SetTextFont(ROOT.gStyle.GetLabelFont())
|
277 |
if not self.log:
|
278 |
t0.DrawTextNDC(0.1059,0.96, "0")
|
279 |
if not os.path.exists(self.plotDir):
|
280 |
os.makedirs(os.path.dirname(self.plotDir))
|
281 |
name = '%s/%s' %(self.plotDir,self.options[6])
|
282 |
c.Print(name)
|