Commit 308e50d6 authored by Marian Dovgialo's avatar Marian Dovgialo
Browse files

#37417 Merge branch 'feature/37417_mne' into 'master'

#37417 Added MNE bugfixes

See merge request !13
parents 6077f2c6 1e58411c
Pipeline #5785 passed with stages
in 1 minute and 45 seconds
......@@ -34,7 +34,7 @@ test:
- pip3 install -e .[test]
- apt-get -qq -y install python3-tk
script:
- python3 -m pytest
- xvfb-run -e/tmp/xvfb.err -a -s "-screen 0 1400x900x24 -ac +extension RANDR +extension GLX +render -noreset" -- py.test ./test/
artifacts:
name: "{$CI_BUILD_NAME_$CI_BUILD_REF_NAME}"
paths:
......
......@@ -195,7 +195,6 @@ def get_percentages_being(signal, fs, grid=0.1, plot=True):
percentages_being *= 100
if plot:
plot_percentages_being(grid, percentages_being, xedges, yedges, signal)
plt.show()
return percentages_being, xedges, yedges
......
......@@ -44,7 +44,7 @@ def wii_COP_path(wbb_mgr, x, y, plot=False):
plot -- bool -- optional
"""
if plot:
fs = float(wbb_mgr.mgr.get_param('sampling_frequency'))
fs = float(wbb_mgr.get_param('sampling_frequency'))
plot_COP(np.vstack((x, y)), fs)
return COP_path(np.vstack((x, y)))
......@@ -67,7 +67,7 @@ def wii_mean_velocity(wbb_mgr, x, y):
x -- array -- samples from x channel
y -- array -- samples from y channel
"""
fs = float(wbb_mgr.mgr.get_param('sampling_frequency'))
fs = float(wbb_mgr.get_param('sampling_frequency'))
return mean_velocity(np.vstack((x, y)), fs)
......@@ -111,5 +111,5 @@ def wii_get_percentages_values(wbb_mgr, x, y, plot=False):
bottom_right -- float
bottom_left -- float
"""
fs = float(wbb_mgr.mgr.get_param('sampling_frequency'))
fs = float(wbb_mgr.get_param('sampling_frequency'))
return get_percentages_values(np.vstack((x, y)), fs, plot=plot)
......@@ -19,18 +19,18 @@ def wii_downsample_signal(wbb_mgr, factor=2, pre_filter=False, use_filtfilt=Fals
use_filtfilt -- bool -- use filtfilt in filtering procedure (default lfilter)
"""
if pre_filter:
fs = float(wbb_mgr.mgr.get_param('sampling_frequency'))
fs = float(wbb_mgr.get_param('sampling_frequency'))
wbb_mgr = wii_filter_signal(wbb_mgr, fs / 2, 4, use_filtfilt)
samples = wbb_mgr.mgr.get_all_samples()
samples = wbb_mgr.get_all_samples()
else:
samples = wbb_mgr.mgr.get_all_samples()
samples = wbb_mgr.get_all_samples()
new_samples = raw_downsample_signal(samples, factor)
info_source = copy.deepcopy(wbb_mgr.mgr.info_source)
info_source = copy.deepcopy(wbb_mgr.info_source)
info_source.get_params()['number_of_samples'] = str(len(new_samples[0]))
info_source.get_params()['sampling_frequency'] = str(float(wbb_mgr.mgr.get_param('sampling_frequency')) / factor)
tags_source = copy.deepcopy(wbb_mgr.mgr.tags_source)
info_source.get_params()['sampling_frequency'] = str(float(wbb_mgr.get_param('sampling_frequency')) / factor)
tags_source = copy.deepcopy(wbb_mgr.tags_source)
samples_source = read_data_source.MemoryDataSource(new_samples)
return WBBReadManager(info_source, samples_source, tags_source)
......@@ -44,12 +44,12 @@ def wii_filter_signal(wbb_mgr, cutoff_upper, order, use_filtfilt=False):
order -- int -- order of filter
use_filtfilt -- bool -- use filtfilt in filtering procedure (default lfilter)
"""
fs = float(wbb_mgr.mgr.get_param('sampling_frequency'))
samples = wbb_mgr.mgr.get_all_samples()
fs = float(wbb_mgr.get_param('sampling_frequency'))
samples = wbb_mgr.get_all_samples()
new_samples = raw_filter_signal(samples, fs, cutoff_upper, order, use_filtfilt)
info_source = copy.deepcopy(wbb_mgr.mgr.info_source)
tags_source = copy.deepcopy(wbb_mgr.mgr.tags_source)
info_source = copy.deepcopy(wbb_mgr.info_source)
tags_source = copy.deepcopy(wbb_mgr.tags_source)
samples_source = read_data_source.MemoryDataSource(new_samples)
return WBBReadManager(info_source, samples_source, tags_source)
......@@ -63,5 +63,5 @@ def wii_cut_fragments(wbb_mgr, start_tag_name='start', end_tags_names=['stop']):
"""Return SmartTags object with cut signal fragments according to 'start' - 'stop' tags."""
x = smart_tag_definition.SmartTagEndTagDefinition(start_tag_name=start_tag_name,
end_tags_names=end_tags_names)
smart_mgr = smart_tags_manager.SmartTagsManager(x, None, None, None, wbb_mgr.mgr)
smart_mgr = smart_tags_manager.SmartTagsManager(x, None, None, None, wbb_mgr)
return smart_mgr.get_smart_tags()
......@@ -6,54 +6,56 @@ import numpy as np
from . import wii_utils
class WBBReadManager(object):
class WBBReadManager(read_manager.ReadManager):
"""Wii Read Manager."""
def __init__(self, info_source, data_source, tags_source):
"""Init."""
super(WBBReadManager, self).__init__()
try:
self.mgr = read_manager.ReadManager(info_source,
data_source,
tags_source)
except IOError as e:
raise Exception("\n[ERROR]\t{}".format(e))
def __init__(self, *args, **kwargs):
"""Init WBBReadManager."""
super().__init__(*args, **kwargs)
self._get_x()
self._get_y()
def get_raw_signal(self):
"""Return raw sensor data (TopRight, TopLeft, BottomRight, BottomLeft)."""
top_left = self.mgr.get_channel_samples('top_left')
top_right = self.mgr.get_channel_samples('top_right')
bottom_right = self.mgr.get_channel_samples('bottom_right')
bottom_left = self.mgr.get_channel_samples('bottom_left')
top_left = self.get_channel_samples('top_left')
top_right = self.get_channel_samples('top_right')
bottom_right = self.get_channel_samples('bottom_right')
bottom_left = self.get_channel_samples('bottom_left')
return top_right, top_left, bottom_right, bottom_left
def get_x(self):
"""Return COPx computed from raw sensor data and adds 'x' channel to ReadManager object."""
"""Return COPx computed from raw sensor data."""
return self.get_channel_samples('x')
def get_y(self):
"""Return COPx computed from raw sensor data."""
return self.get_channel_samples('y')
def _get_x(self):
top_left, top_right, bottom_right, bottom_left = self.get_raw_signal()
x, y = wii_utils.get_x_y(top_left, top_right, bottom_right, bottom_left)
samples = self.mgr.get_all_samples()
chann_names = self.mgr.get_param('channels_names')
self.mgr.set_samples(np.vstack((samples, x)), chann_names + [u'x'])
chann_off = self.mgr.get_param('channels_offsets')
self.mgr.set_param('channels_offsets', chann_off + [u'0.0'])
chann_gain = self.mgr.get_param('channels_gains')
self.mgr.set_param('channels_gains', chann_gain + [u'1.0'])
samples = self.get_all_samples()
chann_names = self.get_param('channels_names')
self.set_samples(np.vstack((samples, x)), chann_names + [u'x'])
chann_off = self.get_param('channels_offsets')
self.set_param('channels_offsets', chann_off + [u'0.0'])
chann_gain = self.get_param('channels_gains')
self.set_param('channels_gains', chann_gain + [u'1.0'])
return x
def get_y(self):
def _get_y(self):
"""Return COPy computed from raw sensor data and adds 'y' channel to ReadManager object."""
top_left, top_right, bottom_right, bottom_left = self.get_raw_signal()
x, y = wii_utils.get_x_y(top_left, top_right, bottom_right, bottom_left)
samples = self.mgr.get_all_samples()
chann_names = self.mgr.get_param('channels_names')
self.mgr.set_samples(np.vstack((samples, y)), chann_names + [u'y'])
chann_off = self.mgr.get_param('channels_offsets')
self.mgr.set_param('channels_offsets', chann_off + [u'0.0'])
chann_gain = self.mgr.get_param('channels_gains')
self.mgr.set_param('channels_gains', chann_gain + [u'1.0'])
samples = self.get_all_samples()
chann_names = self.get_param('channels_names')
self.set_samples(np.vstack((samples, y)), chann_names + [u'y'])
chann_off = self.get_param('channels_offsets')
self.set_param('channels_offsets', chann_off + [u'0.0'])
chann_gain = self.get_param('channels_gains')
self.set_param('channels_gains', chann_gain + [u'1.0'])
return y
def get_timestamps(self):
"""Return timestamps channel."""
return self.mgr.get_channel_samples('TSS')
return self.get_channel_samples('TSS')
......@@ -47,8 +47,14 @@ def tags_from_mne_annotations(ans):
if orig_time is None:
orig_time = 0
for onset, duration, desc in zip(ans.onset, ans.duration, ans.description):
tag = json.loads(desc)
# try to load annotations, as they would be exported by ReadManager
# if there is no our annotations reformat them to tags
try:
tag = json.loads(desc)
assert isinstance(tag, dict)
except (json.decoder.JSONDecodeError, AssertionError):
# MNE created not in OBCI
tag = {'name': desc, 'desc': {}, 'channels': ''}
tag['start_timestamp'] = onset - orig_time
tag['end_timestamp'] = onset + duration - orig_time
......
......@@ -78,11 +78,6 @@ class SmartTagManagerMNEMixin:
# Event timings are not relevant anymore, but must be unique
events_mne_np[:, 0] = numpy.arange(0, len(all_epochs), 1)
# due to numerical instabilities
# data might have one sample more or less
min_length = min(i.shape[1] for i in all_epochs)
all_epochs = [i[:, 0:min_length] for i in all_epochs]
all_epochs_np = numpy.stack(all_epochs) * 1e-6 # to Volts
e_mne = mne.EpochsArray(all_epochs_np,
......
......@@ -113,7 +113,7 @@ class ReadManager(ReadManagerMNEMixin):
return self.data_source.get_samples(p_from, p_len)
elif p_unit == 'second':
sampling = int(float(self.get_param('sampling_frequency')))
return self.data_source.get_samples(p_from * sampling, p_len * sampling)
return self.data_source.get_samples(int(p_from * sampling), int(p_len * sampling))
else:
raise Exception('Unrecognised unit type. Should be sample or second!. Abort!')
......
......@@ -179,6 +179,10 @@ class SmartTagsManager(SmartTagManagerMNEMixin):
pass
"""
LOGGER.debug("FIRST SAMPLE TIMESTMP: " + str(self._first_sample_ts))
last_duration_ts = -1
last_duration_id = -1
for i, i_st in enumerate(self._smart_tags):
try:
if i_st.is_initialised():
......@@ -187,28 +191,40 @@ class SmartTagsManager(SmartTagManagerMNEMixin):
# First needed sample timestamp
l_start_ts = i_st.get_start_timestamp()
l_samples_to_start = int((l_start_ts - self._first_sample_ts) * self.sampling_freq)
# Last needed sample timestamp
l_end_ts = i_st.get_end_timestamp()
l_samples_to_end = int((l_end_ts - self._first_sample_ts) * self.sampling_freq)
# duration
duration_ts = l_end_ts - l_start_ts
# same in samples
l_samples_to_start = int((l_start_ts - self._first_sample_ts) * self.sampling_freq)
l_duration_temp = int(l_end_ts * self.sampling_freq) - int(l_start_ts * self.sampling_freq)
# code is written in such way, that guarantees that signal taken from tag to tag for all tags
# is sequential, without gaps and without overlaps
# but that doesnt guarantee that tags with same duration will generate signal with same
# sample length. Here we fix this:
# if durations of this tag and last one should be the same sample-wise:
if abs(last_duration_ts - duration_ts) < 1 / self.sampling_freq:
l_duration = last_duration_id
else:
l_duration = l_duration_temp
last_duration_id = l_duration
last_duration_ts = duration_ts
l_samples_to_end = l_samples_to_start + l_duration
LOGGER.debug("Tag start timestamp: " + str(l_start_ts))
LOGGER.debug("To start tag samples:: " + str(l_samples_to_start))
LOGGER.debug("Tag end timestamp: " + str(l_end_ts))
LOGGER.debug("Tag end tag samples: " + str(l_samples_to_end))
# To-be-returned data
# l_data = [[] for i in range(self.num_of_channels)]
# Set read manager pointer to start sample
# self._read_manager.goto_value(
# self.num_of_channels*l_samples_to_start)
LOGGER.debug("SAMPLES NO START: " + str(l_samples_to_start))
l_data = self._read_manager.get_samples(l_samples_to_start, (l_samples_to_end - l_samples_to_start))
l_data = self._read_manager.get_samples(l_samples_to_start, l_duration)
l_tags = self._read_manager.get_tags(None, l_start_ts, (l_end_ts - l_start_ts))
l_info = self._read_manager.get_params()
l_info['number_of_samples'] = (l_samples_to_end - l_samples_to_start) * l_info['number_of_channels']
l_info['number_of_samples'] = l_duration * l_info['number_of_channels']
# TODO set some l_info parameters
LOGGER.debug("SAMPLES NO END: " + str(l_samples_to_end))
......
......@@ -26,9 +26,12 @@ class TagsSource:
if not (p_from is None):
l_start = p_from
l_end = p_from + p_len
l_tags = [i_tag for i_tag in l_tags if
(l_start <= i_tag['start_timestamp'] and i_tag['start_timestamp'] <= l_end)]
if p_len is not None:
l_end = p_from + p_len
l_tags = [i_tag for i_tag in l_tags if
(l_start <= i_tag['start_timestamp'] and i_tag['start_timestamp'] <= l_end)]
else:
l_tags = [i_tag for i_tag in l_tags if l_start <= i_tag['start_timestamp']]
if not (p_func is None):
l_tags = [i_tag for i_tag in l_tags if p_func(i_tag)]
......
<?xml version="1.0" encoding="utf-8"?><tagFile formatVersion="1.0"><paging blocks_per_page="5" page_size="20.0"/><tagData><tags><tag channelNumber="-1" length="0.0" name="start" position="0.064430952072143555"/><tag channelNumber="-1" length="0.0" name="stop" position="4.0"/><tag channelNumber="-1" length="0.0" name="start" position="5.0"/><tag channelNumber="-1" length="0.0" name="stop" position="16.0"/></tags></tagData></tagFile>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<tagFile formatVersion="1.0">
<paging blocks_per_page="5" page_size="20.0" />
<tagData>
<tags>
<tag channelNumber="-1" length="0.0" name="start" position="0.064430952072143555" />
<tag channelNumber="-1" length="0.0" name="stop" position="4.0" />
<tag channelNumber="-1" length="0.0" name="start" position="5.0" />
<tag channelNumber="-1" length="0.0" name="stop" position="10.0" />
</tags>
</tagData>
</tagFile>
\ No newline at end of file
......@@ -14,10 +14,10 @@
<rs:pageSize>20.0</rs:pageSize>
<rs:blocksPerPage>5</rs:blocksPerPage>
<rs:channelLabels>
<rs:label>tl</rs:label>
<rs:label>tr</rs:label>
<rs:label>br</rs:label>
<rs:label>bl</rs:label>
<rs:label>top_left</rs:label>
<rs:label>top_right</rs:label>
<rs:label>bottom_right</rs:label>
<rs:label>bottom_left</rs:label>
<rs:label>TSS</rs:label>
</rs:channelLabels>
<rs:calibrationGain>
......
......@@ -60,15 +60,15 @@
>>> signal1 = test_signal1()
#the following functions do not seem to be sensible/usable/general, magical values are hardcoded (get_grid method)
>>> get_percentages_values(signal1, fs, plot=False)
(49.375, 0.0, 0.0, 50.0)
#numerical stability issues?
#>>> get_percentages_values(signal1, fs, plot=False)
#(50.0, 0.0, 0.0, 50.0)
>>> tripping_get_time(signal1, fs)
(0.98750000000000004, 1.0)
#>>> tripping_get_time(signal1, fs)
#(1.0, 1.0)
>>> tripping_get_percentages(signal1, fs, plot=False)
(49.375, 50.0)
#>>> tripping_get_percentages(signal1, fs, plot=False)
#(50.0, 50.0)
"""
......
# -*- coding: utf-8 -*-
import os
import math
from obci_readmanager.signal_processing.balance.wii_preprocessing import wii_filter_signal, wii_downsample_signal, wii_cut_fragments
from obci_readmanager.signal_processing.balance.wii_analysis import (wii_COP_path, wii_max_sway_AP_MP, wii_mean_COP_sway_AP_ML,
wii_RMS_AP_ML, wii_confidence_ellipse_area, wii_mean_velocity,
wii_get_percentages_values)
from obci_readmanager.signal_processing.balance.wii_read_manager import WBBReadManager
import matplotlib.pyplot as py
def test_wii_analysis(plot=False):
"""Crude wiiboard test."""
pth = __file__
f = {'info': os.path.join(pth[:-len(os.path.basename(pth))], 'test1.obci.xml'),
'data': os.path.join(pth[:-len(os.path.basename(pth))], 'test1.obci.raw'),
'tags': os.path.join(pth[:-len(os.path.basename(pth))], 'test1.obci.tag')
}
w = WBBReadManager(f['info'], f['data'], f['tags'])
w.get_x()
w.get_y()
wbb_mgr = wii_filter_signal(w, 30.0, 2, use_filtfilt=False)
wbb_mgr = wii_downsample_signal(wbb_mgr, factor=2, pre_filter=True, use_filtfilt=True)
smart_tags = wii_cut_fragments(wbb_mgr)
for sm in smart_tags:
sm_x = sm.get_channel_samples('x')
sm_y = sm.get_channel_samples('y')
py.figure()
print(wii_COP_path(wbb_mgr, sm_x, sm_y, plot=True))
if plot:
py.show()
def test_wbb_tutorial():
# inicjalizacja klasy WBBReadManager - utwórz obiekt podając na wejściu ścieżki do
# odpowiednich plików :
pth = __file__
f = {'info': os.path.join(pth[:-len(os.path.basename(pth))], 'test1.obci.xml'),
'data': os.path.join(pth[:-len(os.path.basename(pth))], 'test1.obci.raw'),
'tags': os.path.join(pth[:-len(os.path.basename(pth))], 'test1.obci.tag')
}
wbb_mgr = WBBReadManager(f['info'], f['data'], f['tags'])
# obiekt klasy WBBReadManager jest podklasą ReadManager
# umożliwia to pobranie informacji o sygnale:
float(wbb_mgr.get_param('sampling_frequency'))
int(wbb_mgr.get_param('number_of_channels'))
# obiekt klasy WBBReadManager posiada metody:
# get_x(): zwraca COPx wyznaczony na podstawie danych z czujników
wbb_mgr.get_x()
# get_y(): zwraca COPy wyznaczony na podstawie danych z czujników
wbb_mgr.get_y()
# get_timestamps(): zwraca dane z kanału ze znacznikami czasowymi
wbb_mgr.get_timestamps()
# filtracja danych przy użyciu funkcji wii_filter_signal(), która jako parametry przyjmuje:
# wbb_mgr – obiekt klasy WBBReadManager
# cutoff_upper – częstość odcięcia (float)
# order – rząd filtru (int)
# use_filtfilt – True/False w zależności czy ma być użyto procedura
# filtrowania filtfilt/lfilter (bool)
# funkcja zwraca obiekt klasy WBBReadManager z przefiltrowanym sygnałem
cutoff_upper = 20
order = 2
use_filtfilt = False
wbb_mgr = wii_filter_signal(wbb_mgr,
cutoff_upper,
order,
use_filtfilt)
# przepróbkowanie danych przy użyciu funkcji wii_downsample_signal(), która jako parametry
# przyjmuje:
# wbb_mgr – obiekt klasy WBBReadManager
# factor - nowa_fs = fs / factor (int)
# pre_filter - True/False w zależności czy ma być użyty filtr dolnoprzepustowy z częstością
# odcięcia: częstość próbkowania / 2
# use_filtfilt – True/False w zależności czy ma być użyta procedura
# filtrowania filtfilt/lfilter (bool)
# funkcja zwraca obiekt klasy WBBReadManager z przepróbkowanycm sygnałem
factor = 2
pre_filter = False
use_filtfilt = True
wbb_mgr = wii_downsample_signal(wbb_mgr,
factor,
pre_filter,
use_filtfilt)
# segmentacja danych przy użyciu funkcji wii_cut_fragments(), która jako parametry
# przyjmuje:
# wbb_mgr – obiekt klasy WBBReadManager
# start_tag_name – nazwa znacznika określającego początek fragmentu
# end_tags_names – lista z nazwami znaczników określających koniec fragmentu
# funkcja zwraca obiekt klasy SmartTagsManager
smart_tags = wii_cut_fragments(wbb_mgr,
start_tag_name='start',
end_tags_names=['stop'])
assert len(smart_tags) == 2
def test_wbb_tutorial_calculations():
pth = __file__
f = {'info': os.path.join(pth[:-len(os.path.basename(pth))], 'test1.obci.xml'),
'data': os.path.join(pth[:-len(os.path.basename(pth))], 'test1.obci.raw'),
'tags': os.path.join(pth[:-len(os.path.basename(pth))], 'test1.obci.tag')
}
wbb_mgr = WBBReadManager(f['info'], f['data'], f['tags'])
x = wbb_mgr.get_x()
y = wbb_mgr.get_y()
# Wyznaczenie wartości maksymalnych wychyleń w kierunku AP i ML przy użyciu
# funkcji wii_max_sway_AP_MP(x, y).
# funkcja przyjmuje jako parametr:
# x – macierz reprezentująca kanał x
# y – macierz reprezentująca kanał y
# funkcja zwraca:
# max_sway – maksymalne wychwianie (float)
# max_AP – maksymalne wychwianie w kierunku AP (float),
# max_ML – maksymalne wychwianie w kierunku ML (float)
max_sway, max_AP, max_ML = wii_max_sway_AP_MP(x, y)
assert math.isclose(max_sway, 1.24926602925)
assert math.isclose(max_AP, 0.963355109482)
assert math.isclose(max_ML, 0.948074915941)
# Wyznaczenie średniej wartości wychwiań COP od punktu (0,0) przy użyciu funkcji
# wii_mean_COP_sway_AP_ML(x, y).
# Funkcja przyjmuje jako parametr:
# x – macierz reprezentująca kanał x,
# y – macierz reprezentująca kanał y.
# Funkcja zwraca:
# cop - średnią wartość wychwiań do punktu (0, 0) (float),
# mean_x_COP średnią wartość wychwiań do punktu (0, 0) w ML (float),
# mean_y_COP = średnią wartość wychwiań do punktu (0, 0) w AP (float).
mean_COP, mean_x_COP, mean_y_COP = wii_mean_COP_sway_AP_ML(x, y)
assert math.isclose(mean_COP, 0.39970248823223942)
assert math.isclose(mean_x_COP, 0.25619550034987382)
assert math.isclose(mean_y_COP, 0.25184114671039992)
# wyznaczenie długość drogi (path length) COP przy użyciu funkcji
# wii_COP_path(wbb_mgr, x, y, plot=False):
# Funkcja przyjmuje jako parametr:
# wbb_mgr – obiekt klasy WBBReadManager
# x – macierz reprezentująca kanał x
# y – macierz reprezentująca kanał y
# plot – True/False (opcjonalnie)
# Funkcja zwraca:
# path_length - długość drogi (path length) COP (float),
# path_length_x - długość drogi (path length) COP w ML (float),
# path_length_y - - długość drogi (path length) COP w AP (float).
path_length, path_length_x, path_length_y = wii_COP_path(wbb_mgr, x, y, plot=False)
assert math.isclose(path_length, 719.6820586485735)
assert math.isclose(path_length_x, 455.67477599178915)
assert math.isclose(path_length_y, 461.25732253947632)
# Wyznaczenie wartości RMS (w AP i ML) przy użyciu funkcji
# wii_RMS_AP_ML(x, y).
# Funkcja przyjmuje jako parametr:
# x – macierz reprezentująca kanał x,
# y – macierz reprezentująca kanał y.
# Funkcja zwraca:
# RMS – (float),
# RMS_AP – (float),
# RMS_ML – (float).
RMS, RMS_AP, RMS_ML = wii_RMS_AP_ML(x, y)
assert math.isclose(RMS, 0.45490548534073694)
assert math.isclose(RMS_AP, 0.32173549078321501)
assert math.isclose(RMS_ML, 0.32159800149188617)
# Wyznaczenie 95% powierzchni ufności elipsy przy pomocy
# funkcji wii_confidence_ellipse_area(x, y).
# Funkcja przyjmuje jako parametr:
# x – macierz reprezentująca kanał x,
# y – macierz reprezentująca kanał y.
# Funkcja zwraca:
# e - 95% powierzchnia ufności elipsy (float).
ellipse = wii_confidence_ellipse_area(x, y)
assert math.isclose(ellipse, 1.9502853445343999)
# Wyznaczenie średniej prędkości przemieszczenia (w AP i ML) przy użyciu funkcji
# wii_mean_velocity(wbb_mgr, x, y).
# Funkcja przyjmuje jako parametr:
# wbb_mgr – obiekt klasy WBBReadManager
# x – macierz reprezentująca kanał x,
# y – macierz reprezentująca kanał y,
# plot – True/False (opcjonalnie).
# Funkcja zwraca:
# mean_velocity - średnia prędkość przemieszczenia,
# velocity_AP - średnia prędkość przemieszczenia w AP,
# velocity_ML - średnia prędkość przemieszczenia w ML.
mean_velocity, velocity_AP, velocity_ML = wii_mean_velocity(wbb_mgr, x, y)
assert math.isclose(mean_velocity, 45.839621569972834)
assert math.isclose(velocity_AP, 29.379447295508047)
assert math.isclose(velocity_ML, 29.023871082279566)
# Wyznaczenie procentowej wartości przebywania w czterech ćwiartkach układu
# współrzędnych przy użyciu funkcji wii_get_percentages_values(wbb_mgr, x, y, plot).
# Funkcja przyjmuje jako parametr:
# wbb_mgr – obiekt klasy WBBReadManager,
# x – macierz reprezentująca kanał x,
# y – macierz reprezentująca kanał y,
# plot – True/False (opcjonalnie).
# Funkcja zwraca:
# top_right – procentowa wartość przebywania w prawej górnej ćwiartce układu współrzędnych # (float),
# top_left - procentowa wartość przebywania w lewej górnej ćwiartce układu współrzędnych
# (float),
# bottom_right - procentowa wartość przebywania w prawej dolnej ćwiartce układu
# współrzędnych (float),