Example #1
0
def test_depth_does_not_matter(bias_params_free, weight_norm, pick_ori):
    """Test that depth weighting does not matter for normalized filters."""
    evoked, fwd, noise_cov, data_cov, _ = bias_params_free
    data = apply_lcmv(
        evoked,
        make_lcmv(evoked.info,
                  fwd,
                  data_cov,
                  0.05,
                  noise_cov,
                  pick_ori=pick_ori,
                  weight_norm=weight_norm,
                  depth=0.)).data
    data_depth = apply_lcmv(
        evoked,
        make_lcmv(evoked.info,
                  fwd,
                  data_cov,
                  0.05,
                  noise_cov,
                  pick_ori=pick_ori,
                  weight_norm=weight_norm,
                  depth=1.)).data
    assert data.shape == data_depth.shape
    for d1, d2 in zip(data, data_depth):
        # Sign flips can change when nearly orthogonal to the normal direction
        d2 *= np.sign(np.dot(d1.ravel(), d2.ravel()))
        atol = np.linalg.norm(d1) * 1e-7
        assert_allclose(d1, d2, atol=atol)
def test_lcmv_ctf_comp():
    """Test interpolation with compensated CTF data."""
    ctf_dir = op.join(testing.data_path(download=False), 'CTF')
    raw_fname = op.join(ctf_dir, 'somMDYO-18av.ds')
    raw = mne.io.read_raw_ctf(raw_fname, preload=True)

    events = mne.make_fixed_length_events(raw, duration=0.2)[:2]
    epochs = mne.Epochs(raw, events, tmin=-0.1, tmax=0.2)
    evoked = epochs.average()

    with pytest.warns(RuntimeWarning,
                      match='Too few samples .* estimate may be unreliable'):
        data_cov = mne.compute_covariance(epochs)
    fwd = mne.make_forward_solution(evoked.info, None,
                                    mne.setup_volume_source_space(pos=15.0),
                                    mne.make_sphere_model())
    with pytest.raises(ValueError, match='reduce_rank'):
        make_lcmv(evoked.info, fwd, data_cov)
    filters = make_lcmv(evoked.info, fwd, data_cov, reduce_rank=True)
    assert 'weights' in filters

    # test whether different compensations throw error
    info_comp = evoked.info.copy()
    set_current_comp(info_comp, 1)
    with pytest.raises(RuntimeError, match='Compensation grade .* not match'):
        make_lcmv(info_comp, fwd, data_cov)
def test_unit_noise_gain_formula(pick_ori, weight_norm, reg, inversion):
    """Test unit-noise-gain filter against formula."""
    raw = mne.io.read_raw_fif(fname_raw, preload=True)
    events = mne.find_events(raw)
    raw.pick_types(meg='mag')
    assert len(raw.ch_names) == 102
    epochs = mne.Epochs(raw, events, None, preload=True)
    data_cov = mne.compute_covariance(epochs, tmin=0.04, tmax=0.15)
    # for now, avoid whitening to make life easier
    noise_cov = mne.make_ad_hoc_cov(epochs.info, std=dict(grad=1., mag=1.))
    forward = mne.read_forward_solution(fname_fwd)
    convert_forward_solution(forward, surf_ori=True, copy=False)
    rank = None
    kwargs = dict(reg=reg, noise_cov=noise_cov, pick_ori=pick_ori,
                  weight_norm=weight_norm, rank=rank, inversion=inversion)
    if inversion == 'single' and pick_ori == 'vector' and \
            weight_norm == 'unit-noise-gain-invariant':
        with pytest.raises(ValueError, match='Cannot use'):
            make_lcmv(epochs.info, forward, data_cov, **kwargs)
        return
    filters = make_lcmv(epochs.info, forward, data_cov, **kwargs)
    _, _, _, _, G, _, _, _ = _prepare_beamformer_input(
        epochs.info, forward, None, 'vector', noise_cov=noise_cov, rank=rank,
        pca=False, exp=None)
    n_channels, n_sources = G.shape
    n_sources //= 3
    G.shape = (n_channels, n_sources, 3)
    G = G.transpose(1, 2, 0)  # verts, orient, ch
    _assert_weight_norm(filters, G)
Example #4
0
def test_make_lcmv_sphere(pick_ori, weight_norm):
    """Test LCMV with sphere head model."""
    # unit-noise gain beamformer and orientation
    # selection and rank reduction of the leadfield
    _, _, evoked, data_cov, noise_cov, _, _, _, _, _ = _get_data(proj=True)
    assert 'eeg' not in evoked
    assert 'meg' in evoked
    sphere = mne.make_sphere_model(r0=(0., 0., 0.), head_radius=0.080)
    src = mne.setup_volume_source_space(pos=25.,
                                        sphere=sphere,
                                        mindist=5.0,
                                        exclude=2.0)
    fwd_sphere = mne.make_forward_solution(evoked.info, None, src, sphere)

    # Test that we get an error if not reducing rank
    with pytest.raises(ValueError, match='Singular matrix detected'):
        with pytest.warns(RuntimeWarning, match='positive semidefinite'):
            make_lcmv(evoked.info,
                      fwd_sphere,
                      data_cov,
                      reg=0.1,
                      noise_cov=noise_cov,
                      weight_norm=weight_norm,
                      pick_ori=pick_ori,
                      reduce_rank=False,
                      rank='full')

    # Now let's reduce it
    filters = make_lcmv(evoked.info,
                        fwd_sphere,
                        data_cov,
                        reg=0.1,
                        noise_cov=noise_cov,
                        weight_norm=weight_norm,
                        pick_ori=pick_ori,
                        reduce_rank=True)
    stc_sphere = apply_lcmv(evoked, filters, max_ori_out='signed')
    if isinstance(stc_sphere, VolVectorSourceEstimate):
        stc_sphere = stc_sphere.magnitude()
    else:
        stc_sphere = abs(stc_sphere)
    assert isinstance(stc_sphere, VolSourceEstimate)
    stc_sphere.crop(0.02, None)

    stc_pow = np.sum(stc_sphere.data, axis=1)
    idx = np.argmax(stc_pow)
    max_stc = stc_sphere.data[idx]
    tmax = stc_sphere.times[np.argmax(max_stc)]
    assert 0.08 < tmax < 0.15, tmax
    min_, max_ = 1.0, 4.5
    if weight_norm is None:
        min_ *= 2e-7
        max_ *= 2e-7
    assert min_ < np.max(max_stc) < max_, (min_, np.max(max_stc), max_)
def test_lcmv_maxfiltered():
    """Test LCMV on maxfiltered data."""
    raw = mne.io.read_raw_fif(fname_raw).fix_mag_coil_types()
    raw_sss = mne.preprocessing.maxwell_filter(raw)
    events = mne.find_events(raw_sss)
    del raw
    raw_sss.pick_types(meg='mag')
    assert len(raw_sss.ch_names) == 102
    epochs = mne.Epochs(raw_sss, events)
    data_cov = mne.compute_covariance(epochs, tmin=0)
    fwd = mne.read_forward_solution(fname_fwd)
    rank = compute_rank(data_cov, info=epochs.info)
    assert rank == {'mag': 71}
    for use_rank in ('info', rank, 'full', None):
        make_lcmv(epochs.info, fwd, data_cov, rank=use_rank)
Example #6
0
def test_lcmv_raw():
    """Test LCMV with raw data."""
    raw, _, _, _, noise_cov, label, forward, _, _, _ =\
        _get_data(all_forward=False, epochs=False, data_cov=False)

    tmin, tmax = 0, 20
    start, stop = raw.time_as_index([tmin, tmax])

    # use only the left-temporal MEG channels for LCMV
    data_cov = mne.compute_raw_covariance(raw, tmin=tmin, tmax=tmax)
    filters = make_lcmv(raw.info,
                        forward,
                        data_cov,
                        reg=0.01,
                        noise_cov=noise_cov,
                        label=label)
    stc = apply_lcmv_raw(raw,
                         filters,
                         start=start,
                         stop=stop,
                         max_ori_out='signed')

    assert_array_almost_equal(np.array([tmin, tmax]),
                              np.array([stc.times[0], stc.times[-1]]),
                              decimal=2)

    # make sure we get an stc with vertices only in the lh
    vertno = [forward['src'][0]['vertno'], forward['src'][1]['vertno']]
    assert len(stc.vertices[0]) == len(
        np.intersect1d(vertno[0], label.vertices))
    assert len(stc.vertices[1]) == 0
Example #7
0
def test_lcmv_cov(weight_norm, pick_ori):
    """Test LCMV source power computation."""
    raw, epochs, evoked, data_cov, noise_cov, label, forward,\
        forward_surf_ori, forward_fixed, forward_vol = _get_data()
    convert_forward_solution(forward, surf_ori=True, copy=False)
    filters = make_lcmv(evoked.info,
                        forward,
                        data_cov,
                        noise_cov=noise_cov,
                        weight_norm=weight_norm,
                        pick_ori=pick_ori)
    for cov in (data_cov, noise_cov):
        this_cov = pick_channels_cov(cov, evoked.ch_names)
        this_evoked = evoked.copy().pick_channels(this_cov['names'])
        this_cov['projs'] = this_evoked.info['projs']
        assert this_evoked.ch_names == this_cov['names']
        stc = apply_lcmv_cov(this_cov, filters)
        assert stc.data.min() > 0
        assert stc.shape == (498, 1)
        ev = EvokedArray(this_cov.data, this_evoked.info)
        stc_1 = apply_lcmv(ev, filters)
        assert stc_1.data.min() < 0
        ev = EvokedArray(stc_1.data.T, this_evoked.info)
        stc_2 = apply_lcmv(ev, filters)
        assert stc_2.data.shape == (498, 498)
        data = np.diag(stc_2.data)[:, np.newaxis]
        assert data.min() > 0
        assert_allclose(data, stc.data, rtol=1e-12)
Example #8
0
def test_lcmv_fieldtrip():
    """Test LCMV vs fieldtrip output."""
    evoked, data_cov, fwd = _get_bf_data()

    # beamformer types to be tested: unit-gain (vector and scalar) and
    # unit-noise-gain
    bf_types = ['ug_vec', 'ug_scal', 'ung']
    weight_norms = [None, None, 'unit-noise-gain']
    pick_oris = [None, 'max-power', 'max-power']

    for bf_type, weight_norm, pick_ori in zip(bf_types, weight_norms,
                                              pick_oris):

        # run the MNE-Python beamformer
        filters = make_lcmv(evoked.info,
                            fwd,
                            data_cov=data_cov,
                            noise_cov=None,
                            pick_ori=pick_ori,
                            reg=0.05,
                            weight_norm=weight_norm)
        stc_mne = apply_lcmv(evoked, filters)
        # take the absolute value, since orientation is arbitrary by 180 degr.
        stc_mne.data[:, :] = np.abs(stc_mne.data)

        # load the FieldTrip output
        ft_fname = op.join(ft_data_path, 'ft_source_' + bf_type + '-vol.stc')
        stc_ft = mne.read_source_estimate(ft_fname)

        # calculate the Pearson correlation between the source solutions:
        pearson = np.corrcoef(np.concatenate(stc_mne.data),
                              np.concatenate(stc_ft.data))

        assert pearson[0, 1] >= 0.99
def _gen_lcmv(active_cov, baseline_cov, common_cov):
    filters = make_lcmv(epochs.info, fwd, common_cov, reg=0.05,
                        noise_cov=None, pick_ori='max-power')
    stc_base = apply_lcmv_cov(baseline_cov, filters)
    stc_act = apply_lcmv_cov(active_cov, filters)
    stc_act /= stc_base
    return stc_act
Example #10
0
def test_localization_bias_free(bias_params_free, reg, pick_ori, weight_norm,
                                use_cov, depth, lower, upper,
                                lower_ori, upper_ori):
    """Test localization bias for free-orientation LCMV."""
    evoked, fwd, noise_cov, data_cov, want = bias_params_free
    if not use_cov:
        evoked.pick_types(meg='grad')
        noise_cov = None
    with pytest.warns(None):  # rank deficiency of data_cov
        filters = make_lcmv(evoked.info, fwd, data_cov, reg,
                            noise_cov, pick_ori=pick_ori,
                            weight_norm=weight_norm,
                            depth=depth)
    loc = apply_lcmv(evoked, filters).data
    if pick_ori == 'vector':
        ori = loc.copy() / np.linalg.norm(loc, axis=1, keepdims=True)
    else:
        # doesn't make sense for pooled (None) or max-power (can't be all 3)
        ori = None
    loc = np.linalg.norm(loc, axis=1) if pick_ori == 'vector' else np.abs(loc)
    # Compute the percentage of sources for which there is no loc bias:
    max_idx = np.argmax(loc, axis=0)
    perc = (want == max_idx).mean() * 100
    assert lower <= perc <= upper
    _assert_free_ori_match(ori, max_idx, lower_ori, upper_ori)
Example #11
0
def run_lcmv_evoked(evoked, fwd, data_cov, reg, noise_cov=None,
                    pick_ori='max-power', weight_norm='nai'):
    """Run LCMV on average.

    Run weight-normalized LCMV beamformer on evoked data, will return an stc
    object.

    Parameters:
    -----------
    evoked : MNE evoked
        evoked data to source reconstruct.
    fwd : MNE forward model
        forward model.
    data_cov : MNE covariance estimate
        data covariance matrix.
    reg : float
        regularization parameter
    noise_cov : MNE covariance estimate
        noise covariance matrix, optional

    Returns
    -------
    stc : MNE stcs
        original output of apply_lcmv
    filters : dict
        spatial filter used in computation
    """
    filters = make_lcmv(evoked.info, fwd, data_cov=data_cov,
                        noise_cov=noise_cov, pick_ori=pick_ori, reg=reg,
                        weight_norm=weight_norm)

    # apply that filter to epochs
    stc = apply_lcmv(evoked, filters, max_ori_out='signed')

    return stc, filters
Example #12
0
def test_lcmv_fieldtrip(_get_bf_data, bf_type, weight_norm, pick_ori, pwr):
    """Test LCMV vs fieldtrip output."""
    evoked, data_cov, fwd = _get_bf_data

    # run the MNE-Python beamformer
    filters = make_lcmv(evoked.info,
                        fwd,
                        data_cov=data_cov,
                        noise_cov=None,
                        pick_ori=pick_ori,
                        reg=0.05,
                        weight_norm=weight_norm)
    if pwr:
        stc_mne = apply_lcmv_cov(data_cov, filters)
    else:
        stc_mne = apply_lcmv(evoked, filters)

    # load the FieldTrip output
    ft_fname = op.join(ft_data_path, 'ft_source_' + bf_type + '-vol.mat')
    stc_ft_data = read_mat(ft_fname)['stc']
    if stc_ft_data.ndim == 1:
        stc_ft_data.shape = (stc_ft_data.size, 1)

    if stc_mne.data.ndim == 2:
        signs = np.sign((stc_mne.data * stc_ft_data).sum(-1, keepdims=True))
        if pwr:
            assert_array_equal(signs, 1.)
        stc_mne.data *= signs
    assert stc_ft_data.shape == stc_mne.data.shape
    if pick_ori == 'vector':
        # compare norms first
        assert_allclose(np.linalg.norm(stc_mne.data, axis=1),
                        np.linalg.norm(stc_ft_data, axis=1),
                        rtol=1e-6)
    assert_allclose(stc_mne.data, stc_ft_data, rtol=1e-6)
Example #13
0
def test_lcmv_fieldtrip(_get_bf_data, bf_type, weight_norm, pick_ori, pwr):
    """Test LCMV vs fieldtrip output."""
    evoked, data_cov, fwd = _get_bf_data

    # run the MNE-Python beamformer
    filters = make_lcmv(evoked.info,
                        fwd,
                        data_cov=data_cov,
                        noise_cov=None,
                        pick_ori=pick_ori,
                        reg=0.05,
                        weight_norm=weight_norm)
    if pwr is True:
        stc_mne = apply_lcmv_cov(data_cov, filters)
    else:
        stc_mne = apply_lcmv(evoked, filters)
        # take the absolute value, since orientation can be flipped
        stc_mne.data[:, :] = np.abs(stc_mne.data)

    # load the FieldTrip output
    ft_fname = op.join(ft_data_path, 'ft_source_' + bf_type + '-vol.stc')
    stc_ft = mne.read_source_estimate(ft_fname)

    # calculate the Pearson correlation between the source solutions:
    pearson = np.corrcoef(stc_mne.data.ravel(), stc_ft.data.ravel())[0, 1]
    assert pearson >= 0.99
Example #14
0
def run_lcmv_epochs(epochs, fwd, data_cov, reg, noise_cov=None,
                    pick_ori='max-power', weight_norm='nai', verbose=False):
    """Run LCMV on epochs.

    Run weight-normalized LCMV beamformer on epoch data, will return matrix of
    trials or stc object.

    Parameters:
    -----------
    epochs : MNE epochs
        epochs to source reconstruct.
    fwd : MNE forward model
        forward model.
    data_cov : MNE covariance estimate
        data covariance matrix
    reg : float
        regularization parameter
    noise_cov : MNE covariance estimate
        noise covariance matrix, optional
    verbose : bool
        overrides default verbose level, defaults to False, i.e., no logger
        info.

    Returns
    -------
    stcs_mat : numpy array
        matrix with all source trials
    stc : MNE stc
        single trial stc object (last trial)
    filters : dict
        spatial filter used in computation
    """
    filters = make_lcmv(epochs.info, fwd, data_cov=data_cov,
                        noise_cov=noise_cov, pick_ori=pick_ori, reg=reg,
                        weight_norm=weight_norm, verbose=verbose)

    # apply that filter to epochs
    stcs = apply_lcmv_epochs(epochs, filters, return_generator=True,
                             max_ori_out='signed', verbose=verbose)

    # preallocate matrix
    stcs_mat = np.ones((epochs._data.shape[0], fwd['nsource'],
                        len(epochs.times)))

    if verbose is False:
        mne.set_log_level('WARNING')

    # resolve generator
    for trial in range(epochs._data.shape[0]):
        # last time: also save stc
        if trial == 0:
            stc = next(stcs)
            stcs_mat[trial, :, :] = stc.data
        else:
            stcs_mat[trial, :, :] = next(stcs).data

    return stcs_mat, stc, filters
Example #15
0
def test_localization_bias_fixed(bias_params_fixed, reg, weight_norm, use_cov,
                                 lower, upper):
    """Test localization bias for fixed-orientation LCMV."""
    evoked, fwd, noise_cov, data_cov, want = bias_params_fixed
    if not use_cov:
        evoked.pick_types('grad')
        noise_cov = None
    assert data_cov['data'].shape[0] == len(data_cov['names'])
    loc = apply_lcmv(evoked, make_lcmv(evoked.info, fwd, data_cov, reg,
                                       noise_cov)).data
    loc = np.abs(loc)
    # Compute the percentage of sources for which there is no loc bias:
    perc = (want == np.argmax(loc, axis=0)).mean() * 100
    assert lower <= perc <= upper
Example #16
0
def test_lcmv_ctf_comp():
    """Test interpolation with compensated CTF data."""
    raw = mne.io.read_raw_ctf(ctf_fname, preload=True)
    raw.pick(raw.ch_names[:70])

    events = mne.make_fixed_length_events(raw, duration=0.2)[:2]
    epochs = mne.Epochs(raw, events, tmin=-0.1, tmax=0.2)
    evoked = epochs.average()

    data_cov = mne.compute_covariance(epochs)
    fwd = mne.make_forward_solution(evoked.info, None,
                                    mne.setup_volume_source_space(pos=30.0),
                                    mne.make_sphere_model())
    with pytest.raises(ValueError, match='reduce_rank'):
        make_lcmv(evoked.info, fwd, data_cov)
    filters = make_lcmv(evoked.info, fwd, data_cov, reduce_rank=True)
    assert 'weights' in filters

    # test whether different compensations throw error
    info_comp = evoked.info.copy()
    set_current_comp(info_comp, 1)
    with pytest.raises(RuntimeError, match='Compensation grade .* not match'):
        make_lcmv(info_comp, fwd, data_cov)
Example #17
0
def test_localization_bias_free(bias_params_free, reg, pick_ori, weight_norm,
                                use_cov, lower, upper):
    """Test localization bias for free-orientation LCMV."""
    evoked, fwd, noise_cov, data_cov, want = bias_params_free
    if not use_cov:
        evoked.pick_types('grad')
        noise_cov = None
    loc = apply_lcmv(evoked, make_lcmv(evoked.info, fwd, data_cov, reg,
                                       noise_cov, pick_ori=pick_ori,
                                       weight_norm=weight_norm)).data
    loc = np.linalg.norm(loc, axis=1) if pick_ori == 'vector' else np.abs(loc)
    # Compute the percentage of sources for which there is no loc bias:
    perc = (want == np.argmax(loc, axis=0)).mean() * 100
    assert lower <= perc <= upper
Example #18
0
def test_lcmv_ctf_comp():
    """Test interpolation with compensated CTF data."""
    ctf_dir = op.join(testing.data_path(download=False), 'CTF')
    raw_fname = op.join(ctf_dir, 'somMDYO-18av.ds')
    raw = mne.io.read_raw_ctf(raw_fname, preload=True)

    events = mne.make_fixed_length_events(raw, duration=0.2)[:2]
    epochs = mne.Epochs(raw, events, tmin=0., tmax=0.2)
    evoked = epochs.average()

    with pytest.warns(RuntimeWarning,
                      match='Too few samples .* estimate may be unreliable'):
        data_cov = mne.compute_covariance(epochs)
    fwd = mne.make_forward_solution(evoked.info, None,
                                    mne.setup_volume_source_space(pos=15.0),
                                    mne.make_sphere_model())
    filters = make_lcmv(evoked.info, fwd, data_cov)
    assert 'weights' in filters

    # test whether different compensations throw error
    info_comp = evoked.info.copy()
    set_current_comp(info_comp, 1)
    with pytest.raises(RuntimeError, match='Compensation grade .* not match'):
        make_lcmv(info_comp, fwd, data_cov)
Example #19
0
def test_lcmv_reg_proj(proj):
    """Test LCMV with and without proj."""
    raw = mne.io.read_raw_fif(fname_raw, preload=True)
    events = mne.find_events(raw)
    raw.pick_types()
    assert len(raw.ch_names) == 305
    epochs = mne.Epochs(raw, events, None, preload=True, proj=proj)
    with pytest.warns(RuntimeWarning, match='Too few samples'):
        noise_cov = mne.compute_covariance(epochs, tmax=0)
        data_cov = mne.compute_covariance(epochs, tmin=0.04, tmax=0.15)
    forward = mne.read_forward_solution(fname_fwd)
    filters = make_lcmv(epochs.info, forward, data_cov, reg=0.05,
                        noise_cov=noise_cov, pick_ori='max-power',
                        weight_norm='nai', rank=None, verbose=True)
    want_rank = 302  # 305 good channels - 3 MEG projs
    assert filters['rank'] == want_rank
Example #20
0
def test_lcmv_reg_proj(proj):
    """Test LCMV with and without proj."""
    raw = mne.io.read_raw_fif(fname_raw, preload=True)
    events = mne.find_events(raw)
    raw.pick_types()
    assert len(raw.ch_names) == 305
    epochs = mne.Epochs(raw, events, None, preload=True, proj=proj)
    with pytest.warns(RuntimeWarning, match='Too few samples'):
        noise_cov = mne.compute_covariance(epochs, tmax=0)
        data_cov = mne.compute_covariance(epochs, tmin=0.04, tmax=0.15)
    forward = mne.read_forward_solution(fname_fwd)
    filters = make_lcmv(epochs.info, forward, data_cov, reg=0.05,
                        noise_cov=noise_cov, pick_ori='max-power',
                        weight_norm='nai', rank=None, verbose=True)
    want_rank = 302  # 305 good channels - 3 MEG projs
    assert filters['rank'] == want_rank
Example #21
0
def test_lcmv_ctf_comp():
    """Test interpolation with compensated CTF data."""
    ctf_dir = op.join(testing.data_path(download=False), 'CTF')
    raw_fname = op.join(ctf_dir, 'somMDYO-18av.ds')
    raw = mne.io.read_raw_ctf(raw_fname, preload=True)

    events = mne.make_fixed_length_events(raw, duration=0.2)[:2]
    epochs = mne.Epochs(raw, events, tmin=0., tmax=0.2)
    evoked = epochs.average()

    with pytest.warns(RuntimeWarning,
                      match='Too few samples .* estimate may be unreliable'):
        data_cov = mne.compute_covariance(epochs)
    fwd = mne.make_forward_solution(evoked.info, None,
                                    mne.setup_volume_source_space(pos=15.0),
                                    mne.make_sphere_model())
    filters = make_lcmv(evoked.info, fwd, data_cov)
    assert 'weights' in filters
Example #22
0
    def fit(self, X, y):
        from mne.beamformer import make_lcmv
        from process_raw_data import compute_covariance

        epochs = mne.EpochsArray(X, self.info, tmin=self.tmin, verbose=False)
        self.data_cov, self.noise_cov = compute_covariance(
            epochs,
            t_win=self.t_win,
            noise=True,
            t_win_noise=self.t_win_noise,
            check=True,
            plot=False)
        self.filters = make_lcmv(self.info,
                                 self.fwd,
                                 self.data_cov,
                                 noise_cov=self.noise_cov,
                                 pick_ori=self.pick_ori,
                                 weight_norm=self.weight_norm)
        return self
Example #23
0
def test_orientation_max_power(bias_params_fixed, bias_params_free, reg,
                               weight_norm, use_cov, depth, lower, upper,
                               lower_ori, upper_ori):
    """Test orientation selection for bias for max-power LCMV."""
    # we simulate data for the fixed orientation forward and beamform using
    # the free orientation forward, and check the orientation match at the end
    evoked, _, noise_cov, data_cov, want = bias_params_fixed
    fwd = bias_params_free[1]
    if not use_cov:
        evoked.pick_types(meg='grad')
        noise_cov = None
    filters = make_lcmv(evoked.info,
                        fwd,
                        data_cov,
                        reg,
                        noise_cov,
                        pick_ori='max-power',
                        weight_norm=weight_norm,
                        depth=depth)
    loc = apply_lcmv(evoked, filters).data
    ori = filters['max_power_ori']
    assert ori.shape == (246, 3)
    loc = np.abs(loc)
    # Compute the percentage of sources for which there is no loc bias:
    max_idx = np.argmax(loc, axis=0)
    mask = want == max_idx  # ones that localized properly
    perc = mask.mean() * 100
    assert lower <= perc <= upper
    # Compute the dot products of our forward normals and
    assert fwd['coord_frame'] == FIFF.FIFFV_COORD_HEAD
    nn = np.concatenate(
        [s['nn'][v] for s, v in zip(fwd['src'], filters['vertices'])])
    nn = nn[want]
    nn = apply_trans(invert_transform(fwd['mri_head_t']), nn, move=False)
    assert_allclose(np.linalg.norm(nn, axis=1), 1, atol=1e-6)
    assert_allclose(np.linalg.norm(ori, axis=1), 1, atol=1e-12)
    dots = np.abs((nn[mask] * ori[mask]).sum(-1))
    assert_array_less(dots, 1)
    assert_array_less(0, dots)
    got = np.mean(dots)
    assert lower_ori < got < upper_ori
Example #24
0
def get_filter(info,
               forward,
               data_cov,
               noise_cov,
               label=None,
               reg=0.05,
               pick_ori='max-power'):
    """Comput LCMV filter for one region of interest."""
    filter = make_lcmv(info=info,
                       forward=forward,
                       data_cov=data_cov,
                       noise_cov=noise_cov,
                       reg=0.05,
                       pick_ori='max-power',
                       label=label)
    from mne.label import label_sign_flip
    filter['sign_flip_vector'] = label_sign_flip(label, forward['src'])
    del filter['data_cov']
    del filter['noise_cov']
    if 'src' in filter:
        del filter['src']
    return label.name, filter
Example #25
0
def test_lcmv_fieldtrip(_get_bf_data, bf_type, weight_norm, pick_ori, pwr):
    """Test LCMV vs fieldtrip output."""
    evoked, data_cov, fwd = _get_bf_data

    # run the MNE-Python beamformer
    filters = make_lcmv(evoked.info, fwd, data_cov=data_cov,
                        noise_cov=None, pick_ori=pick_ori, reg=0.05,
                        weight_norm=weight_norm)
    if pwr is True:
        stc_mne = apply_lcmv_cov(data_cov, filters)
    else:
        stc_mne = apply_lcmv(evoked, filters)
        # take the absolute value, since orientation can be flipped
        stc_mne.data[:, :] = np.abs(stc_mne.data)

    # load the FieldTrip output
    ft_fname = op.join(ft_data_path, 'ft_source_' + bf_type + '-vol.stc')
    stc_ft = mne.read_source_estimate(ft_fname)

    # calculate the Pearson correlation between the source solutions:
    pearson = np.corrcoef(stc_mne.data.ravel(), stc_ft.data.ravel())[0, 1]
    assert pearson >= 0.99
Example #26
0
def test_lcmv_raw():
    """Test LCMV with raw data."""
    raw, _, _, _, noise_cov, label, forward, _, _, _ =\
        _get_data(all_forward=False, epochs=False, data_cov=False)

    tmin, tmax = 0, 20
    start, stop = raw.time_as_index([tmin, tmax])

    # use only the left-temporal MEG channels for LCMV
    data_cov = mne.compute_raw_covariance(raw, tmin=tmin, tmax=tmax)
    filters = make_lcmv(raw.info, forward, data_cov, reg=0.01,
                        noise_cov=noise_cov, label=label)
    stc = apply_lcmv_raw(raw, filters, start=start, stop=stop,
                         max_ori_out='signed')

    assert_array_almost_equal(np.array([tmin, tmax]),
                              np.array([stc.times[0], stc.times[-1]]),
                              decimal=2)

    # make sure we get an stc with vertices only in the lh
    vertno = [forward['src'][0]['vertno'], forward['src'][1]['vertno']]
    assert len(stc.vertices[0]) == len(np.intersect1d(vertno[0],
                                                      label.vertices))
    assert len(stc.vertices[1]) == 0
Example #27
0
def test_make_lcmv(tmpdir, reg, proj):
    """Test LCMV with evoked data and single trials."""
    raw, epochs, evoked, data_cov, noise_cov, label, forward,\
        forward_surf_ori, forward_fixed, forward_vol = _get_data(proj=proj)

    for fwd in [forward, forward_vol]:
        filters = make_lcmv(evoked.info, fwd, data_cov, reg=reg,
                            noise_cov=noise_cov)
        stc = apply_lcmv(evoked, filters, max_ori_out='signed')
        stc.crop(0.02, None)

        stc_pow = np.sum(np.abs(stc.data), axis=1)
        idx = np.argmax(stc_pow)
        max_stc = stc.data[idx]
        tmax = stc.times[np.argmax(max_stc)]

        assert 0.08 < tmax < 0.15, tmax
        assert 0.9 < np.max(max_stc) < 3.5, np.max(max_stc)

        if fwd is forward:
            # Test picking normal orientation (surface source space only).
            filters = make_lcmv(evoked.info, forward_surf_ori, data_cov,
                                reg=reg, noise_cov=noise_cov,
                                pick_ori='normal', weight_norm=None)
            stc_normal = apply_lcmv(evoked, filters, max_ori_out='signed')
            stc_normal.crop(0.02, None)

            stc_pow = np.sum(np.abs(stc_normal.data), axis=1)
            idx = np.argmax(stc_pow)
            max_stc = stc_normal.data[idx]
            tmax = stc_normal.times[np.argmax(max_stc)]

            lower = 0.04 if proj else 0.025
            assert lower < tmax < 0.14, tmax
            lower = 3e-7 if proj else 2e-7
            assert lower < np.max(max_stc) < 3e-6, np.max(max_stc)

            # No weight normalization was applied, so the amplitude of normal
            # orientation results should always be smaller than free
            # orientation results.
            assert (np.abs(stc_normal.data) <= stc.data).all()

        # Test picking source orientation maximizing output source power
        filters = make_lcmv(evoked.info, fwd, data_cov, reg=reg,
                            noise_cov=noise_cov, pick_ori='max-power')
        stc_max_power = apply_lcmv(evoked, filters, max_ori_out='signed')
        stc_max_power.crop(0.02, None)
        stc_pow = np.sum(np.abs(stc_max_power.data), axis=1)
        idx = np.argmax(stc_pow)
        max_stc = np.abs(stc_max_power.data[idx])
        tmax = stc.times[np.argmax(max_stc)]

        lower = 0.08 if proj else 0.04
        assert lower < tmax < 0.15, tmax
        assert 0.8 < np.max(max_stc) < 3., np.max(max_stc)

        stc_max_power.data[:, :] = np.abs(stc_max_power.data)

        if fwd is forward:
            # Maximum output source power orientation results should be
            # similar to free orientation results in areas with channel
            # coverage
            label = mne.read_label(fname_label)
            mean_stc = stc.extract_label_time_course(label, fwd['src'],
                                                     mode='mean')
            mean_stc_max_pow = \
                stc_max_power.extract_label_time_course(label, fwd['src'],
                                                        mode='mean')
            assert_array_less(np.abs(mean_stc - mean_stc_max_pow), 1.0)

        # Test NAI weight normalization:
        filters = make_lcmv(evoked.info, fwd, data_cov, reg=reg,
                            noise_cov=noise_cov, pick_ori='max-power',
                            weight_norm='nai')
        stc_nai = apply_lcmv(evoked, filters, max_ori_out='signed')
        stc_nai.crop(0.02, None)

        # Test whether unit-noise-gain solution is a scaled version of NAI
        pearsoncorr = np.corrcoef(np.concatenate(np.abs(stc_nai.data)),
                                  np.concatenate(stc_max_power.data))
        assert_almost_equal(pearsoncorr[0, 1], 1.)

    # Test if spatial filter contains src_type
    assert 'src_type' in filters

    # __repr__
    assert len(evoked.ch_names) == 22
    assert len(evoked.info['projs']) == (3 if proj else 0)
    assert len(evoked.info['bads']) == 2
    rank = 17 if proj else 20
    assert 'LCMV' in repr(filters)
    assert 'unknown subject' not in repr(filters)
    assert '4157 vert' in repr(filters)
    assert '20 ch' in repr(filters)
    assert 'rank %s' % rank in repr(filters)

    # I/O
    fname = op.join(str(tmpdir), 'filters.h5')
    with pytest.warns(RuntimeWarning, match='-lcmv.h5'):
        filters.save(fname)
    filters_read = read_beamformer(fname)
    assert isinstance(filters, Beamformer)
    assert isinstance(filters_read, Beamformer)
    # deal with object_diff strictness
    filters_read['rank'] = int(filters_read['rank'])
    filters['rank'] = int(filters['rank'])
    assert object_diff(filters, filters_read) == ''

    # Test if fixed forward operator is detected when picking normal or
    # max-power orientation
    pytest.raises(ValueError, make_lcmv, evoked.info, forward_fixed, data_cov,
                  reg=0.01, noise_cov=noise_cov, pick_ori='normal')
    pytest.raises(ValueError, make_lcmv, evoked.info, forward_fixed, data_cov,
                  reg=0.01, noise_cov=noise_cov, pick_ori='max-power')

    # Test if non-surface oriented forward operator is detected when picking
    # normal orientation
    pytest.raises(ValueError, make_lcmv, evoked.info, forward, data_cov,
                  reg=0.01, noise_cov=noise_cov, pick_ori='normal')

    # Test if volume forward operator is detected when picking normal
    # orientation
    pytest.raises(ValueError, make_lcmv, evoked.info, forward_vol, data_cov,
                  reg=0.01, noise_cov=noise_cov, pick_ori='normal')

    # Test if missing of noise covariance matrix is detected when more than
    # one channel type is present in the data
    pytest.raises(ValueError, make_lcmv, evoked.info, forward_vol,
                  data_cov=data_cov, reg=0.01, noise_cov=None,
                  pick_ori='max-power')

    # Test if wrong channel selection is detected in application of filter
    evoked_ch = deepcopy(evoked)
    evoked_ch.pick_channels(evoked_ch.ch_names[1:])
    filters = make_lcmv(evoked.info, forward_vol, data_cov, reg=0.01,
                        noise_cov=noise_cov)
    pytest.raises(ValueError, apply_lcmv, evoked_ch, filters,
                  max_ori_out='signed')

    # Test if discrepancies in channel selection of data and fwd model are
    # handled correctly in apply_lcmv
    # make filter with data where first channel was removed
    filters = make_lcmv(evoked_ch.info, forward_vol, data_cov, reg=0.01,
                        noise_cov=noise_cov)
    # applying that filter to the full data set should automatically exclude
    # this channel from the data
    # also test here that no warnings are thrown - implemented to check whether
    # src should not be None warning occurs
    with pytest.warns(None) as w:
        stc = apply_lcmv(evoked, filters, max_ori_out='signed')
    assert len(w) == 0
    # the result should be equal to applying this filter to a dataset without
    # this channel:
    stc_ch = apply_lcmv(evoked_ch, filters, max_ori_out='signed')
    assert_array_almost_equal(stc.data, stc_ch.data)

    # Test if non-matching SSP projection is detected in application of filter
    if proj:
        raw_proj = deepcopy(raw)
        raw_proj.del_proj()
        with pytest.raises(ValueError, match='do not match the projections'):
            apply_lcmv_raw(raw_proj, filters, max_ori_out='signed')

    # Test if spatial filter contains src_type
    assert 'src_type' in filters

    # check whether a filters object without src_type throws expected warning
    del filters['src_type']  # emulate 0.16 behaviour to cause warning
    with pytest.warns(RuntimeWarning, match='spatial filter does not contain '
                      'src_type'):
        apply_lcmv(evoked, filters, max_ori_out='signed')

    # Now test single trial using fixed orientation forward solution
    # so we can compare it to the evoked solution
    filters = make_lcmv(epochs.info, forward_fixed, data_cov, reg=0.01,
                        noise_cov=noise_cov)
    stcs = apply_lcmv_epochs(epochs, filters, max_ori_out='signed')
    stcs_ = apply_lcmv_epochs(epochs, filters, return_generator=True,
                              max_ori_out='signed')
    assert_array_equal(stcs[0].data, next(stcs_).data)

    epochs.drop_bad()
    assert (len(epochs.events) == len(stcs))

    # average the single trial estimates
    stc_avg = np.zeros_like(stcs[0].data)
    for this_stc in stcs:
        stc_avg += this_stc.data
    stc_avg /= len(stcs)

    # compare it to the solution using evoked with fixed orientation
    filters = make_lcmv(evoked.info, forward_fixed, data_cov, reg=0.01,
                        noise_cov=noise_cov)
    stc_fixed = apply_lcmv(evoked, filters, max_ori_out='signed')
    assert_array_almost_equal(stc_avg, stc_fixed.data)

    # use a label so we have few source vertices and delayed computation is
    # not used
    filters = make_lcmv(epochs.info, forward_fixed, data_cov, reg=0.01,
                        noise_cov=noise_cov, label=label)
    stcs_label = apply_lcmv_epochs(epochs, filters, max_ori_out='signed')

    assert_array_almost_equal(stcs_label[0].data, stcs[0].in_label(label).data)

    # Test condition where the filters weights are zero. There should not be
    # any divide-by-zero errors
    zero_cov = data_cov.copy()
    zero_cov['data'][:] = 0
    filters = make_lcmv(epochs.info, forward_fixed, zero_cov, reg=0.01,
                        noise_cov=noise_cov)
    assert_array_equal(filters['weights'], 0)

    # Test condition where one channel type is picked
    # (avoid "grad data rank (13) did not match the noise rank (None)")
    data_cov_grad = pick_channels_cov(
        data_cov, [ch_name for ch_name in epochs.info['ch_names']
                   if ch_name.endswith(('2', '3'))])
    assert len(data_cov_grad['names']) > 4
    make_lcmv(epochs.info, forward_fixed, data_cov_grad, reg=0.01,
              noise_cov=noise_cov)
Example #28
0
def test_lcmv_vector():
    """Test vector LCMV solutions."""
    info = mne.io.read_raw_fif(fname_raw).info

    # For speed and for rank-deficiency calculation simplicity,
    # just use grads
    info = mne.pick_info(info, mne.pick_types(info, meg='grad', exclude=()))
    info.update(bads=[], projs=[])

    forward = mne.read_forward_solution(fname_fwd)
    forward = mne.pick_channels_forward(forward, info['ch_names'])
    vertices = [s['vertno'][::100] for s in forward['src']]
    n_vertices = sum(len(v) for v in vertices)
    assert 5 < n_vertices < 20

    amplitude = 100e-9
    stc = mne.SourceEstimate(amplitude * np.eye(n_vertices), vertices,
                             0, 1. / info['sfreq'])
    forward_sim = mne.convert_forward_solution(forward, force_fixed=True,
                                               use_cps=True, copy=True)
    forward_sim = mne.forward.restrict_forward_to_stc(forward_sim, stc)
    noise_cov = mne.make_ad_hoc_cov(info)
    noise_cov.update(data=np.diag(noise_cov['data']), diag=False)
    evoked = simulate_evoked(forward_sim, stc, info, noise_cov, nave=1)
    source_nn = forward_sim['source_nn']
    source_rr = forward_sim['source_rr']

    # Figure out our indices
    mask = np.concatenate([np.in1d(s['vertno'], v)
                           for s, v in zip(forward['src'], vertices)])
    mapping = np.where(mask)[0]
    assert_array_equal(source_rr, forward['source_rr'][mapping])

    # Don't check NN because we didn't rotate to surf ori
    del forward_sim

    # Let's do minimum norm as a sanity check (dipole_fit is slower)
    inv = make_inverse_operator(info, forward, noise_cov, loose=1.)
    stc_vector_mne = apply_inverse(evoked, inv, pick_ori='vector')
    mne_ori = stc_vector_mne.data[mapping, :, np.arange(n_vertices)]
    mne_ori /= np.linalg.norm(mne_ori, axis=-1)[:, np.newaxis]
    mne_angles = np.rad2deg(np.arccos(np.sum(mne_ori * source_nn, axis=-1)))
    assert np.mean(mne_angles) < 35

    # Now let's do LCMV
    data_cov = mne.make_ad_hoc_cov(info)  # just a stub for later
    with pytest.raises(ValueError, match="pick_ori"):
        make_lcmv(info, forward, data_cov, 0.05, noise_cov, pick_ori='bad')

    lcmv_ori = list()
    for ti in range(n_vertices):
        this_evoked = evoked.copy().crop(evoked.times[ti], evoked.times[ti])
        data_cov['diag'] = False
        data_cov['data'] = (np.outer(this_evoked.data, this_evoked.data) +
                            noise_cov['data'])
        vals = linalg.svdvals(data_cov['data'])
        assert vals[0] / vals[-1] < 1e5  # not rank deficient

        with catch_logging() as log:
            filters = make_lcmv(info, forward, data_cov, 0.05, noise_cov,
                                verbose=True)
        log = log.getvalue()
        assert '498 sources' in log
        with catch_logging() as log:
            filters_vector = make_lcmv(info, forward, data_cov, 0.05,
                                       noise_cov, pick_ori='vector',
                                       verbose=True)
        log = log.getvalue()
        assert '498 sources' in log
        stc = apply_lcmv(this_evoked, filters)
        stc_vector = apply_lcmv(this_evoked, filters_vector)
        assert isinstance(stc, mne.SourceEstimate)
        assert isinstance(stc_vector, mne.VectorSourceEstimate)
        assert_allclose(stc.data, stc_vector.magnitude().data)

        # Check the orientation by pooling across some neighbors, as LCMV can
        # have some "holes" at the points of interest
        idx = np.where(cdist(forward['source_rr'], source_rr[[ti]]) < 0.02)[0]
        lcmv_ori.append(np.mean(stc_vector.data[idx, :, 0], axis=0))
        lcmv_ori[-1] /= np.linalg.norm(lcmv_ori[-1])

    lcmv_angles = np.rad2deg(np.arccos(np.sum(lcmv_ori * source_nn, axis=-1)))
    assert np.mean(lcmv_angles) < 55
Example #29
0
def test_lcmv_vector():
    """Test vector LCMV solutions."""
    info = mne.io.read_raw_fif(fname_raw).info
    # For speed and for rank-deficiency calculation simplicity,
    # just use grads:
    info = mne.pick_info(info, mne.pick_types(info, meg='grad', exclude=()))
    info.update(bads=[], projs=[])
    forward = mne.read_forward_solution(fname_fwd)
    forward = mne.pick_channels_forward(forward, info['ch_names'])
    vertices = [s['vertno'][::100] for s in forward['src']]
    n_vertices = sum(len(v) for v in vertices)
    assert 5 < n_vertices < 20
    amplitude = 100e-9
    stc = mne.SourceEstimate(amplitude * np.eye(n_vertices), vertices,
                             0, 1. / info['sfreq'])
    forward_sim = mne.convert_forward_solution(forward, force_fixed=True,
                                               use_cps=True, copy=True)
    forward_sim = mne.forward.restrict_forward_to_stc(forward_sim, stc)
    noise_cov = mne.make_ad_hoc_cov(info)
    noise_cov.update(data=np.diag(noise_cov['data']), diag=False)
    evoked = simulate_evoked(forward_sim, stc, info, noise_cov, nave=1)
    source_nn = forward_sim['source_nn']
    source_rr = forward_sim['source_rr']
    # Figure out our indices
    mask = np.concatenate([np.in1d(s['vertno'], v)
                           for s, v in zip(forward['src'], vertices)])
    mapping = np.where(mask)[0]
    assert_array_equal(source_rr, forward['source_rr'][mapping])
    # Don't check NN because we didn't rotate to surf ori
    del forward_sim

    #
    # Let's do minimum norm as a sanity check (dipole_fit is slower)
    #
    inv = make_inverse_operator(info, forward, noise_cov, loose=1.)
    stc_vector_mne = apply_inverse(evoked, inv, pick_ori='vector')
    mne_ori = stc_vector_mne.data[mapping, :, np.arange(n_vertices)]
    mne_ori /= np.linalg.norm(mne_ori, axis=-1)[:, np.newaxis]
    mne_angles = np.rad2deg(np.arccos(np.sum(mne_ori * source_nn, axis=-1)))
    assert np.mean(mne_angles) < 35

    #
    # Now let's do LCMV
    #
    data_cov = mne.make_ad_hoc_cov(info)  # just a stub for later
    with pytest.raises(ValueError, match='pick_ori must be one of'):
        make_lcmv(info, forward, data_cov, 0.05, noise_cov, pick_ori='bad')
    lcmv_ori = list()
    for ti in range(n_vertices):
        this_evoked = evoked.copy().crop(evoked.times[ti], evoked.times[ti])
        data_cov['data'] = (np.outer(this_evoked.data, this_evoked.data) +
                            noise_cov['data'])
        vals = linalg.svdvals(data_cov['data'])
        assert vals[0] / vals[-1] < 1e5  # not rank deficient
        filters = make_lcmv(info, forward, data_cov, 0.05, noise_cov)
        filters_vector = make_lcmv(info, forward, data_cov, 0.05, noise_cov,
                                   pick_ori='vector')
        stc = apply_lcmv(this_evoked, filters)
        assert isinstance(stc, mne.SourceEstimate)
        stc_vector = apply_lcmv(this_evoked, filters_vector)
        assert isinstance(stc_vector, mne.VectorSourceEstimate)
        assert_allclose(stc.data, stc_vector.magnitude().data)
        # Check the orientation by pooling across some neighbors, as LCMV can
        # have some "holes" at the points of interest
        idx = np.where(cdist(forward['source_rr'], source_rr[[ti]]) < 0.02)[0]
        lcmv_ori.append(np.mean(stc_vector.data[idx, :, 0], axis=0))
        lcmv_ori[-1] /= np.linalg.norm(lcmv_ori[-1])

    lcmv_angles = np.rad2deg(np.arccos(np.sum(lcmv_ori * source_nn, axis=-1)))
    assert np.mean(lcmv_angles) < 55
Example #30
0
# possible to set both parameters to ``None``.
#
#
# Compute the spatial filter
# --------------------------
# Now we can compute the spatial filter. We'll use a unit-noise gain beamformer
# to deal with depth bias, and will also optimize the orientation of the
# sources such that output power is maximized.
# This is achieved by setting ``pick_ori='max-power'``.
# This gives us one source estimate per source (i.e., voxel), which is known
# as a scalar beamformer.

filters = make_lcmv(evoked.info,
                    forward,
                    data_cov,
                    reg=0.05,
                    noise_cov=noise_cov,
                    pick_ori='max-power',
                    weight_norm='unit-noise-gain',
                    rank=None)

# You can save the filter for later use with:
# filters.save('filters-lcmv.h5')

###############################################################################
# It is also possible to compute a vector beamformer, which gives back three
# estimates per voxel, corresponding to the three direction components of the
# source. This can be achieved by setting
# ``pick_ori='vector'`` and will yield a :class:`volume vector source estimate
# <mne.VolVectorSourceEstimate>`. So we will compute another set of filters
# using the vector beamformer approach:
Example #31
0
                               info,
                               mag=0.1,
                               grad=0.1,
                               eeg=0.1,
                               rank='info')

##############################################################################
# Compute LCMV filters with different data covariance matrices
# ------------------------------------------------------------

# compute LCMV beamformer filters for pre-stimulus interval
filters_pre = make_lcmv(info,
                        forward,
                        cov_pre,
                        reg=0.05,
                        noise_cov=noise_cov,
                        pick_ori=None,
                        rank=None,
                        weight_norm=None,
                        reduce_rank=False,
                        verbose=False)

# compute LCMV beamformer filters for post-stimulus interval
filters_post = make_lcmv(info,
                         forward,
                         cov_post,
                         reg=0.05,
                         noise_cov=noise_cov,
                         pick_ori=None,
                         rank=None,
                         weight_norm=None,
                         reduce_rank=False,
Example #32
0
def test_lcmv():
    """Test LCMV with evoked data and single trials."""
    raw, epochs, evoked, data_cov, noise_cov, label, forward,\
        forward_surf_ori, forward_fixed, forward_vol = _get_data()

    for fwd in [forward, forward_vol]:
        filters = make_lcmv(evoked.info, fwd, data_cov, reg=0.01,
                            noise_cov=noise_cov)
        stc = apply_lcmv(evoked, filters, max_ori_out='signed')
        stc.crop(0.02, None)

        stc_pow = np.sum(np.abs(stc.data), axis=1)
        idx = np.argmax(stc_pow)
        max_stc = stc.data[idx]
        tmax = stc.times[np.argmax(max_stc)]

        assert 0.09 < tmax < 0.12, tmax
        assert 0.9 < np.max(max_stc) < 3., np.max(max_stc)

        if fwd is forward:
            # Test picking normal orientation (surface source space only)
            filters = make_lcmv(evoked.info, forward_surf_ori, data_cov,
                                reg=0.01, noise_cov=noise_cov,
                                pick_ori='normal')
            stc_normal = apply_lcmv(evoked, filters, max_ori_out='signed')
            stc_normal.crop(0.02, None)

            stc_pow = np.sum(np.abs(stc_normal.data), axis=1)
            idx = np.argmax(stc_pow)
            max_stc = stc_normal.data[idx]
            tmax = stc_normal.times[np.argmax(max_stc)]

            assert 0.04 < tmax < 0.12, tmax
            assert 0.4 < np.max(max_stc) < 2., np.max(max_stc)

            # The amplitude of normal orientation results should always be
            # smaller than free orientation results
            assert (np.abs(stc_normal.data) <= stc.data).all()

        # Test picking source orientation maximizing output source power
        filters = make_lcmv(evoked.info, fwd, data_cov, reg=0.01,
                            noise_cov=noise_cov, pick_ori='max-power')
        stc_max_power = apply_lcmv(evoked, filters, max_ori_out='signed')
        stc_max_power.crop(0.02, None)
        stc_pow = np.sum(np.abs(stc_max_power.data), axis=1)
        idx = np.argmax(stc_pow)
        max_stc = np.abs(stc_max_power.data[idx])
        tmax = stc.times[np.argmax(max_stc)]

        assert 0.08 < tmax < 0.12, tmax
        assert 0.8 < np.max(max_stc) < 3., np.max(max_stc)

        stc_max_power.data[:, :] = np.abs(stc_max_power.data)

        if fwd is forward:
            # Maximum output source power orientation results should be
            # similar to free orientation results in areas with channel
            # coverage
            label = mne.read_label(fname_label)
            mean_stc = stc.extract_label_time_course(label, fwd['src'],
                                                     mode='mean')
            mean_stc_max_pow = \
                stc_max_power.extract_label_time_course(label, fwd['src'],
                                                        mode='mean')
            assert_array_less(np.abs(mean_stc - mean_stc_max_pow), 0.6)

        # Test NAI weight normalization:
        filters = make_lcmv(evoked.info, fwd, data_cov, reg=0.01,
                            noise_cov=noise_cov, pick_ori='max-power',
                            weight_norm='nai')
        stc_nai = apply_lcmv(evoked, filters, max_ori_out='signed')
        stc_nai.crop(0.02, None)

        # Test whether unit-noise-gain solution is a scaled version of NAI
        pearsoncorr = np.corrcoef(np.concatenate(np.abs(stc_nai.data)),
                                  np.concatenate(stc_max_power.data))
        assert_almost_equal(pearsoncorr[0, 1], 1.)

    # Test sphere head model with unit-noise gain beamformer and orientation
    # selection and rank reduction of the leadfield
    sphere = mne.make_sphere_model(r0=(0., 0., 0.), head_radius=0.080)
    src = mne.setup_volume_source_space(subject=None, pos=15., mri=None,
                                        sphere=(0.0, 0.0, 0.0, 80.0),
                                        bem=None, mindist=5.0, exclude=2.0)

    fwd_sphere = mne.make_forward_solution(evoked.info, trans=None, src=src,
                                           bem=sphere, eeg=False, meg=True)

    # Test that we get an error if not reducing rank
    pytest.raises(ValueError, make_lcmv, evoked.info, fwd_sphere, data_cov,
                  reg=0.1, noise_cov=noise_cov, weight_norm='unit-noise-gain',
                  pick_ori='max-power', reduce_rank=False)

    # Now let's reduce it
    filters = make_lcmv(evoked.info, fwd_sphere, data_cov, reg=0.1,
                        noise_cov=noise_cov, weight_norm='unit-noise-gain',
                        pick_ori='max-power', reduce_rank=True)
    stc_sphere = apply_lcmv(evoked, filters, max_ori_out='signed')
    stc_sphere = np.abs(stc_sphere)
    stc_sphere.crop(0.02, None)

    stc_pow = np.sum(stc_sphere.data, axis=1)
    idx = np.argmax(stc_pow)
    max_stc = stc_sphere.data[idx]
    tmax = stc_sphere.times[np.argmax(max_stc)]

    assert 0.08 < tmax < 0.15, tmax
    assert 0.4 < np.max(max_stc) < 2., np.max(max_stc)

    # Test if spatial filter contains src_type
    assert 'src_type' in filters

    # Test if fixed forward operator is detected when picking normal or
    # max-power orientation
    pytest.raises(ValueError, make_lcmv, evoked.info, forward_fixed, data_cov,
                  reg=0.01, noise_cov=noise_cov, pick_ori='normal')
    pytest.raises(ValueError, make_lcmv, evoked.info, forward_fixed, data_cov,
                  reg=0.01, noise_cov=noise_cov, pick_ori='max-power')

    # Test if non-surface oriented forward operator is detected when picking
    # normal orientation
    pytest.raises(ValueError, make_lcmv, evoked.info, forward, data_cov,
                  reg=0.01, noise_cov=noise_cov, pick_ori='normal')

    # Test if volume forward operator is detected when picking normal
    # orientation
    pytest.raises(ValueError, make_lcmv, evoked.info, forward_vol, data_cov,
                  reg=0.01, noise_cov=noise_cov, pick_ori='normal')

    # Test if missing of noise covariance matrix is detected when more than
    # one channel type is present in the data
    pytest.raises(ValueError, make_lcmv, evoked.info, forward_vol,
                  data_cov=data_cov, reg=0.01, noise_cov=None,
                  pick_ori='max-power')

    # Test if not-yet-implemented orientation selections raise error with
    # neural activity index
    pytest.raises(NotImplementedError, make_lcmv, evoked.info,
                  forward_surf_ori, data_cov, reg=0.01, noise_cov=noise_cov,
                  pick_ori='normal', weight_norm='nai')
    pytest.raises(NotImplementedError, make_lcmv, evoked.info, forward_vol,
                  data_cov, reg=0.01, noise_cov=noise_cov, pick_ori=None,
                  weight_norm='nai')

    # Test if no weight-normalization and max-power source orientation throws
    # an error
    pytest.raises(NotImplementedError, make_lcmv, evoked.info, forward_vol,
                  data_cov, reg=0.01, noise_cov=noise_cov,
                  pick_ori='max-power', weight_norm=None)

    # Test if wrong channel selection is detected in application of filter
    evoked_ch = deepcopy(evoked)
    evoked_ch.pick_channels(evoked_ch.ch_names[1:])
    filters = make_lcmv(evoked.info, forward_vol, data_cov, reg=0.01,
                        noise_cov=noise_cov)
    pytest.raises(ValueError, apply_lcmv, evoked_ch, filters,
                  max_ori_out='signed')

    # Test if discrepancies in channel selection of data and fwd model are
    # handled correctly in apply_lcmv
    # make filter with data where first channel was removed
    filters = make_lcmv(evoked_ch.info, forward_vol, data_cov, reg=0.01,
                        noise_cov=noise_cov)
    # applying that filter to the full data set should automatically exclude
    # this channel from the data
    # also test here that no warnings are thrown - implemented to check whether
    # src should not be None warning occurs
    with pytest.warns(None) as w:
        stc = apply_lcmv(evoked, filters, max_ori_out='signed')
    assert len(w) == 0
    # the result should be equal to applying this filter to a dataset without
    # this channel:
    stc_ch = apply_lcmv(evoked_ch, filters, max_ori_out='signed')
    assert_array_almost_equal(stc.data, stc_ch.data)

    # Test if non-matching SSP projection is detected in application of filter
    raw_proj = deepcopy(raw)
    raw_proj.del_proj()
    pytest.raises(ValueError, apply_lcmv_raw, raw_proj, filters,
                  max_ori_out='signed')

    # Test if setting reduce_rank to True returns a NotImplementedError
    # when no orientation selection is done or pick_ori='normal'
    pytest.raises(NotImplementedError, make_lcmv, evoked.info, forward_vol,
                  data_cov, noise_cov=noise_cov, pick_ori=None,
                  weight_norm='nai', reduce_rank=True)
    pytest.raises(NotImplementedError, make_lcmv, evoked.info,
                  forward_surf_ori, data_cov, noise_cov=noise_cov,
                  pick_ori='normal', weight_norm='nai', reduce_rank=True)

    # Test if spatial filter contains src_type
    assert 'src_type' in filters

    # check whether a filters object without src_type throws expected warning
    del filters['src_type']  # emulate 0.16 behaviour to cause warning
    with pytest.warns(RuntimeWarning, match='spatial filter does not contain '
                      'src_type'):
        apply_lcmv(evoked, filters, max_ori_out='signed')

    # Now test single trial using fixed orientation forward solution
    # so we can compare it to the evoked solution
    filters = make_lcmv(epochs.info, forward_fixed, data_cov, reg=0.01,
                        noise_cov=noise_cov)
    stcs = apply_lcmv_epochs(epochs, filters, max_ori_out='signed')
    stcs_ = apply_lcmv_epochs(epochs, filters, return_generator=True,
                              max_ori_out='signed')
    assert_array_equal(stcs[0].data, advance_iterator(stcs_).data)

    epochs.drop_bad()
    assert (len(epochs.events) == len(stcs))

    # average the single trial estimates
    stc_avg = np.zeros_like(stcs[0].data)
    for this_stc in stcs:
        stc_avg += this_stc.data
    stc_avg /= len(stcs)

    # compare it to the solution using evoked with fixed orientation
    filters = make_lcmv(evoked.info, forward_fixed, data_cov, reg=0.01,
                        noise_cov=noise_cov)
    stc_fixed = apply_lcmv(evoked, filters, max_ori_out='signed')
    assert_array_almost_equal(stc_avg, stc_fixed.data)

    # use a label so we have few source vertices and delayed computation is
    # not used
    filters = make_lcmv(epochs.info, forward_fixed, data_cov, reg=0.01,
                        noise_cov=noise_cov, label=label)
    stcs_label = apply_lcmv_epochs(epochs, filters, max_ori_out='signed')

    assert_array_almost_equal(stcs_label[0].data, stcs[0].in_label(label).data)
epochs = mne.Epochs(raw, events=events, tmin=0, tmax=5.,
                    baseline=None, reject=dict(mag=8e-13), preload=True)
del raw

##############################################################################
# Compute the forward and inverse
# -------------------------------

# This source space is really far too coarse, but we do this for speed
# considerations here
pos = 15.  # 1.5 cm is very broad, done here for speed!
src = mne.setup_volume_source_space('bst_resting', pos, bem=bem,
                                    subjects_dir=subjects_dir, verbose=True)
fwd = mne.make_forward_solution(epochs.info, trans, src, bem)
data_cov = mne.compute_covariance(epochs)
filters = make_lcmv(epochs.info, fwd, data_cov, 0.05, cov,
                    pick_ori='max-power', weight_norm='nai')
del fwd

##############################################################################
# Compute label time series and do envelope correlation
# -----------------------------------------------------

epochs.apply_hilbert()  # faster to do in sensor space
stcs = apply_lcmv_epochs(epochs, filters, return_generator=True)
corr = envelope_correlation(stcs, verbose=True)

##############################################################################
# Compute the degree and plot it
# ------------------------------

degree = mne.connectivity.degree(corr, 0.15)
Example #34
0
# -------------------------------

# This source space is really far too coarse, but we do this for speed
# considerations here
pos = 15.  # 1.5 cm is very broad, done here for speed!
src = mne.setup_volume_source_space('bst_resting',
                                    pos,
                                    bem=bem,
                                    subjects_dir=subjects_dir,
                                    verbose=True)
fwd = mne.make_forward_solution(epochs.info, trans, src, bem)
data_cov = mne.compute_covariance(epochs)
filters = make_lcmv(epochs.info,
                    fwd,
                    data_cov,
                    0.05,
                    cov,
                    pick_ori='max-power',
                    weight_norm='nai')
del fwd

##############################################################################
# Compute label time series and do envelope correlation
# -----------------------------------------------------

epochs.apply_hilbert()  # faster to do in sensor space
stcs = apply_lcmv_epochs(epochs, filters, return_generator=True)
corr = envelope_correlation(stcs, verbose=True)

##############################################################################
# Compute the degree and plot it
Example #35
0
def test_lcmv_reg_proj(proj, weight_norm):
    """Test LCMV with and without proj."""
    raw = mne.io.read_raw_fif(fname_raw, preload=True)
    events = mne.find_events(raw)
    raw.pick_types(meg=True)
    assert len(raw.ch_names) == 305
    epochs = mne.Epochs(raw, events, None, preload=True, proj=proj)
    with pytest.warns(RuntimeWarning, match='Too few samples'):
        noise_cov = mne.compute_covariance(epochs, tmax=0)
        data_cov = mne.compute_covariance(epochs, tmin=0.04, tmax=0.15)
    forward = mne.read_forward_solution(fname_fwd)
    filters = make_lcmv(epochs.info, forward, data_cov, reg=0.05,
                        noise_cov=noise_cov, pick_ori='max-power',
                        weight_norm='nai', rank=None, verbose=True)
    want_rank = 302  # 305 good channels - 3 MEG projs
    assert filters['rank'] == want_rank
    # And also with and without noise_cov
    with pytest.raises(ValueError, match='several sensor types'):
        make_lcmv(epochs.info, forward, data_cov, reg=0.05,
                  noise_cov=None)
    epochs.pick_types(meg='grad')
    kwargs = dict(reg=0.05, pick_ori=None, weight_norm=weight_norm)
    filters_cov = make_lcmv(epochs.info, forward, data_cov,
                            noise_cov=noise_cov, **kwargs)
    filters_nocov = make_lcmv(epochs.info, forward, data_cov,
                              noise_cov=None, **kwargs)
    ad_hoc = mne.make_ad_hoc_cov(epochs.info)
    filters_adhoc = make_lcmv(epochs.info, forward, data_cov,
                              noise_cov=ad_hoc, **kwargs)
    evoked = epochs.average()
    stc_cov = apply_lcmv(evoked, filters_cov)
    stc_nocov = apply_lcmv(evoked, filters_nocov)
    stc_adhoc = apply_lcmv(evoked, filters_adhoc)

    # Compare adhoc and nocov: scale difference is necessitated by using std=1.
    if weight_norm == 'unit-noise-gain':
        scale = np.sqrt(ad_hoc['data'][0])
    else:
        scale = 1.
    assert_allclose(stc_nocov.data, stc_adhoc.data * scale)
    a = np.dot(filters_nocov['weights'], filters_nocov['whitener'])
    b = np.dot(filters_adhoc['weights'], filters_adhoc['whitener']) * scale
    atol = np.mean(np.sqrt(a * a)) * 1e-7
    assert_allclose(a, b, atol=atol, rtol=1e-7)

    # Compare adhoc and cov: locs might not be equivalent, but the same
    # general profile should persist, so look at the std and be lenient:
    if weight_norm == 'unit-noise-gain':
        adhoc_scale = 0.12
    else:
        adhoc_scale = 1.
    assert_allclose(
        np.linalg.norm(stc_adhoc.data, axis=0) * adhoc_scale,
        np.linalg.norm(stc_cov.data, axis=0), rtol=0.3)
    assert_allclose(
        np.linalg.norm(stc_nocov.data, axis=0) / scale * adhoc_scale,
        np.linalg.norm(stc_cov.data, axis=0), rtol=0.3)

    if weight_norm == 'nai':
        # NAI is always normalized by noise-level (based on eigenvalues)
        for stc in (stc_nocov, stc_cov):
            assert_allclose(stc.data.std(), 0.584, rtol=0.2)
    elif weight_norm is None:
        # None always represents something not normalized, reflecting channel
        # weights
        for stc in (stc_nocov, stc_cov):
            assert_allclose(stc.data.std(), 2.8e-8, rtol=0.1)
    else:
        assert weight_norm == 'unit-noise-gain'
        # Channel scalings depend on presence of noise_cov
        assert_allclose(stc_nocov.data.std(), 7.8e-13, rtol=0.1)
        assert_allclose(stc_cov.data.std(), 0.187, rtol=0.2)
Example #36
0
names = ['free', 'normal', 'max-power']
descriptions = [
    'Free orientation, voxel: %i', 'Normal orientation, voxel: %i',
    'Max-power orientation, voxel: %i'
]
colors = ['b', 'k', 'r']

fig, ax = plt.subplots(1)
max_voxs = list()
for pick_ori, name, desc, color in zip(pick_oris, names, descriptions, colors):
    # compute unit-noise-gain beamformer with whitening of the leadfield and
    # data (enabled by passing a noise covariance matrix)
    filters = make_lcmv(evoked.info,
                        forward,
                        data_cov,
                        reg=0.05,
                        noise_cov=noise_cov,
                        pick_ori=pick_ori,
                        weight_norm='unit-noise-gain',
                        rank=None)
    print(filters)
    # apply this spatial filter to source-reconstruct the evoked data
    stc = apply_lcmv(evoked, filters, max_ori_out='signed')

    # View activation time-series in maximum voxel at 100 ms:
    time_idx = stc.time_as_index(0.1)
    max_idx = np.argmax(np.abs(stc.data[:, time_idx]))
    # we know these are all left hemi, so we can just use vertices[0]
    max_voxs.append(stc.vertices[0][max_idx])
    ax.plot(stc.times, stc.data[max_idx, :], color, label=desc % max_idx)

ax.set(xlabel='Time (ms)', ylabel='LCMV value', title='LCMV in maximum voxel')
Example #37
0
def test_lcmv():
    """Test LCMV with evoked data and single trials."""
    raw, epochs, evoked, data_cov, noise_cov, label, forward,\
        forward_surf_ori, forward_fixed, forward_vol = _get_data()

    for fwd in [forward, forward_vol]:
        stc = lcmv(evoked, fwd, noise_cov, data_cov, reg=0.01,
                   max_ori_out='signed')
        stc.crop(0.02, None)

        stc_pow = np.sum(np.abs(stc.data), axis=1)
        idx = np.argmax(stc_pow)
        max_stc = stc.data[idx]
        tmax = stc.times[np.argmax(max_stc)]

        assert_true(0.09 < tmax < 0.105, tmax)
        assert_true(0.9 < np.max(max_stc) < 3., np.max(max_stc))

        if fwd is forward:
            # Test picking normal orientation (surface source space only)
            stc_normal = lcmv(evoked, forward_surf_ori, noise_cov,
                              data_cov, reg=0.01, pick_ori="normal",
                              max_ori_out='signed')
            stc_normal.crop(0.02, None)

            stc_pow = np.sum(np.abs(stc_normal.data), axis=1)
            idx = np.argmax(stc_pow)
            max_stc = stc_normal.data[idx]
            tmax = stc_normal.times[np.argmax(max_stc)]

            assert_true(0.04 < tmax < 0.11, tmax)
            assert_true(0.4 < np.max(max_stc) < 2., np.max(max_stc))

            # The amplitude of normal orientation results should always be
            # smaller than free orientation results
            assert_true((np.abs(stc_normal.data) <= stc.data).all())

        # Test picking source orientation maximizing output source power
        stc_max_power = lcmv(evoked, fwd, noise_cov, data_cov, reg=0.01,
                             pick_ori="max-power", max_ori_out='signed')
        stc_max_power.crop(0.02, None)
        stc_pow = np.sum(np.abs(stc_max_power.data), axis=1)
        idx = np.argmax(stc_pow)
        max_stc = np.abs(stc_max_power.data[idx])
        tmax = stc.times[np.argmax(max_stc)]

        assert_true(0.08 < tmax < 0.11, tmax)
        assert_true(0.8 < np.max(max_stc) < 3., np.max(max_stc))

        stc_max_power.data[:, :] = np.abs(stc_max_power.data)

        if fwd is forward:
            # Maximum output source power orientation results should be
            # similar to free orientation results in areas with channel
            # coverage
            label = mne.read_label(fname_label)
            mean_stc = stc.extract_label_time_course(label, fwd['src'],
                                                     mode='mean')
            mean_stc_max_pow = \
                stc_max_power.extract_label_time_course(label, fwd['src'],
                                                        mode='mean')
            assert_true((np.abs(mean_stc - mean_stc_max_pow) < 0.5).all())

        # Test NAI weight normalization:
        stc_nai = lcmv(evoked, fwd, noise_cov=noise_cov, data_cov=data_cov,
                       reg=0.01, pick_ori='max-power', weight_norm='nai',
                       max_ori_out='signed')
        stc_nai.crop(0.02, None)

        # Test whether unit-noise-gain solution is a scaled version of NAI
        pearsoncorr = np.corrcoef(np.concatenate(np.abs(stc_nai.data)),
                                  np.concatenate(stc_max_power.data))
        assert_almost_equal(pearsoncorr[0, 1], 1.)

    # Test sphere head model with unit-noise gain beamformer and orientation
    # selection and rank reduction of the leadfield
    sphere = mne.make_sphere_model(r0=(0., 0., 0.), head_radius=0.080)
    src = mne.setup_volume_source_space(subject=None, pos=15., mri=None,
                                        sphere=(0.0, 0.0, 0.0, 80.0),
                                        bem=None, mindist=5.0, exclude=2.0)

    fwd_sphere = mne.make_forward_solution(evoked.info, trans=None, src=src,
                                           bem=sphere, eeg=False, meg=True)

    # Test that we get an error is not reducing rank
    assert_raises(ValueError, lcmv, evoked, fwd_sphere, noise_cov, data_cov,
                  reg=0.1, weight_norm='unit-noise-gain', pick_ori="max-power",
                  reduce_rank=False)

    # Now let's reduce it
    stc_sphere = lcmv(evoked, fwd_sphere, noise_cov, data_cov, reg=0.1,
                      weight_norm='unit-noise-gain', pick_ori="max-power",
                      reduce_rank=True, max_ori_out='signed')
    stc_sphere = np.abs(stc_sphere)
    stc_sphere.crop(0.02, None)

    stc_pow = np.sum(stc_sphere.data, axis=1)
    idx = np.argmax(stc_pow)
    max_stc = stc_sphere.data[idx]
    tmax = stc_sphere.times[np.argmax(max_stc)]

    assert_true(0.08 < tmax < 0.11, tmax)
    assert_true(0.4 < np.max(max_stc) < 2., np.max(max_stc))

    # Test if fixed forward operator is detected when picking normal or
    # max-power orientation
    assert_raises(ValueError, lcmv, evoked, forward_fixed, noise_cov, data_cov,
                  reg=0.01, pick_ori="normal")
    assert_raises(ValueError, lcmv, evoked, forward_fixed, noise_cov, data_cov,
                  reg=0.01, pick_ori="max-power", max_ori_out='signed')

    # Test if non-surface oriented forward operator is detected when picking
    # normal orientation
    assert_raises(ValueError, lcmv, evoked, forward, noise_cov, data_cov,
                  reg=0.01, pick_ori="normal")

    # Test if volume forward operator is detected when picking normal
    # orientation
    assert_raises(ValueError, lcmv, evoked, forward_vol, noise_cov, data_cov,
                  reg=0.01, pick_ori="normal")

    # Test if missing of data covariance matrix is detected
    assert_raises(ValueError, lcmv, evoked, forward_vol, noise_cov=noise_cov,
                  data_cov=None, reg=0.01, pick_ori="max-power",
                  max_ori_out='signed')

    # Test if missing of noise covariance matrix is detected when more than
    # one channel type is present in the data
    assert_raises(ValueError, lcmv, evoked, forward_vol, noise_cov=None,
                  data_cov=data_cov, reg=0.01, pick_ori="max-power",
                  max_ori_out='signed')

    # Test if not-yet-implemented orientation selections raise error with
    # neural activity index
    assert_raises(NotImplementedError, lcmv, evoked, forward_surf_ori,
                  noise_cov, data_cov, reg=0.01, pick_ori="normal",
                  weight_norm='nai')
    assert_raises(NotImplementedError, lcmv, evoked, forward_vol, noise_cov,
                  data_cov, reg=0.01, pick_ori=None, weight_norm='nai')

    # Test if no weight-normalization and max-power source orientation throw
    # an error
    assert_raises(NotImplementedError, lcmv, evoked, forward_vol, noise_cov,
                  data_cov, reg=0.01, pick_ori="max-power", weight_norm=None,
                  max_ori_out='signed')

    # Test if wrong channel selection is detected in application of filter
    evoked_ch = deepcopy(evoked)
    evoked_ch.pick_channels(evoked_ch.ch_names[:-1])
    filters = make_lcmv(evoked.info, forward_vol, data_cov, reg=0.01,
                        noise_cov=noise_cov)
    assert_raises(ValueError, apply_lcmv, evoked_ch, filters,
                  max_ori_out='signed')

    # Test if non-matching SSP projection is detected in application of filter
    raw_proj = deepcopy(raw)
    raw_proj.del_proj()
    assert_raises(ValueError, apply_lcmv_raw, raw_proj, filters,
                  max_ori_out='signed')

    # Test if setting reduce_rank to True returns a NotImplementedError
    # when no orientation selection is done or pick_ori='normal'
    assert_raises(NotImplementedError, lcmv, evoked, forward_vol, noise_cov,
                  data_cov, pick_ori=None, weight_norm='nai', reduce_rank=True,
                  max_ori_out='signed')
    assert_raises(NotImplementedError, lcmv, evoked, forward_surf_ori,
                  noise_cov, data_cov, pick_ori='normal', weight_norm='nai',
                  reduce_rank=True, max_ori_out='signed')

    # Now test single trial using fixed orientation forward solution
    # so we can compare it to the evoked solution
    stcs = lcmv_epochs(epochs, forward_fixed, noise_cov, data_cov,
                       reg=0.01, max_ori_out='signed')
    stcs_ = lcmv_epochs(epochs, forward_fixed, noise_cov, data_cov,
                        reg=0.01, return_generator=True,
                        max_ori_out='signed')
    assert_array_equal(stcs[0].data, advance_iterator(stcs_).data)

    epochs.drop_bad()
    assert_true(len(epochs.events) == len(stcs))

    # average the single trial estimates
    stc_avg = np.zeros_like(stcs[0].data)
    for this_stc in stcs:
        stc_avg += this_stc.data
    stc_avg /= len(stcs)

    # compare it to the solution using evoked with fixed orientation
    stc_fixed = lcmv(evoked, forward_fixed, noise_cov, data_cov, reg=0.01,
                     max_ori_out='signed')
    assert_array_almost_equal(stc_avg, stc_fixed.data)

    # use a label so we have few source vertices and delayed computation is
    # not used
    stcs_label = lcmv_epochs(epochs, forward_fixed, noise_cov, data_cov,
                             reg=0.01, label=label, max_ori_out='signed')

    assert_array_almost_equal(stcs_label[0].data, stcs[0].in_label(label).data)
Example #38
0
###############################################################################
# Run beamformers and look at maximum outputs

pick_oris = [None, 'normal', 'max-power']
names = ['free', 'normal', 'max-power']
descriptions = ['Free orientation, voxel: %i', 'Normal orientation, voxel: %i',
                'Max-power orientation, voxel: %i']
colors = ['b', 'k', 'r']

fig, ax = plt.subplots(1)
max_voxs = list()
for pick_ori, name, desc, color in zip(pick_oris, names, descriptions, colors):
    # compute unit-noise-gain beamformer with whitening of the leadfield and
    # data (enabled by passing a noise covariance matrix)
    filters = make_lcmv(evoked.info, forward, data_cov, reg=0.05,
                        noise_cov=noise_cov, pick_ori=pick_ori,
                        weight_norm='unit-noise-gain', rank=None)
    print(filters)
    # apply this spatial filter to source-reconstruct the evoked data
    stc = apply_lcmv(evoked, filters, max_ori_out='signed')

    # View activation time-series in maximum voxel at 100 ms:
    time_idx = stc.time_as_index(0.1)
    max_idx = np.argmax(np.abs(stc.data[:, time_idx]))
    # we know these are all left hemi, so we can just use vertices[0]
    max_voxs.append(stc.vertices[0][max_idx])
    ax.plot(stc.times, stc.data[max_idx, :], color, label=desc % max_idx)

ax.set(xlabel='Time (ms)', ylabel='LCMV value',
       title='LCMV in maximum voxel')
ax.legend(loc='lower right')
Example #39
0
def compute_lcmv_example_data(data_path, fname=None):
    raw_fname = data_path + '/MEG/sample/sample_audvis_raw.fif'
    event_fname = data_path + '/MEG/sample/sample_audvis_raw-eve.fif'
    fname_fwd = data_path + '/MEG/sample/sample_audvis-meg-vol-7-fwd.fif'
    # Get epochs
    event_id, tmin, tmax = [1, 2], -0.2, 0.5

    # Setup for reading the raw data
    raw = mne.io.read_raw_fif(raw_fname, preload=True)
    raw.info['bads'] = ['MEG 2443', 'EEG 053']  # 2 bad channels
    events = mne.read_events(event_fname)

    # Set up pick list: gradiometers and magnetometers, excluding bad channels
    picks = mne.pick_types(raw.info, meg=True, eeg=False, stim=True, eog=True,
                           exclude='bads')

    # Pick the channels of interest
    raw.pick_channels([raw.ch_names[pick] for pick in picks])

    # Re-normalize our empty-room projectors, so they are fine after
    # subselection
    raw.info.normalize_proj()
    # Read epochs
    proj = False  # already applied
    epochs = mne.Epochs(raw, events, event_id, tmin, tmax,
                        baseline=(None, 0), preload=True, proj=proj,
                        reject=dict(grad=4000e-13, mag=4e-12, eog=150e-6))
    evoked = epochs.average()

    # Read regularized noise covariance and compute regularized data covariance
    noise_cov = mne.compute_covariance(epochs, tmin=tmin, tmax=0,
                                       method='shrunk')
    data_cov = mne.compute_covariance(epochs, tmin=0.04, tmax=0.15,
                                      method='shrunk')
    # Read forward model
    forward = mne.read_forward_solution(fname_fwd)

    # Compute weights of free orientation (vector) beamformer with weight
    # normalization (neural activity index, NAI). Providing a noise covariance
    # matrix enables whitening of the data and forward solution. Source
    # orientation is optimized by setting pick_ori to 'max-power'.
    # weight_norm can also be set to 'unit-noise-gain'. Source orientation can
    # also be 'normal' (but only when using a surface-based source space) or
    # None, which computes a vector beamfomer. Note, however, that not all
    # combinations of orientation selection and weight normalization are
    # implemented yet.
    filters = make_lcmv(evoked.info, forward, data_cov, reg=0.05,
                        noise_cov=noise_cov, pick_ori='max-power',
                        weight_norm='nai')

    # Apply this spatial filter to the evoked data.
    stc = apply_lcmv(evoked, filters, max_ori_out='signed')

    # take absolute values for plotting
    stc.data[:, :] = np.abs(stc.data)

    # Save result in stc files if desired
    if fname is not None:
        stc.save('lcmv-vol')

    # select time window (tmin, tmax) in ms - consider changing for real data
    # scenario, since those values were chosen to optimize computation time
    stc.crop(0.087, 0.087)

    src = forward['src']

    # Save result in a 4D nifti file
    img = mne.save_stc_as_volume(fname, stc, src,
                                 mri_resolution=True)

    return img, stc, src
# Read regularized noise covariance and compute regularized data covariance
noise_cov = mne.compute_covariance(epochs, tmin=tmin, tmax=0, method='shrunk',
                                   rank=None)
data_cov = mne.compute_covariance(epochs, tmin=0.04, tmax=0.15,
                                  method='shrunk', rank=None)

# Compute weights of free orientation (vector) beamformer with weight
# normalization (neural activity index, NAI). Providing a noise covariance
# matrix enables whitening of the data and forward solution. Source orientation
# is optimized by setting pick_ori to 'max-power'.
# weight_norm can also be set to 'unit-noise-gain'. Source orientation can also
# be 'normal' (but only when using a surface-based source space) or None,
# which computes a vector beamfomer. Note, however, that not all combinations
# of orientation selection and weight normalization are implemented yet.
filters = make_lcmv(evoked.info, forward, data_cov, reg=0.05,
                    noise_cov=noise_cov, pick_ori='max-power',
                    weight_norm='nai', rank=None)
print(filters)

# You can save these with:
# filters.save('filters-lcmv.h5')

# Apply this spatial filter to the evoked data.
stc = apply_lcmv(evoked, filters, max_ori_out='signed')

###############################################################################
# Plot source space activity:

# You can save result in stc files with:
# stc.save('lcmv-vol')