ATLAS Offline Software
PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
4 
5 """ Produce plots about egamma calibration systematics and corrections """
6 
7 import logging
8 import os
9 import time
10 from fnmatch import fnmatch
11 from functools import wraps
12 from itertools import chain, cycle, product, tee
13 
14 import colorlog
15 import matplotlib as mpl
16 mpl.use("Agg")
17 
18 import matplotlib.lines as mlines
19 import matplotlib.patches as patches
20 import matplotlib.pyplot as plt
21 import numpy as np
22 import ROOT
23 import seaborn as sns
24 import tqdm
25 from matplotlib.ticker import MaxNLocator
26 from matplotlib import rcParams
27 
28 
29 ROOT.PyConfig.IgnoreCommandLineOptions = True
30 
31 plt.rcParams["image.cmap"] = "coolwarm" # RdBu_r
32 
33 rcParams["font.family"] = "sans-serif"
34 rcParams["mathtext.fontset"] = "stixsans"
35 rcParams["mathtext.default"] = "rm"
36 rcParams["font.sans-serif"] = "helvetica, Helvetica, Nimbus Sans L, Mukti Narrow, FreeSans"
37 
38 # axes
39 rcParams["axes.labelsize"] = 20
40 rcParams["xtick.minor.visible"] = True
41 rcParams["ytick.minor.visible"] = True
42 rcParams["xtick.direction"] = "in"
43 rcParams["ytick.direction"] = "in"
44 rcParams["xtick.labelsize"] = 19
45 rcParams["xtick.major.size"] = 12
46 rcParams["xtick.minor.size"] = 6
47 rcParams["ytick.labelsize"] = 19
48 rcParams["ytick.major.size"] = 14
49 rcParams["ytick.minor.size"] = 7
50 rcParams["lines.markersize"] = 8
51 rcParams["ytick.right"] = True
52 rcParams["xtick.top"] = True
53 # rcParams['lines.markeredgewidth'] = 0. # not working, it changes other stuff
54 
55 # legend
56 rcParams["legend.numpoints"] = 1
57 rcParams["legend.fontsize"] = 19
58 rcParams["legend.labelspacing"] = 0.3
59 # rcParams['legend.frameon'] = False
60 
61 extensions = "pdf", "png"
62 
63 
65  def wrapper(self, *args):
66  status = func(self, *args)
67  if not status.isSuccess():
68  raise ValueError("status is not success")
69  return status
70 
71  return wrapper
72 
73 
74 ROOT.CP.EgammaCalibrationAndSmearingTool.initialize = check_status_code(
75  ROOT.CP.EgammaCalibrationAndSmearingTool.initialize
76 )
77 
78 
79 def timed(method):
80  @wraps(method)
81  def timed(*args, **kw):
82  ts = time.time()
83  result = method(*args, **kw)
84  te = time.time()
85 
86  log.info("function %s run in %d second", method.__name__, te - ts)
87  return result
88 
89  return timed
90 
91 
92 def plot_ATLAS(fig, x, y, label="Internal", fontsize=20):
93  label = fig.text(x, y, "ATLAS", fontsize=fontsize, fontstyle="italic", fontweight="bold")
94 
95  def on_draw(event):
96  x_right = label.get_window_extent().transformed(fig.transFigure.inverted()).max[0]
97  fig.text(x_right, y, label, fontsize=fontsize)
98  fig.canvas.mpl_disconnect(cid)
99  return False
100 
101  cid = fig.canvas.mpl_connect("draw_event", on_draw)
102  fig.canvas.draw()
103 
104 
105 fout = ROOT.TFile("output_plot.root", "recreate")
106 
107 
108 def pairwise(iterable):
109  "s -> (s0,s1), (s1,s2), (s2, s3), ..."
110  a, b = tee(iterable)
111  next(b, None)
112  return zip(a, b)
113 
114 
115 def divide_square(n, horizontal=True):
116  """ divide a figure into a square number of subplots in an optimized way """
117  if horizontal:
118  x = np.ceil(np.sqrt(n))
119  y = np.floor(np.sqrt(n))
120  if (x * y) < n:
121  x += 1
122  else:
123  x = np.floor(np.sqrt(n))
124  y = np.ceil(np.sqrt(n))
125  if (x * y) < n:
126  y += 1
127  return int(x), int(y)
128 
129 
130 def histo2data(histo):
131  xs = []
132  ys = []
133  exs = []
134  eys = []
135  for ibin in range(1, histo.GetNbinsX() + 1):
136  xs.append(histo.GetBinCenter(ibin))
137  ys.append(histo.GetBinContent(ibin))
138  eys.append(histo.GetBinError(ibin))
139  exs.append(0.5 * histo.GetBinWidth(ibin))
140  return np.array(xs), np.array(exs), np.array(ys), np.array(eys)
141 
142 
143 def systematics_from_tool(tool, only_scale=True, only_resolution=False, only_up=True):
144  """ return name of the systematics """
145  _ = tool.recommendedSystematics()
146  for sys in _:
147  sys_name = sys.name()
148  if only_scale and "RESOLUTION" in sys_name:
149  continue
150  if only_resolution and "SCALE" in sys_name:
151  continue
152  if only_up and "1down" in sys_name:
153  continue
154  yield sys
155 
156 
157 def partition(x, n):
158  r = []
159  for xx in x:
160  r.append(xx)
161  if len(r) == n:
162  yield r
163  r = []
164  continue
165  if len(r) > 0:
166  yield r
167 
168 
170  store = ROOT.xAOD.TStore()
171 
172  factory = ROOT.EgammaFactory(store)
173  for eta in np.arange(-2.5, 2.5, 0.05):
174  for e in np.arange(1e3, 1000e3, 100e3):
175  photon = factory.create_photon(eta, 0.1, e, 0)
176  yield photon
177  store.clear()
178 
179 
180 def calibrate_eta_pt(tool, etas, pts, simulation=True, particle="unconverted"):
181  log.debug("creating TEvent and EgammaFactory")
182  event = ROOT.xAOD.TEvent()
183  factory = ROOT.EgammaFactory()
184  result = np.ones((len(pts), len(etas)))
185  ei = factory.create_eventinfo(simulation, 266904)
186  assert ei.eventType(ROOT.xAOD.EventInfo.IS_SIMULATION) == simulation
187  log.debug("looping")
188  for ieta, eta in enumerate(etas):
189  for ipt, pt in enumerate(pts):
190  if particle == "unconverted":
191  p = factory.create_photon(eta, 0.1, pt * np.cosh(eta), 0)
192  elif particle == "converted":
193  p = factory.create_photon(eta, 0.1, pt * np.cosh(eta), 100)
194  elif particle == "electron":
195  p = factory.create_electron(eta, 0.1, pt * np.cosh(eta))
196  else:
197  raise ValueError()
198  result[ipt, ieta] = tool.getEnergy(p, ei)
199  log.debug("deleting event")
200  del event
201  log.debug("returning result %s", result)
202  return result
203 
204 
205 def eval_sys_eta_phi(tool, etas, phis, pt, simulation, particle="unconverted"):
206  event = ROOT.xAOD.TEvent()
207  factory = ROOT.EgammaFactory()
208  result = np.ones((len(etas), len(phis)))
209  ei = factory.create_eventinfo(simulation, 100000)
210  for ieta, eta in enumerate(etas):
211  for iphi, phi in enumerate(phis):
212  if particle == "unconverted":
213  p = factory.create_photon(eta, phi, pt * np.cosh(eta), 0)
214  elif particle == "converted":
215  p = factory.create_photon(eta, phi, pt * np.cosh(eta), 100)
216  elif particle == "electron":
217  p = factory.create_electron(eta, phi, pt * np.cosh(eta))
218  else:
219  raise ValueError()
220  result[ieta, iphi] = tool.getEnergy(p, ei)
221  del event
222  return result
223 
224 
225 def eval_eta_slice(tool, etas, pts, ptype, only_material=False, only_up=True):
226  sys_set = ROOT.CP.SystematicSet()
227  tool.applySystematicVariation(sys_set)
228  nominal = calibrate_eta_pt(tool, etas, pts, particle=ptype)
229  all_syst = tool.recommendedSystematics()
230 
231  results = {}
232  for sys in all_syst:
233  sys_name = sys.name()
234  if "RESOLUTION" in sys_name:
235  continue
236  if "1down" in sys_name and only_up:
237  continue
238  if only_material:
239  if "MAT" not in sys_name:
240  continue
241  log.info("computing sys %s, %d eta samplings", sys_name, len(etas))
242  sys_set = ROOT.CP.SystematicSet()
243  sys_set.insert(sys)
244  tool.applySystematicVariation(sys_set)
245 
246  sys = calibrate_eta_pt(tool, etas, pts, particle=ptype)
247 
248  ratio = sys / nominal
249 
250  ratio = np.average(ratio - 1, axis=1) # average the supersampling
251  results[sys_name] = ratio
252  return results
253 
254 
255 def beautify_sysname(sysname):
256  d = {
257  "EG_SCALE_PEDESTAL": "Pedestal",
258  "EG_SCALE_L2GAIN": "L2 gain",
259  "EG_SCALE_L1GAIN": "L1 gain",
260  "EG_SCALE_PS": r"$\alpha_{PS}$",
261  "EG_SCALE_S12": r"$\alpha_{1/2}$",
262  "EG_SCALE_S12EXTRALASTETABINRUN2": r"$\alpha_{1/2}$ [2.4-2.5]",
263  "EG_SCALE_ZEESYST": r"$Z\to ee$ cal. (sys)",
264  "EG_SCALE_ZEESTAT": r"$Z\to ee$ cal. (stat)",
265  "PH_SCALE_LEAKAGEUNCONV": "Leakage unconverted",
266  "EG_SCALE_MATID": "ID material",
267  "EG_SCALE_MATCRYO": "Cryo material",
268  "EG_SCALE_MATPP0": "PP0 material",
269  "EG_SCALE_WTOTS1": "$w_{tots1}$ non-lin.",
270  "EG_SCALE_CONVEFFICIENCY": "Conversion efficiency",
271  "EG_SCALE_MATCALO": "Calo material",
272  "EG_SCALE_ZEE_STAT": r"$Z\to ee$ (stat)",
273  "EG_SCALE_G4": "Geant4",
274  "PH_SCALE_LEAKAGECONV": "Leakage converted",
275  "PH_SCALE_CONVRADIUS": "Conv. radius",
276  "PH_SCALE_CONVFAKERATE": "Conv. fake rate",
277  "PH_SCALE_CONVEFFICIENCY": "Conv. efficiency",
278  "EG_SCALE_LARCALIB": r"$\alpha_{1/2}$ $\mu\to e$ extrap.",
279  "EG_SCALE_E4SCINTILLATOR": "Scintillators",
280  "EG_SCALE_LARTEMPERATURE_EXTRA2016PRE": r"Temp. 2015 $\to$ 2016",
281  "EG_SCALE_LARCALIB_EXTRA2015PRE": r"$\alpha_{1/2}$ Run 1 $\to$ Run 2",
282  }
283  return d.get(sysname, sysname)
284 
285 
286 def beautify_particle(particle):
287  d = {
288  "electron": "Electrons",
289  "converted": "Converted photons",
290  "unconverted": "Unconverted photons",
291  }
292  return d.get(particle, particle).capitalize()
293 
294 
296  etabins,
297  supersampling_eta=3,
298  esmodel="es2012c",
299  decorrelation="FULL_v1",
300  ptype="unconverted",
301  pts=np.logspace(np.log10(5e3), 6, 100), # noqa: B008 (used as constant)
302  basedir="plot",
303  only_material=False,
304  beautify_sysnames=False,
305  sys_order=None,
306  superimpose_all=False,
307  skip_null_sys=False,
308  min_sys=-0.02,
309  max_sys=0.02,
310  only_up=True,
311  debug=False,
312  legend_outside=False,
313  symmetrize_labels=False,
314  log_x=False,
315  plot_qsum=False,
316  abs_sys=False,
317  atlas_label="Internal",
318 ):
319  tool = ROOT.CP.EgammaCalibrationAndSmearingTool("tool")
320  tool.setProperty("ESModel", esmodel)
321  tool.setProperty("decorrelationModel", decorrelation)
322  tool.setProperty[bool]("doSmearing", 0)
323  log.warning("setting randomRunNumber to 297730")
324  tool.setProperty[int]("randomRunNumber", 297730)
325  if debug:
326  tool.msg().setLevel(0)
327 
328  tool.initialize()
329 
330  if superimpose_all:
331  tool_all = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_all")
332  tool_all.setProperty("ESModel", esmodel)
333  tool_all.setProperty("decorrelationModel", "1NP_v1")
334  tool_all.setProperty[bool]("doSmearing", 0)
335  log.warning("setting randomRunNumber to 297730")
336  tool_all.setProperty[int]("randomRunNumber", 297730)
337  tool_all.initialize()
338 
339  # compute the eta-inclusive one, just to sort
340  log.info("compute sys inclusively, just to sort sys by importance")
341  results = eval_eta_slice(
342  tool,
343  np.linspace(-2.5, 2.5, 20),
344  np.linspace(10e3, 200e3, 10), # use this range to mimic the range in the paper
345  ptype,
346  only_material,
347  )
348  sorted_sys_name = sorted(list(results), key=lambda k: -np.max(np.abs(results[k])))
349  if skip_null_sys:
350  sorted_sys_name = [
351  sys_name for sys_name in sorted_sys_name if np.sum(results[sys_name]) != 0
352  ]
353  if sys_order is not None:
354  if sys_order == "paper_run1":
355  partitions = [
356  [
357  "EG_SCALE_PS__1up",
358  "EG_SCALE_S12__1up",
359  "EG_SCALE_LARCALIB__1up",
360  "EG_SCALE_L2GAIN__1up",
361  ],
362  [
363  "EG_SCALE_MATID__1up",
364  "EG_SCALE_MATCRYO__1up",
365  "EG_SCALE_MATCALO__1up",
366  "EG_SCALE_ZEESYST__1up",
367  ],
368  ]
369  if esmodel == "es2016PRE":
370  partitions += [
371  [
372  "EG_SCALE_PEDESTAL__1up",
373  "EG_SCALE_LARCALIB_EXTRA2015PRE__1up",
374  "EG_SCALE_LARTEMPERATURE_EXTRA2016PRE__1up",
375  "EG_SCALE_E4SCINTILLATOR__1up",
376  ]
377  ]
378  elif sys_order == "paper_run2":
379  partitions = [
380  [
381  "EG_SCALE_PS__1up",
382  "EG_SCALE_S12__1up",
383  "EG_SCALE_LARCALIB__1up",
384  "EG_SCALE_LARCALIB_EXTRA2015PRE__1up",
385  "EG_SCALE_S12EXTRALASTETABINRUN2",
386  ],
387  [
388  "EG_SCALE_MATID__1up",
389  "EG_SCALE_MATCRYO__1up",
390  "EG_SCALE_MATCALO__1up",
391  "EG_SCALE_MATPP0__1up",
392  "EG_SCALE_ZEESYST__1up",
393  ],
394  [
395  "EG_SCALE_L2GAIN__1up",
396  "EG_SCALE_WTOTS1__1up",
397  "EG_SCALE_PEDESTAL__1up",
398  "EG_SCALE_E4SCINTILLATOR__1up",
399  ],
400  [
401  "PH_SCALE_CONVEFFICIENCY__1up",
402  "PH_SCALE_CONVFAKERATE__1up",
403  "PH_SCALE_CONVRADIUS__1up",
404  "PH_SCALE_LEAKAGECONV__1up",
405  "PH_SCALE_LEAKAGEUNCONV__1up",
406  ],
407  ]
408  else:
409  raise ValueError("cannot understand sys_order = %s" % sys_order)
410  flat_list = [item for sublist in partitions for item in sublist]
411  remainers = [item for item in sorted_sys_name if item not in flat_list]
412  partitions = chain(partitions, partition(remainers, 4))
413  else:
414  partitions = partition(sorted_sys_name, 4)
415  partitions = list(partitions)
416 
417  for etamin, etamax in tqdm.tqdm(etabins):
418  log.info("plotting eta range %.2f %.2f", etamin, etamax)
419  etas = np.linspace(etamin, etamax, supersampling_eta + 2)[1:-1]
420  results = eval_eta_slice(tool, etas, pts, ptype, only_material, only_up=only_up)
421  result_values = np.array(list(results.values()))
422  qsum = np.sqrt((result_values ** 2).sum(axis=0))
423 
424  if superimpose_all:
425  results_all = eval_eta_slice(tool_all, etas, pts, ptype, only_up=False)
426 
427  for ip, p in enumerate(partitions):
428  log.info("plotting %d/%d", ip + 1, len(partitions))
429 
430  f, ax = plt.subplots()
431  if superimpose_all:
432  # max_up_down = np.max(np.abs([results_all["EG_SCALE_ALL__1down"],
433  # results_all["EG_SCALE_ALL__1up"]]), axis=0)
434  # ax.fill_between(pts / 1E3, -max_up_down * 100., max_up_down * 100,
435  # color='0.8', label='total')
436  # ax.plot(pts/1E3, np.sqrt(np.sum([r ** 2 for r in results.values()], axis=0)) * 100., 'r:')
437  if only_up:
438  if abs_sys:
439  ax.fill_between(
440  pts / 1e3,
441  0,
442  results_all["EG_SCALE_ALL__1up"] * 100,
443  color="0.8",
444  label="Total",
445  )
446  else:
447  ax.fill_between(
448  pts / 1e3,
449  -results_all["EG_SCALE_ALL__1up"] * 100.0,
450  results_all["EG_SCALE_ALL__1up"] * 100,
451  color="0.8",
452  label="Total",
453  )
454  else:
455  ax.fill_between(
456  pts / 1e3,
457  results_all["EG_SCALE_ALL__1down"] * 100.0,
458  results_all["EG_SCALE_ALL__1up"] * 100,
459  color="0.8",
460  label="Total",
461  )
462  for isys, sys_name in enumerate(p):
463  color = "C%d" % isys # TODO: fix, use cycle
464  if sys_name not in results:
465  continue # TODO: FIXME
466  r = results[sys_name]
467  r[np.isnan(r)] = 0
468  sys_label = (
469  beautify_sysname(sys_name.replace("__1up", ""))
470  if beautify_sysnames
471  else sys_name
472  )
473  if not only_up:
474  sys_label += " UP"
475  if abs_sys:
476  mask_positive = r >= 0
477  r = np.abs(r)
478  ax.plot(
479  pts[mask_positive] / 1e3,
480  r[mask_positive] * 100.0,
481  label=sys_label,
482  color=color,
483  )
484  ax.plot(pts[~mask_positive] / 1e3, r[~mask_positive] * 100.0, "--", color=color)
485  else:
486  ax.plot(pts / 1e3, r * 100.0, label=sys_label, color=color)
487 
488  if not only_up:
489  ax.set_prop_cycle(None)
490  for sys_name in p:
491  sys_name = sys_name.replace("up", "down")
492  if sys_name not in results:
493  continue # TODO: FIXME
494  r = results[sys_name]
495  r[np.isnan(r)] = 0
496  sys_label = (
497  beautify_sysname(sys_name.replace("__1down", ""))
498  if beautify_sysnames
499  else sys_name
500  )
501  sys_label += " DOWN"
502  ax.plot(pts / 1e3, r * 100.0, label=sys_label, linestyle="--")
503 
504  if plot_qsum:
505  ax.plot(pts / 1e3, qsum * 100, label="quadrature sum", linestyle=":")
506 
507  ax.set_xlabel("$E_T$ [GeV]", ha="right", x=1.0, fontsize=19)
508  if abs_sys:
509  ax.set_ylabel("Uncertainty [%]", ha="right", y=1.0, fontsize=19)
510  else:
511  ax.set_ylabel("Signed uncertainty [%]", ha="right", y=1.0, fontsize=19)
512 
513  ax.tick_params(axis="both", which="major", labelsize=17)
514 
515  ax.axis("tight")
516 
517  if max_sys is None and min_sys is None:
518  max_sys = max(2, np.max(np.abs(ax.get_ylim())))
519  min_sys = -max_sys
520 
521  ax.set_ylim(min_sys * 100, max_sys * 100)
522 
523  if legend_outside:
524  ax.legend(
525  bbox_to_anchor=(0.0, 1.0, 1, 0.2),
526  mode="expand",
527  borderaxespad=0.0,
528  loc=3,
529  frameon=True,
530  fontsize=17 if only_up else 14,
531  borderpad=1,
532  ncol=1 if only_up else 2,
533  )
534  f.subplots_adjust(top=0.65)
535  plot_ATLAS(f, 0.2, 0.58, label=atlas_label)
536  f.text(0.2, 0.2, beautify_particle(ptype), transform=ax.transAxes, fontsize=16)
537  f.text(
538  0.2,
539  0.25,
540  r"$%.2f < \eta < %.2f$" % (etamin, etamax),
541  transform=ax.transAxes,
542  fontsize=16,
543  )
544  else:
545  ax.legend(
546  loc=1,
547  frameon=False,
548  fontsize=13 if only_up else 9,
549  borderpad=1,
550  ncol=1 if only_up else 2,
551  )
552 
553  plot_ATLAS(f, 0.16, 0.80, label=atlas_label, fontsize=19)
554  f.text(0.16, 0.74, beautify_particle(ptype), transform=ax.transAxes, fontsize=16)
555  f.text(
556  0.16,
557  0.68,
558  r"$%.2f < \eta < %.2f$" % (etamin, etamax),
559  transform=ax.transAxes,
560  fontsize=16,
561  )
562 
563  if log_x:
564  ax.set_xscale("log")
565 
566  for extension in extensions:
567  f.savefig(
568  os.path.join(
569  basedir,
570  "%s_%s_%s_%.2f_%.2f_%d.%s"
571  % (ptype, esmodel, decorrelation, etamin, etamax, ip, extension),
572  ),
573  bbox_inches="tight",
574  )
575  plt.close(f)
576 
577 
578 def values2histo(name, title, x, y):
579  histo = ROOT.TH1F(name, title, len(x) - 1, x)
580  for (
581  ibin,
582  yy,
583  ) in enumerate(y, 1):
584  histo.SetBinContent(ibin, yy)
585  return histo
586 
587 
588 def plot_all_Zee_syst(etas, pt=100e3, basedir="plots"):
589 
590  tool_es2012c = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_es2012c")
591  tool_es2012c.setProperty("ESModel", "es2012c")
592  tool_es2012c.setProperty("decorrelationModel", "FULL_ETACORRELATED_v1")
593  tool_es2012c.setProperty[int]("doSmearing", 0)
594  tool_es2012c.initialize()
595 
596  tool_es2015PRE = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_es2015PRE")
597  tool_es2015PRE.setProperty("ESModel", "es2015PRE")
598  tool_es2015PRE.setProperty("decorrelationModel", "FULL_ETACORRELATED_v1")
599  tool_es2015PRE.setProperty[bool]("doSmearing", 0)
600  tool_es2015PRE.initialize()
601 
602  tool_es2015PRE_notemp = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_es2015PRE_notemp")
603  tool_es2015PRE_notemp.setProperty("ESModel", "es2015PRE")
604  tool_es2015PRE_notemp.setProperty("decorrelationModel", "FULL_ETACORRELATED_v1")
605  tool_es2015PRE_notemp.setProperty[bool]("doSmearing", 0)
606  tool_es2015PRE_notemp.setProperty[int]("use_temp_correction201215", 0)
607  tool_es2015PRE_notemp.initialize()
608 
609  tools = [tool_es2012c, tool_es2015PRE_notemp, tool_es2015PRE]
610 
611  nominal_es2012c = calibrate_eta_pt(tool_es2012c, etas, [pt], particle="electron")[0]
612  nominal_es2015PRE = calibrate_eta_pt(tool_es2015PRE, etas, [pt], particle="electron")[0]
613  nominal_es2015PRE_notemp = calibrate_eta_pt(
614  tool_es2015PRE_notemp, etas, [pt], particle="electron"
615  )[0]
616 
617  # up variations
618  sys = ROOT.CP.SystematicVariation("EG_SCALE_ZEESYST", 1)
619  sys_set = ROOT.CP.SystematicSet()
620  sys_set.insert(sys)
621 
622  for tool in tools:
623  tool.applySystematicVariation(sys_set)
624 
625  sys_up_es2012c = calibrate_eta_pt(tool_es2012c, etas, [pt], particle="electron")[0]
626  sys_up_es2015PRE = calibrate_eta_pt(tool_es2015PRE, etas, [pt], particle="electron")[0]
627  sys_up_es2015PRE_notemp = calibrate_eta_pt(
628  tool_es2015PRE_notemp, etas, [pt], particle="electron"
629  )[0]
630 
631  ratio_sys_up_es2012c = sys_up_es2012c / nominal_es2012c - 1
632  ratio_sys_up_es2015PRE = sys_up_es2015PRE / nominal_es2015PRE - 1
633  ratio_sys_up_es2015PRE_notemp = sys_up_es2015PRE_notemp / nominal_es2015PRE_notemp - 1
634 
635  # down variations
636  sys = ROOT.CP.SystematicVariation("EG_SCALE_ZEESYST", -1)
637  sys_set = ROOT.CP.SystematicSet()
638  sys_set.insert(sys)
639 
640  for tool in tools:
641  tool.applySystematicVariation(sys_set)
642 
643  sys_down_es2012c = calibrate_eta_pt(tool_es2012c, etas, [pt], particle="electron")[0]
644  sys_down_es2015PRE = calibrate_eta_pt(tool_es2015PRE, etas, [pt], particle="electron")[0]
645  sys_down_es2015PRE_notemp = calibrate_eta_pt(
646  tool_es2015PRE_notemp, etas, [pt], particle="electron"
647  )[0]
648 
649  ratio_sys_down_es2012c = sys_down_es2012c / nominal_es2012c - 1
650  ratio_sys_down_es2015PRE = sys_down_es2015PRE / nominal_es2015PRE - 1
651  ratio_sys_down_es2015PRE_notemp = sys_down_es2015PRE_notemp / nominal_es2015PRE_notemp - 1
652 
653  # up stat
654  sys = ROOT.CP.SystematicVariation("EG_SCALE_ZEESTAT", 1)
655  sys_set = ROOT.CP.SystematicSet()
656  sys_set.insert(sys)
657  tool_es2015PRE.applySystematicVariation(sys_set)
658  stat_up_es2015PRE = calibrate_eta_pt(tool_es2015PRE, etas, [pt], particle="electron")[0]
659  ratio_stat_up = stat_up_es2015PRE / nominal_es2015PRE - 1
660 
661  # down stat
662  sys = ROOT.CP.SystematicVariation("EG_SCALE_ZEESTAT", -1)
663  sys_set = ROOT.CP.SystematicSet()
664  sys_set.insert(sys)
665  tool_es2015PRE.applySystematicVariation(sys_set)
666  stat_down_es2015PRE = calibrate_eta_pt(tool_es2015PRE, etas, [pt], particle="electron")[0]
667  ratio_stat_down = stat_down_es2015PRE / nominal_es2015PRE - 1
668 
669  ratio_full_down = -np.sqrt(ratio_stat_down ** 2 + ratio_sys_down_es2015PRE ** 2)
670  ratio_full_up = np.sqrt(ratio_stat_up ** 2 + ratio_sys_up_es2015PRE ** 2)
671 
672  fig, ax = plt.subplots()
673 
674  ax.fill_between(
675  etas,
676  ratio_full_down,
677  ratio_full_up,
678  color="#d69e8f",
679  interpolate=False,
680  label=r"$\cdots\oplus$ stat = 2015PRE (stat $\oplus$ sys)",
681  alpha=0.6,
682  )
683  ax.fill_between(
684  etas,
685  ratio_sys_down_es2015PRE,
686  ratio_sys_up_es2015PRE,
687  color="#d7d790",
688  interpolate=False,
689  label=r"$\cdots\oplus$ temp = 2015PRE sys",
690  alpha=0.6,
691  )
692  ax.fill_between(
693  etas,
694  ratio_sys_down_es2015PRE_notemp,
695  ratio_sys_up_es2015PRE_notemp,
696  color="#91da95",
697  label=r"$\cdots\oplus$ 7/8 TeV diff $\oplus$ 34/68 bins diff",
698  alpha=0.6,
699  )
700  ax.fill_between(
701  etas,
702  ratio_sys_down_es2012c,
703  ratio_sys_up_es2012c,
704  color="#93dcd1",
705  interpolate=False,
706  label="2012c",
707  alpha=0.6,
708  )
709 
710  p1 = patches.Rectangle((0, 0), 1, 1, color="#d69e8f")
711  p2 = patches.Rectangle((0, 0), 1, 1, color="#d7d790")
712  p3 = patches.Rectangle((0, 0), 1, 1, color="#91da95")
713  p4 = patches.Rectangle((0, 0), 1, 1, color="#93dcd1")
714 
715  legend1 = ax.legend(
716  [p4, p3, p2, p1],
717  [
718  "2012c",
719  r"$\cdots\oplus$ 7/8 TeV diff $\oplus$ 34/68 bins diff",
720  r"$\cdots\oplus$ temp = 2015PRE sys",
721  r"$\cdots\oplus$ stat = 2015PRE (stat $\oplus$ sys)",
722  ],
723  loc="upper right",
724  numpoints=1,
725  title="errors",
726  )
727 
728  f = ROOT.TFile("~/Data6_scaledData.root")
729  histo_scale = f.Get("alpha")
730  x, ex, y, ey = histo2data(histo_scale)
731 
732  h1 = ax.errorbar(x, y, yerr=ey, xerr=ex, fmt="o", zorder=11)
733 
734  f2 = ROOT.TFile("~/uA2MeV.root")
735  histo_uA2MeV = f2.Get("histo_uA2MeV_week12")
736  x, ex, y, ey = histo2data(histo_uA2MeV)
737  (line_uA2MeV,) = ax.plot(x, y - 1, "k-", zorder=10, label="expected deviation")
738  ax.plot(-x, y - 1, "k-", zorder=10)
739 
740  ax.set_xlabel(r"$\eta$")
741  ax.set_ylim(-0.08, 0.08)
742 
743  ax.legend(
744  [h1, line_uA2MeV],
745  ["scales 13 TeV|es2015 PRE", "expected deviation"],
746  loc="lower right",
747  numpoints=1,
748  )
749  ax.add_artist(legend1)
750 
751  ax.grid()
752 
753  fig.savefig("Zee_sys.png")
754  fig.savefig("Zee_sys.svg")
755  fig.savefig("Zee_sys.pdf")
756 
757 
758 def plot_all_syst_fixed_pt(tools, names, labels, pt=100e3, ptype="unconverted", basedir="plots"):
759  for tool in tools:
760  empty_set = ROOT.CP.SystematicSet()
761  tool.applySystematicVariation(empty_set)
762  etas_histo = np.linspace(-5, 5, 101, True)
763  etas = 0.5 * (etas_histo[1:] + etas_histo[:-1])
764  nominals = [calibrate_eta_pt(tool, etas, [pt], particle=ptype)[0] for tool in tools]
765  all_syst = tools[0].recommendedSystematics()
766  for sys in all_syst:
767  sys_name = sys.name()
768  sys_set = ROOT.CP.SystematicSet()
769  sys_set.insert(sys)
770  log.info("plotting sys %s %s", sys_name, ptype)
771 
772  f, ax = plt.subplots()
773 
774  for tool, nominal, name, label in zip(tools, nominals, names, labels):
775  tool.applySystematicVariation(sys_set)
776  sys = calibrate_eta_pt(tool, etas, [pt], particle=ptype)[0]
777  ratio = sys / nominal - 1
778  ax.plot(etas, ratio * 100, label=label)
779  histo = values2histo(name + "_" + sys_name, label, etas_histo, ratio * 100)
780  fout.WriteTObject(histo)
781 
782  ax.grid()
783  ax.legend()
784  ax.set_ylabel("effect [%]")
785  ax.set_title(ptype + " " + sys_name + " at $p_{T}$ = %.2f GeV" % (pt / 1e3))
786  ax.set_xlabel(r"$\eta$")
787  for extension in extensions:
788  f.savefig(
789  os.path.join(basedir, "%s_%s_pt_%.2f.%s" % (ptype, sys_name, pt / 1e3, extension))
790  )
791  plt.close(f)
792 
793 
794 def compute_or_read_sys(tool, ptypes, eta_edges, pt_edges):
795  empty_set = ROOT.CP.SystematicSet()
796 
797  eta_edges = np.asarray(eta_edges)
798  pt_edges = np.asarray(pt_edges)
799 
800  # TODO: replace midpoints with supersampling
801  eta_midpoints = 0.5 * (eta_edges[1:] + eta_edges[:-1])
802  pt_midpoints = 0.5 * (pt_edges[1:] + pt_edges[:-1])
803 
804  log.debug("getting list of systematics")
805  all_syst = tool.recommendedSystematics()
806  log.debug("%d systematics found", len(all_syst))
807 
808  results = {ptype: {} for ptype in ptypes}
809 
810  with tqdm.tqdm(total=len(ptypes) * (len(all_syst) + 1), leave=False) as pbar:
811  for iptype, ptype in enumerate(ptypes):
812  log.debug("computing for particle=%s", ptype)
813  tool.applySystematicVariation(empty_set)
814  log.debug(
815  "computing nominal energies for eta=%s, pt=%s, particle=%s",
816  eta_midpoints,
817  pt_midpoints,
818  ptype,
819  )
820 
821  values_nominal = calibrate_eta_pt(tool, eta_midpoints, pt_midpoints, particle=ptype)
822  pbar.update(1)
823 
824  for isys, sys in enumerate(all_syst):
825  sys_name = sys.name()
826  sys_set = ROOT.CP.SystematicSet()
827  sys_set.insert(sys)
828  tool.applySystematicVariation(sys_set)
829  values_sys = calibrate_eta_pt(tool, eta_midpoints, pt_midpoints, particle=ptype)
830  ratio = values_sys / values_nominal - 1
831 
832  results[ptype][sys_name] = ratio
833  pbar.update(1)
834 
835  return results
836 
837 
838 @timed
840  esmodels=None,
841  ptypes=None,
842  decorrelation="FULL_ETACORRELATED_v1",
843  eta_edges=None,
844  pt_edges=None,
845  basedir="plots",
846  smearing=False,
847  only_up=True,
848  abs_sys=False,
849  log_x=False,
850 ):
851  esmodels = esmodels or ["es2012c"]
852  ptypes = ptypes or ["electron"]
853  if pt_edges is None:
854  pt_edges = np.linspace(0, 100, 5)
855  if eta_edges is None:
856  eta_edges = np.array([0, 0.6, 1.0, 1.37, 1.55, 1.82, 2.47])
857  pt_edges = np.asarray(pt_edges)
858  eta_edges = np.asarray(eta_edges)
859 
860  pt_midpoints = 0.5 * (pt_edges[1:] + pt_edges[:-1])
861 
862  log.info(
863  "comparing systematics for esmodels=%s, ptypes=%s, #pt-bins=%d, #eta-bins=%d",
864  (esmodels, ptypes, len(pt_edges) - 1, len(eta_edges) - 1)
865  )
866 
867  effects = {}
868  for esmodel in esmodels:
869  log.info("creating tool for %s", esmodel)
870  tool = ROOT.CP.EgammaCalibrationAndSmearingTool("tool")
871  tool.setProperty("ESModel", esmodel)
872  tool.setProperty("decorrelationModel", decorrelation)
873  tool.setProperty[int]("randomRunNumber", 297730)
874  if not smearing:
875  tool.setProperty[bool]("doSmearing", 0)
876  tool.initialize()
877 
878  log.info("computing systematics for %s", esmodel)
879 
880  sys_values = compute_or_read_sys(tool, ptypes, eta_edges, pt_edges)
881  effects[esmodel] = sys_values
882 
883  log.debug("delete tool")
884  del tool
885 
886  def sorting_function(sys):
887  return max(
888  np.abs(effects[esmodel][ptype].get(sys, np.zeros(1))).max()
889  for esmodel in esmodels
890  for ptype in ptypes
891  )
892 
893  all_sys = set()
894  for effects_esmodel in effects.values():
895  for effects_particle in effects_esmodel.values():
896  all_sys |= set(effects_particle.keys())
897 
898  if only_up:
899  all_sys = set(s for s in all_sys if "__1up" in s)
900  all_sys = set(s for s in all_sys if "RESOLUTION" not in s)
901  sorted_sys = sorted(all_sys, key=sorting_function, reverse=True)
902 
903  log.info("plot")
904  log.info("sorted sys: %s", sorted_sys)
905  colors = sns.color_palette("Set2", len(esmodels))
906  line_styles = "--", ":", "-"
907 
908  for ptype, (ieta, (eta1, eta2)) in tqdm.tqdm(
909  product(ptypes, enumerate(pairwise(eta_edges))),
910  total=len(ptypes) * (len(eta_edges) - 1),
911  desc="plotting",
912  leave=False,
913  ):
914  nsub_x, nsub_y = divide_square(len(sorted_sys))
915  fig, axs = plt.subplots(nsub_x, nsub_y, figsize=(14, 8), sharex=True)
916  if hasattr(axs, "flat"):
917  axs = axs.flat
918  else:
919  axs = [axs]
920  for ax, sys in zip(axs, sorted_sys):
921  for iesmodel, esmodel in enumerate(esmodels):
922  if sys in effects[esmodel][ptype]:
923  values = effects[esmodel][ptype][sys][:, ieta]
924  if abs_sys:
925  values = np.abs(values)
926  else:
927  values = np.zeros_like(pt_midpoints)
928  ax.plot(
929  pt_midpoints / 1e3,
930  values * 100,
931  label=esmodel,
932  ls=line_styles[iesmodel],
933  color=colors[iesmodel],
934  )
935 
936  ylimits = [0.01, 0.3, 0.7, 2.1, 5] # possible y-axis maxima
937  for ylimit in ylimits:
938  if max(np.abs(values)) * 100 < ylimit:
939  if abs_sys:
940  ax.set_ylim(0, ylimit)
941  else:
942  ax.set_ylim(-ylimit, ylimit)
943  break
944 
945  title = sys.replace("EG_SCALE_", "").replace("PH_SCALE_", "").replace("__1up", "")
946  if len(title) > 17:
947  title = title[:17] + "..."
948  ax.set_title(title, fontsize=9)
949  ax.yaxis.set_major_locator(MaxNLocator(6, prune="both"))
950  ax.xaxis.set_major_locator(MaxNLocator(4))
951  ax.tick_params(axis="both", which="major", labelsize=8)
952  ax.tick_params(axis="y", which="minor", left="off", right="off")
953 
954  if log_x:
955  ax.set_xscale("log")
956  ax.set_ylabel("")
957 
958  for ax in axs:
959  if ax.is_last_row():
960  ax.set_xlabel("$p_{T}$ [GeV]", fontsize=11)
961  if ax.is_first_col():
962  ax.set_ylabel("effect [%]", fontsize=11)
963  fig.subplots_adjust(wspace=0.4, hspace=0.27, bottom=0.15)
964 
965  handles = [
966  mlines.Line2D([], [], color=colors[i], ls=line_styles[i]) for i in range(len(esmodels))
967  ]
968  labels = esmodels
969  fig.legend(
970  handles,
971  labels,
972  ncol=len(esmodels),
973  loc="upper center",
974  bbox_to_anchor=(0.1, -0.14, 0.7, 0.2),
975  mode="expand",
976  borderaxespad=0.0,
977  )
978 
979  fig.suptitle(r"%s $|\eta|\in [%.2f, %.2f]$" % (ptype, eta1, eta2), fontsize=14)
980 
981  figname = "compare_sys_%s_eta_%.2f_%.2f_vs_pT" % (ptype, eta1, eta2)
982  log.info("saving %s", figname)
983  for extension in extensions:
984  fig.savefig(os.path.join(basedir, "%s.%s" % (figname, extension)))
985  plt.close(fig)
986 
987 
988 @timed
990  esmodel="es2012c",
991  decorrelation="FULL_v1",
992  ptype="unconverted",
993  basedir="plots",
994  eta_range=None,
995  pt_range=None,
996  log_pt=False,
997  abs_sys=False,
998  only_up=False,
999  sys_filters=None,
1000  min_value=None,
1001  max_value=None,
1002 ):
1003  """
1004  Plot a 2D map (eta, pT) of the value of the systematic in %
1005  """
1006  log.debug("creating tool")
1007  tool = ROOT.CP.EgammaCalibrationAndSmearingTool("tool")
1008  tool.setProperty("ESModel", esmodel)
1009  tool.setProperty("decorrelationModel", decorrelation)
1010  tool.setProperty[int]("doSmearing", 0)
1011  log.warning("setting randomRunNumber to 297730")
1012  tool.setProperty[int]("randomRunNumber", 297730)
1013  tool.initialize()
1014 
1015  etas = eta_range if eta_range is not None else np.arange(-3, 3, 0.1)
1016  pts = pt_range if pt_range is not None else np.logspace(4, 7, 100)
1017 
1018  nominal = calibrate_eta_pt(tool, etas, pts, particle=ptype)
1019 
1020  all_syst = tool.recommendedSystematics()
1021 
1022  nplotted = 0
1023 
1024  for sys in tqdm.tqdm(all_syst):
1025  sys_name = sys.name()
1026  if "RESOLUTION" in sys_name:
1027  log.debug("skipping %s", sys_name)
1028  continue
1029  if only_up and "1up" not in sys_name:
1030  log.debug("skipping %s", sys_name)
1031  continue
1032  if sys_filters is not None:
1033  if not any(fnmatch(sys_name, sys_filter) for sys_filter in sys_filters):
1034  log.debug("skipping %s", sys_name)
1035  continue
1036  nplotted += 1
1037  log.info("computing sys %s", sys_name)
1038 
1039  sys_set = ROOT.CP.SystematicSet()
1040  sys_set.insert(sys)
1041  tool.applySystematicVariation(sys_set)
1042 
1043  sys = calibrate_eta_pt(tool, etas, pts, particle=ptype)
1044 
1045  ratio = sys / nominal
1046  ratio[nominal == 0] = 1
1047  # TODO: check why nan
1048  ratio[np.isnan(ratio)] = 1
1049  ratio = ratio - 1
1050  vmax = max_value or np.percentile(np.abs(ratio), 95)
1051  if abs_sys:
1052  ratio = np.abs(ratio)
1053 
1054  f, ax = plt.subplots()
1055  p = ax.pcolormesh(etas, pts / 1e3, ratio * 100.0, vmin=-vmax * 100, vmax=vmax * 100)
1056  ax.set_title("%s\n%s\n%s" % (ptype, esmodel, sys_name), loc="left")
1057  ax.set_xlabel(r"$\eta$", x=1.0, ha="right")
1058  ax.set_ylabel(r"$p_T$ [GeV]", y=1.0, ha="right")
1059  if log_pt:
1060  ax.set_yscale("log")
1061  cb = f.colorbar(p)
1062  cb.ax.set_ylabel("systematic effect [%]")
1063  for extension in extensions:
1064  f.savefig(
1065  os.path.join(
1066  basedir, "%s_%s_%s_%s.%s" % (ptype, esmodel, decorrelation, sys_name, extension)
1067  )
1068  )
1069  plt.close(f)
1070 
1071  if nplotted == 0:
1072  log.warning("no systematic plotted")
1073  else:
1074  log.info("%d systematic plotted", nplotted)
1075 
1076 
1077 @timed
1079  esmodels, basedir, labels=None, etas=np.arange(-4.5, 4.5, 0.01), add_patch=False, debug=False # noqa: B008 (range used as constant)
1080 ):
1081  log.info("comparing scale factors %s", esmodels)
1082  log.warning("<mu> fixed")
1083  labels = labels or esmodels
1084  scales = {}
1085 
1086  for esmodel, label in zip(esmodels, labels):
1087  energy_with = []
1088  energy_without = []
1089 
1090  key_properties = []
1091  value_properties = []
1092  type_properties = []
1093 
1094  if type(esmodel) is not str:
1095  key_properties = esmodel[1]
1096  value_properties = esmodel[2]
1097  type_properties = esmodel[3]
1098  esmodel = esmodel[0]
1099 
1100  tool_with = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_with")
1101  tool_without = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_without")
1102 
1103  for tool in tool_with, tool_without:
1104  if debug:
1105  tool.msg().setLevel(0)
1106  tool.setProperty("ESModel", esmodel)
1107  tool.setProperty[bool]("doSmearing", 0)
1108  for k, v, t in zip(key_properties, value_properties, type_properties):
1109  tool.setProperty[t](k, v)
1110 
1111  tool_with.setProperty[bool]("doScaleCorrection", 1)
1112  tool_without.setProperty[bool]("doScaleCorrection", 0)
1113 
1114  tool_with.initialize()
1115  tool_without.initialize()
1116 
1117  event = ROOT.xAOD.TEvent() # noqa: F841
1118  factory = ROOT.EgammaFactory()
1119  log.warning("using eveninfo 266904")
1120  ei = factory.create_eventinfo(False, 266904)
1121 
1122  for eta in etas:
1123  el = factory.create_electron(eta, 0.1, 40e3)
1124  en_with = tool_with.getEnergy(el, ei)
1125  en_without = tool_without.getEnergy(el, ei)
1126  energy_with.append(en_with)
1127  energy_without.append(en_without)
1128  scales[label] = np.array(energy_without) / np.array(energy_with) - 1
1129 
1130  f, ax = plt.subplots()
1131  for k, v in scales.items():
1132  ax.plot(etas, v * 100, label=k)
1133  ax.set_xlabel(r"$\eta$", fontsize=15, x=1, ha="right")
1134  ax.set_ylabel("energy without scale factors / energy with scale factors - 1 [%]", fontsize=10)
1135  ax.grid()
1136 
1137  if add_patch:
1138  ax.add_patch(
1139  patches.Rectangle(
1140  (-2.47, -0.013 * 100 - 0.0168 * 100),
1141  +2.47 - 1.55,
1142  2 * 0.0168 * 100,
1143  alpha=0.4,
1144  label="13 TeV scales 3 bins",
1145  color="k",
1146  )
1147  )
1148  # ax.add_patch(patches.Rectangle((-1.55, 0.00419 * 100 - 0.001 * 100), +1.55 - 1.37, 2 * 0.001 * 100, alpha=0.4, color='k'))
1149  ax.add_patch(
1150  patches.Rectangle(
1151  (-1.37, -0.0121 * 100 - 0.0052 * 100),
1152  2 * +1.37,
1153  2 * 0.0052 * 100,
1154  alpha=0.4,
1155  color="k",
1156  )
1157  )
1158  ax.add_patch(
1159  patches.Rectangle(
1160  (1.55, -0.013 * 100 - 0.0168 * 100),
1161  +2.47 - 1.55,
1162  2 * 0.0168 * 100,
1163  alpha=0.4,
1164  color="k",
1165  )
1166  )
1167 
1168  ax.add_patch(
1169  patches.Rectangle(
1170  (-2.47, -0.00649344 * 100 - 0.00465043 * 100),
1171  +2.47 * 2,
1172  2 * 0.00465043 * 100,
1173  alpha=0.5,
1174  label="13 TeV scales 1 bin",
1175  color="orange",
1176  )
1177  )
1178 
1179  ax.legend()
1180 
1181  for extension in extensions:
1182  f.savefig(os.path.join(basedir, "scales.%s" % extension))
1183  plt.close(f)
1184 
1185  # ratio plot
1186  reference = labels[0]
1187  ratio = {label: scales[label] - scales[reference] for label in labels}
1188  f, ax = plt.subplots()
1189  for k, v in ratio.items():
1190  ax.plot(etas, v, label=k)
1191  ax.set_xlabel(r"$\eta$", fontsize=15, x=1, ha="right")
1192  ax.set_ylabel("scales - scales (%s)" % reference, fontsize=10)
1193  ax.grid()
1194  ax.legend()
1195  f.tight_layout()
1196 
1197  for extension in extensions:
1198  f.savefig(os.path.join(basedir, "scales_difference_%s.%s" % (reference, extension)))
1199  plt.close(f)
1200 
1201 
1202 def plot_all_cterms(esmodels, basedir, labels=None, etas=np.arange(-4.5, 4.5, 0.01)): # noqa: B008 (used as constant)
1203  labels = labels or esmodels
1204  cterms_all_models = {}
1205  for esmodel, label in zip(esmodels, labels):
1206 
1207  tool_with = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_with")
1208  tool_with.setProperty("ESModel", esmodel)
1209  tool_with.setProperty[bool]("doSmearing", 1)
1210  tool_with.initialize()
1211 
1212  tool_without = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_without")
1213  tool_without.setProperty("ESModel", esmodel)
1214  tool_without.setProperty[bool]("doSmearing", 0)
1215  tool_without.initialize()
1216 
1217  event = ROOT.xAOD.TEvent() # noqa: F841
1218  factory = ROOT.EgammaFactory()
1219  ei = factory.create_eventinfo(True, 100000)
1220 
1221  cterms = []
1222  for eta in etas:
1223  el = factory.create_electron(eta, 0.1, 40e3)
1224  en_without = tool_without.getEnergy(el, ei)
1225  ratios = np.zeros(1000)
1226  for repetition in range(1000):
1227  en_with = tool_with.getEnergy(el, ei)
1228  ratios[repetition] = en_with / en_without
1229  cterms.append(np.std(ratios))
1230  cterms_all_models[label] = cterms
1231 
1232  f, ax = plt.subplots()
1233  for k, v in cterms_all_models.items():
1234  ax.plot(etas, v, label=k)
1235  ax.set_xlabel(r"$\eta$")
1236  ax.set_ylabel("std (energy with additional cterm / energy without)")
1237 
1238  ax.add_patch(
1239  patches.Rectangle(
1240  (-2.47, 0.028 - 0.027),
1241  +2.47 - 1.55,
1242  2 * 0.027,
1243  alpha=0.4,
1244  label="13 TeV cterm 3 bins",
1245  color="k",
1246  )
1247  )
1248  ax.add_patch(
1249  patches.Rectangle((-1.37, -0.003 - 0.014), +1.37 * 2, 2 * 0.014, alpha=0.4, color="k")
1250  )
1251  ax.add_patch(
1252  patches.Rectangle((1.55, 0.028 - 0.027), +2.47 - 1.55, 2 * 0.027, alpha=0.4, color="k")
1253  )
1254  ax.set_ylim(-0.03, 0.06)
1255 
1256  ax.grid()
1257  ax.legend()
1258  for extension in extensions:
1259  f.savefig(os.path.join(basedir, "cterms.%s" % extension))
1260  plt.close(f)
1261 
1262 
1264  tool1, tool2, pt, simulation, name, basedir, title, particle="unconverted"
1265 ):
1266  etas = np.arange(-4.5, 4.5, 0.01)
1267  r1 = calibrate_eta_pt(tool1, etas, [pt], simulation, particle)
1268  r2 = calibrate_eta_pt(tool2, etas, [pt], simulation, particle)
1269  r = r1 / r2 - 1
1270  r = r[0]
1271  print(r)
1272  f, ax = plt.subplots()
1273  r = np.nan_to_num(r)
1274  ax.plot(etas, r * 100)
1275  ax.set_xlabel(r"$\eta$")
1276  ax.set_ylabel("effect [%]")
1277  ax.set_title(title)
1278  ax.axis("tight")
1279  ax.grid()
1280  for extension in extensions:
1281  f.savefig(os.path.join(basedir, name + "." + extension))
1282  plt.close(f)
1283 
1284 
1286  tool1, tool2, pt, simulation, name, basedir, title, particle="unconverted"
1287 ):
1288  etas = np.arange(-4.5, 4.5, 0.1)
1289  phis = np.arange(-np.pi, np.pi, 0.1)
1290  r1 = eval_sys_eta_phi(tool1, etas, phis, pt, simulation, particle)
1291  r2 = eval_sys_eta_phi(tool2, etas, phis, pt, simulation, particle)
1292  r = r1 / r2 - 1
1293  f, ax = plt.subplots()
1294  m = np.max(np.abs(r))
1295  p = ax.pcolormesh(phis, etas, r * 100, vmin=-m * 100, vmax=m * 100)
1296  ax.set_xlabel(r"$\phi$")
1297  ax.set_ylabel(r"$\eta$")
1298  ax.set_title(title)
1299  ax.axis("tight")
1300  cb = f.colorbar(p)
1301  cb.ax.set_ylabel("ratio to nominal [%]")
1302  for extension in extensions:
1303  f.savefig(os.path.join(basedir, name + "." + extension))
1304  plt.close(f)
1305 
1306 
1308  tool1, tool2, simulation, name, basedir, title, particle="unconverted"
1309 ):
1310  etas = np.arange(-4.5, 4.5, 0.05)
1311  pts = np.logspace(3.2, 6, 50)
1312  r1 = calibrate_eta_pt(tool1, etas, pts, simulation, particle)
1313  r2 = calibrate_eta_pt(tool2, etas, pts, simulation, particle)
1314  r = r1 / r2 - 1
1315  f, ax = plt.subplots()
1316  r = np.nan_to_num(r)
1317  m = np.max(np.abs(r))
1318  p = ax.pcolormesh(etas, pts / 1e3, r * 100, vmin=-m * 100, vmax=m * 100)
1319  ax.set_yscale("log")
1320  ax.set_ylabel("$p_T$ [GeV]")
1321  ax.set_xlabel(r"$\eta$")
1322  ax.set_title(title)
1323  ax.axis("tight")
1324 
1325  cb = f.colorbar(p)
1326  cb.ax.set_ylabel("ratio to nominal [%]")
1327  for extension in extensions:
1328  f.savefig(os.path.join(basedir, name + "." + extension))
1329  plt.close(f)
1330 
1331 
1332 def check_gain(basedir, esmodel):
1333  tool = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_%s" % esmodel)
1334  tool.setProperty("ESModel", esmodel)
1335  tool.setProperty("decorrelationModel", "FULL_ETACORRELATED_v1")
1336  tool.setProperty[bool]("doSmearing", 0)
1337  tool.initialize()
1338 
1339  tool_no_gain = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_%s" % esmodel)
1340  tool_no_gain.setProperty("ESModel", esmodel)
1341  tool_no_gain.setProperty("decorrelationModel", "FULL_ETACORRELATED_v1")
1342  tool_no_gain.setProperty[bool]("doSmearing", 0)
1343  tool_no_gain.setProperty[bool]("useGainCorrection", 0)
1344  tool_no_gain.initialize()
1345 
1346  for ptype in "electron", "unconverted", "converted":
1348  tool_no_gain,
1349  tool,
1350  simulation=False,
1351  name="gain_%s_%s" % (esmodel, ptype),
1352  basedir=basedir,
1353  particle=ptype,
1354  title="gain correction effect - %s - %s" % (esmodel, ptype),
1355  )
1356 
1358  tool_no_gain,
1359  tool,
1360  40e3,
1361  simulation=False,
1362  name="gain_%s_%s_40GeV" % (esmodel, "electron"),
1363  basedir=basedir,
1364  title="gain correction effect - %s 40 GeV electron" % esmodel,
1365  particle="electron",
1366  )
1367 
1368 
1369 def check_fast(basedir, esmodel):
1370  tool = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_%s" % esmodel)
1371  tool.setProperty("ESModel", esmodel)
1372  tool.setProperty("decorrelationModel", "FULL_ETACORRELATED_v1")
1373  tool.setProperty[bool]("doSmearing", 0)
1374  tool.initialize()
1375 
1376  tool_fast = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_%s" % esmodel)
1377  tool_fast.setProperty("ESModel", esmodel)
1378  tool_fast.setProperty("decorrelationModel", "FULL_ETACORRELATED_v1")
1379  tool_fast.setProperty[bool]("doSmearing", 0)
1380  tool_fast.setProperty[bool]("useFastSim", True)
1381  tool_fast.initialize()
1382 
1383  for ptype in "electron", "converted", "unconverted":
1385  tool_fast,
1386  tool,
1387  pt=100e3,
1388  simulation=True,
1389  name="fast_%s_%s" % (esmodel, ptype),
1390  basedir=basedir,
1391  particle=ptype,
1392  title="fast correction effect %s %s 100 GeV" % (esmodel, ptype),
1393  )
1394 
1395 
1396 def check_uniformity(basedir, esmodel):
1397  tool = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_%s" % esmodel)
1398  tool.setProperty("ESModel", esmodel)
1399  tool.setProperty("decorrelationModel", "FULL_ETACORRELATED_v1")
1400  tool.setProperty[bool]("doSmearing", 0)
1401  tool.initialize()
1402 
1403  tool_no_uniformity = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_%s" % esmodel)
1404  tool_no_uniformity.setProperty("ESModel", esmodel)
1405  tool_no_uniformity.setProperty("decorrelationModel", "FULL_ETACORRELATED_v1")
1406  tool_no_uniformity.setProperty[bool]("doSmearing", 0)
1407  tool_no_uniformity.setProperty[bool]("usePhiUniformCorrection", 0)
1408  tool_no_uniformity.initialize()
1409 
1411  tool_no_uniformity,
1412  tool,
1413  pt=100e3,
1414  simulation=False,
1415  name="uniformity_%s" % esmodel,
1416  basedir=basedir,
1417  particle="unconverted",
1418  title="uniformity correction effect - %s - unconverted 100 GeV" % esmodel,
1419  )
1420 
1421 
1422 def compare_all_syst_fixed_pt(basedir, esmodels, names=None, labels=None):
1423  names = names or esmodels
1424  labels = labels or names
1425  tools = []
1426  for esmodel in esmodels:
1427  if type(esmodel) is str:
1428  tool = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_%s" % esmodel)
1429  tool.setProperty("ESModel", esmodel)
1430  tool.setProperty("decorrelationModel", "FULL_ETACORRELATED_v1")
1431  tool.setProperty[bool]("doSmearing", 0)
1432  tool.initialize()
1433  tools.append(tool)
1434  else:
1435  tools.append(esmodel)
1436  plot_all_syst_fixed_pt(tools, names=names, labels=labels, basedir=basedir)
1437 
1438 
1439 def plot_resolution_eta_pt(basedir, tool, pts, etas, ptype, title):
1440  event = ROOT.xAOD.TEvent() # noqa: F841
1441  factory = ROOT.EgammaFactory()
1442  result = np.ones((len(pts), len(etas)))
1443  eta_centers = 0.5 * (etas[1:] + etas[:-1])
1444  pt_centers = 0.5 * (pts[1:] + pts[:-1])
1445 
1446  result = np.zeros((len(eta_centers), len(pt_centers)))
1447 
1448  for ieta, eta in enumerate(eta_centers):
1449  for ipt, pt in enumerate(pt_centers):
1450  e = pt * np.cosh(eta)
1451  if ptype == "electron":
1452  p = factory.create_electron(eta, 0.1, e)
1453  elif ptype == "converted":
1454  p = factory.create_converted_photon(eta, 0.1, e)
1455  elif ptype == "unconverted":
1456  p = factory.create_unconverted_photon(eta, 0.1, e)
1457  else:
1458  raise ValueError()
1459  res = tool.getResolution(p)
1460  result[ieta, ipt] = res
1461 
1462  fig, ax = plt.subplots()
1463  vmin, vmax = np.percentile(result, (2, 98))
1464  p = ax.pcolormesh(pts / 1e3, etas, result, vmin=vmin, vmax=vmax)
1465  ax.set_title(title)
1466  ax.axis("tight")
1467  ax.set_xlabel(r"$p_T$ [GeV]")
1468  ax.set_ylabel(r"$\eta$")
1469  ax.set_xscale("log")
1470  cb = fig.colorbar(p)
1471  cb.ax.set_ylabel("resolution")
1472  for extension in extensions:
1473  fig.savefig(os.path.join(basedir, "resolution_%s.%s" % (ptype, extension)))
1474 
1475 
1476 def plot_resolution_error(basedir, **kwargs):
1477  esmodels = kwargs["esmodels"] or (
1478  "es2012c",
1479  "es2015PRE",
1480  "es2015PRE_res_improved",
1481  "es2016PRE",
1482  "es2017",
1483  )
1484  if kwargs["eta_bins"] is not None:
1485  eta_bins = pairwise(kwargs["eta_bins"])
1486  else:
1487  eta_bins = (0, 0.4), (0.4, 0.6), (0.6, 1.37), (1.52, 1.8), (1.8, 2.37)
1488  for esmodel in esmodels:
1489  log.debug("plotting resolution error for %s", esmodel)
1490  tool = ROOT.AtlasRoot.egammaEnergyCorrectionTool()
1491  if kwargs["debug"]:
1492  tool.msg().setLevel(0)
1493  tool.setESModel(getattr(ROOT.egEnergyCorr, esmodel))
1494  tool.initialize()
1495  for particle in ("electron", "converted", "unconverted"):
1496  log.info("plotting resolution %s", particle)
1497  for eta_min, eta_max in tqdm.tqdm(eta_bins):
1499  eta_min, eta_max, particle, esmodel, basedir, tool=tool, **kwargs
1500  )
1501 
1502 
1503 def plot_resolution_error_bin(eta_min, eta_max, particle, esmodel, basedir, tool=None, **kwargs):
1504  if tool is None:
1505  tool = ROOT.AtlasRoot.egammaEnergyCorrectionTool()
1506  tool.setESModel(getattr(ROOT.egEnergyCorr, esmodel))
1507  tool.initialize()
1508 
1509  ptype = {
1510  "electron": ROOT.PATCore.ParticleType.Electron,
1511  "unconverted": ROOT.PATCore.ParticleType.UnconvertedPhoton,
1512  "converted": ROOT.PATCore.ParticleType.ConvertedPhoton,
1513  }[particle]
1514 
1515  variations_name_up = {
1516  "Zsmearing up": ROOT.egEnergyCorr.Resolution.ZSmearingUp,
1517  "sampling up": ROOT.egEnergyCorr.Resolution.SamplingTermUp,
1518  "material ID up": ROOT.egEnergyCorr.Resolution.MaterialIDUp,
1519  "material calo up": ROOT.egEnergyCorr.Resolution.MaterialCaloUp,
1520  "material gap up": ROOT.egEnergyCorr.Resolution.MaterialGapUp,
1521  "material cryo up": ROOT.egEnergyCorr.Resolution.MaterialCryoUp,
1522  "pileup up": ROOT.egEnergyCorr.Resolution.PileUpUp,
1523  "material ibl up": ROOT.egEnergyCorr.Resolution.MaterialIBLUp,
1524  "material pp0 up": ROOT.egEnergyCorr.Resolution.MaterialPP0Up,
1525  "all up": ROOT.egEnergyCorr.Resolution.AllUp,
1526  }
1527  variations_name_down = {
1528  "Zsmearing down": ROOT.egEnergyCorr.Resolution.ZSmearingDown,
1529  "sampling down": ROOT.egEnergyCorr.Resolution.SamplingTermDown,
1530  "material ID down": ROOT.egEnergyCorr.Resolution.MaterialIDDown,
1531  "material calo down": ROOT.egEnergyCorr.Resolution.MaterialCaloDown,
1532  "material gap down": ROOT.egEnergyCorr.Resolution.MaterialGapDown,
1533  "material cryo down": ROOT.egEnergyCorr.Resolution.MaterialCryoDown,
1534  "pileup down": ROOT.egEnergyCorr.Resolution.PileUpDown,
1535  "material ibl down": ROOT.egEnergyCorr.Resolution.MaterialIBLDown,
1536  "material pp0 down": ROOT.egEnergyCorr.Resolution.MaterialPP0Down,
1537  "all down": ROOT.egEnergyCorr.Resolution.AllDown,
1538  }
1539  # ^ ^
1540  all_errors = [{}, {}] # up and down
1541  # ,--,
1542 
1543  pt_range = kwargs.get("pt_bins")
1544  if pt_range is None:
1545  pt_range = np.linspace(10e3, 2000e3, 100)
1546 
1547  nsamples_eta = kwargs["super_sampling_eta"] or 5
1548  eta_range = np.linspace(eta_min, eta_max, nsamples_eta + 2)[1:-1]
1549 
1550  only_up = True
1551 
1552  for side, errors, variations_name in zip(
1553  ("up", "down"), all_errors, (variations_name_up, variations_name_down)
1554  ):
1555  if only_up and side == "down":
1556  continue
1557 
1558  for variation_name, variation_id in variations_name.items():
1559  errors_var_pt_eta = np.zeros((len(pt_range), len(eta_range)))
1560  for ipt, pt in enumerate(pt_range):
1561  for ieta, eta in enumerate(eta_range):
1562  energy = pt * np.cosh(eta)
1563  log.debug(
1564  "evaluating systematics %s in eta=%.2f pt=%.2f on resolution",
1565  (variation_name, eta, pt)
1566  )
1567  errors_var_pt_eta[ipt, ieta] = tool.getResolutionError(
1568  ROOT.PATCore.ParticleDataType.Full, energy, eta, eta, ptype, variation_id
1569  )
1570  errors[variation_name] = errors_var_pt_eta.mean(
1571  axis=1
1572  ) # average over different eta points inside the eta-bin
1573  if kwargs["abs_sys"]:
1574  errors[variation_name] = np.abs(errors[variation_name])
1575 
1576 # sorted_keys_up = sorted(
1577 # variations_name_up.keys(), key=lambda x: np.abs(all_errors[0][x].mean())
1578 # )
1579  totals = [
1580  np.sqrt(np.sum([e ** 2 for k, e in errors.items() if "all " not in k]))
1581  for errors in all_errors
1582  ]
1583 
1584  fig, ax = plt.subplots()
1585  if only_up:
1586  ax.fill_between(pt_range / 1e3, 0, all_errors[0]["all up"], color="0.8")
1587  else:
1588  ax.fill_between(
1589  pt_range / 1e3, all_errors[0]["all up"], all_errors[1]["all down"], color="0.8"
1590  )
1591  # ax.fill_between(pt_range / 1E3, totals[0], -totals[-1], color='0.8')
1592  # totals[1] *= -1
1593 
1594  colors = ["b", "g", "r", "c", "m", "y", "violet", "pink", "orange"]
1595  props = mpl.rcParams["axes.prop_cycle"] # noqa: F841
1596 
1597  for side, errors, total in zip(("up", "down"), all_errors, totals):
1598  if only_up and side == "down":
1599  continue
1600  # ax.plot(pt_range / 1E3, total, label='sum %s' % side, color='k')
1601  ax.plot(pt_range / 1e3, errors["all %s" % side], "k", label="all %s" % side)
1602  colors_iter = cycle(colors)
1603  for k in sorted(errors.keys()):
1604  if "all" in k:
1605  continue
1606  v = errors[k]
1607  linestyle = "-"
1608  if "down" in k:
1609  linestyle = "--"
1610  if "all" in k:
1611  linestyle = ":"
1612  ax.plot(pt_range / 1e3, v, linestyle, label=k, color=next(colors_iter))
1613 
1614  fig.text(0.16, 0.73, beautify_particle(particle), transform=ax.transAxes, fontsize=15)
1615  fig.text(
1616  0.16,
1617  0.67,
1618  r"$%.2f < \eta < %.2f$" % (eta_min, eta_max),
1619  transform=ax.transAxes,
1620  fontsize=15,
1621  )
1622 
1623  ax.set_title("%s" % esmodel)
1624  ax.set_ylabel("relative resolution error [%]", ha="right", y=1.0, fontsize=19)
1625  ax.set_xlabel("$E_T$ [GeV]", ha="right", x=1.0, fontsize=19)
1626  if kwargs["abs_sys"]:
1627  ax.set_ylim(0, 0.6)
1628  else:
1629  ax.set_ylim(-1.7, 1.7)
1630  ax.set_xlim(np.min(pt_range) / 1e3, np.max(pt_range) / 1e3)
1631 
1632  fig.subplots_adjust(bottom=0.35)
1633 
1634  ax.legend(
1635  loc=3,
1636  bbox_to_anchor=(0.0, -0.5, 1, 0.2),
1637  mode="expand",
1638  ncol=4,
1639  borderaxespad=0.0,
1640  fontsize=10,
1641  )
1642 
1643  plot_ATLAS(fig, 0.16, 0.8, "Internal", fontsize=19)
1644 
1645  if kwargs["grid"]:
1646  ax.grid()
1647  filename = os.path.join(
1648  basedir, "error_relresolution_%s_%s_eta%.2f-%.2f" % (esmodel, particle, eta_min, eta_max)
1649  )
1650  for ext in "png", "pdf":
1651  fig.savefig(filename + "." + ext, bbox_inches="tight")
1652  plt.close(fig)
1653 
1654 
1655 def list_systematics(esmodels, decorrelation="FULL_ETACORRELATED_v1"):
1656  if type(esmodels) is str:
1657  esmodels = [esmodels]
1658  elif esmodels is None:
1659  log.warning("no esmodel specified, using es2012c")
1660  esmodels = ["es2012c"]
1661  syslist_esmodel = {}
1662  for esmodel in esmodels:
1663  log.debug("creating tool for %s", esmodel)
1664  tool = ROOT.CP.EgammaCalibrationAndSmearingTool("tool")
1665  tool.setProperty("ESModel", esmodel)
1666  tool.setProperty("decorrelationModel", decorrelation)
1667  tool.initialize()
1668  syslist_esmodel[esmodel] = [s.name() for s in systematics_from_tool(tool, only_scale=False)]
1669 
1670  for esmodel, sys_list in syslist_esmodel.items():
1671  print("esmodel: %s %s UP variations" % (esmodel, len(sys_list)))
1672  for sysname in sys_list:
1673  print(" {:10s}".format(sysname))
1674 
1675  if len(esmodels) > 1:
1676  log.info("comparing the %s esmodels", len(esmodels))
1677  all_sys = set([item for sublist in syslist_esmodel.values() for item in sublist])
1678  print(" " * 40 + "".join(" [%d] " % i for i in range(len(esmodels))))
1679  for sysname in sorted(all_sys):
1680  cross = "".join(
1681  [
1682  " x " if sysname in syslist_esmodel[esmodel] else " "
1683  for esmodel in esmodels
1684  ]
1685  )
1686  print(("{:40s}".format(sysname) + cross))
1687  for iesmodel, esmodel in enumerate(esmodels):
1688  print("[%d] = %s" % (iesmodel, esmodel))
1689 
1690 
1691 @timed
1692 def main():
1693  from argparse import ArgumentParser, RawDescriptionHelpFormatter
1694 
1695  parser = ArgumentParser(
1696  formatter_class=RawDescriptionHelpFormatter,
1697  epilog="""
1698 to produce paper plots for systematics:
1699  python plot.py sys_eta_slices --beautify-sysnames --sys-order paper_run1 --superimpose-all --skip-null-sys --esmodels es2016PRE --min-sys-value -0.01 --max-sys-value 0.02 --symmetrize-labels --pt-bins-logspace 5E3 1E6 100
1700 
1701  # python plot.py sys_eta_slices --beautify-sysnames --sys-order paper_run1 --superimpose-all --skip-null-sys --esmodels es2016data_mc15c_summer_improved --min-sys-value -0.01 --max-sys-value 0.02 --symmetrize-labels --pt-bins-logspace 5E3 1E6 100
1702 
1703 to produce paper plot for resolution (the name of the esmodels here are the ones used by the internal class)
1704  python plot.py resolution-err --esmodels es2017 --abs-sys --pt-bins-linspace 5E3 200E3 200
1705 
1706 to compare systematics between tools vs pT:
1707  python plot.py compare_sys --particles electron converted unconverted --esmodels es2016data_mc15c_summer_improved es2016data_mc15c_summer --eta-bins 0 0.6 1.0 1.37 1.55 1.82 2.47 --pt-bins-logspace 5E3 1500E3 50 --abs-sys --log-x
1708 
1709 to plot all systematics in a 2d plot (eta, pt):
1710  python plot.py all_sys --esmodel es2016data_mc15c_summer es2012c --decorrelation=FULL_ETACORRELATED_v1 --eta-bins-linspace -2.5 2.5 50 --pt-bins-linspace 15E3 100E3 50 --particles converted unconverted --sys-filters *LARCALIB* *LARELECUNCONV*
1711 
1712 to produce scale factor correction (doScaleCorrection on/off):
1713  python plot.py scale --esmodels es2015PRE es2016data_mc15c_summer
1714 
1715 to list the systematics:
1716  python plot.py list-systematics --esmodels es2012c es2016data_mc15c_summer es2016data_mc15c_summer_improved es2017_R21_PRE
1717 """,
1718  )
1719  parser.add_argument(
1720  "action",
1721  choices=[
1722  "compare_sys",
1723  "compute_sys",
1724  "uA2MeV",
1725  "zee",
1726  "material",
1727  "scale",
1728  "cterm",
1729  "all",
1730  "gain",
1731  "uniformity",
1732  "sys_fixed_pt",
1733  "sys_eta_slices",
1734  "all_sys",
1735  "resolution",
1736  "fast",
1737  "resolution-err",
1738  "list-systematics",
1739  ],
1740  default="all",
1741  help="what to do",
1742  )
1743  parser.add_argument("--esmodels", nargs="*", help="esmodel to consider")
1744  parser.add_argument("--decorrelation", default="FULL_ETACORRELATED_v1")
1745  parser.add_argument(
1746  "--particles",
1747  nargs="*",
1748  help="the particle (electron/converted/unconverted)",
1749  default=["electron"],
1750  )
1751  parser.add_argument("--beautify-sysnames", action="store_true")
1752  parser.add_argument("--eta-bins", nargs="*", type=float, help="edges of the eta-bins")
1753  parser.add_argument(
1754  "--eta-bins-linspace", nargs=3, type=float, help="edge of the eta-bins as min max nbins"
1755  )
1756  parser.add_argument("--pt-bins", nargs="*", type=float, help="edges of the pt-bins")
1757  parser.add_argument(
1758  "--pt-bins-linspace", nargs=3, type=float, help="edge of the eta-bins as min max nbins"
1759  )
1760  parser.add_argument(
1761  "--pt-bins-logspace", nargs=3, type=float, help="edge of the eta-bins as min max nbins"
1762  )
1763  parser.add_argument(
1764  "--super-sampling-eta", type=int, default=5, help="how many point to average inside a bin"
1765  )
1766  parser.add_argument(
1767  "--sys-order",
1768  choices=["paper_run1", "paper_run2"],
1769  help="how to order systematics, options: paper_run1, paper_run2",
1770  )
1771  parser.add_argument("--debug", action="store_true")
1772  parser.add_argument(
1773  "--superimpose-all", action="store_true", help="superimpose sum of systematics"
1774  )
1775  parser.add_argument("--skip-null-sys", action="store_true", help="do not plot null systematics")
1776  parser.add_argument("--yrange", nargs=2, type=float)
1777  parser.add_argument("--add-down", action="store_true", help="plot also the down systematics")
1778  parser.add_argument(
1779  "--legend-outside", action="store_true", help="draw the legend outside the plot"
1780  )
1781  parser.add_argument("--symmetrize-labels", action="store_true")
1782  parser.add_argument(
1783  "--abs-sys", action="store_true", help="consider the abs value of the systeamatics"
1784  )
1785  parser.add_argument("--log-x", action="store_true", help="use log scale")
1786  parser.add_argument("--log-pt", action="store_true", help="use log scale for pT")
1787  parser.add_argument(
1788  "--sys-filters", nargs="*", help="list of wildcard to filter systematic names"
1789  )
1790  parser.add_argument("--min-sys-value", type=float, help="min value for the systematic axis")
1791  parser.add_argument("--max-sys-value", type=float, help="max value for the systematic axis")
1792  parser.add_argument("--grid", action="store_true", help="show grid")
1793  parser.add_argument(
1794  "--plot-qsum",
1795  action="store_true",
1796  help="plot the quadrature sum of the systematics for debug (should be equal to 1NP up)",
1797  )
1798  parser.add_argument(
1799  "--atlas-label", default="Internal", help='Internal, Preliminary, ..., use "" for papers'
1800  )
1801  args = parser.parse_args()
1802 
1803  if args.debug:
1804  log.setLevel(logging.DEBUG)
1805  log.debug("DEBUG activated")
1806 
1807  if args.eta_bins_linspace:
1808  args.eta_bins = np.linspace(
1809  args.eta_bins_linspace[0], args.eta_bins_linspace[1], int(args.eta_bins_linspace[2] + 1)
1810  )
1811  if args.pt_bins_linspace:
1812  args.pt_bins = np.linspace(
1813  args.pt_bins_linspace[0], args.pt_bins_linspace[1], int(args.pt_bins_linspace[2] + 1)
1814  )
1815  if args.pt_bins_logspace:
1816  args.pt_bins = np.logspace(
1817  np.log10(args.pt_bins_logspace[0]),
1818  np.log10(args.pt_bins_logspace[1]),
1819  int(args.pt_bins_logspace[2] + 1),
1820  )
1821 
1822  basedir = "plots"
1823  if not os.path.exists(basedir):
1824  os.makedirs(basedir)
1825 
1826  if args.action == "list-systematics":
1827  list_systematics(args.esmodels, args.decorrelation)
1828 
1829  if args.action == "compute_sys":
1830  log.info("computing systematics")
1831  for esmodel in args.esmodels or ["es2012c"]:
1832  tool = ROOT.CP.EgammaCalibrationAndSmearingTool("tool")
1833  tool.setProperty("ESModel", esmodel)
1834  tool.setProperty("decorrelationModel", "FULL_ETACORRELATED_v1")
1835  tool.setProperty[bool]("doSmearing", 0)
1836  tool.initialize()
1837  result = compute_or_read_sys(tool, ["electron"], args.eta_bins, args.pt_bins)
1838  print(result)
1839 
1840  if args.action == "compare_sys":
1841  log.info("comparing systematics")
1842  compare_sys(
1843  args.esmodels,
1844  ptypes=args.particles,
1845  decorrelation=args.decorrelation,
1846  eta_edges=args.eta_bins,
1847  pt_edges=args.pt_bins,
1848  abs_sys=args.abs_sys,
1849  log_x=args.log_x,
1850  )
1851 
1852  if args.action == "resolution-err":
1853  log.info("plotting resolution error")
1854  plot_resolution_error(basedir="plots", **vars(args))
1855 
1856  if args.action == "zee" or args.action == "all":
1857  log.info("plotting scale systematics")
1858  plot_all_Zee_syst(etas=np.arange(-2.5, 2.5, 0.01), pt=100e3, basedir="plots")
1859 
1860  if args.action == "all" or args.action == "uA2MeV":
1861  log.info("plotting uA2MeV")
1862  tool_es2015PRE_nouA2MeV = ROOT.CP.EgammaCalibrationAndSmearingTool(
1863  "tool_es2015PRE_nouA2MeV"
1864  )
1865  tool_es2015PRE_nouA2MeV.setProperty("ESModel", "es2015PRE")
1866  tool_es2015PRE_nouA2MeV.setProperty("decorrelationModel", "FULL_ETACORRELATED_v1")
1867  tool_es2015PRE_nouA2MeV.setProperty[bool]("doSmearing", 0)
1868  tool_es2015PRE_nouA2MeV.setProperty[bool]("use_uA2MeV_2015_first2weeks_correction", 0)
1869  tool_es2015PRE_nouA2MeV.initialize()
1870 
1871  tool_es2015PRE = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_es2015PRE")
1872  tool_es2015PRE.setProperty("ESModel", "es2015PRE")
1873  tool_es2015PRE.setProperty("decorrelationModel", "FULL_ETACORRELATED_v1")
1874  tool_es2015PRE.setProperty[bool]("doSmearing", 0)
1875  tool_es2015PRE.initialize()
1876 
1878  tool_es2015PRE,
1879  tool_es2015PRE_nouA2MeV,
1880  100e3,
1881  simulation=False,
1882  name="uA2MeV",
1883  basedir=basedir,
1884  title="with uA2MeV correction / without",
1885  particle="electron",
1886  )
1887 
1888  del tool_es2015PRE_nouA2MeV
1889  del tool_es2015PRE
1890 
1891  if args.action == "all" or args.action == "scale":
1892  log.info("plotting scales")
1894  esmodels=args.esmodels,
1895  labels=args.esmodels,
1896  basedir=basedir,
1897  etas=np.arange(-2.5, 2.5, 0.01),
1898  add_patch=False,
1899  debug=args.debug,
1900  )
1901  if args.action == "all" or args.action == "fast":
1902  log.info("plotting full / fast scale")
1903  check_fast(basedir, "es2015PRE")
1905  esmodels=("es2015PRE", ("es2015PRE", ("useFastSim",), (True,), (bool,))),
1906  labels=("2015PRE", "2015PRE FAST"),
1907  basedir=basedir,
1908  etas=np.arange(-2.5, 2.5, 0.01),
1909  )
1910  if args.action == "all" or args.action == "cterm":
1911  log.info("plotting smearings")
1913  esmodels=("es2012c", "es2012XX", "es2015PRE"),
1914  labels=("2012", "new", "new + temp"),
1915  basedir=basedir,
1916  etas=np.arange(-2.5, 2.5, 0.01),
1917  )
1918 
1919  if args.action == "gain" or args.action == "all":
1920  check_gain(basedir, "es2015PRE")
1921 
1922  if args.action == "uniformity" or args.action == "all":
1923  check_uniformity(basedir, "es2012c")
1924  check_uniformity(basedir, "es2015PRE")
1925 
1926  if args.action == "sys_fixed_pt" or args.action == "all":
1927  tool_es2015PRE_notemp = ROOT.CP.EgammaCalibrationAndSmearingTool("tool_es2015PRE_notemp")
1928  tool_es2015PRE_notemp.setProperty("ESModel", "es2015PRE")
1929  tool_es2015PRE_notemp.setProperty("decorrelationModel", "FULL_ETACORRELATED_v1")
1930  tool_es2015PRE_notemp.setProperty[bool]("doSmearing", 0)
1931  tool_es2015PRE_notemp.setProperty[bool]("use_temp_correction201215", 0)
1932  tool_es2015PRE_notemp.initialize()
1933 
1935  basedir,
1936  ("es2012c", tool_es2015PRE_notemp, "es2015PRE"),
1937  names=("es2012c", "es2015_no_temp", "es2015PRE"),
1938  labels=("es2012c", r"$\oplus$ 7/8 diff $\oplus$ 34/68 diff", r"$\oplus$ LAr temperature"),
1939  )
1940 
1941  if args.action == "sys_eta_slices" or args.action == "all":
1942  if not args.eta_bins:
1943  eta_bins = ((0.0, 0.6), (0.6, 1.45), (1.52, 1.7), (1.7, 1.9), (1.9, 2.5), (1.4, 1.6))
1944  log.warning("no eta-binning specified using %s", eta_bins)
1945  else:
1946  eta_bins = list(pairwise(args.eta_bins))
1947  log.info("eta-bin: %s", eta_bins)
1948  for ptype in "electron", "unconverted", "converted":
1949  log.debug("plot all sys FULL_ETACORRELATED_v1 eta slice %s", ptype)
1951  eta_bins,
1952  supersampling_eta=args.super_sampling_eta,
1953  esmodel=args.esmodels[0],
1954  decorrelation="FULL_ETACORRELATED_v1",
1955  ptype=ptype,
1956  basedir=basedir,
1957  beautify_sysnames=args.beautify_sysnames,
1958  sys_order=args.sys_order,
1959  superimpose_all=args.superimpose_all,
1960  skip_null_sys=args.skip_null_sys,
1961  max_sys=args.max_sys_value,
1962  min_sys=args.min_sys_value,
1963  debug=args.debug,
1964  only_up=not args.add_down,
1965  symmetrize_labels=args.symmetrize_labels,
1966  legend_outside=args.legend_outside,
1967  pts=args.pt_bins,
1968  log_x=args.log_x,
1969  plot_qsum=args.plot_qsum,
1970  abs_sys=args.abs_sys,
1971  atlas_label=args.atlas_label,
1972  )
1973 
1974  if args.action == "material" or args.action == "all":
1975  if not os.path.exists("material"):
1976  os.makedirs("material")
1977  etabins = ((0.0, 0.6), (0.6, 1.45), (1.52, 1.7), (1.7, 1.9), (1.9, 2.5))
1978  for ptype in "electron", "unconverted", "converted":
1980  etabins,
1981  supersampling_eta=args.super_sampling_eta,
1982  esmodel=args.esmodels[0],
1983  decorrelation="FULL_ETACORRELATED_v1",
1984  ptype=ptype,
1985  basedir="material",
1986  only_material=True,
1987  beautify_sysnames=args.beautify_sysnames,
1988  sys_order=args.sys_order,
1989  skip_null_sys=args.skip_null_sys,
1990  max_sys=args.max_sys_value,
1991  min_sys=args.min_sys_value,
1992  debug=args.debug,
1993  only_up=not args.add_down,
1994  legend_outside=args.legend_outside,
1995  symmetrize_labels=args.symmetrize_labels,
1996  log_x=args.log_x,
1997  plot_qsum=args.plot_qsum,
1998  abs_sys=args.abs_sys,
1999  atlas_label=args.atlas_label,
2000  )
2001 
2002  if args.action == "all_sys" or args.action == "all":
2003  for esmodel in args.esmodels:
2004  for ptype in args.particles:
2005  log.info("plotting sys for %s %s", ptype, esmodel)
2007  esmodel=esmodel,
2008  decorrelation=args.decorrelation,
2009  ptype=ptype,
2010  basedir=basedir,
2011  eta_range=args.eta_bins,
2012  pt_range=args.pt_bins,
2013  log_pt=args.log_pt,
2014  abs_sys=args.abs_sys,
2015  sys_filters=args.sys_filters,
2016  min_value=args.min_sys_value,
2017  max_value=args.max_sys_value,
2018  )
2019 
2020  if args.action == "resolution" or args.action == "all":
2021  tool = ROOT.CP.EgammaCalibrationAndSmearingTool("tool")
2022  tool.setProperty("ESModel", "es2015PRE")
2023  tool.initialize()
2024  pts = np.logspace(3.2, 6, 50)
2025  etas = np.linspace(-2.49, 2.49, 100)
2027  basedir, tool, pts, etas, "electron", title="resolution electron es2015PRE"
2028  )
2030  basedir, tool, pts, etas, "converted", title="resolution converted es2015PRE"
2031  )
2033  basedir, tool, pts, etas, "unconverted", title="resolution unconverted es2015PRE"
2034  )
2035 
2036 
2037 if __name__ == "__main__":
2038 
2039  class TqdmLoggingHandler(logging.Handler):
2040  def __init__(self, level=logging.NOTSET):
2041  super(self.__class__, self).__init__(level)
2042 
2043  def emit(self, record):
2044  try:
2045  msg = self.format(record)
2046  tqdm.tqdm.write(msg)
2047  self.flush()
2048  except (KeyboardInterrupt, SystemExit):
2049  raise
2050  except Exception:
2051  self.handleError(record)
2052 
2053  log = logging.getLogger(__name__)
2054  log.setLevel(logging.INFO)
2056  handler.setFormatter(
2057  colorlog.ColoredFormatter(
2058  "%(log_color)s %(name)-23s %(levelname)-7s %(message)s",
2059  log_colors={
2060  "DEBUG": "cyan",
2061  "INFO": "blue",
2062  "SUCCESS:": "green",
2063  "WARNING": "yellow",
2064  "ERROR": "red",
2065  "CRITICAL": "red,bg_white",
2066  },
2067  )
2068  )
2069  log.addHandler(handler)
2070 
2071  main()
RunTileTBRec.method
method
Definition: RunTileTBRec.py:73
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
plot.main
def main()
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:1692
plot.plot_all_cterms
def plot_all_cterms(esmodels, basedir, labels=None, etas=np.arange(-4.5, 4.5, 0.01))
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:1202
plot.compare_two_tools_eta
def compare_two_tools_eta(tool1, tool2, pt, simulation, name, basedir, title, particle="unconverted")
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:1263
runLayerRecalibration.chain
chain
Definition: runLayerRecalibration.py:175
max
#define max(a, b)
Definition: cfImp.cxx:41
vtune_athena.format
format
Definition: vtune_athena.py:14
plot.plot_all_Zee_syst
def plot_all_Zee_syst(etas, pt=100e3, basedir="plots")
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:588
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
plot.list_systematics
def list_systematics(esmodels, decorrelation="FULL_ETACORRELATED_v1")
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:1655
plot.plot_resolution_error
def plot_resolution_error(basedir, **kwargs)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:1476
plot.plot_resolution_eta_pt
def plot_resolution_eta_pt(basedir, tool, pts, etas, ptype, title)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:1439
cycle
double cycle(double a, double b)
Definition: SiHitCollectionCnv_p2.cxx:37
plot.plot_all_syst_fixed_pt
def plot_all_syst_fixed_pt(tools, names, labels, pt=100e3, ptype="unconverted", basedir="plots")
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:758
plot.calibrate_eta_pt
def calibrate_eta_pt(tool, etas, pts, simulation=True, particle="unconverted")
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:180
plot.partition
def partition(x, n)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:157
plot.TqdmLoggingHandler
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:2039
plot.compare_all_syst_fixed_pt
def compare_all_syst_fixed_pt(basedir, esmodels, names=None, labels=None)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:1422
plot.plot_ATLAS
def plot_ATLAS(fig, x, y, label="Internal", fontsize=20)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:92
plot.beautify_particle
def beautify_particle(particle)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:286
pool::DbPrintLvl::setLevel
void setLevel(MsgLevel l)
Definition: DbPrint.h:32
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
plot.histo2data
def histo2data(histo)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:130
plot.plot_all_syst_eta_pt
def plot_all_syst_eta_pt(esmodel="es2012c", decorrelation="FULL_v1", ptype="unconverted", basedir="plots", eta_range=None, pt_range=None, log_pt=False, abs_sys=False, only_up=False, sys_filters=None, min_value=None, max_value=None)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:989
plot.compute_or_read_sys
def compute_or_read_sys(tool, ptypes, eta_edges, pt_edges)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:794
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
plot.plot_all_syst_eta_slice
def plot_all_syst_eta_slice(etabins, supersampling_eta=3, esmodel="es2012c", decorrelation="FULL_v1", ptype="unconverted", pts=np.logspace(np.log10(5e3), 6, 100), basedir="plot", only_material=False, beautify_sysnames=False, sys_order=None, superimpose_all=False, skip_null_sys=False, min_sys=-0.02, max_sys=0.02, only_up=True, debug=False, legend_outside=False, symmetrize_labels=False, log_x=False, plot_qsum=False, abs_sys=False, atlas_label="Internal")
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:295
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:224
plot.check_uniformity
def check_uniformity(basedir, esmodel)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:1396
plot.compare_two_tools_eta_pt
def compare_two_tools_eta_pt(tool1, tool2, simulation, name, basedir, title, particle="unconverted")
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:1307
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
plot.systematics_from_tool
def systematics_from_tool(tool, only_scale=True, only_resolution=False, only_up=True)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:143
plot.plot_resolution_error_bin
def plot_resolution_error_bin(eta_min, eta_max, particle, esmodel, basedir, tool=None, **kwargs)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:1503
plot.TqdmLoggingHandler.emit
def emit(self, record)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:2043
plot.check_status_code
def check_status_code(func)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:64
plot.eval_sys_eta_phi
def eval_sys_eta_phi(tool, etas, phis, pt, simulation, particle="unconverted")
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:205
plot.divide_square
def divide_square(n, horizontal=True)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:115
plot.compare_two_tools_eta_phi
def compare_two_tools_eta_phi(tool1, tool2, pt, simulation, name, basedir, title, particle="unconverted")
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:1285
plot.TqdmLoggingHandler.__init__
def __init__(self, level=logging.NOTSET)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:2040
plot.values2histo
def values2histo(name, title, x, y)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:578
plot.check_gain
def check_gain(basedir, esmodel)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:1332
plot.eval_eta_slice
def eval_eta_slice(tool, etas, pts, ptype, only_material=False, only_up=True)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:225
plot.compare_sys
def compare_sys(esmodels=None, ptypes=None, decorrelation="FULL_ETACORRELATED_v1", eta_edges=None, pt_edges=None, basedir="plots", smearing=False, only_up=True, abs_sys=False, log_x=False)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:839
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127
plot.beautify_sysname
def beautify_sysname(sysname)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:255
plot.timed
def timed(method)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:79
plot.plot_all_scales
def plot_all_scales(esmodels, basedir, labels=None, etas=np.arange(-4.5, 4.5, 0.01), add_patch=False, debug=False # noqa:B008(range used as constant))
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:1078
plot.pairwise
def pairwise(iterable)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:108
plot.check_fast
def check_fast(basedir, esmodel)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:1369
plot.generator_photon
def generator_photon(self)
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:169