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

Support eko 0.15 #205

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 25 additions & 10 deletions benchmarks/bench_checks.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import eko
import numpy as np
import pineappl
import pytest
from eko.io import manipulate

import pineko.check

Expand All @@ -16,12 +16,27 @@ def benchmark_check_grid_and_eko_compatible(test_files, tmp_path):
with eko.EKO.edit(
test_files / "data/ekos/400/HERA_NC_225GEV_EP_SIGMARED.tar"
) as ekoop:
with pytest.raises(ValueError):
pineko.check.check_grid_and_eko_compatible(wrong_grid, ekoop, 1.0, 3, 3)
pineko.check.check_grid_and_eko_compatible(grid, ekoop, 1.0, 3, 3)
eko.io.manipulate.xgrid_reshape(
ekoop, targetgrid=eko.interpolation.XGrid([0.0001, 0.001, 0.1, 0.5, 1.0])
)
with pytest.raises(ValueError):
pineko.check.check_grid_and_eko_compatible(grid, ekoop, 1.0, 10, 10)
eko.io.manipulate.xgrid_reshape(ekoop, targetgrid=ekoop.xgrid)
eko_xgrid = ekoop.xgrid.tolist()
for (eko_mu2, _), _ in ekoop.items():
with pytest.raises(ValueError):
pineko.check.check_grid_and_eko_compatible(
wrong_grid, eko_xgrid, eko_mu2, 1.0, 3, 3
)
pineko.check.check_grid_and_eko_compatible(
grid, eko_xgrid, eko_mu2, 1.0, 3, 3
)

# test a wrong rotation
wrong_xgrid = eko.interpolation.XGrid([0.0001, 0.001, 0.1, 0.5, 1.0])
for (eko_mu2, _), op in ekoop.items():
# TODO: here we can only check inputgrid as this eko has dimension (14,40,14,50)
# and ekoop.xgrid has 50
op = manipulate.xgrid_reshape(op, ekoop.xgrid, 4, inputgrid=wrong_xgrid)
assert op.operator.shape[-1] == len(wrong_xgrid)
with pytest.raises(ValueError):
pineko.check.check_grid_and_eko_compatible(
grid, wrong_xgrid.tolist(), eko_mu2, 1.0, 10, 10
)
# restore xgrid
op = manipulate.xgrid_reshape(op, wrong_xgrid, 4, inputgrid=ekoop.xgrid)
assert op.operator.shape[-1] == len(ekoop.xgrid)
3 changes: 1 addition & 2 deletions benchmarks/bench_cli.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import pathlib
import shutil

import lhapdf
from click.testing import CliRunner

from pineko.cli._base import command
Expand All @@ -19,7 +18,7 @@ def benchmark_check_cli(test_files):
result = runner.invoke(
command, ["check", "compatibility", str(grid_path), str(eko_path)]
)
assert "Success: grids are compatible" in result.output
assert "Success: grids and eko are compatible" in result.output
wrong_result = runner.invoke(
command, ["check", "compatibility", str(wrong_grid_path), str(eko_path)]
)
Expand Down
1 change: 0 additions & 1 deletion benchmarks/bench_evolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import pathlib

import eko
import eko.io.legacy
import numpy as np
import pineappl
import pytest
Expand Down
7 changes: 4 additions & 3 deletions benchmarks/bench_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ def xfxQ2(self, pid, x, q2):

def _trim_template(template_card, take_points=10):
"""Trim the template card so that the number of x-values to compute is much smaller"""
card_info = OperatorCard.from_dict(
safe_load(template_card.read_text(encoding="utf-8"))
)
raw_card = safe_load(template_card.read_text(encoding="utf-8"))
raw_card["init"] = (raw_card["mu0"], 4)
del raw_card["mu0"]
card_info = OperatorCard.from_dict(raw_card)
original_x = card_info.xgrid
size = len(original_x.raw)
skip = int(size / take_points)
Expand Down
4 changes: 3 additions & 1 deletion docs/source/overview/prerequisites.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ An example is the following::
polarized: False
time_like: False
n_integration_cores: 1
mu0: 1.65
init:
- 1.65
- 4
mugrid:
- - 50.0
- 5
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ packages = [{ include = "pineko", from = "src" }]

[tool.poetry.dependencies]
python = ">=3.9,<3.13"
eko = "^0.14.2"
pineappl = "^0.8.2"
eko = "^0.15.0"
pineappl = "^0.8.6"
PyYAML = "^6.0"
numpy = "^1.21.0"
pandas = "^2.1"
Expand Down
22 changes: 11 additions & 11 deletions src/pineko/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,19 @@ def in1d(a, b, rtol=1e-05, atol=1e-08):
)


def check_grid_and_eko_compatible(pineappl_grid, operators, xif, max_as, max_al):
"""Check whether the EKO operators and the PineAPPL grid are compatible.
def check_grid_and_eko_compatible(
pineappl_grid, eko_xgrid, eko_mu2, xif, max_as, max_al
):
"""Check whether the EKO operator and the PineAPPL grid are compatible.

Parameters
----------
pineappl_grid : pineappl.grid.Grid
grid
operators : eko.EKO
operators
eko_xgrid : list
eko interpolation xgrid
eko_mu2: float
eko mu2 scale
xif : float
factorization scale variation
max_as: int
Expand All @@ -95,7 +99,7 @@ def check_grid_and_eko_compatible(pineappl_grid, operators, xif, max_as, max_al)
Raises
------
ValueError
If the operators and the grid are not compatible.
If the operator and the grid are not compatible.
"""
order_mask = pineappl.grid.Order.create_mask(
pineappl_grid.orders(), max_as, max_al, True
Expand All @@ -104,16 +108,12 @@ def check_grid_and_eko_compatible(pineappl_grid, operators, xif, max_as, max_al)
x_grid = evol_info.x1
muf2_grid = evol_info.fac1
# Q2 grid
if not np.all(
in1d(np.unique(list(operators.mu2grid)), xif * xif * np.array(muf2_grid))
):
if not np.all(in1d(np.array([eko_mu2]), xif * xif * np.array(muf2_grid))):
raise ValueError(
"Q2 grid in pineappl grid and eko operator are NOT compatible!"
)
# x-grid
if not np.all(
in1d(np.unique(operators.bases.targetgrid.tolist()), np.array(x_grid))
):
if not np.all(in1d(np.unique(eko_xgrid), np.array(x_grid))):
raise ValueError("x grid in pineappl grid and eko operator are NOT compatible!")


Expand Down
16 changes: 9 additions & 7 deletions src/pineko/cli/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,16 @@ def sub_compatibility(grid_path, operator_path, xif, max_as, max_al):

"""
pineappl_grid = pineappl.grid.Grid.read(grid_path)
pineappl_grid.optimize()
with eko.EKO.read(operator_path) as operators:
try:
check.check_grid_and_eko_compatible(
pineappl_grid, operators, xif, max_as, max_al
)
rich.print("[green]Success:[/] grids are compatible")
except ValueError as e:
rich.print("[red]Error:[/]", e)
for (q2, _), _ in operators.items():
try:
check.check_grid_and_eko_compatible(
pineappl_grid, operators.xgrid.tolist(), q2, xif, max_as, max_al
)
except ValueError as e:
rich.print("[red]Error:[/]", e)
rich.print("[green]Success:[/] grids and eko are compatible.")


@dataclass
Expand Down
1 change: 1 addition & 0 deletions src/pineko/cli/convolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ def subcommand(
PDF is an optional PDF set compatible with the EKO to compare grid and FK table.
"""
grid = pineappl.grid.Grid.read(grid_path)
grid.optimize()
n_ekos = len(op_paths)
with eko.EKO.edit(op_paths[0]) as operators1:
rich.print(
Expand Down
65 changes: 28 additions & 37 deletions src/pineko/evolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import rich.panel
import yaml
from eko import basis_rotation
from eko.interpolation import XGrid
from eko.io import manipulate
from eko.io.types import ScaleVariationsMethod
from eko.matchings import Atlas, nf_default
from eko.quantities import heavy_quarks
Expand Down Expand Up @@ -124,9 +126,11 @@ def write_operator_card_from_file(
if not pathlib.Path(pineappl_path).exists():
raise FileNotFoundError(pineappl_path)
pineappl_grid = pineappl.grid.Grid.read(pineappl_path)
pineappl_grid.optimize()
default_card = yaml.safe_load(
pathlib.Path(default_card_path).read_text(encoding="utf-8")
)

return write_operator_card(pineappl_grid, default_card, card_path, tcard)


Expand Down Expand Up @@ -201,10 +205,12 @@ def write_operator_card(pineappl_grid, default_card, card_path, tcard):
# update scale variation method
operators_card["configs"]["scvar_method"] = sv_method

# Make sure that we are using the theory Q0 and fail if the template has a different one
operators_card["mu0"] = tcard["Q0"]
if default_card.get("mu0") is not None and default_card["mu0"] != tcard["Q0"]:
raise ValueError("Template declares a value of Q0 different from theory")
operators_card["init"] = (tcard["Q0"], tcard["nf0"])
if default_card.get("init") is not None and default_card["init"] != [
tcard["Q0"],
tcard["nf0"],
]:
raise ValueError("Template declares a value of Q0, nf0 different from theory")

q2_grid = (xif * xif * muf2_grid).tolist()
masses = np.array([tcard["mc"], tcard["mb"], tcard["mt"]]) ** 2
Expand Down Expand Up @@ -353,40 +359,19 @@ def evolve_grid(

evol_info = grid.evolve_info(order_mask)
x_grid = evol_info.x1
if "integrability_version" in grid.key_values():
x_grid = np.append(x_grid, 1.0)

mur2_grid = evol_info.ren1
xif = 1.0 if operators1.operator_card.configs.scvar_method is not None else xif
tcard = operators1.theory_card
opcard = operators1.operator_card
# rotate the targetgrid
if "integrability_version" in grid.key_values():
x_grid = np.append(x_grid, 1.0)

def xgrid_reshape(full_operator):
"""Reinterpolate operators on output and/or input grids."""
eko.io.manipulate.xgrid_reshape(
full_operator, targetgrid=eko.interpolation.XGrid(x_grid)
)
check.check_grid_and_eko_compatible(grid, full_operator, xif, max_as, max_al)
# rotate to evolution (if doable and necessary)
if np.allclose(full_operator.bases.inputpids, br.flavor_basis_pids):
eko.io.manipulate.to_evol(full_operator)
# Here we are checking if the EKO contains the rotation matrix (flavor to evol)
elif not np.allclose(
full_operator.bases.inputpids, br.rotate_flavor_to_evolution
):
raise ValueError("The EKO is neither in flavor nor in evolution basis.")

xgrid_reshape(operators1)
if operators2 is not None:
xgrid_reshape(operators2)

# PineAPPL wants alpha_s = 4*pi*a_s
# remember that we already accounted for xif in the opcard generation
evmod = eko.couplings.couplings_mod_ev(opcard.configs.evolution_method)
# Couplings ask for the square of the masses
thresholds_ratios = np.power(tcard.heavy.matching_ratios, 2.0)
for q in range(tcard.couplings.max_num_flavs + 1, 6 + 1):
thresholds_ratios[q - 4] = np.inf
sc = eko.couplings.Couplings(
tcard.couplings,
tcard.order,
Expand All @@ -398,25 +383,31 @@ def xgrid_reshape(full_operator):
# To compute the alphas values we are first reverting the factorization scale shift
# and then obtaining the renormalization scale using xir.
ren_grid2 = xir * xir * mur2_grid
nfgrid = [x[1] for x in operators1.operator_card.mugrid]
alphas_values = [
4.0
* np.pi
* sc.a_s(
mur2,
)
for mur2 in ren_grid2
4.0 * np.pi * sc.a_s(mur2, nf_to=nf) for mur2, nf in zip(ren_grid2, nfgrid)
]

def prepare(operator):
"""Match the raw operator with its relevant metadata."""
for (q2, _), op in operator.items():
# reshape the x-grid output
op = manipulate.xgrid_reshape(
op,
operator.xgrid,
opcard.configs.interpolation_polynomial_degree,
targetgrid=XGrid(x_grid),
)
# rotate the input to evolution basis
op = manipulate.to_evol(op, source=True)
check.check_grid_and_eko_compatible(grid, x_grid, q2, xif, max_as, max_al)
info = PyOperatorSliceInfo(
fac0=operator.mu20,
x0=operator.bases.inputgrid.raw,
x0=operator.xgrid.tolist(),
pids0=basis_rotation.evol_basis_pids,
fac1=q2,
x1=operator.bases.targetgrid.raw,
pids1=operator.bases.targetpids,
x1=x_grid.tolist(),
pids1=basis_rotation.flavor_basis_pids,
pid_basis=PyPidBasis.Evol,
)
yield (info, op.operator)
Expand Down
1 change: 0 additions & 1 deletion src/pineko/theory.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import time

import eko
import eko.io.legacy
import numpy as np
import pineappl
import rich
Expand Down
12 changes: 6 additions & 6 deletions tests/test_evolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,20 @@ def test_write_operator_card_q0(tmp_path):
g = FakePine()
t = copy.deepcopy(default_card)
o = copy.deepcopy(example.raw_operator())
# 1. Same Q0 and mu0, all ok
# 1. Same Q0 and init, all ok
t["Q0"] = 5.0
o["mu0"] = 5.0
o["init"] = [5.0, 4]
_xs, _mu2s = pineko.evolve.write_operator_card(g, o, p, t)
with open(p, encoding="utf8") as f:
oo = yaml.safe_load(f)
np.testing.assert_allclose(oo["mu0"], t["Q0"])
np.testing.assert_allclose(oo["init"][0], t["Q0"])
# 2. Q0 only in theory, all ok
o.pop("mu0")
o.pop("init")
_xs, _mu2s = pineko.evolve.write_operator_card(g, o, p, t)
with open(p, encoding="utf8") as f:
oo = yaml.safe_load(f)
np.testing.assert_allclose(oo["mu0"], t["Q0"])
np.testing.assert_allclose(oo["init"][0], t["Q0"])
# 3. op is different, raises error
o["mu0"] = 11.0
o["init"] = [11.0, 3]
with pytest.raises(ValueError):
_xs, _mu2s = pineko.evolve.write_operator_card(g, o, p, t)
Loading