Source code for validphys.covmats_utils

"""
covmat_utils.py

Utils functions for constructing covariance matrices from systematics.
Leveraged by :py:mod:`validphys.covmats` which contains relevant
actions/providers.

"""
import numpy as np
import pandas as pd


[docs]def systematics_matrix(stat_errors: np.array, sys_errors: pd.DataFrame): """Basic function to create a systematics matrix , :math:`A`, such that: .. math:: C = A A^T Where :math:`C` is the covariance matrix. This is achieved by creating a block diagonal matrix by adding the uncorrelated systematics in quadrature then taking the square-root and concatenating the correlated systematics, schematically: .. code::python A = concat([diag(sqrt(A_uncorr.sum(axis=1))), A_corr]) Parameters ---------- stat_errors: np.array a 1-D array of statistical uncertainties sys_errors: pd.DataFrame a dataframe with shape (N_data * N_sys) and systematic name as the column headers. The uncertainties should be in the same units as the data. Notes ----- This function doesn't contain any logic to ignore certain contributions to the covmat, if you wanted to not include a particular systematic/set of systematics i.e all uncertainties with MULT errors, then filter those out of ``sys_errors`` before passing that to this function. """ diagonal = stat_errors**2 is_uncorr = sys_errors.columns.isin(("UNCORR", "THEORYUNCORR")) diagonal += (sys_errors.loc[:, is_uncorr].to_numpy() ** 2).sum(axis=1) corr_sys_mat = sys_errors.loc[:, ~is_uncorr].to_numpy() return np.concatenate((np.diag(np.sqrt(diagonal)), corr_sys_mat), axis=1)
[docs]def construct_covmat(stat_errors: np.array, sys_errors: pd.DataFrame): """Basic function to construct a covariance matrix (covmat), given the statistical error and a dataframe of systematics. Errors with name UNCORR or THEORYUNCORR are added in quadrature with the statistical error to the diagonal of the covmat. Other systematics are treated as correlated; their covmat contribution is found by multiplying them by their transpose. Parameters ---------- stat_errors: np.array a 1-D array of statistical uncertainties sys_errors: pd.DataFrame a dataframe with shape (N_data * N_sys) and systematic name as the column headers. The uncertainties should be in the same units as the data. Notes ----- This function doesn't contain any logic to ignore certain contributions to the covmat, if you wanted to not include a particular systematic/set of systematics i.e all uncertainties with MULT errors, then filter those out of ``sys_errors`` before passing that to this function. """ diagonal = stat_errors**2 is_uncorr = sys_errors.columns.isin(("UNCORR", "THEORYUNCORR")) diagonal += (sys_errors.loc[:, is_uncorr].to_numpy() ** 2).sum(axis=1) corr_sys_mat = sys_errors.loc[:, ~is_uncorr].to_numpy() return np.diag(diagonal) + corr_sys_mat @ corr_sys_mat.T