-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Raising meaningful warnings/errors for interpolate_bads, when supplie… #13518
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
base: main
Are you sure you want to change the base?
Conversation
…d loc field with missing or invalid data
for more information, see https://pre-commit.ci
|
Should we update the user about what's going on, on a deeper level or is it going to be too verbose. Because if we look, that why the bug exists, its primarily because of how create_info creates the info dict structure - its all NaN for the loc field. Of course we're not expecting the user to provide the exact positions of the sensor but we should also give the user a heads up about this. Also in the add_channels, something like: And something similar for the interpolate_bads. If that's the case then we should create a separate utility method for this, something like: def _is_invalid_loc(loc):
return np.allclose(loc, 0.0, atol=1e-16) or np.isnan(loc).any()And use that, wherever its required to warn the user about this. |
|
@1himan I haven't followed this ticket super closely but if I understand correctly it seems like you are talking about 2 or 3 different ideas here: 1: "Should we update the user about what's going on on a deeper level [during the
|
for more information, see https://pre-commit.ci
…, Parameters {on_no_position} not found - fix
…ne-python into interpolate_bads_bugfix
|
Ready to run rest of the tests? |
drammock
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution!
there should be a test (or modification of an existing test) to ensure that this works as intended. For example, a pytest.raises() context around a call when the value is "raise", a pytest.warns() context around a call when the value is "warn", and no context (or a null context) when called with the value "ignore". Should also assert that the invalid chs end up as all NaN (though since that's current behavior I'm guessing that's already tested, but please confirm)
|
I've made the suggested changes @drammock. and yes, the assertion for bad channel interpolated to all nan values is already implemented. |
| raw.info["chs"][1]["loc"] = np.full(12, np.nan) | ||
| # DOES NOT interpolates at all. So raw.info["bads"] remains as is | ||
| raw.interpolate_bads(on_bad_position="raise") | ||
| assert np.isnan(raw.info["chs"][1]["loc"]).any() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking more closely this time... I'm not sure what the point of this assert statement is. We don't expect interpolate_bads to ever change the loc of a channel, so what is the point of asserting this here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for correcting, what I really wanted to do here is - to assert that the interpolated channel is all nan, which is the current behaviour and I got too fixated on the sensor position. So instead of that, we would want something like this:
assert np.isnan(bad_chs).all, "Interpolated channel should be all nan"| 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)." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
two thoughts about this:
- if the user passed "warn" they're going to see this message as a warning, which means that the interpolation will proceed, even though the text implies that it will not. That's confusing.
- in the case where
method="nan"it's actually quite plausible to want to apply this to channels with invalid locations. So I wonder if we want to issue this warning at all ifmethod="nan". My hunch is that we probably still do want to warn, but would like other opinions (@larsoner ?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original issue which this PR is meant to fix, was more of a UX improvement request, that we should at least raise a warning when interpolating a channel with bad sensor positions instead of silently interpolating the channel to np.nan.
"ignore"- interpolate anyways"warn"- interpolate anyways as well, but leaves a warning message in terminal"raise"- no interpolation, stops the code execution and gives a runtime warning
To make it less confusing, I think, the default value should be on_bad_position="raise" instead of "warn".
Because, for most of the users who happened to have the data with invalid sensor positions, the workflow would look like:
- Trying to interpolate bad channels via
.interpolate_bads() - Bumps into this runtime error - because default is
on_bad_position="raise" - Now they can either choose to
"ignore"it, or some users(who know what they're doing) might wanna use"warn"just as a reminder/note. Apart from that I don't see"warn"to be of any use, or any case where the user want to deliberately set it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also in the end it just depends on how we want things to be, "raise" could be a default for "better UX" since its good to tell users, "hey, there's something wrong with your code, so we're stopping the code execution immediately, see below for possible fixes", and then show a meaningful error message in the terminal and tell them to either use "warn" or "ignore", to continue.
But if we don't wanna:
- throw a WHOLE runtime error to the user and,
- stop the code execution immediately
for "better UX", we might wanna use "warn" as default.
Its just a choice of what we consider "better UX" to be?
Raising meaningful warnings/errors for interpolate_bads, when supplied loc field with missing or invalid data.
What does this implement/fix?
Fixes #13363
Additional information
TODO:
Add checks in add_channels() as well.
Refactor code according to mne's philosophy.