Skip to content

Commit

Permalink
[FIX] Reading an EDF with preload=False and mixed frequency (#13069)
Browse files Browse the repository at this point in the history
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Eric Larson <[email protected]>
  • Loading branch information
3 people authored Jan 17, 2025
1 parent 087779c commit bd8c318
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 3 deletions.
1 change: 1 addition & 0 deletions doc/changes/devel/13069.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix bug cause by unnecessary assertion when loading mixed frequency EDFs without preloading :func:`mne.io.read_raw_edf` by `Simon Kern`_.
1 change: 1 addition & 0 deletions mne/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ def pytest_configure(config: pytest.Config):
ignore:.*builtin type swigvarlink has no.*:DeprecationWarning
# eeglabio
ignore:numpy\.core\.records is deprecated.*:DeprecationWarning
ignore:Starting field name with a underscore.*:
# joblib
ignore:process .* is multi-threaded, use of fork/exec.*:DeprecationWarning
""" # noqa: E501
Expand Down
9 changes: 6 additions & 3 deletions mne/io/edf/edf.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,21 +436,24 @@ def _read_segment_file(data, idx, fi, start, stop, raw_extras, filenames, cals,
ones[orig_idx, smp_read : smp_read + len(one_i)] = one_i
n_smp_read[orig_idx] += len(one_i)

# resample channels with lower sample frequency
# skip if no data was requested, ie. only annotations were read
if sum(n_smp_read) > 0:
if any(n_smp_read) > 0:
# expected number of samples, equals maximum sfreq
smp_exp = data.shape[-1]
assert max(n_smp_read) == smp_exp

# resample data after loading all chunks to prevent edge artifacts
resampled = False

for i, smp_read in enumerate(n_smp_read):
# nothing read, nothing to resample
if smp_read == 0:
continue
# upsample if n_samples is lower than from highest sfreq
if smp_read != smp_exp:
assert (ones[i, smp_read:] == 0).all() # sanity check
# sanity check that we read exactly how much we expected
assert (ones[i, smp_read:] == 0).all()

ones[i, :] = resample(
ones[i, :smp_read].astype(np.float64),
smp_exp,
Expand Down
18 changes: 18 additions & 0 deletions mne/io/edf/tests/test_edf.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,24 @@ def test_edf_different_sfreqs(stim_channel):
assert_allclose(times1, times2)


@testing.requires_testing_data
@pytest.mark.parametrize("stim_channel", (None, False, "auto"))
def test_edf_different_sfreqs_nopreload(stim_channel):
"""Test loading smaller sfreq channels without preloading."""
# load without preloading, then load a channel that has smaller sfreq
# as other channels, produced an error, see mne-python/issues/12897

for i in range(1, 13):
raw = read_raw_edf(input_fname=edf_reduced, verbose="error", preload=False)

# this should work for channels of all sfreq, even if larger sfreqs
# are present in the file
x1 = raw.get_data(picks=[f"A{i}"], return_times=False)
# load next ch, this is sometimes with a higher sometimes a lower sfreq
x2 = raw.get_data([f"A{i + 1}"], return_times=False)
assert x1.shape == x2.shape


def test_edf_data_broken(tmp_path):
"""Test edf files."""
raw = _test_raw_reader(
Expand Down

0 comments on commit bd8c318

Please sign in to comment.