ATLAS Offline Software
Loading...
Searching...
No Matches
PlotEFTrk.py
Go to the documentation of this file.
1#!/usr/bin/env python
2# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3# Authors: Calla Hinderks, Federica Piazza
4
5import ROOT
6import math
7
8ROOT.gROOT.SetStyle("ATLAS")
9ROOT.gROOT.SetBatch()
10
11
12
13category_dict = {
14 'eff' : 'Efficiencies',
15 'tech_eff' : 'Efficiencies/Technical',
16 'purity' : 'Efficiencies/Purities',
17 'resolution' : 'Resolutions',
18 'parameter' : 'Parameters',
19 'fakerate' : 'FakeRates',
20 'duplrate' : 'Duplicates',
21 'num' : 'Multiplicities',
22 'summary' : 'Multiplicities',
23 'hits' : 'HitsOnTracks',
24 'pixels' : 'PixelClusters',
25 'strips' : 'StripClusters',
26 'tails' : 'Parameters',
27}
28
29resolution_dict = {
30 'resHelp' : 'resHelper',
31 'pullHelp' : 'pullHelper',
32 'pullwidth' : 'pullwidth',
33 'pullmean' : 'pullmean',
34 'res' : 'resolution',
35 'resmean' : 'resmean',
36 'corr' : 'corr'
37}
38
40
41 from argparse import ArgumentParser
42 parser = ArgumentParser( description='Parser for IDTPM plotting' )
43 parser.add_argument( '--test', help="Input test ROOT files", nargs = '+')
44 parser.add_argument( '--ref', help="Input reference ROOT files", nargs = '+')
45 parser.add_argument( '-o', '--output', help="Output directory")
46 parser.add_argument( '--trkAnalysisTest', help='IDTPM TrackAnalysis for test (e.g. TrkAnaEF)', nargs = '+')
47 parser.add_argument( '--trkAnalysisRef', help='IDTPM TrackAnalysis for reference (e.g. TrkAnaEF)', nargs = '+')
48 parser.add_argument( '--chain', help="Trigger chain (or Offline)", default = 'Offline')
49 parser.add_argument( '-t','--type', help="type of plot (eff, tech_eff, purity, resolution, fakerate, duplrate, num, summary)")
50 parser.add_argument( '-p','--param', help="parameter (e.g pt/eta for efficiencies, d0_vs_truth_eta for resolutions, ...)")
51 parser.add_argument( '--resplot', help="which resolution plot ('resHelp','pullHelp','pullwidth','pullmean','res','resmean','corr')", default=None)
52 parser.add_argument( '--log', help="log scale on x axis, y axis or bot (x, y, xy)", default = '')
53 parser.add_argument( '--ymax', help="maximum value for y-axis ", default = 0)
54 parser.add_argument( '--ymin', help="minimum value for y-axis ", default = 0)
55 parser.add_argument( '--ratioyrange', help="range of ratio y-axis", default = None, nargs = '+', type = float)
56 parser.add_argument( '--dim', help="specify 1D or 2D ", default='1D')
57 parser.add_argument( '--pipelineTest', help="Tested pipeline", nargs = '+')
58 parser.add_argument( '--pipelineRef', help="Reference pipeline", nargs = '+')
59 parser.add_argument( '--norm', help="normalize to unit area", action='store_true')
60 parser.add_argument( '--pu-comparison', help="compare different PU samples", action='store_true')
61 parser.add_argument( '--mu', help="<mu> value (will be printed in ATLAS legend)", default = 200)
62 parser.add_argument( '--sample', help="Sample (e.g. 't#bar{t}' / 'single e, p_{T}>10 GeV', ...). Will be printed in ATLAS legend", default = '')
63 parser.add_argument( '--particle', help="Truth particle (e.g. B-hadrons / #tau, p_{T}>15 GeV). Will be printed in ATLAS legend", default = '')
64 parser.add_argument( '--legend-coord', help="xmin, ymin, xmax, ymax TLegend coordinates", default = [0.65,0.65,0.9,0.87], type = float, nargs = '+')
65 parser.add_argument( '--tag', help="output file tag", default = '')
66 parser.print_help()
67 return parser.parse_args()
68
70 return obj.InheritsFrom("TEfficiency")
71
72def isTProfile(obj):
73 return obj.InheritsFrom("TProfile")
74
75def getHistoName(category, args):
76
77 par = args.param
78 match category:
79 case 'Parameters': return par
80 case 'Resolutions': return f"{resolution_dict[args.resplot]}_{par}"
81 case 'Efficiencies': return f"eff_vs_truth_{par}" if par!="truthMu" else "eff_vs_truthMu"
82 case 'Efficiencies/Technical': return f"eff_vs_truth_{par}" if par!="truthMu" else "eff_vs_truthMu"
83 case 'Efficiencies/Purities': return f"eff_vs_offl_{par}" if par!="truthMu" else "eff_vs_truthMu"
84 case 'FakeRates': return f"fakerate_vs_offl_{par}" if par!="truthMu" else "fakerate_vs_truthMu"
85 case 'Duplicates': return f"duplrate_vs_truth_{par}" if par!="truthMu" else "duplrate_vs_truthMu"
86 case 'Multiplicities': return par
87 case 'HitsOnTracks': return par
88 case 'PixelClusters': return par
89 case 'StripClusters': return par
90 case _: return 'None'
91
92def getHistoPath(cfg):
93
94 histopath = f"InDetTrackPerfMonPlots/{cfg['trkAnalysis']}/{cfg['chain']}/Tracks/{cfg['category']}/{cfg['histo']}" if 'Clusters' not in cfg['category'] else f"InDetTrackPerfMonPlots/{cfg['trkAnalysis']}/Offline/{cfg['category']}/{cfg['histo']}"
95 h = cfg['input'].Get(histopath)
96 if cfg['norm']: h.Scale(1./h.Integral())
97 print(cfg['input'])
98
99 return h
100
101def getConfig (input, chain, pipeline, trkana, args, color, markstyle, linestyle, isRef=False):
102
103 category = category_dict[args.type.split('_vs_')[0]] #Efficiencies, Resolutions, FakeRates, ...
104 histo = getHistoName(category, args)
105
106 config_dict = {
107 'pipeline' : pipeline,
108 'chain' : chain,
109 'isReference' : isRef,
110 'input' : input,
111 'trkAnalysis' : trkana,
112 'category' : category,
113 'histo' : histo,
114 'legend' : pipeline,
115 'linestyle' : linestyle,
116 'linecolor' : color,
117 'markstyle' : markstyle,
118 'markcolor' : color,
119 'log' : args.log,
120 'ymax' : float(args.ymax),
121 'ymin' : float(args.ymin),
122 'ratioyrange' : args.ratioyrange,
123 'dimension' : args.dim,
124 'norm' : args.norm,
125 }
126
127 return config_dict
128
129
130def getLegend(xmin,ymin,xmax,ymax):
131
132 leg = ROOT.TLegend(xmin,ymin,xmax,ymax)
133 leg.SetFillColor(0)
134 leg.SetLineColor(0)
135 leg.SetBorderSize(0)
136 leg.SetTextSize(0.05)
137 leg.SetTextFont(42)
138 leg.SetLineWidth(2)
139
140 return leg
141
143
144 sample = ''
145 if args.sample == '':
146 if 'ttbar' in args.ref[0]: sample = 't#bar{t}'
147 if 'SingleMu' in args.ref[0]: sample = 'single #mu'
148 if 'SinglePi' in args.ref[0]: sample = 'single #pi'
149 if 'SingleEl' in args.ref[0]: sample = 'single e'
150 if 'pT10_' in args.ref[0]: sample += ', p_{T} = 10 GeV'
151 if 'pT100' in args.ref[0]: sample += ', p_{T} = 100 GeV'
152 if 'pT1_' in args.ref[0]: sample += ', p_{T} = 1 GeV'
153 else: sample = args.sample
154 if args.particle != '': sample += f', {args.particle}'
155
156 subatlas = ROOT.TLatex(.2, .84, "#splitline{#bf{#it{ATLAS}} Simulation Internal}{#splitline{#sqrt{s} = 14 TeV, HL-LHC}{#splitline{ITk Layout: 03-00-01}{<#mu> = %s, %s}}}" %(args.mu, sample))
157 if args.pu_comparison:
158 subatlas = ROOT.TLatex(.2, .84, "#splitline{#bf{#it{ATLAS}} Simulation Internal}{#splitline{#sqrt{s} = 14 TeV, HL-LHC}{#splitline{ITk Layout: 03-00-01}{%s}}}" %(sample))
159 subatlas.SetNDC(1)
160 subatlas.SetTextFont(42)
161 subatlas.SetTextSize(0.05)
162
163 return subatlas
164
165def getPadSizes(args, NRef):
166
167 pad_heights = [600*0.65]
168
169 for nref in range(NRef-1): pad_heights.append(600*0.35 * (1-0.05-1/3))
170 pad_heights.append(600*0.35)
171
172 return pad_heights
173
174def getCanvas(args,cfg, NRef):
175
176 pad_heights = getPadSizes(args, NRef)
177 canv_heigh = sum(pad_heights)
178 pad_bottom = [(1-sum([pad_heights[j] for j in range(i+1)])/canv_heigh) for i in range(len(pad_heights))]
179 canv = ROOT.TCanvas("c","c",600,int(canv_heigh))
180
181 canv.cd()
182 pad1 = ROOT.TPad("pad1","pad1",0,pad_bottom[0],1,1)
183 pad1.SetNumber(1)
184 pad1.SetBottomMargin(0.05)
185
186 ratio_pads = []
187
188 for r in range(NRef):
189 ratio_pads.append(ROOT.TPad(f"pad{r+2}",f"pad{r+2}",0,pad_bottom[r+1],1,pad_bottom[r]))
190 ratio_pads[r].SetTopMargin(0.05)
191 ratio_pads[r].SetBottomMargin(0.05 if r!=(NRef-1) else 1./3.)
192 ratio_pads[r].SetNumber(r+2)
193
194 if cfg['log'] == 'x':
195 pad1.SetLogx()
196 for r in range(NRef): ratio_pads[r].SetLogx()
197
198 if cfg['log'] == 'y':
199 pad1.SetLogy()
200
201 if cfg['log'] == 'xy':
202 pad1.SetLogx()
203 pad1.SetLogy()
204 for r in range(NRef): ratio_pads[r].SetLogx()
205
206 pad1.Draw()
207
208 for r in range(NRef): ratio_pads[r].Draw()
209
210 return canv
211
212def getURDRequirementLine(h, type, canv, scale, logx = False):
213
214 scaleshift = canv.GetPad(1).GetHNDC()/canv.GetPad(2).GetHNDC()
215
216 level = 0.01 if 'rate' in type else 2
217 xmin, xmax = h.GetXaxis().GetXmin(), h.GetXaxis().GetXmax()
218 ymax,ymin = h.GetMaximum(), h.GetMinimum()
219
220 requirement_line = (ROOT.TLine(xmin,level,xmax,level))
221 requirement_line.SetLineStyle(2)
222 requirement_line.SetLineColor(ROOT.kRed)
223 requirement_line.SetLineWidth(1)
224
225 shiftup = 0.01*scaleshift if 'rate' not in type else 0.01
226 shiftdn = 0.07*scaleshift if 'rate' not in type else 0.07
227 y = level + shiftup*(ymax-ymin) if level < ymax else ymax - shiftdn *(ymax-ymin)
228 x = (.63*(xmax-xmin)+xmin) if not logx else math.exp( math.log(xmin) + 0.63*(math.log(xmax) - math.log(xmin)) )
229
230 requirement_text = ROOT.TLatex(x,y, f"#uparrow URD requirement = {level}" if level > ymax else f"URD requirement = {level}")
231 requirement_text.SetTextFont(42)
232 requirement_text.SetTextSize(0.04*scale if 'rate' not in type else 0.04)
233 requirement_text.SetTextColor(ROOT.kRed)
234 return requirement_line, requirement_text
235
236def setStyle(h, cfg):
237
238 h.SetLineColor(cfg['linecolor'])
239 h.SetLineStyle(cfg['linestyle'])
240 h.SetMarkerStyle(cfg['markstyle'])
241 h.SetMarkerColor(cfg['markcolor'])
242 h.SetMarkerSize(0.8)
243 h.SetLineWidth(2)
244
245 if isTEfficiency(h):
246
247 ROOT.gPad.Update()
248
249 if 'Efficiencies' in cfg['category']:
250 h.GetPaintedGraph().SetMaximum(1.2 if cfg['ymax']==0 else cfg['ymax'])
251 h.GetPaintedGraph().SetMinimum(0.7 if cfg['ymin']==0 else cfg['ymin'])
252
253 else:
254
255 if 'y' in str(cfg['log']):
256 h.GetPaintedGraph().SetMaximum(10*max(1,abs(math.log10(max(h.GetPaintedGraph().GetY()))))*max(h.GetPaintedGraph().GetY()) if cfg['ymax']==0 else cfg['ymax'])
257 h.GetPaintedGraph().SetMinimum(max(1e-10, min(h.GetPaintedGraph().GetY())*(0.9)) if cfg['ymin']==0 else cfg['ymin'])
258
259 else:
260 h.GetPaintedGraph().SetMaximum(1.5*float(max(h.GetPaintedGraph().GetY())) if cfg['ymax']==0 else cfg['ymax'])
261 h.GetPaintedGraph().SetMinimum(0 if cfg['ymin']==0 else cfg['ymin'])
262
263 h.GetPaintedGraph().GetXaxis().SetTitleSize(0)
264 h.GetPaintedGraph().GetXaxis().SetLabelSize(0)
265 h.GetPaintedGraph().GetYaxis().SetLabelSize(0.05)
266 h.GetPaintedGraph().GetXaxis().SetTitleSize(0.05)
267
268 else:
269
270 if cfg['norm']:
271 h.SetMaximum(1.5 if cfg['ymax']==0 else cfg['ymax'])
272 h.SetMinimum(0 if cfg['ymin']==0 else cfg['ymin'])
273
274 else:
275
276 if 'y' in str(cfg['log']):
277 h.SetMaximum(1.5*max(1,max(1,abs(math.log10(h.GetMaximum()))))*h.GetMaximum() if cfg['ymax']==0 else cfg['ymax'])
278 h.SetMinimum(max(1e-10, h.GetMinimum()*(0.9)) if cfg['ymin']==0 else cfg['ymin'])
279 if 'avgNum' in cfg['histo']: h.SetMinimum(100 if cfg['ymin']==0 else cfg['ymin'])
280
281 else:
282 h.SetMaximum(1.4*h.GetMaximum() if cfg['ymax']==0 else cfg['ymax'])
283 h.SetMinimum(0 if cfg['ymin']==0 else cfg['ymin'])
284
285 h.GetXaxis().SetTitleSize(0)
286 h.GetXaxis().SetLabelSize(0)
287 h.GetYaxis().SetLabelSize(0.05)
288 h.GetYaxis().SetTitleSize(0.05)
289
290def setRatioStyle(ratio, cfg, color, linestyle, markstyle, ref='C000', multigraph=False, labelsizescale = 65./35., lastpad = False, splittitle = False):
291 if 'vs_truthMu' in cfg['histo']: ratio.GetXaxis().SetTitle('Truth <#mu>')
292 ratio.GetXaxis().SetTitleOffset(1.5)
293 ratio.GetYaxis().SetTitle('#splitline{Ratio wrt}{%s}' %ref if splittitle else 'Ratio wrt %s' %ref)
294 ratio.GetYaxis().SetTitleSize(0.05*labelsizescale)
295 ratio.GetYaxis().SetNdivisions(505)
296 ratio.GetYaxis().SetTitleOffset(1.3*1/labelsizescale)
297
298 if cfg['ratioyrange'] is None:
299
300 if not multigraph:
301 ratio.SetMaximum()
302 ratio.SetMinimum()
303 ratio.GetYaxis().SetRangeUser(max(0.,min(ratio.GetMinimum()-0.1,abs(1.9-ratio.GetMaximum()))),max(ratio.GetMaximum()+0.1,abs(2-ratio.GetMinimum())))
304
305 else:
306 ratio.GetYaxis().SetRangeUser(cfg['ratioyrange'][0],cfg['ratioyrange'][1])
307
308 ratio.GetXaxis().SetLabelSize(0.05*labelsizescale if lastpad else 0)
309 ratio.GetXaxis().SetTitleSize(0.05*labelsizescale if lastpad else 0)
310 ratio.GetYaxis().SetLabelSize(0.05*labelsizescale)
311 ratio.GetYaxis().SetTitleSize(0.05*labelsizescale)
312
313 if not multigraph:
314
315 ratio.SetLineColor(color)
316 ratio.SetLineStyle(linestyle)
317 ratio.SetMarkerStyle(markstyle)
318 ratio.SetMarkerColor(color)
319 ratio.SetMarkerSize(0.8)
320
322
323 xmin, xmax = histos[0].GetPaintedGraph().GetXaxis().GetXmin(), histos[0].GetPaintedGraph().GetXaxis().GetXmax()
324 g1 = ROOT.TGraphAsymmErrors(histos[0].GetPaintedGraph())
325 g2 = ROOT.TGraphAsymmErrors(histos[1].GetPaintedGraph())
326 title = g1.GetXaxis().GetTitle()
327 ratio = ROOT.TGraphAsymmErrors()
328 n, n_ref, n_test = max(g1.GetN(),g2.GetN()), g1.GetN(), g2.GetN()
329 x_ref_arr, y_ref_arr = g1.GetX(), g1.GetY()
330 x_test_arr, y_test_arr = g2.GetX(), g2.GetY()
331 i_test, i_ref = 0, 0
332 err_r_low = []
333 err_r_high = []
334
335 for i in range(n):
336
337 if i_test < n_test and i_ref < n_ref:
338
339 x_ref, y_ref = x_ref_arr[i_ref], y_ref_arr[i_ref]
340 x_test, y_test = x_test_arr[i_test], y_test_arr[i_test]
341 err_ref_low, err_ref_high = g1.GetErrorYlow(i_ref), g1.GetErrorYhigh(i_ref)
342 err_test_low, err_test_high = g2.GetErrorYlow(i_test), g2.GetErrorYhigh(i_test)
343
344 # Check points matching between test and reference
345 if x_test==x_ref:
346 y_ref, y_test = y_ref_arr[i_ref], y_test_arr[i_test]
347 i_test += 1
348 i_ref += 1
349
350 if x_ref>x_test:
351 x_ref = x_test
352 y_ref, y_test = 0, y_test_arr[i_test]
353 i_test+= 1
354
355 if x_test>x_ref:
356 x_test = x_ref
357 y_test, y_ref = 0, y_ref_arr[i_ref]
358 i_ref += 1
359
360 r = y_test / y_ref if y_ref != 0 else 1000
361 if y_test == 0 and y_ref == 0: r = 1
362 err_r_low.append(r * math.sqrt((err_ref_low / y_ref)**2 + (err_test_low / y_test)**2) if y_ref > 0 and y_test > 0 else 0)
363 err_r_high.append(r * math.sqrt((err_ref_high / y_ref)**2 + (err_test_high / y_test)**2) if y_ref > 0 and y_test > 0 else 0)
364 ratio.SetPoint(i, x_ref, r)
365 ratio.GetXaxis().SetTitle(title)
366
367 # Set errors and final x axis range
368 for i in range(ratio.GetN()):
369
370 width = ratio.GetPointX(i+1)-ratio.GetPointX(i) if i < ratio.GetN()-1 else ratio.GetPointX(i)-ratio.GetPointX(i-1)
371 ratio.SetPointError(i, width/2.,width/2., err_r_low[i], err_r_high[i])
372
373 ratio.GetXaxis().SetLimits(xmin, xmax)
374
375 return ratio
376
377def drawTEfficiencyOutliers(r, configs, multigraphs, markers, NRef):
378
379 outliers_index = 0
380
381 for j,g in enumerate(multigraphs[r].GetListOfGraphs()):
382 markers.append([])
383 ROOT.gPad.Update()
384 ymin = ROOT.gPad.GetFrame().GetY1()
385 ymax = ROOT.gPad.GetFrame().GetY2()
386
387 for i in range(g.GetN()):
388
389 if g.GetPointY(i) > ymax:
390 markers[r].append(ROOT.TMarker(g.GetPointX(i), ymax-(ymax-ymin)*0.05, 26))
391 markers[r][outliers_index].SetMarkerColor(configs[j+NRef]['linecolor'])
392 markers[r][outliers_index].SetMarkerSize(1.2)
393 markers[r][outliers_index].Draw('same')
394 outliers_index += 1
395
396 if g.GetPointY(i) < ymin and g.GetPointY(i) > 0:
397 markers[r].append(ROOT.TMarker(g.GetPointX(i), ymin+(ymax-ymin)*0.05, 32))
398 markers[r][outliers_index].SetMarkerColor(configs[j+NRef]['linecolor'])
399 markers[r][outliers_index].SetMarkerSize(1.2)
400 markers[r][outliers_index].Draw('same')
401 outliers_index += 1
402
403def drawTHOutliers(r, configs, ratios, markers, NRef):
404
405 outliers_index = 0
406
407 for j,ratio in enumerate(ratios):
408 ROOT.gPad.Update()
409 ymin = ROOT.gPad.GetFrame().GetY1()
410 ymax = ROOT.gPad.GetFrame().GetY2()
411
412 for i in range(ratio.GetNbinsX()):
413
414 if ratio.GetBinContent(i) > ymax:
415 markers[r].append(ROOT.TMarker(ratio.GetXaxis().GetBinCenter(i), ymax-(ymax-ymin)*0.05, 26))
416 markers[r][outliers_index].SetMarkerColor(configs[j+NRef]['linecolor'])
417 markers[r][outliers_index].SetMarkerSize(1.2)
418 markers[r][outliers_index].Draw('same')
419 outliers_index += 1
420
421 if ratio.GetBinContent(i) < ymin and ratio.GetBinContent(i) > 0:
422 markers[r].append(ROOT.TMarker(ratio.GetXaxis().GetBinCenter(i), ymin+(ymax-ymin)*0.05, 32))
423 markers[r][outliers_index].SetMarkerColor(configs[j+NRef]['linecolor'])
424 markers[r][outliers_index].SetMarkerSize(1.2)
425 markers[r][outliers_index].Draw('same')
426 outliers_index += 1
427
428def drawRefLine(r, ratios, reflines):
429
430 reflines.append(ROOT.TLine(ratios[0].GetXaxis().GetXmin(),1,ratios[0].GetXaxis().GetXmax(),1))
431 reflines[r].SetLineStyle(2)
432 reflines[r].SetLineColor(ROOT.kBlack)
433 reflines[r].SetLineWidth(1)
434 reflines[r].Draw('same')
435
436def draw(args, configs, tails=False, pu_comparison=False):
437
438 NRef = len(args.ref) if not pu_comparison else 1
439 canv = getCanvas(args,configs[0], NRef)
440 ATLASLabel = getATLASLabel(args)
441 legend = getLegend(args.legend_coord[0],args.legend_coord[1],args.legend_coord[2],args.legend_coord[3])
442 doComparison = len(configs) > 1
443 isTEfficiencyObj = False
444 histos = []
445 canv.cd(1)
446
447 for i,cfg in enumerate(configs): # loop over the trkAnalysis to be compared (if single plot, there will be only 1 trkAnalysis)
448 h = getHistoPath(cfg)
449 isTEfficiencyObj = isTEfficiency(h)
450 histos.append(h)
451
452 if not tails: h.Draw('same' if i!=0 else '')
453
454 else: h.Draw('sameHISTE' if i%2!=0 else 'samePE')
455
456 setStyle(h, cfg)
457
458 if doComparison and cfg['dimension'] == '1D':
459 draw_option = 'lp'
460
461 if tails:
462 draw_option = 'l' if i%2!=0 else 'lp'
463 jet = 'b-Jet' if i%2==0 else 'LF-Jet'
464 legend.AddEntry(h, f"{cfg['legend']} {jet}",draw_option)
465
466 else: legend.AddEntry(h, cfg['legend'],draw_option)
467
468 legend.Draw()
469
470 ATLASLabel.Draw()
471
472 multigraphs = []
473 reflines = []
474 markers = []
475 urd_lines = []
476 urd_text = []
477
478 # Loop over reference histograms to create one ratio per reference
479 for r in range(NRef):
480
481 labelsizescales = [canv.GetPad(1).GetHNDC()/canv.GetPad(i+2).GetHNDC() for i in range(NRef)]
482 canv.cd(r+2)
483 ratios = []
484 multigraphs.append(ROOT.TMultiGraph())
485 markers.append([])
486
487 if not tails and not pu_comparison:
488
489 for i in range(NRef, len(configs)):
490 ratio_histos = [histos[r] if not isTProfile(histos[r]) else histos[r].ProjectionX(), histos[i] if not isTProfile(histos[i]) else histos[i].ProjectionX()]
491
492 if isTEfficiencyObj: ratios.append(getTEfficiencyRatio(ratio_histos))
493
494 else:
495 ratio = ratio_histos[1].Clone()
496 ratio.Divide(ratio_histos[0])
497 ratios.append(ratio)
498
499 for i, ratio in enumerate(ratios):
500 color = configs[i+NRef]['linecolor'] #if len(configs)>2 else ROOT.kBlack
501 linestyle = configs[i+1]['linestyle']# if len(configs)>2 else 1
502 markstyle = configs[i+1]['markstyle']# if len(configs)>2 else 20
503 setRatioStyle(ratio, configs[i], color, linestyle, markstyle, ref=configs[r]['pipeline'], labelsizescale = labelsizescales[r], lastpad = (r==NRef-1), splittitle = (NRef>1))
504
505 if isTEfficiencyObj:
506 multigraphs[r].Add(ratio,'p')
507
508 else:
509 ratio.Draw('same')
510
511 if isTEfficiencyObj:
512 xmin, xmax = ratios[0].GetXaxis().GetXmin(), ratios[0].GetXaxis().GetXmax()
513 setRatioStyle(multigraphs[r], configs[i], color, linestyle, markstyle, ref=configs[r]['pipeline'], multigraph=True, labelsizescale = labelsizescales[r], lastpad = (r==NRef-1), splittitle = (NRef>1))
514 multigraphs[r].Draw('a')
515 drawTEfficiencyOutliers(r, configs, multigraphs, markers, NRef)
516 multigraphs[r].GetXaxis().SetLimits(xmin, xmax)
517
518 else:
519 drawTHOutliers(r, configs, ratios, markers, NRef)
520
521 drawRefLine(r, ratios, reflines)
522
523 if args.type == 'resolution' and not pu_comparison and 'C000' in args.ref[0]:
524 requirement_line, requirement_text = getURDRequirementLine(ratios[0], 'resolution', canv, labelsizescales[r], logx = ('x' in args.log))
525 urd_lines.append(requirement_line)
526 urd_text.append(requirement_text)
527 urd_lines[r].Draw('same')
528 urd_text[r].Draw('same')
529
530 else:
531 for i in [0,2]:
532 ratio_histos = [histos[i],histos[i+1]]
533 ratio = ratio_histos[0].Clone()
534 ratio.Divide(ratio_histos[1])
535 ratios.append(ratio)
536
537 for i, ratio in enumerate(ratios):
538 color = configs[i*2]['linecolor']
539 linestyle = configs[i*2]['linestyle']
540 markstyle = configs[i*2]['markstyle']
541 setRatioStyle(ratio, configs[i], color, linestyle, markstyle, ref=configs[r]['pipeline'],labelsizescale = labelsizescales[r], lastpad = (r==NRef-1))
542 ratio.GetYaxis().SetTitle('b-Jet / LF-Jet' if tails else '<#mu> = 140/<#mu> = 200')
543 ratio.Draw('same')
544
545 drawRefLine(r, ratios, reflines)
546
547 var = cfg['histo'] if not cfg['category'] == 'Efficiencies/Technical' else cfg['histo'].replace('eff','tech_eff')
548 canv.SaveAs(f"{args.output}/{args.tag+'_' if args.tag != '' else ''}{var}.png")
549
550def main():
551
552 args = GetParserArgs()
553 chain = args.chain
554 inputTest = args.test
555 inputRef = args.ref
556 pipelinesRef = args.pipelineRef
557 pipelinesTest = args.pipelineTest
558 trkanalysesRef = args.trkAnalysisRef
559 trkanalysesTest = args.trkAnalysisTest
560 doTails = (args.type == 'tails')
561 doPUComparison = args.pu_comparison
562
563
564 if not doTails and not doPUComparison:
565 colors = [ ROOT.kRed, ROOT.kBlue, ROOT.kGreen+2, ROOT.kOrange+7, ROOT.kMagenta, ROOT.kCyan+1, ROOT.kViolet, ROOT.kTeal+2, ROOT.kPink+6, ROOT.kAzure+1]
566 linestyles = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
567 markstyles = [ 20, 21, 22, 23, 24, 25, 26, 27, 28, 30 ]
568 inputFiles = inputRef+inputTest
569 pipelines = pipelinesRef+pipelinesTest
570 trkanalyses = trkanalysesRef+trkanalysesTest
571 inputFiles = inputRef+inputTest
572
573 print(pipelines)
574 print(trkanalyses)
575 print(inputFiles)
576
577 configs = []
578
579 for i,pipeline in enumerate(pipelines):
580 isReference = (i<len(pipelinesRef))
581 f = ROOT.TFile.Open(inputFiles[i], 'READ')
582 configs.append(getConfig(f, chain, pipeline, trkanalyses[i], args, colors[i], markstyles[i], linestyles[i], isReference))
583
584 draw(args, configs)
585
586 else:
587
588 colors = [ROOT.kRed, ROOT.kRed, ROOT.kBlue, ROOT.kBlue]
589 linestyles = [2,1,2,1]
590 markstyles = [20,0,24,0] if doTails else [20, 24, 20, 24]
591 pipelines = args.pipelineRef+args.pipelineRef+args.pipelineTest+args.pipelineTest if doTails else args.pipelineRef+args.pipelineTest
592 trkanalyses = args.trkAnalysisRef
593 trkanalyses.extend(args.trkAnalysisTest)
594 inputFiles = inputRef+inputRef+inputTest+inputTest if doTails else inputRef+inputTest
595 configs = []
596
597 for i,trkana in enumerate(trkanalyses):
598 f = ROOT.TFile.Open(inputFiles[i], 'READ')
599 configs.append(getConfig(f, chain, pipelines[i], trkanalyses[i], args, colors[i], markstyles[i], linestyles[i]))
600
601 draw(args, configs, tails=doTails,pu_comparison=doPUComparison)
602
603if __name__ == "__main__":
604 main()
void print(char *figname, TCanvas *c1)
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
T * Get(TFile &f, const std::string &n, const std::string &dir="", const chainmap_t *chainmap=0, std::vector< std::string > *saved=0)
get a histogram given a path, and an optional initial directory if histogram is not found,...
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:310
getHistoPath(cfg)
Definition PlotEFTrk.py:92
getConfig(input, chain, pipeline, trkana, args, color, markstyle, linestyle, isRef=False)
Definition PlotEFTrk.py:101
getURDRequirementLine(h, type, canv, scale, logx=False)
Definition PlotEFTrk.py:212
drawTHOutliers(r, configs, ratios, markers, NRef)
Definition PlotEFTrk.py:403
setRatioStyle(ratio, cfg, color, linestyle, markstyle, ref='C000', multigraph=False, labelsizescale=65./35., lastpad=False, splittitle=False)
Definition PlotEFTrk.py:290
drawRefLine(r, ratios, reflines)
Definition PlotEFTrk.py:428
getATLASLabel(args)
Definition PlotEFTrk.py:142
getLegend(xmin, ymin, xmax, ymax)
Definition PlotEFTrk.py:130
getCanvas(args, cfg, NRef)
Definition PlotEFTrk.py:174
getTEfficiencyRatio(histos)
Definition PlotEFTrk.py:321
isTEfficiency(obj)
Definition PlotEFTrk.py:69
drawTEfficiencyOutliers(r, configs, multigraphs, markers, NRef)
Definition PlotEFTrk.py:377
GetParserArgs()
Definition PlotEFTrk.py:39
getHistoName(category, args)
Definition PlotEFTrk.py:75
setStyle(h, cfg)
Definition PlotEFTrk.py:236
isTProfile(obj)
Definition PlotEFTrk.py:72
draw(args, configs, tails=False, pu_comparison=False)
Definition PlotEFTrk.py:436
getPadSizes(args, NRef)
Definition PlotEFTrk.py:165