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
Make removeTrend output identical to MATLAB PREP #71
Conversation
Whoops, looks like I broke something by accident. Serves me right for being too lazy to run unit tests locally before pushing. |
Okay, so I may have jumped the gun a bit: I was looking at the wrong values in MATLAB (the pre-filtered ones) and my FIR filter was also broken (missing the big spike in the middle), so with the two issues combined it looked like it was working. I've fixed the custom filter itself so it's actually identical to MATLAB's now, but MNE's filter applying function still produces values from EEGLAB's so I'm giving this a rest for now. The actual filter application code in MATLAB looks reasonably simple, so maybe on a future day I'll try adapting that too. |
If something is unclear from the MNE side, you can always pose a question on https://mne.discourse.group :-) |
@sappelhoff So it absolutely wasn't worth the total time and effort, but sunk cost fallacy kept me going until the end: in the latest commit I've implemented the equivalent of MATLAB's Now NoisyChannels gives me identical RANSAC correlations regardless of whether I use a .set that's been pre-highpassed in MATLAB (what I've been doing so far for tests) or I do the high-passing in PyPREP with removeTrend. On the flip side, this method is also about 4x slower than the previous one (~8 seconds vs. ~2 seconds for a 64-channel, 694016-sample file), and I really don't know much about filter theory or signal processing so MNE's filtering could be technically superior at trend-removal than the code here. My current thinking is that maybe this should just be wrapped in Comparisons of RANSAC correlations between removeTrend methods (click to unhide)Current removeTrend method (MNE's
|
yes! Let's do that and keep the mne detrending as a default 👍 the differences are quite tiny but it's good you got it to align perfectly --> yet as you say, we don't know how "good" and/or "robust" your code is ... at least relative to MNE's filtering implementation that is tested every minute by lots of users. |
If you know anyone who knows their stuff re: filtering and signal processing theory, it'd be interesting to hear their take on the functional difference between the EEGLAB and MNE methods. Since we're wrapping this in |
@sappelhoff Okay, think I've got this sorted now! In addition to wrapping this in If either of us learn any more about the costs/benefits of MNE's filtering algorithm vs. EEGLAB's, I'll update the deliberate differences section accordingly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, only some tiny clarifications needed if possible
Codecov Report
@@ Coverage Diff @@
## master #71 +/- ##
==========================================
+ Coverage 97.15% 97.33% +0.17%
==========================================
Files 7 7
Lines 597 637 +40
==========================================
+ Hits 580 620 +40
Misses 17 17
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks a bunch!
@sappelhoff So I'm currently taking a grad course on signal processing, and I think I finally understand the key difference between MNE's highpass filter and EEGLAB's: MNE defaults to applying the filter using a zero-phase method that doesn't result in any phase shift in the signal (the equivalent of As far as I can tell, other than theoretically being faster (which it isn't in the current implementation) there's absolutely no reason to use a forwards-only filter like EEGLAB does instead of the backwards-forwards zero-phase approach used by MNE. I'm guessing this is a weird legacy carry-over for EEGLAB from the days when people were running EEG analyses on Pentium 3's and PowerPC G4's so CPU cycles were at a major premium. I'll update the "differences" docs to reflect this when I get a chance! |
😱 gosh ...
you are probably right, EEGLAB has been around for quite some time! great that you remembered this issue! |
PR Description
Closes #55.
Basically, MNE and EEGLAB calculate FIR filter parameters slightly differently (specifically, the length of the filter). To bypass this, I've added a new function that calculates the parameter values the same way that EEGLAB does and uses SciPy's
signal.firwin
to turn them into a MatPREP-identical filter. Then, I use the same internal method MNE'sfilter.filter_data
does to apply the filter to the signal, producing identical output to MatPREP'sremoveTrend
.Merge Checklist
closes #<issue-number>
to automatically close an issue