ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/dhidas/OSUAnalysis/Tools/scripts/EstimateQCD.py
Revision: 1.1.1.1 (vendor branch)
Committed: Thu Dec 1 16:28:48 2011 UTC (13 years, 5 months ago) by dhidas
Content type: text/x-python
Branch: dhidas, MAIN
CVS Tags: START, HEAD
Changes since 1.1: +0 -0 lines
Log Message:
osu copy modified

File Contents

# Content
1 from __future__ import division
2
3 from HistGetter import *
4 from tdrStyle import *
5 from ROOT import *
6 from math import pow, exp, sqrt
7 from copy import deepcopy
8 from array import array
9
10 class QCDEstimator:
11 luminosity = 36.145#pb-1
12 mc_luminosity = 36.145#pb-1
13 luminosity_unit = 'pb-1'
14 scale = luminosity / mc_luminosity
15 jetBins = ['0jet', 'allJets', '1jet', '1orMoreJets', '2jets', '2orMoreJets', '3jets', '3orMoreJets', '4orMoreJets']
16 jetBinsLatex = {'0jet':'0 jet', 'allJets':'#geq 0 jets', '1jet':'1 jet', '1orMoreJets':'#geq 1 jet',
17 '2jets':'2 jets', '2orMoreJets':'#geq 2 jets', '3jets':'3 jets', '3orMoreJets':'#geq 3 jets',
18 '4orMoreJets':'#geq 4 jets'}
19 binWidth = 0.01
20 rebin = 10
21 fitRangesClosureTest = [ ( 0.1, 0.9 ), ( 0.1, 1.0 ), ( 0.1, 1.1 ),
22 ( 0.2, 0.9 ), ( 0.2, 1.0 ), ( 0.2, 1.1 ),
23 ( 0.3, 0.9 ), ( 0.3, 1.0 ), ( 0.3, 1.1 )]
24
25 fitRangesEstimation = [ ( 0.1, 1.1 ), ( 0.2, 1.1 )]#, ( 0.3, 1.1 )]
26 signalRegion = ( 0, 0.1 )
27 maxValue = 1.6
28 pfIsoHistogramPrefix = 'QCDest_PFIsolation_WithMETCutAndAsymJetCuts_'
29 pfIsoControlRegionHistogramPrefix = 'QCDest_PFIsolation_controlRegion2_WithMETCutAndAsymJetCuts_'
30 relIsoHistogramPrefix = 'QCDest_CombRelIso_'
31 pfIsoResults = {}
32 relIsoResults = {}
33 allPfIsoResults = {}
34 allRelIsoResults = {}
35
36 useEntryAsData = 'data'
37 constrainFit = False
38 numberOfFreeParameters = 0
39
40 currentFitRange = ( 0.1, 1.6 )
41 currentFitFuntion = 'gaus'
42 currentJetBin = jetBins[-1]
43
44 outputFormat = 'pdf'
45 outputFolder = ''
46
47 def __init__( self, files ):
48 self.files = files
49 HistGetter.samplefiles = files
50 self.histograms = {}
51 self.histGetter = HistGetter()
52 self.histGetter.setStyle()
53 self.getHistograms()
54 self.applyStyleAndCreateStack()
55
56 for bin in self.jetBins:
57 self.pfIsoResults[bin] = {'actualNumberOfQCDEvents': 0, 'estimatedNumberOfQCDEvents':0,
58 'fitFunction': None, 'fitParameters': {}, 'numberOfAllDataEvents':0,
59 'numberOfAllMCEvents':0}
60 self.relIsoResults[bin] = {'actualNumberOfQCDEvents': 0, 'estimatedNumberOfQCDEvents':0,
61 'fitFunction': None, 'fitParameters': {}, 'numberOfAllDataEvents':0,
62 'numberOfAllMCEvents':0}
63
64 def getHistograms( self ):
65 relIsoHists = [self.relIsoHistogramPrefix + jetbin for jetbin in self.jetBins]
66 pfIsoHists = [self.pfIsoHistogramPrefix + jetbin for jetbin in self.jetBins]
67 pfIsoControlHists = [self.pfIsoControlRegionHistogramPrefix + jetbin for jetbin in self.jetBins]
68 allHists = relIsoHists
69 allHists.extend( pfIsoHists )
70 allHists.extend( pfIsoControlHists )
71 HistGetter.hists = allHists
72
73 self.histograms = self.histGetter.getHistsFromFiles()
74 self.histograms = self.histGetter.addSampleSum( self.histograms )
75
76 def applyStyleAndCreateStack( self ):
77 samplesOfInterest = ['data', 'qcd', 'zjets', 'wjets', 'singleTop', 'ttbar', 'allMC']
78 colors = {'ttbar' : kRed + 1,
79 'wjets' : kGreen - 3,
80 'zjets' : kAzure - 2,
81 'qcd' : kYellow,
82 'singleTop' : kMagenta}
83
84 mcStack = {}
85
86 for sample in samplesOfInterest:#sample
87 for histname in self.histograms[sample].keys():
88 self.histograms[sample][histname].Rebin( self.rebin )
89 if not sample in ['data', 'allMC']:
90 self.histograms[sample][histname].Scale( self.scale )
91 self.histograms[sample][histname].SetFillStyle( 1001 )
92 self.histograms[sample][histname].SetFillColor( colors[sample] )
93 if not mcStack.has_key( histname ):
94 mcStack[histname] = THStack( "MC_" + histname, "MC_" + histname );
95 mcStack[histname].Add( self.histograms[sample][histname] )
96 else:
97 self.histograms[sample][histname].SetMarkerStyle( 8 );
98
99
100 self.histograms['MCStack'] = mcStack
101 self.setStyle()
102 print "=" * 40
103 print "data integrated luminosity:", self.luminosity, self.luminosity_unit
104 print "MC integrated luminosity:", self.mc_luminosity, self.luminosity_unit
105 print "MC scale factor: ", self.scale
106 print '=' * 40
107
108
109 def setStyle( self ):
110 tdrstyle = setTDRStyle();
111 tdrstyle.SetPadRightMargin( 0.05 )#originally was 0.02, too narrow!
112 tdrStyle.SetStatH( 0.2 );
113 tdrStyle.SetOptStat( 0 );#off title
114 tdrStyle.SetOptFit( 0 );#off title
115 tdrStyle.cd();
116 gROOT.ForceStyle();
117 gStyle.SetTitleH( 0.1 );
118 gStyle.SetStatH( 0.22 ); #0.24);
119 gStyle.SetStatW( 0.22 ); #0.26);
120 gStyle.SetOptStat( 1 ); #on stat
121 gStyle.SetLineScalePS( 2 ); #D=3
122 gStyle.SetOptFit( 112 );
123
124
125 def doClosureTests( self, function = 'gaus' ):
126 self.useEntryAsData = 'allMC'
127 self.currentFitFuntion = function
128
129 for fitRange in self.fitRangesClosureTest:
130 self.currentFitRange = fitRange
131 for bin in self.jetBins:
132 self.currentJetBin = bin
133 self.EstimateJetBin( bin )
134 self.plot( self.pfIsoHistogramPrefix + bin, self.pfIsoResults[bin] )
135 self.plot( self.relIsoHistogramPrefix + bin, self.relIsoResults[bin] )
136 self.allPfIsoResults['%1.1f-%1.1f' % fitRange] = deepcopy( self.pfIsoResults )
137 self.allRelIsoResults['%1.1f-%1.1f' % fitRange] = deepcopy( self.relIsoResults )
138 self.plotClosureTest( self.pfIsoHistogramPrefix, self.allPfIsoResults )
139 self.plotClosureTest( self.relIsoHistogramPrefix, self.allRelIsoResults )
140
141
142 def doEstimate( self, function = 'gaus' ):
143 self.useEntryAsData = 'data'
144 self.currentFitFuntion = function
145
146 for fitRange in self.fitRangesEstimation:
147 self.currentFitRange = fitRange
148 for bin in self.jetBins:
149 self.currentJetBin = bin
150 self.EstimateJetBin( bin )
151 self.plot( self.pfIsoHistogramPrefix + bin, self.pfIsoResults[bin] )
152 self.plot( self.relIsoHistogramPrefix + bin, self.relIsoResults[bin] )
153 self.allPfIsoResults['%1.1f-%1.1f' % fitRange] = deepcopy( self.pfIsoResults )
154 self.allRelIsoResults['%1.1f-%1.1f' % fitRange] = deepcopy( self.relIsoResults )
155
156 def EstimateJetBin( self, jetbin ):
157 # fitRange = self.currentFitRange
158 function = self.currentFitFuntion
159
160 QCD = self.histograms['qcd']
161 data = self.histograms[self.useEntryAsData]
162 allMC = self.histograms['allMC']
163 pfIsoHist = self.pfIsoHistogramPrefix + jetbin
164 relIsoHist = self.relIsoHistogramPrefix + jetbin
165
166 self.pfIsoResults[jetbin]['actualNumberOfQCDEvents'] = QCD[pfIsoHist].GetBinContent(1)
167 self.pfIsoResults[jetbin]['numberOfAllDataEvents'] = data[pfIsoHist].GetBinContent(1)
168 self.pfIsoResults[jetbin]['numberOfAllMCEvents'] = allMC[pfIsoHist].GetBinContent(1)
169
170 pfIsoFit = self.doFit( data[pfIsoHist] )
171 self.pfIsoResults[jetbin]['fitFunction'] = pfIsoFit
172 self.pfIsoResults[jetbin]['fitParameters'] = self.getFitParameters( pfIsoFit )
173 estimate = 0
174 if pfIsoFit:
175 estimate = pfIsoFit.Integral( self.signalRegion[0], self.signalRegion[1] ) / ( self.binWidth * self.rebin )
176
177 self.pfIsoResults[jetbin]['estimatedNumberOfQCDEvents'] = estimate
178
179 #----------------------------------------------------------------------------------------------------------------------
180 self.relIsoResults[jetbin]['actualNumberOfQCDEvents'] = QCD[relIsoHist].GetBinContent(1)
181 self.relIsoResults[jetbin]['numberOfAllDataEvents'] = data[relIsoHist].GetBinContent(1)
182 self.relIsoResults[jetbin]['numberOfAllMCEvents'] = allMC[relIsoHist].GetBinContent(1)
183
184 relIsoFit = self.doFit( data[relIsoHist] )
185 self.relIsoResults[jetbin]['fitFunction'] = relIsoFit
186 self.relIsoResults[jetbin]['fitParameters'] = self.getFitParameters( relIsoFit )
187
188 estimate = relIsoFit.Integral( self.signalRegion[0], self.signalRegion[1] ) / ( self.binWidth * self.rebin )
189 self.relIsoResults[jetbin]['estimatedNumberOfQCDEvents'] = estimate
190
191
192
193 def doFit( self, histogram ):
194 function = self.currentFitFuntion
195 fitRange = self.currentFitRange
196
197 if not self.constrainFit:
198 histogram.Fit( function, "Q0", "ah", fitRange[0], fitRange[1] )
199
200 else:
201 ff = TF1( function, function, 0, 1 );
202 self.numberOfFreeParameters = ff.GetNumberFreeParameters();
203
204 return histogram.GetFunction( function )
205
206 def plot( self, histname, results ):
207 data = self.histograms[self.useEntryAsData][histname]
208 mcStack = self.histograms['MCStack'][histname]
209 fitFunction = results['fitFunction']
210 if not fitFunction:
211 print 'no fitfunction found'
212 return;
213
214 data.GetXaxis().SetRangeUser( 0, self.maxValue - 0.01 );
215 fitFunction.SetLineColor( kRed );
216 fitFunction.SetLineWidth( 2 )
217
218 fitFunction2 = fitFunction.Clone()
219 fitFunction2.SetLineColor( kBlue );
220 fitFunction2.SetRange( self.signalRegion[0], self.signalRegion[1] );
221
222 fitFunction3 = fitFunction.Clone()
223 fitFunction3.SetLineColor( kBlue );
224 fitFunction3.SetLineStyle( kDashed );
225 fitFunction3.SetRange( self.signalRegion[1], self.currentFitRange[0] );
226
227 canvas = TCanvas( "c1", "Iso fit", 1920, 1080 )
228 data.Draw();
229
230 max = 0
231 if mcStack.GetMaximum() > data.GetBinContent( 1 ):
232 max = mcStack.GetMaximum()*1.1
233 else:
234 max = data.GetBinContent( 1 ) * 1.1
235
236 data.GetYaxis().SetRangeUser( 0, max );
237 data.SetXTitle( "Relative Isolation" );
238 data.SetYTitle( "Events/0.1" );
239 # draw mc
240 mcStack.Draw( "hist same" );
241 data.Draw( "ae same" );
242
243 fitFunction.Draw( "same" );
244 fitFunction2.Draw( "same" );
245 fitFunction3.Draw( "same" );
246
247 label = self.add_cms_label( self.currentJetBin )
248 label.Draw()
249
250 legend = self.add_legend( histname )
251 # legend.Draw()
252
253 if self.currentFitFuntion == "pol1":
254 out = "%s_fit_linear_from_0%.0f_%s" % ( histname, self.currentFitRange[0] * 10.0, self.useEntryAsData );
255 else:
256 out = "%s_fit_%s_from_%1.1f_to_%1.1f_%s" % ( histname, self.currentFitFuntion, self.currentFitRange[0],
257 self.currentFitRange[1], self.useEntryAsData );
258 # if self.outputFormat == 'pdf':
259 # canvas.SaveAs( '%s.eps' % out );
260 # gROOT.ProcessLine( ".!ps2pdf -dEPSCrop %s.eps" % out );
261 # gROOT.ProcessLine( ".!rm -f %s.eps" % out );
262 # else:
263 canvas.SaveAs( '%s/%s.%s' % ( self.outputFolder, out, self.outputFormat ) )
264
265 canvas.Close(); #crucial!
266
267
268 def plotClosureTest( self, histname, results ):
269 c2 = TCanvas( "c2", "QCD estimates", 1080, 1080 );
270 x = array( 'd', [2, 3, 4] )
271 jetBinsOfInterest = [#'1jet',
272 '2jets', '3jets', '4orMoreJets']
273 function = self.currentFitFuntion
274
275 gStyle.SetMarkerSize( 1.7 );
276 gStyle.SetMarkerStyle( 20 );
277 c2.SetTopMargin( 0.1 );
278 # c2.SetLeftMargin( 0.12 );
279 c2.SetRightMargin( 0.35 );
280
281 y = {}
282 for fitRange in self.fitRangesClosureTest:
283 range = '%1.1f-%1.1f' % fitRange
284 y[range] = []
285 for bin in jetBinsOfInterest:
286
287 est = results[range][bin]['estimatedNumberOfQCDEvents']
288 true = results[range][bin]['actualNumberOfQCDEvents']
289 variation = 0
290 if not true == 0:
291 variation = ( est - true ) / true
292 y[range].append( variation )
293 nbins = 3
294 gr1 = TGraph( nbins, x, array( 'd', y['%1.1f-%1.1f' % self.fitRangesClosureTest[0]] ) )
295 gr2 = TGraph( nbins, x, array( 'd', y['%1.1f-%1.1f' % self.fitRangesClosureTest[1]] ) )
296 gr3 = TGraph( nbins, x, array( 'd', y['%1.1f-%1.1f' % self.fitRangesClosureTest[2]] ) )
297 gr4 = TGraph( nbins, x, array( 'd', y['%1.1f-%1.1f' % self.fitRangesClosureTest[3]] ) )
298 gr5 = TGraph( nbins, x, array( 'd', y['%1.1f-%1.1f' % self.fitRangesClosureTest[4]] ) )
299 gr6 = TGraph( nbins, x, array( 'd', y['%1.1f-%1.1f' % self.fitRangesClosureTest[5]] ) )
300 gr7 = TGraph( nbins, x, array( 'd', y['%1.1f-%1.1f' % self.fitRangesClosureTest[6]] ) )
301 gr8 = TGraph( nbins, x, array( 'd', y['%1.1f-%1.1f' % self.fitRangesClosureTest[7]] ) )
302 gr9 = TGraph( nbins, x, array( 'd', y['%1.1f-%1.1f' % self.fitRangesClosureTest[8]] ) )
303
304 gr1.SetMarkerColor( kGreen + 1 );
305 gr2.SetMarkerColor( kGreen + 2 );
306 gr3.SetMarkerColor( kGreen + 3 );
307 gr4.SetMarkerColor( kAzure + 7 );
308 gr5.SetMarkerColor( kAzure - 3 );
309 gr6.SetMarkerColor( kBlue );
310 gr7.SetMarkerColor( kOrange );
311 gr8.SetMarkerColor( kOrange - 1 );
312 gr9.SetMarkerColor( kOrange - 6 );
313
314 gStyle.SetTitleW( 0.9 );
315 gStyle.SetTitleH( 0.05 )
316
317 h = None
318 if function == "gaus":
319 h = TH1D( "h", "Variation of QCD estimates with fit range (Gaussian)", 4, 0.5, 4.5 );
320 elif function == "pol3":
321 h = TH1D( "h", "Variation of QCD estimates with fit range (Pol3)", 4, 0.5, 4.5 );
322 elif function == "pol1":
323 h = TH1D( "h", "Variation of QCD estimates with fit range (Pol1)", 4, 0.5, 4.5 );
324 elif function == "landau":
325 h = TH1D( "h", "Variation of QCD estimates with fit range (Landau)", 4, 0.5, 4.5 );
326
327 h.SetStats( kFALSE ); # no statistics
328 h.Draw();
329 h.SetYTitle( "Deviation = (N_{QCD,est}-N_{QCD,true})/N_{QCD,true}" );
330 h.GetYaxis().SetRangeUser( -1, 1 );
331 h.GetXaxis().SetRangeUser( 1.5, 5.5 );
332 # h.GetXaxis().SetBinLabel( 1, "1j" );
333 h.GetXaxis().SetBinLabel( 2, "2j" );
334 h.GetXaxis().SetBinLabel( 3, "3j" );
335 h.GetXaxis().SetBinLabel( 4, "#geq4j" );
336 h.GetXaxis().SetLabelSize( 0.07 );
337 h.GetYaxis().SetTitleOffset( 1.3 );
338
339 gr1.Draw( "P" );
340 gr2.Draw( "P" ); #to superimpose graphs, do not re-draw axis
341 gr3.Draw( "P" );
342 gr4.Draw( "P" );
343 gr5.Draw( "P" );
344 gr6.Draw( "P" );
345 gr7.Draw( "P" );
346 gr8.Draw( "P" );
347 gr9.Draw( "P" );
348
349 c2.SetGrid( 1, 1 );
350
351 leg = TLegend( 0.65, 0.1, 0.98, 0.9 );
352 leg.SetFillColor( 0 );
353 leg.AddEntry( gr1, "Free: 0.1-0.9", "p" );
354 leg.AddEntry( gr2, "Free: 0.1-1.0", "p" );
355 leg.AddEntry( gr3, "Free: 0.1-1.1", "p" );
356 leg.AddEntry( gr4, "Free: 0.2-0.9", "p" );
357 leg.AddEntry( gr5, "Free: 0.2-1.0", "p" );
358 leg.AddEntry( gr6, "Free: 0.2-1.1", "p" );
359 leg.AddEntry( gr7, "Free: 0.3-0.9", "p" );
360 leg.AddEntry( gr8, "Free: 0.3-1.0", "p" );
361 leg.AddEntry( gr9, "Free: 0.3-1.1", "p" );
362
363 leg.Draw();
364
365 c2.SaveAs( "%s/%s_qcd_estimate_%s.%s" % ( self.outputFolder, histname, function, self.outputFormat ) )
366
367 setRange = h.GetYaxis().SetRangeUser
368 saveAs = c2.SaveAs
369 for limit in [1, 2, 3, 6, 8]:
370 setRange( -limit, limit );
371 saveAs( "%s/%s_qcd_estimate_%s_zoom_%d.%s" % ( self.outputFolder, histname, function, limit, self.outputFormat ) );
372
373 def getFitParameters( self, fitFunction ):
374 fitParameters = {'chi2':-1, 'numberOfdegreesOfFreedom': 0, 'constrain1': 0, 'constrain2': 0,
375 'constrain3': 0, 'constrain4': 0}
376 if fitFunction:
377 fitParameters['chi2'] = fitFunction.GetChisquare()
378 fitParameters['numberOfdegreesOfFreedom'] = fitFunction.GetNDF()
379 return fitParameters
380
381 def doConstrainedFit( self, histogram, function = 'gaus', limits = ( 0.1, 1.6 ) ):
382 fitFunction = None
383 if function == 'gaus':
384 fitFunction = TF1( "gaus", "gaus", 0, 2 );
385 elif function == 'pol3':
386 fitFunction = TF1( "pol3", "[0] * ( 1 + [1]*x + [2]*x^2 + [3]*x^3 )", 0, 2 );
387 elif function == 'landau':
388 fitFunction = TF1( "landau", "landau", 0, 2 )
389
390
391 myFitResult = data.Fit( function, "Q0", "ah", limits[0], limits[1] );
392
393 def add_cms_label( self, njet = "" ):
394
395 mytext = TPaveText( 0.3, 0.8, 0.6, 0.93, "NDC" );
396 mytext.AddText( "CMS Preliminary" );
397 mytext.AddText( "%.1f pb^{-1} at #sqrt{s} = 7 TeV" % self.luminosity );
398 if njet != "":
399 mytext.AddText( "e+jets, %s" % self.jetBinsLatex[njet] )
400 mytext.SetFillStyle( 0 );
401 mytext.SetBorderSize( 0 );
402 mytext.SetTextFont( 42 );
403 mytext.SetTextAlign( 13 );
404 return mytext
405
406 def add_legend( self, histname ):
407 function = self.currentFitFuntion
408
409 tt = self.histograms['ttbar'][histname]
410 wj = self.histograms['wjets'][histname]
411 zj = self.histograms['zjets'][histname]
412 data = self.histograms['data'][histname]
413 QCD = self.histograms['qcd'][histname]
414 stop = self.histograms['singleTop'][histname]
415
416 leg = TLegend( 0.64, 0.4, 0.9, 0.9 );
417 leg.SetFillStyle( 0 );
418 leg.SetBorderSize( 0 );
419 leg.SetTextFont( 42 );
420
421 # Here I define coloured lines for use in the legend
422 blue = TF1( "blue", "pol0", 0, 1 );
423 red = TF1( "red", "pol0", 0, 1 );
424
425 blue.SetLineColor( kBlue );
426 red.SetLineColor( kRed );
427
428 red.SetLineWidth( 2 );
429 blue.SetLineWidth( 2 );
430
431 blue.SetLineStyle( kDashed );
432
433 # Add entry to legend
434 if self.useEntryAsData == 'data':
435 leg.AddEntry( data, "Data", "LP" );
436 else:
437 leg.AddEntry( data, "All MC events", "LP" );
438 if function == "pol1":
439 leg.AddEntry( red, "Linear Fit", "l" );
440 elif function == "expo":
441 leg.AddEntry( red, "Exponenetial Fit", "l" );
442 elif function == "gaus":
443 leg.AddEntry( red, "Gaussian Fit", "l" );
444
445 leg.AddEntry( blue, "Extrapolation", "l" );
446 leg.AddEntry( tt, "t#bar{t}", "F" );
447 leg.AddEntry( stop, "Single-Top", "F" );
448 leg.AddEntry( wj, "W#rightarrowl#nu", "F" );
449 leg.AddEntry( zj, "Z/#gamma*#rightarrowl^{+}l^{-}", "F" );
450 leg.AddEntry( QCD, "QCD & #gamma+jets", "F" );
451 leg.Draw()
452 return ( leg, red, blue )
453
454 def printResults( self, results ):
455 self.printJetBinResults( results, '3jets' )
456 print '=' * 60
457 self.printJetBinResults( results, '3orMoreJets' )
458 print '=' * 60
459 self.printJetBinResults( results, '4orMoreJets' )
460 print '=' * 60
461
462
463 def printJetBinResults( self, results, jetBin ):
464 estimate = 0
465 estimate2 = 0
466 predicted = results[results.keys()[0]][jetBin]['actualNumberOfQCDEvents']
467 allData = results[results.keys()[0]][jetBin]['numberOfAllDataEvents']
468 allMC = results[results.keys()[0]][jetBin]['numberOfAllMCEvents']
469
470 if jetBin == '4orMoreJets':
471 print 'Estimation for >= 4 jets'
472 elif jetBin == '3orMoreJets':
473 print 'Estimation for >= 3 jets'
474 elif jetBin == '3jets':
475 print 'Estimation for == 3 jets'
476 print 'predicted number of QCD events', predicted
477 for fitRange in self.fitRangesEstimation:
478 range = '%1.1f-%1.1f' % fitRange
479 est = results[range][jetBin]['estimatedNumberOfQCDEvents']
480 true = results[range][jetBin]['actualNumberOfQCDEvents']
481 variation = ( est - true ) / true
482 estimate += est
483 estimate2 += est * est
484
485
486 print
487 print 'estimated number of QCD events'
488 print 'for range', range, ': ',
489 print est
490 print
491 mean = estimate / len( self.fitRangesEstimation )
492 mean2 = estimate2 / len( self.fitRangesEstimation )
493 error = sqrt( ( mean2 - mean * mean ) / len( self.fitRangesEstimation ) )
494 print 'average estimate', mean, '+-', error
495 weight = estimate / len( self.fitRangesEstimation ) / predicted
496 print 'average weight factor', weight
497 print 'Total number of data in signal bin(<0.1)', allData
498 print 'Total number of MC in signal bin(<0.1) before reweighting QCD', allMC
499 print 'Total number of MC in signal bin(<0.1) after reweighting QCD', ( allMC - predicted ) + predicted * weight
500
501 def plotControlRegionComparison( self ):
502 for bin in self.jetBins:
503 hist = self.pfIsoHistogramPrefix + bin
504 histControl = self.pfIsoControlRegionHistogramPrefix + bin
505 QCD_control = self.histograms['qcd'][histControl]
506 QCD = self.histograms['qcd'][hist]
507 nQCD_Control = QCD_control.Integral()
508 nQCD = QCD.Integral()
509 if nQCD_Control > 0:
510 QCD_control.Scale( 1 / nQCD_Control )
511 if nQCD > 0:
512 QCD.Scale( 1 / nQCD )
513 QCD_control.SetFillStyle( 3004 )
514 QCD.GetXaxis().SetRangeUser( 0., self.maxValue - 0.01 )
515
516 max = 0
517 if QCD.GetMaximum() > QCD_control.GetMaximum():
518 max = QCD.GetMaximum()*1.1
519 else:
520 max = QCD_control.GetMaximum()*1.1
521
522 QCD.GetYaxis().SetRangeUser( 0., max )
523
524 canvas = TCanvas( "c1", "Shape comparision", 1920, 1080 )
525 QCD.Draw()
526 QCD_control.Draw( 'same' )
527 label = self.add_cms_label( bin )
528 label.Draw()
529
530 leg = TLegend( 0.64, 0.4, 0.9, 0.9 );
531 leg.SetFillStyle( 0 );
532 leg.SetBorderSize( 0 );
533 leg.SetTextFont( 42 );
534 leg.AddEntry( QCD_control, 'QCD control region' )
535 leg.AddEntry( QCD, 'QCD standard selection' )
536 leg.Draw()
537
538 canvas.SaveAs( '%s/%s_shapeComparison.%s' % ( self.outputFolder, hist, self.outputFormat ) )
539
540 if __name__ == '__main__':
541 gROOT.SetBatch( True )
542 gROOT.ProcessLine( 'gErrorIgnoreLevel = 1001;' )
543
544 path = '/storage/results/outputfiles/Preapproval2/'
545 files = {'data': path + "data_36.145pb_PFElectron_PF2PATJets_PFMET.root",
546 'ttbar' : path + "ttjet_36.145pb_PFElectron_PF2PATJets_PFMET.root",
547 'wjets' : path + "wj_36.145pb_PFElectron_PF2PATJets_PFMET.root",
548 'zjets' : path + "zj_36.145pb_PFElectron_PF2PATJets_PFMET.root",
549 'bce1' : path + "bce1_36.145pb_PFElectron_PF2PATJets_PFMET.root",
550 'bce2' : path + "bce2_36.145pb_PFElectron_PF2PATJets_PFMET.root",
551 'bce3' : path + "bce3_36.145pb_PFElectron_PF2PATJets_PFMET.root",
552 'enri1' : path + "enri1_36.145pb_PFElectron_PF2PATJets_PFMET.root",
553 'enri2' : path + "enri2_36.145pb_PFElectron_PF2PATJets_PFMET.root",
554 'enri3' : path + "enri3_36.145pb_PFElectron_PF2PATJets_PFMET.root",
555 'pj1' : path + "pj1_36.145pb_PFElectron_PF2PATJets_PFMET.root",
556 'pj2' : path + "pj2_36.145pb_PFElectron_PF2PATJets_PFMET.root",
557 'pj3' : path + "pj3_36.145pb_PFElectron_PF2PATJets_PFMET.root",
558 'tW' : path + "tW_36.145pb_PFElectron_PF2PATJets_PFMET.root",
559 'tchan' : path + "tchan_36.145pb_PFElectron_PF2PATJets_PFMET.root"}
560 q = QCDEstimator( files )
561 QCDEstimator.outputFolder = '/storage/results/QCD_Estimate/Preapproval2'
562 QCDEstimator.outputFormat = 'pdf'
563
564 q.doEstimate( 'gaus' )
565 print '=' * 60
566 print 'ParticleFlowIsolation results'
567 q.printResults( q.allPfIsoResults )
568 # print 'Relative isolation results'
569 # q.printResults( q.allRelIsoResults )
570 # print '=' * 60
571
572
573 print 'Starting closure tests'
574 q.doClosureTests( 'gaus' )
575 q.plotControlRegionComparison()
576