From 71af69a2567623df76cf8261ccec57e8fb8c20e1 Mon Sep 17 00:00:00 2001 From: Jacob Woessner Date: Wed, 4 Dec 2024 18:40:53 -0600 Subject: [PATCH 1/9] Fix reading response --- mne/io/cnt/cnt.py | 18 +++++++++++++++++- mne/io/cnt/tests/test_cnt.py | 2 ++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/mne/io/cnt/cnt.py b/mne/io/cnt/cnt.py index 16c074269bf..e7fad43e81c 100644 --- a/mne/io/cnt/cnt.py +++ b/mne/io/cnt/cnt.py @@ -150,7 +150,23 @@ def _update_bad_span_onset(accept_reject, onset, duration, description): np.array([e.KeyPad_Accept for e in my_events]) ) - description = np.array([str(e.StimType) for e in my_events]) + # Check to see if there are any button presses + description = [] + for event in my_events: + # Extract the 4-bit fields + # Upper nibble (4 bits) currently not used + accept = (event.KeyPad_Accept[0] & 0xF0) >> 4 + # Lower nibble (4 bits) keypad button press + keypad = event.KeyPad_Accept[0] & 0x0F + if str(keypad) != '0': + description.append("KeyPad Response" + " " + str(keypad)) + elif event.KeyBoard != 0: + description.append("Keyboard Response" + + " " + str(event.KeyBoard)) + else: + description.append(str(event.StimType)) + + description = np.array(description) onset, duration, description = _update_bad_span_onset( accept_reject, onset / sfreq, duration, description diff --git a/mne/io/cnt/tests/test_cnt.py b/mne/io/cnt/tests/test_cnt.py index c098b58e6f3..e17a3344e57 100644 --- a/mne/io/cnt/tests/test_cnt.py +++ b/mne/io/cnt/tests/test_cnt.py @@ -58,6 +58,7 @@ def test_auto_data(): with first, second, third: raw = read_raw_cnt(input_fname=fname_bad_spans) + assert 'KeyPad Response 1' in raw.annotations.description assert raw.info["bads"] == ["F8"] with _no_parse, pytest.warns(RuntimeWarning, match="number of bytes"): @@ -67,6 +68,7 @@ def test_auto_data(): # make sure we use annotations event if we synthesized stim assert len(raw.annotations) == 6 + # Test that responses are read properly eog_chs = pick_types(raw.info, eog=True, exclude=[]) assert len(eog_chs) == 2 # test eog='auto' From a87ce5306a8b056efd81348acaea428712611ee4 Mon Sep 17 00:00:00 2001 From: Jacob Woessner Date: Wed, 4 Dec 2024 18:50:20 -0600 Subject: [PATCH 2/9] Move comment --- mne/io/cnt/tests/test_cnt.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mne/io/cnt/tests/test_cnt.py b/mne/io/cnt/tests/test_cnt.py index e17a3344e57..cb43776b3da 100644 --- a/mne/io/cnt/tests/test_cnt.py +++ b/mne/io/cnt/tests/test_cnt.py @@ -57,7 +57,7 @@ def test_auto_data(): third = pytest.warns(RuntimeWarning, match="Omitted 6 annot") with first, second, third: raw = read_raw_cnt(input_fname=fname_bad_spans) - + # Test that responses are read properly assert 'KeyPad Response 1' in raw.annotations.description assert raw.info["bads"] == ["F8"] @@ -68,7 +68,6 @@ def test_auto_data(): # make sure we use annotations event if we synthesized stim assert len(raw.annotations) == 6 - # Test that responses are read properly eog_chs = pick_types(raw.info, eog=True, exclude=[]) assert len(eog_chs) == 2 # test eog='auto' From e2c0857d9198e172484350a611f18a8efa0ee68f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2024 00:51:14 +0000 Subject: [PATCH 3/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mne/io/cnt/cnt.py | 5 ++--- mne/io/cnt/tests/test_cnt.py | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mne/io/cnt/cnt.py b/mne/io/cnt/cnt.py index e7fad43e81c..00b3470091b 100644 --- a/mne/io/cnt/cnt.py +++ b/mne/io/cnt/cnt.py @@ -158,11 +158,10 @@ def _update_bad_span_onset(accept_reject, onset, duration, description): accept = (event.KeyPad_Accept[0] & 0xF0) >> 4 # Lower nibble (4 bits) keypad button press keypad = event.KeyPad_Accept[0] & 0x0F - if str(keypad) != '0': + if str(keypad) != "0": description.append("KeyPad Response" + " " + str(keypad)) elif event.KeyBoard != 0: - description.append("Keyboard Response" + - " " + str(event.KeyBoard)) + description.append("Keyboard Response" + " " + str(event.KeyBoard)) else: description.append(str(event.StimType)) diff --git a/mne/io/cnt/tests/test_cnt.py b/mne/io/cnt/tests/test_cnt.py index cb43776b3da..f98253b1317 100644 --- a/mne/io/cnt/tests/test_cnt.py +++ b/mne/io/cnt/tests/test_cnt.py @@ -58,7 +58,7 @@ def test_auto_data(): with first, second, third: raw = read_raw_cnt(input_fname=fname_bad_spans) # Test that responses are read properly - assert 'KeyPad Response 1' in raw.annotations.description + assert "KeyPad Response 1" in raw.annotations.description assert raw.info["bads"] == ["F8"] with _no_parse, pytest.warns(RuntimeWarning, match="number of bytes"): From f99cbbdd00478aaa81140df0b4ce251d726d773a Mon Sep 17 00:00:00 2001 From: Jacob Woessner Date: Wed, 4 Dec 2024 19:14:17 -0600 Subject: [PATCH 4/9] comment out unused line --- mne/io/cnt/cnt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mne/io/cnt/cnt.py b/mne/io/cnt/cnt.py index 00b3470091b..dcda3fd09f6 100644 --- a/mne/io/cnt/cnt.py +++ b/mne/io/cnt/cnt.py @@ -155,7 +155,7 @@ def _update_bad_span_onset(accept_reject, onset, duration, description): for event in my_events: # Extract the 4-bit fields # Upper nibble (4 bits) currently not used - accept = (event.KeyPad_Accept[0] & 0xF0) >> 4 + # accept = (event.KeyPad_Accept[0] & 0xF0) >> 4 # Lower nibble (4 bits) keypad button press keypad = event.KeyPad_Accept[0] & 0x0F if str(keypad) != "0": From 9fa41bc463782aac0341c93802d5187a4bbaa9ec Mon Sep 17 00:00:00 2001 From: Jacob Woessner Date: Thu, 5 Dec 2024 16:15:34 -0600 Subject: [PATCH 5/9] Update mne/io/cnt/cnt.py Co-authored-by: Eric Larson --- mne/io/cnt/cnt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mne/io/cnt/cnt.py b/mne/io/cnt/cnt.py index dcda3fd09f6..e1dd7cb1e06 100644 --- a/mne/io/cnt/cnt.py +++ b/mne/io/cnt/cnt.py @@ -161,7 +161,7 @@ def _update_bad_span_onset(accept_reject, onset, duration, description): if str(keypad) != "0": description.append("KeyPad Response" + " " + str(keypad)) elif event.KeyBoard != 0: - description.append("Keyboard Response" + " " + str(event.KeyBoard)) + description.append(f"Keyboard Response {event.KeyBoard}") else: description.append(str(event.StimType)) From 648214ba629d7363b42af52ad6815365fe9b0551 Mon Sep 17 00:00:00 2001 From: Jacob Woessner Date: Thu, 5 Dec 2024 16:16:01 -0600 Subject: [PATCH 6/9] Apply suggestions from code review Co-authored-by: Eric Larson --- mne/io/cnt/cnt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mne/io/cnt/cnt.py b/mne/io/cnt/cnt.py index e1dd7cb1e06..4fe505422aa 100644 --- a/mne/io/cnt/cnt.py +++ b/mne/io/cnt/cnt.py @@ -159,7 +159,7 @@ def _update_bad_span_onset(accept_reject, onset, duration, description): # Lower nibble (4 bits) keypad button press keypad = event.KeyPad_Accept[0] & 0x0F if str(keypad) != "0": - description.append("KeyPad Response" + " " + str(keypad)) + description.append(f"KeyPad Response {keypad}") elif event.KeyBoard != 0: description.append(f"Keyboard Response {event.KeyBoard}") else: From 83c2d9048df6af2f0b3da10233ad477294d7e92a Mon Sep 17 00:00:00 2001 From: Jacob Woessner Date: Thu, 5 Dec 2024 16:53:21 -0600 Subject: [PATCH 7/9] Fix cnt warnings --- mne/io/cnt/cnt.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/mne/io/cnt/cnt.py b/mne/io/cnt/cnt.py index 4fe505422aa..bdb878c38f8 100644 --- a/mne/io/cnt/cnt.py +++ b/mne/io/cnt/cnt.py @@ -14,7 +14,13 @@ from ..._fiff.utils import _create_chs, _find_channels, _mult_cal_one, read_str from ...annotations import Annotations from ...channels.layout import _topo_to_sphere -from ...utils import _check_option, _validate_type, fill_doc, warn +from ...utils import ( + _check_option, + _validate_type, + fill_doc, + warn, + _explain_exception +) from ..base import BaseRaw from ._utils import ( CNTEventType3, @@ -547,7 +553,8 @@ def __init__( ) except Exception: raise RuntimeError( - "Could not read header from *.cnt file. mne.io.read_raw_cnt " + f"{_explain_exception()}\n" + "WARNING: mne.io.read_raw_cnt " "supports Neuroscan CNT files only. If this file is an ANT Neuro CNT, " "please use mne.io.read_raw_ant instead." ) From 2f1f4e7a70d049be9ad742a96fea42248a36ea97 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2024 22:55:16 +0000 Subject: [PATCH 8/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mne/io/cnt/cnt.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/mne/io/cnt/cnt.py b/mne/io/cnt/cnt.py index bdb878c38f8..da91ee59f9e 100644 --- a/mne/io/cnt/cnt.py +++ b/mne/io/cnt/cnt.py @@ -14,13 +14,7 @@ from ..._fiff.utils import _create_chs, _find_channels, _mult_cal_one, read_str from ...annotations import Annotations from ...channels.layout import _topo_to_sphere -from ...utils import ( - _check_option, - _validate_type, - fill_doc, - warn, - _explain_exception -) +from ...utils import _check_option, _explain_exception, _validate_type, fill_doc, warn from ..base import BaseRaw from ._utils import ( CNTEventType3, From 94e304128cdd567fa62cd198bdc68ba66207c682 Mon Sep 17 00:00:00 2001 From: Jacob Woessner Date: Thu, 5 Dec 2024 17:00:29 -0600 Subject: [PATCH 9/9] Update changelog --- doc/changes/devel/13007.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changes/devel/13007.bugfix.rst diff --git a/doc/changes/devel/13007.bugfix.rst b/doc/changes/devel/13007.bugfix.rst new file mode 100644 index 00000000000..e39d44eae5e --- /dev/null +++ b/doc/changes/devel/13007.bugfix.rst @@ -0,0 +1 @@ +Correct :func:`mne.io.read_raw_cnt` to read responses and fix exceptions by `Jacob Woessner`_. \ No newline at end of file