Skip to content

Commit

Permalink
Merge pull request #142 from NNPDF/fix-damping-fonll-140
Browse files Browse the repository at this point in the history
Fix condition to new damping convention
  • Loading branch information
felixhekhorn authored Dec 7, 2023
2 parents 68c41e7 + 7d5ae55 commit 054440a
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 83 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ repos:
hooks:
- id: pycln
args: [--config=pyproject.toml]
- repo: https://github.com/psf/black
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 23.11.0
hooks:
- id: black
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/bench_evolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def benchmark_write_operator_card_from_file_num_fonll(
# Check if the opcards are ok
for opcard_path, cfg in zip(
targets_path_list,
pineko.fonll.MIXED_FNS_CONFIG if is_mixed else pineko.fonll.FNS_CONFIG,
pineko.fonll.FNS_CONFIG,
):
with open(opcard_path, encoding="utf-8") as f:
ocard = yaml.safe_load(f)
Expand Down
3 changes: 1 addition & 2 deletions benchmarks/bench_fonll.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import numpy as np
import pytest
import yaml

Expand All @@ -19,7 +18,7 @@ def benchmark_produce_fonll_tcards(
base_pto = pineko.fonll.FNS_BASE_PTO[tcard["FNS"]]
for num_fonll_tcard, cfg in zip(
theorycards,
pineko.fonll.MIXED_FNS_CONFIG if is_mixed else pineko.fonll.FNS_CONFIG,
pineko.fonll.FNS_CONFIG,
):
po = int(base_pto) + (cfg.delta_pto if is_mixed else 0)
assert num_fonll_tcard["FNS"] == cfg.scheme
Expand Down
46 changes: 9 additions & 37 deletions src/pineko/cli/fonll.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,9 @@ def grids_names(yaml_file):
@click.argument("dataset", type=str)
@click.option("--FFNS3", type=int, help="theoryID containing the ffns3 fktable")
@click.option("--FFN03", type=int, help="theoryID containing the ffn03 fktable")
@click.option("--FFNS4", type=int, help="theoryID containing the ffns4 fktable")
@click.option("--FFNS4til", type=int, help="theoryID containing the ffns4til fktable")
@click.option("--FFNS4bar", type=int, help="theoryID containing the ffns4bar fktable")
@click.option("--FFN04", type=int, help="theoryID containing the ffn04 fktable")
@click.option("--FFNS5", type=int, help="theoryID containing the ffns5 fktable")
@click.option("--FFNS5til", type=int, help="theoryID containing the ffns5til fktable")
@click.option("--FFNS5bar", type=int, help="theoryID containing the ffns5bar fktable")
@click.option("--overwrite", is_flag=True, help="Allow files to be overwritten")
Expand All @@ -61,11 +59,9 @@ def subcommand(
dataset,
ffns3,
ffn03,
ffns4,
ffns4til,
ffns4bar,
ffn04,
ffns5,
ffns5til,
ffns5bar,
overwrite,
Expand All @@ -83,40 +79,18 @@ def subcommand(
if not ffns3 or not ffn03:
raise InconsistentInputsError("ffns3 and/or ffn03 is not provided.")

if any([ffns4, ffns4til, ffns4bar]):
if ffns4:
if any([ffns4til, ffns4bar]):
raise InconsistentInputsError(
"If ffns4 is provided no ffnstil or ffnsbar should be provided."
)
else:
if ffns4til is None or ffns4bar is None:
raise InconsistentInputsError(
"if ffnstil is provided also ffnsbar should be provided, and vice versa."
)
else:
raise InconsistentInputsError("ffns4 is not provided.")

# Do we consider two masses, i.e. mc and mb
two_masses = False
if any([ffns5, ffns5til, ffns5bar]):
two_masses = True
if ffns5:
if any([ffns5til, ffns5bar]):
raise InconsistentInputsError(
"If ffns5 is provided no ffnstil or ffnsbar should be provided."
)
else:
if ffns5til is None or ffns5bar is None:
raise InconsistentInputsError(
"if ffnstil is provided also ffnsbar should be provided, and vice versa."
)

if (ffn04 is None and two_masses) or (ffn04 is not None and not two_masses):
if ffns4til is None or ffns4bar is None:
raise InconsistentInputsError(
"If two masses are to be considered, both ffn04 and the nf=5 coefficient should be provided"
"At least one of ffns4til and ffns4bar should be provided."
)

# Do we consider two masses, i.e. mc and mb
if any([ffns5til, ffns5bar, ffn04]):
if (ffns5til is None and ffns5bar is None) or ffn04 is None:
raise InconsistentInputsError(
"To include nf5 contributions, ffn04 and at least one between ffns5til and ffns5bar are mandatory"
)

# Get theory info
tcard = theory_card.load(theoryid)
if tcard["DAMP"] == 1:
Expand Down Expand Up @@ -144,11 +118,9 @@ def subcommand(
for name in (
ffns3,
ffn03,
ffns4,
ffns4til,
ffns4bar,
ffn04,
ffns5,
ffns5til,
ffns5bar,
)
Expand Down
49 changes: 19 additions & 30 deletions src/pineko/fonll.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,31 +40,30 @@ class FONLLInfo:
"""Class containing all the information for FONLL predictions."""

def __init__(
self, ffns3, ffn03, ffns4, ffns4til, ffns4bar, ffn04, ffns5, ffns5til, ffns5bar
self, ffns3, ffn03, ffns4til, ffns4bar, ffn04, ffns5til, ffns5bar
) -> None:
"""Initialize fonll info."""
self.paths = {
"ffns3": ffns3,
"ffn03": ffn03,
"ffns4": ffns4,
"ffns4til": ffns4til,
"ffns4bar": ffns4bar,
"ffn04": ffn04,
"ffns5": ffns5,
"ffns5til": ffns5til,
"ffns5bar": ffns5bar,
}
actually_existing_paths = [p for p in self.paths if self.paths[p] is not None]
actually_existing_paths = [p for p, g in self.paths.items() if g is not None]
for p in self.paths:
if p not in actually_existing_paths:
logger.warning(
f"Warning! FK table for {p} does not exist and thus is being skipped."
"Warning! FK table for %s does not exist and thus is being skipped.",
p,
)

@property
def fk_paths(self):
"""Returns the list of the FK table paths needed to produce FONLL predictions."""
return {p: Path(self.paths[p]) for p in self.paths if self.paths[p] is not None}
return {p: Path(self.paths[p]) for p, g in self.paths.items() if g is not None}

@property
def fks(self):
Expand Down Expand Up @@ -106,8 +105,11 @@ def Q2grid(self):


def update_fk_theorycard(combined_fk, input_theorycard_path):
"""Update theorycard entries for the combined fktable by reading the yamldb of the original theory."""
with open(input_theorycard_path) as f:
"""Update theorycard entries for the combined FK table.
Update by reading the yamldb of the original theory.
"""
with open(input_theorycard_path, encoding="utf-8") as f:
final_theorycard = yaml.safe_load(f)
theorycard = json.loads(combined_fk.key_values()["theory"])
theorycard["FNS"] = final_theorycard["FNS"]
Expand Down Expand Up @@ -147,8 +149,8 @@ def combine(fk_dict, dampings=None):
sign = -1 if fk in FK_WITH_MINUS else 1
fk_dict[fk].scale(sign)
if dampings is not None:
for mass in FK_TO_DAMP:
if fk in FK_TO_DAMP[mass]:
for mass, fks in FK_TO_DAMP.items():
if fk in fks:
fk_dict[fk].scale_by_bin(dampings[mass])
fk_dict[fk].write_lz4(tmpfile_path)
combined_fk.merge_from_file(tmpfile_path)
Expand All @@ -158,21 +160,17 @@ def combine(fk_dict, dampings=None):
def produce_combined_fk(
ffns3,
ffn03,
ffns4,
ffns4til,
ffns4bar,
ffn04,
ffns5,
ffns5til,
ffns5bar,
theoryid,
damp=(0, None, None),
cfg=None,
):
"""Combine the FONLL FK tables into one single FK table."""
fonll_info = FONLLInfo(
ffns3, ffn03, ffns4, ffns4til, ffns4bar, ffn04, ffns5, ffns5til, ffns5bar
)
fonll_info = FONLLInfo(ffns3, ffn03, ffns4til, ffns4bar, ffn04, ffns5til, ffns5bar)
theorycard_constituent_fks = fonll_info.theorycard_no_fns_pto
fk_dict = fonll_info.fks
dampings = (
Expand Down Expand Up @@ -210,7 +208,7 @@ def scheme(self):
return "FONLL-FFN" + ("0" if self.asy else "S")


MIXED_FNS_CONFIG = [
FNS_CONFIG = [
SubTheoryConfig(False, 3, "full", 1),
SubTheoryConfig(True, 3, "full", 1),
SubTheoryConfig(False, 4, "massless"),
Expand All @@ -221,23 +219,13 @@ def scheme(self):
]
"""Mixed FONLL schemes."""

FNS_CONFIG = [
SubTheoryConfig(False, 3, "full"),
SubTheoryConfig(True, 3, "full"),
SubTheoryConfig(False, 4, "full"),
SubTheoryConfig(True, 4, "full"),
SubTheoryConfig(False, 5, "full"),
]
"""Plain FONLL schemes."""


def collect_updates(fonll_fns, damp):
def collect_updates(fonll_fns):
"""Produce the different theory cards according to which FONLL is asked for."""
updates = []
is_mixed = fonll_fns in MIXED_ORDER_FNS
is_damped = damp != 0
base_pto = FNS_BASE_PTO[fonll_fns]
cfgs = MIXED_FNS_CONFIG if is_mixed or is_damped else FNS_CONFIG
cfgs = FNS_CONFIG
for cfg in cfgs:
po = int(base_pto) + (cfg.delta_pto if is_mixed else 0)
updates.append(
Expand All @@ -260,9 +248,10 @@ def collect_updates(fonll_fns, damp):
def dump_tcards(tcard, tcard_parent_path, theoryid):
"""Produce the seven FONLL theory cards from the original one.
The produced theory cards are dumped in `tcard_parent_path` with names from '{theoryid}00.yaml' to '{theoryid}06.yaml'.
The produced theory cards are dumped in `tcard_parent_path` with names
from '{theoryid}00.yaml' to '{theoryid}06.yaml'.
"""
updates = collect_updates(tcard["FNS"], tcard["DAMP"])
updates = collect_updates(tcard["FNS"])
n_theory = len(updates)
theorycards = [copy.deepcopy(tcard) for _ in range(n_theory)]
paths_list = []
Expand Down
16 changes: 4 additions & 12 deletions tests/test_fonll.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ def test_FONLLInfo():
full_list = [
"ffns3.pineappl.lz4",
"ffn03.pineappl.lz4",
"ffns4.pineappl.lz4",
"ffns4til.pineappl.lz4",
"ffns4bar.pineappl.lz4",
"ffn04.pineappl.lz4",
"ffns5.pineappl.lz4",
"ffns5til.pineappl.lz4",
"ffns5bar.pineappl.lz4",
]
Expand All @@ -24,20 +22,16 @@ def test_FONLLInfo():
full_list[4],
None,
None,
None,
full_list[8],
)
partialfonll_fake_info = pineko.fonll.FONLLInfo(
full_list[0], full_list[1], None, full_list[3], None, None, None, None, None
full_list[0], full_list[1], full_list[2], full_list[3], None, None, None
)
name_list = [
"ffns3",
"ffn03",
"ffns4",
"ffns4til",
"ffns4bar",
"ffn04",
"ffns5",
"ffns5til",
"ffns5bar",
]
Expand All @@ -47,14 +41,12 @@ def test_FONLLInfo():
assert wrongfonll_fake_info.fk_paths == {
name: pathlib.Path(fk)
for name, fk in zip(
name_list[:2] + name_list[3:5] + [name_list[-1]],
full_list[:2] + full_list[3:5] + [full_list[-1]],
name_list[:2] + name_list[3:5],
full_list[:2] + full_list[3:5],
)
}
assert partialfonll_fake_info.fk_paths == {
name: pathlib.Path(fk)
for name, fk in zip(
name_list[:2] + name_list[3:4], full_list[:2] + full_list[3:4]
)
for name, fk in zip(name_list[:4], full_list[:4])
if fk is not None
}

0 comments on commit 054440a

Please sign in to comment.