Repository: mne-tools/mne-bids

Issue:
new EEGLAB files may contain fields in root of file, instead of nested in "EEG" struct
see: https://github.com/mne-tools/mne-python/pull/8874

We need to apply @cbrnr's fix also here:

https://github.com/mne-tools/mne-bids/blob/415988e88f6253527d38d60dd521d0b94d5baa98/mne_bids/copyfiles.py#L516-L518





Discussion:
And we should make use of the new test file he provided
@cbrnr do you maybe have some time to take this over? :-) before users start running into this as a problem?
Sure!

Resolving patch:
diff --git a/mne_bids/copyfiles.py b/mne_bids/copyfiles.py
--- a/mne_bids/copyfiles.py
+++ b/mne_bids/copyfiles.py
@@ -502,20 +502,21 @@ def copyfile_eeglab(src, dest):
     if not mne.utils.check_version('scipy', '1.5.0'):  # pragma: no cover
         raise ImportError('SciPy >=1.5.0 is required handling EEGLAB data.')
 
-    # Get extenstion of the EEGLAB file
+    # Get extension of the EEGLAB file
     _, ext_src = _parse_ext(src)
     fname_dest, ext_dest = _parse_ext(dest)
     if ext_src != ext_dest:
         raise ValueError(f'Need to move data with same extension'
                          f' but got {ext_src}, {ext_dest}')
 
-    # Load the EEG struct.
+    # Load the EEG struct
     uint16_codec = None
-    mat = loadmat(file_name=src, simplify_cells=True,
+    eeg = loadmat(file_name=src, simplify_cells=True,
                   appendmat=False, uint16_codec=uint16_codec)
-    if 'EEG' not in mat:
-        raise ValueError(f'Could not find "EEG" field in {src}')
-    eeg = mat['EEG']
+    oldstyle = False
+    if 'EEG' in eeg:
+        eeg = eeg['EEG']
+        oldstyle = True
 
     if isinstance(eeg['data'], str):
         # If the data field is a string, it points to a .fdt file in src dir
@@ -532,7 +533,7 @@ def copyfile_eeglab(src, dest):
         eeg['data'] = tail
 
         # Save the EEG dictionary as a Matlab struct again
-        mdict = dict(EEG=eeg)
+        mdict = dict(EEG=eeg) if oldstyle else eeg
         savemat(file_name=dest, mdict=mdict, appendmat=False)
     else:
         # If no .fdt file, simply copy the .set file, no modifications


Test patch:
diff --git a/mne_bids/tests/test_copyfiles.py b/mne_bids/tests/test_copyfiles.py
--- a/mne_bids/tests/test_copyfiles.py
+++ b/mne_bids/tests/test_copyfiles.py
@@ -9,7 +9,6 @@
 from distutils.version import LooseVersion
 
 import pytest
-from scipy.io import savemat
 
 # This is here to handle mne-python <0.20
 import warnings
@@ -184,7 +183,8 @@ def _edf_get_real_date(fpath):
 
 
 @pytest.mark.parametrize('fname',
-                         ('test_raw.set', 'test_raw_chanloc.set'))
+                         ('test_raw.set', 'test_raw_chanloc.set',
+                          'test_raw_2021.set'))
 def test_copyfile_eeglab(tmpdir, fname):
     """Test the copying of EEGlab set and fdt files."""
     if (fname == 'test_raw_chanloc.set' and
@@ -200,21 +200,15 @@ def test_copyfile_eeglab(tmpdir, fname):
     with pytest.raises(ValueError, match="Need to move data with same ext"):
         copyfile_eeglab(raw_fname, new_name + '.wrong')
 
-    # Bad .set file testing
-    with pytest.raises(ValueError, match='Could not find "EEG" field'):
-        fake_set = op.join(bids_root, 'fake.set')
-        savemat(fake_set, {'arr': [1, 2, 3]}, appendmat=False)
-        copyfile_eeglab(fake_set, new_name)
-
-    # Test copying and reading a combined set+fdt
+    # Test copying and reading
     copyfile_eeglab(raw_fname, new_name)
-    if fname == 'test_raw_chanloc.set':
+    if fname == 'test_raw_chanloc.set':  # combined set+fdt
         with pytest.warns(RuntimeWarning,
                           match="The data contains 'boundary' events"):
             raw = mne.io.read_raw_eeglab(new_name)
             assert 'Fp1' in raw.ch_names
-    else:
-        raw = mne.io.read_raw_eeglab(new_name)
+    else:  # combined set+fdt and single set (new EEGLAB format)
+        raw = mne.io.read_raw_eeglab(new_name, preload=True)
         assert 'EEG 001' in raw.ch_names
     assert isinstance(raw, mne.io.BaseRaw)