Skip to content

fix EDF loading: Resample channels after loading whole file#11549

Merged
larsoner merged 27 commits intomne-tools:mainfrom
skjerns:issue10635-edf-resampling
Aug 1, 2023
Merged

fix EDF loading: Resample channels after loading whole file#11549
larsoner merged 27 commits intomne-tools:mainfrom
skjerns:issue10635-edf-resampling

Conversation

@skjerns
Copy link
Copy Markdown
Contributor

@skjerns skjerns commented Mar 12, 2023

Reference issue

Example: Fixes #10635

TODO before merge:

  • write some tests, just opening this PR for the issue that came up below
  • include warning when resampling is applied

What does this implement/fix?

Previously, when loading EDF files with different sample frequencies, data was loaded in chunks and each chunk was resampled independently. This created edge artifacts for each chunk, see also:

else:
# XXX resampling each chunk isn't great,
# it forces edge artifacts to appear at
# each buffer boundary :(
# it can also be very slow...

I changed the loading such that minimal changes in the code appear. All channel data is loaded completely, and then resampled. Downside is that it needs 2x as much memory, but only briefly.

However, some tests now fail, as in test_raw.py, it is tested whether data from certain time selections loaded "on the fly" is equivalent to when data is preloaded. I suspect this fails now, as the "on the fly" loaded resampled data contains different edge artifacts, however, I don't fully understand yet why in some cases the edge artifacts look so different.

Details

One tests fails when preload=False and specific timeframes are accessed. I presume this is due to edge artifacts, as it only happens for channels which were resampled:

this test:

@pytest.mark.parametrize('stim_channel', (None, False, 'auto'))
def test_edf_others(fname, stim_channel):
"""Test EDF with various sampling rates and overlapping annotations."""
_test_raw_reader(
read_raw_edf, input_fname=fname, stim_channel=stim_channel,
verbose='error')

which calls this test in io/tests/test_raw.py, when using preload=False, the other tests works (preload=buffer)

for sl_time in slices:
data1, times1 = raw[picks, sl_time]
for other_raw in other_raws:
data2, times2 = other_raw[picks, sl_time]
assert_allclose(
data1, data2, err_msg='Data mismatch with preload')

Plotting differences between the loaded signals reveals A9 having clear edge artefacts, as it is indeed the only resampled channel
test_reduced edf-1

However, some other time indices look weird and not like clear edge artifacts (plottet are diffs between data1 and data2):

test_reduced edf-5
test_reduced edf-7

Any idea what to do with this? Simply remove the test?

@skjerns skjerns changed the title Resample channels after loading whole file [WIP] Resample channels after loading whole file Mar 12, 2023
@skjerns skjerns changed the title [WIP] Resample channels after loading whole file [WIP] EDF: Resample channels after loading whole file Mar 12, 2023
@agramfort
Copy link
Copy Markdown
Member

can you convert the images/scripts above into a unit tests?

@skjerns
Copy link
Copy Markdown
Contributor Author

skjerns commented Jul 26, 2023

I implemented the following solution as proposed by @cbrnr in #10635

  • When preload=False and a subselection is loaded, give a RuntimeWarning.

Btw: Do you want me do make a new PR with these changes? Commit history is kind of chaotic now.

@larsoner
Copy link
Copy Markdown
Member

Btw: Do you want me do make a new PR with these changes? Commit history is kind of chaotic now.

We squash and merge so the chaos evaporates :) Let me know when I should look

@skjerns
Copy link
Copy Markdown
Contributor Author

skjerns commented Jul 27, 2023

Should be ready now @larsoner :)

@skjerns skjerns changed the title [WIP] EDF: Resample channels after loading whole file [PR] EDF: Resample channels after loading whole file Jul 27, 2023
@skjerns skjerns changed the title [PR] EDF: Resample channels after loading whole file fix EDF: Resample channels after loading whole file Jul 27, 2023
@skjerns skjerns changed the title fix EDF: Resample channels after loading whole file fix EDF loading: Resample channels after loading whole file Jul 27, 2023
verbose="error",
test_preloading=False,
preload=True, # no preload=False for mixed sfreqs
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a second run of this with something like:

with pytest.warns(...):
    _test_raw_reader(...)

? In theory it should still pass, right?

Copy link
Copy Markdown
Contributor Author

@skjerns skjerns Aug 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the problem is that the _test_raw_reader also tests for array equivalence when loading slices without preloading vs loading slices with preloading. These will have different edge artifacts and therefore will fail the numpy tests. Therefore _test_raw_reader will not only throw a warning but raise an AssertionError :-/

@larsoner larsoner added this to the 1.5 milestone Aug 1, 2023
@larsoner larsoner enabled auto-merge (squash) August 1, 2023 17:31
@larsoner
Copy link
Copy Markdown
Member

larsoner commented Aug 1, 2023

Marking for merge when green, thanks in advance @skjerns !

@larsoner larsoner merged commit 21efb09 into mne-tools:main Aug 1, 2023
snwnde pushed a commit to snwnde/mne-python that referenced this pull request Mar 20, 2024
@skjerns skjerns deleted the issue10635-edf-resampling branch January 27, 2026 08:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When loading EDF+ with different sampling frequencies, don't resample blockwise

3 participants