mne-python: EDF read in not working in certain files, read in slow
edf_test_edited.zip edf_test.zip
The attached EDF file “edf_test.edf” can be opened via pyedflib:
Python 3.6.6 |Anaconda custom (64-bit)| (default, Jun 28 2018, 11:07:29)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.4.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import pyedflib
In [2]: f = pyedflib.EdfReader("edf_test.edf")
In [3]: f.readSignal(chn=0)
Out[3]:
array([-18000. , -18000. , -18000. , ...,
4210.98649577, 4210.98649577, 4210.98649577])
File cannot be opened with mne:
In [1]: import mne
In [2]: mne.io.read_raw_edf("edf_test.edf", preload = True)
Extracting EDF parameters from edf_test.edf...
EDF file detected
Setting channel info structure...
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-2-8bfb048068a5> in <module>()
----> 1 mne.io.read_raw_edf("edf_test.edf", preload = True)
~/anaconda3/lib/python3.6/site-packages/mne/io/edf/edf.py in read_raw_edf(input_fname, montage, eog, misc, stim_channel, annot, annotmap, exclude, preload, verbose)
1237 return RawEDF(input_fname=input_fname, montage=montage, eog=eog, misc=misc,
1238 stim_channel=stim_channel, annot=annot, annotmap=annotmap,
-> 1239 exclude=exclude, preload=preload, verbose=verbose)
~/anaconda3/lib/python3.6/site-packages/mne/io/edf/edf.py in __init__(self, input_fname, montage, eog, misc, stim_channel, annot, annotmap, exclude, preload, verbose)
~/anaconda3/lib/python3.6/site-packages/mne/utils.py in verbose(function, *args, **kwargs)
727 with use_log_level(verbose_level):
728 return function(*args, **kwargs)
--> 729 return function(*args, **kwargs)
730
731
~/anaconda3/lib/python3.6/site-packages/mne/io/edf/edf.py in __init__(self, input_fname, montage, eog, misc, stim_channel, annot, annotmap, exclude, preload, verbose)
156 input_fname = os.path.abspath(input_fname)
157 info, edf_info = _get_info(input_fname, stim_channel, annot,
--> 158 annotmap, eog, misc, exclude, preload)
159 logger.info('Creating raw.info structure...')
160 _check_update_montage(info, montage)
~/anaconda3/lib/python3.6/site-packages/mne/io/edf/edf.py in _get_info(fname, stim_channel, annot, annotmap, eog, misc, exclude, preload)
509 data_samps = np.delete(n_samps, slice(stim_channel, stim_channel + 1))
510 sfreq = data_samps.max() * \
--> 511 edf_info['record_length'][1] / edf_info['record_length'][0]
512
513 info = _empty_info(sfreq)
~/anaconda3/lib/python3.6/site-packages/numpy/core/_methods.py in _amax(a, axis, out, keepdims)
24 # small reductions
25 def _amax(a, axis=None, out=None, keepdims=False):
---> 26 return umr_maximum(a, axis, None, out, keepdims)
27
28 def _amin(a, axis=None, out=None, keepdims=False):
ValueError: zero-size array to reduction operation maximum which has no identity
With nme, adding stim_chan = None solves the problem:
In [3]: mne.io.read_raw_edf("edf_test.edf", preload = True, stim_channel=None)
Extracting EDF parameters from edf_test.edf...
EDF file detected
Setting channel info structure...
Creating raw.info structure...In [1]: import mne
In [2]: mne.io.read_raw_edf("edf_test_edited.edf", preload=True)
Extracting EDF parameters from edf_test_edited.edf...
EDF file detected
EDF annotations detected (consider using raw.find_edf_events() to extract them)
Setting channel info structure...
Creating raw.info structure...
Reading 0 ... 1843199 = 0.000 ... 3599.998 secs...
Out[2]: <RawEDF | edf_test_edited.edf, n_channels x n_times : 2 x 1843200 (3600.0 sec), ~28.1 MB, data loaded>
Reading 0 ... 1843199 = 0.000 ... 3599.998 secs...
Out[3]: <RawEDF | edf_test.edf, n_channels x n_times : 1 x 1843200 (3600.0 sec), ~14.1 MB, data loaded>
The same EDF file with annotations (edf_test_edited.edf):
In [3]: mne.io.read_raw_edf("edf_test_edited.edf", preload = True)
Extracting EDF parameters from edf_test_edited.edf...
EDF file detected
EDF annotations detected (consider using raw.find_edf_events() to extract them)
Setting channel info structure...
Creating raw.info structure...
Reading 0 ... 1843199 = 0.000 ... 3599.998 secs...
Out[3]: <RawEDF | edf_test_edited.edf, n_channels x n_times : 2 x 1843200 (3600.0 sec), ~28.1 MB, data loaded>
Note that the EDF files only contain 1 channel, but <RawEDF | edf_test_edited.edf, n_channels x n_times : 2 x 1843200 (3600.0 sec), ~28.1 MB, data loaded> states n_channels = 2.
Additionaly, EDF readin is really slow with stim_chan = None:
Timing for read in of annotated file without stim_channel=None is really slow:
%timeit mne.io.read_raw_edf("edf_test_edited.edf", preload=True)
Extracting EDF parameters from edf_test_edited.edf...
EDF file detected
EDF annotations detected (consider using raw.find_edf_events() to extract them)
Setting channel info structure...
Creating raw.info structure...
Reading 0 ... 1843199 = 0.000 ... 3599.998 secs..
4.59 s ± 12.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
compared to read in with stim_chan=None:
%timeit mne.io.read_raw_edf("edf_test_edited.edf", preload=True, stim_channel=None)
Extracting EDF parameters from edf_test_edited.edf...
EDF file detected
EDF annotations detected (consider using raw.find_edf_events() to extract them)
Setting channel info structure...
Creating raw.info structure...
<magic-timeit>:1: RuntimeWarning: 1 channel names are too long, have been truncated to 15 characters:
['EDF Annotations-1']
1 channel names are too long, have been truncated to 15 characters:
['EDF Annotations-1']
Reading 0 ... 1843199 = 0.000 ... 3599.998 secs...
59.2 ms ± 962 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Can these issues be solved?
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 16 (11 by maintainers)
I don’t have much time to comment but the annotations in edf files should become raw.annotations attribute by default and not produce a stim channel if not present in the file. Then it should be possible to get events from raw.annotations.
See previous discussion on this.
It will speed up IO by avoiding extra allocations and heavily simply EDF IO code, especially with preload=False