You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.4 KiB
74 lines
2.4 KiB
""" Sensospot Data Parser |
|
|
|
Parsing the numerical output from Sensovations Sensospot image analysis. |
|
""" |
|
|
|
from pathlib import Path |
|
from collections import namedtuple |
|
|
|
import numpy |
|
import pandas |
|
from defusedxml import ElementTree |
|
|
|
from . import columns |
|
|
|
|
|
|
|
def _search_measurement_params_file(folder): |
|
"""searches for a exposure settings file in a folder""" |
|
folder_path = Path(folder) |
|
params_folder = folder_path / "Parameters" |
|
if not params_folder.is_dir(): |
|
return None |
|
param_files = list(params_folder.glob("**/*.svexp")) |
|
if len(param_files) == 1: |
|
return param_files[0] |
|
else: |
|
return None |
|
|
|
|
|
def _get_channel_data(channel_node): |
|
# child.tag == "ChannelConfig1" |
|
exposure_id = int(channel_node.tag[-1]) |
|
# channel_description == "[Cy3|Cy5] Green" |
|
description = channel_node.attrib["Description"] |
|
exposure_channel = description.rsplit(" ", 1)[-1] |
|
# floats can be used for exposure times, not only ints |
|
exposure_time = float(channel_node.attrib["ExposureTimeMs"]) |
|
return { |
|
columns.EXPOSURE_ID: exposure_id, |
|
columns.PARAMETERS_CHANNEL: exposure_channel.lower(), |
|
columns.PARAMETERS_TIME: exposure_time, |
|
} |
|
|
|
|
|
def _parse_measurement_params(params_file): |
|
"""parses the cannel informations from a settings file""" |
|
file_path = 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): |
|
"""returns measurement parameters""" |
|
params_file = _search_measurement_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): |
|
"""adds measurement params to the data frame, if they could be parsed""" |
|
params = get_measurement_params(folder) |
|
if params is not None: |
|
params_exposures = params[columns.EXPOSURE_ID].unique() |
|
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 |
|
return data_frame
|
|
|