Skip to content
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
1 change: 1 addition & 0 deletions doc/changes/dev/13962.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix bug in :func:`mne.read_annotations` where reading a ``.txt`` file containing a single channel-specific annotation raised an ``AttributeError``, by :newcontrib:`Piotr Durka`.
1 change: 1 addition & 0 deletions doc/changes/names.inc
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@
.. _Pierre Guetschel: https://github.com/PierreGtch
.. _Pierre-Antoine Bannier: https://github.com/PABannier
.. _Ping-Keng Jao: https://github.com/nafraw
.. _Piotr Durka: https://github.com/pjdurka
.. _Pragnya Khandelwal: https://github.com/PragnyaKhandelwal
.. _Proloy Das: https://github.com/proloyd
.. _Qian Chu: https://github.com/qian-chu
Expand Down
2 changes: 1 addition & 1 deletion mne/annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2105,7 +2105,7 @@ def _read_annotations_txt(fname):
if ch_names is not None:
ch_names = [
_safe_name_list(ch.decode().strip(), "read", f"ch_names[{ci}]")
for ci, ch in enumerate(ch_names)
for ci, ch in enumerate(np.atleast_1d(ch_names))
]

annotations = Annotations(
Expand Down
12 changes: 12 additions & 0 deletions mne/tests/test_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,18 @@ def test_io_annotation(dummy_annotation_file, tmp_path, fmt, ch_names, with_extr
_assert_annotations_equal(annot, annot2)


def test_read_annotations_txt_single_channel_specific(tmp_path):
"""Read a .txt with a SINGLE channel-specific annotation (gh-13961)."""
# np.loadtxt(..., unpack=True) squeezes a 1-row file to 0-D scalars;
# ch_names (unlike onset/duration/description) was not wrapped in
# np.atleast_1d, so it was iterated as bytes-ints -> AttributeError.
annot = Annotations([1.0], [0.5], ["BAD_x"], ch_names=[["EEG001"]])
fname = tmp_path / "annotations.txt"
annot.save(fname)
annot_read = read_annotations(fname)
assert list(annot_read.ch_names) == [("EEG001",)]


@pytest.mark.parametrize("fmt", [pytest.param("csv", marks=needs_pandas), "txt"])
def test_write_annotation_warn_heterogeneous(tmp_path, fmt):
"""Test that CSV, and TXT annotation writers warn on heterogeneous dtypes."""
Expand Down
Loading