Repository: mne-tools/mne-python

Issue:
Problem with load eeglab file
Hi everyone!
I have problem with loading data. I have eeglab files (example: https://ufile.io/f/js83q) and after using mne.io.read_raw_eeglab
I get:
Reading rest1_1_trigg.fdt
```python-traceback
TypeError Traceback (most recent call last)
TypeError: only size-1 arrays can be converted to Python scalars

The above exception was the direct cause of the following exception:

ValueError Traceback (most recent call last)

<ipython-input-20-49d5d8853521> in <module>
----> 1 mne.io.read_raw_eeglab(os.path.join(folder_with_data, files_all[0]))

~.conda\envs\mne\lib\site-packages\mne\io\eeglab\eeglab.py in read_raw_eeglab(input_fname, eog, preload, uint16_codec, verbose)
219 .. versionadded:: 0.11.0
220 """
--> 221 return RawEEGLAB(input_fname=input_fname, preload=preload,
222 eog=eog, verbose=verbose, uint16_codec=uint16_codec)
223

<decorator-gen-197> in init(self, input_fname, eog, preload, uint16_codec, verbose)

~.conda\envs\mne\lib\site-packages\mne\io\eeglab\eeglab.py in init(self, input_fname, eog, preload, uint16_codec, verbose)
353
354 # create event_ch from annotations
--> 355 annot = read_annotations(input_fname)
356 self.set_annotations(annot)
357 _check_boundary(annot, None)

~.conda\envs\mne\lib\site-packages\mne\annotations.py in read_annotations(fname, sfreq, uint16_codec)
665
666 elif name.endswith('set'):
--> 667 annotations = _read_annotations_eeglab(fname,
668 uint16_codec=uint16_codec)
669

~.conda\envs\mne\lib\site-packages\mne\io\eeglab\eeglab.py in _read_annotations_eeglab(eeg, uint16_codec)
611 duration = np.zeros(len(onset))
612 if len(events) > 0 and hasattr(events[0], 'duration'):
--> 613 duration[:] = [event.duration for event in events]
614
615 return Annotations(onset=np.array(onset) / eeg.srate,

ValueError: setting an array element with a sequence.
```
I am using version 0.20.8 of mne and Python 3.8.5.
Can you help me with this problem?


Discussion:
Hi @ociepkam 
I can confirm the problem, I'll take a look at it.
For some reason my traceback renders better on github (highlighting), so I paste it here:

```python-traceback
TypeError: only size-1 arrays can be converted to Python scalars


The above exception was the direct cause of the following exception:

Traceback (most recent call last):

  File "D:\Dropbox\DANE\GabCon\code\py scripts\untitled6.py", line 12, in <module>
    mne.io.read_raw_eeglab(op.join(read_dir, fname))

  File "c:\src\mne-python\mne\io\eeglab\eeglab.py", line 222, in read_raw_eeglab
    eog=eog, verbose=verbose, uint16_codec=uint16_codec)

  File "<decorator-gen-216>", line 21, in __init__

  File "c:\src\mne-python\mne\io\eeglab\eeglab.py", line 355, in __init__
    annot = read_annotations(input_fname)

  File "c:\src\mne-python\mne\annotations.py", line 670, in read_annotations
    uint16_codec=uint16_codec)

  File "c:\src\mne-python\mne\io\eeglab\eeglab.py", line 612, in _read_annotations_eeglab
    duration[:] = [event.duration for event in events]

ValueError: setting an array element with a sequence.
```
@ociepkam It seems some of the durations are empty and other are `NaN` in your case. I's easy to fix but I'm not sure this is typical for eeglab files - were the files preprocessed outside of EEGLAB? What EEGLAB version did you use?


Resolving patch:
diff --git a/mne/io/eeglab/eeglab.py b/mne/io/eeglab/eeglab.py
--- a/mne/io/eeglab/eeglab.py
+++ b/mne/io/eeglab/eeglab.py
@@ -609,7 +609,11 @@ def _read_annotations_eeglab(eeg, uint16_codec=None):
     onset = [event.latency - 1 for event in events]
     duration = np.zeros(len(onset))
     if len(events) > 0 and hasattr(events[0], 'duration'):
-        duration[:] = [event.duration for event in events]
+        for idx, event in enumerate(events):
+            # empty duration fields are read as empty arrays
+            is_empty_array = (isinstance(event.duration, np.ndarray)
+                              and len(event.duration) == 0)
+            duration[idx] = np.nan if is_empty_array else event.duration
 
     return Annotations(onset=np.array(onset) / eeg.srate,
                        duration=duration / eeg.srate,


Test patch:
diff --git a/mne/io/eeglab/tests/test_eeglab.py b/mne/io/eeglab/tests/test_eeglab.py
--- a/mne/io/eeglab/tests/test_eeglab.py
+++ b/mne/io/eeglab/tests/test_eeglab.py
@@ -129,6 +129,24 @@ def test_io_set_raw_more(tmpdir):
                     overlap_fname.replace('.set', '.fdt'))
     read_raw_eeglab(input_fname=overlap_fname, preload=True)
 
+    # test reading file with empty event durations
+    empty_dur_fname = op.join(tmpdir, 'test_empty_durations.set')
+    evnts = deepcopy(eeg.event)
+    for ev in evnts:
+        ev.duration = np.array([], dtype='float')
+
+    io.savemat(empty_dur_fname,
+               {'EEG': {'trials': eeg.trials, 'srate': eeg.srate,
+                        'nbchan': eeg.nbchan,
+                        'data': 'test_negative_latency.fdt',
+                        'epoch': eeg.epoch, 'event': evnts,
+                        'chanlocs': eeg.chanlocs, 'pnts': eeg.pnts}},
+               appendmat=False, oned_as='row')
+    shutil.copyfile(op.join(base_dir, 'test_raw.fdt'),
+                    empty_dur_fname.replace('.set', '.fdt'))
+    raw = read_raw_eeglab(input_fname=empty_dur_fname, preload=True)
+    assert (raw.annotations.duration == 0).all()
+
     # test reading file when the EEG.data name is wrong
     io.savemat(overlap_fname,
                {'EEG': {'trials': eeg.trials, 'srate': eeg.srate,