-
Notifications
You must be signed in to change notification settings - Fork 14
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] Add PSD feature via MNE #73
base: main
Are you sure you want to change the base?
Conversation
psd feature creation script
Just to clarify, how are these and the topographic PR different from what is included in ICLabel? I might've missed this discussion. |
Codecov Report
@@ Coverage Diff @@
## main #73 +/- ##
==========================================
+ Coverage 86.76% 86.84% +0.08%
==========================================
Files 15 16 +1
Lines 831 859 +28
Branches 101 105 +4
==========================================
+ Hits 721 746 +25
- Misses 82 83 +1
- Partials 28 30 +2
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
@adam2392 The ICLabel ones are a copy/paste of the MATLAB features.. which are not super clean and nice.
And that's not the only example of 'weird' coding choices/behaviors. I added comment in the mne-icalabel/mne_icalabel/iclabel/features.py Lines 375 to 378 in 26a2f1f
which corresponds to the variable which is never provided to the function https://github.com/sccn/ICLabel/blob/d0cfb0f8638cd4518ee2e66a3bff0bb32ff40969/ICL_feature_extractor.m#L77 Or this one: mne-icalabel/mne_icalabel/iclabel/features.py Lines 426 to 429 in 26a2f1f
which corresponds to https://github.com/sccn/ICLabel/blob/d0cfb0f8638cd4518ee2e66a3bff0bb32ff40969/eeg_autocorr_welch.m#L36-L44 Overall, I'm not super confident in the ICLabel features, so I asked Anand to prepare functions to extract features from Instance/ICA decomposition using MNE, starting with the topographic map and the PSD based on the |
FYI to fix the style easily and the sorting of imports:
|
Co-authored-by: Mathieu Scheltienne <mathieu.scheltienne@gmail.com>
def test_psd_feature(): | ||
"""Test scalp topography array generation""" | ||
psds_mean = get_psds(ica, raw) | ||
assert isinstance(psds_mean, np.ndarray) |
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.
Can we add a better test perhaps? Anything that can be inspired from MNE-Python test suite?
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.
Yes definitely.
@anandsaini024 Please look into additional tests as we discussed:
I'll try to double-check this PR this week. |
Check fmax value in psd.py. added a few tests in tests_psd.py
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.
@anandsaini024 Please check that the output you are getting from the function makes sense also when you vary the different arguments.
For instance, what happens when you provide a raw which does have "bad"
annotations and reject_by_annotation
was set to True? Or to False?
And so on.. please test all the arguments in different scenarios to make sure they each work. Those tests that you will do manually at the beginning can then be incorporated in test_psd_arguments
.
with pytest.raises(ValueError): | ||
get_psds(ica, inst, picks="eeg") | ||
with pytest.raises(ValueError, match="All picks must be < n_channels"): | ||
get_psds(ica, inst, picks=10) | ||
with pytest.raises(ValueError): | ||
get_psds(ica, inst, fmax=[210, 410]) | ||
with pytest.raises(ValueError): | ||
get_psds(ica, inst, fmax="string") | ||
with pytest.raises(ValueError): | ||
get_psds(ica, inst, normalization="string") |
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.
Please add the match
keyword and either part of the error message, the entire error message, or a regex pattern that matches the error. This will avoid catching ANY ValueError
.
with pytest.raises(Error, match="error I want to test against"):
function_that_raises_that_error()
Also, if you notice that an error message is not super clear, then you can start checking the user input at the beginning of the function. I've done it for fmin
and fmax
, but any error message that does not give clear guidelines to the user on how to correct it is not good enough.
Hi, I popped in to see whats new in mne-icalabel (great project!) and saw your discussion of |
Maybe, I didn't dig in too far, but it looked to me like the feature extraction code I translated was half-baked. Also, I'll finalize this PR at some point ;) |
PSD feature creation script.