Belle II Software light-2609-luna
ReweighterParticle Class Reference

Public Member Functions

str get_varname (self, str varname)
 
list get_binning_variables (self)
 
list get_pdg_variables (self)
 
None generate_variations (self, int n_variations, np.ndarray rho_sys=None, np.ndarray rho_stat=None)
 
int get_seed (self, str component)
 
np.ndarray get_covariance (self, int n_variations, np.ndarray rho_sys=None, np.ndarray rho_stat=None)
 
str __str__ (self)
 
 plot_coverage (self, fig=None, axs=None)
 

Public Attributes

 variable_aliases
 Variable aliases of the weight table.
 
 prefix = self.variable_aliases[varname]
 Prefix of the particle in the ntuple.
 
str type = "PID":
 Add the mcPDG code requirement for PID particle.
 
 weight_name = weights.T
 Weight column name that will be added to the ntuple.
 
 pdg_binning
 Kinematic binning of the weight table per particle.
 

Static Public Attributes

pd merged_table .DataFrame
 Type of the particle (PID or FEI)
 
list column_names = None
 Internal list of the names of the weight columns.
 
int sys_seed = None
 Random seed for systematics only (legacy, prefer seed)
 
np cov = None
 Covariance matrix corresponds to the total uncertainty.
 
bool syscorr = True
 When true assume systematics are 100% correlated.
 
float coverage = None
 Coverage of the user ntuple.
 
dict plot_values = None
 Values for the plots.
 
int seed = None
 Base seed for all variations, see get_seed.
 

Detailed Description

Class that stores the information of a particle.

Definition at line 94 of file sysvar.py.

Member Function Documentation

◆ __str__()

str __str__ ( self)
Converts the object to a string.

Definition at line 243 of file sysvar.py.

243 def __str__(self) -> str:
244 """
245 Converts the object to a string.
246 """
247 separator = '------------------'
248 title = 'ReweighterParticle'
249 prefix_str = f'Type: {self.type} Prefix: {self.prefix}'
250 columns = _weight_cols
251 merged_table_str = f'Merged table:\n{self.merged_table[columns].describe()}'
252 pdg_binning_str = 'PDG binning:\n'
253 for pdgs in self.pdg_binning:
254 pdg_binning_str += f'{pdgs}: {self.pdg_binning[pdgs]}\n'
255 return '\n'.join([separator, title, prefix_str, merged_table_str, pdg_binning_str]) + separator
256

◆ generate_variations()

None generate_variations ( self,
int n_variations,
np.ndarray rho_sys = None,
np.ndarray rho_stat = None )
Generates variations of weights according to the uncertainties

Definition at line 169 of file sysvar.py.

172 rho_stat: np.ndarray = None) -> None:
173 """
174 Generates variations of weights according to the uncertainties
175 """
176 self.merged_table['stat_error'] = self.merged_table[["data_MC_uncertainty_stat_up",
177 "data_MC_uncertainty_stat_dn"]].max(axis=1)
178 self.merged_table['sys_error'] = self.merged_table[["data_MC_uncertainty_sys_up",
179 "data_MC_uncertainty_sys_dn"]].max(axis=1)
180 self.merged_table["error"] = np.sqrt(self.merged_table["stat_error"] ** 2 + self.merged_table["sys_error"] ** 2)
181 means = self.merged_table["data_MC_ratio"].values
182
183 self.column_names = [f"{self.weight_name}_{i}" for i in range(n_variations)]
184 cov = self.get_covariance(n_variations, rho_sys, rho_stat)
185 weights = cov + means
186 self.merged_table[self.weight_name] = self.merged_table["data_MC_ratio"]
187 self.merged_table[self.column_names] = weights.T
188 self.column_names.insert(0, self.weight_name)
189

◆ get_binning_variables()

list get_binning_variables ( self)
Returns the list of variables that are used for the binning

Definition at line 152 of file sysvar.py.

152 def get_binning_variables(self) -> list:
153 """
154 Returns the list of variables that are used for the binning
155 """
156 variables = set(sum([list(d.keys()) for d in self.pdg_binning.values()], []))
157 return [f'{self.get_varname(var)}' for var in variables]
158

◆ get_covariance()

np.ndarray get_covariance ( self,
int n_variations,
np.ndarray rho_sys = None,
np.ndarray rho_stat = None )
Returns the covariance matrix of the weights

Definition at line 203 of file sysvar.py.

206 rho_stat: np.ndarray = None) -> np.ndarray:
207 """
208 Returns the covariance matrix of the weights
209 """
210 len_means = len(self.merged_table["data_MC_ratio"])
211 zeros = np.zeros(len_means)
212 if self.cov is None:
213 if rho_sys is None:
214 if self.syscorr:
215 rho_sys = np.ones((len_means, len_means))
216 else:
217 rho_sys = np.identity(len_means)
218 if rho_stat is None:
219 rho_stat = np.identity(len_means)
220 sys_cov = np.matmul(
221 np.matmul(np.diag(self.merged_table['sys_error']), rho_sys), np.diag(self.merged_table['sys_error'])
222 )
223 stat_cov = np.matmul(
224 np.matmul(np.diag(self.merged_table['stat_error']), rho_stat), np.diag(self.merged_table['stat_error'])
225 )
226 if self.seed is not None:
227 # Local generators, so the caller's global RNG state is left untouched
228 sys = np.random.default_rng(self.get_seed('sys')).multivariate_normal(zeros, sys_cov, n_variations)
229 stat = np.random.default_rng(self.get_seed('stat')).multivariate_normal(zeros, stat_cov, n_variations)
230 return sys + stat
231 # Legacy sys_seed behaviour
232 np.random.seed(self.sys_seed)
233 sys = np.random.multivariate_normal(zeros, sys_cov, n_variations)
234 np.random.seed(None)
235 stat = np.random.multivariate_normal(zeros, stat_cov, n_variations)
236 return sys + stat
237 # Total covariance: a single draw covers sys and stat
238 if self.seed is not None:
239 return np.random.default_rng(self.get_seed('total')).multivariate_normal(zeros, self.cov, n_variations)
240 errors = np.random.multivariate_normal(zeros, self.cov, n_variations)
241 return errors
242

◆ get_pdg_variables()

list get_pdg_variables ( self)
Returns the list of variables that are used for the PDG codes

Definition at line 159 of file sysvar.py.

159 def get_pdg_variables(self) -> list:
160 """
161 Returns the list of variables that are used for the PDG codes
162 """
163 pdg_vars = ['PDG']
164
165 if self.type == "PID":
166 pdg_vars += ['mcPDG']
167 return [f'{self.get_varname(var)}' for var in pdg_vars]
168

◆ get_seed()

int get_seed ( self,
str component )
Returns the seed for one component of the variations: 'sys', 'stat', or 'total'
for the combined draw when cov is set.

Derived from seed, the table identity and the component, so a table gives the
same variations in every dataframe it is applied to, while different tables and
components are independent.

Definition at line 190 of file sysvar.py.

190 def get_seed(self, component: str) -> int:
191 """
192 Returns the seed for one component of the variations: 'sys', 'stat', or 'total'
193 for the combined draw when cov is set.
194
195 Derived from seed, the table identity and the component, so a table gives the
196 same variations in every dataframe it is applied to, while different tables and
197 components are independent.
198 """
199 if self.seed is None:
200 return None
201 return _derive_seed(self.seed, f'{component}:{_table_key(self.merged_table)}')
202

◆ get_varname()

str get_varname ( self,
str varname )
Returns the variable name with the prefix and use alias if defined.

Definition at line 141 of file sysvar.py.

141 def get_varname(self, varname: str) -> str:
142 """
143 Returns the variable name with the prefix and use alias if defined.
144 """
145 name = varname
146 if self.variable_aliases and varname in self.variable_aliases:
147 name = self.variable_aliases[varname]
148 if name.startswith(self.prefix):
149 return name
150 return f'{self.prefix}{name}'
151

◆ plot_coverage()

plot_coverage ( self,
fig = None,
axs = None )
Plots the coverage of the ntuple.

Definition at line 257 of file sysvar.py.

257 def plot_coverage(self, fig=None, axs=None):
258 """
259 Plots the coverage of the ntuple.
260 """
261 if self.plot_values is None:
262 return
263 vars = set(sum([list(d.keys()) for d in self.plot_values.values()], []))
264 if fig is None:
265 fig, axs = plt.subplots(len(self.plot_values), len(vars), figsize=(5 * len(vars), 3 * len(self.plot_values)), dpi=120)
266 axs = np.array(axs)
267 if len(axs.shape) < 2:
268 axs = axs.reshape(len(self.plot_values), len(vars))
269 bin_plt = {'linewidth': 3, 'linestyle': '--', 'color': '0.5'}
270 fig.suptitle(f'{self.type} particle {self.prefix.strip("_")}')
271 for (reco_pdg, mc_pdg), ax_row in zip(self.plot_values, axs):
272 for var, ax in zip(self.plot_values[(reco_pdg, mc_pdg)], ax_row):
273 ymin = 0
274 ymax = self.plot_values[(reco_pdg, mc_pdg)][var][1].max() * 1.1
275 # Plot binning
276 if self.type == 'PID':
277 ax.vlines(self.pdg_binning[(reco_pdg, mc_pdg)][var], ymin, ymax,
278 label='Binning',
279 alpha=0.8,
280 **bin_plt)
281 elif self.type == 'FEI':
282 values = np.array([int(val[4:]) for val in self.pdg_binning[(reco_pdg, mc_pdg)][var]])
283 ax.bar(values + 0.5,
284 np.ones(len(values)) * ymax,
285 width=1,
286 alpha=0.5,
287 label='Binning',
288 **bin_plt)
289 rest = np.setdiff1d(self.plot_values[(reco_pdg, mc_pdg)][var][0], values)
290 ax.bar(rest + 0.5,
291 np.ones(len(rest)) * ymax,
292 width=1,
293 alpha=0.2,
294 label='Rest category',
295 **bin_plt)
296 # Plot values
297 widths = (self.plot_values[(reco_pdg, mc_pdg)][var][0][1:] - self.plot_values[(reco_pdg, mc_pdg)][var][0][:-1])
298 centers = self.plot_values[(reco_pdg, mc_pdg)][var][0][:-1] + widths / 2
299 ax.bar(centers,
300 self.plot_values[(reco_pdg, mc_pdg)][var][1],
301 width=widths,
302 label='Values',
303 alpha=0.8)
304 ax.set_title(f'True {pdg.to_name(mc_pdg)} to reco {pdg.to_name(reco_pdg)} coverage')
305 ax.set_xlabel(var)
306 axs[-1][-1].legend()
307 fig.tight_layout()
308 return fig, axs
309
310

Member Data Documentation

◆ column_names

list column_names = None
static

Internal list of the names of the weight columns.

Definition at line 121 of file sysvar.py.

◆ cov

cov = None
static

Covariance matrix corresponds to the total uncertainty.

Definition at line 127 of file sysvar.py.

◆ coverage

float coverage = None
static

Coverage of the user ntuple.

Definition at line 133 of file sysvar.py.

◆ merged_table

pd merged_table .DataFrame
static

Type of the particle (PID or FEI)

Merged table of the weights

Definition at line 106 of file sysvar.py.

◆ pdg_binning

pdg_binning

Kinematic binning of the weight table per particle.

Definition at line 253 of file sysvar.py.

◆ plot_values

plot_values = None
static

Values for the plots.

Definition at line 136 of file sysvar.py.

◆ prefix

prefix = self.variable_aliases[varname]

Prefix of the particle in the ntuple.

Definition at line 148 of file sysvar.py.

◆ seed

seed = None
static

Base seed for all variations, see get_seed.

None falls back to sys_seed

Definition at line 139 of file sysvar.py.

◆ sys_seed

sys_seed = None
static

Random seed for systematics only (legacy, prefer seed)

Definition at line 124 of file sysvar.py.

◆ syscorr

bool syscorr = True
static

When true assume systematics are 100% correlated.

Definition at line 130 of file sysvar.py.

◆ type

str type = "PID":

Add the mcPDG code requirement for PID particle.

Definition at line 165 of file sysvar.py.

◆ variable_aliases

variable_aliases

Variable aliases of the weight table.

Definition at line 146 of file sysvar.py.

◆ weight_name

weight_name = weights.T

Weight column name that will be added to the ntuple.

Definition at line 188 of file sysvar.py.


The documentation for this class was generated from the following file: