added option to keep or remove the DC for psd calculations issue #11767#11769
added option to keep or remove the DC for psd calculations issue #11767#11769drammock merged 9 commits intomne-tools:mainfrom
Conversation
|
For the failed tests, when I go to CircleCI, I get "block-unregistered-user" |
|
Can you try logging in there through GitHub, then push another commit? If that doesn't fix it, I can push an empty commit and it should run |
I restarted CircleCI. I think if you create a CircleCI account (or "log in with GitHub"?) then that will stop happening on your PRs. It's a bit annoying, I'll grant, but since we actually pay for CircleCI time it prevents someone (accidentally or maliciously) burning through a lot of our grant money by opening a bunch of doc-build-heavy PRs. |
|
I created an account now on CircleCI now, thanks, let's see if I have issues again in the future |
|
Are any of the fails related to my PR? I did not change the functions that fail. |
mne/utils/docs.py
Outdated
| function (e.g., ``n_fft, n_overlap, n_per_seg, average, window, remove_dc`` | ||
| for Welch method, or | ||
| ``bandwidth, adaptive, low_bias, normalization`` for multitaper | ||
| ``bandwidth, adaptive, low_bias, normalization, remove_dc`` for multitaper |
There was a problem hiding this comment.
if remove_dc is a common kwarg for both welch and multitaper, then it should probably become part of the main signature of compute_psd rather than being a **method_kwarg (which is meant to handle only the kwargs that differ between methods)
There was a problem hiding this comment.
I was thinking about that too. If we put that option outside of method_kwarg, I would need to add it almost "everywhere" in the time_frequency classes/methods, all the constructors, etc... Was wondering if there would be a way to avoid that...
There was a problem hiding this comment.
$ git grep method_kw_psd
mne/epochs.py:2364: %(method_kw_psd)s
mne/epochs.py:2455: %(method_kw_psd)s
mne/evoked.py:1059: %(method_kw_psd)s
mne/evoked.py:1151: %(method_kw_psd)s
mne/io/base.py:2170: %(method_kw_psd)s
mne/time_frequency/spectrum.py:124: %(method_kw_psd)s
mne/time_frequency/spectrum.py:179: %(method_kw_psd)s Defaults to ``dict(n_fft=2048)``.
mne/time_frequency/spectrum.py:263: %(method_kw_psd)s
mne/time_frequency/spectrum.py:1066: %(method_kw_psd)s
mne/time_frequency/spectrum.py:1201: %(method_kw_psd)s
mne/utils/docs.py:2493: "method_kw_psd"I count ten places. That seems doable? It is only for spectrum classes and the compute_psd methods, not for the time-frequency classes/methods I think.
There was a problem hiding this comment.
I count 56 if you do git grep method_kw, but yeah doable I guess!
There was a problem hiding this comment.
Before I start making all the changes, is there a preference of where it should come in the order of variables? Here is the init of BaseSpectrum for example:
def __init__(
self,
inst,
method,
fmin,
fmax,
tmin,
tmax,
picks,
proj,
*,
n_jobs,
verbose=None,
**method_kw,
):
There was a problem hiding this comment.
ok i'll wait for your input before making any changes
There was a problem hiding this comment.
Hi @drammock! Checking in if you have any updates on this.
There was a problem hiding this comment.
OK, sorry it took so long to get you an answer. I think we should add the new kwarg to:
- {BaseRaw, Epochs, Evoked}.compute_psd() and {BaseSpectrum,Spectrum,EpochsSpectrum}.
__init__should all get the new named paramremove_dc- you'll need to pass it through to
._compute_spectraand from there pass it intoself._psd_func.
- you'll need to pass it through to
- {BaseRaw, Epochs, Evoked}.plot_psd() should NOT --- those are legacy methods and their API shouldn't change. It should still work to pass
remove_dc--- it will get bundled intomethod_kw - SpectrumMixin.plot_psd(), .plot_psd_topo() and .plot_psd_topomap() should NOT (same reason: legacy)
Hopefully that works; this is based on git grep and reading/reasoning about the code; I haven't tested it. If it turns out to fail or be really messy it won't be the end of the world to incorporate remove_dc into the method_kw everywhere.
There was a problem hiding this comment.
I'll work on it now
There was a problem hiding this comment.
finished, please have a look, i tested in my notebook, all seems ok
fix to avoid the test failures and make it compatible with existing code. Updated doc as requested.
|
I haven't looked closely yet but the names of the failing test functions suggest that they're legitimate failures. For example: |
|
if you run those tests locally do they pass? |
|
Sorry, forgot to run to check locally. I think the issue is because of the new default value for remove_dc. I'll check what is going on |
|
in nitime code there is: https://github.com/nipy/nitime/blob/2d5a7b05a084960567318b39256a523e53f07790/nitime/utils.py#L735 So it seams they remove the mean automatically.
|
For me I think I lean toward preserving backward compatibility here, which means we should make
To me this says "there are at least some cases where demeaning makes sense so we can't consider this a bugfix". Therefore defaulting to @larsoner are you convinced by that reasoning? (note that if |
|
Yes I think unless someone looks up in a signal processing textbook or online material (or already has the knowledge!) the reasoning behind mean removal and finds that it's always safely optional then we should assume that it's at least sometimes unsafe and so shouldn't change our default. I have some vague recollection that you need to do it to prevent leakage as you say so my gut says it's better to be safe than sorry here |
|
ok, I set remove_dc = True (although I'll personally use remove_dc=False :) ). All tests pass locally, needed to fix one bug in class initialization. |
|
Here are some reasons for detrending in the Welch case (from https://holometer.fnal.gov/GH_FFT.pdf), so probably does make sense to keep remove_dc=True in the default case. But good to have the choice now. For Multitaper, which only has one segment, I imagine it could help with some numerical stability, as it only affects one point of the resulting PSD. |
|
+1 to keep constant detrend by default.
scipy does it too:
https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.welch.html
but we could expose the same API as scipy here to control this
Alex
… Message ID: ***@***.***>
|
|
Glad to see it merged! Do I need to document the changes somewhere? |
haha, oops! I was supposed to ask you for a changelog entry before merging. Can you do a quick follow-up to add an entry to Added option to avoid detrending / DC removal when computing Welch or multitaper spectra (:gh:`11769` by `Nikolai Chapochnikov`_)feel free to edit the changelog entry if you want to mention the specific functions/methods/classes that are affected |
related to issue mne-tools#11767 and PR mne-tools#11769
|
ok, I added another PR, not sure if there was a simpler way? |
alas there is not really a simpler way. |
Co-authored-by: Daniel McCloy <dan@mccloy.info>
Reference issue
Fixes #11767
What does this implement/fix?
enhanced the functions
psd_array_welchandpsd_array_multitaperwith option "remove_dc", with True as default, since the previous default behavior was to remove the DC. Updated the relevant documentation and all the related functions.