From d262c095574e9bf7127635318be4a66444006aaa Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Mon, 13 Jun 2022 11:58:23 +0200 Subject: [PATCH 1/5] add general parameter to cfg CLI --- src/haddock/clis/cli_cfg.py | 39 +++++++++++++++++-- src/haddock/gear/yaml2cfg.py | 8 +++- tests/__init__.py | 2 + .../configs/yaml2cfg_converted_no_header.cfg | 32 +++++++++++++++ tests/test_cli_cfg.py | 9 +++++ tests/test_yaml2cfg.py | 23 ++++++++++- 6 files changed, 106 insertions(+), 7 deletions(-) create mode 100644 tests/configs/yaml2cfg_converted_no_header.cfg diff --git a/src/haddock/clis/cli_cfg.py b/src/haddock/clis/cli_cfg.py index 5e1e438ca..ead5561b2 100644 --- a/src/haddock/clis/cli_cfg.py +++ b/src/haddock/clis/cli_cfg.py @@ -8,14 +8,15 @@ haddock3-cfg -m MODULE haddock3-cfg -m MODULE -l LEVEL + haddock3-cfg -m topoaa -l all + haddock3-cfg -m rigidbody -l all -g """ import argparse import importlib +import os import sys from haddock import config_expert_levels -from haddock.gear.yaml2cfg import yaml2cfg_text -from haddock.libs.libio import read_from_yaml from haddock.modules import modules_category @@ -42,6 +43,13 @@ choices=config_expert_levels + ("all",), ) +ap.add_argument( + '-g', + dest='add_global', + help="Add also the optional module's general parameters.", + action="store_true", + ) + def _ap(): return ap @@ -65,8 +73,12 @@ def maincli(): cli(ap, main) -def main(module, explevel): +def main(module, explevel, add_global=True): """Extract the default configuration file for a given module.""" + from haddock import modules_defaults_path + from haddock.gear.yaml2cfg import yaml2cfg_text + from haddock.libs.libio import read_from_yaml + module_name = ".".join(( 'haddock', 'modules', @@ -78,8 +90,27 @@ def main(module, explevel): cfg = module_lib.DEFAULT_CONFIG ycfg = read_from_yaml(cfg) - new_config = yaml2cfg_text(ycfg, module, explevel) + + if add_global: + general_cfg = read_from_yaml(modules_defaults_path) + general_params_str = yaml2cfg_text( + general_cfg, + module=None, + explevel="all", + ) + comment = os.linesep.join(( + "# The parameters below are optional parameters. ", + "# They can either be used as global parameters or as part ", + "# of the module's parameters", + )) + + new_config = os.linesep.join(( + comment, + general_params_str, + new_config, + )) + print(new_config, file=sys.stdout, flush=True) # noqa: T201 return 0 diff --git a/src/haddock/gear/yaml2cfg.py b/src/haddock/gear/yaml2cfg.py index c545cc777..fb366b571 100644 --- a/src/haddock/gear/yaml2cfg.py +++ b/src/haddock/gear/yaml2cfg.py @@ -33,7 +33,8 @@ def yaml2cfg_text(ymlcfg, module, explevel): parameters will be considered. """ new_config = [] - new_config.append(f"[{module}]") + if module is not None: + new_config.append(f"[{module}]") new_config.append(_yaml2cfg_text(ymlcfg, module, explevel)) @@ -68,7 +69,10 @@ def _yaml2cfg_text(ycfg, module, explevel): if isinstance(param, Mapping) and "default" not in param: params.append("") # give extra space - curr_module = f"{module}.{param_name}" + if module is not None: + curr_module = f"{module}.{param_name}" + else: + curr_module = param_name params.append(f"[{curr_module}]") _ = _yaml2cfg_text(param, module=curr_module, explevel=explevel) params.append(_) diff --git a/tests/__init__.py b/tests/__init__.py index 29afd2059..88b5f5ed1 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -11,6 +11,8 @@ emptycfg = Path(configs_data, 'empty.cfg') haddock3_yaml_cfg_examples = Path(configs_data, 'yml_example.yml') haddock3_yaml_converted = Path(configs_data, 'yaml2cfg_converted.cfg') +haddock3_yaml_converted_no_header = \ + Path(configs_data, 'yaml2cfg_converted_no_header.cfg') # defines which modules are already working working_modules = [t for t in modules_category.items() if t[0] != 'topocg'] diff --git a/tests/configs/yaml2cfg_converted_no_header.cfg b/tests/configs/yaml2cfg_converted_no_header.cfg new file mode 100644 index 000000000..c3d860a40 --- /dev/null +++ b/tests/configs/yaml2cfg_converted_no_header.cfg @@ -0,0 +1,32 @@ +autohis = True # $title Automatic HIS protonation state / $group molecule +delenph = True # $title Keep or remove non-polar hydrogen atoms / $group molecule +log_level = 'verbose' # $minchars 0 / $maxchars 100 / $title Log level verbosity for CNS / $group module +iniseed = 917 # $min 0 / $max 9999999999999999 / $precision 3 / $title Random seed / $group molecule +ligand_param_fname = '' # $title No title yet +ligand_top_fname = '' # $title No title yet +limit = True # $title No title yet +tolerance = 0 # $min -9999 / $max 9999 / $precision 3 / $title No title yet + +[mol1] +prot_segid = 'A' # $minchars 0 / $maxchars 100 / $title No title yet +fix_origin = False # $title No title yet +dna = False # $title No title yet +shape = False # $title No title yet +cg = False # $title No title yet +cyclicpept = False # $title No title yet +nhisd = 0 # $min -9999 / $max 9999 / $precision 3 / $title No title yet +hisd_1 = nan # $min -9999 / $max 9999 / $precision 3 / $title No title yet +nhise = 0 # $min -9999 / $max 9999 / $precision 3 / $title No title yet +hise_1 = nan # $min -9999 / $max 9999 / $precision 3 / $title No title yet + +[mol2] +prot_segid = 'B' # $minchars 0 / $maxchars 100 / $title No title yet +fix_origin = False # $title No title yet +dna = False # $title No title yet +shape = False # $title No title yet +cg = False # $title No title yet +cyclicpept = False # $title No title yet +nhisd = 0 # $min -9999 / $max 9999 / $precision 3 / $title No title yet +hisd_1 = nan # $min -9999 / $max 9999 / $precision 3 / $title No title yet +nhise = 0 # $min -9999 / $max 9999 / $precision 3 / $title No title yet +hise_1 = nan # $min -9999 / $max 9999 / $precision 3 / $title No title yet diff --git a/tests/test_cli_cfg.py b/tests/test_cli_cfg.py index 5c79e6f09..4b2de86ec 100644 --- a/tests/test_cli_cfg.py +++ b/tests/test_cli_cfg.py @@ -19,3 +19,12 @@ def config_level(request): def test_export_cfgs(module, config_level): """Test export all configs work.""" cli_cfg.main(module, config_level) + + +@pytest.mark.parametrize( + "module", + list(modules_category.keys()), + ) +def test_export_cfgs_add_global(module, config_level): + """Test export all configs work with `add_global` parameter.""" + cli_cfg.main(module, explevel=config_level, add_global=True) diff --git a/tests/test_yaml2cfg.py b/tests/test_yaml2cfg.py index acccebf28..0535be4a2 100644 --- a/tests/test_yaml2cfg.py +++ b/tests/test_yaml2cfg.py @@ -5,7 +5,11 @@ from haddock.gear.yaml2cfg import flat_yaml_cfg, yaml2cfg_text from haddock.libs.libio import read_from_yaml -from . import haddock3_yaml_cfg_examples, haddock3_yaml_converted +from . import ( + haddock3_yaml_cfg_examples, + haddock3_yaml_converted, + haddock3_yaml_converted_no_header, + ) complex_cfg = { @@ -76,3 +80,20 @@ def test_yaml2cfg_test(): assert filecmp.cmp(p, haddock3_yaml_converted, shallow=False) p.unlink() + + +def test_yaml2cfg_test_no_header(): + """Test yaml dict to cfg.""" + ycfg = read_from_yaml(haddock3_yaml_cfg_examples) + result = yaml2cfg_text(ycfg, None, "all") + assert isinstance(result, str) + + p = Path('dummy_test.cfg') + p.write_text(result) + + assert filecmp.cmp( + p, + haddock3_yaml_converted_no_header, + shallow=False, + ) + p.unlink() From dc497907be555dc704510062d8bfa5921beedbcf Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Mon, 13 Jun 2022 12:00:01 +0200 Subject: [PATCH 2/5] rename file --- tests/{test_yaml2cfg.py => test_gear_yaml2cfg.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{test_yaml2cfg.py => test_gear_yaml2cfg.py} (100%) diff --git a/tests/test_yaml2cfg.py b/tests/test_gear_yaml2cfg.py similarity index 100% rename from tests/test_yaml2cfg.py rename to tests/test_gear_yaml2cfg.py From 3bf5be7dc1bd65c6a58b286992a315d22937d1d0 Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Wed, 22 Jun 2022 12:47:16 +0200 Subject: [PATCH 3/5] with multiple params --- src/haddock/clis/cli_cfg.py | 87 ++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 21 deletions(-) diff --git a/src/haddock/clis/cli_cfg.py b/src/haddock/clis/cli_cfg.py index ead5561b2..f72427639 100644 --- a/src/haddock/clis/cli_cfg.py +++ b/src/haddock/clis/cli_cfg.py @@ -10,6 +10,7 @@ haddock3-cfg -m MODULE -l LEVEL haddock3-cfg -m topoaa -l all haddock3-cfg -m rigidbody -l all -g + haddock3-cfg -G """ import argparse import importlib @@ -26,15 +27,36 @@ formatter_class=argparse.RawDescriptionHelpFormatter, ) -ap.add_argument( +_group = ap.add_argument_group( + "Mandatory parameters", + "These parameters are mutually exclusive.", + ) +group = _group.add_mutually_exclusive_group(required=True) +groupm = ap.add_argument_group( + title="Additional arguments when selecting a module", + description=( + "Use these optional arguments together with the `-m` option. " + "If `-G` is given, these arguments will be ignored." + ), + ) + +group.add_argument( "-m", dest="module", help="The module for which you want to retrieve the default configuration.", - required=True, choices=sorted(modules_category.keys()), + default=None, ) -ap.add_argument( +group.add_argument( + "-G", + "--only-globals", + dest="only_globals", + help="Retrieve only the optional module's general parameters.", + action="store_true", + ) + +groupm.add_argument( "-l", dest="explevel", required=False, @@ -43,7 +65,7 @@ choices=config_expert_levels + ("all",), ) -ap.add_argument( +groupm.add_argument( '-g', dest='add_global', help="Add also the optional module's general parameters.", @@ -73,26 +95,33 @@ def maincli(): cli(ap, main) -def main(module, explevel, add_global=True): - """Extract the default configuration file for a given module.""" +def main(module=None, explevel="all", add_globals=True): + """ + Extract the defaults in the form of a run configuration file. + + Parameters + ---------- + module : str or None + The module name to extract the defaults from. ``None`` can be given + if ``only_globals`` is ``True``. + + explevel : str + Filter the parameters according to the expert level. Output all + parameters that belong to the referred level or below. Choices + are: all, easy, expert, and guru. + + add_globals : bool + Whether to add the module's general global parameter. If this + option is given and ``module`` is ``None``, outputs only the + general parameters. + """ from haddock import modules_defaults_path from haddock.gear.yaml2cfg import yaml2cfg_text from haddock.libs.libio import read_from_yaml - module_name = ".".join(( - 'haddock', - 'modules', - modules_category[module], - module, - )) + new_config = '' - module_lib = importlib.import_module(module_name) - cfg = module_lib.DEFAULT_CONFIG - - ycfg = read_from_yaml(cfg) - new_config = yaml2cfg_text(ycfg, module, explevel) - - if add_global: + if add_globals: general_cfg = read_from_yaml(modules_defaults_path) general_params_str = yaml2cfg_text( general_cfg, @@ -108,10 +137,26 @@ def main(module, explevel, add_global=True): new_config = os.linesep.join(( comment, general_params_str, - new_config, )) - print(new_config, file=sys.stdout, flush=True) # noqa: T201 + if module: + + module_name = ".".join(( + 'haddock', + 'modules', + modules_category[module], + module, + )) + + module_lib = importlib.import_module(module_name) + cfg = module_lib.DEFAULT_CONFIG + + ycfg = read_from_yaml(cfg) + module_config = yaml2cfg_text(ycfg, module, explevel) + + new_config = os.linesep.join((new_config, module_config)) + + sys.stdout.write(new_config, flush=True) return 0 From 388cbecd971d5290990ee463127bca389406c33c Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Wed, 22 Jun 2022 13:23:35 +0200 Subject: [PATCH 4/5] add option for globals only --- src/haddock/clis/cli_cfg.py | 70 +++++++++++++++++-------------------- tests/test_cli_cfg.py | 12 +++++-- 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/src/haddock/clis/cli_cfg.py b/src/haddock/clis/cli_cfg.py index f72427639..989ed7c1a 100644 --- a/src/haddock/clis/cli_cfg.py +++ b/src/haddock/clis/cli_cfg.py @@ -6,11 +6,12 @@ Usage:: - haddock3-cfg -m MODULE + haddock3-cfg # prints only the general parametes + haddock3-cfg -g # same as above + haddock3-cfg -m MODULE # prints only the module parameters haddock3-cfg -m MODULE -l LEVEL haddock3-cfg -m topoaa -l all - haddock3-cfg -m rigidbody -l all -g - haddock3-cfg -G + haddock3-cfg -m rigidbody -l all -g # prints the module and the globals """ import argparse import importlib @@ -27,20 +28,7 @@ formatter_class=argparse.RawDescriptionHelpFormatter, ) -_group = ap.add_argument_group( - "Mandatory parameters", - "These parameters are mutually exclusive.", - ) -group = _group.add_mutually_exclusive_group(required=True) -groupm = ap.add_argument_group( - title="Additional arguments when selecting a module", - description=( - "Use these optional arguments together with the `-m` option. " - "If `-G` is given, these arguments will be ignored." - ), - ) - -group.add_argument( +ap.add_argument( "-m", dest="module", help="The module for which you want to retrieve the default configuration.", @@ -48,15 +36,7 @@ default=None, ) -group.add_argument( - "-G", - "--only-globals", - dest="only_globals", - help="Retrieve only the optional module's general parameters.", - action="store_true", - ) - -groupm.add_argument( +ap.add_argument( "-l", dest="explevel", required=False, @@ -65,9 +45,10 @@ choices=config_expert_levels + ("all",), ) -groupm.add_argument( +ap.add_argument( '-g', - dest='add_global', + '--globals', + dest='global_params', help="Add also the optional module's general parameters.", action="store_true", ) @@ -87,6 +68,20 @@ def load_args(ap): def cli(ap, main): """Command-line interface entry point.""" cmd = load_args(ap) + + # I didn't want to to have the `--globals` param as a negative parameter + # ('store_false'). However, `module` and `globals` can't both be false. + # In order for the commands below performing the same: + # + # haddock3-cfg + # haddock3-cfg -g + # + # we need this quick if statement. Which basically adjust the argparse to + # the default values in the main function. + # @joaomcteixeira + if cmd.global_params is False and cmd.module is None: + cmd.global_params = True + main(**vars(cmd)) @@ -95,25 +90,26 @@ def maincli(): cli(ap, main) -def main(module=None, explevel="all", add_globals=True): +def main(module=None, explevel="all", global_params=True): """ Extract the defaults in the form of a run configuration file. Parameters ---------- module : str or None - The module name to extract the defaults from. ``None`` can be given - if ``only_globals`` is ``True``. + The module name to extract the defaults from. + If ``None`` given, we expect ``global_params`` to be ``True``, + otherwise nothing will be printed. explevel : str Filter the parameters according to the expert level. Output all parameters that belong to the referred level or below. Choices are: all, easy, expert, and guru. - add_globals : bool - Whether to add the module's general global parameter. If this - option is given and ``module`` is ``None``, outputs only the - general parameters. + global_params : bool + Whether to add the module's general global parameter. If + ``True`` and ``module`` is ``None``, outputs only the general + parameters. """ from haddock import modules_defaults_path from haddock.gear.yaml2cfg import yaml2cfg_text @@ -121,7 +117,7 @@ def main(module=None, explevel="all", add_globals=True): new_config = '' - if add_globals: + if global_params: general_cfg = read_from_yaml(modules_defaults_path) general_params_str = yaml2cfg_text( general_cfg, @@ -156,7 +152,7 @@ def main(module=None, explevel="all", add_globals=True): new_config = os.linesep.join((new_config, module_config)) - sys.stdout.write(new_config, flush=True) + sys.stdout.write(new_config) return 0 diff --git a/tests/test_cli_cfg.py b/tests/test_cli_cfg.py index 4b2de86ec..1efd82673 100644 --- a/tests/test_cli_cfg.py +++ b/tests/test_cli_cfg.py @@ -12,9 +12,15 @@ def config_level(request): return request.param +@pytest.fixture(params=(True, False)) +def global_params(request): + """Haddock3 config levels.""" + return request.param + + @pytest.mark.parametrize( "module", - list(modules_category.keys()), + list(modules_category.keys()) + [None], ) def test_export_cfgs(module, config_level): """Test export all configs work.""" @@ -25,6 +31,6 @@ def test_export_cfgs(module, config_level): "module", list(modules_category.keys()), ) -def test_export_cfgs_add_global(module, config_level): +def test_export_cfgs_add_global(module, config_level, global_params): """Test export all configs work with `add_global` parameter.""" - cli_cfg.main(module, explevel=config_level, add_global=True) + cli_cfg.main(module, explevel=config_level, global_params=global_params) From 83bcd116d57a10ae56acc0f60cc07ce5fb54ff1c Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Wed, 22 Jun 2022 13:27:31 +0200 Subject: [PATCH 5/5] simplify tests --- tests/test_cli_cfg.py | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/tests/test_cli_cfg.py b/tests/test_cli_cfg.py index 1efd82673..99cd8fdb7 100644 --- a/tests/test_cli_cfg.py +++ b/tests/test_cli_cfg.py @@ -18,19 +18,11 @@ def global_params(request): return request.param -@pytest.mark.parametrize( - "module", - list(modules_category.keys()) + [None], - ) -def test_export_cfgs(module, config_level): - """Test export all configs work.""" - cli_cfg.main(module, config_level) - - -@pytest.mark.parametrize( - "module", - list(modules_category.keys()), - ) +@pytest.fixture(params=list(modules_category.keys()) + [None]) +def module(request): + return request.param + + def test_export_cfgs_add_global(module, config_level, global_params): """Test export all configs work with `add_global` parameter.""" cli_cfg.main(module, explevel=config_level, global_params=global_params)