diff --git a/sensospot_data/parameters.py b/sensospot_data/parameters.py index 1d09d68..26a1579 100644 --- a/sensospot_data/parameters.py +++ b/sensospot_data/parameters.py @@ -3,8 +3,9 @@ Parsing the numerical output from Sensovations Sensospot image analysis. """ -from pathlib import Path -from collections import namedtuple +import pathlib +from typing import Any, Dict, Union, Optional +from xml.etree.ElementTree import Element as ElementType import numpy import pandas @@ -12,11 +13,12 @@ from defusedxml import ElementTree from . import columns +PathLike = Union[str, pathlib.Path] -def _search_measurement_params_file(folder): +def _search_params_file(folder: PathLike) -> Optional[PathLike]: """searches for a exposure settings file in a folder""" - folder_path = Path(folder) + folder_path = pathlib.Path(folder) params_folder = folder_path / "Parameters" if not params_folder.is_dir(): return None @@ -27,7 +29,7 @@ def _search_measurement_params_file(folder): return None -def _get_channel_data(channel_node): +def _get_channel_data(channel_node: ElementType) -> Dict[str, Any]: # child.tag == "ChannelConfig1" exposure_id = int(channel_node.tag[-1]) # channel_description == "[Cy3|Cy5] Green" @@ -42,24 +44,26 @@ def _get_channel_data(channel_node): } -def _parse_measurement_params(params_file): +def _parse_measurement_params(params_file: PathLike) -> pandas.DataFrame: """parses the cannel informations from a settings file""" - file_path = Path(params_file) + file_path = pathlib.Path(params_file) with file_path.open("r") as file_handle: tree = ElementTree.parse(file_handle) data = [_get_channel_data(child) for child in tree.find("Channels")] return pandas.DataFrame(data) -def get_measurement_params(folder): +def get_measurement_params(folder: PathLike) -> Optional[pandas.DataFrame]: """returns measurement parameters""" - params_file = _search_measurement_params_file(folder) + params_file = _search_params_file(folder) if params_file is not None: return _parse_measurement_params(params_file) return None -def add_optional_measurement_parameters(data_frame, folder): +def add_measurement_parameters( + data_frame: pandas.DataFrame, folder: PathLike +) -> pandas.DataFrame: """adds measurement params to the data frame, if they could be parsed""" params = get_measurement_params(folder) if params is not None: @@ -67,7 +71,7 @@ def add_optional_measurement_parameters(data_frame, folder): data_exposures = data_frame[columns.EXPOSURE_ID].unique() if set(data_exposures) == set(params_exposures): return data_frame.merge(params, how="left", on=columns.EXPOSURE_ID) - + # only executing if the parameters were not merged to the data frame data_frame[columns.PARAMETERS_CHANNEL] = numpy.nan data_frame[columns.PARAMETERS_TIME] = numpy.nan diff --git a/sensospot_data/parser.py b/sensospot_data/parser.py index 1b8515a..d8c4268 100755 --- a/sensospot_data/parser.py +++ b/sensospot_data/parser.py @@ -10,8 +10,7 @@ from collections import namedtuple import pandas from . import columns -from .parameters import add_optional_measurement_parameters - +from .parameters import add_measurement_parameters REGEX_WELL = re.compile( r""" @@ -146,7 +145,7 @@ def parse_folder(folder, quiet=False): data_frame = parse_multiple_files(file_list) except ValueError: raise ValueError(f"No sensospot data found in folder '{folder}'") - data_frame = add_optional_measurement_parameters(data_frame, folder_path) + data_frame = add_measurement_parameters(data_frame, folder_path) if quiet: return data_frame return _sanity_check(data_frame) diff --git a/tests/test_parameters.py b/tests/test_parameters.py index 48f2b5c..f2f8d1f 100644 --- a/tests/test_parameters.py +++ b/tests/test_parameters.py @@ -1,54 +1,51 @@ import pandas + from .conftest import EXAMPLE_DIR_WO_PARAMS, EXAMPLE_DIR_WITH_PARAMS -def test_search_measurement_params_file_ok(example_dir): - from sensospot_data.parameters import _search_measurement_params_file +def test_search_params_file_ok(example_dir): + from sensospot_data.parameters import _search_params_file - result = _search_measurement_params_file( - example_dir / EXAMPLE_DIR_WITH_PARAMS - ) + result = _search_params_file(example_dir / EXAMPLE_DIR_WITH_PARAMS) assert result.suffix == ".svexp" -def test_search_measurement_params_file_no_parameters_folder(example_dir): - from sensospot_data.parameters import _search_measurement_params_file +def test_search_params_file_no_parameters_folder(example_dir): + from sensospot_data.parameters import _search_params_file - result = _search_measurement_params_file( - example_dir / EXAMPLE_DIR_WO_PARAMS - ) + result = _search_params_file(example_dir / EXAMPLE_DIR_WO_PARAMS) assert result is None def test_ssearch_measurement_params_file_parameters_file(tmpdir): - from sensospot_data.parameters import _search_measurement_params_file + from sensospot_data.parameters import _search_params_file params_dir = tmpdir / "Parameters" params_dir.mkdir() - result = _search_measurement_params_file(tmpdir) + result = _search_params_file(tmpdir) assert result is None def test_parse_channel_info(example_dir): from sensospot_data.parameters import ( + _search_params_file, _parse_measurement_params, - _search_measurement_params_file, ) - params = _search_measurement_params_file( - example_dir / EXAMPLE_DIR_WITH_PARAMS - ) + params = _search_params_file(example_dir / EXAMPLE_DIR_WITH_PARAMS) result = _parse_measurement_params(params) - expected = pandas.DataFrame({ - "Exposure.Id": [1,2,3], - "Parameters.Channel": ["green", "red", "red"], - "Parameters.Time" : [100.0, 150.0, 15.0] - }) + expected = pandas.DataFrame( + { + "Exposure.Id": [1, 2, 3], + "Parameters.Channel": ["green", "red", "red"], + "Parameters.Time": [100.0, 150.0, 15.0], + } + ) assert result.equals(expected) @@ -58,12 +55,14 @@ def test_get_measurement_params_file_found(example_dir): result = get_measurement_params(example_dir / EXAMPLE_DIR_WITH_PARAMS) - expected = pandas.DataFrame({ - "Exposure.Id": [1,2,3], - "Parameters.Channel": ["green", "red", "red"], - "Parameters.Time" : [100.0, 150.0, 15.0] - }) - + expected = pandas.DataFrame( + { + "Exposure.Id": [1, 2, 3], + "Parameters.Channel": ["green", "red", "red"], + "Parameters.Time": [100.0, 150.0, 15.0], + } + ) + assert result.equals(expected) @@ -75,13 +74,11 @@ def test_get_measurement_params_file_not_found(example_dir): assert result is None -def test_add_optional_measurement_parameters_with_params_file( - exposure_df, example_dir -): - from sensospot_data.parameters import add_optional_measurement_parameters +def test_add_measurement_parameters_with_params_file(exposure_df, example_dir): + from sensospot_data.parameters import add_measurement_parameters folder = example_dir / EXAMPLE_DIR_WITH_PARAMS - exposure_df = add_optional_measurement_parameters(exposure_df, folder) + exposure_df = add_measurement_parameters(exposure_df, folder) expected = [(1, "green", 100), (2, "red", 150), (3, "red", 15)] for exposure_id, channel, time in expected: @@ -91,18 +88,16 @@ def test_add_optional_measurement_parameters_with_params_file( assert example_row["Parameters.Time"] == time -def test_add_optional_measurement_parameters_without_params_file( +def test_add_measurement_parameters_without_params_file( exposure_df, example_dir ): - from sensospot_data.parameters import add_optional_measurement_parameters + from sensospot_data.parameters import add_measurement_parameters folder = example_dir / EXAMPLE_DIR_WO_PARAMS - exposure_df = add_optional_measurement_parameters(exposure_df, folder) + exposure_df = add_measurement_parameters(exposure_df, folder) for exposure_id in range(1, 4): mask = exposure_df["Exposure.Id"] == exposure_id one_exposure_data_frame = exposure_df.loc[mask] assert one_exposure_data_frame["Parameters.Channel"].hasnans assert one_exposure_data_frame["Parameters.Time"].hasnans - -