Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event Annotator for Biosignals #13

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion biosppy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

A toolbox for biosignal processing written in Python.

:copyright: (c) 2015-2021 by Instituto de Telecomunicacoes
:copyright: (c) 2015-2023 by Instituto de Telecomunicacoes
:license: BSD 3-clause, see LICENSE for more details.
"""

Expand Down
2 changes: 1 addition & 1 deletion biosppy/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

Version tracker.

:copyright: (c) 2015-2021 by Instituto de Telecomunicacoes
:copyright: (c) 2015-2023 by Instituto de Telecomunicacoes
:license: BSD 3-clause, see LICENSE for more details.
"""

Expand Down
2 changes: 1 addition & 1 deletion biosppy/biometrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* identify: determine the identity of collected biometric dataset;
* authenticate: verify the identity of collected biometric dataset.

:copyright: (c) 2015-2018 by Instituto de Telecomunicacoes
:copyright: (c) 2015-2023 by Instituto de Telecomunicacoes
:license: BSD 3-clause, see LICENSE for more details.
"""

Expand Down
2 changes: 1 addition & 1 deletion biosppy/clustering.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
This module provides various unsupervised machine learning (clustering)
algorithms.

:copyright: (c) 2015-2018 by Instituto de Telecomunicacoes
:copyright: (c) 2015-2023 by Instituto de Telecomunicacoes
:license: BSD 3-clause, see LICENSE for more details.
"""

Expand Down
3 changes: 2 additions & 1 deletion biosppy/inter_plotting/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@

This package provides methods to interactively display plots for the
following physiological signals (biosignals):
* Acceleration (ACC)
* Electrocardiogram (ECG)

:copyright: (c) 2015-2021 by Instituto de Telecomunicacoes
:copyright: (c) 2015-2023 by Instituto de Telecomunicacoes
:license: BSD 3-clause, see LICENSE for more details.
"""

Expand Down
2 changes: 1 addition & 1 deletion biosppy/inter_plotting/acc.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

This module provides an interactive display option for the ACC plot.

:copyright: (c) 2015-2018 by Instituto de Telecomunicacoes
:copyright: (c) 2015-2023 by Instituto de Telecomunicacoes
:license: BSD 3-clause, see LICENSE for more details.

"""
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
190 changes: 190 additions & 0 deletions biosppy/inter_plotting/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# -*- coding: utf-8 -*-
"""
biosppy.inter_plotting.ecg
-------------------

This module provides configuration functions and variables for the Biosignal Annotator.

:copyright: (c) 2015-2023 by Instituto de Telecomunicacoes
:license: BSD 3-clause, see LICENSE for more details.

"""

from matplotlib.backend_bases import MouseButton
import matplotlib.colors as mcolors
from ..signals import eda
from ..signals import ecg
from ..signals import abp
from ..signals import emg
from ..signals import pcg
from ..signals import ppg


def UI_intention(event, var_edit_plots=None, var_toggle_Ctrl=None, var_zoomed_in=None, window_in_border=None,
closest_event=False):
"""Returns the user intention and action given an event.

Parameters
----------
var_edit_plots : None
Enables (if set to 1) or disables (if set to 0) annotation editing.
var_toggle_Ctrl : None
Stores whether currently zoomed-in (if set to 1) or zoomed-out (if set to 0) in amplitude.
var_zoomed_in : None
Stores whether currently zoomed-in (if true) or zoomed-out (if false) in time.
window_in_border: None
Stores whether the current zoomed-in window is in the borders of the time range (x-scale).
closest_event : None
Stores whether closest event is within defined range (if true) or not (false).

Returns
-------
return_dict : dict
The returned dictionary with keys 'triggered_intention' and 'triggered_action'.

"""

triggered_intention = None
triggered_action = None

if hasattr(event, 'inaxes'):

if event.inaxes is not None and not event.dblclick: # and var_edit_plots.get() == 1

if event.button == MouseButton.RIGHT:
triggered_intention = "rmv_annotation"

if var_edit_plots is not None:

if var_edit_plots.get() == 1 and closest_event:
triggered_action = "rmv_annotation"

elif var_edit_plots.get() == 1 and not closest_event:
triggered_action = "rmv_annotation_not_close"

# else the action remain None

elif event.button == MouseButton.LEFT:
triggered_intention = "add_annotation"

if var_edit_plots is not None:

if var_edit_plots.get() == 1:
triggered_action = "add_annotation"

elif hasattr(event, 'keysym'):

# Moving to the Right (right arrow)
if event.keysym == 'Right':
triggered_intention = "move_right"

if window_in_border is not None:
if not window_in_border:
triggered_action = "move_right"

# else, window doesn't move to the right (stays the same)

# Moving to the left (left arrow)
elif event.keysym == 'Left':
triggered_intention = "move_left"

if window_in_border is not None:
if not window_in_border:
triggered_action = "move_left"
# else, window doesn't move to the left (stays the same)

# Zooming out to original xlims or to previous zoomed in lims
elif event.keysym == 'Shift_L':
triggered_intention = "adjust_in_time"

if var_zoomed_in is not None:
# if the window was not zoomed in, it should zoom in
if not var_zoomed_in:
triggered_action = "zooming_in"

# else, it should zoom out
else:
triggered_action = "zooming_out"

# if Left Control is pressed
elif event.keysym == 'Control_L':

triggered_intention = "adjust_in_amplitude"

if var_toggle_Ctrl is not None:

# if the window was not zoomed in, it should zoom in
if var_toggle_Ctrl.get() == 0:
triggered_action = "zooming_in"

# else, it should zoom out
else:
triggered_action = "zooming_out"

elif event.keysym == 'Escape':
triggered_intention = "quit_ui"

return_dict = {'triggered_intention': triggered_intention, 'triggered_action': triggered_action}
return return_dict

# possible intentions and actions
UI_intentions_actions = {

"adjust_in_amplitude": {None: "Error", "zooming_in": "Amplitude Zoom-in", "zooming_out": "Amplitude Zoom-out"},

"adjust_in_time": {None: "Error", "zooming_in": "Time zoom-in", "zooming_out": "Time zoom-out"},

"move_right": {None: "Cannot move further to the right (signal ends there).", "move_right": "Moving right"},
"move_left": {None: "Cannot move further to the left (signal ends there).", "move_left": "Moving left"},

"add_annotation": {None: "Click on \'Edit Annotations\' checkbox", "add_annotation": "Adding Annotation"},
"rmv_annotation": {None: "Click on \'Edit Annotations\' checkbox", "rmv_annotation": "Removing Annotation",
"rmv_annotation_not_close": "Click closer to the annotation."},

}

# listed BioSPPy default filtering methods and main feature extraction methods.
list_functions = {'EDA': {
'Basic SCR Extractor - Onsets': {'preprocess': eda.preprocess_eda, 'function': eda.basic_scr,
'template_key': 'onsets'},
'Basic SCR Extractor - Peaks': {'preprocess': eda.preprocess_eda, 'function': eda.basic_scr,
'template_key': 'onsets'},
'KBK SCR Extractor - Onsets': {'preprocess': eda.preprocess_eda, 'function': eda.kbk_scr,
'template_key': 'peaks'},
'KBK SCR Extractor - Peaks': {'preprocess': eda.preprocess_eda, 'function': eda.kbk_scr,
'template_key': 'peaks'}},
'ECG': {'R-peak Hamilton Segmenter': {'preprocess': ecg.preprocess_ecg,
'function': ecg.hamilton_segmenter, 'template_key': 'rpeaks'},
'R-peak SSF Segmenter': {'preprocess': ecg.preprocess_ecg, 'function': ecg.ssf_segmenter,
'template_key': 'rpeaks'},
'R-peak Christov Segmenter': {'preprocess': ecg.preprocess_ecg,
'function': ecg.christov_segmenter, 'template_key': 'rpeaks'},
'R-peak Engzee Segmenter': {'preprocess': ecg.preprocess_ecg,
'function': ecg.engzee_segmenter, 'template_key': 'rpeaks'},
'R-peak Gamboa Segmenter': {'preprocess': ecg.preprocess_ecg,
'function': ecg.gamboa_segmenter, 'template_key': 'rpeaks'},
'R-peak ASI Segmenter': {'preprocess': ecg.preprocess_ecg, 'function': ecg.ASI_segmenter,
'template_key': 'rpeaks'}},
'ABP': {'Onset Extractor': {'preprocess': abp.preprocess_abp, 'function': abp.find_onsets_zong2003,
'template_key': 'onsets'}},
'EMG': {'Basic Onset Finder': {'preprocess': emg.preprocess_emg, 'function': emg.find_onsets,
'template_key': 'onsets'}},

# 'Hodges Onset Finder': {'preprocess': emg.preprocess_emg,'function': emg.hodges_bui_onset_detector, 'template_key': 'onsets'},
# 'Bonato Onset Finder': {'preprocess': emg.preprocess_emg,'function': emg.bonato_onset_detector, 'template_key': 'onsets'},
# 'Lidierth Onset Finder': {'preprocess': emg.preprocess_emg,'function': emg.lidierth_onset_detector, 'template_key': 'onsets'},
# 'Abbink Onset Finder': {'preprocess': emg.preprocess_emg,'function': emg.abbink_onset_detector, 'template_key': 'onsets'},
# 'Solnik Onset Finder': {'preprocess': emg.preprocess_emg,'function': emg.solnik_onset_detector, 'template_key': 'onsets'},
# 'Silva Onset Finder': {'preprocess': emg.preprocess_emg,'function': emg.silva_onset_detector, 'template_key': 'onsets'},
# 'londral_onset_detector': {'preprocess': emg.preprocess_emg,'function': emg.londral_onset_detector, 'template_key': 'onsets'}},

'PCG': {
'Basic Peak Finger': {'preprocess': None, 'function': pcg.find_peaks, 'template_key': 'peaks'}},
'PPG': {'Elgendi Onset Finder': {'preprocess': ppg.preprocess_ppg,
'function': ppg.find_onsets_elgendi2013, 'template_key': 'onsets'},
'Kavsaoglu Onset Finder': {'preprocess': ppg.preprocess_ppg,
'function': ppg.find_onsets_kavsaoglu2016,
'template_key': 'onsets'}}
}

plot_colors = list(mcolors.TABLEAU_COLORS.values())
2 changes: 1 addition & 1 deletion biosppy/inter_plotting/ecg.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

This module provides an interactive display option for the ECG plot.

:copyright: (c) 2015-2018 by Instituto de Telecomunicacoes
:copyright: (c) 2015-2023 by Instituto de Telecomunicacoes
:license: BSD 3-clause, see LICENSE for more details.

"""
Expand Down
Loading