Skip to content

Commit

Permalink
update ekocompatibility layout
Browse files Browse the repository at this point in the history
  • Loading branch information
giacomomagni committed Jul 16, 2024
1 parent 9137643 commit d62dac4
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 26 deletions.
35 changes: 16 additions & 19 deletions src/pineko/ekompatibility.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
"""Compatibility layer for EKO migration."""

from typing import Any, Dict

from eko import EKO, basis_rotation
from pineappl.grid import PyOperatorSliceInfo, PyPidBasis


def pineappl_layout(operator: EKO) -> Dict[str, Any]:
"""Extract information required by :func:`pineappl.grid.Grid.convolute_eko`.
def pineappl_layout(operator: EKO) -> list:
"""Extract information required by :func:`pineappl.grid.Grid.convolve_eko`.
Parameters
----------
Expand All @@ -19,18 +18,16 @@ def pineappl_layout(operator: EKO) -> Dict[str, Any]:
a minimal object, with all and only the information consumed by PineAPPL
"""
oldgrid = {}
oldgrid["Q2grid"] = {}
for q2, op in operator.items():
oldop = dict(operators=op.operator)
oldgrid["Q2grid"][q2[0]] = oldop

oldgrid["q2_ref"] = operator.mu20
oldgrid["targetpids"] = operator.bases.targetpids
oldgrid["targetgrid"] = operator.bases.targetgrid.raw
# The EKO contains the rotation matrix but we pass the list of
# evol basis pids to pineappl.
oldgrid["inputpids"] = basis_rotation.evol_basis_pids
oldgrid["inputgrid"] = operator.bases.inputgrid.raw

return oldgrid
eko_iterator = []
for (q2, _), op in operator.items():
info = PyOperatorSliceInfo(
fac0=operator.mu20,
x0=operator.bases.inputgrid.raw,
pids0=basis_rotation.evol_basis_pids,
fac1=q2,
x1=operator.bases.targetgrid.raw,
pids1=operator.bases.targetpids,
pid_basis=PyPidBasis.Pdg,
)
eko_iterator.append((info, op.operator))
return eko_iterator
16 changes: 9 additions & 7 deletions src/pineko/evolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from eko.io.types import ScaleVariationsMethod
from eko.matchings import Atlas, nf_default
from eko.quantities import heavy_quarks
from pineappl.fk_table import PyFkAssumptions

from . import check, comparator, ekompatibility, version

Expand Down Expand Up @@ -285,11 +286,11 @@ def evolve_grid(
Parameters
----------
grid : pineappl.grid.Grid
unconvoluted grid
unconvolved grid
operators_a : eko.EKO
evolution operator
fktable_path : str
target path for convoluted grid
target path for convolved grid
max_as : int
maximum power of strong coupling
max_al : int
Expand Down Expand Up @@ -372,21 +373,22 @@ def xgrid_reshape(operators):
# We need to use ekompatibility in order to pass a dictionary to pineappl
if operators_b is not None:
fktable = grid.evolve_with_slice_iter2(
ekompatibility.pineappl_layout(operators_a),
ekompatibility.pineappl_layout(operators_b),
iter(ekompatibility.pineappl_layout(operators_a)),
iter(ekompatibility.pineappl_layout(operators_b)),
alphas_table=alphas_values,
xi=(xir, xif),
order_mask=order_mask,
)
else:
fktable = grid.evolve_with_slice_iter(
ekompatibility.pineappl_layout(operators_a),
alphas_table=alphas_values,
iter(ekompatibility.pineappl_layout(operators_a)),

This comment has been minimized.

Copy link
@cschwan

cschwan Jul 16, 2024

Contributor

@giacomomagni @felixhekhorn @alecandido is this the most efficient way to pass the EKO slices? It seems you construct the 5D EKO with pineappl_layout and then convert them into 4D slices again with iter().

This comment has been minimized.

Copy link
@alecandido

alecandido Jul 16, 2024

Member

I would say it is not, and ekompatibility was a compatibility layer created because PineAPPL did not support 4D slices, with the intention to drop it as soon as the support would have landed (since EKO and PineAPPL are expected to be as much interoperable as possible, without the need of rearranging elements).

Not sure why it is still there.

This comment has been minimized.

Copy link
@cschwan

cschwan Jul 16, 2024

Contributor

I suppose it's there because the first aim was to see whether it works. If that's the case I propose to make it efficient.

This comment has been minimized.

Copy link
@felixhekhorn

felixhekhorn Jul 17, 2024

Contributor

@giacomomagni you can do e.g. something like this for ekompatibility.pineappl_layout

a = {(10.,5): "a",(20.,6):"b"}
b = map(lambda s,q2nf:f"{q2nf[0]} - {s}", a.values(), a.keys() )
for e in b: print(e)

This comment has been minimized.

Copy link
@giacomomagni

giacomomagni Jul 17, 2024

Author Contributor

but then one still have to construct the PyOperatorSliceInfo object, as this is not available in EKO no?

This comment has been minimized.

Copy link
@felixhekhorn

felixhekhorn Jul 17, 2024

Contributor

yesyes that's why I said "something like" 🙃 here you go

def prepare(op, q2nf):
        info = PyOperatorSliceInfo(
            fac0=operator.mu20,
            x0=operator.bases.inputgrid.raw,
            pids0=basis_rotation.evol_basis_pids,
            fac1=q2nf[0],
            x1=operator.bases.targetgrid.raw,
            pids1=operator.bases.targetpids,
            pid_basis=PyPidBasis.Pdg,
        )
        return (info, op.operator)
return map(prepare, operator.values(), operator.keys() )

but watch out! I wrote this completely blind 🙈 (what could possibly go wrong)

This comment has been minimized.

Copy link
@giacomomagni

giacomomagni Jul 17, 2024

Author Contributor

Thanks, indeed EKO object has no attribute values,keys, moreover one would need to pass also operator to the function prepare... in any case here it is b1c8c78

ren1=mur2_grid,
alphas=alphas_values,
xi=(xir, xif),
order_mask=order_mask,
)
rich.print(f"Optimizing for {assumptions}")
fktable.optimize(assumptions)
fktable.optimize(PyFkAssumptions(assumptions))
fktable.set_key_value("eko_version", operators_a.metadata.version)
fktable.set_key_value("eko_theory_card", json.dumps(operators_a.theory_card.raw))

Expand Down

0 comments on commit d62dac4

Please sign in to comment.