Open qian-chu opened 9 months ago
Hello! 👋 Thanks for opening your first issue here! ❤️ We will try to get back to you soon. 🚴
This has been asked before:
If you're willing to make a PR we'd be happy to have support for electrode-shaft referencing.
Can you have a look at those other issues (particularly the ideas about the API) and then tell us what approach best supports your use case as well as the other use cases mentioned there (if they're different)? Your dict
-based approach looks very flexible --- we could maybe even allow mne.set_eeg_reference(ref_channels=dict(...))
--- but I want to be sure we're considering all use cases before we commit to an API.
This has been asked before:
- Add laplace reference method to mne/io/reference.py #10163
- Re-reference methods about sEEG data #8481
If you're willing to make a PR we'd be happy to have support for electrode-shaft referencing.
Can you have a look at those other issues (particularly the ideas about the API) and then tell us what approach best supports your use case as well as the other use cases mentioned there (if they're different)? Your
dict
-based approach looks very flexible --- we could maybe even allowmne.set_eeg_reference(ref_channels=dict(...))
--- but I want to be sure we're considering all use cases before we commit to an API.
Thanks for mentioning the 2 relevant issues. My reflection is in iEEG there is no one-size-fits-all scheme. The optimal reference method varies depending on the research question (ERP? oscillations? epileptic activity? decoding?). I also echo with @larsoner in this comment that we cannot add support specifically for every scheme, especially since MNE doesn't support electrode grouping at the moment.
Thus in my opinion we can offer a flexible function that allows for local ref and people can start from there based on their needs, thus the dict
approach. What do you think? We can probably add tutorials about how to implement different reference schemes with the API using ECoG or sEEG datasets.
Regarding whether to create a new API or just expand set_eeg_reference()
, it has been suggested that we can add a new picks
argument to set_eeg_reference()
. This would be a nice addition but probably requires several iterations if people want to reref several shafts at the same time. I would personally prefer having a new API.
My colleague @AlexLepauvre is also interested in this topic. Alex, from your perspective (especially having seen different iEEG data from multiple centers) what might be most useful to the community?
I'm a bit in favor of expanding the existing API instead of creating a new one. mne.set_eeg_reference(ref_channels=dict(...))
seems like an elegant solution with ref_channels : str | list[str] | dict[str, str | list[str]]
.
thinking further about this, I do really like the ref_channels=dict(...)
approach: it's flexible and seems (to me at least) easy to understand, and probably not too hard to implement.
However, if we implement this, we probably can't prevent users from applying it to regular scalp EEG data. So one thing we should also think about though is our mechanisms for keeping track of whether EEG reference has been applied; how will we do that for this referencing approach? what will we do during apply_inverse
when it checks for (and doesn't find) the desired situation of "EEG average reference applied"? (we do have mechanisms for overriding that particular safeguard --- and maybe that's already enough --- but there may be some documentation / user education to be done around the possible downsides of this kind of referencing)
Hello everyone,
As @qian-chu mentioned, this is something for which we made a custom implementation in my project using data from various sites, using laplace referencing (ch2 = ch2 - mean(ch1, ch3)), so I would be happy to help out for the PR once we have figured out the details. In our case, we created a referencing dictionary for each single subject semi-automatically, which was then used to re-reference the channels.
In addition, we also took into account bad channels information. Any channel marked as bad was removed from the referencing scheme. If for a given channel, both references were marked as bad, the channel was also discarded, and if only one of the two was marked as bad, then bipolar referencing was applied.
One nice additional feature (especially for ECoG channels) would be electrodes relocalization. In case of bipolar referencing, it is best to relocate the channel as the midpoint between the two references. In the case of surface electrode, that might result in a point that is actually not on the cortical surface anymore. The relocated electrodes should be projected to the surface. This would be interesting to consider as well.
Would you think both features are relevant to implement?
For the dict stuff, I think it should be okay for inverse modeling so long as we set CUSTOM_REF_ON
so that modeling can't be done for now. Later when we want to support it we can keep track of the channels used as references properly in info
and account for it properly in the inverse. But that can and should be follow-up PRs.
For the relocalization, I don't think we should mess with info['chs']['loc']
at all. I think it can be useful maybe for visualization to think about moving where the activation gets plotted or so. So this would be an option for project_sensors_onto_brain
and should probably be a separate PR from the rereferencing-dict one as well.
To sum the discussion above, it seems that most are in favor of mne.set_eeg_reference(ref_channels=dict(...))
with certain things to keep in mind:
inst.info['custom_ref_applied'] = FIFF.FIFFV_MNE_CUSTOM_REF_ON
If this sounds good I'm going to create a PR draft.
To sum the discussion above, it seems that most are in favor of
mne.set_eeg_reference(ref_channels=dict(...))
yes I think that's right
If this sounds good I'm going to create a PR draft.
go for it!
Great :) @qian-chu, I will give it a go next week and we can see where we go from my initial commit.
Describe the new feature or enhancement
In some cases, especially intracranial EEG, re-referencing of channels should be local (e.g. within the same shaft/grid/strip) rather than global (i.e., ref all channels to one or an average of channels). This thus requires some flexible re-ref schemes, but the existing functions
set_eeg_reference
andset_bipolar_reference
are not super convenient for such purposes. On the basis of the proposed function, multiple re-ref schemes can be added (for example see https://doi.org/10.1016/j.neuroimage.2018.08.020)Describe your proposed implementation
A new preprocessing function
mne.set_custom_reference(inst, ref_dict, copy=True, on_bad='warn', verbose=None)
Whereref_dict
contains a dictionary with keys being the source channel names and values being ref channel names. For example:ref_dict = {'A1': 'A1', 'A2': 'A1', 'A3': 'A1', 'A4': 'A1'}
performs monopolar reference;ref_dict = {'A1': 'A2', 'A2': ['A1', 'A3'], 'A3': ['A2', 'A4'], 'A4': 'A3'}
performs Laplacian reference. I'm happy to open a pull request draft if someone can confirm the value of the proposed function.Describe possible alternatives
Alternatively we can expand
mne.set_eeg_reference
instead of writing a new function.Additional context
No response