-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Add standardized measurement error (SME) #12707
Conversation
is it MEAN or MEASUREMENT error? |
Ha! Of course it is measurement! Thanks! It is referenced correctly everywhere in the code though I think. |
Would it make more sense to add it as part of #12434 ? |
@larsoner not sure what you mean, I wouldn't want to wait until everything else in that PR is ready. If you meant moving the function into |
Maybe a single method to compute different kind of metrics for epochs, instead of one method per metric to avoid clutering the object API? Just a thought, no strong feeling. |
I'd prefer to move for now. If we start adding methods for every type of ERP measure to |
Done, the function is now available as Do you have any input/thoughts on the default data quality use case I mentioned? |
@cbrnr Would you consider adding a tiny example perhaps? just to get an idea of what the output would look like and how to interpret it? |
Yes, sure, good idea! |
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.
We usually make functions available in the parent package, i.e. mne.stats.compute_sme()
in this case. Do we even want that here?
And BTW, I'm totally confused by the doc error. I'm assuming it has to do with |
I haven't looked at the error, but it might be: |
ERP-related statistics: | ||
|
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.
ERP-related statistics: | |
ERP-related statistics | |
---------------------- | |
:py:mod:`mne.stats.erp`: | |
.. automodule:: mne.stats.erp | |
:no-members: | |
:no-inherited-members: | |
.. currentmodule:: mne.stats.erp |
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.
... or something like this would work. Locally you can iteratively do make html-noplot
(will take ~10 min the first time then should be quick on follow-up runs). I can push a commit if you want
mne/tests/test_epochs.py
Outdated
@@ -5263,3 +5264,20 @@ def test_empty_error(method, epochs_empty): | |||
pytest.importorskip("pandas") | |||
with pytest.raises(RuntimeError, match="is empty."): | |||
getattr(epochs_empty.copy(), method[0])(**method[1]) | |||
|
|||
|
|||
def test_epochs_sme(): |
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.
I think this should probably live in mne/stats/erp/tests/test_<something>.py
if you don't want to expose the "child" module, we might as well consider making it private |
We should expose it, that was the plan in #12434 that this PR is meant to follow |
but then why clutter the stats namespace and not leave it in stats.erp 🧐 |
I agree it shouldn't live in |
ok cool. so then we agree :) |
Before I implement the separate |
Looks good, marking for merge when green, thanks @cbrnr |
Sorry, I have not worked on #12434 in a while! My role at my lab changed quite a lot when we started a new study. I think I can have everything finished next week though! |
I also wanted to add that we didn't resolve the question how to compute the SME for regularly spaced time segments (e.g. every 100ms). I think this would be important, and even though I can tackle this in a new PR, I'd really appreciate any input on how to best implement it. |
You mean like if you have 1 sec of 1000 Hz data and you want the SME for each 100 ms interval, i.e., 10 values? I think some suitable |
@larsoner see my example at the bottom of the initial comment. I think this is too onerous for users. |
Maybe allow |
Yes, that would work. I guess my main issue is that I don't know how to create 100ms segments reliably though. Even epochs defined as -0.2 to 0.8 seconds relative to an event tend to have time ranges that cannot be divided by an integer number of 100ms segments. I guess it is probably not worth implementing a logic to do that automatically, so I'd rather leave it to the users. But is there a simpler way to create such segments other than in my example (which also doesn't even check bounds, especially in the last segment). |
Seems like we have some code that is close enough to doing this already that it shouldn't be too tricky to refactor it to be useful here too. E.g. for So I think it wouldn't be too hard to add this capability... but I'm unsure what the API should be:
|
Great, Regarding the API, I don't know either. I kind of want to suggest that simply calling |
hmm... to me |
* upstream/main: (252 commits) Disable the "Back to top" button in the documentation (mne-tools#12688) DOC: match_channel_orders works on Epochs and Evoked, too (mne-tools#12699) Scale points and labels in montage plot (mne-tools#12703) Add license header to mne.stats.erp (mne-tools#12712) Update license year to 2024 (mne-tools#12713) Add standardized measurement error (SME) (mne-tools#12707) ENH: Parallel example execution in doc build (mne-tools#12708) MAINT: Update PR template (mne-tools#12692) MAINT: Fix doc build (mne-tools#12706) [pre-commit.ci] pre-commit autoupdate (mne-tools#12702) Improve documentation of ylim argument through Evoked plotting function (mne-tools#12697) [pre-commit.ci] pre-commit autoupdate (mne-tools#12696) BUG: Fix bug with CSP rank="full" (mne-tools#12694) MRG: Add epochs metadata summary to HTML representation (mne-tools#12686) Correct `Epochs.apply_function` docstring (mne-tools#12691) FIX: Gracefully handle missing datetime in Eyelink File (mne-tools#12687) MAINT: Restore SciPy pre (mne-tools#12689) Enh single channel annotation (mne-tools#12669) [pre-commit.ci] pre-commit autoupdate (mne-tools#12682) Bump autofix-ci/action from 1.2 to 1.3 in the actions group (mne-tools#12681) ...
Fixes #10647. This PR adds a new function
compute_sme()
(inmne.stats.erp
), which (as the name suggests) computes the analytic standardized mean error (SME). Analytic in this context means that the target measure is mean amplitude within a defined time window. Other target measures like peak amplitude or peak latency will require a different approach using bootstrapping, which is not implemented in this PR.Here's how to use it:
The SME is a data quality measure for ERP analysis. I think the current interface quite nicely integrates into the MNE API, but there is one (important) use case that I'd like to discuss. By default (i.e., without any arguments), ERPLAB divides the entire epoch duration into 100-millisecond segments and computes the SME within each segment (see here for how this looks like). This is a quick way to get some data quality metrics very quickly. How could we achieve this in MNE? Of course, it is possible to do it manually like this:
This throws an error, because the last time window is out of bounds. Sure this can be fixed, but I can't think of a simple solution right now. Also, I'm not sure if it would be preferable to provide a built-in way to compute this. If so, what API would you suggest?