5 """ Produce plots about egamma calibration systematics and corrections """
10 from fnmatch
import fnmatch
11 from functools
import wraps
12 from itertools
import chain, cycle, product, tee
15 import matplotlib
as mpl
18 import matplotlib.lines
as mlines
19 import matplotlib.patches
as patches
20 import matplotlib.pyplot
as plt
25 from matplotlib.ticker
import MaxNLocator
26 from matplotlib
import rcParams
29 ROOT.PyConfig.IgnoreCommandLineOptions =
True
31 plt.rcParams[
"image.cmap"] =
"coolwarm"
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"
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
56 rcParams[
"legend.numpoints"] = 1
57 rcParams[
"legend.fontsize"] = 19
58 rcParams[
"legend.labelspacing"] = 0.3
61 extensions =
"pdf",
"png"
65 def wrapper(self, *args):
66 status = func(self, *args)
67 if not status.isSuccess():
68 raise ValueError(
"status is not success")
75 ROOT.CP.EgammaCalibrationAndSmearingTool.initialize
81 def timed(*args, **kw):
83 result =
method(*args, **kw)
86 log.info(
"function %s run in %d second", method.__name__, te - ts)
92 def plot_ATLAS(fig, x, y, label="Internal", fontsize=20):
93 label = fig.text(x, y,
"ATLAS", fontsize=fontsize, fontstyle=
"italic", fontweight=
"bold")
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)
101 cid = fig.canvas.mpl_connect(
"draw_event", on_draw)
105 fout = ROOT.TFile(
"output_plot.root",
"recreate")
109 "s -> (s0,s1), (s1,s2), (s2, s3), ..."
116 """ divide a figure into a square number of subplots in an optimized way """
118 x = np.ceil(np.sqrt(n))
119 y = np.floor(np.sqrt(n))
123 x = np.floor(np.sqrt(n))
124 y = np.ceil(np.sqrt(n))
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)
144 """ return name of the systematics """
145 _ = tool.recommendedSystematics()
147 sys_name = sys.name()
148 if only_scale
and "RESOLUTION" in sys_name:
150 if only_resolution
and "SCALE" in sys_name:
152 if only_up
and "1down" in sys_name:
170 store = ROOT.xAOD.TStore()
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)
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
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))
198 result[ipt, ieta] = tool.getEnergy(p, ei)
199 log.debug(
"deleting event")
201 log.debug(
"returning result %s", result)
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))
220 result[ieta, iphi] = tool.getEnergy(p, ei)
226 sys_set = ROOT.CP.SystematicSet()
227 tool.applySystematicVariation(sys_set)
229 all_syst = tool.recommendedSystematics()
233 sys_name = sys.name()
234 if "RESOLUTION" in sys_name:
236 if "1down" in sys_name
and only_up:
239 if "MAT" not in sys_name:
241 log.info(
"computing sys %s, %d eta samplings", sys_name, len(etas))
242 sys_set = ROOT.CP.SystematicSet()
244 tool.applySystematicVariation(sys_set)
248 ratio = sys / nominal
250 ratio = np.average(ratio - 1, axis=1)
251 results[sys_name] = ratio
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",
283 return d.get(sysname, sysname)
288 "electron":
"Electrons",
289 "converted":
"Converted photons",
290 "unconverted":
"Unconverted photons",
292 return d.get(particle, particle).capitalize()
299 decorrelation="FULL_v1",
301 pts=np.logspace(np.log10(5e3), 6, 100),
304 beautify_sysnames=
False,
306 superimpose_all=
False,
312 legend_outside=
False,
313 symmetrize_labels=
False,
317 atlas_label=
"Internal",
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)
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()
340 log.info(
"compute sys inclusively, just to sort sys by importance")
343 np.linspace(-2.5, 2.5, 20),
344 np.linspace(10e3, 200e3, 10),
348 sorted_sys_name =
sorted(
list(results), key=
lambda k: -np.max(np.abs(results[k])))
351 sys_name
for sys_name
in sorted_sys_name
if np.sum(results[sys_name]) != 0
353 if sys_order
is not None:
354 if sys_order ==
"paper_run1":
359 "EG_SCALE_LARCALIB__1up",
360 "EG_SCALE_L2GAIN__1up",
363 "EG_SCALE_MATID__1up",
364 "EG_SCALE_MATCRYO__1up",
365 "EG_SCALE_MATCALO__1up",
366 "EG_SCALE_ZEESYST__1up",
369 if esmodel ==
"es2016PRE":
372 "EG_SCALE_PEDESTAL__1up",
373 "EG_SCALE_LARCALIB_EXTRA2015PRE__1up",
374 "EG_SCALE_LARTEMPERATURE_EXTRA2016PRE__1up",
375 "EG_SCALE_E4SCINTILLATOR__1up",
378 elif sys_order ==
"paper_run2":
383 "EG_SCALE_LARCALIB__1up",
384 "EG_SCALE_LARCALIB_EXTRA2015PRE__1up",
385 "EG_SCALE_S12EXTRALASTETABINRUN2",
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",
395 "EG_SCALE_L2GAIN__1up",
396 "EG_SCALE_WTOTS1__1up",
397 "EG_SCALE_PEDESTAL__1up",
398 "EG_SCALE_E4SCINTILLATOR__1up",
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",
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]
414 partitions =
partition(sorted_sys_name, 4)
415 partitions =
list(partitions)
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))
425 results_all =
eval_eta_slice(tool_all, etas, pts, ptype, only_up=
False)
427 for ip, p
in enumerate(partitions):
428 log.info(
"plotting %d/%d", ip + 1, len(partitions))
430 f, ax = plt.subplots()
442 results_all[
"EG_SCALE_ALL__1up"] * 100,
449 -results_all[
"EG_SCALE_ALL__1up"] * 100.0,
450 results_all[
"EG_SCALE_ALL__1up"] * 100,
457 results_all[
"EG_SCALE_ALL__1down"] * 100.0,
458 results_all[
"EG_SCALE_ALL__1up"] * 100,
462 for isys, sys_name
in enumerate(p):
464 if sys_name
not in results:
466 r = results[sys_name]
476 mask_positive = r >= 0
479 pts[mask_positive] / 1e3,
480 r[mask_positive] * 100.0,
484 ax.plot(pts[~mask_positive] / 1e3, r[~mask_positive] * 100.0,
"--", color=color)
486 ax.plot(pts / 1e3, r * 100.0, label=sys_label, color=color)
489 ax.set_prop_cycle(
None)
491 sys_name = sys_name.replace(
"up",
"down")
492 if sys_name
not in results:
494 r = results[sys_name]
502 ax.plot(pts / 1e3, r * 100.0, label=sys_label, linestyle=
"--")
505 ax.plot(pts / 1e3, qsum * 100, label=
"quadrature sum", linestyle=
":")
507 ax.set_xlabel(
"$E_T$ [GeV]", ha=
"right", x=1.0, fontsize=19)
509 ax.set_ylabel(
"Uncertainty [%]", ha=
"right", y=1.0, fontsize=19)
511 ax.set_ylabel(
"Signed uncertainty [%]", ha=
"right", y=1.0, fontsize=19)
513 ax.tick_params(axis=
"both", which=
"major", labelsize=17)
517 if max_sys
is None and min_sys
is None:
518 max_sys =
max(2, np.max(np.abs(ax.get_ylim())))
521 ax.set_ylim(min_sys * 100, max_sys * 100)
525 bbox_to_anchor=(0.0, 1.0, 1, 0.2),
530 fontsize=17
if only_up
else 14,
532 ncol=1
if only_up
else 2,
534 f.subplots_adjust(top=0.65)
540 r"$%.2f < \eta < %.2f$" % (etamin, etamax),
541 transform=ax.transAxes,
548 fontsize=13
if only_up
else 9,
550 ncol=1
if only_up
else 2,
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)
558 r"$%.2f < \eta < %.2f$" % (etamin, etamax),
559 transform=ax.transAxes,
566 for extension
in extensions:
570 "%s_%s_%s_%.2f_%.2f_%d.%s"
571 % (ptype, esmodel, decorrelation, etamin, etamax, ip, extension),
579 histo = ROOT.TH1F(name, title, len(x) - 1, x)
583 )
in enumerate(y, 1):
584 histo.SetBinContent(ibin, yy)
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()
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()
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()
609 tools = [tool_es2012c, tool_es2015PRE_notemp, tool_es2015PRE]
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]
614 tool_es2015PRE_notemp, etas, [pt], particle=
"electron"
618 sys = ROOT.CP.SystematicVariation(
"EG_SCALE_ZEESYST", 1)
619 sys_set = ROOT.CP.SystematicSet()
623 tool.applySystematicVariation(sys_set)
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]
628 tool_es2015PRE_notemp, etas, [pt], particle=
"electron"
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
636 sys = ROOT.CP.SystematicVariation(
"EG_SCALE_ZEESYST", -1)
637 sys_set = ROOT.CP.SystematicSet()
641 tool.applySystematicVariation(sys_set)
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]
646 tool_es2015PRE_notemp, etas, [pt], particle=
"electron"
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
654 sys = ROOT.CP.SystematicVariation(
"EG_SCALE_ZEESTAT", 1)
655 sys_set = ROOT.CP.SystematicSet()
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
662 sys = ROOT.CP.SystematicVariation(
"EG_SCALE_ZEESTAT", -1)
663 sys_set = ROOT.CP.SystematicSet()
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
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)
672 fig, ax = plt.subplots()
680 label=
r"$\cdots\oplus$ stat = 2015PRE (stat $\oplus$ sys)",
685 ratio_sys_down_es2015PRE,
686 ratio_sys_up_es2015PRE,
689 label=
r"$\cdots\oplus$ temp = 2015PRE sys",
694 ratio_sys_down_es2015PRE_notemp,
695 ratio_sys_up_es2015PRE_notemp,
697 label=
r"$\cdots\oplus$ 7/8 TeV diff $\oplus$ 34/68 bins diff",
702 ratio_sys_down_es2012c,
703 ratio_sys_up_es2012c,
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")
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)",
728 f = ROOT.TFile(
"~/Data6_scaledData.root")
729 histo_scale = f.Get(
"alpha")
732 h1 = ax.errorbar(x, y, yerr=ey, xerr=ex, fmt=
"o", zorder=11)
734 f2 = ROOT.TFile(
"~/uA2MeV.root")
735 histo_uA2MeV = f2.Get(
"histo_uA2MeV_week12")
737 (line_uA2MeV,) = ax.plot(x, y - 1,
"k-", zorder=10, label=
"expected deviation")
738 ax.plot(-x, y - 1,
"k-", zorder=10)
740 ax.set_xlabel(
r"$\eta$")
741 ax.set_ylim(-0.08, 0.08)
745 [
"scales 13 TeV|es2015 PRE",
"expected deviation"],
749 ax.add_artist(legend1)
753 fig.savefig(
"Zee_sys.png")
754 fig.savefig(
"Zee_sys.svg")
755 fig.savefig(
"Zee_sys.pdf")
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()
767 sys_name = sys.name()
768 sys_set = ROOT.CP.SystematicSet()
770 log.info(
"plotting sys %s %s", sys_name, ptype)
772 f, ax = plt.subplots()
774 for tool, nominal, name, label
in zip(tools, nominals, names, labels):
775 tool.applySystematicVariation(sys_set)
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)
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:
789 os.path.join(basedir,
"%s_%s_pt_%.2f.%s" % (ptype, sys_name, pt / 1e3, extension))
795 empty_set = ROOT.CP.SystematicSet()
797 eta_edges = np.asarray(eta_edges)
798 pt_edges = np.asarray(pt_edges)
801 eta_midpoints = 0.5 * (eta_edges[1:] + eta_edges[:-1])
802 pt_midpoints = 0.5 * (pt_edges[1:] + pt_edges[:-1])
804 log.debug(
"getting list of systematics")
805 all_syst = tool.recommendedSystematics()
806 log.debug(
"%d systematics found", len(all_syst))
808 results = {ptype: {}
for ptype
in ptypes}
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)
815 "computing nominal energies for eta=%s, pt=%s, particle=%s",
821 values_nominal =
calibrate_eta_pt(tool, eta_midpoints, pt_midpoints, particle=ptype)
824 for isys, sys
in enumerate(all_syst):
825 sys_name = sys.name()
826 sys_set = ROOT.CP.SystematicSet()
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
832 results[ptype][sys_name] = ratio
842 decorrelation="FULL_ETACORRELATED_v1",
851 esmodels = esmodels
or [
"es2012c"]
852 ptypes = ptypes
or [
"electron"]
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)
860 pt_midpoints = 0.5 * (pt_edges[1:] + pt_edges[:-1])
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)
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)
875 tool.setProperty[bool](
"doSmearing", 0)
878 log.info(
"computing systematics for %s", esmodel)
881 effects[esmodel] = sys_values
883 log.debug(
"delete tool")
886 def sorting_function(sys):
888 np.abs(effects[esmodel][ptype].
get(sys, np.zeros(1))).
max()
889 for esmodel
in esmodels
894 for effects_esmodel
in effects.values():
895 for effects_particle
in effects_esmodel.values():
896 all_sys |=
set(effects_particle.keys())
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)
904 log.info(
"sorted sys: %s", sorted_sys)
905 colors = sns.color_palette(
"Set2", len(esmodels))
906 line_styles =
"--",
":",
"-"
908 for ptype, (ieta, (eta1, eta2))
in tqdm.tqdm(
909 product(ptypes, enumerate(
pairwise(eta_edges))),
910 total=len(ptypes) * (len(eta_edges) - 1),
915 fig, axs = plt.subplots(nsub_x, nsub_y, figsize=(14, 8), sharex=
True)
916 if hasattr(axs,
"flat"):
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]
925 values = np.abs(values)
927 values = np.zeros_like(pt_midpoints)
932 ls=line_styles[iesmodel],
933 color=colors[iesmodel],
936 ylimits = [0.01, 0.3, 0.7, 2.1, 5]
937 for ylimit
in ylimits:
938 if max(np.abs(values)) * 100 < ylimit:
940 ax.set_ylim(0, ylimit)
942 ax.set_ylim(-ylimit, ylimit)
945 title = sys.replace(
"EG_SCALE_",
"").
replace(
"PH_SCALE_",
"").
replace(
"__1up",
"")
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")
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)
966 mlines.Line2D([], [], color=colors[i], ls=line_styles[i])
for i
in range(len(esmodels))
974 bbox_to_anchor=(0.1, -0.14, 0.7, 0.2),
979 fig.suptitle(
r"%s $|\eta|\in [%.2f, %.2f]$" % (ptype, eta1, eta2), fontsize=14)
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)))
991 decorrelation="FULL_v1",
1004 Plot a 2D map (eta, pT) of the value of the systematic in %
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)
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)
1020 all_syst = tool.recommendedSystematics()
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)
1029 if only_up
and "1up" not in sys_name:
1030 log.debug(
"skipping %s", sys_name)
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)
1037 log.info(
"computing sys %s", sys_name)
1039 sys_set = ROOT.CP.SystematicSet()
1041 tool.applySystematicVariation(sys_set)
1045 ratio = sys / nominal
1046 ratio[nominal == 0] = 1
1048 ratio[np.isnan(ratio)] = 1
1050 vmax = max_value
or np.percentile(np.abs(ratio), 95)
1052 ratio = np.abs(ratio)
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")
1060 ax.set_yscale(
"log")
1062 cb.ax.set_ylabel(
"systematic effect [%]")
1063 for extension
in extensions:
1066 basedir,
"%s_%s_%s_%s.%s" % (ptype, esmodel, decorrelation, sys_name, extension)
1072 log.warning(
"no systematic plotted")
1074 log.info(
"%d systematic plotted", nplotted)
1079 esmodels, basedir, labels=None, etas=np.arange(-4.5, 4.5, 0.01), add_patch=
False, debug=
False
1081 log.info(
"comparing scale factors %s", esmodels)
1082 log.warning(
"<mu> fixed")
1083 labels = labels
or esmodels
1086 for esmodel, label
in zip(esmodels, labels):
1091 value_properties = []
1092 type_properties = []
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]
1100 tool_with = ROOT.CP.EgammaCalibrationAndSmearingTool(
"tool_with")
1101 tool_without = ROOT.CP.EgammaCalibrationAndSmearingTool(
"tool_without")
1103 for tool
in tool_with, tool_without:
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)
1111 tool_with.setProperty[bool](
"doScaleCorrection", 1)
1112 tool_without.setProperty[bool](
"doScaleCorrection", 0)
1114 tool_with.initialize()
1115 tool_without.initialize()
1117 event = ROOT.xAOD.TEvent()
1118 factory = ROOT.EgammaFactory()
1119 log.warning(
"using eveninfo 266904")
1120 ei = factory.create_eventinfo(
False, 266904)
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
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)
1140 (-2.47, -0.013 * 100 - 0.0168 * 100),
1144 label=
"13 TeV scales 3 bins",
1151 (-1.37, -0.0121 * 100 - 0.0052 * 100),
1160 (1.55, -0.013 * 100 - 0.0168 * 100),
1170 (-2.47, -0.00649344 * 100 - 0.00465043 * 100),
1172 2 * 0.00465043 * 100,
1174 label=
"13 TeV scales 1 bin",
1181 for extension
in extensions:
1182 f.savefig(os.path.join(basedir,
"scales.%s" % extension))
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)
1197 for extension
in extensions:
1198 f.savefig(os.path.join(basedir,
"scales_difference_%s.%s" % (reference, extension)))
1203 labels = labels
or esmodels
1204 cterms_all_models = {}
1205 for esmodel, label
in zip(esmodels, labels):
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()
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()
1217 event = ROOT.xAOD.TEvent()
1218 factory = ROOT.EgammaFactory()
1219 ei = factory.create_eventinfo(
True, 100000)
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
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)")
1240 (-2.47, 0.028 - 0.027),
1244 label=
"13 TeV cterm 3 bins",
1249 patches.Rectangle((-1.37, -0.003 - 0.014), +1.37 * 2, 2 * 0.014, alpha=0.4, color=
"k")
1252 patches.Rectangle((1.55, 0.028 - 0.027), +2.47 - 1.55, 2 * 0.027, alpha=0.4, color=
"k")
1254 ax.set_ylim(-0.03, 0.06)
1258 for extension
in extensions:
1259 f.savefig(os.path.join(basedir,
"cterms.%s" % extension))
1264 tool1, tool2, pt, simulation, name, basedir, title, particle="unconverted"
1266 etas = np.arange(-4.5, 4.5, 0.01)
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 [%]")
1280 for extension
in extensions:
1281 f.savefig(os.path.join(basedir, name +
"." + extension))
1286 tool1, tool2, pt, simulation, name, basedir, title, particle="unconverted"
1288 etas = np.arange(-4.5, 4.5, 0.1)
1289 phis = np.arange(-np.pi, np.pi, 0.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$")
1301 cb.ax.set_ylabel(
"ratio to nominal [%]")
1302 for extension
in extensions:
1303 f.savefig(os.path.join(basedir, name +
"." + extension))
1308 tool1, tool2, simulation, name, basedir, title, particle="unconverted"
1310 etas = np.arange(-4.5, 4.5, 0.05)
1311 pts = np.logspace(3.2, 6, 50)
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$")
1326 cb.ax.set_ylabel(
"ratio to nominal [%]")
1327 for extension
in extensions:
1328 f.savefig(os.path.join(basedir, name +
"." + extension))
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)
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()
1346 for ptype
in "electron",
"unconverted",
"converted":
1351 name=
"gain_%s_%s" % (esmodel, ptype),
1354 title=
"gain correction effect - %s - %s" % (esmodel, ptype),
1362 name=
"gain_%s_%s_40GeV" % (esmodel,
"electron"),
1364 title=
"gain correction effect - %s 40 GeV electron" % esmodel,
1365 particle=
"electron",
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)
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()
1383 for ptype
in "electron",
"converted",
"unconverted":
1389 name=
"fast_%s_%s" % (esmodel, ptype),
1392 title=
"fast correction effect %s %s 100 GeV" % (esmodel, ptype),
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)
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()
1415 name=
"uniformity_%s" % esmodel,
1417 particle=
"unconverted",
1418 title=
"uniformity correction effect - %s - unconverted 100 GeV" % esmodel,
1423 names = names
or esmodels
1424 labels = labels
or names
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)
1435 tools.append(esmodel)
1440 event = ROOT.xAOD.TEvent()
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])
1446 result = np.zeros((len(eta_centers), len(pt_centers)))
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)
1459 res = tool.getResolution(p)
1460 result[ieta, ipt] = res
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)
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)))
1477 esmodels = kwargs[
"esmodels"]
or (
1480 "es2015PRE_res_improved",
1484 if kwargs[
"eta_bins"]
is not None:
1485 eta_bins =
pairwise(kwargs[
"eta_bins"])
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()
1493 tool.setESModel(getattr(ROOT.egEnergyCorr, esmodel))
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
1505 tool = ROOT.AtlasRoot.egammaEnergyCorrectionTool()
1506 tool.setESModel(getattr(ROOT.egEnergyCorr, esmodel))
1510 "electron": ROOT.PATCore.ParticleType.Electron,
1511 "unconverted": ROOT.PATCore.ParticleType.UnconvertedPhoton,
1512 "converted": ROOT.PATCore.ParticleType.ConvertedPhoton,
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,
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,
1540 all_errors = [{}, {}]
1543 pt_range = kwargs.get(
"pt_bins")
1544 if pt_range
is None:
1545 pt_range = np.linspace(10e3, 2000e3, 100)
1547 nsamples_eta = kwargs[
"super_sampling_eta"]
or 5
1548 eta_range = np.linspace(eta_min, eta_max, nsamples_eta + 2)[1:-1]
1552 for side, errors, variations_name
in zip(
1553 (
"up",
"down"), all_errors, (variations_name_up, variations_name_down)
1555 if only_up
and side ==
"down":
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)
1564 "evaluating systematics %s in eta=%.2f pt=%.2f on resolution",
1565 (variation_name, eta, pt)
1567 errors_var_pt_eta[ipt, ieta] = tool.getResolutionError(
1568 ROOT.PATCore.ParticleDataType.Full, energy, eta, eta, ptype, variation_id
1570 errors[variation_name] = errors_var_pt_eta.mean(
1573 if kwargs[
"abs_sys"]:
1574 errors[variation_name] = np.abs(errors[variation_name])
1580 np.sqrt(np.sum([e ** 2
for k, e
in errors.items()
if "all " not in k]))
1581 for errors
in all_errors
1584 fig, ax = plt.subplots()
1586 ax.fill_between(pt_range / 1e3, 0, all_errors[0][
"all up"], color=
"0.8")
1589 pt_range / 1e3, all_errors[0][
"all up"], all_errors[1][
"all down"], color=
"0.8"
1594 colors = [
"b",
"g",
"r",
"c",
"m",
"y",
"violet",
"pink",
"orange"]
1595 props = mpl.rcParams[
"axes.prop_cycle"]
1597 for side, errors, total
in zip((
"up",
"down"), all_errors, totals):
1598 if only_up
and side ==
"down":
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()):
1612 ax.plot(pt_range / 1e3, v, linestyle, label=k, color=
next(colors_iter))
1614 fig.text(0.16, 0.73,
beautify_particle(particle), transform=ax.transAxes, fontsize=15)
1618 r"$%.2f < \eta < %.2f$" % (eta_min, eta_max),
1619 transform=ax.transAxes,
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"]:
1629 ax.set_ylim(-1.7, 1.7)
1630 ax.set_xlim(np.min(pt_range) / 1e3, np.max(pt_range) / 1e3)
1632 fig.subplots_adjust(bottom=0.35)
1636 bbox_to_anchor=(0.0, -0.5, 1, 0.2),
1643 plot_ATLAS(fig, 0.16, 0.8,
"Internal", fontsize=19)
1647 filename = os.path.join(
1648 basedir,
"error_relresolution_%s_%s_eta%.2f-%.2f" % (esmodel, particle, eta_min, eta_max)
1650 for ext
in "png",
"pdf":
1651 fig.savefig(filename +
"." + ext, bbox_inches=
"tight")
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)
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:
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):
1682 " x " if sysname
in syslist_esmodel[esmodel]
else " "
1683 for esmodel
in esmodels
1687 for iesmodel, esmodel
in enumerate(esmodels):
1688 print(
"[%d] = %s" % (iesmodel, esmodel))
1693 from argparse
import ArgumentParser, RawDescriptionHelpFormatter
1695 parser = ArgumentParser(
1696 formatter_class=RawDescriptionHelpFormatter,
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
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
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
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
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*
1712 to produce scale factor correction (doScaleCorrection on/off):
1713 python plot.py scale --esmodels es2015PRE es2016data_mc15c_summer
1715 to list the systematics:
1716 python plot.py list-systematics --esmodels es2012c es2016data_mc15c_summer es2016data_mc15c_summer_improved es2017_R21_PRE
1719 parser.add_argument(
1743 parser.add_argument(
"--esmodels", nargs=
"*", help=
"esmodel to consider")
1744 parser.add_argument(
"--decorrelation", default=
"FULL_ETACORRELATED_v1")
1745 parser.add_argument(
1748 help=
"the particle (electron/converted/unconverted)",
1749 default=[
"electron"],
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"
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"
1760 parser.add_argument(
1761 "--pt-bins-logspace", nargs=3, type=float, help=
"edge of the eta-bins as min max nbins"
1763 parser.add_argument(
1764 "--super-sampling-eta", type=int, default=5, help=
"how many point to average inside a bin"
1766 parser.add_argument(
1768 choices=[
"paper_run1",
"paper_run2"],
1769 help=
"how to order systematics, options: paper_run1, paper_run2",
1771 parser.add_argument(
"--debug", action=
"store_true")
1772 parser.add_argument(
1773 "--superimpose-all", action=
"store_true", help=
"superimpose sum of systematics"
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"
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"
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"
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(
1795 action=
"store_true",
1796 help=
"plot the quadrature sum of the systematics for debug (should be equal to 1NP up)",
1798 parser.add_argument(
1799 "--atlas-label", default=
"Internal", help=
'Internal, Preliminary, ..., use "" for papers'
1801 args = parser.parse_args()
1804 log.setLevel(logging.DEBUG)
1805 log.debug(
"DEBUG activated")
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)
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)
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),
1823 if not os.path.exists(basedir):
1824 os.makedirs(basedir)
1826 if args.action ==
"list-systematics":
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)
1840 if args.action ==
"compare_sys":
1841 log.info(
"comparing systematics")
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,
1852 if args.action ==
"resolution-err":
1853 log.info(
"plotting resolution error")
1856 if args.action ==
"zee" or args.action ==
"all":
1857 log.info(
"plotting scale systematics")
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"
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()
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()
1879 tool_es2015PRE_nouA2MeV,
1884 title=
"with uA2MeV correction / without",
1885 particle=
"electron",
1888 del tool_es2015PRE_nouA2MeV
1891 if args.action ==
"all" or args.action ==
"scale":
1892 log.info(
"plotting scales")
1894 esmodels=args.esmodels,
1895 labels=args.esmodels,
1897 etas=np.arange(-2.5, 2.5, 0.01),
1901 if args.action ==
"all" or args.action ==
"fast":
1902 log.info(
"plotting full / fast scale")
1905 esmodels=(
"es2015PRE", (
"es2015PRE", (
"useFastSim",), (
True,), (bool,))),
1906 labels=(
"2015PRE",
"2015PRE FAST"),
1908 etas=np.arange(-2.5, 2.5, 0.01),
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"),
1916 etas=np.arange(-2.5, 2.5, 0.01),
1919 if args.action ==
"gain" or args.action ==
"all":
1922 if args.action ==
"uniformity" or args.action ==
"all":
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()
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"),
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)
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)
1952 supersampling_eta=args.super_sampling_eta,
1953 esmodel=args.esmodels[0],
1954 decorrelation=
"FULL_ETACORRELATED_v1",
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,
1964 only_up=
not args.add_down,
1965 symmetrize_labels=args.symmetrize_labels,
1966 legend_outside=args.legend_outside,
1969 plot_qsum=args.plot_qsum,
1970 abs_sys=args.abs_sys,
1971 atlas_label=args.atlas_label,
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":
1981 supersampling_eta=args.super_sampling_eta,
1982 esmodel=args.esmodels[0],
1983 decorrelation=
"FULL_ETACORRELATED_v1",
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,
1993 only_up=
not args.add_down,
1994 legend_outside=args.legend_outside,
1995 symmetrize_labels=args.symmetrize_labels,
1997 plot_qsum=args.plot_qsum,
1998 abs_sys=args.abs_sys,
1999 atlas_label=args.atlas_label,
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)
2008 decorrelation=args.decorrelation,
2011 eta_range=args.eta_bins,
2012 pt_range=args.pt_bins,
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,
2020 if args.action ==
"resolution" or args.action ==
"all":
2021 tool = ROOT.CP.EgammaCalibrationAndSmearingTool(
"tool")
2022 tool.setProperty(
"ESModel",
"es2015PRE")
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"
2030 basedir, tool, pts, etas,
"converted", title=
"resolution converted es2015PRE"
2033 basedir, tool, pts, etas,
"unconverted", title=
"resolution unconverted es2015PRE"
2037 if __name__ ==
"__main__":
2041 super(self.__class__, self).
__init__(level)
2045 msg = self.format(record)
2046 tqdm.tqdm.write(msg)
2048 except (KeyboardInterrupt, SystemExit):
2051 self.handleError(record)
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",
2062 "SUCCESS:":
"green",
2063 "WARNING":
"yellow",
2065 "CRITICAL":
"red,bg_white",
2069 log.addHandler(handler)