12 Utilities for plotting
14 from pxd.utils import getH1Sigma68WithError
19 import matplotlib.pyplot
as plt
20 plt.style.use(
'belle2')
30 ROOT.gStyle.SetCanvasBorderMode(0)
31 ROOT.gStyle.SetCanvasBorderSize(10)
32 ROOT.gStyle.SetCanvasColor(0)
33 ROOT.gStyle.SetCanvasDefH(450)
34 ROOT.gStyle.SetCanvasDefW(500)
35 ROOT.gStyle.SetCanvasDefX(10)
36 ROOT.gStyle.SetCanvasDefY(10)
38 ROOT.gStyle.SetPadBorderMode(0)
39 ROOT.gStyle.SetPadBorderSize(10)
40 ROOT.gStyle.SetPadColor(0)
41 ROOT.gStyle.SetPadBottomMargin(0.16)
42 ROOT.gStyle.SetPadTopMargin(0.10)
43 ROOT.gStyle.SetPadLeftMargin(0.17)
44 ROOT.gStyle.SetPadRightMargin(0.19)
45 ROOT.gStyle.SetPadGridX(1)
46 ROOT.gStyle.SetPadGridY(1)
47 ROOT.gStyle.SetGridStyle(2)
48 ROOT.gStyle.SetGridColor(ROOT.kGray + 1)
50 ROOT.gStyle.SetFrameFillStyle(0)
51 ROOT.gStyle.SetFrameFillColor(0)
52 ROOT.gStyle.SetFrameLineColor(1)
53 ROOT.gStyle.SetFrameLineStyle(0)
54 ROOT.gStyle.SetFrameLineWidth(2)
55 ROOT.gStyle.SetFrameBorderMode(0)
56 ROOT.gStyle.SetFrameBorderSize(10)
58 ROOT.gStyle.SetLabelFont(42,
"xyz")
59 ROOT.gStyle.SetLabelOffset(0.015,
"xyz")
60 ROOT.gStyle.SetLabelSize(0.048,
"xyz")
61 ROOT.gStyle.SetNdivisions(505,
"xyz")
62 ROOT.gStyle.SetTitleFont(42,
"xyz")
63 ROOT.gStyle.SetTitleSize(0.050,
"xyz")
64 ROOT.gStyle.SetTitleOffset(1.3,
"x")
65 ROOT.gStyle.SetTitleOffset(1.2,
"y")
66 ROOT.gStyle.SetTitleOffset(1.4,
"z")
67 ROOT.gStyle.SetPadTickX(1)
68 ROOT.gStyle.SetPadTickY(1)
70 ROOT.gStyle.SetTitleBorderSize(0)
71 ROOT.gStyle.SetTitleFillColor(10)
72 ROOT.gStyle.SetTitleAlign(12)
73 ROOT.gStyle.SetTitleFontSize(0.045)
74 ROOT.gStyle.SetTitleX(0.560)
75 ROOT.gStyle.SetTitleY(0.860)
76 ROOT.gStyle.SetTitleFont(42,
"")
78 ROOT.gStyle.SetStatBorderSize(0)
79 ROOT.gStyle.SetStatColor(10)
80 ROOT.gStyle.SetStatFont(42)
81 ROOT.gStyle.SetStatX(0.94)
82 ROOT.gStyle.SetStatY(0.91)
84 ROOT.gStyle.SetOptTitle(0)
85 ROOT.gStyle.SetOptStat(0)
86 ROOT.gStyle.SetHistLineWidth(3)
87 ROOT.TH2.SetDefaultSumw2()
90 def df_plot_errorbar(df, x, y, yerr_low, yerr_up, ax=None, *args, **kwargs):
92 errorbar extention for pandas.DataFrame
95 x (str): column used as the x-axis
96 y (str): column used as the y-axis
97 yerr_low (str): column of the lower error of value y
98 yerr_up (str): column of the upper error of value y
100 ax: matplotlib.pyplot.axis
101 args: positional arguments
102 kwargs: named arguments
106 array_x = df[x].to_numpy()
107 array_y = df[y].to_numpy()
108 yerr = [df[yerr_low].to_numpy(), df[yerr_up].to_numpy()]
109 default_kwargs = {
"fmt":
"o",
"label": y,
"alpha": 0.7}
110 kwargs = {**default_kwargs, **kwargs}
112 ax.errorbar(x=array_x, y=array_y, yerr=yerr, *args, **kwargs)
120 if hasattr(pd.DataFrame,
"errorbar"):
121 b2.B2WARNING(
"DataFrame.errorbar has already been defined. Replacing it!")
122 pd.DataFrame.errorbar = df_plot_errorbar
125 def plot_ip_resolutions(tree, cut="0<z0_err<1 & 0<d0_err<1", figsize=(16, 6), save_to=
""):
127 Helper function to plot ip resolutions as a function of run number.
129 tree: a ROOT.TTree which contains run, hD0, hZ0 from PXD calibration validation.
130 figsize (tuple): figsize for matplotlib pyplot
131 save_to (str): Target file name to save a figure when it's not empty.
133 pandas.DataFrame with resolutions
135 plt.figure(figsize=figsize)
136 ip_res_dic = {
"run": [],
"d0": [],
"d0_err": [],
"z0": [],
"z0_err": []}
137 for i
in range(tree.GetEntries()):
140 run = getattr(tree,
"run")
141 hD0 = getattr(tree,
"hD0")
142 hZ0 = getattr(tree,
"hZ0")
143 res_d0, res_d0_err = np.array(getH1Sigma68WithError(hD0, 1000)) / 2 * 1e4
144 res_z0, res_z0_err = np.array(getH1Sigma68WithError(hZ0, 1000)) / 2 * 1e4
146 ip_res_dic[
"run"].append(run)
147 ip_res_dic[
"d0"].append(res_d0)
148 ip_res_dic[
"d0_err"].append(res_d0_err)
149 ip_res_dic[
"z0"].append(res_z0)
150 ip_res_dic[
"z0_err"].append(res_z0_err)
151 df_res = pd.DataFrame(ip_res_dic)
152 df_res.query(cut).errorbar(y=
"z0", x=
"run", yerr_low=
"z0_err", yerr_up=
"z0_err")
153 df_res.query(cut).errorbar(y=
"d0", x=
"run", yerr_low=
"d0_err", yerr_up=
"d0_err")
154 plt.ylabel(
r"$\sigma_{68}$ " +
r"[$\mathrm{\mu m}$]")
159 def plot_efficiency_map(tree, exp_runs=[], num_name="hTrackClustersLayer1", den_name="hTrackPointsLayer1",
160 title="Efficiency of layer 1", canvas=None, save_to=""):
162 Helper function to plot efficiency map of modules for a given layer.
163 Color map can be set by ROOT.gStyle.SetPalette(ROOT.kDarkRainBow)
166 exp_runs (list): list of (experiment_number, run_number) or list of run_number
167 num_name (str): histogram name of the ROOT.TH2 used for numerator
168 den_name (str): histogram name of the ROOT.TH2 used for denominator
169 title (str): title of the plot
170 canvas (ROOT.TCanvas): TCanvas for plotting
171 save_to (str): File name to save the figure
173 the efficiency map (ROOT.TH2)
176 canvas = ROOT.TCanvas(
"c1",
"c1", 900, 600)
177 use_exp_run_tuple =
True
180 elif not isinstance(exp_runs[0], tuple):
181 exp_runs = sorted(exp_runs)
182 use_exp_run_tuple =
False
184 h_eff, h_num, h_den =
None,
None,
None
185 for i_evt
in range(tree.GetEntries()):
187 exp = getattr(tree,
"exp")
188 run = getattr(tree,
"run")
189 if not use_exp_run_tuple:
190 if run < exp_runs[0]
or run > exp_runs[-1]:
192 elif (exp, run)
not in exp_runs:
195 h_num = getattr(tree, num_name).Clone()
196 h_den = getattr(tree, den_name).Clone()
198 h_num.Add(getattr(tree, num_name))
199 h_den.Add(getattr(tree, den_name))
202 h_temp = h_den.Clone()
204 h_eff = h_num.Clone()
205 h_eff.Add(h_temp, 1e-9)
207 h_eff.SetTitle(title)
210 ROOT.gStyle.SetOptStat(10)
213 s = h_eff.GetListOfFunctions().FindObject(
"stats")
219 s.SetFillColorAlpha(0, 0.1)
220 s.SetLineColorAlpha(0, 0)
223 h_eff.GetZaxis().SetRangeUser(0.9, 1)
225 canvas.Print(save_to+
".above90.png")
226 h_eff.GetZaxis().SetRangeUser(0, 1)
228 canvas.Print(save_to)
231 return h_eff, h_num, h_den
234 def plot_in_module_efficiency(df, pxdid=1052, figsize=(12, 16), alpha=0.7, save_to=
"",
235 y=
"eff_sel", x=
"run", cut=
"eff_sel>0&eff_sel_err_low<0.01",
236 yerr_low=
"eff_sel_err_low", yerr_up=
"eff_sel_err_up"):
238 Helper function to plot efficiencies of 4 x 6 ASIC regions in one module
240 df (pandas.DataFrame): pandas DataFrame for plotting
241 pxdid (int): pxdid, e.g., 1052
242 figsize (tuple): figsize for matplotlib pyplot
243 alpha (float): alpha color
244 save_to (str): File name to save the figure
245 y (str): column of the efficiency
246 x (str): column of the run
247 cut (str): additional cut
248 yerr_low (str): column of the lower error
249 yerr_up (str): column of the upper error
252 fig, axes = plt.subplots(4, 1, sharex=
False, sharey=
True, figsize=figsize)
253 for uBin
in range(4):
255 for vBin
in range(6):
256 df.query(cut +
"&" + f
"pxdid=={pxdid}&uBin=={uBin}&vBin=={vBin}").errorbar(
257 y=y, x=x, yerr_low=yerr_low, yerr_up=yerr_up, ax=ax, label=f
"{pxdid},u{uBin}v{vBin}", alpha=0.7)
258 ax.legend(bbox_to_anchor=(1, 1), loc=
"upper left")
259 ymin, ymax = ax.get_ylim()
260 ax.set_ylim(ymin, 1.)
262 fig.savefig(save_to, bbox_inches=
"tight")
265 def plot_efficiency_vs_run(
268 eff_sel_var="eff_sel",
273 save_to=
"pxd_efficiency_vs_run.png"):
275 Helper function to plot efficiency vs run
277 df (pandas.DataFrame): pandas DataFrame for plotting
278 eff_var (str): column of the efficiency
279 eff_sel_var (str): column of the efficiency of selected regions
280 max_err (float): the maximum error used to clean up points with large errors
281 figsize (tuple): figsize for matplotlib pyplot
282 save_to (str): file name to save the figure
285 plt.figure(figsize=figsize)
286 df.query(f
"{eff_var}_err_low<{max_err}").errorbar(
289 yerr_low=f
"{eff_var}_err_low",
290 yerr_up=f
"{eff_var}_err_up",
293 df.query(f
"{eff_sel_var}_err_low<{max_err}").errorbar(
296 yerr_low=f
"{eff_sel_var}_err_low",
297 yerr_up=f
"{eff_sel_var}_err_up",
299 label=
"Excluding hot/dead regions")
300 plt.ylabel(
"PXD efficiency")
301 ymin, ymax = plt.ylim()
307 def plot_module_efficiencies_in_DHHs(df, eff_var="eff_sel", phase="early_phase3", figsize=(12, 6), save_to=
"efficiency_vs_run.png"):
309 Helper function to plot efficiencies of modules in a DHH.
311 df (pandas.DataFrame): pandas DataFrame for plotting
312 eff_var (str): column of the efficiency
313 phase (str): belle2 phase, the default is earyly_phase3 with half PXD
314 figsize (tuple): figsize for matplotlib pyplot
315 save_to (str): file name to save the figure
319 if phase ==
"early_phase3":
321 "H30": [1012, 1022, 1052, 1082, 2042],
322 "H40": [1042, 1062, 1072, 2052],
323 "H50": [1041, 1051, 1061, 1071, 2051],
324 "H60": [1011, 1021, 1031, 1081, 2041],
326 for dhh, pxdid_list
in dhh_modules_dic.items():
327 plt.figure(figsize=figsize)
329 for pxdid
in pxdid_list:
330 df.query(f
"{eff_var}>0&pxdid=={pxdid}&{eff_var}_err_low<0.01").errorbar(
331 y=eff_var, x=
"run", yerr_low=f
"{eff_var}_err_low", yerr_up=f
"{eff_var}_err_up", label=f
"{pxdid}", alpha=0.7)
332 ymin = min(plt.ylim()[0], ymin)
333 plt.ylabel(
"Efficiency (selected)")
334 plt.title(dhh +
" efficiency")
337 plt.savefig(dhh +
"_" + save_to)
340 if __name__ ==
'__main__':