-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
MRG: Protect against bad projections #2838
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
Conversation
|
what's with the |
|
for the beamformer test can't you just apply the projections before subselection? and raise a warning if proj have not been applied? I don't like this new stacklevel parameter either ;) |
|
It's in private functions so don't worry about it. It makes it so toy
actually see where you as a user made a call that created a problem. We
should have probably been doing it with all our warnings. If that's not
clear I'll give an example.
I don't think applying first (e.g. to raw) will fully fix it. I think it
had to do with the covariance that is loaded also having projectors that
get partially applied. But I'll try again.
Do you tentatively agree warnings are the way to go?
|
|
FYI the i.e., not informative about user's line caused the warning, to:
|
|
@agramfort if I do I think it's an interaction with the covariance code, where even if you apply proj, after doing a selection with epochs, you need to subselect the channels from the covariance that actually need to be used in beamforming. During that process, projectors get applied with a limited subset of channels. I suspect it's a bug -- it seems like we'd want to apply the projectors to the covariance matrix and then subselect -- but it looks like someone went through a lot of effort to let it work the other way (subselect, then apply re-normalized partial projection vectors). It might be related to needing to know the degrees of freedom. If you apply |
|
I suspect a bug too... I may have the time to look next time.
leave me a broken PR I can take over if you want
|
|
Once the stacklevel stuff is merged, this will be rebased and more or less ready to go. You can find the bugs by looking at where I had to add warning-catchers. |
e50a95d to
50852af
Compare
|
@agramfort now you can see where all the |
mne/beamformer/_lcmv.py
Outdated
|
|
||
| # Handle whitening + data covariance | ||
| whitener, _ = compute_whitener(noise_cov, info, picks, rank=rank) | ||
| whitener = compute_whitener(noise_cov, info, picks, rank=rank)[0] |
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.
I prefer the older way. I find it less error prone as it makes the code break when the number of output args changes.
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.
reverted
50852af to
63cd409
Compare
|
@agramfort feel free to push directly to this branch if you want |
mne/io/proj.py
Outdated
| orig_n = p['data']['data'].shape[1] | ||
| if len(vecsel) < 0.9 * orig_n: | ||
| warn('Projection vector "%s" magnitude %0.2f, ' | ||
| 'applying projector with %s/%s of the original ' |
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.
I don't get this sentence. Words are missing or something.
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.
"vector %s has magnitude %f (should be unity)" make more sense?
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.
yes it does
|
about the "lot of efforts" are you talking about the _prepare_beamformer_input function? |
|
Not quite. The problem is that I'm not sure how you properly deal with using projections, but then later only subselecting a set of channels like is done in that example. Fortunately we don't do it in many places in the codebase (maybe only in tests to primarily save time?) but I suspect what we're doing isn't quite right. If you eliminate, say, half the channels than your previously-orthogonal vectors very will might not be orthogonal anymore. So things like rank estimates can get screwed up. But I suppose in that case we'd be conservative by saying that 2 projectors always decreases rank by 2, even with channel removal. |
|
Also see from above:
|
63cd409 to
408e82e
Compare
|
Changed warning text and rebased |
|
does this help: ? |
|
The way to check would be to remove all the |
mne/beamformer/tests/test_lcmv.py
Outdated
| picks=picks, baseline=(None, 0), | ||
| preload=epochs_preload, | ||
| reject=dict(grad=4000e-13, mag=4e-12, eog=150e-6)) | ||
| with warnings.catch_warnings(record=True): |
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.
this one still needs to stay
|
I stopped after the first three checks, but it looks like no, it didn't help |
|
I think it's because a lot of the warnings come from the guts of the covariance code, not the beamforming code |
|
ok I'll try to look later... I have to stop.
|
|
Cool, thanks for looking. Feel free to push to my branch if you find a solution, I probably won't work on it in the meantime. |
|
@agramfort comments addressed, see what you think |
| vals = np.abs(vals) # avoid negative values (numerical errors) | ||
| # avoid negative (numerical errors) or zero (semi-definite matrix) values | ||
| tol = vals.max() * vals.size * np.finfo(np.float64).eps | ||
| vals = np.where(vals > tol, vals, tol) |
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.
We were getting some values that actually equalled zero, which threw a warning. This prevents that from happening hopefully by setting a hopefully reasonable minimum, but please double-check my logic @agramfort
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.
LGTM
|
ping @agramfort |
mne/io/proj.py
Outdated
| '%s/%s of the original channels available may ' | ||
| 'be dangerous, consider recomputing and adding ' | ||
| 'projection vectors for channels that are ' | ||
| 'eventually used' |
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.
please update the warning to recommend to use normalize_proj method
|
@agramfort warning updated. Anything else? |
|
@Eric89GXL I pushed a commit here. I think we're almost there... |
|
@agramfort anything left to do that you can see? |
|
I think we're good. Hopefully we did not break anything... please rebase and add a clear message on what's new. thanks heaps @Eric89GXL ! |
|
Done and merged by rebase, thanks @agramfort |
|
thanks !
|
One possible solution to the projection issue. @agramfort can you take a look and see if you think this is a good approach? You can see that for e.g. our LCMV tests we had a lot of violations due to subselections. I'll need to make a lot of other cleanups to get rid of all the warnings in tests, but I wanted to make sure that's the right approach before doing it.
Related to #2760.