From 411ba5938864f679c1640a98fe8233deaea85b67 Mon Sep 17 00:00:00 2001 From: yucongalicechen Date: Sat, 22 Feb 2025 22:23:48 -0500 Subject: [PATCH 1/3] initial commit --- src/diffpy/labpdfproc/tools.py | 30 +++++++++++++++++++++++++++++- tests/conftest.py | 1 + tests/test_tools.py | 23 +++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/diffpy/labpdfproc/tools.py b/src/diffpy/labpdfproc/tools.py index 3850673..75b34ff 100644 --- a/src/diffpy/labpdfproc/tools.py +++ b/src/diffpy/labpdfproc/tools.py @@ -7,6 +7,7 @@ XQUANTITIES, ) from diffpy.utils.tools import ( + _load_config, check_and_build_global_config, compute_mud, get_package_info, @@ -159,6 +160,33 @@ def set_input_lists(args): return args +def _load_wavelength_from_config_file(args): + """Load wavelength and anode type from config files. + It takes cli inputs first, and local config, and then global config. + + Parameters + ---------- + args : argparse.Namespace + The arguments from the parser. + + Returns + ------- + args : argparse.Namespace + The updated arguments with the updated wavelength and anode type. + """ + if args.wavelength or args.anode_type: + return args + global_config = _load_config(Path().home() / "diffpyconfig.json") + local_config = _load_config(Path().cwd() / "diffpyconfig.json") + if local_config: + args.wavelength = local_config.get("wavelength") + args.anode_type = local_config.get("anode_type") + elif global_config: + args.wavelength = global_config.get("wavelength") + args.anode_type = global_config.get("anode_type") + return args + + def set_wavelength(args): """Set the wavelength based on the given anode_type or wavelength. @@ -185,7 +213,7 @@ def set_wavelength(args): args : argparse.Namespace The updated arguments with the wavelength. """ - # first load values from config file + args = _load_wavelength_from_config_file(args) if args.wavelength is None and args.anode_type is None: if args.xtype not in ANGLEQUANTITIES: raise ValueError( diff --git a/tests/conftest.py b/tests/conftest.py index 2dcb4a5..18055f9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -60,6 +60,7 @@ def user_filesystem(tmp_path): f.write(f"{str(input_dir.resolve() / 'good_data.txt')}\n") home_config_data = { + "wavelength": 0.25, "owner_name": "home_username", "owner_email": "home@email.com", "owner_orcid": "home_orcid", diff --git a/tests/test_tools.py b/tests/test_tools.py index e6f2269..0e2a8fa 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -6,6 +6,7 @@ from diffpy.labpdfproc.labpdfprocapp import get_args from diffpy.labpdfproc.tools import ( + _load_wavelength_from_config_file, known_sources, load_metadata, load_package_info, @@ -195,6 +196,28 @@ def test_set_output_directory_bad(user_filesystem): assert not Path(actual_args.output_directory).is_dir() +def test_load_wavelength_from_config_file_with_home_conf_file(): + # C1: args provided, return args + # C2: no args, local config exists, return local config + # C3: no args or local config file, return global config + return True + + +def test_load_wavelength_from_config_file_with_local_conf_file(): + # C1: args provided, return args + # C2: no args, return local config file + # remove global config file to test again + return True + + +def test_load_wavelength_from_config_file_without_conf_files(user_filesystem): + # C1: args provided, return args + cli_inputs = ["2.5", "data.xy", "-w", "0.25"] + actual_args = get_args(cli_inputs) + actual_args = _load_wavelength_from_config_file(actual_args) + assert actual_args.wavelength == 0.25 + + @pytest.mark.parametrize( "inputs, expected", [ From bc118ea36092ad303b483ce6d0062db5c0a24937 Mon Sep 17 00:00:00 2001 From: yucongalicechen Date: Mon, 24 Feb 2025 18:19:13 -0500 Subject: [PATCH 2/3] feat: add tests --- tests/conftest.py | 2 +- tests/test_tools.py | 122 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 109 insertions(+), 15 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 18055f9..63d4646 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -60,7 +60,7 @@ def user_filesystem(tmp_path): f.write(f"{str(input_dir.resolve() / 'good_data.txt')}\n") home_config_data = { - "wavelength": 0.25, + "wavelength": 0.3, "owner_name": "home_username", "owner_email": "home@email.com", "owner_orcid": "home_orcid", diff --git a/tests/test_tools.py b/tests/test_tools.py index 0e2a8fa..ac5cfa5 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -1,3 +1,4 @@ +import json import os import re from pathlib import Path @@ -196,26 +197,119 @@ def test_set_output_directory_bad(user_filesystem): assert not Path(actual_args.output_directory).is_dir() -def test_load_wavelength_from_config_file_with_home_conf_file(): - # C1: args provided, return args - # C2: no args, local config exists, return local config - # C3: no args or local config file, return global config - return True +@pytest.mark.parametrize( + "inputs, expected", + [ + # Test when only a home config file exists (no local config file), + # expect to return args if wavelength or anode type is specified, + # otherwise update args with values from the home config file. + # C1: no args, expect to update arg values from home config + ([""], {"wavelength": 0.3, "anode_type": None}), + # C2: wavelength provided, expect to return args unchanged + (["--wavelength", "0.25"], {"wavelength": 0.25, "anode_type": None}), + # C3: anode type provided, expect to return args unchanged + (["--anode-type", "Mo"], {"wavelength": None, "anode_type": "Mo"}), + # C4: both wavelength and anode type provided, + # expect to return args unchanged + ( + ["--wavelength", "0.7", "--anode-type", "Mo"], + {"wavelength": 0.7, "anode_type": "Mo"}, + ), + ], +) +def test_load_wavelength_from_config_file_with_home_conf_file( + mocker, user_filesystem, inputs, expected +): + cwd = Path(user_filesystem) + home_dir = cwd / "home_dir" + mocker.patch("pathlib.Path.home", lambda _: home_dir) + os.chdir(cwd) + + cli_inputs = ["2.5", "data.xy"] + inputs + actual_args = get_args(cli_inputs) + actual_args = _load_wavelength_from_config_file(actual_args) + assert actual_args.wavelength == expected["wavelength"] + assert actual_args.anode_type == expected["anode_type"] + + +@pytest.mark.parametrize( + "inputs, expected", + [ + # Test when a local config file exists, + # expect to return args if wavelength or anode type is specified, + # otherwise update args with values from the home config file. + # Results should be the same whether if the home config exists. + # C1: no args, expect to update arg values from local config + ([""], {"wavelength": 0.6, "anode_type": None}), + # C2: wavelength provided, expect to return args unchanged + (["--wavelength", "0.25"], {"wavelength": 0.25, "anode_type": None}), + # C3: anode type provided, expect to return args unchanged + (["--anode-type", "Mo"], {"wavelength": None, "anode_type": "Mo"}), + # C4: both wavelength and anode type provided, + # expect to return args unchanged + ( + ["--wavelength", "0.7", "--anode-type", "Mo"], + {"wavelength": 0.7, "anode_type": "Mo"}, + ), + ], +) +def test_load_wavelength_from_config_file_with_local_conf_file( + mocker, user_filesystem, inputs, expected +): + cwd = Path(user_filesystem) + home_dir = cwd / "home_dir" + mocker.patch("pathlib.Path.home", lambda _: home_dir) + os.chdir(cwd) + local_config_data = {"wavelength": 0.6} + with open(cwd / "diffpyconfig.json", "w") as f: + json.dump(local_config_data, f) + cli_inputs = ["2.5", "data.xy"] + inputs + actual_args = get_args(cli_inputs) + actual_args = _load_wavelength_from_config_file(actual_args) + assert actual_args.wavelength == expected["wavelength"] + assert actual_args.anode_type == expected["anode_type"] -def test_load_wavelength_from_config_file_with_local_conf_file(): - # C1: args provided, return args - # C2: no args, return local config file - # remove global config file to test again - return True + # remove home config file, expect the same results + confile = home_dir / "diffpyconfig.json" + os.remove(confile) + assert actual_args.wavelength == expected["wavelength"] + assert actual_args.anode_type == expected["anode_type"] -def test_load_wavelength_from_config_file_without_conf_files(user_filesystem): - # C1: args provided, return args - cli_inputs = ["2.5", "data.xy", "-w", "0.25"] +@pytest.mark.parametrize( + "inputs, expected", + [ + # Test when no config files exist, + # expect to return args without modification. + # C1: no args + ([""], {"wavelength": None, "anode_type": None}), + # C1: wavelength provided + (["--wavelength", "0.25"], {"wavelength": 0.25, "anode_type": None}), + # C2: anode type provided + (["--anode-type", "Mo"], {"wavelength": None, "anode_type": "Mo"}), + # C4: both wavelength and anode type provided + ( + ["--wavelength", "0.7", "--anode-type", "Mo"], + {"wavelength": 0.7, "anode_type": "Mo"}, + ), + ], +) +def test_load_wavelength_from_config_file_without_conf_files( + mocker, user_filesystem, inputs, expected +): + cwd = Path(user_filesystem) + home_dir = cwd / "home_dir" + mocker.patch("pathlib.Path.home", lambda _: home_dir) + os.chdir(cwd) + confile = home_dir / "diffpyconfig.json" + os.remove(confile) + + cli_inputs = ["2.5", "data.xy"] + inputs actual_args = get_args(cli_inputs) actual_args = _load_wavelength_from_config_file(actual_args) - assert actual_args.wavelength == 0.25 + assert actual_args.wavelength == expected["wavelength"] + assert actual_args.anode_type == expected["anode_type"] @pytest.mark.parametrize( From c6c8b670cf1ddc25b332a3c022bf61fd34784f1a Mon Sep 17 00:00:00 2001 From: yucongalicechen Date: Mon, 24 Feb 2025 18:20:13 -0500 Subject: [PATCH 3/3] docs: add news --- news/wavelength-config.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/wavelength-config.rst diff --git a/news/wavelength-config.rst b/news/wavelength-config.rst new file mode 100644 index 0000000..ba90ac7 --- /dev/null +++ b/news/wavelength-config.rst @@ -0,0 +1,23 @@ +**Added:** + +* Functionality to allow users to specify wavelength or anode type in a diffpy config file. + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +*