-
Notifications
You must be signed in to change notification settings - Fork 216
Add DetectAndRemoveBadChannelsRecording
and DetectAndInterpolateBadChannelsRecording
classes
#3685
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
base: main
Are you sure you want to change the base?
Add DetectAndRemoveBadChannelsRecording
and DetectAndInterpolateBadChannelsRecording
classes
#3685
Conversation
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.
This looks good to me, few suggestions / questions. Really love this as it solves a big problem for me!
src/spikeinterface/preprocessing/tests/test_detect_bad_channels.py
Outdated
Show resolved
Hide resolved
# make sure they are removed | ||
assert len(set(new_rec._kwargs["bad_channel_ids"]).intersection(new_rec.channel_ids)) == 0 | ||
# and that the kwarg is propogatged to the kwargs of new_rec. | ||
assert new_rec._kwargs["noisy_channel_threshold"] == 0 |
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.
Is there anything to worry about channel ordering here? I guess not (and this is a question for ChannelSliceRecording
tests anyways. But as I have no understanding of how the ordering works I thought worth asking 😆
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.
The ordering of the channel ids?
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.
erm like order of the channels on the recording itself (I'm not sure how exactly this is represented 😅 ). But like the default order when you do plot_traces
without order_channel_by_depth
src/spikeinterface/preprocessing/tests/test_detect_bad_channels.py
Outdated
Show resolved
Hide resolved
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.
Let's figure out how to deal with precomputed kwargs before merging this
We need a strong refactoring to separate kwargs in 2 parts, the parametrsation and caching some heavy computation. |
+1 on discussing this. Sam mentioned it on the last meeting. Would be good to bring it back. |
Just a quick thought on this, there is the interpolate_bad_channels class, but that takes a list of channel ids. Given the function in this PR (and in general) you might expect it to detect-and-interpolate bad channels. I wonder if it makes sense to change that to |
Yes it makes total sense @JoeZiminski What about having two classes:
They are a bit verbose, but it binds the @chrishalcrow what do yo think? |
I think the verboseness makes it very clear that the function is dong two things, which is great! Thanks for the suggestion @JoeZiminski So you'd use |
Hello @JoeZiminski and @alejoe91 - I've added a |
Nice! That looks great @chrishalcrow cheers this will be super useful. I had a quick look at the code and looks good, I've got a slight preference to refactor the shared code:
into a new function on |
I've refactored (and moved) the gross |
RemoveBadChannelsRecording
class and remove_bad_channels
DetectAndRemoveBadChannelsRecording
and DetectAndInterpolateBadChannelsRecording
classes
Hello, I think this is ready @alejoe91 |
Hello, I now really think this is ready. @alejoe91 |
rec_only_good_channels = detect_and_remove_bad_channels(recording=rec) | ||
|
||
# detect and interpolate the bad channels | ||
rec_interpolated_channels = detect_and_interpolate_bad_channels(remove_channel_ids=bad_channel_ids) |
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.
rec_interpolated_channels = detect_and_interpolate_bad_channels(remove_channel_ids=bad_channel_ids) | |
rec_interpolated_channels = detect_and_interpolate_bad_channels(recording=rec) |
@chrishalcrow looks perfect! Just something of fin the docs and the merge conflict and ready to merge on my end |
Part of plan to
class
-ifty all preprocessing steps.This PR introduces the very verbose
detect_and_interpolate_bad_channels
function which will detect then interpolate bad channels, anddetect_and_remove_bad_channels
which will detect then remove bad channels.The idea is that these can be used in a standard pipeline => can be chained like any other preprocessing step.
Users can now use
and can chain with other steps:
The user can specify the bad channels, to skip the
detect
step. Idea is that this argument can be used when you load from dict. NOTE: When you load a saved recording from dict, it will not recompute the bad channels. This is a good feature.Most difficult thing was the kwargs.
RemoveBadChannelsRecording
shares much of the same signature asdetect_bad_channels
, and I didn't want to duplicate the default parameters, but did want to save them in theRemoveBadChannelsRecording._kwargs
. Ended up usinginspect
fromsignature
, as is also done in the motion module. Happy to discuss different implementations.