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

implement channel specific epoch rejection #12219

Draft
wants to merge 48 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
d7ccfd4
function to reject epochs per channel
CarinaFo Nov 16, 2023
f94c7e4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 16, 2023
32a87f8
added masked data to channel specific rejection
CarinaFo Nov 16, 2023
8fccf71
Merge branch 'channel_specific_epoch_rejection' of github.com:CarinaF…
CarinaFo Nov 16, 2023
6e6c4a4
added masked data to function and to return
CarinaFo Nov 16, 2023
7da2ab5
Merge branch 'main' into channel_specific_epoch_rejection
CarinaFo Nov 16, 2023
300ce43
updated epochs.average with np.nanmean
CarinaFo Nov 16, 2023
afd2c8e
Merge branch 'channel_specific_epoch_rejection' of github.com:CarinaF…
CarinaFo Nov 16, 2023
f5804ab
Merge branch 'main' into channel_specific_epoch_rejection
CarinaFo Nov 17, 2023
880d157
Merge branch 'main' into channel_specific_epoch_rejection
CarinaFo Nov 17, 2023
afed69d
Update mne/epochs.py
CarinaFo Nov 17, 2023
194c83a
Merge branch 'main' into channel_specific_epoch_rejection
CarinaFo Nov 18, 2023
e054119
Merge branch 'main' into channel_specific_epoch_rejection
CarinaFo Dec 1, 2023
f742c1e
Merge branch 'main' into channel_specific_epoch_rejection
CarinaFo Dec 5, 2023
b74d4de
updated changelog for PR11776
CarinaFo Feb 7, 2024
cbd7083
updated github account name
CarinaFo Feb 7, 2024
8a3eea5
resolve merge conflict - forgot to pull before adding to changelog
CarinaFo Feb 7, 2024
eb6ac3d
added contribution to changelog
CarinaFo Feb 7, 2024
7d17f89
added second PR number to close both
CarinaFo Feb 7, 2024
c84bebb
Merge branch 'channel_specific_epoch_rejection' of github.com:CarinaF…
CarinaFo Feb 13, 2024
9e00065
Merge branch 'mne-tools:main' into channel_specific_epoch_rejection
CarinaFo Feb 13, 2024
0c20484
Merge branch 'mne-tools:main' into channel_specific_epoch_rejection
CarinaFo Feb 14, 2024
0d03885
deleted bad epochs function
CarinaFo Feb 14, 2024
e16cf74
added interpolate bad epochs method
CarinaFo Feb 14, 2024
b00f2b0
Merge branch 'channel_specific_epoch_rejection' of github.com:CarinaF…
CarinaFo Feb 14, 2024
0cb0ed5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 14, 2024
8a2f95b
fixed bug in interpolate epochs method
CarinaFo Feb 14, 2024
3e9435b
Merge branch 'channel_specific_epoch_rejection' of github.com:CarinaF…
CarinaFo Feb 14, 2024
341fd25
Merge branch 'main' into channel_specific_epoch_rejection
CarinaFo Feb 15, 2024
1e2252e
added interpolate bad epochs nan to interpolate_bads function
CarinaFo Feb 15, 2024
dfbba00
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 15, 2024
cc58b73
removed interpolate bad epochs from interpolate_bads due to MixinClass
CarinaFo Feb 15, 2024
167f38c
removed interpolate bad epochs
CarinaFo Feb 15, 2024
4e675cc
added set bad epochs to NaN method for epochs class
CarinaFo Feb 15, 2024
3b5d67b
Merge branch 'channel_specific_epoch_rejection' of github.com:CarinaF…
CarinaFo Feb 15, 2024
2868197
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 15, 2024
7fc2be1
removed return statement (operates in-place)
CarinaFo Feb 15, 2024
91302bb
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 15, 2024
b22cf11
deleted epoch based rejection from doc string
CarinaFo Feb 15, 2024
b011e6a
Merge branch 'main' into channel_specific_epoch_rejection
CarinaFo Feb 15, 2024
c794710
DW initial revisions
dominikwelke Feb 21, 2024
a27b135
Merge branch 'main' into channel_specific_epoch_rejection
CarinaFo Feb 21, 2024
f2ea3c4
Merge branch 'mne-tools:main' into channel_specific_epoch_rejection
CarinaFo Feb 24, 2024
7feea14
Merge branch 'channel_specific_epoch_rejection' of github.com:CarinaF…
CarinaFo Feb 26, 2024
1856286
Merge branch 'channel_specific_epoch_rejection' of github.com:CarinaF…
CarinaFo Feb 26, 2024
caac9f4
Merge pull request #3 from dominikwelke/carinafo/channel_specific_epo…
CarinaFo Feb 26, 2024
fa9567a
fixed docstring
CarinaFo Feb 28, 2024
4abf7fd
fixed dostring set_bad_epochs_to_NaN
CarinaFo Feb 28, 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
3 changes: 2 additions & 1 deletion mne/channels/channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,7 @@ def interpolate_bads(
exclude=(),
verbose=None,
):
"""Interpolate bad MEG and EEG channels.
"""Interpolate bad MEG, EEG and fNIRS channels.

Operates in place.

Expand Down Expand Up @@ -858,6 +858,7 @@ def interpolate_bads(
exclude : list | tuple
The channels to exclude from interpolation. If excluded a bad
channel will stay in bads.

%(verbose)s

Returns
Expand Down
31 changes: 31 additions & 0 deletions mne/epochs.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,37 @@ def __init__(
self._check_consistency()
self.set_annotations(annotations, on_missing="ignore")

def set_bad_epochs_to_NaN(self, bad_epochs_indices: list = None):
"""
Define bad epochs based on indices list and set to NaN.

Parameters
----------
self : instance of Epochs
bad_epochs_indices : list of arrays
List of arrays with indices of bad epochs per channel.

Notes
-----
This function operates in-place.
"""
if not self.preload:
raise ValueError("Data must be preloaded.")

if len(bad_epochs_indices) != self.get_data().shape[1]:
raise RuntimeError(
"The length of the list of bad epochs indices "
"must match the number of channels."
)
# extract the data from the epochs object: shape (n_epochs, n_channels, n_times)
data = self.get_data()
# loop over channels of specific type
for ch in range(data.shape[1]):
# use those indices to set the epochs per channel to NaN for all timepoints
data[bad_epochs_indices[ch], ch, :] = np.nan
# put back into epochs structure
self.data = data

def _check_consistency(self):
"""Check invariants of epochs object."""
if hasattr(self, "events"):
Expand Down
16 changes: 16 additions & 0 deletions mne/tests/test_epochs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5240,3 +5240,19 @@ def test_empty_error(method, epochs_empty):
pytest.importorskip("pandas")
with pytest.raises(RuntimeError, match="is empty."):
getattr(epochs_empty.copy(), method[0])(**method[1])


def test_set_bad_epochs_to_nan():
"""Test channel specific epoch rejection."""
# preload=False
raw, ev, _ = _get_data(preload=False)
ep = Epochs(raw, ev, tmin=0, tmax=0.1, baseline=(0, 0))
bads = [[]] * ep.info["nchan"]
bads[0] = [1]
with pytest.raises(ValueError, match="must be preloaded"):
ep.set_bad_epochs_to_NaN(bads)

# preload=True
ep.load_data()
ep.set_bad_epochs_to_NaN(bads)
_ = ep.average()
4 changes: 2 additions & 2 deletions mne/utils/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -919,12 +919,12 @@ def _check_combine(mode, valid=("mean", "median", "std"), axis=0):
if mode == "mean":

def fun(data):
return np.mean(data, axis=axis)
return np.nanmean(data, axis=axis)

elif mode == "std":

def fun(data):
return np.std(data, axis=axis)
return np.nanstd(data, axis=axis)

elif mode == "median" or mode == np.median:

Expand Down