Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions src/pineko/cli/convolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ def subcommand(
assumptions=assumptions,
comparison_pdfs=pdfs,
min_as=min_as,
grid_path=pathlib.Path(grid_path),
)

if len(operators) > 1:
Expand Down
46 changes: 43 additions & 3 deletions src/pineko/evolve.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Tools related to evolution/eko."""

import copy
import hashlib
import json
import logging
import os
Expand Down Expand Up @@ -67,7 +68,7 @@ def construct_atlas(tcard):
return atlas


def construct_empty_fktable(grid, theory_meta, fktable_path):
def construct_empty_fktable(grid, theory_meta, fktable_path, grid_path=None):
"""Construct and write a structurally valid but numerically empty FK table.

"Empty" means the FK table carries a single trivial order ``(0,0,0,0,0)``
Expand Down Expand Up @@ -113,6 +114,21 @@ def construct_empty_fktable(grid, theory_meta, fktable_path):
fktable = pineappl.fk_table.FkTable(empty_grid)
fktable.set_metadata("pineko_version", version.__version__)
fktable.set_metadata("theory_card", json.dumps(theory_meta))
if grid_path is not None:
grid_path_obj = pathlib.Path(grid_path).resolve()
grid_hash = hashlib.md5(grid_path_obj.read_bytes()).hexdigest()
grid_path_parts = grid_path_obj.parts
if "pineko" in grid_path_parts:
pineko_idx = grid_path_parts.index("pineko")
display_path = str(pathlib.Path("/", *grid_path_parts[pineko_idx + 1 :]))
elif "data" in grid_path_parts:
data_idx = grid_path_parts.index("data")
display_path = str(pathlib.Path("/", *grid_path_parts[data_idx:]))
else:
display_path = grid_path_obj.name
fktable.set_metadata("grid_hash", grid_hash)
fktable.set_metadata("grid_theory", grid_path_obj.parent.name)
fktable.set_metadata("grid_path", display_path)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. This is far too much code duplication - this needs to be encapsulated
  2. do we really need grid_path? this looks fairly complicated ...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the grids path part is a bit more complicated than needed, data/grids are not important.

Once you have the grid path, the "path of the grid itself" is grid_path.name and the theory folder grid_path.parent.name. You don't need anything else.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to simplify the metadata, using a function and calling it when the FK table is constructed (so there is no code duplication):

def set_fktable_metadata(fktable, theory_meta, grid_path=None):
    """Store the common FK metadata and, if available, grid provenance."""
    fktable.set_metadata("pineko_version", version.__version__)
    fktable.set_metadata("theory_card", json.dumps(theory_meta))
    if grid_path is None:
        return

    grid_path_obj = pathlib.Path(grid_path).resolve()
    grid_hash = hashlib.md5(grid_path_obj.read_bytes()).hexdigest()
    fktable.set_metadata("grid_hash", grid_hash)
    fktable.set_metadata("grid_theory", grid_path_obj.parent.name)
    fktable.set_metadata("grid_name", grid_path_obj.name)

For consistency I moved into the function also pineko_version and theory_card. I removed the path since the relevant information is the name of the folder, which is also the theory ID.

fktable.write_lz4(str(fktable_path))
return fktable

Expand Down Expand Up @@ -353,6 +369,7 @@ def evolve_grid(
assumptions="Nf6Ind",
comparison_pdfs: Optional[list[str]] = None,
min_as=None,
grid_path: Optional[os.PathLike] = None,
):
"""Convolute grid with EKO from file paths.

Expand Down Expand Up @@ -382,6 +399,8 @@ def evolve_grid(
if given, a comparison table (with / without evolution) will be printed
min_as: None or int
minimum power of strong coupling
grid_path : str or os.PathLike or None
path to the grid file, used to store grid hash metadata

Returns
-------
Expand All @@ -399,7 +418,9 @@ def evolve_grid(
# A grid with no orders is a valid input for some workflows. In that case we
# cannot build evolution kinematics, so we directly emit an empty FK table.
if len(grid.orders()) == 0:
fktable = construct_empty_fktable(grid, theory_meta, fktable_path)
fktable = construct_empty_fktable(
grid, theory_meta, fktable_path, grid_path=grid_path
)
return grid, fktable, None

order_mask = pineappl.boc.Order.create_mask(grid.orders(), max_as, max_al, True)
Expand All @@ -423,7 +444,9 @@ def evolve_grid(
# `XGrid` requires at least 2 points, otherwise it panics. In this case, we
# simply return an empty FK table instead.
if (len(x_grid) < 2) or (len(muf2_grid) == 0) or (len(mur2_grid) == 0):
fktable = construct_empty_fktable(grid, theory_meta, fktable_path)
fktable = construct_empty_fktable(
grid, theory_meta, fktable_path, grid_path=grid_path
)
return grid, fktable, None

xif = 1.0 if operators[0].operator_card.configs.scvar_method is not None else xif
Expand Down Expand Up @@ -510,6 +533,23 @@ def prepare(operator, convolution_types):
fktable.set_metadata("pineko_version", version.__version__)
fktable.set_metadata("theory_card", json.dumps(theory_meta))

# Store grid hash, theory folder, and repo-style grid path information
if grid_path is not None:
grid_path_obj = pathlib.Path(grid_path).resolve()
grid_hash = hashlib.md5(grid_path_obj.read_bytes()).hexdigest()
grid_path_parts = grid_path_obj.parts
if "pineko" in grid_path_parts:
pineko_idx = grid_path_parts.index("pineko")
display_path = str(pathlib.Path("/", *grid_path_parts[pineko_idx + 1 :]))
elif "data" in grid_path_parts:
data_idx = grid_path_parts.index("data")
display_path = str(pathlib.Path("/", *grid_path_parts[data_idx:]))
else:
display_path = grid_path_obj.name
fktable.set_metadata("grid_hash", grid_hash)
fktable.set_metadata("grid_theory", grid_path_obj.parent.name)
fktable.set_metadata("grid_path", display_path)

# compare before/after
comparison = None
if comparison_pdfs is not None:
Expand Down
1 change: 1 addition & 0 deletions src/pineko/theory.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ def fk(self, name, grid_path, tcard, pdfs):
theory_meta=tcard,
assumptions=assumptions,
comparison_pdfs=pdfs,
grid_path=grid_path,
)

if n_ekos > 1:
Expand Down
Loading