From dd2cb069040a918baa8faf5e2e0936e4c8824167 Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Fri, 23 May 2025 17:18:34 +0200 Subject: [PATCH 01/20] Introduction of template.py to contain constants and xgrid --- src/pineko/template.py | 102 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/pineko/template.py diff --git a/src/pineko/template.py b/src/pineko/template.py new file mode 100644 index 00000000..aeea8802 --- /dev/null +++ b/src/pineko/template.py @@ -0,0 +1,102 @@ +"""Default settings and interpolation xgrid (previously in _template.yaml).""" + +from eko.interpolation import XGrid + +# Define the interpolation x-grid as previously defined as 'xgrid' in _template.yaml +INTERPOLATION_XGRID = XGrid( + [1.9999999999999954e-07, + 3.034304765867952e-07, + 4.6035014748963906e-07, + 6.984208530700364e-07, + 1.0596094959101024e-06, + 1.607585498470808e-06, + 2.438943292891682e-06, + 3.7002272069854957e-06, + 5.613757716930151e-06, + 8.516806677573355e-06, + 1.292101569074731e-05, + 1.9602505002391748e-05, + 2.97384953722449e-05, + 4.511438394964044e-05, + 6.843744918967896e-05, + 0.00010381172986576898, + 0.00015745605600841445, + 0.00023878782918561914, + 0.00036205449638139736, + 0.0005487795323670796, + 0.0008314068836488144, + 0.0012586797144272762, + 0.0019034634022867384, + 0.0028738675812817515, + 0.004328500638820811, + 0.006496206194633799, + 0.009699159574043398, + 0.014375068581090129, + 0.02108918668378717, + 0.030521584007828916, + 0.04341491741702269, + 0.060480028754447364, + 0.08228122126204893, + 0.10914375746330703, + 0.14112080644440345, + 0.17802566042569432, + 0.2195041265003886, + 0.2651137041582823, + 0.31438740076927585, + 0.3668753186482242, + 0.4221667753589648, + 0.4798989029610255, + 0.5397572337880445, + 0.601472197967335, + 0.6648139482473823, + 0.7295868442414312, + 0.7956242522922756, + 0.8627839323906108, + 0.9309440808717544, + 1] + ) + +# Define some default parameters + +CONSTANTS = { + "configs": { + "ev_op_iterations": 1, + "ev_op_max_order": (10,1), + "evolution_method": iterate-exact, + "interpolation_is_log": true, + "interpolation_polynomial_degree": 4, + "inversion_method": expanded, + "n_integration_cores": 1, + "polarized": false, + "scvar_method": null, + "time_like": false + }, + "debug": { + "skip_non_singlet": false, + "skip_singlet": false + }, + "eko_version": 0.14.2, + "mu0": 0, +} + + + + + + + + + + + + + + + + + + + + + + From 51eb28bf7cb11ff27d39461c09815df589357eb8 Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Fri, 23 May 2025 17:25:43 +0200 Subject: [PATCH 02/20] Introduction of template.py to contain constants and xgrid --- src/pineko/template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pineko/template.py b/src/pineko/template.py index aeea8802..68b31b74 100644 --- a/src/pineko/template.py +++ b/src/pineko/template.py @@ -56,7 +56,7 @@ 1] ) -# Define some default parameters +# Define default constants CONSTANTS = { "configs": { From 756be45d2b9caef8ffff9cc6b81fa6a7396c7c3d Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Thu, 19 Jun 2025 12:00:03 +0200 Subject: [PATCH 03/20] Removal of need of _template.yaml --- src/pineko/evolve.py | 31 +++++++++++++------------------ src/pineko/template.py | 30 +++++++++++++++++------------- src/pineko/theory.py | 2 -- 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/pineko/evolve.py b/src/pineko/evolve.py index ca6c1784..c84bd811 100644 --- a/src/pineko/evolve.py +++ b/src/pineko/evolve.py @@ -22,7 +22,7 @@ from pineappl.fk_table import PyFkAssumptions from pineappl.grid import PyOperatorSliceInfo, PyPidBasis -from . import check, comparator, version +from . import check, comparator, version, template logger = logging.getLogger(__name__) @@ -95,7 +95,6 @@ def check_convolution_types(grid, operators1, operators2): def write_operator_card_from_file( pineappl_path: os.PathLike, - default_card_path: os.PathLike, card_path: os.PathLike, tcard, ): @@ -105,8 +104,6 @@ def write_operator_card_from_file( ---------- pineappl_path : str or os.PathLike path to grid to evolve - default_card : str or os.PathLike - base operator card card_path : str or os.PathLike target path tcard: dict @@ -124,10 +121,7 @@ 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) - 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) + return write_operator_card(pineappl_grid, card_path, tcard) def dump_card(card_path, operators_card, conv_type, suffix=False): @@ -160,15 +154,13 @@ def dump_card(card_path, operators_card, conv_type, suffix=False): ) -def write_operator_card(pineappl_grid, default_card, card_path, tcard): +def write_operator_card(pineappl_grid, card_path, tcard): """Generate operator card for this grid. Parameters ---------- pineappl_grid : pineappl.grid.Grid grid to evolve - default_card : dict - base operator card card_path : str or os.PathLike target path tcard: dict @@ -195,16 +187,17 @@ def write_operator_card(pineappl_grid, default_card, card_path, tcard): # ... to get the x and muF grids for the eko evol_info = pineappl_grid.evolve_info(order_mask) muf2_grid = evol_info.fac1 - operators_card = copy.deepcopy(default_card) + operators_card = {} + operators_card["configs"] = {} sv_method = sv_scheme(tcard) xif = 1.0 if sv_method is not None else tcard["XIF"] # update scale variation method - operators_card["configs"]["scvar_method"] = sv_method + operators_card["configs"]["scvar_method"] = sv_scheme(tcard) # 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") +# if template.CONSTANTS["mu0"] is not None and template.CONSTANTS["mu0"] != tcard["Q0"]: +# raise ValueError("Q0 from theory differs from standard Q0") q2_grid = (xif * xif * muf2_grid).tolist() masses = np.array([tcard["mc"], tcard["mb"], tcard["mt"]]) ** 2 @@ -228,6 +221,8 @@ def write_operator_card(pineappl_grid, default_card, card_path, tcard): x_grid = np.append(x_grid, 1.0) operators_card["configs"]["interpolation_polynomial_degree"] = 1 operators_card["xgrid"] = x_grid.tolist() + else: + operators_card["xgrid"] = template.xgrid # Add the version of eko and pineko to the operator card # using importlib.metadata.version to get the correct tag in editable mode @@ -257,17 +252,17 @@ def write_operator_card(pineappl_grid, default_card, card_path, tcard): ) # If the evolution method is defined in the template and it is different, fail - template_method = default_card["configs"].get("evolution_method") + template_method = template.CONSTANTS["configs"]["evolution_method"] if ( template_method is not None and template_method != opconf["evolution_method"] ): raise ValueError( - f"The template and the theory have different evolution method ({template_method} vs {opconf['key']})" + f"Your theory has a different evolution method than the default({template_method} vs {opconf['key']})" ) # If the change is on the number of iterations, take the template value but warn the user - template_iter = default_card["configs"].get("ev_op_iterations") + template_iter = template.CONSTANTS["configs"]["ev_op_iterations"] if template_iter is not None and template_method != opconf["ev_op_iterations"]: opconf["ev_op_iterations"] = template_iter logger.warning( diff --git a/src/pineko/template.py b/src/pineko/template.py index 68b31b74..fe75fbaa 100644 --- a/src/pineko/template.py +++ b/src/pineko/template.py @@ -1,9 +1,9 @@ """Default settings and interpolation xgrid (previously in _template.yaml).""" - +import yaml from eko.interpolation import XGrid # Define the interpolation x-grid as previously defined as 'xgrid' in _template.yaml -INTERPOLATION_XGRID = XGrid( +xgrid = ( [1.9999999999999954e-07, 3.034304765867952e-07, 4.6035014748963906e-07, @@ -56,32 +56,36 @@ 1] ) -# Define default constants +mugrid = [(4.6,4),(5.1,5),(5.6,5)] CONSTANTS = { "configs": { "ev_op_iterations": 1, "ev_op_max_order": (10,1), - "evolution_method": iterate-exact, - "interpolation_is_log": true, + "evolution_method": "iterate-exact", + "interpolation_is_log": True, "interpolation_polynomial_degree": 4, - "inversion_method": expanded, + "inversion_method": "expanded", "n_integration_cores": 1, - "polarized": false, - "scvar_method": null, - "time_like": false + "polarized": False, + "scvar_method": "null", + "time_like": False }, "debug": { - "skip_non_singlet": false, - "skip_singlet": false + "skip_non_singlet": False, + "skip_singlet": False }, - "eko_version": 0.14.2, + "eko_version": "0.14.2", "mu0": 0, } +operator_card = {} +operator_card["mugrid"] = mugrid - +card_path = "./test.yaml" +with open(card_path, "w", encoding="UTF-8") as f: + yaml.safe_dump(operator_card, f) diff --git a/src/pineko/theory.py b/src/pineko/theory.py index fa58d169..b5b39bb9 100644 --- a/src/pineko/theory.py +++ b/src/pineko/theory.py @@ -271,8 +271,6 @@ def opcard(self, name, grid, tcard): return _x_grid, q2_grid = evolve.write_operator_card_from_file( grid, - self.operator_cards_path - / configs.configs["paths"]["operator_card_template_name"], opcard_path, tcard, ) From ed25c7dc1e823b035e71ba6a5d86424de5a3a69e Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Thu, 19 Jun 2025 12:18:59 +0200 Subject: [PATCH 04/20] Remove test that checks q0 from theory card & _template.py --- tests/test_evolve.py | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/tests/test_evolve.py b/tests/test_evolve.py index f529b80b..facc3dde 100644 --- a/tests/test_evolve.py +++ b/tests/test_evolve.py @@ -46,26 +46,3 @@ def key_values(self): return {"convolution_particle_1": 2212, "convolution_particle_2": 11} -def test_write_operator_card_q0(tmp_path): - """Checks https://github.com/NNPDF/pineko/issues/146""" - p = tmp_path / "q0.yaml" - g = FakePine() - t = copy.deepcopy(default_card) - o = copy.deepcopy(example.raw_operator()) - # 1. Same Q0 and mu0, all ok - t["Q0"] = 5.0 - o["mu0"] = 5.0 - _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"]) - # 2. Q0 only in theory, all ok - o.pop("mu0") - _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"]) - # 3. op is different, raises error - o["mu0"] = 11.0 - with pytest.raises(ValueError): - _xs, _mu2s = pineko.evolve.write_operator_card(g, o, p, t) From b0350dcf68509534f56682dfd9330c19b69e1769 Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Thu, 19 Jun 2025 17:30:26 +0200 Subject: [PATCH 05/20] Remove unnecessary stuff from template.py --- src/pineko/template.py | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/src/pineko/template.py b/src/pineko/template.py index fe75fbaa..44ae5f0f 100644 --- a/src/pineko/template.py +++ b/src/pineko/template.py @@ -56,51 +56,15 @@ 1] ) -mugrid = [(4.6,4),(5.1,5),(5.6,5)] - CONSTANTS = { "configs": { "ev_op_iterations": 1, - "ev_op_max_order": (10,1), "evolution_method": "iterate-exact", - "interpolation_is_log": True, - "interpolation_polynomial_degree": 4, "inversion_method": "expanded", - "n_integration_cores": 1, "polarized": False, "scvar_method": "null", "time_like": False }, - "debug": { - "skip_non_singlet": False, - "skip_singlet": False - }, "eko_version": "0.14.2", - "mu0": 0, } - -operator_card = {} -operator_card["mugrid"] = mugrid - -card_path = "./test.yaml" -with open(card_path, "w", encoding="UTF-8") as f: - yaml.safe_dump(operator_card, f) - - - - - - - - - - - - - - - - - - From 22d9ac289ede86059236ab2e917ca7a3abba45fc Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Fri, 20 Jun 2025 17:16:13 +0200 Subject: [PATCH 06/20] Forgot to add template.py --- src/pineko/template.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pineko/template.py b/src/pineko/template.py index 44ae5f0f..dc6ed952 100644 --- a/src/pineko/template.py +++ b/src/pineko/template.py @@ -65,6 +65,7 @@ "scvar_method": "null", "time_like": False }, + "init": (1.65, 4), "eko_version": "0.14.2", } From 5f7394b8b3ae0bc9b74f11ed9a490b226301c4ad Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Tue, 14 Apr 2026 15:23:36 +0200 Subject: [PATCH 07/20] Remove eko version from template.py Co-authored-by: Felix Hekhorn --- src/pineko/template.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pineko/template.py b/src/pineko/template.py index dc6ed952..c5594111 100644 --- a/src/pineko/template.py +++ b/src/pineko/template.py @@ -66,6 +66,5 @@ "time_like": False }, "init": (1.65, 4), - "eko_version": "0.14.2", } From f560b91894cd5ecfcf27b5ecf8d8459db2a7c9a1 Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Thu, 23 Apr 2026 16:13:30 +0200 Subject: [PATCH 08/20] change ev_op_iterations Co-authored-by: Felix Hekhorn --- src/pineko/template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pineko/template.py b/src/pineko/template.py index c5594111..03c81e1e 100644 --- a/src/pineko/template.py +++ b/src/pineko/template.py @@ -58,7 +58,7 @@ CONSTANTS = { "configs": { - "ev_op_iterations": 1, + "ev_op_iterations": 60, "evolution_method": "iterate-exact", "inversion_method": "expanded", "polarized": False, From 5b931b6670766e9fcbdfe5b1af0b3afc516548af Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Thu, 23 Apr 2026 16:24:27 +0200 Subject: [PATCH 09/20] Adjusted function in cli and changed last thing in evolve.py --- src/pineko/cli/opcard.py | 2 +- src/pineko/evolve.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pineko/cli/opcard.py b/src/pineko/cli/opcard.py index 0f175a01..60e3017a 100644 --- a/src/pineko/cli/opcard.py +++ b/src/pineko/cli/opcard.py @@ -29,5 +29,5 @@ def subcommand(pineappl_path, default_card_path, thcard_path, opcard_path): tcard = yaml.safe_load(pathlib.Path(thcard_path).read_text(encoding="utf-8")) opcard_path = pathlib.Path(opcard_path) _x_grid, q2_grid = evolve.write_operator_card_from_file( - pineappl_path, default_card_path, opcard_path, tcard + pineappl_path, opcard_path, tcard ) diff --git a/src/pineko/evolve.py b/src/pineko/evolve.py index da690d5c..262bb7dd 100644 --- a/src/pineko/evolve.py +++ b/src/pineko/evolve.py @@ -22,7 +22,7 @@ from eko.matchings import Atlas, nf_default from eko.quantities import heavy_quarks -from . import check, comparator, version, template +from . import check, comparator, template, version logger = logging.getLogger(__name__) @@ -123,6 +123,7 @@ def write_operator_card_from_file( pineappl_grid.optimize() return write_operator_card(pineappl_grid, card_path, tcard) + def dump_card( card_path: Union[str, os.PathLike], operators_card: dict, @@ -239,7 +240,7 @@ def write_operator_card( opconf["evolution_method"] = "iterate-exact" if "IterEv" in tcard: opconf["ev_op_iterations"] = tcard["IterEv"] - elif "ev_op_iterations" not in default_card["configs"]: + elif template.CONSTANTS["configs"]["ev_op_iterations"] is None: raise ValueError( "EXA used but IterEv not found in the theory card and not ev_op_iterations set in the template" ) From 53b193b76ccc3a42d520c5a3b845f11716ee178c Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Thu, 23 Apr 2026 16:46:03 +0200 Subject: [PATCH 10/20] Change ValueError of evolution method --- src/pineko/evolve.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pineko/evolve.py b/src/pineko/evolve.py index 262bb7dd..e2910d14 100644 --- a/src/pineko/evolve.py +++ b/src/pineko/evolve.py @@ -252,7 +252,7 @@ def write_operator_card( and template_method != opconf["evolution_method"] ): raise ValueError( - f"Your theory has a different evolution method than the default({template_method} vs {opconf['key']})" + f"Your theory has a different evolution method than the default({template_method} vs {opconf['evolution_method']})" ) # If the change is on the number of iterations, take the template value but warn the user From d8332f931b85856d11d07fb392538d0b47693491 Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Mon, 27 Apr 2026 15:04:25 +0200 Subject: [PATCH 11/20] Adjust evolve benchmark --- benchmarks/bench_evolve.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/benchmarks/bench_evolve.py b/benchmarks/bench_evolve.py index 7da92ed8..59124dd5 100644 --- a/benchmarks/bench_evolve.py +++ b/benchmarks/bench_evolve.py @@ -34,7 +34,7 @@ def benchmark_write_operator_card_from_file_num_fonll( with open(tcard_path, encoding="utf-8") as f: tcard = yaml.safe_load(f) _x_grid, _q2_grid = pineko.evolve.write_operator_card_from_file( - pine_path, default_path, target_path, tcard + pine_path, target_path, tcard ) # Check if the opcards are ok for opcard_path, cfg in zip( @@ -49,11 +49,10 @@ def benchmark_write_operator_card_from_file_num_fonll( def benchmark_write_operator_card_from_file(tmp_path, test_files, test_configs): pine_path = test_files / "data/grids/400/HERA_NC_225GEV_EP_SIGMARED.pineappl.lz4" - default_path = test_files / "data/operator_cards/400/_template.yaml" target_path = pathlib.Path(tmp_path / "test_operator.yaml") tcard = pineko.theory_card.load(400) x_grid, _q2_grid = pineko.evolve.write_operator_card_from_file( - pine_path, default_path, target_path, tcard + pine_path, target_path, tcard ) # Load the operator card @@ -64,13 +63,12 @@ def benchmark_write_operator_card_from_file(tmp_path, test_files, test_configs): wrong_pine_path = test_files / "data/grids/208/HERA_CC_318GEV_EM_wrong.pineappl.lz4" with pytest.raises(FileNotFoundError): _ = pineko.evolve.write_operator_card_from_file( - wrong_pine_path, default_path, target_path, 1.0 + wrong_pine_path, target_path, 1.0 ) def benchmark_dglap(tmp_path, test_files, test_configs): pine_path = test_files / "data/grids/400/HERA_NC_225GEV_EP_SIGMARED.pineappl.lz4" - default_path = test_files / "data/operator_cards/400/_template.yaml" target_path = pathlib.Path(tmp_path / "test_operator.yaml") theory_id = 400 @@ -78,7 +76,7 @@ def benchmark_dglap(tmp_path, test_files, test_configs): # In order to check if the operator card is enough for eko, let's compute the eko pineko.evolve.write_operator_card_from_file( - pine_path, default_path, target_path, tcard + pine_path, target_path, tcard ) # Load the opcard From 4c9ee46cb033a800e5d8c97538aafd673f8f39af Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Tue, 5 May 2026 10:11:17 +0200 Subject: [PATCH 12/20] Change ValueError into warning --- src/pineko/evolve.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pineko/evolve.py b/src/pineko/evolve.py index e2910d14..2b948cc4 100644 --- a/src/pineko/evolve.py +++ b/src/pineko/evolve.py @@ -251,8 +251,9 @@ def write_operator_card( template_method is not None and template_method != opconf["evolution_method"] ): - raise ValueError( - f"Your theory has a different evolution method than the default({template_method} vs {opconf['evolution_method']})" + logger.warning( + f"Your theory has a different evolution method than the default({template_method} vs {opconf['evolution_method']})." + f"The evolution method will be set to the default value {template_method}, check if this is what you want" ) # If the change is on the number of iterations, take the template value but warn the user @@ -261,7 +262,7 @@ def write_operator_card( opconf["ev_op_iterations"] ): raise ValueError( - f"The number of iteration in the theory and template is different, ({template_iter} vs {opconf['ev_op_iterations']})" + f"Warning! The number of iteration in the theory and template is different, ({template_iter} vs {opconf['ev_op_iterations']})" ) # Some safety checks From 7b060308ddaecc650f8f286dadfd18de0a483988 Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Tue, 5 May 2026 10:30:58 +0200 Subject: [PATCH 13/20] Change error into warning and remove unnecessary import --- src/pineko/evolve.py | 5 +++-- src/pineko/template.py | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pineko/evolve.py b/src/pineko/evolve.py index 2b948cc4..e145b109 100644 --- a/src/pineko/evolve.py +++ b/src/pineko/evolve.py @@ -261,8 +261,9 @@ def write_operator_card( if template_iter is not None and int(template_iter) != int( opconf["ev_op_iterations"] ): - raise ValueError( - f"Warning! The number of iteration in the theory and template is different, ({template_iter} vs {opconf['ev_op_iterations']})" + logger.warning( + f"Warning! The number of iteration in the theory and template is different, ({template_iter} vs {opconf['ev_op_iterations']})." + f"The evolution method will be set to the default value {template_iter}, check if this is what you want" ) # Some safety checks diff --git a/src/pineko/template.py b/src/pineko/template.py index 03c81e1e..41379509 100644 --- a/src/pineko/template.py +++ b/src/pineko/template.py @@ -1,6 +1,5 @@ """Default settings and interpolation xgrid (previously in _template.yaml).""" import yaml -from eko.interpolation import XGrid # Define the interpolation x-grid as previously defined as 'xgrid' in _template.yaml xgrid = ( From b714df05b84e8b7703d15f62c23d2f40095d7209 Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Mon, 18 May 2026 13:57:51 +0200 Subject: [PATCH 14/20] Add missing keys to template --- src/pineko/evolve.py | 5 +++++ src/pineko/template.py | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/pineko/evolve.py b/src/pineko/evolve.py index e145b109..4e7ab3fd 100644 --- a/src/pineko/evolve.py +++ b/src/pineko/evolve.py @@ -202,6 +202,11 @@ def write_operator_card( operators_card["configs"]["scvar_method"] = sv_scheme(tcard) operators_card["init"] = (tcard["Q0"], tcard["nf0"]) + operators_card["configs"]["ev_op_max_order"] = template.CONSTANTS["configs"]["ev_op_max_order"] + operators_card["configs"]["inversion_method"] = template.CONSTANTS["configs"]["inversion_method"] + operators_card["configs"]["interpolation_polynomial_degree"] = template.CONSTANTS["configs"]["interpolation_polynomial_degree"] + operators_card["configs"]["interpolation_is_log"] = template.CONSTANTS["configs"]["interpolation_is_log"] + operators_card["debug"] = template.CONSTANTS["debug"] if template.CONSTANTS["init"] is not None and template.CONSTANTS["init"] != ( tcard["Q0"], tcard["nf0"], diff --git a/src/pineko/template.py b/src/pineko/template.py index 41379509..01da3e2b 100644 --- a/src/pineko/template.py +++ b/src/pineko/template.py @@ -62,8 +62,15 @@ "inversion_method": "expanded", "polarized": False, "scvar_method": "null", - "time_like": False + "time_like": False, + "ev_op_max_order": (10, 0), + "interpolation_polynomial_degree": 4, + "interpolation_is_log": True, }, "init": (1.65, 4), + "debug": { + "skip_non_singlet": True, + "skip_singlet": True, + }, } From 8e23b88f866bb9ce9709c860a83878e0f26f9bf6 Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Mon, 18 May 2026 16:16:06 +0200 Subject: [PATCH 15/20] fix formatting of scripts and change debug settings to false --- benchmarks/bench_evolve.py | 4 +--- benchmarks/bench_regression.py | 2 +- src/pineko/evolve.py | 20 ++++++++++++++------ src/pineko/template.py | 14 ++++++-------- tests/test_evolve.py | 2 -- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/benchmarks/bench_evolve.py b/benchmarks/bench_evolve.py index 59124dd5..66a78acd 100644 --- a/benchmarks/bench_evolve.py +++ b/benchmarks/bench_evolve.py @@ -75,9 +75,7 @@ def benchmark_dglap(tmp_path, test_files, test_configs): tcard = pineko.theory_card.load(theory_id) # In order to check if the operator card is enough for eko, let's compute the eko - pineko.evolve.write_operator_card_from_file( - pine_path, target_path, tcard - ) + pineko.evolve.write_operator_card_from_file(pine_path, target_path, tcard) # Load the opcard myopcard = yaml.safe_load(target_path.read_text(encoding="utf-8")) diff --git a/benchmarks/bench_regression.py b/benchmarks/bench_regression.py index 7f79ec6a..5d02b349 100644 --- a/benchmarks/bench_regression.py +++ b/benchmarks/bench_regression.py @@ -70,7 +70,7 @@ def xfxQ2(self, pid, x, q2): return np.power(x, alpha) * np.power(1 - x, beta) -def _trim_template(template_card, take_points=10): +def _trim_template(template_card, take_points=30): """Trim the template card so that the number of x-values to compute is much smaller""" raw_card = safe_load(template_card.read_text(encoding="utf-8")) raw_card["init"] = (raw_card["mu0"], 4) diff --git a/src/pineko/evolve.py b/src/pineko/evolve.py index 4e7ab3fd..cc6a1aaf 100644 --- a/src/pineko/evolve.py +++ b/src/pineko/evolve.py @@ -202,10 +202,18 @@ def write_operator_card( operators_card["configs"]["scvar_method"] = sv_scheme(tcard) operators_card["init"] = (tcard["Q0"], tcard["nf0"]) - operators_card["configs"]["ev_op_max_order"] = template.CONSTANTS["configs"]["ev_op_max_order"] - operators_card["configs"]["inversion_method"] = template.CONSTANTS["configs"]["inversion_method"] - operators_card["configs"]["interpolation_polynomial_degree"] = template.CONSTANTS["configs"]["interpolation_polynomial_degree"] - operators_card["configs"]["interpolation_is_log"] = template.CONSTANTS["configs"]["interpolation_is_log"] + operators_card["configs"]["ev_op_max_order"] = template.CONSTANTS["configs"][ + "ev_op_max_order" + ] + operators_card["configs"]["inversion_method"] = template.CONSTANTS["configs"][ + "inversion_method" + ] + operators_card["configs"]["interpolation_polynomial_degree"] = template.CONSTANTS[ + "configs" + ]["interpolation_polynomial_degree"] + operators_card["configs"]["interpolation_is_log"] = template.CONSTANTS["configs"][ + "interpolation_is_log" + ] operators_card["debug"] = template.CONSTANTS["debug"] if template.CONSTANTS["init"] is not None and template.CONSTANTS["init"] != ( tcard["Q0"], @@ -258,7 +266,7 @@ def write_operator_card( ): logger.warning( f"Your theory has a different evolution method than the default({template_method} vs {opconf['evolution_method']})." - f"The evolution method will be set to the default value {template_method}, check if this is what you want" + f"The evolution method will be set to the default value {template_method}, check if this is what you want" ) # If the change is on the number of iterations, take the template value but warn the user @@ -268,7 +276,7 @@ def write_operator_card( ): logger.warning( f"Warning! The number of iteration in the theory and template is different, ({template_iter} vs {opconf['ev_op_iterations']})." - f"The evolution method will be set to the default value {template_iter}, check if this is what you want" + f"The evolution method will be set to the default value {template_iter}, check if this is what you want" ) # Some safety checks diff --git a/src/pineko/template.py b/src/pineko/template.py index 01da3e2b..cbfd54ed 100644 --- a/src/pineko/template.py +++ b/src/pineko/template.py @@ -1,9 +1,8 @@ """Default settings and interpolation xgrid (previously in _template.yaml).""" -import yaml # Define the interpolation x-grid as previously defined as 'xgrid' in _template.yaml -xgrid = ( - [1.9999999999999954e-07, +xgrid = [ + 1.9999999999999954e-07, 3.034304765867952e-07, 4.6035014748963906e-07, 6.984208530700364e-07, @@ -52,8 +51,8 @@ 0.7956242522922756, 0.8627839323906108, 0.9309440808717544, - 1] - ) + 1, +] CONSTANTS = { "configs": { @@ -69,8 +68,7 @@ }, "init": (1.65, 4), "debug": { - "skip_non_singlet": True, - "skip_singlet": True, + "skip_non_singlet": False, + "skip_singlet": False, }, } - diff --git a/tests/test_evolve.py b/tests/test_evolve.py index 91fb56a9..7d6b10c4 100644 --- a/tests/test_evolve.py +++ b/tests/test_evolve.py @@ -50,5 +50,3 @@ def evolve_info(self, _): @property def metadata(self): return {"convolution_particle_1": 2212, "convolution_particle_2": 11} - - From 3664fa2d18c1f65398b447bccd7c0c91e6a0a2c3 Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Tue, 19 May 2026 13:36:40 +0200 Subject: [PATCH 16/20] Last changes to pass last test, had forgotten some keys in template.py --- benchmarks/bench_regression.py | 3 ++- src/pineko/evolve.py | 9 ++++++--- src/pineko/template.py | 5 ++++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/benchmarks/bench_regression.py b/benchmarks/bench_regression.py index 5d02b349..2f34ea99 100644 --- a/benchmarks/bench_regression.py +++ b/benchmarks/bench_regression.py @@ -16,6 +16,7 @@ import pytest from eko.interpolation import XGrid from eko.io.runcards import OperatorCard +from pineko.evolve import write_operator_card from pineappl.fk_table import FkTable from yaml import dump, safe_load @@ -70,7 +71,7 @@ def xfxQ2(self, pid, x, q2): return np.power(x, alpha) * np.power(1 - x, beta) -def _trim_template(template_card, take_points=30): +def _trim_template(template_card, take_points=10): """Trim the template card so that the number of x-values to compute is much smaller""" raw_card = safe_load(template_card.read_text(encoding="utf-8")) raw_card["init"] = (raw_card["mu0"], 4) diff --git a/src/pineko/evolve.py b/src/pineko/evolve.py index cc6a1aaf..22679eea 100644 --- a/src/pineko/evolve.py +++ b/src/pineko/evolve.py @@ -214,7 +214,10 @@ def write_operator_card( operators_card["configs"]["interpolation_is_log"] = template.CONSTANTS["configs"][ "interpolation_is_log" ] + operators_card["configs"]["n_integration_cores"] = template.CONSTANTS["configs"]["n_integration_cores"] operators_card["debug"] = template.CONSTANTS["debug"] + operators_card["configs"]["time_like"] = template.CONSTANTS["configs"]["time_like"] + operators_card["configs"]["polarized"] = template.CONSTANTS["configs"]["polarized"] if template.CONSTANTS["init"] is not None and template.CONSTANTS["init"] != ( tcard["Q0"], tcard["nf0"], @@ -268,6 +271,7 @@ def write_operator_card( f"Your theory has a different evolution method than the default({template_method} vs {opconf['evolution_method']})." f"The evolution method will be set to the default value {template_method}, check if this is what you want" ) + opconf["evolution_method"]=template_method # If the change is on the number of iterations, take the template value but warn the user template_iter = template.CONSTANTS["configs"]["ev_op_iterations"] @@ -276,9 +280,9 @@ def write_operator_card( ): logger.warning( f"Warning! The number of iteration in the theory and template is different, ({template_iter} vs {opconf['ev_op_iterations']})." - f"The evolution method will be set to the default value {template_iter}, check if this is what you want" + f"The number of iterations will be set to default value {template_iter}, check if this is what you want" ) - + opconf["ev_op_iterations"]=template_iter # Some safety checks if ( operators_card["configs"]["evolution_method"] == "truncated" @@ -294,7 +298,6 @@ def write_operator_card( for conv in convolutions: dump_card(card_path, operators_card, conv) - return operators_card["xgrid"], q2_grid diff --git a/src/pineko/template.py b/src/pineko/template.py index cbfd54ed..f8870592 100644 --- a/src/pineko/template.py +++ b/src/pineko/template.py @@ -62,9 +62,12 @@ "polarized": False, "scvar_method": "null", "time_like": False, - "ev_op_max_order": (10, 0), + "ev_op_max_order": [10, 0], "interpolation_polynomial_degree": 4, "interpolation_is_log": True, + "n_integration_cores": 1, + "polarized": False, + "time_like": False, }, "init": (1.65, 4), "debug": { From 89304e2a9eb2bd078c346b62729a43411fe36e9b Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Tue, 19 May 2026 16:56:07 +0200 Subject: [PATCH 17/20] new regression data --- benchmarks/regression_data/LHCBWZMU8TEV.npy | Bin 400 -> 400 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/benchmarks/regression_data/LHCBWZMU8TEV.npy b/benchmarks/regression_data/LHCBWZMU8TEV.npy index f6824c2049fad95a8f6ac104e8204e2b8fa6789f..06bb9ca7ed6896b088938228faa713e4676a9603 100644 GIT binary patch delta 281 zcmV+!0p|XY1CRrdfPdK3YbB(N;y*GKs>Rhb{XdP1vC?xK2|!m>DO-o}5kPH6Cn06< z7eMpyIBW#39Y8k%grE!1AwX1o0$MFCqRIkWg+RDCqTPu z2inp0B|uWQz=2N%BS4zG>8D1s9zerDKoLov7C`4&{nJ*>4SzsRoMFzpLH9qzGb&$V z$-X}Wf;*~y+Co6n4qaxtl0-lo^m4-U7Dhl==zQg0C`UkMbORCBsz*S)DiFh~k4HfI z=yx`@{6#=mam^ae4M9NDjIQ-0Oi4fj=^6zX&r3j7C1rD!qD?@<#ocD+A5K7Qt`m9r fy-Yy8^xbJpe-cSR@!_q74WU9nQ-dP^3Ij7hkiLBb delta 281 zcmV+!0p|XY1CRrdfPcw7z&Rmf%s<$G9Iz}s>p!kg;!8(U{Xd2^DwB1<2tcP-#*=(? z5kMM`2K2&`5kMaqLecWf20+0^GveL4#6RcT{~uDp0>Fnq-xT753BXM}hiq1F2f$wB z2`B0`{=Xpma_Tv4>c703Y;pq2%Rk*{NMZD{?mvH^im67e^?yGlNww8LIUhit z>e*GT1QI|V_wo0TMjAk((STzF7$!iDwM+&9dLlp=1~P0?W+6atG Date: Thu, 21 May 2026 10:05:12 +0200 Subject: [PATCH 18/20] Removed _template from & added extra keys to CLI & evolution method from theory card --- benchmarks/bench_cli.py | 4 - benchmarks/bench_evolve.py | 1 - benchmarks/bench_regression.py | 1 - pineko.ci.toml | 1 - pineko.debug.toml | 1 - src/pineko/cli/opcard.py | 22 ++-- src/pineko/cli/theory_.py | 7 +- src/pineko/configs.py | 5 +- src/pineko/evolve.py | 103 ++++++++++-------- .../{template.py => opcard_template.py} | 7 -- src/pineko/scaffold.py | 6 + src/pineko/theory.py | 9 +- tests/conftest.py | 1 - tests/test_scaffold.py | 1 - 14 files changed, 90 insertions(+), 79 deletions(-) rename src/pineko/{template.py => opcard_template.py} (87%) diff --git a/benchmarks/bench_cli.py b/benchmarks/bench_cli.py index 5cf195a8..0b24ec25 100644 --- a/benchmarks/bench_cli.py +++ b/benchmarks/bench_cli.py @@ -50,9 +50,6 @@ def benchmark_opcard_cli(tmp_path, test_files): grid_path = pathlib.Path( test_files / "data/grids/400/HERA_NC_225GEV_EP_SIGMARED.pineappl.lz4" ) - default_card_path = pathlib.Path( - test_files / "data/operator_cards/400/_template.yaml" - ) thcard_path = pathlib.Path(test_files / "data" / "theory_cards" / "400.yaml") target_path = pathlib.Path(tmp_path / "test_ope_card.yaml") runner = CliRunner() @@ -61,7 +58,6 @@ def benchmark_opcard_cli(tmp_path, test_files): [ "opcard", str(grid_path), - str(default_card_path), str(thcard_path), str(target_path), ], diff --git a/benchmarks/bench_evolve.py b/benchmarks/bench_evolve.py index 66a78acd..fd061087 100644 --- a/benchmarks/bench_evolve.py +++ b/benchmarks/bench_evolve.py @@ -25,7 +25,6 @@ def benchmark_write_operator_card_from_file_num_fonll( / "400" / "HERA_NC_225GEV_EP_SIGMARED.pineappl.lz4" ) - default_path = test_files / "data" / "operator_cards" / "400" / "_template.yaml" num_opcard = 7 if is_mixed else 5 targets_path_list = [ tmp_path / f"test_opcard_{num}.yaml" for num in range(num_opcard) diff --git a/benchmarks/bench_regression.py b/benchmarks/bench_regression.py index 2f34ea99..7f79ec6a 100644 --- a/benchmarks/bench_regression.py +++ b/benchmarks/bench_regression.py @@ -16,7 +16,6 @@ import pytest from eko.interpolation import XGrid from eko.io.runcards import OperatorCard -from pineko.evolve import write_operator_card from pineappl.fk_table import FkTable from yaml import dump, safe_load diff --git a/pineko.ci.toml b/pineko.ci.toml index 0a202214..b0ff54c1 100644 --- a/pineko.ci.toml +++ b/pineko.ci.toml @@ -4,7 +4,6 @@ nnpdf=true [paths] # inputs grids = "./theory_productions/data/grids" -operator_card_template_name = "_template.ci.yaml" # outputs operator_cards = "./theory_productions/operator_cards" ekos = "./theory_productions/data/ekos" diff --git a/pineko.debug.toml b/pineko.debug.toml index e9adec0f..5df63423 100644 --- a/pineko.debug.toml +++ b/pineko.debug.toml @@ -3,7 +3,6 @@ ymldb = "data/ymldb" grids = "data/grids" theory_cards = "data/theory_cards" -operator_card_template_name = "_template.yaml" # outputs operator_cards = "data/operator_cards" ekos = "data/ekos" diff --git a/src/pineko/cli/opcard.py b/src/pineko/cli/opcard.py index 60e3017a..10c5859d 100644 --- a/src/pineko/cli/opcard.py +++ b/src/pineko/cli/opcard.py @@ -2,6 +2,7 @@ import pathlib +import rich import rich_click as click import yaml @@ -11,16 +12,23 @@ @command.command("opcard") @click.argument("pineappl-path", metavar="PINEAPPL", type=click.Path(exists=True)) -@click.argument( - "default-card-path", metavar="DEFAULT_CARD", type=click.Path(exists=True) -) @click.argument("thcard-path", metavar="THCARD", type=click.Path()) @click.argument("opcard-path", metavar="OPCARD", type=click.Path()) -def subcommand(pineappl_path, default_card_path, thcard_path, opcard_path): +@click.option("--ipd", default=4, show_default=True, help="interpolation polynomial degree") +@click.option("--iil", default=True, show_default=True, help="interpolation is log") +@click.option("--int-cores", default=1, show_default=True, help="number of integration cores") +def subcommand( + pineappl_path, + thcard_path, + opcard_path, + ipd, + iil, + int_cores, +): """Write EKO card for PineAPPL grid. - Writes a copy of the default card from DEFAULT_CARD to OPCARD - with the adjusted x grid and Q2 grid read from PINEAPPL. + Writes an operator card OPCARD from the information in + opcard_template.py and the theory card. A THCARD is required, since some of the EKO's OPCARD information come from the NNPDF theory entries (e.g. :math:`Q0`). @@ -29,5 +37,5 @@ def subcommand(pineappl_path, default_card_path, thcard_path, opcard_path): tcard = yaml.safe_load(pathlib.Path(thcard_path).read_text(encoding="utf-8")) opcard_path = pathlib.Path(opcard_path) _x_grid, q2_grid = evolve.write_operator_card_from_file( - pineappl_path, opcard_path, tcard + pineappl_path, opcard_path, tcard, ipd, iil, int_cores ) diff --git a/src/pineko/cli/theory_.py b/src/pineko/cli/theory_.py index 1e1f8696..47817e80 100644 --- a/src/pineko/cli/theory_.py +++ b/src/pineko/cli/theory_.py @@ -29,9 +29,12 @@ def inherit_grids(source_theory_id, target_theory_id, datasets, overwrite): @click.argument("theory_id", type=click.INT) @click.argument("datasets", type=click.STRING, nargs=-1) @click.option("--overwrite", is_flag=True, help="Allow files to be overwritten") -def opcards(theory_id, datasets, overwrite): +@click.option("--ipd", default=4, show_default=True, help="interpolation polynomial degree") +@click.option("--iil", default=True, show_default=True, help="interpolation is log") +@click.option("--int-cores", default=1, show_default=True, help="number of integration cores") +def opcards(theory_id, datasets, overwrite, ipd, iil, int_cores): """Write EKO card for all FK tables in all datasets.""" - theory.TheoryBuilder(theory_id, datasets, overwrite=overwrite).opcards() + theory.TheoryBuilder(theory_id, datasets, overwrite=overwrite).opcards(ipd, iil, int_cores) @theory_.command() diff --git a/src/pineko/configs.py b/src/pineko/configs.py index 6afbb25f..bcddeff8 100644 --- a/src/pineko/configs.py +++ b/src/pineko/configs.py @@ -16,13 +16,12 @@ NEEDED_KEYS = [ "operator_cards", "grids", - "operator_card_template_name", THEORY_PATH_KEY, "fktables", "ekos", ] +NEEDED_FILES = [] -NEEDED_FILES = ["operator_card_template_name"] GENERIC_OPTIONS = "general" @@ -87,8 +86,6 @@ def enhance_paths(configs_): for key in required_keys: if key not in configs_["paths"]: raise ValueError(f"Configuration is missing a 'paths.{key}' key") - if key in NEEDED_FILES: - continue if pathlib.Path(configs_["paths"][key]).anchor == "": configs_["paths"][key] = configs_["paths"]["root"] / configs_["paths"][key] else: diff --git a/src/pineko/evolve.py b/src/pineko/evolve.py index 22679eea..d55666ce 100644 --- a/src/pineko/evolve.py +++ b/src/pineko/evolve.py @@ -22,7 +22,7 @@ from eko.matchings import Atlas, nf_default from eko.quantities import heavy_quarks -from . import check, comparator, template, version +from . import check, comparator, opcard_template, version logger = logging.getLogger(__name__) @@ -96,6 +96,9 @@ def write_operator_card_from_file( pineappl_path: os.PathLike, card_path: os.PathLike, tcard: dict, + ipd=4, + iil=True, + int_cores=1, ): """Generate operator card for a grid. @@ -107,6 +110,15 @@ def write_operator_card_from_file( target path tcard: dict theory card for the run + ipd: + interpolation polynomial degree, taken from cli. + Set to default value + iil: + interpolation is log, taken from cli. + Set to default value + int_cores: + number of integration cores, taken + from cli. Set to default value Returns ------- @@ -121,7 +133,7 @@ def write_operator_card_from_file( raise FileNotFoundError(pineappl_path) pineappl_grid = pineappl.grid.Grid.read(pineappl_path) pineappl_grid.optimize() - return write_operator_card(pineappl_grid, card_path, tcard) + return write_operator_card(pineappl_grid, card_path, tcard, ipd, iil, int_cores) def dump_card( @@ -161,6 +173,9 @@ def write_operator_card( pineappl_grid: pineappl.grid.Grid, card_path: Union[str, os.PathLike], tcard: dict, + ipd, + iil, + int_cores ): """Generate operator card for this grid. @@ -173,6 +188,12 @@ def write_operator_card( tcard: dict theory card for the run, since some information in EKO is now required in operator card, but before was in the theory card + ipd: + interpolation polynomial degree, taken from cli + iil: + interpolation is log, taken from cli + int_cores: + number of integration cores, taken from cli Returns ------- @@ -200,29 +221,26 @@ def write_operator_card( xif = 1.0 if sv_method is not None else tcard["XIF"] # update scale variation method operators_card["configs"]["scvar_method"] = sv_scheme(tcard) - + for key in ["polarized", + "time_like", + "ev_op_max_order", + ]: + operators_card["configs"][key] = opcard_template.CONSTANTS["configs"][key] + operators_card["debug"] = opcard_template.CONSTANTS["debug"] operators_card["init"] = (tcard["Q0"], tcard["nf0"]) - operators_card["configs"]["ev_op_max_order"] = template.CONSTANTS["configs"][ - "ev_op_max_order" - ] - operators_card["configs"]["inversion_method"] = template.CONSTANTS["configs"][ - "inversion_method" - ] - operators_card["configs"]["interpolation_polynomial_degree"] = template.CONSTANTS[ - "configs" - ]["interpolation_polynomial_degree"] - operators_card["configs"]["interpolation_is_log"] = template.CONSTANTS["configs"][ - "interpolation_is_log" - ] - operators_card["configs"]["n_integration_cores"] = template.CONSTANTS["configs"]["n_integration_cores"] - operators_card["debug"] = template.CONSTANTS["debug"] - operators_card["configs"]["time_like"] = template.CONSTANTS["configs"]["time_like"] - operators_card["configs"]["polarized"] = template.CONSTANTS["configs"]["polarized"] - if template.CONSTANTS["init"] is not None and template.CONSTANTS["init"] != ( + # setting the parameters from the cli + operators_card["configs"]["interpolation_polynomial_degree"] = ipd + operators_card["configs"]["interpolation_is_log"] = iil + operators_card["configs"]["n_integration_cores"] = int_cores + if opcard_template.CONSTANTS["init"] is not None and opcard_template.CONSTANTS["init"] != ( tcard["Q0"], tcard["nf0"], ): - raise ValueError("Q0, nf0 from theory different than default") + raise logger.warning( + f"Warning! Q0 and nf0 from your theory are different " + f"than default settings ({tcard['Q0']}, {tcard['nf0']} vs " + f"{opcard_template.CONSTANTS['init']}). Check if this is really what you want!" + ) q2_grid = (xif * xif * muf2_grid).tolist() # If we are producing nFONLL FKs we need to look to NfFF... @@ -240,7 +258,7 @@ def write_operator_card( operators_card["configs"]["interpolation_polynomial_degree"] = 1 operators_card["xgrid"] = x_grid.tolist() else: - operators_card["xgrid"] = template.xgrid + operators_card["xgrid"] = opcard_template.xgrid # Add the version of eko and pineko to the operator card # using importlib.metadata.version to get the correct tag in editable mode @@ -256,33 +274,26 @@ def write_operator_card( opconf["evolution_method"] = "iterate-exact" if "IterEv" in tcard: opconf["ev_op_iterations"] = tcard["IterEv"] - elif template.CONSTANTS["configs"]["ev_op_iterations"] is None: + else: raise ValueError( - "EXA used but IterEv not found in the theory card and not ev_op_iterations set in the template" + "EXA used but IterEv not found in the theory card" ) - - # If the evolution method is defined in the template and it is different, fail - template_method = template.CONSTANTS["configs"]["evolution_method"] - if ( - template_method is not None - and template_method != opconf["evolution_method"] - ): - logger.warning( - f"Your theory has a different evolution method than the default({template_method} vs {opconf['evolution_method']})." - f"The evolution method will be set to the default value {template_method}, check if this is what you want" - ) - opconf["evolution_method"]=template_method - - # If the change is on the number of iterations, take the template value but warn the user - template_iter = template.CONSTANTS["configs"]["ev_op_iterations"] - if template_iter is not None and int(template_iter) != int( - opconf["ev_op_iterations"] - ): - logger.warning( - f"Warning! The number of iteration in the theory and template is different, ({template_iter} vs {opconf['ev_op_iterations']})." - f"The number of iterations will be set to default value {template_iter}, check if this is what you want" + else: + raise ValueError( + "Evolution method not set in theory card" + ) + + if "inversion_method" in tcard: + opconf = operators_card["configs"] + opconf["inversion_method"] = tcard["inversion_method"] + else: + opconf["inversion_method"] = opcard_template.CONSTANTS["configs"]["inversion_method"] + logger.warning( + "Inversion method not set in theory card, it's being set to default value " + f"{opcard_template.CONSTANTS['configs']['inversion_method']}. " + "Check if that is what you want." ) - opconf["ev_op_iterations"]=template_iter + # Some safety checks if ( operators_card["configs"]["evolution_method"] == "truncated" diff --git a/src/pineko/template.py b/src/pineko/opcard_template.py similarity index 87% rename from src/pineko/template.py rename to src/pineko/opcard_template.py index f8870592..91c15c2c 100644 --- a/src/pineko/template.py +++ b/src/pineko/opcard_template.py @@ -56,18 +56,11 @@ CONSTANTS = { "configs": { - "ev_op_iterations": 60, - "evolution_method": "iterate-exact", "inversion_method": "expanded", "polarized": False, "scvar_method": "null", "time_like": False, "ev_op_max_order": [10, 0], - "interpolation_polynomial_degree": 4, - "interpolation_is_log": True, - "n_integration_cores": 1, - "polarized": False, - "time_like": False, }, "init": (1.65, 4), "debug": { diff --git a/src/pineko/scaffold.py b/src/pineko/scaffold.py index d9539301..fa364a68 100644 --- a/src/pineko/scaffold.py +++ b/src/pineko/scaffold.py @@ -2,9 +2,11 @@ import dataclasses import pathlib +import logging from .configs import NEEDED_FILES, NEEDED_KEYS +logger = logging.getLogger(__name__) @dataclasses.dataclass class CheckResult: @@ -45,6 +47,10 @@ def set_up_project(configs): path[log_path].mkdir(parents=True, exist_ok=True) else: raise TypeError(f"Not recognized entry {log_path} in configs") + elif path == "_template.yaml": + logger.warning(f"{path} is no longer a supported method for setting up " + "your operator card, remove it from your configuration" + ) else: raise TypeError(f"Not recognized entry {path} in configs") diff --git a/src/pineko/theory.py b/src/pineko/theory.py index 9b6e2a2c..7614b288 100644 --- a/src/pineko/theory.py +++ b/src/pineko/theory.py @@ -287,7 +287,7 @@ def iterate(self, f, **kwargs): f(name, grid, **kwargs) rich.print() - def opcard(self, name, grid, tcard): + def opcard(self, name, grid, tcard, ipd=4, iil=True, int_cores=1): """Write a single operator card. Parameters @@ -311,13 +311,16 @@ def opcard(self, name, grid, tcard): grid, opcard_path, tcard, + ipd, + iil, + int_cores, ) - def opcards(self): + def opcards(self, ipd=4, iil=True, int_cores=1): """Write operator cards.""" tcard = theory_card.load(self.theory_id) self.operator_cards_path.mkdir(exist_ok=True) - self.iterate(self.opcard, tcard=tcard) + self.iterate(self.opcard, tcard=tcard, ipd=ipd, iil=iil, int_cores=int_cores) def load_operator_card(self, name): """Read current operator card. diff --git a/tests/conftest.py b/tests/conftest.py index b39879fa..53b2cf9c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -34,7 +34,6 @@ def fake_configs(tmp_path): "ymldb": tmp_path / "data" / "ymldb", "operator_cards": tmp_path / "data" / "operator_cards", "grids": tmp_path / "data" / "grids", - "operator_card_template_name": "_template.yaml", "theory_cards": tmp_path / "data" / "theory_cards", "fktables": tmp_path / "data" / "fktables", "ekos": tmp_path / "data" / "ekos", diff --git a/tests/test_scaffold.py b/tests/test_scaffold.py index 795b85fe..50994451 100644 --- a/tests/test_scaffold.py +++ b/tests/test_scaffold.py @@ -19,7 +19,6 @@ def test_check_folder(fake_configs_incomplete, fake_configs): assert [ "operator_cards", "grids", - "operator_card_template_name", "theory_cards", "fktables", "ekos", From 37242b3f1a0514a05390b5080d595b8bfa5311a0 Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Thu, 21 May 2026 17:12:04 +0200 Subject: [PATCH 19/20] Set inversion method to expanded for truncated and exact for iterate-exact --- src/pineko/evolve.py | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/pineko/evolve.py b/src/pineko/evolve.py index d55666ce..c648ce56 100644 --- a/src/pineko/evolve.py +++ b/src/pineko/evolve.py @@ -266,14 +266,15 @@ def write_operator_card( # Choose the evolution method according to the theory if the key is included if "ModEv" in tcard: - opconf = operators_card["configs"] if tcard["ModEv"] == "TRN": - opconf["evolution_method"] = "truncated" - opconf["ev_op_iterations"] = 1 + operators_card["configs"]["evolution_method"] = "truncated" + operators_card["configs"]["ev_op_iterations"] = 1 + operators_card["configs"]["inversion_method"] = "expanded" elif tcard["ModEv"] == "EXA": - opconf["evolution_method"] = "iterate-exact" + operators_card["configs"]["evolution_method"] = "iterate-exact" + operators_card["configs"]["inversion_method"] = "exact" if "IterEv" in tcard: - opconf["ev_op_iterations"] = tcard["IterEv"] + operators_card["configs"]["ev_op_iterations"] = tcard["IterEv"] else: raise ValueError( "EXA used but IterEv not found in the theory card" @@ -282,17 +283,6 @@ def write_operator_card( raise ValueError( "Evolution method not set in theory card" ) - - if "inversion_method" in tcard: - opconf = operators_card["configs"] - opconf["inversion_method"] = tcard["inversion_method"] - else: - opconf["inversion_method"] = opcard_template.CONSTANTS["configs"]["inversion_method"] - logger.warning( - "Inversion method not set in theory card, it's being set to default value " - f"{opcard_template.CONSTANTS['configs']['inversion_method']}. " - "Check if that is what you want." - ) # Some safety checks if ( From 7a3167c485064b6deb32a39db50984f7a7e46f49 Mon Sep 17 00:00:00 2001 From: Eva Groenendijk Date: Thu, 21 May 2026 20:50:37 +0200 Subject: [PATCH 20/20] Remove time_like and polarized keys from operator card --- src/pineko/evolve.py | 6 +----- src/pineko/opcard_template.py | 3 --- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/pineko/evolve.py b/src/pineko/evolve.py index c648ce56..1558878f 100644 --- a/src/pineko/evolve.py +++ b/src/pineko/evolve.py @@ -221,11 +221,7 @@ def write_operator_card( xif = 1.0 if sv_method is not None else tcard["XIF"] # update scale variation method operators_card["configs"]["scvar_method"] = sv_scheme(tcard) - for key in ["polarized", - "time_like", - "ev_op_max_order", - ]: - operators_card["configs"][key] = opcard_template.CONSTANTS["configs"][key] + operators_card["configs"]["ev_op_max_order"] = opcard_template.CONSTANTS["configs"]["ev_op_max_order"] operators_card["debug"] = opcard_template.CONSTANTS["debug"] operators_card["init"] = (tcard["Q0"], tcard["nf0"]) # setting the parameters from the cli diff --git a/src/pineko/opcard_template.py b/src/pineko/opcard_template.py index 91c15c2c..1a27925e 100644 --- a/src/pineko/opcard_template.py +++ b/src/pineko/opcard_template.py @@ -56,10 +56,7 @@ CONSTANTS = { "configs": { - "inversion_method": "expanded", - "polarized": False, "scvar_method": "null", - "time_like": False, "ev_op_max_order": [10, 0], }, "init": (1.65, 4),