183 def plot_coverage(self, fig=None, axs=None):
184 """
185 Plots the coverage of the ntuple.
186 """
187 if self.plot_values is None:
188 return
189 vars = set(sum([list(d.keys()) for d in self.plot_values.values()], []))
190 if fig is None:
191 fig, axs = plt.subplots(len(self.plot_values), len(vars), figsize=(5*len(vars), 3*len(self.plot_values)), dpi=120)
192 axs = np.array(axs)
193 if len(axs.shape) < 1:
194 axs = axs.reshape(len(self.plot_values), len(vars))
195 bin_plt = {'linewidth': 3, 'linestyle': '--', 'color': '0.5'}
196 fig.suptitle(f'{self.type} particle {self.prefix.strip("_")}')
197 for (reco_pdg, mc_pdg), ax_row in zip(self.plot_values, axs):
198 for var, ax in zip(self.plot_values[(reco_pdg, mc_pdg)], ax_row):
199 ymin = 0
200 ymax = self.plot_values[(reco_pdg, mc_pdg)][var][1].max()*1.1
201
202 if self.type == 'PID':
203 ax.vlines(self.pdg_binning[(reco_pdg, mc_pdg)][var], ymin, ymax,
204 label='Binning',
205 alpha=0.8,
206 **bin_plt)
207 elif self.type == 'FEI':
208 values = np.array([int(val[4:]) for val in self.pdg_binning[(reco_pdg, mc_pdg)][var]])
209 ax.bar(values+0.5,
210 np.ones(len(values))*ymax,
211 width=1,
212 alpha=0.5,
213 label='Binning',
214 **bin_plt)
215 rest = np.setdiff1d(self.plot_values[(reco_pdg, mc_pdg)][var][0], values)
216 ax.bar(rest+0.5,
217 np.ones(len(rest))*ymax,
218 width=1,
219 alpha=0.2,
220 label='Rest category',
221 **bin_plt)
222
223 widths = (self.plot_values[(reco_pdg, mc_pdg)][var][0][1:] - self.plot_values[(reco_pdg, mc_pdg)][var][0][:-1])
224 centers = self.plot_values[(reco_pdg, mc_pdg)][var][0][:-1] + widths/2
225 ax.bar(centers,
226 self.plot_values[(reco_pdg, mc_pdg)][var][1],
227 width=widths,
228 label='Values',
229 alpha=0.8)
230 ax.set_title(f'True {pdg.to_name(mc_pdg)} to reco {pdg.to_name(reco_pdg)} coverage')
231 ax.set_xlabel(var)
232 axs[-1][-1].legend()
233 fig.tight_layout()
234 return fig, axs
235
236