From 250fbc12c7035732a0d63effbebae2db107c15a6 Mon Sep 17 00:00:00 2001 From: juacrumar Date: Tue, 28 Oct 2025 15:11:10 +0100 Subject: [PATCH 1/3] Move the scale variation check to the operator card creation --- src/pineko/theory.py | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/pineko/theory.py b/src/pineko/theory.py index 8286fabe..6c38f65f 100644 --- a/src/pineko/theory.py +++ b/src/pineko/theory.py @@ -23,6 +23,29 @@ logger = logging.getLogger(__name__) +def _check_for_scale_variations(tcard, grid_path): + """Check that the grid is compatible with the requested scale_variations (if any). + + Parameters + ---------- + tcard : dict + theory card + grid_path : pathlib.Path + path to grid + """ + grid = pineappl.grid.Grid.read(grid_path) + xir = tcard["XIR"] + xif = tcard["XIF"] + max_al = 0 # We don't do SV for alpha + max_as = 1 + int(tcard["PTO"]) + # In FONLL-B we might need to change max_as + max_as += int(check.is_fonll_mixed(tcard["FNS"], grid.convolutions)) + if not np.isclose(xir, 1.0): + check_scvar_evolve(grid, max_as, max_al, check.Scale.REN) + if not np.isclose(xif, 1.0) and evolve.sv_scheme(tcard) is None: + check_scvar_evolve(grid, max_as, max_al, check.Scale.FACT) + + def get_eko_names(grid_path, name, filter=True): """Get the names of the ekos depending on the types of convolutions. @@ -276,6 +299,9 @@ def opcard(self, name, grid, tcard): tcard : dict theory card """ + # Before creating the operator card, check whether this grid is legal or not + _check_for_scale_variations(tcard, grid) + opcard_path = self.operator_cards_path / f"{name}.yaml" if opcard_path.exists(): if not self.overwrite: @@ -436,7 +462,6 @@ def fk(self, name, grid_path, tcard, pdfs): # check if grid contains SV if theory is requesting them (in particular # if theory is requesting scheme A or C) - sv_method = evolve.sv_scheme(tcard) xir = tcard["XIR"] xif = tcard["XIF"] xia = 1.0 # TODO: modify into `tcard["XIA"]` @@ -473,12 +498,6 @@ def fk(self, name, grid_path, tcard, pdfs): rich.print("[green] Skipping empty grid.") return - # check for sv - if not np.isclose(xir, 1.0): - check_scvar_evolve(grid, max_as, max_al, check.Scale.REN) - if sv_method is None: - if not np.isclose(xif, 1.0): - check_scvar_evolve(grid, max_as, max_al, check.Scale.FACT) # TODO: Add fragmentation scale variations # loading ekos to produce a tmp copy n_ekos = len(eko_filename) From 0d12492f7a0cca74b858aadee0d2f13d3bf004b6 Mon Sep 17 00:00:00 2001 From: "Juan M. Cruz-Martinez" Date: Wed, 29 Oct 2025 16:20:31 +0100 Subject: [PATCH 2/3] Update src/pineko/theory.py Co-authored-by: Felix Hekhorn --- src/pineko/theory.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pineko/theory.py b/src/pineko/theory.py index 6c38f65f..5cb53f78 100644 --- a/src/pineko/theory.py +++ b/src/pineko/theory.py @@ -39,7 +39,8 @@ def _check_for_scale_variations(tcard, grid_path): max_al = 0 # We don't do SV for alpha max_as = 1 + int(tcard["PTO"]) # In FONLL-B we might need to change max_as - max_as += int(check.is_fonll_mixed(tcard["FNS"], grid.convolutions)) + if check.is_fonll_mixed(tcard["FNS"], grid.convolutions): + max_as += 1 if not np.isclose(xir, 1.0): check_scvar_evolve(grid, max_as, max_al, check.Scale.REN) if not np.isclose(xif, 1.0) and evolve.sv_scheme(tcard) is None: From 7e8372ddbc1c9e6f5d89b28e3320b5ef0c358cd8 Mon Sep 17 00:00:00 2001 From: juacrumar Date: Tue, 4 Nov 2025 13:43:32 +0100 Subject: [PATCH 3/3] remove delete --- src/pineko/fonll.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pineko/fonll.py b/src/pineko/fonll.py index b3b250e5..e9fe54ea 100644 --- a/src/pineko/fonll.py +++ b/src/pineko/fonll.py @@ -137,7 +137,6 @@ def theorycard_no_fns_pto(self): continue if card[key] != theorycards[0][key]: differ.append(key) - del theorycards[0][key] if len(differ) > 0: raise ValueError(