Source code for sysvar.covariance_calculator

from __future__ import annotations

from os import path, makedirs
import itertools
from functools import cached_property
from typing import List

from tqdm import tqdm

import numpy as np
from pandas import DataFrame

import uproot

from sysvar.corrections import create_correction_object
from sysvar.variations import Variator
from sysvar.templates import Template1D, TemplateND
from sysvar.utils import SavableAttributesObject
from sysvar.eigendecomposer import EigenDecomposer

import logging

logging.basicConfig(
    format="%(levelname)s : %(funcName)s: %(lineno)d :  %(message)s",
    level=logging.INFO,
)


[docs] class CovarianceCalculator(EigenDecomposer): def __init__( self, df: DataFrame, settings: dict, syst_effect: str, binning: dict, channels: int | List[str] = None, cov_input: np.ndarray | None = None, verbose: bool = False, ): super().__init__(df, settings, syst_effect, verbose) if cov_input is not None: self.variator.cov_matrix = cov_input self.variator.variations = self.variator.get_correction_variations() self.binning = binning self.channels = channels @property def cov(self) -> np.ndarray: for j, tmp_template in enumerate(self.templates.values()): # If this is the first templates initialize an emtpy cov matrix if j == 0: cov = np.zeros((tmp_template.Nbins, tmp_template.Nbins)) # Now add the template cov matrix cov += tmp_template.cov_matrix return cov
[docs] def save_covariance(self): # extract its topdir base_path = self.settings["covariance_matrices_dir"] # check if the covariance directory exists # if not path.exists(base_path): # if not create it makedirs(base_path, exist_ok=True) filename = "_".join( ( "_".join([str(x) for x in self.channels]), "_".join(list(self.binning.keys())), "_".join( [ str(np.round(b, 2)) for bin_list in self.binning.values() for b in bin_list ] ), self.syst_effect, "cov.npy", ) ) outpath = path.join(base_path, filename) np.save(outpath, self.cov) logging.info("Save covariance matrix at %s", str(outpath))