"""
theorycovarianceutils.py
Low level utilities for theorycovariance module
"""
import logging
from reportengine.checks import check, make_argcheck
from validphys.loader import Loader
from validphys.plotoptions.core import get_info
log = logging.getLogger(__name__)
[docs]
def check_correct_theory_combination_internal(
theoryids, point_prescription: (str, type(None)) = None
):
"""Checks that a valid theory combination corresponding to an existing
prescription has been inputted"""
xifs = [theoryid.get_description()["XIF"] for theoryid in theoryids]
xirs = [theoryid.get_description()["XIR"] for theoryid in theoryids]
correct_xifs = correct_xirs = None
if point_prescription == "3f point":
correct_xifs = [1.0, 2.0, 0.5]
correct_xirs = [1.0, 1.0, 1.0]
if point_prescription == "3r point":
correct_xifs = [1.0, 1.0, 1.0]
correct_xirs = [1.0, 2.0, 0.5]
if point_prescription == "3 point":
correct_xifs = [1.0, 2.0, 0.5]
correct_xirs = [1.0, 2.0, 0.5]
if point_prescription in ["3pt missing", "3pt hadronic"]:
correct_xifs = [1.0, 1.0, 1.0]
correct_xirs = [1.0, 0.5, 2.0]
if point_prescription == "5 point":
correct_xifs = [1.0, 2.0, 0.5, 1.0, 1.0]
correct_xirs = [1.0, 1.0, 1.0, 2.0, 0.5]
if point_prescription == "5bar point":
correct_xifs = [1.0, 2.0, 0.5, 2.0, 0.5]
correct_xirs = [1.0, 2.0, 0.5, 0.5, 2.0]
if point_prescription in ["7 point"]:
correct_xifs = [1.0, 2.0, 0.5, 1.0, 1.0, 2.0, 0.5]
correct_xirs = [1.0, 1.0, 1.0, 2.0, 0.5, 2.0, 0.5]
if correct_xirs != None and correct_xifs != None:
# some covmats don't rely on scale variations so we don't explicitly check those
check(
xifs == correct_xifs and xirs == correct_xirs,
"Choice of input theories does not correspond to a valid "
"prescription for the requested scale variation covmat",
)
if point_prescription == "ad ihou":
n3lo_vars_list = []
for theoryid in theoryids:
n3lo_vars_list.append(theoryid.get_description()["n3lo_ad_variation"][:4])
full_var_list = [[0, 0, 0, 0]]
n3lo_vars_dict = {"gg": 19, "gq": 21, "qg": 15, "qq": 6}
for entry, max_var in enumerate(n3lo_vars_dict.values()):
for idx in range(1, max_var + 1):
base_var = [0, 0, 0, 0]
base_var[entry] = idx
full_var_list.append(base_var)
check(
n3lo_vars_list == full_var_list,
f"Theories do not include the full list of N3LO variation but {n3lo_vars_list}",
)
check_correct_theory_combination = make_argcheck(check_correct_theory_combination_internal)
[docs]
@make_argcheck
def check_fit_dataset_order_matches_grouped(
group_dataset_inputs_by_metadata, data_input, processed_metadata_group
):
"""
Check for use with theory covmat generation.
Makes sure that the order of datasets listed in the fit runcard is the same
as that specified by the metadata grouping. Otherwise there can be a
misalignment between the experiment covmat and theory covmat.
"""
data_input_iter = iter(data_input)
for group in group_dataset_inputs_by_metadata:
for dsinput in group["data_input"]:
grouped_ds = dsinput.name
input_ds = next(data_input_iter).name
check(
grouped_ds == input_ds,
"Dataset ordering is changed by grouping, this will cause "
"errors when running fits with theory covmat. Datasets should "
f"be ordered by {processed_metadata_group} in the runcard.",
)
[docs]
def process_lookup(name):
"""
Returns the `nnpdf31_process` of the corresponding dataset.
"""
cd = Loader().check_commondata(setname=name)
proc = get_info(cd).nnpdf31_process
return proc