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

ENH: Use data-based padding instead of "odd" padding when filtering in raw.plot #13183

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

larsoner
Copy link
Member

@larsoner larsoner commented Apr 2, 2025

I was annoyed at the prominent edge ringing when browsing raw data, see rightmost edge of this plot:

Screenshot From 2025-04-02 13-35-42

I originally decided to combat this by using padtype="constant", but that wasn't quite good enough. I then tried making it so that even for IIR filters we could use our default padtype="reflect_limited", and this helped, but again not quite enough. It also showed that there were slight differences between our "reflect_limited" and NumPy's "reflect", even when there were sufficient samples. Even "reflect" didn't get rid of the ringing entirely, which makes sense for the MEG data I was looking at where very high-frequency, high-amplitude cHPI frequencies cause sharp edges for all of these chosen pad types.

So the ideal/correct fix is really to load sufficient data before and after the viewed window, then filter, then crop back to what you want to display (and do stuff like remove DC from that, choose min/max, decimate, etc.). With that behavior we get something much nicer:

image

So this PR will need/has following things:

  • Clarifies differences between np.pad(..., padtype="reflect") and _smart_pad(..., "reflect_limited") via unit tests. There is really just 1 sample difference, and you could make arguments for either as being more correct. Ours works slightly better for existing tests so let's keep it as-is.
  • Removes a (seemingly) unused thread= arg from _process_data
  • Removes a +1 that was changed to a +2 in an indexing calculation from ENH: Add time_format to Raw.plot() #9419.
  • I need to fully understand why this ☝️ was being done... I think it's probably not the right fix. Instead, somewhere the duration plotted should probably use a np.ceil instead of np.round on the number of samples plotted to ensure that the chosen duration is actually shown. That way when you have start, stop bounds you always get stop - start number of samples, not a kind of weird stop - start + 2, which is the behavior in main. (I think it was still being displayed correctly, but the code for it is unnecessarily complicated).
  • I need to update mne-qt-browser to allow _process_data to accept the modified *args and future proof it against stuff like this, and then cut a bugfix release.
  • Revert larsoner branch uses in CIs here

I don't think there are too many (any?) tests to add here since it's really hard to quantify the edge ringing. So hopefully just looking

)
else:
x_filtered = _overlap_add_filter(x_copy, h, n_fft, phase=phase)[0]
assert_allclose(x_filtered, x_expected, atol=1e-13)
Copy link
Member Author

Choose a reason for hiding this comment

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

This is all just unindenting (and maybe 1 or 2 trivial cleanups I think)

@larsoner
Copy link
Member Author

larsoner commented Apr 3, 2025

@drammock I think this one is ready for review. If the ideas look reasonable we can review and merge mne-tools/mne-qt-browser#320 first, I can cut a release there, and then revert the larsoner/mne-qt-browser uses here

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.

1 participant