Holger Frey
4 years ago
7 changed files with 173 additions and 177 deletions
@ -1,6 +1,67 @@ |
|||||||
|
import numpy |
||||||
|
|
||||||
|
from .columns import ( |
||||||
|
META_DATA_EXPOSURE_ID, |
||||||
|
SETTINGS_EXPOSURE_TIME, |
||||||
|
META_DATA_PARAMETERS_TIME, |
||||||
|
SETTINGS_EXPOSURE_CHANNEL, |
||||||
|
META_DATA_PARAMETERS_CHANNEL, |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
def split_data_frame(data_frame, column): |
def split_data_frame(data_frame, column): |
||||||
""" splits a data frame on unique column values """ |
""" splits a data frame on unique column values """ |
||||||
values = data_frame[column].unique() |
values = data_frame[column].unique() |
||||||
masks = {value: (data_frame[column] == value) for value in values} |
masks = {value: (data_frame[column] == value) for value in values} |
||||||
return {value: data_frame[mask] for value, mask in masks.items()} |
return {value: data_frame[mask] for value, mask in masks.items()} |
||||||
|
|
||||||
|
|
||||||
|
def _set_exposure_data_from_parameters(data_frame): |
||||||
|
"""infer the exposures from measurement parameters |
||||||
|
|
||||||
|
will raise a ValueError if the parameters contain NaNs |
||||||
|
""" |
||||||
|
df = data_frame # shorthand for cleaner code |
||||||
|
|
||||||
|
if ( |
||||||
|
df[META_DATA_PARAMETERS_CHANNEL].hasnans |
||||||
|
or df[META_DATA_PARAMETERS_TIME].hasnans |
||||||
|
): |
||||||
|
raise ValueError("Exposure Map: measurement parameters incomplete") |
||||||
|
|
||||||
|
df[SETTINGS_EXPOSURE_CHANNEL] = df[META_DATA_PARAMETERS_CHANNEL] |
||||||
|
df[SETTINGS_EXPOSURE_TIME] = df[META_DATA_PARAMETERS_TIME] |
||||||
|
return df |
||||||
|
|
||||||
|
|
||||||
|
def apply_exposure_map(data_frame, exposure_map=None): |
||||||
|
"""applies the parameters of a exposure map to the data frame |
||||||
|
|
||||||
|
exposure map: |
||||||
|
keys: must be the same as the exposure ids, |
||||||
|
values: objects with at least time and channel attributes |
||||||
|
|
||||||
|
if the exposure map is None, the values from the optionally parsed |
||||||
|
measurement parameters are used. |
||||||
|
|
||||||
|
will raise an ValueError, if the provided exposure map does not map to the |
||||||
|
exposure ids. |
||||||
|
""" |
||||||
|
|
||||||
|
if exposure_map is None: |
||||||
|
return _set_exposure_data_from_parameters(data_frame) |
||||||
|
|
||||||
|
existing = set(data_frame[META_DATA_EXPOSURE_ID].unique()) |
||||||
|
provided = set(exposure_map.keys()) |
||||||
|
if existing != provided: |
||||||
|
raise ValueError( |
||||||
|
f"Exposure Map differs from data frame: {provided} != {existing}" |
||||||
|
) |
||||||
|
|
||||||
|
data_frame[SETTINGS_EXPOSURE_CHANNEL] = numpy.nan |
||||||
|
data_frame[SETTINGS_EXPOSURE_TIME] = numpy.nan |
||||||
|
for exposure_id, exposure_info in exposure_map.items(): |
||||||
|
mask = data_frame[META_DATA_EXPOSURE_ID] == exposure_id |
||||||
|
data_frame.loc[mask, SETTINGS_EXPOSURE_CHANNEL] = exposure_info.channel |
||||||
|
data_frame.loc[mask, SETTINGS_EXPOSURE_TIME] = exposure_info.time |
||||||
|
return data_frame |
||||||
|
@ -1,14 +1,88 @@ |
|||||||
|
from collections import namedtuple |
||||||
|
|
||||||
from .conftest import EXAMPLE_DIR_WITH_PARAMS |
import pytest |
||||||
|
|
||||||
|
ExposureSetting = namedtuple("ExposureSetting", ["channel", "time"]) |
||||||
|
|
||||||
def test_split_data_frame(example_dir): |
|
||||||
from sensospot_data.parser import parse_folder |
|
||||||
from sensospot_data.utils import split_data_frame |
|
||||||
|
|
||||||
data_frame = parse_folder(example_dir / EXAMPLE_DIR_WITH_PARAMS) |
def test_split_data_frame(data_frame_with_params): |
||||||
|
from sensospot_data.utils import split_data_frame |
||||||
|
|
||||||
result = split_data_frame(data_frame, "Well.Row") |
result = split_data_frame(data_frame_with_params, "Well.Row") |
||||||
|
|
||||||
assert set(result.keys()) == set("ABC") |
assert set(result.keys()) == set("ABC") |
||||||
for key, value_df in result.items(): |
for key, value_df in result.items(): |
||||||
assert set(value_df["Well.Row"].unique()) == {key} |
assert set(value_df["Well.Row"].unique()) == {key} |
||||||
|
|
||||||
|
|
||||||
|
def test_infer_exposure_from_parameters(data_frame_with_params): |
||||||
|
from sensospot_data.utils import _set_exposure_data_from_parameters |
||||||
|
|
||||||
|
result = _set_exposure_data_from_parameters(data_frame_with_params) |
||||||
|
|
||||||
|
assert all(result["Exposure.Channel"] == result["Parameters.Channel"]) |
||||||
|
assert all(result["Exposure.Time"] == result["Parameters.Time"]) |
||||||
|
|
||||||
|
|
||||||
|
def test_infer_exposure_from_parameters_raises_error( |
||||||
|
data_frame_without_params, |
||||||
|
): |
||||||
|
from sensospot_data.utils import _set_exposure_data_from_parameters |
||||||
|
|
||||||
|
with pytest.raises(ValueError) as excinfo: |
||||||
|
_set_exposure_data_from_parameters(data_frame_without_params) |
||||||
|
|
||||||
|
assert str(excinfo.value).startswith("Exposure Map: measurement") |
||||||
|
|
||||||
|
|
||||||
|
def test_apply_exposure_map(data_frame_with_params): |
||||||
|
from sensospot_data.utils import apply_exposure_map |
||||||
|
|
||||||
|
exposure_map = { |
||||||
|
1: ExposureSetting("Cy3", 100), |
||||||
|
2: ExposureSetting("Cy5", 15), |
||||||
|
3: ExposureSetting("Cy5", 150), |
||||||
|
} |
||||||
|
|
||||||
|
result = apply_exposure_map(data_frame_with_params, exposure_map) |
||||||
|
|
||||||
|
for key, value in exposure_map.items(): |
||||||
|
mask = result["Exposure.Id"] == key |
||||||
|
partial = result.loc[mask] |
||||||
|
assert set(partial["Exposure.Channel"].unique()) == {value.channel} |
||||||
|
assert set(partial["Exposure.Time"].unique()) == {value.time} |
||||||
|
|
||||||
|
|
||||||
|
def test_apply_exposure_map_raises_error(data_frame_with_params): |
||||||
|
from sensospot_data.utils import apply_exposure_map |
||||||
|
|
||||||
|
exposure_map = { |
||||||
|
1: ExposureSetting("Cy3", 100), |
||||||
|
2: ExposureSetting("Cy5", 15), |
||||||
|
"X": ExposureSetting("Cy5", 150), |
||||||
|
} |
||||||
|
|
||||||
|
with pytest.raises(ValueError) as excinfo: |
||||||
|
apply_exposure_map(data_frame_with_params, exposure_map) |
||||||
|
|
||||||
|
assert str(excinfo.value).startswith("Exposure Map differs") |
||||||
|
|
||||||
|
|
||||||
|
def test_apply_exposure_map_from_parameters(data_frame_with_params): |
||||||
|
from sensospot_data.utils import apply_exposure_map |
||||||
|
|
||||||
|
result = apply_exposure_map(data_frame_with_params, None) |
||||||
|
|
||||||
|
assert all(result["Exposure.Channel"] == result["Parameters.Channel"]) |
||||||
|
assert all(result["Exposure.Time"] == result["Parameters.Time"]) |
||||||
|
|
||||||
|
|
||||||
|
def test_apply_exposure_map_from_parameters_raises_error( |
||||||
|
data_frame_without_params, |
||||||
|
): |
||||||
|
from sensospot_data.utils import apply_exposure_map |
||||||
|
|
||||||
|
with pytest.raises(ValueError) as excinfo: |
||||||
|
apply_exposure_map(data_frame_without_params, None) |
||||||
|
|
||||||
|
assert str(excinfo.value).startswith("Exposure Map: measurement") |
||||||
|
Loading…
Reference in new issue