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

# User Rev Content
1 ahart 1.1 #!/usr/bin/env python
2     import sys
3     import os
4     import re
5 ahart 1.7 import time
6 lantonel 1.4 from math import *
7 ahart 1.1 from array import *
8     from decimal import *
9 lantonel 1.4 from optparse import OptionParser
10 ahart 1.1 from OSUT3Analysis.Configuration.configurationOptions import *
11     from OSUT3Analysis.Configuration.processingUtilities import *
12 lantonel 1.4 from OSUT3Analysis.Configuration.formattingUtilities import *
13    
14 ahart 1.1
15 lantonel 1.4
16     ### parse the command-line options
17 ahart 1.1
18     parser = OptionParser()
19     parser = set_commandline_arguments(parser)
20    
21 lantonel 1.4 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 ahart 1.7 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 lantonel 1.4 parser.add_option("-E", "--ratioRelErrMax", dest="ratioRelErrMax",
30 ahart 1.7 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 ahart 1.1
34     (arguments, args) = parser.parse_args()
35    
36 lantonel 1.4
37 ahart 1.1 if arguments.localConfig:
38 lantonel 1.4 sys.path.append(os.getcwd())
39 ahart 1.1 exec("from " + arguments.localConfig.rstrip('.py') + " import *")
40    
41 lantonel 1.4 #### 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 ahart 1.1 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 lantonel 1.4 if arguments.makeRatioPlots and arguments.noStack:
53 ahart 1.7 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 lantonel 1.4 arguments.makeRatioPlots = False
55     if arguments.makeDiffPlots and arguments.noStack:
56 ahart 1.7 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 lantonel 1.4 arguments.makeDiffPlots = False
58 ahart 1.7
59 lantonel 1.4
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 ahart 1.1
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 lantonel 1.4 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 ahart 1.1 gROOT.ForceStyle()
97    
98    
99 lantonel 1.4 #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 ahart 1.1
125    
126 lantonel 1.4 ##########################################################################################################################################
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 ahart 1.7 print "Error: trying to run ratioHistogram but dataHist is invalid"
135 lantonel 1.4 return
136    
137     if not mcHist:
138 ahart 1.7 print "Error: trying to run ratioHistogram but mcHist is invalid"
139 lantonel 1.4 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 ahart 1.7
145 lantonel 1.4 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 ahart 1.7 if Data > 0 and MC > 0 and Data != MC:
149 lantonel 1.4 return abs(math.sqrt( (dataErr2+mcErr2)/(Data-MC)**2 + mcErr2/MC**2 ) * (Data-MC)/MC)
150     else:
151     return 0
152 ahart 1.1
153 lantonel 1.4 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 ahart 1.7 dataHist.GetName().find("GenMatch") is not -1):
164 lantonel 1.4 ratio = dataHist.Clone()
165     ratio.Add(mcHist,-1)
166     ratio.Divide(mcHist)
167     ratio.SetTitle("")
168 ahart 1.1 else:
169 lantonel 1.4 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 ahart 1.7 def MakeOneDHist(pathToDir,distribution):
186 lantonel 1.4
187     numFittingSamples = 0
188 ahart 1.7
189 lantonel 1.4 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 ahart 1.1
195 lantonel 1.4 LumiLabel = TPaveLabel(topLeft_x_left,topLeft_y_bottom,topLeft_x_right,topLeft_y_top,LumiText,"NDC")
196 ahart 1.1 LumiLabel.SetBorderSize(0)
197     LumiLabel.SetFillColor(0)
198     LumiLabel.SetFillStyle(0)
199 ahart 1.7
200 lantonel 1.4 NormLabel = TPaveLabel()
201     NormLabel.SetDrawOption("NDC")
202     NormLabel.SetX1NDC(topLeft_x_left)
203     NormLabel.SetX2NDC(topLeft_x_right)
204 ahart 1.7
205 lantonel 1.4 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 ahart 1.7
230 lantonel 1.4 Legend = TLegend()
231     Legend.SetBorderSize(0)
232     Legend.SetFillColor(0)
233     Legend.SetFillStyle(0)
234    
235 ahart 1.7
236 lantonel 1.4 fittingIntegral = 0
237     scaleFactor = 1
238 ahart 1.1
239 lantonel 1.4 HistogramsToFit = []
240     TargetDataset = distribution['target_dataset']
241    
242     FittingLegendEntries = []
243     DataLegendEntries = []
244    
245     FittingHistogramDatasets = []
246 ahart 1.1
247    
248 lantonel 1.4 Stack_list = []
249     Stack_list.append (THStack("stack_before",distribution['name']))
250 ahart 1.7 Stack_list.append (THStack("stack_after",distribution['name']))
251 ahart 1.1
252 lantonel 1.4 fileName = condor_dir + "/" + distribution['target_dataset'] + ".root"
253 ahart 1.1 if not os.path.exists(fileName):
254 lantonel 1.4 return
255 ahart 1.1 inputFile = TFile(fileName)
256     if inputFile.IsZombie() or not inputFile.GetNkeys():
257 lantonel 1.4 return
258    
259    
260 ahart 1.1
261 lantonel 1.4 Target = inputFile.Get("OSUAnalysis/"+distribution['channel']+"/"+distribution['name']).Clone()
262 ahart 1.1 Target.SetDirectory(0)
263     inputFile.Close()
264 ahart 1.7
265 lantonel 1.4 Target.SetMarkerStyle(20)
266     Target.SetMarkerSize(0.8)
267 ahart 1.1 Target.SetFillStyle(0)
268     Target.SetLineColor(colors[TargetDataset])
269     Target.SetLineStyle(1)
270     Target.SetLineWidth(2)
271 lantonel 1.4 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 ahart 1.7
280 ahart 1.1 if not outputFile.Get ("OSUAnalysis"):
281     outputFile.mkdir ("OSUAnalysis")
282 lantonel 1.4 if not outputFile.Get ("OSUAnalysis/" + distribution['channel']):
283     outputFile.Get ("OSUAnalysis").mkdir (distribution['channel'])
284 ahart 1.7
285 lantonel 1.4 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 ahart 1.7 print "WARNING: Could not find histogram " + pathToDir + "/" + distribution['name'] + " in file " + dataset_file + ". Will skip it and continue."
292     continue
293 lantonel 1.4 Histogram = HistogramObj.Clone()
294 ahart 1.1 Histogram.SetDirectory(0)
295     inputFile.Close()
296     if arguments.rebinFactor:
297     RebinFactor = int(arguments.rebinFactor)
298 lantonel 1.4 #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 ahart 1.1 Histogram.Rebin(RebinFactor)
301    
302 lantonel 1.4 xAxisLabel = Histogram.GetXaxis().GetTitle()
303     unitBeginIndex = xAxisLabel.find("[")
304     unitEndIndex = xAxisLabel.find("]")
305 ahart 1.7
306 lantonel 1.4 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 ahart 1.7
311 lantonel 1.4 if not arguments.makeFancy:
312     histoTitle = Histogram.GetTitle()
313     else:
314     histoTitle = ""
315    
316 ahart 1.1
317 lantonel 1.4 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 ahart 1.7
325 lantonel 1.4 numFittingSamples += 1
326     fittingIntegral += Histogram.Integral()
327 ahart 1.7
328 lantonel 1.4 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 ahart 1.7
341 lantonel 1.4 numFittingSamples += 1
342 ahart 1.7
343 ahart 1.1 Histogram.SetFillStyle(0)
344 lantonel 1.4 Histogram.SetLineColor(colors[sample])
345     Histogram.SetLineStyle(1)
346 ahart 1.1 Histogram.SetLineWidth(2)
347 lantonel 1.4 if(arguments.normalizeToUnitArea and Histogram.Integral() > 0):
348     Histogram.Scale(1./Histogram.Integral())
349 ahart 1.7
350 lantonel 1.4 HistogramsToFit.append(Histogram)
351     FittingHistogramDatasets.append(sample)
352 ahart 1.7
353 lantonel 1.4 #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 ahart 1.1
365    
366     def fitf (x, par):
367     xBin = HistogramsToFit[0].FindBin (x[0])
368     value = 0.0
369 ahart 1.7
370 ahart 1.1 for i in range (0, len (HistogramsToFit)):
371 ahart 1.7 value += par[i] * HistogramsToFit[i].GetBinContent (xBin) + par[i + len (HistogramsToFit)] * HistogramsToFit[i].GetBinError (xBin)
372 lantonel 1.6
373 ahart 1.1 return value
374    
375 lantonel 1.6
376 ahart 1.1 lowerLimit = Target.GetBinLowEdge (1)
377     upperLimit = Target.GetBinLowEdge (Target.GetNbinsX ()) + Target.GetBinWidth (Target.GetNbinsX ())
378 lantonel 1.4 if 'lowerLimit' in distribution:
379     lowerLimit = distribution['lowerLimit']
380     if 'upperLimit' in distribution:
381     upperLimit = distribution['upperLimit']
382 ahart 1.7 func = TF1 ("fit", fitf, lowerLimit, upperLimit, 2 * len (HistogramsToFit))
383 ahart 1.1
384     for i in range (0, len (HistogramsToFit)):
385 lantonel 1.6 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 ahart 1.7 func.SetParLimits (i, 0.0, 1.0e2)
390 lantonel 1.4 func.SetParName (i, labels[FittingHistogramDatasets[i]])
391 ahart 1.1
392 ahart 1.7 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 lantonel 1.4 for i in range (0, distribution['iterations'] - 1):
414 ahart 1.1 print "Iteration " + str (i + 1) + "..."
415     Target.Fit ("fit", "QEMR0")
416     Target.Fit ("fit", "VEMR0")
417    
418 ahart 1.2 finalMax = 0
419     if not arguments.noStack:
420 lantonel 1.4 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 ahart 1.2 if(Target.GetMaximum() > finalMax):
427     finalMax = Target.GetMaximum()
428 ahart 1.7
429 ahart 1.2 Target.SetMaximum(1.1*finalMax)
430     Target.SetMinimum(0.0001)
431 ahart 1.7
432 lantonel 1.4 Canvas = TCanvas(distribution['name'] + "_FitFunction")
433 ahart 1.1 Canvas.cd (1)
434     Target.Draw ()
435 lantonel 1.4 func.Draw ("same")
436 ahart 1.7
437 lantonel 1.4 outputFile.cd ("OSUAnalysis/" + distribution['channel'])
438 ahart 1.1 Canvas.Write ()
439 lantonel 1.4 if arguments.savePDFs:
440     if histogram == input_histograms[0]:
441     Canvas.Print (pdfFileName + "(", "pdf")
442     else:
443     Canvas.Print (pdfFileName, "pdf")
444 ahart 1.1 Target.SetStats (0)
445    
446 lantonel 1.4
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 ahart 1.1
473 ahart 1.7 ratios = []
474     errors = []
475     parErrors = []
476    
477 ahart 1.1 if i == 1:
478     for j in range (0, len (HistogramsToFit)):
479 ahart 1.7
480 ahart 1.1 HistogramsToFit[j].Scale (func.GetParameter (j))
481 lantonel 1.4 ratios.append(func.GetParameter (j))
482 lantonel 1.6 errors.append(func.GetParError(j))
483 ahart 1.7 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 lantonel 1.4 for fittingHist in HistogramsToFit:
489 ahart 1.1 if not arguments.noStack:
490 lantonel 1.4 Stack_list[i].Add(fittingHist)
491    
492    
493     #creating the histogram to represent the statistical errors on the stack
494 ahart 1.7 if not arguments.noStack:
495 lantonel 1.4 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 ahart 1.1
505     if i == 0:
506 lantonel 1.4 Canvas = TCanvas(distribution['name'] + "_Before")
507 ahart 1.1 if i == 1:
508 lantonel 1.4 Canvas = TCanvas(distribution['name'] + "_After")
509    
510 ahart 1.1 if makeRatioPlots or makeDiffPlots:
511     Canvas.SetFillStyle(0)
512     Canvas.Divide(1,2)
513     Canvas.cd(1)
514 lantonel 1.4 gPad.SetPad(0,0.25,1,1)
515     gPad.SetMargin(0.15,0.05,0.01,0.07)
516 ahart 1.1 gPad.SetFillStyle(0)
517     gPad.Update()
518     gPad.Draw()
519 lantonel 1.4 if arguments.setLogY:
520     gPad.SetLogy()
521 ahart 1.1 Canvas.cd(2)
522 lantonel 1.4 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 ahart 1.1 gPad.SetFillStyle(0)
526     gPad.SetGridy(1)
527     gPad.Update()
528     gPad.Draw()
529 ahart 1.7
530 ahart 1.1 Canvas.cd(1)
531    
532 lantonel 1.4 ### 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 ahart 1.7 if arguments.setYMax:
544 lantonel 1.4 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 ahart 1.1 if makeRatioPlots or makeDiffPlots:
555 lantonel 1.4 Stack_list[i].GetHistogram().GetXaxis().SetLabelSize(0)
556     #draw shaded error bands
557     ErrorHisto.Draw("A E2 SAME")
558 ahart 1.7
559 lantonel 1.4 else: #draw the unstacked backgrounds
560 ahart 1.1 HistogramsToFit[0].SetTitle(histoTitle)
561     HistogramsToFit[0].Draw("HIST")
562     HistogramsToFit[0].GetXaxis().SetTitle(xAxisLabel)
563 lantonel 1.4 HistogramsToFit[0].GetYaxis().SetTitle(yAxisLabel)
564     HistogramsToFit[0].SetMaximum(finalMax)
565 ahart 1.7 HistogramsToFit[0].SetMinimum(yAxisMin)
566 ahart 1.1 for bgMCHist in HistogramsToFit:
567 lantonel 1.4 bgMCHist.Draw("A HIST SAME")
568 ahart 1.1
569 lantonel 1.4 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 ahart 1.7
586 lantonel 1.4 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 ahart 1.7
596 lantonel 1.4 # 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 ahart 1.7
612 lantonel 1.4 # 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 ahart 1.7 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 lantonel 1.4 YieldsLabel.Draw()
645     RatiosLabel.Draw()
646 ahart 1.1
647 lantonel 1.4 # drawing the ratio or difference plot if requested
648 ahart 1.7 if (makeRatioPlots or makeDiffPlots):
649 ahart 1.1 Canvas.cd(2)
650 lantonel 1.4 BgSum = Stack_list[i].GetStack().Last()
651 ahart 1.1 if makeRatioPlots:
652 lantonel 1.4 if arguments.ratioRelErrMax:
653     Comparison = ratioHistogram(Target,BgSum,arguments.ratioRelErrMax)
654     else:
655     Comparison = ratioHistogram(Target,BgSum)
656 ahart 1.1 elif makeDiffPlots:
657 lantonel 1.4 Comparison = Target.Clone("diff")
658     Comparison.Add(BgSum,-1)
659     Comparison.SetTitle("")
660 ahart 1.1 Comparison.GetYaxis().SetTitle("Data-MC")
661 lantonel 1.4 Comparison.GetXaxis().SetTitle(xAxisLabel)
662 ahart 1.1 Comparison.GetYaxis().CenterTitle()
663     Comparison.GetYaxis().SetTitleSize(0.1)
664 lantonel 1.4 Comparison.GetYaxis().SetTitleOffset(0.5)
665 ahart 1.1 Comparison.GetXaxis().SetTitleSize(0.15)
666     Comparison.GetYaxis().SetLabelSize(0.1)
667     Comparison.GetXaxis().SetLabelSize(0.15)
668     if makeRatioPlots:
669 lantonel 1.4 RatioYRange = 1.15
670     if arguments.ratioYRange:
671     RatioYRange = float(arguments.ratioYRange)
672     Comparison.GetYaxis().SetRangeUser(-1*RatioYRange, RatioYRange)
673 ahart 1.1 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 ahart 1.7
686 ahart 1.1 Comparison.GetYaxis().SetNdivisions(205)
687     Comparison.Draw()
688    
689 lantonel 1.4
690    
691 ahart 1.1 if i == 0:
692 lantonel 1.4 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 ahart 1.1 if i == 1:
698 lantonel 1.4 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 ahart 1.7
707 lantonel 1.4 ##########################################################################################################################################
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 ahart 1.7
732 ahart 1.1
733 lantonel 1.4 #get root directory in the first layer, generally "OSUAnalysis"
734     for distribution in input_distributions:
735     MakeOneDHist("OSUAnalysis",distribution)
736 ahart 1.1
737 ahart 1.7 outputFile.Close()