Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX : EDF+ Annotation Timestamps missing sub-second accuracy #7875

Merged
merged 5 commits into from
Jun 8, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mne/datasets/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def _data_path(path=None, force_update=False, update_path=True, download=True,
path = _get_path(path, key, name)
# To update the testing or misc dataset, push commits, then make a new
# release on GitHub. Then update the "releases" variable:
releases = dict(testing='0.91', misc='0.6')
releases = dict(testing='0.92', misc='0.6')
# And also update the "md5_hashes['testing']" variable below.

# To update any other dataset, update the data archive itself (upload
Expand Down Expand Up @@ -326,7 +326,7 @@ def _data_path(path=None, force_update=False, update_path=True, download=True,
sample='12b75d1cb7df9dfb4ad73ed82f61094f',
somato='ea825966c0a1e9b2f84e3826c5500161',
spm='9f43f67150e3b694b523a21eb929ea75',
testing='f87f04fcdf56a7a55fb73b1b260b5b5b',
testing='42daafd1b882da2ef041de860ca6e771',
multimodal='26ec847ae9ab80f58f204d09e2c08367',
fnirs_motor='c4935d19ddab35422a69f3326a01fef8',
opm='370ad1dcfd5c47e029e692c85358a374',
Expand Down
15 changes: 13 additions & 2 deletions mne/io/edf/edf.py
Original file line number Diff line number Diff line change
Expand Up @@ -1375,12 +1375,23 @@ def _read_annotations_edf(annotations):
triggers = re.findall(pat, tals.decode('latin-1'))

events = []
for ev in triggers:
onset = float(ev[0])
offset = 0.
for k, ev in enumerate(triggers):
onset = float(ev[0]) + offset
duration = float(ev[2]) if ev[2] else 0
for description in ev[3].split('\x14')[1:]:
if description:
events.append([onset, duration, description])
elif k == 0:
# The startdate/time of a file is specified in the EDF+ header
# fields 'startdate of recording' and 'starttime of recording'.
# These fields must indicate the absolute second in which the
# start of the first data record falls. So, the first TAL in
# the first data record always starts with +0.X, indicating
# that the first data record starts a fraction, X, of a second
# after the startdate/time that is specified in the EDF+
# header. If X=0, then the .X may be omitted.
offset = -onset

return zip(*events) if events else (list(), list(), list())

Expand Down
8 changes: 8 additions & 0 deletions mne/io/edf/tests/test_edf.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
'multiple_annotation_chans.bdf')
test_generator_bdf = op.join(data_path, 'BDF', 'test_generator_2.bdf')
test_generator_edf = op.join(data_path, 'EDF', 'test_generator_2.edf')
edf_annot_sub_ms_path = op.join(data_path, 'EDF', 'subsecond_starttime.edf')

eog = ['REOG', 'LEOG', 'IEOG']
misc = ['EXG1', 'EXG5', 'EXG8', 'M1', 'M2']
Expand Down Expand Up @@ -385,3 +386,10 @@ def test_edf_lowpass_zero():
with pytest.warns(RuntimeWarning, match='too long.*truncated'):
raw = read_raw_edf(edf_stim_resamp_path)
assert_allclose(raw.info["lowpass"], raw.info["sfreq"] / 2)


@testing.requires_testing_data
def test_edf_annot_ms_onset():
"""Test reading of sub-milisecond annotation onsets."""
raw = read_raw_edf(edf_annot_sub_ms_path)
assert_allclose(raw.annotations.onset, [1.951172, 3.492188])