import six
|
|
import warnings
|
|
|
|
from nd2reader.common import get_from_dict_if_exists
|
|
|
|
|
|
def parse_if_not_none(to_check, callback):
|
|
if to_check is not None:
|
|
return callback()
|
|
return None
|
|
|
|
|
|
def parse_dimension_text_line(line):
|
|
if six.b("Dimensions:") in line:
|
|
entries = line.split(six.b("\r\n"))
|
|
for entry in entries:
|
|
if entry.startswith(six.b("Dimensions:")):
|
|
return entry
|
|
return None
|
|
|
|
|
|
def parse_roi_shape(shape):
|
|
if shape == 3:
|
|
return 'rectangle'
|
|
elif shape == 9:
|
|
return 'circle'
|
|
|
|
return None
|
|
|
|
|
|
def parse_roi_type(type_no):
|
|
if type_no == 4:
|
|
return 'stimulation'
|
|
elif type_no == 3:
|
|
return 'reference'
|
|
elif type_no == 2:
|
|
return 'background'
|
|
|
|
return None
|
|
|
|
|
|
def get_loops_from_data(loop_data):
|
|
# special ND experiment
|
|
if six.b('pPeriod') not in loop_data:
|
|
return []
|
|
|
|
if six.b('uiPeriodCount') in loop_data and loop_data[six.b('uiPeriodCount')] > 0:
|
|
loops = []
|
|
for i, period in enumerate(loop_data[six.b('pPeriod')]):
|
|
# exclude invalid periods
|
|
if six.b('pPeriodValid') in loop_data:
|
|
try:
|
|
if loop_data[six.b('pPeriodValid')][i] == 1:
|
|
loops.append(loop_data[six.b('pPeriod')][period])
|
|
except IndexError:
|
|
continue
|
|
else:
|
|
# we can't be sure, append all
|
|
loops.append(loop_data[six.b('pPeriod')][period])
|
|
|
|
return [loop_data]
|
|
|
|
|
|
def guess_sampling_from_loops(duration, loop):
|
|
""" In some cases, both keys are not saved. Then try to calculate it.
|
|
|
|
Args:
|
|
duration: the total duration of the loop
|
|
loop: the raw loop data
|
|
|
|
Returns:
|
|
float: the guessed sampling interval in milliseconds
|
|
|
|
"""
|
|
number_of_loops = get_from_dict_if_exists('uiCount', loop)
|
|
number_of_loops = number_of_loops if number_of_loops is not None and number_of_loops > 0 else 1
|
|
interval = duration / number_of_loops
|
|
return interval
|
|
|
|
|
|
def determine_sampling_interval(duration, loop):
|
|
"""Determines the loop sampling interval in milliseconds
|
|
|
|
Args:
|
|
duration: loop duration in milliseconds
|
|
loop: loop dictionary
|
|
|
|
Returns:
|
|
float: the sampling interval in milliseconds
|
|
|
|
"""
|
|
interval = get_from_dict_if_exists('dPeriod', loop)
|
|
avg_interval = get_from_dict_if_exists('dAvgPeriodDiff', loop)
|
|
|
|
if interval is None or interval <= 0:
|
|
interval = avg_interval
|
|
else:
|
|
avg_interval_set = avg_interval is not None and avg_interval > 0
|
|
|
|
if round(avg_interval) != round(interval) and avg_interval_set:
|
|
message = ("Reported average frame interval (%.1f ms) doesn't"
|
|
" match the set interval (%.1f ms). Using the average"
|
|
" now.")
|
|
warnings.warn(message % (avg_interval, interval), RuntimeWarning)
|
|
interval = avg_interval
|
|
|
|
if interval is None or interval <= 0:
|
|
# In some cases, both keys are not saved. Then try to calculate it.
|
|
interval = guess_sampling_from_loops(duration, loop)
|
|
|
|
return interval
|