ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/OSUT3Analysis/Configuration/scripts/makePlots.py
Revision: 1.55
Committed: Tue Jul 23 08:39:25 2013 UTC (11 years, 9 months ago) by lantonel
Content type: text/x-python
Branch: MAIN
Changes since 1.54: +5 -3 lines
Log Message:
fixed a bug in the y-axis unit labeling, it had been assuming that the unit was at the end of the x-axis label

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