ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/OSUT3Analysis/Configuration/scripts/makePlots.py
Revision: 1.45
Committed: Tue Jun 25 11:17:16 2013 UTC (11 years, 10 months ago) by wulsin
Content type: text/x-python
Branch: MAIN
Changes since 1.44: +5 -3 lines
Log Message:
Move definition of yAxisMin outside of bkgd MC loop to avoid error when plotting signal samples

File Contents

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