diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6f413f3b..768746f9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,7 +20,7 @@ repos: hooks: - id: pycln args: [--config=pyproject.toml] - - repo: https://github.com/psf/black + - repo: https://github.com/psf/black-pre-commit-mirror rev: 23.11.0 hooks: - id: black diff --git a/benchmarks/bench_evolve.py b/benchmarks/bench_evolve.py index 27dd876a..a11ef73b 100644 --- a/benchmarks/bench_evolve.py +++ b/benchmarks/bench_evolve.py @@ -39,7 +39,7 @@ def benchmark_write_operator_card_from_file_num_fonll( # Check if the opcards are ok for opcard_path, cfg in zip( targets_path_list, - pineko.fonll.MIXED_FNS_CONFIG if is_mixed else pineko.fonll.FNS_CONFIG, + pineko.fonll.FNS_CONFIG, ): with open(opcard_path, encoding="utf-8") as f: ocard = yaml.safe_load(f) diff --git a/benchmarks/bench_fonll.py b/benchmarks/bench_fonll.py index 2f2381ff..27e81c33 100644 --- a/benchmarks/bench_fonll.py +++ b/benchmarks/bench_fonll.py @@ -1,4 +1,3 @@ -import numpy as np import pytest import yaml @@ -19,7 +18,7 @@ def benchmark_produce_fonll_tcards( base_pto = pineko.fonll.FNS_BASE_PTO[tcard["FNS"]] for num_fonll_tcard, cfg in zip( theorycards, - pineko.fonll.MIXED_FNS_CONFIG if is_mixed else pineko.fonll.FNS_CONFIG, + pineko.fonll.FNS_CONFIG, ): po = int(base_pto) + (cfg.delta_pto if is_mixed else 0) assert num_fonll_tcard["FNS"] == cfg.scheme diff --git a/src/pineko/cli/fonll.py b/src/pineko/cli/fonll.py index becc5cac..7a061fa4 100644 --- a/src/pineko/cli/fonll.py +++ b/src/pineko/cli/fonll.py @@ -47,11 +47,9 @@ def grids_names(yaml_file): @click.argument("dataset", type=str) @click.option("--FFNS3", type=int, help="theoryID containing the ffns3 fktable") @click.option("--FFN03", type=int, help="theoryID containing the ffn03 fktable") -@click.option("--FFNS4", type=int, help="theoryID containing the ffns4 fktable") @click.option("--FFNS4til", type=int, help="theoryID containing the ffns4til fktable") @click.option("--FFNS4bar", type=int, help="theoryID containing the ffns4bar fktable") @click.option("--FFN04", type=int, help="theoryID containing the ffn04 fktable") -@click.option("--FFNS5", type=int, help="theoryID containing the ffns5 fktable") @click.option("--FFNS5til", type=int, help="theoryID containing the ffns5til fktable") @click.option("--FFNS5bar", type=int, help="theoryID containing the ffns5bar fktable") @click.option("--overwrite", is_flag=True, help="Allow files to be overwritten") @@ -61,11 +59,9 @@ def subcommand( dataset, ffns3, ffn03, - ffns4, ffns4til, ffns4bar, ffn04, - ffns5, ffns5til, ffns5bar, overwrite, @@ -83,40 +79,18 @@ def subcommand( if not ffns3 or not ffn03: raise InconsistentInputsError("ffns3 and/or ffn03 is not provided.") - if any([ffns4, ffns4til, ffns4bar]): - if ffns4: - if any([ffns4til, ffns4bar]): - raise InconsistentInputsError( - "If ffns4 is provided no ffnstil or ffnsbar should be provided." - ) - else: - if ffns4til is None or ffns4bar is None: - raise InconsistentInputsError( - "if ffnstil is provided also ffnsbar should be provided, and vice versa." - ) - else: - raise InconsistentInputsError("ffns4 is not provided.") - - # Do we consider two masses, i.e. mc and mb - two_masses = False - if any([ffns5, ffns5til, ffns5bar]): - two_masses = True - if ffns5: - if any([ffns5til, ffns5bar]): - raise InconsistentInputsError( - "If ffns5 is provided no ffnstil or ffnsbar should be provided." - ) - else: - if ffns5til is None or ffns5bar is None: - raise InconsistentInputsError( - "if ffnstil is provided also ffnsbar should be provided, and vice versa." - ) - - if (ffn04 is None and two_masses) or (ffn04 is not None and not two_masses): + if ffns4til is None or ffns4bar is None: raise InconsistentInputsError( - "If two masses are to be considered, both ffn04 and the nf=5 coefficient should be provided" + "At least one of ffns4til and ffns4bar should be provided." ) + # Do we consider two masses, i.e. mc and mb + if any([ffns5til, ffns5bar, ffn04]): + if (ffns5til is None and ffns5bar is None) or ffn04 is None: + raise InconsistentInputsError( + "To include nf5 contributions, ffn04 and at least one between ffns5til and ffns5bar are mandatory" + ) + # Get theory info tcard = theory_card.load(theoryid) if tcard["DAMP"] == 1: @@ -144,11 +118,9 @@ def subcommand( for name in ( ffns3, ffn03, - ffns4, ffns4til, ffns4bar, ffn04, - ffns5, ffns5til, ffns5bar, ) diff --git a/src/pineko/fonll.py b/src/pineko/fonll.py index 2d9fb548..469e643c 100644 --- a/src/pineko/fonll.py +++ b/src/pineko/fonll.py @@ -40,31 +40,30 @@ class FONLLInfo: """Class containing all the information for FONLL predictions.""" def __init__( - self, ffns3, ffn03, ffns4, ffns4til, ffns4bar, ffn04, ffns5, ffns5til, ffns5bar + self, ffns3, ffn03, ffns4til, ffns4bar, ffn04, ffns5til, ffns5bar ) -> None: """Initialize fonll info.""" self.paths = { "ffns3": ffns3, "ffn03": ffn03, - "ffns4": ffns4, "ffns4til": ffns4til, "ffns4bar": ffns4bar, "ffn04": ffn04, - "ffns5": ffns5, "ffns5til": ffns5til, "ffns5bar": ffns5bar, } - actually_existing_paths = [p for p in self.paths if self.paths[p] is not None] + actually_existing_paths = [p for p, g in self.paths.items() if g is not None] for p in self.paths: if p not in actually_existing_paths: logger.warning( - f"Warning! FK table for {p} does not exist and thus is being skipped." + "Warning! FK table for %s does not exist and thus is being skipped.", + p, ) @property def fk_paths(self): """Returns the list of the FK table paths needed to produce FONLL predictions.""" - return {p: Path(self.paths[p]) for p in self.paths if self.paths[p] is not None} + return {p: Path(self.paths[p]) for p, g in self.paths.items() if g is not None} @property def fks(self): @@ -106,8 +105,11 @@ def Q2grid(self): def update_fk_theorycard(combined_fk, input_theorycard_path): - """Update theorycard entries for the combined fktable by reading the yamldb of the original theory.""" - with open(input_theorycard_path) as f: + """Update theorycard entries for the combined FK table. + + Update by reading the yamldb of the original theory. + """ + with open(input_theorycard_path, encoding="utf-8") as f: final_theorycard = yaml.safe_load(f) theorycard = json.loads(combined_fk.key_values()["theory"]) theorycard["FNS"] = final_theorycard["FNS"] @@ -147,8 +149,8 @@ def combine(fk_dict, dampings=None): sign = -1 if fk in FK_WITH_MINUS else 1 fk_dict[fk].scale(sign) if dampings is not None: - for mass in FK_TO_DAMP: - if fk in FK_TO_DAMP[mass]: + for mass, fks in FK_TO_DAMP.items(): + if fk in fks: fk_dict[fk].scale_by_bin(dampings[mass]) fk_dict[fk].write_lz4(tmpfile_path) combined_fk.merge_from_file(tmpfile_path) @@ -158,11 +160,9 @@ def combine(fk_dict, dampings=None): def produce_combined_fk( ffns3, ffn03, - ffns4, ffns4til, ffns4bar, ffn04, - ffns5, ffns5til, ffns5bar, theoryid, @@ -170,9 +170,7 @@ def produce_combined_fk( cfg=None, ): """Combine the FONLL FK tables into one single FK table.""" - fonll_info = FONLLInfo( - ffns3, ffn03, ffns4, ffns4til, ffns4bar, ffn04, ffns5, ffns5til, ffns5bar - ) + fonll_info = FONLLInfo(ffns3, ffn03, ffns4til, ffns4bar, ffn04, ffns5til, ffns5bar) theorycard_constituent_fks = fonll_info.theorycard_no_fns_pto fk_dict = fonll_info.fks dampings = ( @@ -210,7 +208,7 @@ def scheme(self): return "FONLL-FFN" + ("0" if self.asy else "S") -MIXED_FNS_CONFIG = [ +FNS_CONFIG = [ SubTheoryConfig(False, 3, "full", 1), SubTheoryConfig(True, 3, "full", 1), SubTheoryConfig(False, 4, "massless"), @@ -221,23 +219,13 @@ def scheme(self): ] """Mixed FONLL schemes.""" -FNS_CONFIG = [ - SubTheoryConfig(False, 3, "full"), - SubTheoryConfig(True, 3, "full"), - SubTheoryConfig(False, 4, "full"), - SubTheoryConfig(True, 4, "full"), - SubTheoryConfig(False, 5, "full"), -] -"""Plain FONLL schemes.""" - -def collect_updates(fonll_fns, damp): +def collect_updates(fonll_fns): """Produce the different theory cards according to which FONLL is asked for.""" updates = [] is_mixed = fonll_fns in MIXED_ORDER_FNS - is_damped = damp != 0 base_pto = FNS_BASE_PTO[fonll_fns] - cfgs = MIXED_FNS_CONFIG if is_mixed or is_damped else FNS_CONFIG + cfgs = FNS_CONFIG for cfg in cfgs: po = int(base_pto) + (cfg.delta_pto if is_mixed else 0) updates.append( @@ -260,9 +248,10 @@ def collect_updates(fonll_fns, damp): def dump_tcards(tcard, tcard_parent_path, theoryid): """Produce the seven FONLL theory cards from the original one. - The produced theory cards are dumped in `tcard_parent_path` with names from '{theoryid}00.yaml' to '{theoryid}06.yaml'. + The produced theory cards are dumped in `tcard_parent_path` with names + from '{theoryid}00.yaml' to '{theoryid}06.yaml'. """ - updates = collect_updates(tcard["FNS"], tcard["DAMP"]) + updates = collect_updates(tcard["FNS"]) n_theory = len(updates) theorycards = [copy.deepcopy(tcard) for _ in range(n_theory)] paths_list = [] diff --git a/tests/test_fonll.py b/tests/test_fonll.py index bb947ad1..7a11d08a 100644 --- a/tests/test_fonll.py +++ b/tests/test_fonll.py @@ -7,11 +7,9 @@ def test_FONLLInfo(): full_list = [ "ffns3.pineappl.lz4", "ffn03.pineappl.lz4", - "ffns4.pineappl.lz4", "ffns4til.pineappl.lz4", "ffns4bar.pineappl.lz4", "ffn04.pineappl.lz4", - "ffns5.pineappl.lz4", "ffns5til.pineappl.lz4", "ffns5bar.pineappl.lz4", ] @@ -24,20 +22,16 @@ def test_FONLLInfo(): full_list[4], None, None, - None, - full_list[8], ) partialfonll_fake_info = pineko.fonll.FONLLInfo( - full_list[0], full_list[1], None, full_list[3], None, None, None, None, None + full_list[0], full_list[1], full_list[2], full_list[3], None, None, None ) name_list = [ "ffns3", "ffn03", - "ffns4", "ffns4til", "ffns4bar", "ffn04", - "ffns5", "ffns5til", "ffns5bar", ] @@ -47,14 +41,12 @@ def test_FONLLInfo(): assert wrongfonll_fake_info.fk_paths == { name: pathlib.Path(fk) for name, fk in zip( - name_list[:2] + name_list[3:5] + [name_list[-1]], - full_list[:2] + full_list[3:5] + [full_list[-1]], + name_list[:2] + name_list[3:5], + full_list[:2] + full_list[3:5], ) } assert partialfonll_fake_info.fk_paths == { name: pathlib.Path(fk) - for name, fk in zip( - name_list[:2] + name_list[3:4], full_list[:2] + full_list[3:4] - ) + for name, fk in zip(name_list[:4], full_list[:4]) if fk is not None }