ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/OSUT3Analysis/Configuration/scripts/fitMCToData.py
Revision: 1.6
Committed: Tue Sep 3 08:20:58 2013 UTC (11 years, 8 months ago) by lantonel
Content type: text/x-python
Branch: MAIN
Changes since 1.5: +26 -9 lines
Log Message:
added ability to fix some distributions

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