Skip to content
1 change: 1 addition & 0 deletions doc/changes/dev/13458.apichange.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add ``encoding`` parameter to :func:`mne.io.read_raw_nihon` for better handling of annotation decoding, by `Tom Ma`_.
31 changes: 17 additions & 14 deletions mne/io/nihon/nihon.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ def _ensure_path(fname):


@fill_doc
def read_raw_nihon(fname, preload=False, verbose=None) -> "RawNihon":
def read_raw_nihon(
fname, preload=False, *, encoding="utf-8", verbose=None
) -> "RawNihon":
"""Reader for an Nihon Kohden EEG file.

Parameters
Expand All @@ -32,6 +34,9 @@ def read_raw_nihon(fname, preload=False, verbose=None) -> "RawNihon":
Path to the Nihon Kohden data file (``.EEG``).
preload : bool
If True, all data are loaded at initialization.
%(encoding_nihon)s

.. versionadded:: 1.11
%(verbose)s

Returns
Expand All @@ -44,7 +49,7 @@ def read_raw_nihon(fname, preload=False, verbose=None) -> "RawNihon":
--------
mne.io.Raw : Documentation of attributes and methods of RawNihon.
"""
return RawNihon(fname, preload, verbose)
return RawNihon(fname, preload, encoding=encoding, verbose=verbose)


_valid_headers = [
Expand Down Expand Up @@ -315,7 +320,7 @@ def _parse_sub_event_log(sub_event_log):
return t_sub_desc, t_sub_onset


def _read_nihon_annotations(fname):
def _read_nihon_annotations(fname, encoding="utf-8"):
fname = _ensure_path(fname)
log_fname = fname.with_suffix(".LOG")
if not log_fname.exists():
Expand Down Expand Up @@ -346,15 +351,10 @@ def _read_nihon_annotations(fname):
t_onset += t_sub_onset

t_desc = t_desc.rstrip(b"\x00")
for enc in _encodings:
try:
t_desc = t_desc.decode(enc)
except UnicodeDecodeError:
pass
else:
break
else:
warn(f"Could not decode log as one of {_encodings}")
try:
t_desc = t_desc.decode(encoding)
except UnicodeDecodeError:
warn(f"Could not decode log as {encoding}")
continue

all_onsets.append(t_onset)
Expand Down Expand Up @@ -414,6 +414,9 @@ class RawNihon(BaseRaw):
Path to the Nihon Kohden data ``.eeg`` file.
preload : bool
If True, all data are loaded at initialization.
%(encoding_nihon)s

.. versionadded:: 1.11
%(verbose)s

See Also
Expand All @@ -422,7 +425,7 @@ class RawNihon(BaseRaw):
"""

@verbose
def __init__(self, fname, preload=False, verbose=None):
def __init__(self, fname, preload=False, *, encoding="utf-8", verbose=None):
fname = _check_fname(fname, "read", True, "fname")
data_name = fname.name
logger.info(f"Loading {data_name}")
Expand Down Expand Up @@ -468,7 +471,7 @@ def __init__(self, fname, preload=False, verbose=None):
)

# Get annotations from LOG file
annots = _read_nihon_annotations(fname)
annots = _read_nihon_annotations(fname, encoding)

# Annotate acquisition skips
controlblock = header["controlblocks"][0]
Expand Down
5 changes: 5 additions & 0 deletions mne/utils/docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1285,6 +1285,11 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75):
encoding according to the EDF+ standard).
"""

docdict["encoding_nihon"] = """
encoding : str
Text encoding of Nihon Kohden annotations. See :ref:`standard-encodings`.
"""

docdict["encoding_nirx"] = """
encoding : str
Text encoding of the NIRX header file. See :ref:`standard-encodings`.
Expand Down
Loading