ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/OSUT3Analysis/Configuration/scripts/makePlots.py
Revision: 1.51
Committed: Thu Jun 27 14:49:27 2013 UTC (11 years, 10 months ago) by lantonel
Content type: text/x-python
Branch: MAIN
CVS Tags: V02-03-01, V02-03-00
Changes since 1.50: +1 -24 lines
Log Message:
migrated useful functions to formattingUtilities.py

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