diff --git a/doc/changes/devel/12730.bugfix.rst b/doc/changes/devel/12730.bugfix.rst new file mode 100644 index 00000000000..b6180815110 --- /dev/null +++ b/doc/changes/devel/12730.bugfix.rst @@ -0,0 +1 @@ +Fix bug when reading NIRX files saved in a non-western encoding, by `Daniel McCloy`_. diff --git a/mne/io/nirx/_localized_abbr.py b/mne/io/nirx/_localized_abbr.py index a3fe8e0b3c9..77622c496e7 100644 --- a/mne/io/nirx/_localized_abbr.py +++ b/mne/io/nirx/_localized_abbr.py @@ -41,6 +41,7 @@ print('}\n') """ +# TODO: this should really be outsourced to a dedicated module like arrow or babel _localized_abbr = { "en_US.utf8": { "month": { diff --git a/mne/io/nirx/nirx.py b/mne/io/nirx/nirx.py index b5a13a478b5..95fa061ea4e 100644 --- a/mne/io/nirx/nirx.py +++ b/mne/io/nirx/nirx.py @@ -35,7 +35,7 @@ @fill_doc def read_raw_nirx( - fname, saturated="annotate", preload=False, verbose=None + fname, saturated="annotate", *, preload=False, encoding="latin-1", verbose=None ) -> "RawNIRX": """Reader for a NIRX fNIRS recording. @@ -45,6 +45,7 @@ def read_raw_nirx( Path to the NIRX data folder or header file. %(saturated)s %(preload)s + %(encoding_nirx)s %(verbose)s Returns @@ -61,7 +62,9 @@ def read_raw_nirx( ----- %(nirx_notes)s """ - return RawNIRX(fname, saturated, preload, verbose) + return RawNIRX( + fname, saturated, preload=preload, encoding=encoding, verbose=verbose + ) def _open(fname): @@ -78,6 +81,7 @@ class RawNIRX(BaseRaw): Path to the NIRX data folder or header file. %(saturated)s %(preload)s + %(encoding_nirx)s %(verbose)s See Also @@ -90,7 +94,7 @@ class RawNIRX(BaseRaw): """ @verbose - def __init__(self, fname, saturated, preload=False, verbose=None): + def __init__(self, fname, saturated, *, preload=False, encoding=None, verbose=None): logger.info(f"Loading {fname}") _validate_type(fname, "path-like", "fname") _validate_type(saturated, str, "saturated") @@ -102,10 +106,7 @@ def __init__(self, fname, saturated, preload=False, verbose=None): fname = str(_check_fname(fname, "read", True, "fname", need_dir=True)) json_config = glob.glob(f"{fname}/*{'config.json'}") - if len(json_config): - is_aurora = True - else: - is_aurora = False + is_aurora = len(json_config) if is_aurora: # NIRSport2 devices using Aurora software @@ -178,7 +179,7 @@ def __init__(self, fname, saturated, preload=False, verbose=None): # Read header file # The header file isn't compliant with the configparser. So all the # text between comments must be removed before passing to parser - with _open(files["hdr"]) as f: + with open(files["hdr"], encoding=encoding) as f: hdr_str_all = f.read() hdr_str = re.sub("#.*?#", "", hdr_str_all, flags=re.DOTALL) if is_aurora: @@ -242,6 +243,7 @@ def __init__(self, fname, saturated, preload=False, verbose=None): '"%a %d %b %Y""%H:%M:%S.%f"', '"%a, %d %b %Y""%H:%M:%S.%f"', "%Y-%m-%d %H:%M:%S.%f", + '"%Y年%m月%d日""%H:%M:%S.%f"', ]: try: meas_date = dt.datetime.strptime(loc_datetime_str, dt_code) diff --git a/mne/utils/docs.py b/mne/utils/docs.py index 0f123661758..f59aaa31306 100644 --- a/mne/utils/docs.py +++ b/mne/utils/docs.py @@ -1275,6 +1275,11 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75): encoding according to the EDF+ standard). """ +docdict["encoding_nirx"] = """ +encoding : str + Text encoding of the NIRX header file. See :ref:`standard-encodings`. +""" + docdict["epochs_preload"] = """ Load all epochs from disk when creating the object or wait before accessing each epoch (more memory