Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
54dd4a1
Raising meaningful warnings/errors for interpolate_bads, when supplie…
1himan Dec 1, 2025
be254c4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 1, 2025
7f5d63b
Improved logic and error message
1himan Dec 3, 2025
0fa2ba9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 3, 2025
272c38a
Removed my custome testing file
1himan Dec 3, 2025
04d2f7e
minor changes
1himan Dec 3, 2025
db1b993
Fixing CI tests
1himan Dec 3, 2025
8ea167e
Merge branch 'main' into interpolate_bads_bugfix
1himan Dec 4, 2025
8c0a5a9
Merge branch 'main' into interpolate_bads_bugfix
1himan Dec 13, 2025
feb4415
Merge branch 'main' into interpolate_bads_bugfix
1himan Dec 16, 2025
63f8dd5
Validation warning while processing docstring for .interpolate_bads()…
1himan Dec 21, 2025
c566b90
Merge branch 'interpolate_bads_bugfix' of https://github.com/1himan/m…
1himan Dec 21, 2025
c1bcbc5
Indentation fix
1himan Dec 21, 2025
fec6daf
CLI check fix
1himan Dec 21, 2025
fdff96d
Merge branch 'mne-tools:main' into interpolate_bads_bugfix
1himan Dec 24, 2025
d84c11f
this fixes the cli tests
1himan Jan 2, 2026
54c82e5
Merge branch 'main' into interpolate_bads_bugfix
1himan Jan 3, 2026
78ad836
Made suggested changes
1himan Jan 7, 2026
9358051
Improved tests
1himan Jan 7, 2026
2d19ecb
Fixed linting errors
1himan Jan 7, 2026
68f7039
Merge branch 'main' into interpolate_bads_bugfix
1himan Jan 7, 2026
4915ff0
Rmoved redundancy
1himan Jan 8, 2026
e4b7bb9
Merge branch 'main' into interpolate_bads_bugfix
1himan Jan 10, 2026
68dbb28
Added dev entries, and fixed test logic
1himan Jan 13, 2026
fecd9c9
Merge branch 'main' into interpolate_bads_bugfix
1himan Jan 13, 2026
a3f70e3
Fixing ci tests
1himan Jan 13, 2026
fc9621f
Merge branch 'main' into interpolate_bads_bugfix
1himan Jan 17, 2026
4238184
Merge branch 'main' into interpolate_bads_bugfix
1himan Jan 20, 2026
3828f82
Polish
1himan Jan 20, 2026
1f335df
Merge branch 'main' into interpolate_bads_bugfix
1himan Jan 27, 2026
c1fe227
Merge branch 'main' into interpolate_bads_bugfix
1himan Feb 12, 2026
bce4d64
Merge branch 'main' into interpolate_bads_bugfix
1himan Feb 20, 2026
c801334
Change on_bad_position behavior from 'raise' to 'warn'
1himan Feb 23, 2026
5907250
More meaningful error and warning message to the user
1himan Feb 23, 2026
590861c
fixed ruff error
1himan Feb 23, 2026
a2ab8c9
Adding final suggestions
1himan Feb 25, 2026
7b1e697
Merge branch 'main' into interpolate_bads_bugfix
1himan Feb 25, 2026
a026239
Merge branch 'main' into interpolate_bads_bugfix
1himan Mar 5, 2026
4c551d9
Merge branch 'main' into interpolate_bads_bugfix
1himan Mar 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/changes/dev/13518.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make :meth:`~mne.io.Raw.interpolate_bads` method flexible (ignore, warn, raise) about how to handle interpolation of channels with invalid positions, by `Himanshu Mahor`_.
31 changes: 31 additions & 0 deletions mne/channels/channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,7 @@ def interpolate_bads(
origin="auto",
method=None,
exclude=(),
on_bad_position="warn",
verbose=None,
):
"""Interpolate bad MEG and EEG channels.
Expand Down Expand Up @@ -874,6 +875,10 @@ def interpolate_bads(
exclude : list | tuple
The channels to exclude from interpolation. If excluded a bad
channel will stay in bads.
on_bad_position : "raise" | "warn" | "ignore"
What to do when one or more sensor positions are invalid (zero or NaN).
If ``"warn"`` or ``"ignore"``, channels with invalid positions will be
filled with :data:`~numpy.nan`.
%(verbose)s

Returns
Expand All @@ -898,6 +903,32 @@ def interpolate_bads(

_check_preload(self, "interpolation")
_validate_type(method, (dict, str, None), "method")

# check for channels with invalid position(s)
invalid_chs = []
for ch in self.info["bads"]:
loc = self.info["chs"][self.ch_names.index(ch)]["loc"][:3]
if np.allclose(loc, 0.0, rtol=0, atol=1e-16) or np.isnan(loc).any():
invalid_chs.append(ch)

if invalid_chs:
if on_bad_position == "raise":
msg = (
f"Channel(s) {invalid_chs} have invalid sensor position(s). "
"Interpolation cannot proceed correctly. If you want to "
"continue despite missing positions, set "
"on_bad_position='warn' or 'ignore', which outputs all "
"NaN values (np.nan) for the interpolated channel(s)."
)
else:
msg = (
f"Channel(s) {invalid_chs} have invalid sensor position(s) "
"and cannot be interpolated. The values of these channels "
"will be all NaN. To ignore this warning, pass "
"on_bad_position='ignore'."
)
_on_missing(on_bad_position, msg)

method = _handle_default("interpolation_method", method)
ch_types = self.get_channel_types(unique=True)
# figure out if we have "mag" for "meg", "hbo" for "fnirs", ... to filter the
Expand Down
21 changes: 21 additions & 0 deletions mne/channels/tests/test_interpolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,27 @@ def test_nan_interpolation(raw):
raw.interpolate_bads(method="nan", reset_bads=False)
assert raw.info["bads"] == ch_to_interp

store = raw.info["chs"][1]["loc"]
# for on_bad_position="raise"
raw.info["bads"] = ch_to_interp
raw.info["chs"][1]["loc"] = np.full(12, np.nan)
with pytest.raises(ValueError, match="have invalid sensor position"):
# DOES NOT interpolates at all. So raw.info["bads"] remains as is
raw.interpolate_bads(on_bad_position="raise")

# for on_bad_position="warn"
with pytest.warns(RuntimeWarning, match="have invalid sensor position"):
# this DOES the interpolation BUT with a warning
# so raw.info["bad"] will be empty again,
# and interpolated channel with be all np.nan
raw.interpolate_bads(on_bad_position="warn")

# for on_bad_position="ignore"
raw.info["bads"] = ch_to_interp
assert raw.interpolate_bads(on_bad_position="ignore")
assert np.isnan(bad_chs).all, "Interpolated channel should be all NaN"
raw.info["chs"][1]["loc"] = store

# make sure other channels are untouched
raw.drop_channels(ch_to_interp)
good_chs = raw.get_data()
Expand Down
Loading