Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Next runcards update #295

Merged
merged 15 commits into from
Aug 9, 2024
22 changes: 0 additions & 22 deletions src/eko/io/runcards.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,28 +255,6 @@ def new_operator(self):
return OperatorCard.from_dict(new)


def update(theory: Union[RawCard, TheoryCard], operator: Union[RawCard, OperatorCard]):
"""Update legacy runcards.

This function is mainly defined for compatibility with the old interface.
Prefer direct usage of :class:`Legacy` in new code.

Consecutive applications of this function yield identical results::

cards = update(theory, operator)
assert update(*cards) == cards

"""
if isinstance(theory, TheoryCard) or isinstance(operator, OperatorCard):
# if one is not a dict, both have to be new cards
assert isinstance(theory, TheoryCard)
assert isinstance(operator, OperatorCard)
return theory, operator

cards = Legacy(theory, operator)
return cards.new_theory, cards.new_operator


def default_atlas(masses: list, matching_ratios: list):
r"""Create default landscape.

Expand Down
4 changes: 3 additions & 1 deletion src/eko/runner/legacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import os
from typing import Union

from ekomark.data import update_runcards

from ..evolution_operator.grid import OperatorGrid
from ..io import EKO, Operator, runcards
from ..io.types import RawCard
Expand Down Expand Up @@ -43,7 +45,7 @@ def __init__(
path where to store the computed operator

"""
new_theory, new_operator = runcards.update(theory_card, operators_card)
new_theory, new_operator = update_runcards(theory_card, operators_card)

# Store inputs
self.path = path
Expand Down
28 changes: 28 additions & 0 deletions src/ekomark/data/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,29 @@
"""EKO database configuration."""
from typing import Union

from eko.io.runcards import Legacy, OperatorCard, TheoryCard
from eko.io.types import RawCard


def update_runcards(
felixhekhorn marked this conversation as resolved.
Show resolved Hide resolved
theory: Union[RawCard, TheoryCard], operator: Union[RawCard, OperatorCard]
):
"""Update legacy runcards.

This function is mainly defined for compatibility with the old interface.
Prefer direct usage of :class:`Legacy` in new code.

Consecutive applications of this function yield identical results::

cards = update(theory, operator)
assert update(*cards) == cards

"""
if isinstance(theory, TheoryCard) or isinstance(operator, OperatorCard):
# if one is not a dict, both have to be new cards
assert isinstance(theory, TheoryCard)
assert isinstance(operator, OperatorCard)
return theory, operator

cards = Legacy(theory, operator)
return cards.new_theory, cards.new_operator
88 changes: 0 additions & 88 deletions tests/eko/io/test_runcards.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import copy
from io import StringIO

import numpy as np
import pytest
import yaml
from banana.data.theories import default_card as theory_card

from eko.io import runcards as rc
from eko.io.bases import Bases
from ekomark.data.operators import default_card as operator_card


def test_flavored_mu2grid():
Expand All @@ -31,48 +28,6 @@ def test_flavored_mu2grid():
assert t == tuple(l)


def test_runcards_opcard():
# check conversion
tc = copy.deepcopy(theory_card)
oc = copy.deepcopy(operator_card)
tc["Q0"] = 2.0
# mugrid
oc["mugrid"] = [2.0, 10.0]
_nt, no = rc.update(tc, oc)
assert isinstance(no, rc.OperatorCard)
assert len(no.evolgrid) == len(oc["mugrid"])
assert len(no.mu2grid) == len(no.evolgrid)
assert no.evolgrid[0][-1] == 4
assert no.evolgrid[1][-1] == 5
np.testing.assert_allclose(no.mu0, tc["Q0"])
np.testing.assert_allclose(no.mu20, tc["Q0"] ** 2.0)
assert len(no.pids) == 14
check_dumpable(no)
del oc["mugrid"]
# or mu2grid
oc["mu2grid"] = [9.0, 30.0, 32.0]
_nt, no = rc.update(tc, oc)
assert isinstance(no, rc.OperatorCard)
assert len(no.evolgrid) == len(oc["mu2grid"])
assert len(no.mu2grid) == len(no.evolgrid)
assert no.evolgrid[0][-1] == 4
assert no.evolgrid[1][-1] == 5
assert no.evolgrid[2][-1] == 5
check_dumpable(no)
del oc["mu2grid"]
# or Q2grid
oc["Q2grid"] = [15.0, 130.0, 140.0, 1e5]
_nt, no = rc.update(tc, oc)
assert isinstance(no, rc.OperatorCard)
assert len(no.evolgrid) == len(oc["Q2grid"])
assert len(no.mu2grid) == len(no.evolgrid)
assert no.evolgrid[0][-1] == 4
assert no.evolgrid[1][-1] == 5
assert no.evolgrid[2][-1] == 5
assert no.evolgrid[3][-1] == 6
check_dumpable(no)


def check_dumpable(no):
"""Check we can write and read to yaml."""
so = StringIO()
Expand All @@ -81,49 +36,6 @@ def check_dumpable(no):
noo = yaml.safe_load(so)


def test_runcards_ekomark():
# check conversion
tc = copy.deepcopy(theory_card)
oc = copy.deepcopy(operator_card)
nt, no = rc.update(tc, oc)
assert isinstance(nt, rc.TheoryCard)
assert isinstance(no, rc.OperatorCard)
# check is idempotent
nnt, nno = rc.update(nt, no)
assert nnt == nt
assert nno == no


def test_runcards_quarkmass():
tc = copy.deepcopy(theory_card)
tc["nfref"] = 5
tc["IC"] = 1
oc = copy.deepcopy(operator_card)
nt, no = rc.update(tc, oc)
for _, scale in nt.heavy.masses:
assert np.isnan(scale)
m2s = rc.masses(nt, no.configs.evolution_method)
raw = rc.Legacy.heavies("m%s", tc)
raw2 = np.power(raw, 2.0)
np.testing.assert_allclose(m2s, raw2)
tc["HQ"] = "MSBAR"
tc["Qmc"] = raw[0] * 1.1
tc["Qmb"] = raw[1] * 1.1
tc["Qmt"] = raw[2] * 0.9
nt, no = rc.update(tc, oc)
for _, scale in nt.heavy.masses:
assert not np.isnan(scale)
m2s = rc.masses(nt, no.configs.evolution_method)
for m1, m2 in zip(m2s, raw2):
assert not np.isclose(m1, m2)
tc["HQ"] = "Blub"
with pytest.raises(ValueError, match="mass scheme"):
_nt, _no = rc.update(tc, oc)
nt.heavy.masses_scheme = "Bla"
with pytest.raises(ValueError, match="mass scheme"):
_ms = rc.masses(nt, no.configs.evolution_method)


def test_legacy_fallback():
assert rc.Legacy.fallback(1, 2, 3) == 1
assert rc.Legacy.fallback(None, 2, 3) == 2
Expand Down
Empty file added tests/ekomark/data/__init__.py
Empty file.
96 changes: 96 additions & 0 deletions tests/ekomark/data/test_init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import copy

import numpy as np
import pytest
from banana.data.theories import default_card as theory_card

from eko.io import runcards as rc
from ekomark.data import update_runcards
from ekomark.data.operators import default_card as operator_card

from ...eko.io.test_runcards import check_dumpable


def test_runcards_opcard():
# check conversion
tc = copy.deepcopy(theory_card)
oc = copy.deepcopy(operator_card)
tc["Q0"] = 2.0
# mugrid
oc["mugrid"] = [2.0, 10.0]
_nt, no = update_runcards(tc, oc)
assert isinstance(no, rc.OperatorCard)
assert len(no.evolgrid) == len(oc["mugrid"])
assert len(no.mu2grid) == len(no.evolgrid)
assert no.evolgrid[0][-1] == 4
assert no.evolgrid[1][-1] == 5
np.testing.assert_allclose(no.mu0, tc["Q0"])
np.testing.assert_allclose(no.mu20, tc["Q0"] ** 2.0)
assert len(no.pids) == 14
check_dumpable(no)
del oc["mugrid"]
# or mu2grid
oc["mu2grid"] = [9.0, 30.0, 32.0]
_nt, no = update_runcards(tc, oc)
assert isinstance(no, rc.OperatorCard)
assert len(no.evolgrid) == len(oc["mu2grid"])
assert len(no.mu2grid) == len(no.evolgrid)
assert no.evolgrid[0][-1] == 4
assert no.evolgrid[1][-1] == 5
assert no.evolgrid[2][-1] == 5
check_dumpable(no)
del oc["mu2grid"]
# or Q2grid
oc["Q2grid"] = [15.0, 130.0, 140.0, 1e5]
_nt, no = update_runcards(tc, oc)
assert isinstance(no, rc.OperatorCard)
assert len(no.evolgrid) == len(oc["Q2grid"])
assert len(no.mu2grid) == len(no.evolgrid)
assert no.evolgrid[0][-1] == 4
assert no.evolgrid[1][-1] == 5
assert no.evolgrid[2][-1] == 5
assert no.evolgrid[3][-1] == 6
check_dumpable(no)


def test_runcards_ekomark():
# check conversion
tc = copy.deepcopy(theory_card)
oc = copy.deepcopy(operator_card)
nt, no = update_runcards(tc, oc)
assert isinstance(nt, rc.TheoryCard)
assert isinstance(no, rc.OperatorCard)
# check is idempotent
nnt, nno = update_runcards(nt, no)
assert nnt == nt
assert nno == no


def test_runcards_quarkmass():
tc = copy.deepcopy(theory_card)
tc["nfref"] = 5
tc["IC"] = 1
oc = copy.deepcopy(operator_card)
nt, no = update_runcards(tc, oc)
for _, scale in nt.heavy.masses:
assert np.isnan(scale)
m2s = rc.masses(nt, no.configs.evolution_method)
raw = rc.Legacy.heavies("m%s", tc)
raw2 = np.power(raw, 2.0)
np.testing.assert_allclose(m2s, raw2)
tc["HQ"] = "MSBAR"
tc["Qmc"] = raw[0] * 1.1
tc["Qmb"] = raw[1] * 1.1
tc["Qmt"] = raw[2] * 0.9
nt, no = update_runcards(tc, oc)
for _, scale in nt.heavy.masses:
assert not np.isnan(scale)
m2s = rc.masses(nt, no.configs.evolution_method)
for m1, m2 in zip(m2s, raw2):
assert not np.isclose(m1, m2)
tc["HQ"] = "Blub"
with pytest.raises(ValueError, match="mass scheme"):
_nt, _no = update_runcards(tc, oc)
nt.heavy.masses_scheme = "Bla"
with pytest.raises(ValueError, match="mass scheme"):
_ms = rc.masses(nt, no.configs.evolution_method)