From c66a031069c7ed6ec11a075f451da8cb294f4323 Mon Sep 17 00:00:00 2001 From: mschwoerer <82171591+mschwoer@users.noreply.github.com> Date: Thu, 23 Jan 2025 16:37:14 +0100 Subject: [PATCH 1/6] fix --fasta parameter not working --- alphadia/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alphadia/cli.py b/alphadia/cli.py index 8d3e86d1..5c1a8099 100644 --- a/alphadia/cli.py +++ b/alphadia/cli.py @@ -211,7 +211,7 @@ def run(*args, **kwargs): cli_params_config = { **({ConfigKeys.RAW_PATHS: raw_paths} if raw_paths else {}), **({ConfigKeys.LIBRARY_PATH: args.library} if args.library is not None else {}), - **({ConfigKeys.FASTA_PATHS: args.library} if args.fasta else {}), + **({ConfigKeys.FASTA_PATHS: args.fasta} if args.fasta else {}), **( {ConfigKeys.QUANT_DIRECTORY: args.library} if args.quant_dir is not None From 683f6df190beda06d394a256964b4c331cc82532 Mon Sep 17 00:00:00 2001 From: mschwoerer <82171591+mschwoer@users.noreply.github.com> Date: Thu, 23 Jan 2025 16:37:22 +0100 Subject: [PATCH 2/6] fix --quant_dir parameter not working --- alphadia/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alphadia/cli.py b/alphadia/cli.py index 5c1a8099..a43d2c45 100644 --- a/alphadia/cli.py +++ b/alphadia/cli.py @@ -213,7 +213,7 @@ def run(*args, **kwargs): **({ConfigKeys.LIBRARY_PATH: args.library} if args.library is not None else {}), **({ConfigKeys.FASTA_PATHS: args.fasta} if args.fasta else {}), **( - {ConfigKeys.QUANT_DIRECTORY: args.library} + {ConfigKeys.QUANT_DIRECTORY: args.quant_dir} if args.quant_dir is not None else {} ), From 4176ed033ef273b001cd1ec4c38491580e878d5f Mon Sep 17 00:00:00 2001 From: mschwoerer <82171591+mschwoer@users.noreply.github.com> Date: Thu, 23 Jan 2025 17:15:01 +0100 Subject: [PATCH 3/6] add tests --- tests/unit_tests/test_cli.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/tests/unit_tests/test_cli.py b/tests/unit_tests/test_cli.py index 7ed5c405..1d743bbb 100644 --- a/tests/unit_tests/test_cli.py +++ b/tests/unit_tests/test_cli.py @@ -1,10 +1,24 @@ -#!python -m unittest tests.test_utils """This module provides unit tests for alphadia.cli.""" -# builtin -import unittest +from unittest.mock import patch, MagicMock +from alphadia.cli import run -# local -if __name__ == "__main__": - unittest.main() +@patch("alphadia.cli.parser.parse_known_args") +@patch("alphadia.cli.reporting.init_logging") +@patch("alphadia.cli.SearchPlan") +def test_cli_minimal_args(mock_search_plan, mock_init_logging, mock_parse_known_args): + """Test the run function of the CLI with minimal arguments.""" + mock_args = MagicMock(config=None, version=None, output="/output") + mock_parse_known_args.return_value = (mock_args, []) + + # when + run() + + mock_search_plan.assert_called_once_with("/output", {}, { + 'library_path': mock_args.library, + 'fasta_paths': mock_args.fasta, + 'quant_directory': mock_args.quant_dir} + ) + + mock_init_logging.assert_called_once_with("/output") From 166ff3b74572e2c1462b2e09314c4d9a5c8829b3 Mon Sep 17 00:00:00 2001 From: mschwoerer <82171591+mschwoer@users.noreply.github.com> Date: Thu, 23 Jan 2025 17:19:01 +0100 Subject: [PATCH 4/6] format --- tests/unit_tests/test_cli.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/unit_tests/test_cli.py b/tests/unit_tests/test_cli.py index 1d743bbb..5f94ff2f 100644 --- a/tests/unit_tests/test_cli.py +++ b/tests/unit_tests/test_cli.py @@ -1,6 +1,7 @@ """This module provides unit tests for alphadia.cli.""" -from unittest.mock import patch, MagicMock +from unittest.mock import MagicMock, patch + from alphadia.cli import run @@ -15,10 +16,14 @@ def test_cli_minimal_args(mock_search_plan, mock_init_logging, mock_parse_known_ # when run() - mock_search_plan.assert_called_once_with("/output", {}, { - 'library_path': mock_args.library, - 'fasta_paths': mock_args.fasta, - 'quant_directory': mock_args.quant_dir} - ) + mock_search_plan.assert_called_once_with( + "/output", + {}, + { + "library_path": mock_args.library, + "fasta_paths": mock_args.fasta, + "quant_directory": mock_args.quant_dir, + }, + ) mock_init_logging.assert_called_once_with("/output") From ebfa5bb73b4a2b884ec955e6164f5f5486f5056c Mon Sep 17 00:00:00 2001 From: mschwoerer <82171591+mschwoer@users.noreply.github.com> Date: Thu, 23 Jan 2025 17:50:54 +0100 Subject: [PATCH 5/6] add more tests --- tests/unit_tests/test_cli.py | 96 ++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/tests/unit_tests/test_cli.py b/tests/unit_tests/test_cli.py index 5f94ff2f..8adfb100 100644 --- a/tests/unit_tests/test_cli.py +++ b/tests/unit_tests/test_cli.py @@ -1,15 +1,75 @@ """This module provides unit tests for alphadia.cli.""" -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock, mock_open, patch -from alphadia.cli import run +import yaml + +from alphadia.cli import _get_config_from_args, _get_from_args_or_config, run + +# TODO add tests for _get_raw_path_list_from_args_and_config + + +def test_get_config_from_args(): + """Test the _get_config_from_args function correctly merges configs.""" + mock_args = MagicMock(config="config.yaml", config_dict='{"key3": "value3"}') + + yaml_content = {"key1": "value1", "key2": "value2"} + mock_yaml = yaml.dump(yaml_content) + + with patch("builtins.open", mock_open(read_data=mock_yaml)): + result = _get_config_from_args(mock_args) + + assert result == {"key1": "value1", "key2": "value2", "key3": "value3"} + + +def test_get_from_args_or_config_returns_value_from_args(): + """Test that the function returns the value from the args when it is not None.""" + args = MagicMock(output="cli_output") + config = {"output_directory": "config_output"} + + # when + result = _get_from_args_or_config( + args, config, args_key="output", config_key="output_directory" + ) + + assert result == "cli_output" + + +def test_get_from_args_or_config_returns_value_from_config_when_args_none(): + """Test that the function returns the value from the config when the args value is None.""" + args = MagicMock(output=None) + config = {"output_directory": "config_output"} + + # when + result = _get_from_args_or_config( + args, config, args_key="output", config_key="output_directory" + ) + + assert result == "config_output" + + +@patch("alphadia.cli.parser.parse_known_args") +@patch("builtins.print") +@patch("alphadia.cli.SearchPlan") +def test_cli_unknown_args( + mock_search_plan, + mock_print, + mock_parse_known_args, +): + mock_parse_known_args.return_value = (MagicMock, ["unknown_arg"]) + + # when + run() + + mock_print.assert_called_once_with("Unknown arguments: ['unknown_arg']") + mock_search_plan.assert_not_called() @patch("alphadia.cli.parser.parse_known_args") @patch("alphadia.cli.reporting.init_logging") @patch("alphadia.cli.SearchPlan") def test_cli_minimal_args(mock_search_plan, mock_init_logging, mock_parse_known_args): - """Test the run function of the CLI with minimal arguments.""" + """Test the run function of the CLI with minimal arguments maps correctly to SearchPlan.""" mock_args = MagicMock(config=None, version=None, output="/output") mock_parse_known_args.return_value = (mock_args, []) @@ -20,6 +80,7 @@ def test_cli_minimal_args(mock_search_plan, mock_init_logging, mock_parse_known_ "/output", {}, { + # TODO raw_paths missing here "library_path": mock_args.library, "fasta_paths": mock_args.fasta, "quant_directory": mock_args.quant_dir, @@ -27,3 +88,32 @@ def test_cli_minimal_args(mock_search_plan, mock_init_logging, mock_parse_known_ ) mock_init_logging.assert_called_once_with("/output") + + +@patch("alphadia.cli.parser.parse_known_args") +@patch("alphadia.cli.reporting.init_logging") +@patch("alphadia.cli.SearchPlan") +def test_cli_minimal_args_all_none( + mock_search_plan, mock_init_logging, mock_parse_known_args +): + """Test the run function of the CLI with minimal arguments maps correctly to SearchPlan if nothing given.""" + mock_args = MagicMock( + config=None, + version=None, + output="/output", + fasta=None, + library=None, + quant_dir=None, + ) + mock_parse_known_args.return_value = (mock_args, []) + + # when + run() + + mock_search_plan.assert_called_once_with( + "/output", + {}, + {}, + ) + + mock_init_logging.assert_called_once_with("/output") From 034a9f468c8c33e06813430a081df8e92f12f25a Mon Sep 17 00:00:00 2001 From: mschwoerer <82171591+mschwoer@users.noreply.github.com> Date: Fri, 24 Jan 2025 11:49:36 +0100 Subject: [PATCH 6/6] add some TODOs --- alphadia/utils.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/alphadia/utils.py b/alphadia/utils.py index 8de0e8ae..b1576a8d 100644 --- a/alphadia/utils.py +++ b/alphadia/utils.py @@ -63,7 +63,7 @@ def ion_hash(precursor_idx, number, type, charge): @nb.njit -def extended_ion_hash(precursor_idx, rank, number, type, charge): +def extended_ion_hash(precursor_idx, rank, number, type, charge): # TODO: unused? # create a 64 bit hash from the precursor_idx, number and type # the precursor_idx is the lower 32 bits # the number is the next 8 bits @@ -73,7 +73,9 @@ def extended_ion_hash(precursor_idx, rank, number, type, charge): return precursor_idx + (rank << 32) + (number << 40) + (type << 48) + (charge << 56) -def recursive_update(full_dict: dict, update_dict: dict): +def recursive_update( + full_dict: dict, update_dict: dict +): # TODO merge with Config._update """recursively update a dict with a second dict. The dict is updated inplace. Parameters @@ -99,12 +101,12 @@ def recursive_update(full_dict: dict, update_dict: dict): full_dict[key] = value -def normal(x, mu, sigma): +def normal(x, mu, sigma): # TODO: unused? """ """ return 1 / (sigma * np.sqrt(2 * np.pi)) * np.exp(-np.power((x - mu) / sigma, 2) / 2) -def plt_limits(mobility_limits, dia_cycle_limits): +def plt_limits(mobility_limits, dia_cycle_limits): # TODO: unused? mobility_len = mobility_limits[1] - mobility_limits[0] dia_cycle_len = dia_cycle_limits[1] - dia_cycle_limits[0] @@ -202,7 +204,7 @@ def amean0(array): @nb.njit() -def astd0(array): +def astd0(array): # TODO: unused? out = np.zeros(array.shape[1]) for i in range(len(out)): out[i] = np.std(array[:, i]) @@ -248,11 +250,11 @@ def mass_range(mz_list, ppm_tolerance): return out_mz -def function_call(q): +def function_call(q): # TODO: unused? q.put("X" * 1000000) -def modify(n, x, s, A): +def modify(n, x, s, A): # TODO: unused? n.value **= 2 x.value **= 2 s.value = s.value.upper() @@ -261,7 +263,7 @@ def modify(n, x, s, A): a.y **= 2 -class Point(Structure): +class Point(Structure): # TODO: unused? _fields_ = [("x", c_double), ("y", c_double)] @@ -315,7 +317,7 @@ def make_slice_2d(start_stop): @nb.njit -def fourier_filter(dense_stack, kernel): +def fourier_filter(dense_stack, kernel): # TODO: unused? """Numba helper function to apply a gaussian filter to a dense stack. The filter is applied as convolution wrapping around the edges, calculated in fourier space. @@ -512,7 +514,7 @@ def channel_score_groups(elution_group_idx, decoy, rank): @nb.njit() -def profile_correlation(profile, tresh=3, shift=2, kernel_size=12): +def profile_correlation(profile, tresh=3, shift=2, kernel_size=12): # TODO: unused? mask = np.sum((profile >= tresh).astype(np.int8), axis=0) == profile.shape[0] output = np.zeros(profile.shape, dtype=np.float32)