Repository: mne-tools/mne-python

Issue:
Reading .mff file - keyerror: 'EEG'
Python noob. Please help me with this error whilst reading in an .mff file!!! Why am I getting a KeyError for 'EEG' and how do I fix? Thank you



INPUT:
```
raw_path = r'/~/Desktop/file.mff'
raw_data = mne.io.read_raw_egi(raw_path)
```

OUTPUT:
```
Reading EGI MFF Header from /~/Desktop/file.mff...
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-14-6153fc6ec773> in <module>
      1 raw_path = r'/Users/rahulkakaiya/Desktop/neuro-analysis/Rahul-1-Danielle.mff'
----> 2 raw_data = mne.io.read_raw_egi(raw_path)

<decorator-gen-167> in read_raw_egi(input_fname, eog, misc, include, exclude, preload, channel_naming, verbose)

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/mne/io/egi/egi.py in read_raw_egi(input_fname, eog, misc, include, exclude, preload, channel_naming, verbose)
    151     if input_fname.endswith('.mff'):
    152         return _read_raw_egi_mff(input_fname, eog, misc, include,
--> 153                                  exclude, preload, channel_naming, verbose)
    154     return RawEGI(input_fname, eog, misc, include, exclude, preload,
    155                   channel_naming, verbose)

<decorator-gen-165> in _read_raw_egi_mff(input_fname, eog, misc, include, exclude, preload, channel_naming, verbose)

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/mne/io/egi/egimff.py in _read_raw_egi_mff(input_fname, eog, misc, include, exclude, preload, channel_naming, verbose)
    275     """
    276     return RawMff(input_fname, eog, misc, include, exclude,
--> 277                   preload, channel_naming, verbose)
    278 
    279 

<decorator-gen-166> in __init__(self, input_fname, eog, misc, include, exclude, preload, channel_naming, verbose)

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/mne/io/egi/egimff.py in __init__(self, input_fname, eog, misc, include, exclude, preload, channel_naming, verbose)
    287         """Init the RawMff class."""
    288         logger.info('Reading EGI MFF Header from %s...' % input_fname)
--> 289         egi_info = _read_header(input_fname)
    290         if eog is None:
    291             eog = []

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/mne/io/egi/egimff.py in _read_header(input_fname)
    152         Main headers set.
    153     """
--> 154     mff_hdr = _read_mff_header(input_fname)
    155     with open(input_fname + '/signal1.bin', 'rb') as fid:
    156         version = np.fromfile(fid, np.int32, 1)[0]

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/mne/io/egi/egimff.py in _read_mff_header(filepath)
     28     """
     29     all_files = _get_signalfname(filepath)
---> 30     eeg_file = all_files['EEG']['signal']
     31     eeg_info_file = all_files['EEG']['info']
     32 

KeyError: 'EEG'
```


Discussion:
I don't know the EGI format, but can you confirm that you are trying to load a valid EGI file? That is, have you tried opening it with other programs (e.g. Biosig)?

Resolving patch:
diff --git a/mne/io/egi/general.py b/mne/io/egi/general.py
--- a/mne/io/egi/general.py
+++ b/mne/io/egi/general.py
@@ -8,6 +8,8 @@
 
 import numpy as np
 
+from ...utils import _pl
+
 
 def _extract(tags, filepath=None, obj=None):
     """Extract info from XML."""
@@ -123,9 +125,11 @@ def _get_signalfname(filepath):
     binfiles = list(f for f in listfiles if 'signal' in f and
                     f[-4:] == '.bin' and f[0] != '.')
     all_files = {}
+    infofiles = list()
     for binfile in binfiles:
         bin_num_str = re.search(r'\d+', binfile).group()
         infofile = 'info' + bin_num_str + '.xml'
+        infofiles.append(infofile)
         infobjfile = os.path.join(filepath, infofile)
         infobj = parse(infobjfile)
         if len(infobj.getElementsByTagName('EEG')):
@@ -135,6 +139,10 @@ def _get_signalfname(filepath):
         all_files[signal_type] = {
             'signal': 'signal{}.bin'.format(bin_num_str),
             'info': infofile}
+    if 'EEG' not in all_files:
+        raise FileNotFoundError(
+            'Could not find any EEG data in the %d file%s found in %s:\n%s'
+            % (len(infofiles), _pl(infofiles), filepath, '\n'.join(infofiles)))
     return all_files
 
 


Test patch:
diff --git a/mne/io/egi/tests/test_egi.py b/mne/io/egi/tests/test_egi.py
--- a/mne/io/egi/tests/test_egi.py
+++ b/mne/io/egi/tests/test_egi.py
@@ -5,6 +5,8 @@
 
 import os.path as op
 import inspect
+import os
+import shutil
 
 import numpy as np
 from numpy.testing import assert_array_equal, assert_allclose, assert_equal
@@ -108,7 +110,7 @@ def test_io_egi():
 
 
 @requires_testing_data
-def test_io_egi_pns_mff():
+def test_io_egi_pns_mff(tmpdir):
     """Test importing EGI MFF with PNS data."""
     egi_fname_mff = op.join(data_path(), 'EGI', 'test_egi_pns.mff')
     raw = read_raw_egi(egi_fname_mff, include=None, preload=True,
@@ -147,6 +149,15 @@ def test_io_egi_pns_mff():
         raw_data = raw[ch_idx][0]
         assert_array_equal(mat_data, raw_data)
 
+    # EEG missing
+    new_mff = str(tmpdir.join('temp.mff'))
+    shutil.copytree(egi_fname_mff, new_mff)
+    read_raw_egi(new_mff, verbose='error')
+    os.remove(op.join(new_mff, 'info1.xml'))
+    os.remove(op.join(new_mff, 'signal1.bin'))
+    with pytest.raises(FileNotFoundError, match='Could not find any EEG'):
+        read_raw_egi(new_mff, verbose='error')
+
 
 @requires_testing_data
 def test_io_egi_pns_mff_bug():