3 """This script compares two given root files and saves plots where they differ
6 author: Felix Socher <Felix.Socher@cern.ch>"""
22 newdir = cwd +
"/" + directory
23 if not os.path.isdir( newdir ):
24 print "Creating folder " + newdir
31 for x
in range(refHist.GetNbinsX()):
32 for y
in range(refHist.GetNbinsY()):
33 for z
in range(refHist.GetNbinsZ()):
34 if refHist.GetBinContent(x,y,z) != testHist.GetBinContent(x,y,z):
return False
38 for x
in range(refHist.GetNbinsX()):
39 for y
in range(refHist.GetNbinsY()):
40 for z
in range(refHist.GetNbinsZ()):
41 if abs(refHist.GetBinContent(x,y,z) - testHist.GetBinContent(x,y,z)) > 0.01:
return False
48 """docstring for Validator"""
49 def __init__(self, structDirs, exclude, compareFunc, normalization):
58 openedFiles = [ TFile.Open(f)
for f
in fileNames ]
64 newRefDir = refDir.GetDirectory(dirName)
66 if testDir == refDir:
continue
68 print 'ERROR --------- test dir not found: ', dirName, testDir
71 newTestDirs = [ testDir.GetDirectory(dirName)
for testDir
in dirs ]
78 for key
in theDir.GetListOfKeys():
83 if obj.IsA().InheritsFrom(ROOT.TH2.Class()):
86 if obj.IsA().InheritsFrom(ROOT.TH1.Class()):
89 testHists = [ newTestDir.Get(key.GetName())
for newTestDir
in newTestDirs ]
91 elif obj.IsA().InheritsFrom(ROOT.TDirectory.Class()):
108 if (ymin==0
and ymax==0):
109 ymin =
min( [ h.GetMinimum()
for h
in hists ] )
110 ymax =
min( [ h.GetMaximum()
for h
in hists ] )
111 if ymin>0
and ymax>0:
114 ymin = ymin - 0.15*abs(ymin)
115 ymax = ymax+ 0.15*ymax
119 hists[0].SetMinimum(ymin)
120 hists[0].SetMaximum(ymax)
129 canvas = ROOT.TCanvas(
"",
"", 900, 900 )
130 padMain = ROOT.TPad(
'padMain',
'padMain', 0, 0.3, 1, 1 )
131 padMain.SetBottomMargin( 0.02 )
134 padRatio = ROOT.TPad(
'padRatio',
'padRatio', 0, 0, 1, 0.3 )
135 padRatio.SetTopMargin( 0.01 )
136 padRatio.SetBottomMargin( 0.25 )
141 leg = ROOT.TLegend(0.82,0.78,0.96,0.94)
147 leg.SetTextSizePixels(32)
150 refHist.SetLineColor(17)
159 for i
in range(0,len(hists)):
160 leg.AddEntry(hists[i], LABELS[i],
'lp')
162 if self.
DoNormalization and not "_Eff_" in refHist.GetName()
and not "_eff" in refHist.GetName()
and not "_Eff" in refHist.GetName():
170 ref_textsize = 32./(padMain.GetWh()*padMain.GetAbsHNDC())
171 refHist.GetYaxis().SetLabelSize( ref_textsize )
172 refHist.GetXaxis().SetLabelSize( 0 )
173 refHist.GetXaxis().SetTitleSize( 0 )
174 refHist.GetYaxis().SetTitleSize( 1.3*ref_textsize )
175 refHist.GetYaxis().SetTitleOffset(1)
176 refHist.GetYaxis().SetTitleColor( kAzure )
180 refHist.SetMarkerSize(0)
181 refHist.SetLineColor(ROOT.kRed)
187 histmax.DrawCopy(
'e')
199 h.DrawCopy(
'histsame')
206 h.SetLineStyle(ROOT.kDashed)
207 h.DrawCopy(
'ehistsame')
220 if h
is refHist:
continue
221 ratioHist = h.Clone()
222 ratioHist.Divide(refHist)
223 ratioHist =
SetBounds( [ratioHist, ratioHist], 0.84,1.16)
224 for i
in range(ratioHist.GetNbinsX()):
225 nref = refHist.GetBinContent(i)
226 ntest = h.GetBinContent(i)
227 if nref == 0
or ntest == 0:
228 ratioHist.SetBinError(i, 0)
231 error = nref/ntest*
max(refHist.GetBinError(i)/nref, h.GetBinError(i)/ntest)
232 ratioHist.SetBinError(i, error)
234 ratioHist_textsize = 32./(padRatio.GetWh()*padRatio.GetAbsHNDC())
235 ratioHist.GetYaxis().SetLabelSize( ratioHist_textsize )
236 ratioHist.GetXaxis().SetLabelSize( ratioHist_textsize )
237 ratioHist.GetXaxis().SetTitleSize( 1.2*ratioHist_textsize )
238 ratioHist.GetXaxis().SetTitleOffset(0.75)
239 ratioHist.GetXaxis().SetTitleColor(kAzure)
240 ratioHist.GetYaxis().SetTitleSize( ratioHist_textsize )
241 ratioHist.GetYaxis().SetTitleOffset(0.6)
244 ratioHist.SetLineColor(ROOT.kBlack)
245 ratioHist.SetMarkerStyle(24)
246 ratioHist.SetYTitle(
"test / ref")
248 ratioHist.DrawCopy(
"p")
249 lineRatio = ROOT.TLine( ratioHist.GetXaxis().GetXmin(), 1,
250 ratioHist.GetXaxis().GetXmax(), 1 )
251 lineRatio.SetLineColor( ROOT.kRed )
252 lineRatio.SetLineWidth( 2 )
253 lineRatio.Draw(
"same")
255 ratioHist.SetMarkerStyle(25)
256 ratioHist.SetMarkerColor(8)
257 ratioHist.SetLineColor(8)
258 ratioHist.DrawCopy(
"psame")
262 npath = path[path.find(
":/")+2:] +
"/"
263 npath = re.sub(
r"[:,./]",
"_", npath+
"/")
270 t.DrawLatex(0.,0.97,refHist.GetName())
272 canvas.SaveAs(npath + refHist.GetName() +
".pdf")
278 Main function to be executed when starting the code.
281 parser = argparse.ArgumentParser( description =
'Distribution Plotter' )
282 parser.add_argument(
'-s',
'--structDirs', default =
True, action =
"store_true", help =
' if true, it creates directories following the same structure as in the root file to store the pdf plots')
283 parser.add_argument(
'-r',
'--reference', help =
'The reference' )
284 parser.add_argument(
'-t',
'--test', help =
'The test' )
285 parser.add_argument(
'-t2',
'--test2', default =
'', help =
'The additional test' )
286 parser.add_argument(
'-d',
'--directory', default =
"/", help =
'Print cutflow fror systematic variations' )
287 parser.add_argument(
'-e',
'--exclude', default =
"_bin_", help =
'histograms whose names contain the provided strings are not examined')
288 parser.add_argument(
'-n',
'--normalize', default =
False, action =
"store_true", help =
'normalize histograms with larger stats for better comparison')
289 parser.add_argument(
'-l',
'--labels', default =
'', help =
'Add text to legend for ref/test/test2, split with commas' )
291 args = parser.parse_args()
295 ROOT.gROOT.SetBatch()
297 ROOT.gROOT.LoadMacro(
"./AtlasStyle.C")
298 ROOT.TH1.SetDefaultSumw2(ROOT.kTRUE)
303 if args.labels
is '':
304 LABELS = [
'Ref',
'Test' ]
305 if args.test2
is not '':
306 LABELS.append(
'Test2' )
308 LABELS = args.labels.split(
",")
315 validator =
Validator( args.structDirs, args.exclude, SameHist, args.normalize )
317 allFiles = [ os.path.abspath(args.reference), os.path.abspath(args.test) ]
319 allFiles = [ os.path.abspath(args.reference), os.path.abspath(args.test), os.path.abspath(args.test2) ]
322 if __name__ ==
"__main__":
324 Here the code should appear that is executed when running the plotter directly
325 (and not import it in another python file via 'import Plotter')