mne-tools / mne-python

MNE: Magnetoencephalography (MEG) and Electroencephalography (EEG) in Python
https://mne.tools
BSD 3-Clause "New" or "Revised" License
2.63k stars 1.31k forks source link

ENH: Add EEG support to find_bad_channels_maxwell #12384

Open larsoner opened 6 months ago

larsoner commented 6 months ago

find_bad_channels_maxwell uses the SSS basis to find MEG channels that are bad. In principle the same thing should be doable for EEG using the scalar spherical harmonic basis. Code-wise I think the changes would be fairly simple, and it's a pretty straightforward extension of the existing bad-channel method conceptually. So I'm thinking it's worth implementing it and testing it on some data I have locally and in MNE-BIDS-Pipeline to see if it works reasonably well. I could compare to autoreject as well as LOF. Thoughts?

I'm thinking this could be implemented via a find_bad_channels_maxwell(..., *, ch_type="meg" (default) | "eeg") for example to allow finding bad channels for MEG or EEG channels. An alternative would be to add a picks argument but really you fit/process all channels of a given type jointly, so I tend toward liking ch_type instead. And I think it's okay to have to call it twice if you have both channel types, though in theory we could allow a ch_type="all" or picks=("meg", "eeg") or whatever to mean "loop over MEG and EEG channels), which would be okay, too.

@hoechenberger do you think this would then also be useful for MNE-BIDS(-Pipeline)?

hoechenberger commented 6 months ago

Hello, I had not idea this approach could work for EEG, too. If you believe it makes sense, we could try it out and compare the results to pyprep and autoreject, like you suggested (even though autoreject works on epoched data only; so I suppose pyprep would actually be the "better" benchmark)

If the results are promising, this should definitely go into MNE-BIDS-Pipeline as well.

cc @sappelhoff @cbrnr

sappelhoff commented 6 months ago

I would also suggest comparing against pyprep's: pyprep.NoisyChannels(raw).find_all_bads()

hoechenberger commented 6 months ago

I have to say that find_all_Bads marks way too many channels as bad in my datasets. I usually only use a subset of the functions in pyprep (I can share which those are specifically in case you're interested)

sappelhoff commented 6 months ago

I have to say that find_all_Bads marks way too many channels as bad in my datasets. I usually only use a subset of the functions in pyprep (I can share which those are specifically in case you're interested)

you can use pyprep.NoisyChannels.get_bads with as_dict=True to then get info on why channels were marked bad :-)

but yeah, fine to also just run a subset of methods to detect bad channels.

hoechenberger commented 6 months ago

Yes I believe it's usually the SNR criterium that fails for me.

agramfort commented 6 months ago

It’s published works so I am supportive assuming it’s properly validated against what we already have or what pyprep has.