Browse Source

added typing information to module parameters

xmlparsing
Holger Frey 3 years ago
parent
commit
81db693157
  1. 26
      sensospot_data/parameters.py
  2. 5
      sensospot_data/parser.py
  3. 69
      tests/test_parameters.py

26
sensospot_data/parameters.py

@ -3,8 +3,9 @@ @@ -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 @@ -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): @@ -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): @@ -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): @@ -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

5
sensospot_data/parser.py

@ -10,8 +10,7 @@ from collections import namedtuple @@ -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): @@ -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)

69
tests/test_parameters.py

@ -1,54 +1,51 @@ @@ -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): @@ -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): @@ -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( @@ -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

Loading…
Cancel
Save