Skip to content
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

Add support for dictionary-type ref_channels in set_eeg_reference() #12366

Draft
wants to merge 30 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1bce965
init the PR draft
qian-chu Jan 16, 2024
f42d5fb
Merge branch 'main' into dict_ref
qian-chu Jan 16, 2024
278fdf3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 16, 2024
f3cff5a
Create 12366.newfeature.rst
qian-chu Jan 16, 2024
b7b5c0c
Update 12366.newfeature.rst
qian-chu Jan 17, 2024
7ece510
Merge branch 'mne-tools:main' into dict_ref
qian-chu May 2, 2024
8d4516d
Add custom reference based on dict
May 3, 2024
42f45b8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 3, 2024
95a1434
BF: use isintance to check if dict
May 3, 2024
c921d69
BF: remove extra copy of data
May 3, 2024
b0c91d2
Add custom reference
May 3, 2024
78a5c7e
change doc (add Alex)
May 3, 2024
ca6908c
Add warning if bad channels in re-referencing scheme
May 3, 2024
6ac7bed
Merge branch 'dict_ref' of https://github.com/qian-chu/mne-python int…
May 3, 2024
b1165b9
add _check_before_dict_reference and enrich set_eeg_reference_see_als…
qian-chu May 3, 2024
ed56c97
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 3, 2024
d27ce12
Update reference.py
qian-chu May 31, 2024
073ca9d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 31, 2024
8d744ca
Update test_reference.py
qian-chu May 31, 2024
9e9507d
Update reference.py
qian-chu Jun 3, 2024
24d16a5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 3, 2024
2a6db40
Update test_reference.py
qian-chu Jun 3, 2024
6699de0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 3, 2024
8a5232a
formatting
qian-chu Jun 3, 2024
73ad30d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 3, 2024
3474370
dict does not accept repeated keys, no need to test
qian-chu Jun 5, 2024
cd213ee
add test for warnings and raises
qian-chu Jun 5, 2024
6c79a60
Update test_reference.py
qian-chu Jun 5, 2024
e36ddd2
Update docs.py
qian-chu Jun 5, 2024
41893f3
Merge branch 'mne-tools:main' into dict_ref
qian-chu Jun 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/changes/devel/12366.newfeature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for `dict` type argument ``ref_channels`` to :func:`mne._fiff.reference.set_eeg_reference`, by `Qian Chu`_.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain what that allows users to do?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I don't think we should document a private function here. Can you add references to the public API instead? Thank you

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry that I wasn't too familiar with the private/public API and simply copied the path to the function. Does :func:mne.set_eeg_reference work?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is the right function! Regarding the changelog entry, can you maybe also include an example what you mean by "flexible re-referencing"? Users (not developers) should learn what nice new feature you added and how they can use it!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Users will rarely call this function directly though, I suppose. They will usually call the methods of Raw, Epochs, ..., objects, so I believe these should be referenced or briefly mentioned

30 changes: 29 additions & 1 deletion mne/_fiff/reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,31 @@ def _apply_reference(inst, ref_from, ref_to=None, forward=None, ch_type="auto"):
return inst, ref_data


def _apply_dict_reference(inst, ref_dict, ch_type="auto"):
"""Apply a dict-based custom EEG referencing scheme."""
# ref_to = _check_before_reference(inst, ref_from, ref_to, ch_type)

# # Compute reference
# if len(ref_from) > 0:
# # this is guaranteed below, but we should avoid the crazy pick_channels
# # behavior that [] gives all. Also use ordered=True just to make sure
# # that all supplied channels actually exist.
# assert len(ref_to) > 0
# ref_names = ref_from
# ref_from = pick_channels(inst.ch_names, ref_from, ordered=True)
# ref_to = pick_channels(inst.ch_names, ref_to, ordered=True)

# data = inst._data
# ref_data = data[..., ref_from, :].mean(-2, keepdims=True)
# data[..., ref_to, :] -= ref_data
# ref_data = ref_data[..., 0, :]

# else:
# ref_data = None

# return inst, ref_data


@fill_doc
def add_reference_channels(inst, ref_channels, copy=True):
"""Add reference channels to data that consists of all zeros.
Expand Down Expand Up @@ -430,7 +455,10 @@ def set_eeg_reference(
"reference."
)

return _apply_reference(inst, ref_channels, ch_sel, forward, ch_type=ch_type)
if ref_channels is dict:
qian-chu marked this conversation as resolved.
Show resolved Hide resolved
return _apply_dict_reference(inst, ref_channels, ch_type=ch_type)
else:
return _apply_reference(inst, ref_channels, ch_sel, forward, ch_type=ch_type)


def _get_ch_type(inst, ch_type):
Expand Down
11 changes: 9 additions & 2 deletions mne/utils/docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3213,13 +3213,20 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75):
"""

docdict["ref_channels_set_eeg_reference"] = """
ref_channels : list of str | str
ref_channels : list of str | str | dict
Can be:

- The name(s) of the channel(s) used to construct the reference.
- The name(s) of the channel(s) used to construct the reference for
every channel of ``ch_type``.
- ``'average'`` to apply an average reference (default)
- ``'REST'`` to use the Reference Electrode Standardization Technique
infinity reference :footcite:`Yao2001`.
- A dictionary mapping names of channels to be referenced to (a list of)
names of channels to use as reference. This is the most flexible
re-referencing approaching. For example, {'A1': 'A3'} would replace the
data in channel 'A1' with the difference between 'A1' and 'A3'. To take
the average of multiple channels as reference, supply a list of channel
names as the dictionary value, e.g. {'A1': ['A2', 'A3']}.
- An empty list, in which case MNE will not attempt any re-referencing of
the data
"""
Expand Down