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

Kernel param for apply inverse #6609

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1645de3
add full_data param to apply_inverse_epochs
DiGyt Jul 16, 2019
cba0585
Merge https://github.com/mne-tools/mne-python into kernel_param_for_a…
DiGyt Jul 27, 2019
5775bec
Added test
DiGyt Jul 27, 2019
3e35749
Improved Tests, docstrings
DiGyt Jul 27, 2019
75cace0
changed param name, added fixture
DiGyt Jul 29, 2019
3424e24
corrected bool param semantics
DiGyt Jul 29, 2019
a5349a3
improved docstring
DiGyt Jul 30, 2019
246fbce
Merge https://github.com/mne-tools/mne-python into kernel_param_for_a…
DiGyt Jul 30, 2019
15bfbda
Update mne/minimum_norm/inverse.py
DiGyt Jul 30, 2019
5c6bec5
Update mne/minimum_norm/inverse.py
DiGyt Jul 30, 2019
a60e33c
changed fixture name...
DiGyt Jul 30, 2019
fd56d56
fixed docstring
DiGyt Jul 30, 2019
4eccbba
raise error if delayed and vector orientation
DiGyt Jul 31, 2019
864c20d
Delayed works for pick_ori = "vector" now
DiGyt Aug 1, 2019
acfe50a
Merge https://github.com/mne-tools/mne-python into kernel_param_for_a…
DiGyt Aug 6, 2019
108bfdf
corrected stuff
DiGyt Aug 6, 2019
05607e0
adapted data, introduced tests
DiGyt Aug 8, 2019
2a29730
also cover VolVectorSourceEstimates
DiGyt Aug 8, 2019
17f9d05
rebase
DiGyt Aug 8, 2019
cc6e612
Merge https://github.com/mne-tools/mne-python into kernel_param_for_a…
DiGyt Aug 8, 2019
4ace218
merged with master
DiGyt Aug 8, 2019
f254a95
only one return statement in _make_stc
DiGyt Aug 20, 2019
6950b95
fixed flake
DiGyt Aug 20, 2019
e41236f
this should work
massich Aug 21, 2019
6bd01a7
change error message
DiGyt Aug 22, 2019
782e61f
Merge https://github.com/mne-tools/mne-python into kernel_param_for_a…
DiGyt Aug 22, 2019
c3427b1
Merge https://github.com/mne-tools/mne-python into kernel_param_for_a…
DiGyt Aug 30, 2019
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
16 changes: 12 additions & 4 deletions mne/minimum_norm/inverse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1069,7 +1069,7 @@ def apply_inverse_raw(raw, inverse_operator, lambda2, method="dSPM",
def _apply_inverse_epochs_gen(epochs, inverse_operator, lambda2, method='dSPM',
label=None, nave=1, pick_ori=None,
prepared=False, method_params=None,
verbose=None):
delayed=False, verbose=None):
"""Generate inverse solutions for epochs. Used in apply_inverse_epochs."""
_check_option('method', method, INVERSE_METHODS)
_check_ori(pick_ori, inverse_operator['source_ori'])
Expand Down Expand Up @@ -1122,7 +1122,7 @@ def _apply_inverse_epochs_gen(epochs, inverse_operator, lambda2, method='dSPM',
sol *= noise_norm
else:
# Linear inverse: do computation here or delayed
if len(sel) < K.shape[1]:
if delayed:
DiGyt marked this conversation as resolved.
Show resolved Hide resolved
sol = (K, e[sel])
else:
sol = np.dot(K, e[sel])
Expand All @@ -1141,7 +1141,7 @@ def _apply_inverse_epochs_gen(epochs, inverse_operator, lambda2, method='dSPM',
def apply_inverse_epochs(epochs, inverse_operator, lambda2, method="dSPM",
label=None, nave=1, pick_ori=None,
return_generator=False, prepared=False,
method_params=None, verbose=None):
method_params=None, delayed=False, verbose=None):
"""Apply inverse operator to Epochs.

Parameters
Expand Down Expand Up @@ -1177,6 +1177,14 @@ def apply_inverse_epochs(epochs, inverse_operator, lambda2, method="dSPM",
Additional options for eLORETA. See Notes of :func:`apply_inverse`.

.. versionadded:: 0.16
delayed : bool
If False, the full data is returned. If True, data is stored as a tuple
DiGyt marked this conversation as resolved.
Show resolved Hide resolved
of smaller arrays in order to save memory. In this case, the full data
field will be automatically constructed when stc.data is called for the
first time. `delayed=True` is only implemented for fixed
orientations. Defaults to False.
DiGyt marked this conversation as resolved.
Show resolved Hide resolved

.. versionadded:: 0.19
%(verbose)s

Returns
Expand All @@ -1192,7 +1200,7 @@ def apply_inverse_epochs(epochs, inverse_operator, lambda2, method="dSPM",
stcs = _apply_inverse_epochs_gen(
epochs, inverse_operator, lambda2, method=method, label=label,
nave=nave, pick_ori=pick_ori, verbose=verbose, prepared=prepared,
method_params=method_params)
method_params=method_params, delayed=delayed)

if not return_generator:
# return a list
Expand Down
70 changes: 54 additions & 16 deletions mne/minimum_norm/tests/test_inverse.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,12 +781,9 @@ def test_apply_mne_inverse_fixed_raw():
assert_array_almost_equal(stc.data, stc3.data)


@testing.requires_testing_data
def test_apply_mne_inverse_epochs():
"""Test MNE with precomputed inverse operator on Epochs."""
inverse_operator = read_inverse_operator(fname_full)
label_lh = read_label(fname_label % 'Aud-lh')
label_rh = read_label(fname_label % 'Aud-rh')
@pytest.fixture
def get_epochs():
"""Create an epochs object used for testing."""
event_id, tmin, tmax = 1, -0.2, 0.5
raw = read_raw_fif(fname_raw)

Expand All @@ -799,14 +796,24 @@ def test_apply_mne_inverse_epochs():
epochs = Epochs(raw, events, event_id, tmin, tmax, picks=picks,
baseline=(None, 0), reject=reject, flat=flat)

return epochs
DiGyt marked this conversation as resolved.
Show resolved Hide resolved


@testing.requires_testing_data
def test_apply_mne_inverse_epochs(get_epochs):
DiGyt marked this conversation as resolved.
Show resolved Hide resolved
"""Test MNE with precomputed inverse operator on Epochs."""
inverse_operator = read_inverse_operator(fname_full)
label_lh = read_label(fname_label % 'Aud-lh')
label_rh = read_label(fname_label % 'Aud-rh')

inverse_operator = prepare_inverse_operator(inverse_operator, nave=1,
lambda2=lambda2,
method="dSPM")
for pick_ori in [None, "normal", "vector"]:
stcs = apply_inverse_epochs(epochs, inverse_operator, lambda2, "dSPM",
label=label_lh, pick_ori=pick_ori)
stcs2 = apply_inverse_epochs(epochs, inverse_operator, lambda2, "dSPM",
label=label_lh, pick_ori=pick_ori,
stcs = apply_inverse_epochs(get_epochs, inverse_operator, lambda2,
"dSPM", label=label_lh, pick_ori=pick_ori)
stcs2 = apply_inverse_epochs(get_epochs, inverse_operator, lambda2,
"dSPM", label=label_lh, pick_ori=pick_ori,
DiGyt marked this conversation as resolved.
Show resolved Hide resolved
prepared=True)
# test if using prepared and not prepared inverse operator give the
# same result
Expand All @@ -818,7 +825,7 @@ def test_apply_mne_inverse_epochs():
assert (stcs[0].subject == 'sample')
inverse_operator = read_inverse_operator(fname_full)

stcs = apply_inverse_epochs(epochs, inverse_operator, lambda2, "dSPM",
stcs = apply_inverse_epochs(get_epochs, inverse_operator, lambda2, "dSPM",
label=label_lh, pick_ori='normal')
data = sum(stc.data for stc in stcs) / len(stcs)
flip = label_sign_flip(label_lh, inverse_operator['src'])
Expand All @@ -832,11 +839,11 @@ def test_apply_mne_inverse_epochs():
inverse_operator = prepare_inverse_operator(inverse_operator, nave=1,
lambda2=lambda2,
method="dSPM")
stcs_rh = apply_inverse_epochs(epochs, inverse_operator, lambda2, "dSPM",
label=label_rh, pick_ori="normal",
stcs_rh = apply_inverse_epochs(get_epochs, inverse_operator, lambda2,
"dSPM", label=label_rh, pick_ori="normal",
prepared=True)
stcs_bh = apply_inverse_epochs(epochs, inverse_operator, lambda2, "dSPM",
label=label_lh + label_rh,
stcs_bh = apply_inverse_epochs(get_epochs, inverse_operator, lambda2,
"dSPM", label=label_lh + label_rh,
pick_ori="normal",
prepared=True)

Expand All @@ -845,7 +852,7 @@ def test_apply_mne_inverse_epochs():
assert_array_almost_equal(stcs_rh[0].data, stcs_bh[0].data[n_lh:])

# test without using a label (so delayed computation is used)
stcs = apply_inverse_epochs(epochs, inverse_operator, lambda2, "dSPM",
stcs = apply_inverse_epochs(get_epochs, inverse_operator, lambda2, "dSPM",
pick_ori="normal", prepared=True)
assert (stcs[0].subject == 'sample')
label_stc = stcs[0].in_label(label_rh)
Expand Down Expand Up @@ -891,4 +898,35 @@ def test_inverse_ctf_comp():
apply_inverse_raw(raw, inv, 1. / 9.)


def _check_delayed_data(inst, delayed):
"""Check whether data is represented as kernel or not."""
if delayed:
assert isinstance(inst._kernel, np.ndarray)
assert isinstance(inst._sens_data, np.ndarray)
assert inst._data is None
assert not inst._kernel_removed
else:
assert inst._kernel is None
assert inst._sens_data is None
assert isinstance(inst._data, np.ndarray)


@testing.requires_testing_data
def test_delayed_data(get_epochs):
"""Test if kernel in apply_inverse_epochs was properly applied."""
inverse_operator = read_inverse_operator(fname_full)
inverse_operator = prepare_inverse_operator(inverse_operator, nave=1,
lambda2=lambda2,
method="dSPM")
larsoner marked this conversation as resolved.
Show resolved Hide resolved
DiGyt marked this conversation as resolved.
Show resolved Hide resolved
full_stcs = apply_inverse_epochs(get_epochs, inverse_operator, lambda2,
pick_ori="normal", delayed=False)
kernel_stcs = apply_inverse_epochs(get_epochs, inverse_operator, lambda2,
pick_ori="normal", delayed=True)

for full_stc, kern_stc in zip(full_stcs, kernel_stcs):
_check_delayed_data(full_stc, delayed=False)
_check_delayed_data(kern_stc, delayed=True)
assert_allclose(kern_stc.data, full_stc.data)


run_tests_if_main()