-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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: muscle artifact detection #7407
Conversation
Codecov Report
@@ Coverage Diff @@
## master #7407 +/- ##
=======================================
Coverage 90.10% 90.10%
=======================================
Files 452 452
Lines 83102 83102
Branches 13165 13165
=======================================
Hits 74882 74882
Misses 5387 5387
Partials 2833 2833 |
@larsoner I am getting again a test_nesting error. Not sure if it's my fault... |
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 can test with eeg data later (today or tomorrow), a few steps down the road it would be nice to have a simple detection GUI similar to what is available in fieldtrip. |
@agramfort thanks for your comments. I run the example on the Brainstorm just because the Latter, in between my thesis writing rests I will address your comments. |
The only difference with EEG will be the threshold, as it has fewer
channels.
can you find a parametrization that is immune to the number of channels?
… |
In fieldtrip IIRC they divide by |
Actually, in fieldtrip they just take the sum of all the channels zscores, thus the threshold can be very high, typically 10. Here the mean is taken. Do you suggest to divide the sum by the sqrt(n_channels)? |
I don't have experience with this but trying on different datasets
will tell you how much
your parameters are data dependent
|
Co-Authored-By: Alexandre Gramfort <[email protected]>
…into detect_muscle
I will work on testing sum(zcores)/sqrt(n_chans) tomorrow. I wanted to use eegbci data for the example but the sampling rate is 160Hz. I will look for other eeg datasets. |
raw_copy.pick_types(ref_meg=False) # Remove ref chans just in case | ||
# Only one type of channel, otherwise z-score will be biased | ||
assert(len(set(raw_copy.get_channel_types())) == 1), 'Different channel ' \ | ||
'types, pick one type' |
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.
throw an explicit ValueError
error instead of AssertionError
I think it is better to be more flexible in the filtering step (for example allow the user to specify what frequency range should be considered) than to ignore datasets with such sampling rate. I am also wondering whether ignoring signal segments with bad annotations in the z score computation would be helpful. (imagine there is some known period with huge artifacts that would bias the z scores) If so, these segments could be nan'ed out (or removed) prior to zscoring. |
The way I would do it is make it so that this function ignores any segments that are already marked |
I can't find how to use |
See https://mne.tools/dev/generated/mne.io.Raw.html#mne.io.Raw.get_data and reject_by_annotations parameter
|
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.
In addition to the specific comments below, generally speaking I'd encourage you to interleave the code and explanation a little more, instead of having just a few big code blocks. One example is the note about notch-filtering before running muscle artifact detection; it would make sense to have this note come after all the data is loaded, right before a small code block where you run the notch filtering. Similarly, the text about only using one channel type could be right next to the pick_types
line.
Following @mmagnuski conversation on the code suggestions debating over if it is a good idea to slow pass filtering of the z-scores to smooth peaks. I looked at two datasets, the sample elekta data, and the brainstorm auditory data. I have to say that both recordings are very clean, probably with well trained subjects, and in my case, with children or patients data it does not look that clean. So the low-pass smoothing advantage is not that clear. Below are the z-scores for brainstorm auditory subject one: LMKWYT |
I see. I think that at this point, I would prefer to leave it for another PR. This function will go into the 0.21 version and there will be time if it is needed. |
+1 for delaying removing The complication is |
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.
only a few minor docstring nitpicks left at this point. +1 for merge.
You were incorrect.
…-------- Original Message --------
On Mar 26, 2020, 12:34, Adonay Nunes wrote:
@AdoNunes commented on this pull request.
---------------------------------------------------------------
In [mne/preprocessing/artifact_detection.py](#7407 (comment)):
> + `filter_freq` whose envelope magnitude exceeds the specified z-score
+ threshold (when summed across channels and divided by `sqrt(n_channels)`).
***@***.***(https://github.com/drammock) always double backticks? I thought function parameters have one and its values two?
—
You are receiving this because you were mentioned.
Reply to this email directly, [view it on GitHub](#7407 (comment)), or [unsubscribe](https://github.com/notifications/unsubscribe-auth/AAN2AU27O2APLS2BCDAWUQDRJOU45ANCNFSM4LD7QOPA).
|
+10 for merge |
@larsoner @agramfort I thought that the PR was already merged after 2 approvals? |
Please exhibit some patience. Version 0.20 just shipped (which is a lot of work); everyone is dealing with a global pandemic, and it is the weekend. I understand that you have invested a lot of time and energy in this PR, and maybe are eager to be done with it. Don't get pushy. Some PRs are merged after one approval, some after two, sometimes more. It depends on the content of the PR and the expertise of the person(s) reviewing it. |
In case you are waiting for me to do something, plz let me know it. I just marked the conversations as resolved in case you were waiting for it. |
Hi @AdoNunes, it would be good to just add a test for the ValueError part you added, you can use: with pytest.raises(ValueError, match="No M/EEG channel types found"):
# call annotate_muscle_zscore with data without meg or eeg and all would be good. :) |
@mmagnuski what a surprise 😆 |
It shouldn't be a surprise. We try to test every single warning and error that we raise, to make sure that they are actually happening in the conditions that we want them to happen.
As @mmagnuski said, put in a call to your function, passing in data that doesn't have meg or eeg channels. |
@drammock Sorry I don't get it. Now I am more surprised -well confused-, I thought that I had to put it in the |
Quoting from the contributor guide:
So yes, the test should go in |
@mmagnuski done, the new test went through all the checks. All good now? 😄 |
Thanks @AdoNunes ! |
👍 |
* upstream/master: (1522 commits) FIX: Show bug MRG, FIX: Datetime call in gdf 2.x age calculation (mne-tools#7581) DOC: Simplify Darwin installation (mne-tools#7584) MRG, ENH: Allow picking without preload (mne-tools#7507) DOC: Document anonymization better (mne-tools#7587) Rework _Brain show (mne-tools#7580) DOC: Fixes in tutorial (mne-tools#7579) ENH: muscle artifact detection (mne-tools#7407) MRG: Remove toolbars in PyVista plotter (mne-tools#7572) WIP: Deregister plotter from the figure list in close() (mne-tools#7573) MRG: Fix mouse wheel event in _TimeViewer (mne-tools#7563) FIX: Fix toggle all (mne-tools#7567) MRG, FIX: parallel n_jobs check (mne-tools#7566) Rename artifact detection to movement detection (mne-tools#7569) ENH: Update spelling check [ci skip] (mne-tools#7565) MRG, ENH: Dont require preload for raw resample (mne-tools#7508) MRG: Add interpolation for NIRS signals (mne-tools#7428) WIP: Add temporal derivative distribution repair algorithm (mne-tools#7556) DOC: fix link in docstr [skip ci] (mne-tools#7562) ENH: Custom figure title when plotting Dipole locations (mne-tools#7558) ...
* upstream/master: (1522 commits) FIX: Show bug MRG, FIX: Datetime call in gdf 2.x age calculation (mne-tools#7581) DOC: Simplify Darwin installation (mne-tools#7584) MRG, ENH: Allow picking without preload (mne-tools#7507) DOC: Document anonymization better (mne-tools#7587) Rework _Brain show (mne-tools#7580) DOC: Fixes in tutorial (mne-tools#7579) ENH: muscle artifact detection (mne-tools#7407) MRG: Remove toolbars in PyVista plotter (mne-tools#7572) WIP: Deregister plotter from the figure list in close() (mne-tools#7573) MRG: Fix mouse wheel event in _TimeViewer (mne-tools#7563) FIX: Fix toggle all (mne-tools#7567) MRG, FIX: parallel n_jobs check (mne-tools#7566) Rename artifact detection to movement detection (mne-tools#7569) ENH: Update spelling check [ci skip] (mne-tools#7565) MRG, ENH: Dont require preload for raw resample (mne-tools#7508) MRG: Add interpolation for NIRS signals (mne-tools#7428) WIP: Add temporal derivative distribution repair algorithm (mne-tools#7556) DOC: fix link in docstr [skip ci] (mne-tools#7562) ENH: Custom figure title when plotting Dipole locations (mne-tools#7558) ...
closes #7359
I have added a new function
detect_muscle
in artifact_detection.py. I also included the example and test.