ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/OSUT3Analysis/Configuration/scripts/fitMCToData.py
Revision: 1.7
Committed: Tue Sep 3 20:54:33 2013 UTC (11 years, 8 months ago) by ahart
Content type: text/x-python
Branch: MAIN
CVS Tags: HEAD
Changes since 1.6: +93 -77 lines
Log Message:
Added an option (-P) which will cause, for each dataset being used in the fit,
two additional fits to be performed, one with that dataset scaled down one
sigma and one with that dataset scaled up one sigma. The difference in the
results for that dataset are then displayed as an additional "parametric"
error.

File Contents

# Content
1 #!/usr/bin/env python
2 import sys
3 import os
4 import re
5 import time
6 from math import *
7 from array import *
8 from decimal import *
9 from optparse import OptionParser
10 from OSUT3Analysis.Configuration.configurationOptions import *
11 from OSUT3Analysis.Configuration.processingUtilities import *
12 from OSUT3Analysis.Configuration.formattingUtilities import *
13
14
15
16 ### parse the command-line options
17
18 parser = OptionParser()
19 parser = set_commandline_arguments(parser)
20
21 parser.add_option("-f", "--fancy", action="store_true", dest="makeFancy", default=False,
22 help="removes the title and replaces it with the official CMS plot heading")
23 parser.add_option("--ylog", action="store_true", dest="setLogY", default=False,
24 help="Set logarithmic scale on vertical axis on all plots")
25 parser.add_option("--ymin", dest="setYMin",
26 help="Minimum of y axis")
27 parser.add_option("--ymax", dest="setYMax",
28 help="Maximum of y axis")
29 parser.add_option("-E", "--ratioRelErrMax", dest="ratioRelErrMax",
30 help="maximum error used in rebinning the ratio histogram")
31 parser.add_option("-P", "--parametricErrors", action="store_true", dest="parametricErrors", default=False,
32 help="calculate parametric errors and display on histograms")
33
34 (arguments, args) = parser.parse_args()
35
36
37 if arguments.localConfig:
38 sys.path.append(os.getcwd())
39 exec("from " + arguments.localConfig.rstrip('.py') + " import *")
40
41 #### deal with conflicting arguments
42 if arguments.normalizeToData and arguments.normalizeToUnitArea:
43 print "Conflicting normalizations requsted, will normalize to unit area"
44 arguments.normalizeToData = False
45 if arguments.normalizeToData and arguments.noStack:
46 print "You have asked to scale non-stacked backgrounds to data. This is a very strange request. Will normalize to unit area instead"
47 arguments.normalizeToData = False
48 arguments.normalizeToUnitArea = True
49 if arguments.makeRatioPlots and arguments.makeDiffPlots:
50 print "You have requested both ratio and difference plots. Will make just ratio plots instead"
51 arguments.makeRatioPlots = False
52 if arguments.makeRatioPlots and arguments.noStack:
53 print "You have asked to make a ratio plot and to not stack the backgrounds. This is a very strange request. Will skip making the ratio plot."
54 arguments.makeRatioPlots = False
55 if arguments.makeDiffPlots and arguments.noStack:
56 print "You have asked to make a difference plot and to not stack the backgrounds. This is a very strange request. Will skip making the difference plot."
57 arguments.makeDiffPlots = False
58
59
60 from ROOT import TFile, gROOT, gStyle, gDirectory, TStyle, THStack, TH1F, TCanvas, TString, TLegend, TLegendEntry, THStack, TIter, TKey, TPaveLabel, TPaveText, TF1, gPad
61
62
63 ### setting ROOT options so our plots will look awesome and everyone will love us
64
65 gROOT.SetBatch()
66 gStyle.SetOptStat(0)
67 gStyle.SetCanvasBorderMode(0)
68 gStyle.SetPadBorderMode(0)
69 gStyle.SetPadColor(0)
70 gStyle.SetCanvasColor(0)
71 gStyle.SetTextFont(42)
72 gStyle.SetCanvasDefH(600)
73 gStyle.SetCanvasDefW(600)
74 gStyle.SetCanvasDefX(0)
75 gStyle.SetCanvasDefY(0)
76 gStyle.SetPadTopMargin(0.07)
77 gStyle.SetPadBottomMargin(0.13)
78 gStyle.SetPadLeftMargin(0.15)
79 gStyle.SetPadRightMargin(0.05)
80 gStyle.SetTitleColor(1, "XYZ")
81 gStyle.SetTitleFont(42, "XYZ")
82 gStyle.SetTitleSize(0.04, "XYZ")
83 gStyle.SetTitleXOffset(1.1)
84 gStyle.SetTitleYOffset(2)
85 gStyle.SetTextAlign(12)
86 gStyle.SetLabelColor(1, "XYZ")
87 gStyle.SetLabelFont(42, "XYZ")
88 gStyle.SetLabelOffset(0.007, "XYZ")
89 gStyle.SetLabelSize(0.04, "XYZ")
90 gStyle.SetAxisColor(1, "XYZ")
91 gStyle.SetStripDecimals(True)
92 gStyle.SetTickLength(0.03, "XYZ")
93 gStyle.SetNdivisions(510, "XYZ")
94 gStyle.SetPadTickX(1)
95 gStyle.SetPadTickY(1)
96 gROOT.ForceStyle()
97
98
99 #set the text for the luminosity label
100 if(intLumi < 1000.):
101 LumiInPb = intLumi
102 LumiText = "L_{int} = " + str(intLumi) + " pb^{-1}"
103 LumiText = "L_{int} = " + str.format('{0:.1f}', LumiInPb) + " pb^{-1}"
104 else:
105 LumiInFb = intLumi/1000.
106 LumiText = "L_{int} = " + str.format('{0:.1f}', LumiInFb) + " fb^{-1}"
107
108 #bestest place for lumi. label, in top left corner
109 topLeft_x_left = 0.1375839
110 topLeft_x_right = 0.4580537
111 topLeft_y_bottom = 0.8479021
112 topLeft_y_top = 0.9475524
113 topLeft_y_offset = 0.035
114
115 #set the text for the fancy heading
116 HeaderText = "CMS Preliminary: " + LumiText + " at #sqrt{s} = 8 TeV"
117
118 #position for header
119 header_x_left = 0.2181208
120 header_x_right = 0.9562937
121 header_y_bottom = 0.9479866
122 header_y_top = 0.9947552
123
124
125
126 ##########################################################################################################################################
127 ##########################################################################################################################################
128 ##########################################################################################################################################
129
130 # some fancy-ass code from Andrzej Zuranski to merge bins in the ratio plot until the error goes below some threshold
131 def ratioHistogram( dataHist, mcHist, relErrMax=0.10):
132
133 if not dataHist:
134 print "Error: trying to run ratioHistogram but dataHist is invalid"
135 return
136
137 if not mcHist:
138 print "Error: trying to run ratioHistogram but mcHist is invalid"
139 return
140
141 def groupR(group):
142 Data,MC = [float(sum(hist.GetBinContent(i) for i in group)) for hist in [dataHist,mcHist]]
143 return (Data-MC)/MC if MC else 0
144
145 def groupErr(group):
146 Data,MC = [float(sum(hist.GetBinContent(i) for i in group)) for hist in [dataHist,mcHist]]
147 dataErr2,mcErr2 = [sum(hist.GetBinError(i)**2 for i in group) for hist in [dataHist,mcHist]]
148 if Data > 0 and MC > 0 and Data != MC:
149 return abs(math.sqrt( (dataErr2+mcErr2)/(Data-MC)**2 + mcErr2/MC**2 ) * (Data-MC)/MC)
150 else:
151 return 0
152
153 def regroup(groups):
154 err,iG = max( (groupErr(g),groups.index(g)) for g in groups )
155 if err < relErrMax or len(groups)<3 : return groups
156 iH = max( [iG-1,iG+1], key = lambda i: groupErr(groups[i]) if 0<=i<len(groups) else -1 )
157 iLo,iHi = sorted([iG,iH])
158 return regroup(groups[:iLo] + [groups[iLo]+groups[iHi]] + groups[iHi+1:])
159
160 #don't rebin the histograms of the number of a given object (except for the pileup ones)
161 if ((dataHist.GetName().find("num") is not -1 and dataHist.GetName().find("Primaryvertexs") is -1) or
162 dataHist.GetName().find("CutFlow") is not -1 or
163 dataHist.GetName().find("GenMatch") is not -1):
164 ratio = dataHist.Clone()
165 ratio.Add(mcHist,-1)
166 ratio.Divide(mcHist)
167 ratio.SetTitle("")
168 else:
169 groups = regroup( [(i,) for i in range(1,1+dataHist.GetNbinsX())] )
170 ratio = TH1F("ratio","",len(groups), array('d', [dataHist.GetBinLowEdge(min(g)) for g in groups ] + [dataHist.GetXaxis().GetBinUpEdge(dataHist.GetNbinsX())]) )
171 for i,g in enumerate(groups) :
172 ratio.SetBinContent(i+1,groupR(g))
173 ratio.SetBinError(i+1,groupErr(g))
174
175 ratio.GetYaxis().SetTitle("#frac{Data-MC}{MC}")
176 ratio.SetLineColor(1)
177 ratio.SetLineWidth(2)
178 return ratio
179
180 ##########################################################################################################################################
181 ##########################################################################################################################################
182 ##########################################################################################################################################
183
184
185 def MakeOneDHist(pathToDir,distribution):
186
187 numFittingSamples = 0
188
189 HeaderLabel = TPaveLabel(header_x_left,header_y_bottom,header_x_right,header_y_top,HeaderText,"NDC")
190 HeaderLabel.SetTextAlign(32)
191 HeaderLabel.SetBorderSize(0)
192 HeaderLabel.SetFillColor(0)
193 HeaderLabel.SetFillStyle(0)
194
195 LumiLabel = TPaveLabel(topLeft_x_left,topLeft_y_bottom,topLeft_x_right,topLeft_y_top,LumiText,"NDC")
196 LumiLabel.SetBorderSize(0)
197 LumiLabel.SetFillColor(0)
198 LumiLabel.SetFillStyle(0)
199
200 NormLabel = TPaveLabel()
201 NormLabel.SetDrawOption("NDC")
202 NormLabel.SetX1NDC(topLeft_x_left)
203 NormLabel.SetX2NDC(topLeft_x_right)
204
205 NormLabel.SetBorderSize(0)
206 NormLabel.SetFillColor(0)
207 NormLabel.SetFillStyle(0)
208
209 NormText = ""
210 if arguments.normalizeToUnitArea:
211 NormText = "Scaled to unit area"
212 elif arguments.normalizeToData:
213 NormText = "MC scaled to data"
214 NormLabel.SetLabel(NormText)
215
216 YieldsLabel = TPaveText(0.39, 0.7, 0.59, 0.9,"NDC")
217 YieldsLabel.SetBorderSize(0)
218 YieldsLabel.SetFillColor(0)
219 YieldsLabel.SetFillStyle(0)
220 YieldsLabel.SetTextAlign(12)
221
222 RatiosLabel = TPaveText()
223 RatiosLabel.SetDrawOption("NDC")
224 RatiosLabel.SetBorderSize(0)
225 RatiosLabel.SetFillColor(0)
226 RatiosLabel.SetFillStyle(0)
227 RatiosLabel.SetTextAlign(32)
228
229
230 Legend = TLegend()
231 Legend.SetBorderSize(0)
232 Legend.SetFillColor(0)
233 Legend.SetFillStyle(0)
234
235
236 fittingIntegral = 0
237 scaleFactor = 1
238
239 HistogramsToFit = []
240 TargetDataset = distribution['target_dataset']
241
242 FittingLegendEntries = []
243 DataLegendEntries = []
244
245 FittingHistogramDatasets = []
246
247
248 Stack_list = []
249 Stack_list.append (THStack("stack_before",distribution['name']))
250 Stack_list.append (THStack("stack_after",distribution['name']))
251
252 fileName = condor_dir + "/" + distribution['target_dataset'] + ".root"
253 if not os.path.exists(fileName):
254 return
255 inputFile = TFile(fileName)
256 if inputFile.IsZombie() or not inputFile.GetNkeys():
257 return
258
259
260
261 Target = inputFile.Get("OSUAnalysis/"+distribution['channel']+"/"+distribution['name']).Clone()
262 Target.SetDirectory(0)
263 inputFile.Close()
264
265 Target.SetMarkerStyle(20)
266 Target.SetMarkerSize(0.8)
267 Target.SetFillStyle(0)
268 Target.SetLineColor(colors[TargetDataset])
269 Target.SetLineStyle(1)
270 Target.SetLineWidth(2)
271 targetIntegral = Target.Integral()
272 if(arguments.normalizeToUnitArea and Target.Integral() > 0):
273 Target.Scale(1./Target.Integral())
274
275 ### formatting target histogram and adding to legend
276 legendIndex = 0
277 Legend.AddEntry(Target,labels[TargetDataset],"LEP")
278 legendIndex = legendIndex+1
279
280 if not outputFile.Get ("OSUAnalysis"):
281 outputFile.mkdir ("OSUAnalysis")
282 if not outputFile.Get ("OSUAnalysis/" + distribution['channel']):
283 outputFile.Get ("OSUAnalysis").mkdir (distribution['channel'])
284
285 for sample in distribution['datasets']: # loop over different samples requested to be fit
286
287 dataset_file = "%s/%s.root" % (condor_dir,sample)
288 inputFile = TFile(dataset_file)
289 HistogramObj = inputFile.Get(pathToDir+"/"+distribution['channel']+"/"+distribution['name'])
290 if not HistogramObj:
291 print "WARNING: Could not find histogram " + pathToDir + "/" + distribution['name'] + " in file " + dataset_file + ". Will skip it and continue."
292 continue
293 Histogram = HistogramObj.Clone()
294 Histogram.SetDirectory(0)
295 inputFile.Close()
296 if arguments.rebinFactor:
297 RebinFactor = int(arguments.rebinFactor)
298 #don't rebin histograms which will have less than 5 bins or any gen-matching histograms
299 if Histogram.GetNbinsX() >= RebinFactor*5 and Histogram.GetName().find("GenMatch") is -1:
300 Histogram.Rebin(RebinFactor)
301
302 xAxisLabel = Histogram.GetXaxis().GetTitle()
303 unitBeginIndex = xAxisLabel.find("[")
304 unitEndIndex = xAxisLabel.find("]")
305
306 if unitBeginIndex is not -1 and unitEndIndex is not -1: #x axis has a unit
307 yAxisLabel = "Entries / " + str(Histogram.GetXaxis().GetBinWidth(1)) + " " + xAxisLabel[unitBeginIndex+1:unitEndIndex]
308 else:
309 yAxisLabel = "Entries per bin (" + str(Histogram.GetXaxis().GetBinWidth(1)) + " width)"
310
311 if not arguments.makeFancy:
312 histoTitle = Histogram.GetTitle()
313 else:
314 histoTitle = ""
315
316
317 legLabel = labels[sample]
318 if (arguments.printYields):
319 yieldHist = Histogram.Integral()
320 legLabel = legLabel + " (%.1f)" % yieldHist
321 FittingLegendEntries.append(legLabel)
322
323 if( types[sample] == "bgMC"):
324
325 numFittingSamples += 1
326 fittingIntegral += Histogram.Integral()
327
328 Histogram.SetLineStyle(1)
329 if(arguments.noStack):
330 Histogram.SetFillStyle(0)
331 Histogram.SetLineColor(colors[sample])
332 Histogram.SetLineWidth(2)
333 else:
334 Histogram.SetFillStyle(1001)
335 Histogram.SetFillColor(colors[sample])
336 Histogram.SetLineColor(1)
337 Histogram.SetLineWidth(1)
338
339 elif( types[sample] == "signalMC"):
340
341 numFittingSamples += 1
342
343 Histogram.SetFillStyle(0)
344 Histogram.SetLineColor(colors[sample])
345 Histogram.SetLineStyle(1)
346 Histogram.SetLineWidth(2)
347 if(arguments.normalizeToUnitArea and Histogram.Integral() > 0):
348 Histogram.Scale(1./Histogram.Integral())
349
350 HistogramsToFit.append(Histogram)
351 FittingHistogramDatasets.append(sample)
352
353 #scaling histograms as per user's specifications
354 if targetIntegral > 0 and fittingIntegral > 0:
355 scaleFactor = targetIntegral/fittingIntegral
356 for fittingHist in HistogramsToFit:
357 if arguments.normalizeToData:
358 fittingHist.Scale(scaleFactor)
359
360 if arguments.normalizeToUnitArea and not arguments.noStack and fittingIntegral > 0:
361 fittingHist.Scale(1./fittingIntegral)
362 elif arguments.normalizeToUnitArea and arguments.noStack and fittingHist.Integral() > 0:
363 fittingHist.Scale(1./fittingHist.Integral())
364
365
366 def fitf (x, par):
367 xBin = HistogramsToFit[0].FindBin (x[0])
368 value = 0.0
369
370 for i in range (0, len (HistogramsToFit)):
371 value += par[i] * HistogramsToFit[i].GetBinContent (xBin) + par[i + len (HistogramsToFit)] * HistogramsToFit[i].GetBinError (xBin)
372
373 return value
374
375
376 lowerLimit = Target.GetBinLowEdge (1)
377 upperLimit = Target.GetBinLowEdge (Target.GetNbinsX ()) + Target.GetBinWidth (Target.GetNbinsX ())
378 if 'lowerLimit' in distribution:
379 lowerLimit = distribution['lowerLimit']
380 if 'upperLimit' in distribution:
381 upperLimit = distribution['upperLimit']
382 func = TF1 ("fit", fitf, lowerLimit, upperLimit, 2 * len (HistogramsToFit))
383
384 for i in range (0, len (HistogramsToFit)):
385 if 'fixed_datasets' in distribution and distribution['datasets'][i] in distribution['fixed_datasets']:
386 func.FixParameter (i, 1.0)
387 else:
388 func.SetParameter (i, 1.0)
389 func.SetParLimits (i, 0.0, 1.0e2)
390 func.SetParName (i, labels[FittingHistogramDatasets[i]])
391
392 parErrorRanges = {}
393 if arguments.parametricErrors:
394 for i in range (0, len (HistogramsToFit)):
395 for j in [-1, 1]:
396 for k in range (len (HistogramsToFit), 2 * len (HistogramsToFit)):
397 func.FixParameter (k, 0)
398 func.FixParameter (i + len (HistogramsToFit), j)
399 for k in range (0, distribution['iterations'] - 1):
400 if j == -1:
401 print "Scale down " + labels[FittingHistogramDatasets[i]] + " iteration " + str (k + 1) + "..."
402 if j == 1:
403 print "Scale up " + labels[FittingHistogramDatasets[i]] + " iteration " + str (k + 1) + "..."
404 Target.Fit ("fit", "QEMR0")
405 Target.Fit ("fit", "VEMR0")
406 if j == -1:
407 parErrorRanges[labels[FittingHistogramDatasets[i]]] = [func.GetParameter (i)]
408 if j == 1:
409 parErrorRanges[labels[FittingHistogramDatasets[i]]].append (func.GetParameter (i))
410
411 for i in range (len (HistogramsToFit), 2 * len (HistogramsToFit)):
412 func.FixParameter (i, 0)
413 for i in range (0, distribution['iterations'] - 1):
414 print "Iteration " + str (i + 1) + "..."
415 Target.Fit ("fit", "QEMR0")
416 Target.Fit ("fit", "VEMR0")
417
418 finalMax = 0
419 if not arguments.noStack:
420 for fittingHist in HistogramsToFit:
421 finalMax += fittingHist.GetMaximum()
422 else:
423 for fittingHist in HistogramsToFit:
424 if(fittingHist.GetMaximum() > finalMax):
425 finalMax = fittingHist.GetMaximum()
426 if(Target.GetMaximum() > finalMax):
427 finalMax = Target.GetMaximum()
428
429 Target.SetMaximum(1.1*finalMax)
430 Target.SetMinimum(0.0001)
431
432 Canvas = TCanvas(distribution['name'] + "_FitFunction")
433 Canvas.cd (1)
434 Target.Draw ()
435 func.Draw ("same")
436
437 outputFile.cd ("OSUAnalysis/" + distribution['channel'])
438 Canvas.Write ()
439 if arguments.savePDFs:
440 if histogram == input_histograms[0]:
441 Canvas.Print (pdfFileName + "(", "pdf")
442 else:
443 Canvas.Print (pdfFileName, "pdf")
444 Target.SetStats (0)
445
446
447
448
449 ### formatting bgMC histograms and adding to legend
450 legendIndex = numFittingSamples-1
451 for Histogram in reversed(HistogramsToFit):
452 if(arguments.noStack):
453 Legend.AddEntry(Histogram,FittingLegendEntries[legendIndex],"L")
454 else:
455 Legend.AddEntry(Histogram,FittingLegendEntries[legendIndex],"F")
456 legendIndex = legendIndex-1
457
458
459 ### Drawing histograms to canvas
460
461 makeRatioPlots = arguments.makeRatioPlots
462 makeDiffPlots = arguments.makeDiffPlots
463
464 yAxisMin = 0.0001
465 if arguments.setYMin:
466 yAxisMin = float(arguments.setYMin)
467
468
469 ### Draw everything to the canvases !!!!
470
471 for i in range (0, 2): # 0 => before, 1 => after
472
473 ratios = []
474 errors = []
475 parErrors = []
476
477 if i == 1:
478 for j in range (0, len (HistogramsToFit)):
479
480 HistogramsToFit[j].Scale (func.GetParameter (j))
481 ratios.append(func.GetParameter (j))
482 errors.append(func.GetParError(j))
483 if arguments.parametricErrors:
484 scaleDown = parErrorRanges[labels[FittingHistogramDatasets[j]]][0]
485 scaleUp = parErrorRanges[labels[FittingHistogramDatasets[j]]][1]
486 parErrors.append (abs (scaleUp - scaleDown))
487
488 for fittingHist in HistogramsToFit:
489 if not arguments.noStack:
490 Stack_list[i].Add(fittingHist)
491
492
493 #creating the histogram to represent the statistical errors on the stack
494 if not arguments.noStack:
495 ErrorHisto = HistogramsToFit[0].Clone("errors")
496 ErrorHisto.SetFillStyle(3001)
497 ErrorHisto.SetFillColor(13)
498 ErrorHisto.SetLineWidth(0)
499 if i == 1:
500 Legend.AddEntry(ErrorHisto,"Stat. Errors","F")
501 for Histogram in HistogramsToFit:
502 if Histogram is not HistogramsToFit[0]:
503 ErrorHisto.Add(Histogram)
504
505 if i == 0:
506 Canvas = TCanvas(distribution['name'] + "_Before")
507 if i == 1:
508 Canvas = TCanvas(distribution['name'] + "_After")
509
510 if makeRatioPlots or makeDiffPlots:
511 Canvas.SetFillStyle(0)
512 Canvas.Divide(1,2)
513 Canvas.cd(1)
514 gPad.SetPad(0,0.25,1,1)
515 gPad.SetMargin(0.15,0.05,0.01,0.07)
516 gPad.SetFillStyle(0)
517 gPad.Update()
518 gPad.Draw()
519 if arguments.setLogY:
520 gPad.SetLogy()
521 Canvas.cd(2)
522 gPad.SetPad(0,0,1,0.25)
523 # format: gPad.SetMargin(l,r,b,t)
524 gPad.SetMargin(0.15,0.05,0.4,0.01)
525 gPad.SetFillStyle(0)
526 gPad.SetGridy(1)
527 gPad.Update()
528 gPad.Draw()
529
530 Canvas.cd(1)
531
532 ### finding the maximum value of anything going on the canvas, so we know how to set the y-axis
533 finalMax = 0
534 if numFittingSamples is not 0 and not arguments.noStack:
535 finalMax = ErrorHisto.GetMaximum() + ErrorHisto.GetBinError(ErrorHisto.GetMaximumBin())
536 else:
537 for bgMCHist in HistogramsToFit:
538 if(bgMCHist.GetMaximum() > finalMax):
539 finalMax = bgMCHist.GetMaximum()
540 if(Target.GetMaximum() > finalMax):
541 finalMax = Target.GetMaximum() + Target.GetBinError(Target.GetMaximumBin())
542 finalMax = 1.15*finalMax
543 if arguments.setYMax:
544 finalMax = float(arguments.setYMax)
545
546
547 if not arguments.noStack: # draw stacked background samples
548 Stack_list[i].SetTitle(histoTitle)
549 Stack_list[i].Draw("HIST")
550 Stack_list[i].GetXaxis().SetTitle(xAxisLabel)
551 Stack_list[i].GetYaxis().SetTitle(yAxisLabel)
552 Stack_list[i].SetMaximum(finalMax)
553 Stack_list[i].SetMinimum(yAxisMin)
554 if makeRatioPlots or makeDiffPlots:
555 Stack_list[i].GetHistogram().GetXaxis().SetLabelSize(0)
556 #draw shaded error bands
557 ErrorHisto.Draw("A E2 SAME")
558
559 else: #draw the unstacked backgrounds
560 HistogramsToFit[0].SetTitle(histoTitle)
561 HistogramsToFit[0].Draw("HIST")
562 HistogramsToFit[0].GetXaxis().SetTitle(xAxisLabel)
563 HistogramsToFit[0].GetYaxis().SetTitle(yAxisLabel)
564 HistogramsToFit[0].SetMaximum(finalMax)
565 HistogramsToFit[0].SetMinimum(yAxisMin)
566 for bgMCHist in HistogramsToFit:
567 bgMCHist.Draw("A HIST SAME")
568
569 Target.Draw("A E X0 SAME")
570
571
572
573 #legend coordinates, empirically determined :-)
574 x_left = 0.6761745
575 x_right = 0.9328859
576 x_width = x_right - x_left
577 y_max = 0.9
578 entry_height = 0.05
579
580 if(numFittingSamples is not 0): #then draw the data & bgMC legend
581
582 numExtraEntries = 2 # count the target and (lack of) title
583 Legend.SetX1NDC(x_left)
584 numExtraEntries = numExtraEntries + 1 # count the stat. errors entry
585
586 Legend.SetY1NDC(y_max-entry_height*(numExtraEntries+numFittingSamples))
587 Legend.SetX2NDC(x_right)
588 Legend.SetY2NDC(y_max)
589 Legend.Draw()
590
591 RatiosLabel.SetX1NDC(x_left - 0.1)
592 RatiosLabel.SetX2NDC(x_right)
593 RatiosLabel.SetY2NDC(Legend.GetY1NDC() - 0.1)
594 RatiosLabel.SetY1NDC(RatiosLabel.GetY2NDC() - entry_height*(numFittingSamples))
595
596 # Deciding which text labels to draw and drawing them
597 drawLumiLabel = False
598 drawNormLabel = False
599 offsetNormLabel = False
600 drawHeaderLabel = False
601
602 if not arguments.normalizeToUnitArea: #don't draw the lumi label if there's no data and it's scaled to unit area
603 drawLumiLabel = True
604 # move the normalization label down before drawing if we drew the lumi. label
605 offsetNormLabel = True
606 if arguments.normalizeToUnitArea or arguments.normalizeToData:
607 drawNormLabel = True
608 if arguments.makeFancy:
609 drawHeaderLabel = True
610 drawLumiLabel = False
611
612 # now that flags are set, draw the appropriate labels
613
614 if drawLumiLabel:
615 LumiLabel.Draw()
616
617 if drawNormLabel:
618 if offsetNormLabel:
619 NormLabel.SetY1NDC(topLeft_y_bottom-topLeft_y_offset)
620 NormLabel.SetY2NDC(topLeft_y_top-topLeft_y_offset)
621 else:
622 NormLabel.SetY1NDC(topLeft_y_bottom)
623 NormLabel.SetY2NDC(topLeft_y_top)
624 NormLabel.Draw()
625
626 if drawHeaderLabel:
627 HeaderLabel.Draw()
628
629 YieldsLabel.Clear()
630 mcYield = Stack_list[i].GetStack().Last().Integral()
631 dataYield = Target.Integral()
632 if i == 0:
633 YieldsLabel.AddText ("Before Fit to Data")
634 if i == 1:
635 YieldsLabel.AddText ("After Fit to Data")
636 YieldsLabel.AddText ("data yield: " + '%.1f' % dataYield)
637 YieldsLabel.AddText ("MC yield: " + '%.1f' % mcYield)
638 if i == 1:
639 for j in range(0,len(FittingLegendEntries)):
640 text = FittingLegendEntries[j]+" ratio: " + '%.2f' % ratios[j] + ' #pm %.2f' % errors[j]
641 if arguments.parametricErrors:
642 text += ' #pm %.2f' % parErrors[j]
643 RatiosLabel.AddText (text)
644 YieldsLabel.Draw()
645 RatiosLabel.Draw()
646
647 # drawing the ratio or difference plot if requested
648 if (makeRatioPlots or makeDiffPlots):
649 Canvas.cd(2)
650 BgSum = Stack_list[i].GetStack().Last()
651 if makeRatioPlots:
652 if arguments.ratioRelErrMax:
653 Comparison = ratioHistogram(Target,BgSum,arguments.ratioRelErrMax)
654 else:
655 Comparison = ratioHistogram(Target,BgSum)
656 elif makeDiffPlots:
657 Comparison = Target.Clone("diff")
658 Comparison.Add(BgSum,-1)
659 Comparison.SetTitle("")
660 Comparison.GetYaxis().SetTitle("Data-MC")
661 Comparison.GetXaxis().SetTitle(xAxisLabel)
662 Comparison.GetYaxis().CenterTitle()
663 Comparison.GetYaxis().SetTitleSize(0.1)
664 Comparison.GetYaxis().SetTitleOffset(0.5)
665 Comparison.GetXaxis().SetTitleSize(0.15)
666 Comparison.GetYaxis().SetLabelSize(0.1)
667 Comparison.GetXaxis().SetLabelSize(0.15)
668 if makeRatioPlots:
669 RatioYRange = 1.15
670 if arguments.ratioYRange:
671 RatioYRange = float(arguments.ratioYRange)
672 Comparison.GetYaxis().SetRangeUser(-1*RatioYRange, RatioYRange)
673 elif makeDiffPlots:
674 YMax = Comparison.GetMaximum()
675 YMin = Comparison.GetMinimum()
676 if YMax <= 0 and YMin <= 0:
677 Comparison.GetYaxis().SetRangeUser(-1.2*YMin,0)
678 elif YMax >= 0 and YMin >= 0:
679 Comparison.GetYaxis().SetRangeUser(0,1.2*YMax)
680 else: #axis crosses y=0
681 if abs(YMax) > abs(YMin):
682 Comparison.GetYaxis().SetRangeUser(-1.2*YMax,1.2*YMax)
683 else:
684 Comparison.GetYaxis().SetRangeUser(-1.2*YMin,1.2*YMin)
685
686 Comparison.GetYaxis().SetNdivisions(205)
687 Comparison.Draw()
688
689
690
691 if i == 0:
692 Canvas.Write (distribution['name'] + "_Before")
693 if arguments.savePDFs:
694 pathToDirString = plainTextString(pathToDir)
695 Canvas.SaveAs(condor_dir+"/fitting_histogram_pdfs/"+pathToDirString+"/"+distribution['name']+"_Before.pdf")
696
697 if i == 1:
698 Canvas.Write (distribution['name'] + "_After")
699 if arguments.savePDFs:
700 pathToDirString = plainTextString(pathToDir)
701 Canvas.SaveAs(condor_dir+"/fitting_histogram_pdfs/"+pathToDirString+"/"+distribution['name']+"_After.pdf")
702
703
704
705
706
707 ##########################################################################################################################################
708 ##########################################################################################################################################
709 ##########################################################################################################################################
710
711
712 ##########################################################################################################################################
713 ##########################################################################################################################################
714 ##########################################################################################################################################
715
716
717 condor_dir = set_condor_output_dir(arguments)
718
719
720 # make output file
721 outputFileName = "mc_fit_to_data.root"
722 if arguments.outputFileName:
723 outputFileName = arguments.outputFileName
724
725 outputFile = TFile(condor_dir + "/" + outputFileName, "RECREATE")
726
727
728 if arguments.savePDFs:
729 os.system("rm -rf %s/fitting_histograms_pdfs" % (condor_dir))
730 os.system("mkdir %s/fitting_histograms_pdfs" % (condor_dir))
731
732
733 #get root directory in the first layer, generally "OSUAnalysis"
734 for distribution in input_distributions:
735 MakeOneDHist("OSUAnalysis",distribution)
736
737 outputFile.Close()