예제 #1
0
def test_make_dics_rank(_load_forward, idx, whiten):
    """Test making DICS beamformer filters with rank param."""
    _, fwd_surf, fwd_fixed, _ = _load_forward
    epochs, _, csd, _, label, _, _ = _simulate_data(fwd_fixed, idx)
    if whiten:
        noise_csd, want_rank = _make_rand_csd(epochs.info, csd)
        kind = 'mag + grad'
    else:
        noise_csd = None
        epochs.pick_types(meg='grad')
        want_rank = len(epochs.ch_names)
        assert want_rank == 41
        kind = 'grad'

    with catch_logging() as log:
        filters = make_dics(epochs.info,
                            fwd_surf,
                            csd,
                            label=label,
                            noise_csd=noise_csd,
                            verbose=True)
    log = log.getvalue()
    assert f'Estimated rank ({kind}): {want_rank}' in log, log
    stc, _ = apply_dics_csd(csd, filters)
    other_rank = want_rank - 1  # shouldn't make a huge difference
    use_rank = dict(meg=other_rank)
    if not whiten:
        # XXX it's a bug that our rank functions don't treat "meg"
        # properly here...
        use_rank['grad'] = use_rank.pop('meg')
    with catch_logging() as log:
        filters_2 = make_dics(epochs.info,
                              fwd_surf,
                              csd,
                              label=label,
                              noise_csd=noise_csd,
                              rank=use_rank,
                              verbose=True)
    log = log.getvalue()
    assert f'Computing rank from covariance with rank={use_rank}' in log, log
    stc_2, _ = apply_dics_csd(csd, filters_2)
    corr = np.corrcoef(stc_2.data.ravel(), stc.data.ravel())[0, 1]
    assert 0.8 < corr < 0.99999

    # degenerate conditions
    if whiten:
        # make rank deficient
        data = noise_csd.get_data(0.)
        data[0] = data[:0] = 0
        noise_csd._data[:, 0] = _sym_mat_to_vector(data)
        with pytest.raises(ValueError, match='meg data rank.*the noise rank'):
            filters = make_dics(epochs.info,
                                fwd_surf,
                                csd,
                                label=label,
                                noise_csd=noise_csd,
                                verbose=True)
예제 #2
0
def test_real(_load_forward):
    """Test using a real-valued filter."""
    fwd_free, fwd_surf, fwd_fixed, fwd_vol, label = _load_forward
    epochs, _, csd, source_vertno = _simulate_data(fwd_fixed)
    vertices = np.intersect1d(label.vertices, fwd_free['src'][0]['vertno'])
    source_ind = vertices.tolist().index(source_vertno)
    rr_want = fwd_free['src'][0]['rr'][source_vertno]
    epochs.pick_types('grad')
    reg = 1  # Lots of regularization for our toy dataset
    filters_real = make_dics(epochs.info,
                             fwd_surf,
                             csd,
                             label=label,
                             reg=reg,
                             real_filter=True)
    # Also test here that no warings are thrown - implemented to check whether
    # src should not be None warning occurs:
    with pytest.warns(None) as w:
        power, f = apply_dics_csd(csd, filters_real)
    assert len(w) == 0

    assert f == [10, 20]
    assert np.argmax(power.data[:, 1]) == source_ind
    assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Test rank reduction
    filters_real = make_dics(epochs.info,
                             fwd_surf,
                             csd,
                             label=label,
                             reg=5,
                             pick_ori='max-power',
                             inversion='matrix',
                             reduce_rank=True)
    power, f = apply_dics_csd(csd, filters_real)
    assert f == [10, 20]
    idx = np.argmax(power.data[:, 1])
    rr_got = fwd_free['src'][0]['rr'][vertices[idx]]
    dist = np.linalg.norm(rr_got - rr_want)
    assert dist <= 0.02
    assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Test computing source power on a volume source space
    filters_vol = make_dics(epochs.info, fwd_vol, csd, reg=reg)
    power, f = apply_dics_csd(csd, filters_vol)
    vol_source_ind = 3851  # FIXME: not make this hardcoded
    assert f == [10, 20]
    assert np.argmax(power.data[:, 1]) == vol_source_ind
    assert power.data[vol_source_ind, 1] > power.data[vol_source_ind, 0]

    # check whether a filters object without src_type throws expected warning
    del filters_vol['src_type']  # emulate 0.16 behaviour to cause warning
    with pytest.warns(RuntimeWarning,
                      match='spatial filter does not contain '
                      'src_type'):
        apply_dics_csd(csd, filters_vol)
예제 #3
0
def test_real(_load_forward, idx, mat_tol, vol_tol):
    """Test using a real-valued filter."""
    fwd_free, fwd_surf, fwd_fixed, fwd_vol = _load_forward
    epochs, _, csd, source_vertno, label, vertices, source_ind = \
        _simulate_data(fwd_fixed, idx)
    epochs.pick_types('grad')
    reg = 1  # Lots of regularization for our toy dataset
    filters_real = make_dics(epochs.info,
                             fwd_surf,
                             csd,
                             label=label,
                             reg=reg,
                             real_filter=True)
    # Also test here that no warings are thrown - implemented to check whether
    # src should not be None warning occurs:
    with pytest.warns(None) as w:
        power, f = apply_dics_csd(csd, filters_real)
    assert len(w) == 0

    assert f == [10, 20]
    dist = _fwd_dist(power, fwd_surf, vertices, source_ind)
    assert dist == 0
    assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Test rank reduction
    filters_real = make_dics(epochs.info,
                             fwd_surf,
                             csd,
                             label=label,
                             reg=5,
                             pick_ori='max-power',
                             inversion='matrix',
                             reduce_rank=True)
    power, f = apply_dics_csd(csd, filters_real)
    assert f == [10, 20]
    dist = _fwd_dist(power, fwd_surf, vertices, source_ind)
    assert dist == 0
    assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Test computing source power on a volume source space
    filters_vol = make_dics(epochs.info, fwd_vol, csd, reg=reg)
    power, f = apply_dics_csd(csd, filters_vol)
    vol_source_ind = _nearest_vol_ind(fwd_vol, fwd_surf, vertices, source_ind)
    assert f == [10, 20]
    dist = _fwd_dist(power, fwd_vol, fwd_vol['src'][0]['vertno'],
                     vol_source_ind)
    assert dist <= vol_tol
    assert power.data[vol_source_ind, 1] > power.data[vol_source_ind, 0]

    # check whether a filters object without src_type throws expected warning
    del filters_vol['src_type']  # emulate 0.16 behaviour to cause warning
    with pytest.warns(RuntimeWarning,
                      match='spatial filter does not contain '
                      'src_type'):
        apply_dics_csd(csd, filters_vol)
예제 #4
0
def test_apply_dics_ori_inv(_load_forward, pick_ori, inversion):
    """Testpicking different orientations and inversion modes."""
    fwd_free, fwd_surf, fwd_fixed, fwd_vol, label = _load_forward
    epochs, _, csd, source_vertno = _simulate_data(fwd_fixed)
    epochs.pick_types('grad')
    vertices = np.intersect1d(label.vertices, fwd_free['src'][0]['vertno'])
    source_ind = vertices.tolist().index(source_vertno)
    rr_want = fwd_free['src'][0]['rr'][source_vertno]

    reg_ = 5 if inversion == 'matrix' else 1
    filters = make_dics(epochs.info,
                        fwd_surf,
                        csd,
                        label=label,
                        reg=reg_,
                        pick_ori=pick_ori,
                        inversion=inversion,
                        normalize_fwd=False,
                        weight_norm='unit-noise-gain')
    power, f = apply_dics_csd(csd, filters)
    assert f == [10, 20]
    idx = np.argmax(power.data[:, 1])
    rr_got = fwd_free['src'][0]['rr'][vertices[idx]]
    dist = np.linalg.norm(rr_got - rr_want)
    assert dist <= (0.03 if inversion == 'matrix' else 0.)
    assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Test unit-noise-gain weighting
    csd_noise = csd.copy()
    inds = np.triu_indices(csd.n_channels)
    csd_noise._data[...] = np.eye(csd.n_channels)[inds][:, np.newaxis]
    noise_power, f = apply_dics_csd(csd_noise, filters)
    assert np.allclose(noise_power.data, 1)

    # Test filter with forward normalization instead of weight
    # normalization
    filters = make_dics(epochs.info,
                        fwd_surf,
                        csd,
                        label=label,
                        reg=reg_,
                        pick_ori=pick_ori,
                        inversion=inversion,
                        weight_norm=None,
                        normalize_fwd=True)
    power, f = apply_dics_csd(csd, filters)
    assert f == [10, 20]
    idx = np.argmax(power.data[:, 1])
    rr_got = fwd_free['src'][0]['rr'][vertices[idx]]
    dist = np.linalg.norm(rr_got - rr_want)
    assert dist <= (0.035 if inversion == 'matrix' else 0.)
    assert power.data[source_ind, 1] > power.data[source_ind, 0]
def _gen_dics(active_win, baseline_win, epochs):
    freqs = np.logspace(np.log10(12), np.log10(30), 9)
    csd = csd_morlet(epochs, freqs, tmin=-1, tmax=1.5, decim=20)
    csd_baseline = csd_morlet(epochs, freqs, tmin=baseline_win[0],
                              tmax=baseline_win[1], decim=20)
    csd_ers = csd_morlet(epochs, freqs, tmin=active_win[0], tmax=active_win[1],
                         decim=20)
    filters = make_dics(epochs.info, fwd, csd.mean(), pick_ori='max-power',
                        reduce_rank=True, real_filter=True)
    stc_base, freqs = apply_dics_csd(csd_baseline.mean(), filters)
    stc_act, freqs = apply_dics_csd(csd_ers.mean(), filters)
    stc_act /= stc_base
    return stc_act
예제 #6
0
def test_apply_dics_ori_inv(_load_forward, pick_ori, inversion, idx):
    """Test picking different orientations and inversion modes."""
    fwd_free, fwd_surf, fwd_fixed, fwd_vol = _load_forward
    epochs, _, csd, source_vertno, label, vertices, source_ind = \
        _simulate_data(fwd_fixed, idx)
    epochs.pick_types(meg='grad')

    reg_ = 5 if inversion == 'matrix' else 1
    filters = make_dics(epochs.info,
                        fwd_surf,
                        csd,
                        label=label,
                        reg=reg_,
                        pick_ori=pick_ori,
                        inversion=inversion,
                        depth=None,
                        weight_norm='unit-noise-gain')
    power, f = apply_dics_csd(csd, filters)
    assert f == [10, 20]
    dist = _fwd_dist(power, fwd_surf, vertices, source_ind)
    # This is 0. for unit-noise-gain-invariant:
    assert dist <= (0.02 if inversion == 'matrix' else 0.)
    assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Test unit-noise-gain weighting
    csd_noise = csd.copy()
    inds = np.triu_indices(csd.n_channels)
    csd_noise._data[...] = np.eye(csd.n_channels)[inds][:, np.newaxis]
    noise_power, f = apply_dics_csd(csd_noise, filters)
    want_norm = 3 if pick_ori is None else 1.
    assert_allclose(noise_power.data, want_norm, atol=1e-7)

    # Test filter with forward normalization instead of weight
    # normalization
    filters = make_dics(epochs.info,
                        fwd_surf,
                        csd,
                        label=label,
                        reg=reg_,
                        pick_ori=pick_ori,
                        inversion=inversion,
                        weight_norm=None,
                        depth=1.)
    power, f = apply_dics_csd(csd, filters)
    assert f == [10, 20]
    dist = _fwd_dist(power, fwd_surf, vertices, source_ind)
    mat_tol = {0: 0.055, 100: 0.20, 200: 0.015, 233: 0.035}[idx]
    max_ = (mat_tol if inversion == 'matrix' else 0.)
    assert 0 <= dist <= max_
    assert power.data[source_ind, 1] > power.data[source_ind, 0]
예제 #7
0
def test_apply_dics_ori_inv(_load_forward, pick_ori, inversion, idx, mat_tol,
                            vol_tol):
    """Testpicking different orientations and inversion modes."""
    fwd_free, fwd_surf, fwd_fixed, fwd_vol = _load_forward
    epochs, _, csd, source_vertno, label, vertices, source_ind = \
        _simulate_data(fwd_fixed, idx)
    epochs.pick_types('grad')

    reg_ = 5 if inversion == 'matrix' else 1
    filters = make_dics(epochs.info,
                        fwd_surf,
                        csd,
                        label=label,
                        reg=reg_,
                        pick_ori=pick_ori,
                        inversion=inversion,
                        normalize_fwd=False,
                        weight_norm='unit-noise-gain')
    power, f = apply_dics_csd(csd, filters)
    assert f == [10, 20]
    dist = _fwd_dist(power, fwd_surf, vertices, source_ind)
    assert dist <= (0.03 if inversion == 'matrix' else 0.)
    assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Test unit-noise-gain weighting
    csd_noise = csd.copy()
    inds = np.triu_indices(csd.n_channels)
    csd_noise._data[...] = np.eye(csd.n_channels)[inds][:, np.newaxis]
    noise_power, f = apply_dics_csd(csd_noise, filters)
    assert np.allclose(noise_power.data, 1)

    # Test filter with forward normalization instead of weight
    # normalization
    filters = make_dics(epochs.info,
                        fwd_surf,
                        csd,
                        label=label,
                        reg=reg_,
                        pick_ori=pick_ori,
                        inversion=inversion,
                        weight_norm=None,
                        normalize_fwd=True)
    power, f = apply_dics_csd(csd, filters)
    assert f == [10, 20]
    dist = _fwd_dist(power, fwd_surf, vertices, source_ind)
    max_ = (mat_tol if inversion == 'matrix' else 0.)
    assert 0 <= dist <= max_
    assert power.data[source_ind, 1] > power.data[source_ind, 0]
예제 #8
0
def test_apply_dics_csd(_load_forward, idx, inversion, weight_norm):
    """Test applying a DICS beamformer to a CSD matrix."""
    fwd_free, fwd_surf, fwd_fixed, _ = _load_forward
    epochs, _, csd, source_vertno, label, vertices, source_ind = \
        _simulate_data(fwd_fixed, idx)
    reg = 1  # Lots of regularization for our toy dataset

    with pytest.raises(ValueError, match='several sensor types'):
        make_dics(epochs.info, fwd_free, csd)
    epochs.pick_types(meg='grad')

    # Try different types of forward models
    assert label.hemi == 'lh'
    for fwd in [fwd_free, fwd_surf, fwd_fixed]:
        filters = make_dics(epochs.info, fwd, csd, label=label, reg=reg,
                            inversion=inversion, weight_norm=weight_norm)
        power, f = apply_dics_csd(csd, filters)
        assert f == [10, 20]

        # Did we find the true source at 20 Hz?
        dist = _fwd_dist(power, fwd_free, vertices, source_ind)
        assert dist == 0.

        # Is the signal stronger at 20 Hz than 10?
        assert power.data[source_ind, 1] > power.data[source_ind, 0]
예제 #9
0
def test_apply_dics_csd(_load_forward):
    """Test applying a DICS beamformer to a CSD matrix."""
    fwd_free, fwd_surf, fwd_fixed, _, label = _load_forward
    epochs, _, csd, source_vertno = _simulate_data(fwd_fixed)
    vertices = np.intersect1d(label.vertices, fwd_free['src'][0]['vertno'])
    source_ind = vertices.tolist().index(source_vertno)
    reg = 1  # Lots of regularization for our toy dataset

    with pytest.raises(RuntimeError, match='several sensor types'):
        make_dics(epochs.info, fwd_free, csd)
    epochs.pick_types(meg='grad')

    # Try different types of forward models
    assert label.hemi == 'lh'
    assert vertices[source_ind] == source_vertno
    rr_want = fwd_free['src'][0]['rr'][source_vertno]
    for fwd in [fwd_free, fwd_surf, fwd_fixed]:
        filters = make_dics(epochs.info,
                            fwd,
                            csd,
                            label=label,
                            reg=reg,
                            inversion='single')
        power, f = apply_dics_csd(csd, filters)
        assert f == [10, 20]

        # Did we find the true source at 20 Hz?
        idx = np.argmax(power.data[:, 1])
        rr_got = fwd_free['src'][0]['rr'][vertices[idx]]
        dist = np.linalg.norm(rr_got - rr_want)
        assert dist == 0.

        # Is the signal stronger at 20 Hz than 10?
        assert power.data[source_ind, 1] > power.data[source_ind, 0]
# Set picks
picks = mne.pick_types(raw.info, meg=True, eeg=False, eog=False,
                       stim=False, exclude='bads')

# Read epochs
event_id, tmin, tmax = 1, -0.2, 0.5
events = mne.read_events(event_fname)
epochs = mne.Epochs(raw, events, event_id, tmin, tmax, proj=True,
                    picks=picks, baseline=(None, 0), preload=True,
                    reject=dict(grad=4000e-13, mag=4e-12))
evoked = epochs.average()

# Read forward operator
forward = mne.read_forward_solution(fname_fwd)

###############################################################################
# Computing the cross-spectral density matrix at 4 evenly spaced frequencies
# from 6 to 10 Hz. We use a decim value of 20 to speed up the computation in
# this example at the loss of accuracy.
csd = csd_morlet(epochs, tmin=0, tmax=0.5, decim=20,
                 frequencies=np.linspace(6, 10, 4))

# Compute DICS spatial filter and estimate source power.
filters = make_dics(epochs.info, forward, csd, reg=0.5)
stc, freqs = apply_dics_csd(csd, filters)

message = 'DICS source power in the 8-12 Hz frequency band'
brain = stc.plot(surface='inflated', hemi='rh', subjects_dir=subjects_dir,
                 time_label=message)
예제 #11
0
def test_tf_dics():
    """Test 5D time-frequency beamforming based on DICS."""
    fwd_free, fwd_surf, fwd_fixed, fwd_vol, label = _load_forward()
    epochs, evoked, _, source_vertno = _simulate_data(fwd_fixed)
    vertices = np.intersect1d(label.vertices, fwd_free['src'][0]['vertno'])
    source_ind = vertices.tolist().index(source_vertno)
    reg = 1  # Lots of regularization for our toy dataset

    tmin = 0
    tmax = 9
    tstep = 4
    win_lengths = [5, 5]
    frequencies = [10, 20]
    freq_bins = [(8, 12), (18, 22)]

    # Compute DICS for two time windows and two frequencies
    for mode in ['fourier', 'multitaper', 'cwt_morlet']:
        stcs = tf_dics(epochs, fwd_surf, None, tmin, tmax, tstep, win_lengths,
                       mode=mode, freq_bins=freq_bins, frequencies=frequencies,
                       decim=10, reg=reg, label=label)

        # Did we find the true source at 20 Hz?
        assert np.argmax(stcs[1].data[:, 0]) == source_ind
        assert np.argmax(stcs[1].data[:, 1]) == source_ind

        # 20 Hz power should decrease over time
        assert stcs[1].data[source_ind, 0] > stcs[1].data[source_ind, 1]

        # 20 Hz power should be more than 10 Hz power at the true source
        assert stcs[1].data[source_ind, 0] > stcs[0].data[source_ind, 0]

    # Manually compute source power and compare with the last tf_dics result.
    source_power = []
    time_windows = [(0, 5), (4, 9)]
    for time_window in time_windows:
        csd = csd_morlet(epochs, frequencies=[frequencies[1]],
                         tmin=time_window[0], tmax=time_window[1], decim=10)
        csd = csd.sum()
        csd._data /= csd.n_fft
        filters = make_dics(epochs.info, fwd_surf, csd, reg=reg, label=label)
        stc_source_power, _ = apply_dics_csd(csd, filters)
        source_power.append(stc_source_power.data)

    # Comparing tf_dics results with dics_source_power results
    assert_allclose(stcs[1].data, np.array(source_power).squeeze().T, atol=0)

    # Test using noise csds. We're going to use identity matrices. That way,
    # since we're using unit-noise-gain weight normalization, there should be
    # no effect.
    stcs = tf_dics(epochs, fwd_surf, None, tmin, tmax, tstep, win_lengths,
                   mode='cwt_morlet', frequencies=frequencies, decim=10,
                   reg=reg, label=label, normalize_fwd=False,
                   weight_norm='unit-noise-gain')
    noise_csd = csd.copy()
    inds = np.triu_indices(csd.n_channels)
    # Using [:, :] syntax for in-place broadcasting
    noise_csd._data[:, :] = 2 * np.eye(csd.n_channels)[inds][:, np.newaxis]
    noise_csd.n_fft = 2  # Dividing by n_fft should yield an identity CSD
    noise_csds = [noise_csd, noise_csd]  # Two frequency bins
    stcs_norm = tf_dics(epochs, fwd_surf, noise_csds, tmin, tmax, tstep,
                        win_lengths, mode='cwt_morlet',
                        frequencies=frequencies, decim=10, reg=reg,
                        label=label, normalize_fwd=False,
                        weight_norm='unit-noise-gain')
    assert_allclose(stcs_norm[0].data, stcs[0].data, atol=0)
    assert_allclose(stcs_norm[1].data, stcs[1].data, atol=0)

    # Test invalid parameter combinations
    raises(ValueError, tf_dics, epochs, fwd_surf, None, tmin, tmax, tstep,
           win_lengths, mode='fourier', freq_bins=None)
    raises(ValueError, tf_dics, epochs, fwd_surf, None, tmin, tmax, tstep,
           win_lengths, mode='cwt_morlet', frequencies=None)

    # Test if incorrect number of noise CSDs is detected
    raises(ValueError, tf_dics, epochs, fwd_surf, [noise_csds[0]], tmin, tmax,
           tstep, win_lengths, freq_bins=freq_bins)

    # Test if freq_bins and win_lengths incompatibility is detected
    raises(ValueError, tf_dics, epochs, fwd_surf, None, tmin, tmax, tstep,
           win_lengths=[0, 1, 2], freq_bins=freq_bins)

    # Test if time step exceeding window lengths is detected
    raises(ValueError, tf_dics, epochs, fwd_surf, None, tmin, tmax, tstep=0.15,
           win_lengths=[0.2, 0.1], freq_bins=freq_bins)

    # Test if incorrent number of n_ffts is detected
    raises(ValueError, tf_dics, epochs, fwd_surf, None, tmin, tmax, tstep,
           win_lengths, freq_bins=freq_bins, n_ffts=[1])

    # Test if incorrect number of mt_bandwidths is detected
    raises(ValueError, tf_dics, epochs, fwd_surf, None, tmin, tmax, tstep,
           win_lengths=win_lengths, freq_bins=freq_bins, mode='multitaper',
           mt_bandwidths=[20])

    # Test if subtracting evoked responses yields NaN's, since we only have one
    # epoch. Suppress division warnings.
    with pytest.warns(RuntimeWarning, match='[invalid|empty]'):
        stcs = tf_dics(epochs, fwd_surf, None, tmin, tmax, tstep, win_lengths,
                       mode='cwt_morlet', frequencies=frequencies,
                       subtract_evoked=True, reg=reg, label=label, decim=20)
    assert np.all(np.isnan(stcs[0].data))
예제 #12
0
def test_apply_dics_csd():
    """Test applying a DICS beamformer to a CSD matrix."""
    fwd_free, fwd_surf, fwd_fixed, fwd_vol, label = _load_forward()
    epochs, _, csd, source_vertno = _simulate_data(fwd_fixed)
    vertices = np.intersect1d(label.vertices, fwd_free['src'][0]['vertno'])
    source_ind = vertices.tolist().index(source_vertno)
    reg = 1  # Lots of regularization for our toy dataset

    # Construct an identity "noise" CSD, which we will use to test the
    # 'unit-noise-gain' setting.
    csd_noise = csd.copy()
    inds = np.triu_indices(csd.n_channels)
    # Using [:, :] syntax for in-place broadcasting
    csd_noise._data[:, :] = np.eye(csd.n_channels)[inds][:, np.newaxis]

    # Try different types of forward models
    for fwd in [fwd_free, fwd_surf, fwd_fixed]:
        filters = make_dics(epochs.info, fwd, csd, label=label, reg=reg,
                            inversion='single')
        power, f = apply_dics_csd(csd, filters)
        assert f == [10, 20]

        # Did we find the true source at 20 Hz?
        assert np.argmax(power.data[:, 1]) == source_ind

        # Is the signal stronger at 20 Hz than 10?
        assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Try picking different orientations and inversion modes
    for pick_ori in [None, 'normal', 'max-power']:
        for inversion in ['single', 'matrix']:
            # Matrix inversion mode needs more regularization for this toy
            # dataset.
            if inversion == 'matrix':
                reg_ = 5
            else:
                reg_ = reg

            filters = make_dics(epochs.info, fwd_surf, csd, label=label,
                                reg=reg_, pick_ori=pick_ori,
                                inversion=inversion,
                                weight_norm='unit-noise-gain')
            power, f = apply_dics_csd(csd, filters)
            assert f == [10, 20]
            assert np.argmax(power.data[:, 1]) == source_ind
            assert power.data[source_ind, 1] > power.data[source_ind, 0]

            # Test unit-noise-gain weighting
            noise_power, f = apply_dics_csd(csd_noise, filters)
            assert np.allclose(noise_power.data, 1)

            # Test filter with forward normalization instead of weight
            # normalization
            filters = make_dics(epochs.info, fwd_surf, csd, label=label,
                                reg=reg_, pick_ori=pick_ori,
                                inversion=inversion, weight_norm=None,
                                normalize_fwd=True)
            power, f = apply_dics_csd(csd, filters)
            assert f == [10, 20]
            assert np.argmax(power.data[:, 1]) == source_ind
            assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Test using a real-valued filter
    filters_real = make_dics(epochs.info, fwd_surf, csd, label=label, reg=reg,
                             real_filter=True)
    # Also test here that no warings are thrown - implemented to check whether
    # src should not be None warning occurs:
    with pytest.warns(None) as w:
        power, f = apply_dics_csd(csd, filters_real)
    assert len(w) == 0

    assert f == [10, 20]
    assert np.argmax(power.data[:, 1]) == source_ind
    assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Test rank reduction
    filters_real = make_dics(epochs.info, fwd_surf, csd, label=label, reg=5,
                             pick_ori='max-power', inversion='matrix',
                             reduce_rank=True)
    power, f = apply_dics_csd(csd, filters_real)
    assert f == [10, 20]
    assert np.argmax(power.data[:, 1]) == source_ind
    assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Test computing source power on a volume source space
    filters_vol = make_dics(epochs.info, fwd_vol, csd, reg=reg)
    power, f = apply_dics_csd(csd, filters_vol)
    vol_source_ind = 3851  # FIXME: not make this hardcoded
    assert f == [10, 20]
    assert np.argmax(power.data[:, 1]) == vol_source_ind
    assert power.data[vol_source_ind, 1] > power.data[vol_source_ind, 0]

    # check whether a filters object without src_type throws expected warning
    del filters_vol['src_type']  # emulate 0.16 behaviour to cause warning
    with pytest.warns(RuntimeWarning, match='spatial filter does not contain '
                      'src_type'):
        apply_dics_csd(csd, filters_vol)
예제 #13
0
    csd_pos_gamma = csd_pos_gamma.mean()
    # csd_rest_alpha = mne.time_frequency.read_csd("{dir}nc_{meg}-csd_rest_alpha.h5".format(dir=meg_dir,meg=meg))
    # csd_rest_theta = mne.time_frequency.read_csd("{dir}nc_{meg}-csd_rest_theta.h5".format(dir=meg_dir,meg=meg))
    # csd_rest_beta_low = mne.time_frequency.read_csd("{dir}nc_{meg}-csd_rest_beta_low.h5".format(dir=meg_dir,meg=meg))
    # csd_rest_beta_high = mne.time_frequency.read_csd("{dir}nc_{meg}-csd_rest_beta_high.h5".format(dir=meg_dir,meg=meg))
    # csd_rest_gamma = mne.time_frequency.read_csd("{dir}nc_{meg}-csd_rest_gamma.h5".format(dir=meg_dir,meg=meg))

    # make DICS beamformers / filters (common filters) for different freq bands
    filters_exp_alpha = make_dics(epo_exp.info,fwd_exp,csd_exp_alpha,pick_ori='max-power',rank=None,inversion='single',weight_norm=None,normalize_fwd=True,real_filter=False)
    filters_exp_theta = make_dics(epo_exp.info,fwd_exp,csd_exp_theta,pick_ori='max-power',rank=None,inversion='single',weight_norm=None,normalize_fwd=True,real_filter=False)
    filters_exp_beta_low = make_dics(epo_exp.info,fwd_exp,csd_exp_beta_low,pick_ori='max-power',rank=None,inversion='single',weight_norm=None,normalize_fwd=True,real_filter=False)
    filters_exp_beta_high = make_dics(epo_exp.info,fwd_exp,csd_exp_beta_high,pick_ori='max-power',rank=None,inversion='single',weight_norm=None,normalize_fwd=True,real_filter=False)
    filters_exp_gamma = make_dics(epo_exp.info,fwd_exp,csd_exp_gamma,pick_ori='max-power',rank=None,inversion='single',weight_norm=None,normalize_fwd=True,real_filter=False)

    # apply the DICS beamformers to get source Estimates for ton, neg, pos using common filters & save to file
    stc_ton_alpha, freqs_ton_alpha = apply_dics_csd(csd_ton_alpha,filters_exp_alpha)
    stc_ton_theta, freqs_ton_theta = apply_dics_csd(csd_ton_theta,filters_exp_theta)
    stc_ton_beta_low, freqs_ton_beta_low = apply_dics_csd(csd_ton_beta_low,filters_exp_beta_low)
    stc_ton_beta_high, freqs_ton_beta_high = apply_dics_csd(csd_ton_beta_high,filters_exp_beta_high)
    stc_ton_gamma, freqs_ton_gamma = apply_dics_csd(csd_ton_gamma,filters_exp_gamma)
    stc_ton_alpha.save(fname=meg_dir+"nc_{}_stc_ton_alpha".format(meg))
    stc_ton_theta.save(fname=meg_dir+"nc_{}_stc_ton_theta".format(meg))
    stc_ton_beta_low.save(fname=meg_dir+"nc_{}_stc_ton_beta_low".format(meg))
    stc_ton_beta_high.save(fname=meg_dir+"nc_{}_stc_ton_beta_high".format(meg))
    stc_ton_gamma.save(fname=meg_dir+"nc_{}_stc_ton_gamma".format(meg))

    stc_neg_alpha, freqs_neg_alpha = apply_dics_csd(csd_neg_alpha,filters_exp_alpha)
    stc_neg_theta, freqs_neg_theta = apply_dics_csd(csd_neg_theta,filters_exp_theta)
    stc_neg_beta_low, freqs_neg_beta_low = apply_dics_csd(csd_neg_beta_low,filters_exp_beta_low)
    stc_neg_beta_high, freqs_neg_beta_high = apply_dics_csd(csd_neg_beta_high,filters_exp_beta_high)
    stc_neg_gamma, freqs_neg_gamma = apply_dics_csd(csd_neg_gamma,filters_exp_gamma)
예제 #14
0
        csd_ton = mne.time_frequency.read_csd(
            "{dir}nc_{meg}-csd_ton_{freq}.h5".format(dir=meg_dir,
                                                     meg=meg,
                                                     freq=freq))
        # make DICS beamformers / filters (common filters)
        filters_bas = make_dics(epo_bas.info,
                                fwd_base,
                                csd_bas,
                                pick_ori='max-power',
                                rank=None,
                                inversion='single',
                                weight_norm=None,
                                normalize_fwd=True,
                                real_filter=False)
        # apply the DICS beamformers to get source Estimates for rest,ton using common filters & save to file
        stc_rest, freqs_rest = apply_dics_csd(csd_rest, filters_bas)
        stc_ton, freqs_ton = apply_dics_csd(csd_ton, filters_bas)
        # calculate the difference of each condition to the tone baseline & save to file
        stc_tonbas_diff = (stc_ton - stc_rest) / stc_rest
        # morph the resulting stcs to fsaverage & save  (to be loaded again and averaged)
        morph = mne.compute_source_morph(stc_tonbas_diff,
                                         subject_from=mri,
                                         subject_to="fsaverage",
                                         subjects_dir=mri_dir)
        stc_fs_tonbas_diff = morph.apply(stc_tonbas_diff)
        stc_fs_tonbas_diff.save(
            fname=meg_dir + "nc_{}_stc_fs_tonbas_diff_F_{}".format(meg, freq))

# prepare for source diff permutation t-test
src = mne.read_source_spaces("{}fsaverage_ico5-src.fif".format(meg_dir))
connectivity = mne.spatial_src_connectivity(src)
예제 #15
0
def test_tf_dics(_load_forward, idx, mat_tol, vol_tol):
    """Test 5D time-frequency beamforming based on DICS."""
    fwd_free, fwd_surf, fwd_fixed, _ = _load_forward
    epochs, _, _, source_vertno, label, vertices, source_ind = \
        _simulate_data(fwd_fixed, idx)
    reg = 1  # Lots of regularization for our toy dataset

    tmin = 0
    tmax = 9
    tstep = 4
    win_lengths = [5, 5]
    frequencies = [10, 20]
    freq_bins = [(8, 12), (18, 22)]

    with pytest.raises(RuntimeError, match='several sensor types'):
        stcs = tf_dics(epochs,
                       fwd_surf,
                       None,
                       tmin,
                       tmax,
                       tstep,
                       win_lengths,
                       freq_bins=freq_bins,
                       frequencies=frequencies,
                       decim=10,
                       reg=reg,
                       label=label)
    epochs.pick_types(meg='grad')
    # Compute DICS for two time windows and two frequencies
    for mode in ['fourier', 'multitaper', 'cwt_morlet']:
        stcs = tf_dics(epochs,
                       fwd_surf,
                       None,
                       tmin,
                       tmax,
                       tstep,
                       win_lengths,
                       mode=mode,
                       freq_bins=freq_bins,
                       frequencies=frequencies,
                       decim=10,
                       reg=reg,
                       label=label)

        # Did we find the true source at 20 Hz?
        dist = _fwd_dist(stcs[1], fwd_surf, vertices, source_ind, tidx=0)
        assert dist == 0
        dist = _fwd_dist(stcs[1], fwd_surf, vertices, source_ind, tidx=1)
        assert dist == 0

        # 20 Hz power should decrease over time
        assert stcs[1].data[source_ind, 0] > stcs[1].data[source_ind, 1]

        # 20 Hz power should be more than 10 Hz power at the true source
        assert stcs[1].data[source_ind, 0] > stcs[0].data[source_ind, 0]

    # Manually compute source power and compare with the last tf_dics result.
    source_power = []
    time_windows = [(0, 5), (4, 9)]
    for time_window in time_windows:
        csd = csd_morlet(epochs,
                         frequencies=[frequencies[1]],
                         tmin=time_window[0],
                         tmax=time_window[1],
                         decim=10)
        csd = csd.sum()
        csd._data /= csd.n_fft
        filters = make_dics(epochs.info, fwd_surf, csd, reg=reg, label=label)
        stc_source_power, _ = apply_dics_csd(csd, filters)
        source_power.append(stc_source_power.data)

    # Comparing tf_dics results with dics_source_power results
    assert_allclose(stcs[1].data, np.array(source_power).squeeze().T, atol=0)

    # Test using noise csds. We're going to use identity matrices. That way,
    # since we're using unit-noise-gain weight normalization, there should be
    # no effect.
    stcs = tf_dics(epochs,
                   fwd_surf,
                   None,
                   tmin,
                   tmax,
                   tstep,
                   win_lengths,
                   mode='cwt_morlet',
                   frequencies=frequencies,
                   decim=10,
                   reg=reg,
                   label=label,
                   normalize_fwd=False,
                   weight_norm='unit-noise-gain')
    noise_csd = csd.copy()
    inds = np.triu_indices(csd.n_channels)
    # Using [:, :] syntax for in-place broadcasting
    noise_csd._data[:, :] = 2 * np.eye(csd.n_channels)[inds][:, np.newaxis]
    noise_csd.n_fft = 2  # Dividing by n_fft should yield an identity CSD
    noise_csds = [noise_csd, noise_csd]  # Two frequency bins
    stcs_norm = tf_dics(epochs,
                        fwd_surf,
                        noise_csds,
                        tmin,
                        tmax,
                        tstep,
                        win_lengths,
                        mode='cwt_morlet',
                        frequencies=frequencies,
                        decim=10,
                        reg=reg,
                        label=label,
                        normalize_fwd=False,
                        weight_norm='unit-noise-gain')
    assert_allclose(stcs_norm[0].data, stcs[0].data, atol=0)
    assert_allclose(stcs_norm[1].data, stcs[1].data, atol=0)

    # Test invalid parameter combinations
    with pytest.raises(ValueError, match='fourier.*freq_bins" parameter'):
        tf_dics(epochs,
                fwd_surf,
                None,
                tmin,
                tmax,
                tstep,
                win_lengths,
                mode='fourier',
                freq_bins=None)
    with pytest.raises(ValueError, match='cwt_morlet.*frequencies" param'):
        tf_dics(epochs,
                fwd_surf,
                None,
                tmin,
                tmax,
                tstep,
                win_lengths,
                mode='cwt_morlet',
                frequencies=None)

    # Test if incorrect number of noise CSDs is detected
    with pytest.raises(ValueError, match='One noise CSD object expected per'):
        tf_dics(epochs,
                fwd_surf, [noise_csds[0]],
                tmin,
                tmax,
                tstep,
                win_lengths,
                freq_bins=freq_bins)

    # Test if freq_bins and win_lengths incompatibility is detected
    with pytest.raises(ValueError, match='One time window length expected'):
        tf_dics(epochs,
                fwd_surf,
                None,
                tmin,
                tmax,
                tstep,
                win_lengths=[0, 1, 2],
                freq_bins=freq_bins)

    # Test if time step exceeding window lengths is detected
    with pytest.raises(ValueError, match='Time step should not be larger'):
        tf_dics(epochs,
                fwd_surf,
                None,
                tmin,
                tmax,
                tstep=0.15,
                win_lengths=[0.2, 0.1],
                freq_bins=freq_bins)

    # Test if incorrect number of n_ffts is detected
    with pytest.raises(ValueError, match='When specifying number of FFT'):
        tf_dics(epochs,
                fwd_surf,
                None,
                tmin,
                tmax,
                tstep,
                win_lengths,
                freq_bins=freq_bins,
                n_ffts=[1])

    # Test if incorrect number of mt_bandwidths is detected
    with pytest.raises(ValueError, match='When using multitaper mode and'):
        tf_dics(epochs,
                fwd_surf,
                None,
                tmin,
                tmax,
                tstep,
                win_lengths=win_lengths,
                freq_bins=freq_bins,
                mode='multitaper',
                mt_bandwidths=[20])

    # Test if subtracting evoked responses yields NaN's, since we only have one
    # epoch. Suppress division warnings.
    assert len(epochs) == 1, len(epochs)
    with np.errstate(invalid='ignore'):
        stcs = tf_dics(epochs,
                       fwd_surf,
                       None,
                       tmin,
                       tmax,
                       tstep,
                       win_lengths,
                       mode='cwt_morlet',
                       frequencies=frequencies,
                       subtract_evoked=True,
                       reg=reg,
                       label=label,
                       decim=20)
    assert np.all(np.isnan(stcs[0].data))
예제 #16
0
            info = epochs_joint.info
        else:
            raise ValueError('Invalid sensor type: %s', sensor_type)

        filters = make_dics(info,
                            fwd_disc_man,
                            csd,
                            reg=reg,
                            pick_ori=pick_ori,
                            inversion=inversion,
                            weight_norm=weight_norm,
                            noise_csd=noise_csd if use_noise_cov else None,
                            normalize_fwd=normalize_fwd,
                            real_filter=real_filter,
                            reduce_rank=reduce_rank)
        stc_est_power, freqs = apply_dics_csd(csd, filters)

        peak_vertex, _ = stc_est_power.get_peak(vert_as_index=True)

        # Compute distance between true and estimated source locations
        pos_est = fwd_disc_man['source_rr'][peak_vertex]
        pos_true = fwd_disc_man['source_rr'][config.vertex]
        dist = np.linalg.norm(pos_est - pos_true)

        # Ratio between estimated peak activity and all estimated activity.
        focality_score = stc_est_power.data[peak_vertex,
                                            0] / stc_est_power.data.sum()

        if pick_ori == 'max-power':
            estimated_ori = filters['max_power_oris'][0][config.vertex]
            ori_error = np.rad2deg(abs(np.arccos(estimated_ori @ true_ori)))
예제 #17
0
            raise ValueError('Invalid sensor type: %s', sensor_type)
        # Allow using other MNE branches without this arg
        use_kwargs = dict(noise_csd=noise_csd) if use_noise_cov else dict()

        filters = make_dics(info,
                            fwd_disc_man,
                            csd if use_noise_cov else signal_csd,
                            reg=reg,
                            pick_ori=pick_ori,
                            inversion=inversion,
                            weight_norm=weight_norm,
                            depth=1. if normalize_fwd else None,
                            real_filter=real_filter,
                            reduce_rank=reduce_rank,
                            **use_kwargs)
        stc_est_power, freqs = apply_dics_csd(signal_csd, filters)
        stc_noise_power, freqs = apply_dics_csd(noise_csd, filters)

        peak_vertex, _ = stc_est_power.get_peak(vert_as_index=True)

        # Compute distance between true and estimated source locations
        pos_est = fwd_disc_man['source_rr'][peak_vertex]
        pos_true = fwd_disc_man['source_rr'][config.vertex]
        dist = np.linalg.norm(pos_est - pos_true)

        # Ratio between estimated peak activity and all estimated activity.
        focality_score = stc_est_power.data[peak_vertex,
                                            0] / stc_est_power.data.sum()

        if pick_ori == 'max-power':
            estimated_ori = filters['max_power_ori'][0][config.vertex]
예제 #18
0
def test_apply_dics_csd():
    """Test applying a DICS beamformer to a CSD matrix."""
    fwd_free, fwd_surf, fwd_fixed, fwd_vol, label = _load_forward()
    epochs, _, csd, source_vertno = _simulate_data(fwd_fixed)
    vertices = np.intersect1d(label.vertices, fwd_free['src'][0]['vertno'])
    source_ind = vertices.tolist().index(source_vertno)
    reg = 1  # Lots of regularization for our toy dataset

    # Construct an identity "noise" CSD, which we will use to test the
    # 'unit-noise-gain' setting.
    csd_noise = csd.copy()
    inds = np.triu_indices(csd.n_channels)
    # Using [:, :] syntax for in-place broadcasting
    csd_noise._data[:, :] = np.eye(csd.n_channels)[inds][:, np.newaxis]

    # Try different types of forward models
    for fwd in [fwd_free, fwd_surf, fwd_fixed]:
        filters = make_dics(epochs.info, fwd, csd, label=label, reg=reg,
                            inversion='single')
        power, f = apply_dics_csd(csd, filters)
        assert f == [10, 20]

        # Did we find the true source at 20 Hz?
        assert np.argmax(power.data[:, 1]) == source_ind

        # Is the signal stronger at 20 Hz than 10?
        assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Try picking different orientations and inversion modes
    for pick_ori in [None, 'normal', 'max-power']:
        for inversion in ['single', 'matrix']:
            # Matrix inversion mode needs more regularization for this toy
            # dataset.
            if inversion == 'matrix':
                reg_ = 5
            else:
                reg_ = reg

            filters = make_dics(epochs.info, fwd_surf, csd, label=label,
                                reg=reg_, pick_ori=pick_ori,
                                inversion=inversion,
                                weight_norm='unit-noise-gain')
            power, f = apply_dics_csd(csd, filters)
            assert f == [10, 20]
            assert np.argmax(power.data[:, 1]) == source_ind
            assert power.data[source_ind, 1] > power.data[source_ind, 0]

            # Test unit-noise-gain weighting
            noise_power, f = apply_dics_csd(csd_noise, filters)
            assert np.allclose(noise_power.data, 1)

            # Test filter with forward normalization instead of weight
            # normalization
            filters = make_dics(epochs.info, fwd_surf, csd, label=label,
                                reg=reg_, pick_ori=pick_ori,
                                inversion=inversion, weight_norm=None,
                                normalize_fwd=True)
            power, f = apply_dics_csd(csd, filters)
            assert f == [10, 20]
            assert np.argmax(power.data[:, 1]) == source_ind
            assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Test using a real-valued filter
    filters_real = make_dics(epochs.info, fwd_surf, csd, label=label, reg=reg,
                             real_filter=True)
    # Also test here that no warings are thrown - implemented to check whether
    # src should not be None warning occurs:
    with pytest.warns(None) as w:
        power, f = apply_dics_csd(csd, filters_real)
    assert len(w) == 0

    assert f == [10, 20]
    assert np.argmax(power.data[:, 1]) == source_ind
    assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Test rank reduction
    filters_real = make_dics(epochs.info, fwd_surf, csd, label=label, reg=5,
                             pick_ori='max-power', inversion='matrix',
                             reduce_rank=True)
    power, f = apply_dics_csd(csd, filters_real)
    assert f == [10, 20]
    assert np.argmax(power.data[:, 1]) == source_ind
    assert power.data[source_ind, 1] > power.data[source_ind, 0]

    # Test computing source power on a volume source space
    filters_vol = make_dics(epochs.info, fwd_vol, csd, reg=reg)
    power, f = apply_dics_csd(csd, filters_vol)
    vol_source_ind = 3851  # FIXME: not make this hardcoded
    assert f == [10, 20]
    assert np.argmax(power.data[:, 1]) == vol_source_ind
    assert power.data[vol_source_ind, 1] > power.data[vol_source_ind, 0]

    # check whether a filters object without src_type throws expected warning
    del filters_vol['src_type']  # emulate 0.16 behaviour to cause warning
    with pytest.warns(RuntimeWarning, match='spatial filter does not contain '
                      'src_type'):
        apply_dics_csd(csd, filters_vol)
예제 #19
0
        #         stc.save("{a}stcs/nc_{b}_{c}_{f0}-{f1}Hz_{d}_{sp}".format(
        #                   a=proc_dir, b=sub, c=epo_name, f0=f[0], f1=f[-1],
        #                   d=event, sp=spacing))

        # now byresp epo
        for run in ["audio", "visual", "visselten"]:
            epo_name = "{dir}{sub}_{run}_byresp-epo.fif".format(dir=proc_dir,
                                                                sub=sub,
                                                                run=run)
            epo = mne.read_epochs(epo_name)
            for event in range(len(epo)):
                print(event)
                event_csd = csd_morlet(epo[event],
                                       frequencies=freqs,
                                       n_jobs=n_jobs,
                                       n_cycles=7,
                                       decim=3)
                stc, freqs = apply_dics_csd(event_csd, filters)
                del event_csd
                stc.expand([s["vertno"] for s in src])
                stc.subject = sub
                stc.save(
                    "{a}stcs/nc_{b}_{c}_byresp_{f0}-{f1}Hz_{d}_{sp}".format(
                        a=proc_dir,
                        b=sub,
                        c=run,
                        f0=f[0],
                        f1=f[-1],
                        d=event,
                        sp=spacing))
예제 #20
0
            info = epochs_grad.info
        elif sensor_type == 'mag':
            info = epochs_mag.info
        else:
            raise ValueError('Invalid sensor type: %s', sensor_type)

        filters = make_dics(info,
                            fwd,
                            csd,
                            reg=reg,
                            pick_ori=pick_ori,
                            inversion=inversion,
                            weight_norm=weight_norm,
                            normalize_fwd=normalize_fwd,
                            real_filter=real_filter)
        stc, freqs = apply_dics_csd(csd, filters)

        # Compute distance between true and estimated source
        dip_true = make_dipole(stc_signal, fwd['src'])
        dip_est = make_dipole(stc, fwd['src'])
        dist = np.linalg.norm(dip_true.pos - dip_est.pos)

        # Fancy evaluation metric
        ev = evaluate_stc(stc, stc_signal)
    except Exception as e:
        print(e)
        dist = np.nan
        ev = np.nan
    print(setting, dist, ev)

    dists.append(dist)
예제 #21
0
 csd_pos_gamma_high = mne.time_frequency.read_csd("{dir}nc_{meg}-csd_pos_gamma_high.h5".format(dir=meg_dir,meg=meg))
 csd_pos_gamma_high = csd_pos_gamma_high.mean()
 csd_rest_gamma_high = mne.time_frequency.read_csd("{dir}nc_{meg}-csd_rest_gamma_high.h5".format(dir=meg_dir,meg=meg))
 csd_rest_gamma_high = csd_rest_gamma_high.mean()
 # build DICS filters
 # for experimental conditions analyses
 filters_exp_gamma_high = make_dics(epo_exp.info,fwd_exp,csd_exp_gamma_high,pick_ori='max-power',rank=None,inversion='single',weight_norm=None,normalize_fwd=True,real_filter=False)
 # clean memory
 del epo_exp, fwd_exp, csd_exp_gamma_high
 # for baseline analyses
 filters_bas_gamma_high = make_dics(epo_bas.info,fwd_base,csd_bas_gamma_high,pick_ori='max-power',rank=None,inversion='single',weight_norm=None,normalize_fwd=True,real_filter=False)
 # clean memory
 del epo_bas, fwd_base, csd_bas_gamma_high
 # apply filters, calculate difference stcs & save
 # for experiment
 stc_ton_gamma_high, freqs_ton_gamma_high = apply_dics_csd(csd_ton_gamma_high,filters_exp_gamma_high)
 stc_neg_gamma_high, freqs_neg_gamma_high = apply_dics_csd(csd_neg_gamma_high,filters_exp_gamma_high)
 stc_pos_gamma_high, freqs_pos_gamma_high = apply_dics_csd(csd_pos_gamma_high,filters_exp_gamma_high)
 stc_diff_gamma_high = (stc_neg_gamma_high - stc_pos_gamma_high) / stc_ton_gamma_high
 stc_diff_gamma_high.save(fname=meg_dir+"nc_{}_stc_limb_mix_diff_gamma_high".format(meg))
 # clean memory
 del filters_exp_gamma_high, csd_neg_gamma_high, csd_pos_gamma_high
 # for baseline
 stc_ton_gamma_high, freqs_ton_gamma_high = apply_dics_csd(csd_ton_gamma_high,filters_bas_gamma_high)
 stc_rest_gamma_high, freqs_rest_gamma_high = apply_dics_csd(csd_rest_gamma_high,filters_bas_gamma_high)
 stc_tonbas_gamma_high = (stc_ton_gamma_high - stc_rest_gamma_high) / stc_rest_gamma_high
 stc_tonbas_gamma_high.save(fname=meg_dir+"nc_{}_stc_limb_mix_tonbas_gamma_high".format(meg))
 # clean memory
 del filters_bas_gamma_high, csd_rest_gamma_high, csd_ton_gamma_high
 del stc_rest_gamma_high, stc_ton_gamma_high, stc_neg_gamma_high, stc_pos_gamma_high
 # read mixed source space
예제 #22
0
파일: 09_power.py 프로젝트: sherdim/conpy
# Read the info structure
info = mne.io.read_info(fname.epo(subject=subject))

# Compute source power for all frequency bands and all conditions
fmin = [f[0] for f in freq_bands]
fmax = [f[1] for f in freq_bands]

csds = dict()
for condition in conditions + ['baseline']:
    print('Reading CSD matrix for condition:', condition)
    # Read the CSD matrix
    csds[condition] = read_csd(fname.csd(condition=condition, subject=subject))

# Average the CSDs of both conditions
csd = csds['face'].copy()
csd._data += csds['scrambled']._data
csd._data /= 2

# Compute the DICS beamformer using the CSDs from both conditions, for all
# frequency bands.
filters = make_dics(info=info, forward=fwd, csd=csd.mean(fmin, fmax), reg=reg,
                    pick_ori='max-power')

stcs = dict()
for condition in conditions + ['baseline']:
    print('Computing power for condition:', condition)
    stcs[condition], _ = apply_dics_csd(csds[condition].mean(fmin, fmax),
                                        filters)
    stcs[condition].save(fname.power(condition=condition, subject=subject))
예제 #23
0
# Rotate the view and add a title.
mlab.view(0, 0, 550, [0, 0, 0])
mlab.title('MNE-dSPM inverse (RMS)', height=0.9)

###############################################################################
# Computing a cortical power map at 10 Hz. using a DICS beamformer:

# Estimate the cross-spectral density (CSD) matrix on the trial containing the
# signal.
csd_signal = csd_morlet(epochs['signal'], frequencies=[10])

# Compute the DICS powermap. For this simulated dataset, we need a lot of
# regularization for the beamformer to behave properly. For real recordings,
# this amount of regularization is probably too much.
filters = make_dics(epochs.info, fwd, csd_signal, reg=1, pick_ori='max-power')
power, f = apply_dics_csd(csd_signal, filters)

# Plot the DICS power map.
brain = power.plot('sample',
                   subjects_dir=subjects_dir,
                   hemi='both',
                   figure=2,
                   size=400)

# Indicate the true locations of the source activity on the plot.
brain.add_foci(source_vert1, coords_as_verts=True, hemi='lh')
brain.add_foci(source_vert2, coords_as_verts=True, hemi='rh')

# Rotate the view and add a title.
mlab.view(0, 0, 550, [0, 0, 0])
mlab.title('DICS power map at %.1f Hz' % f[0], height=0.9)
예제 #24
0
        info_eq, fwd_eq, csd_eq = mne.channels.equalize_channels(
            [info, fwd, csd])
        filters = make_dics(info_eq,
                            fwd_eq,
                            csd_eq,
                            reg=reg,
                            pick_ori=pick_ori,
                            inversion=inversion,
                            weight_norm=weight_norm,
                            noise_csd=csd_baseline if use_noise_cov else None,
                            normalize_fwd=normalize_fwd,
                            real_filter=real_filter,
                            reduce_rank=reduce_rank)

        # Compute source power
        stc_baseline, _ = apply_dics_csd(csd_baseline, filters)
        stc_power, _ = apply_dics_csd(csd_ers, filters)

        # Normalize with baseline power.
        stc_power /= stc_baseline
        stc_power.data = np.log(stc_power.data)

        peak_vertex, _ = stc_power.get_peak(vert_as_index=True)

        # Compute distance between true and estimated source locations
        pos = fwd['source_rr'][peak_vertex]
        dist = np.linalg.norm(dip.pos - pos)

        # Ratio between estimated peak activity and all estimated activity.
        focality_score = stc_power.data[peak_vertex, 0] / stc_power.data.sum()
예제 #25
0
filters_approach2 = make_dics(info,
                              fwd,
                              csd_signal,
                              reg=0.1,
                              pick_ori='max-power',
                              normalize_fwd=False,
                              inversion='matrix',
                              weight_norm='unit-noise-gain')
print(filters_approach2)

# You can save these to disk with:
# filters_approach1.save('filters_1-dics.h5')

# Compute the DICS power map by applying the spatial filters to the CSD matrix.
power_approach1, f = apply_dics_csd(csd_signal, filters_approach1)
power_approach2, f = apply_dics_csd(csd_signal, filters_approach2)

# Plot the DICS power maps for both approaches.
for approach, power in enumerate([power_approach1, power_approach2], 1):
    brain = power.plot('sample',
                       subjects_dir=subjects_dir,
                       hemi='both',
                       figure=approach + 1,
                       size=600)

    # Indicate the true locations of the source activity on the plot.
    brain.add_foci(source_vert1, coords_as_verts=True, hemi='lh')
    brain.add_foci(source_vert2, coords_as_verts=True, hemi='rh')

    # Rotate the view and add a title.
예제 #26
0
                       fwd_b,
                       csd,
                       pick_ori=None,
                       rank='full',
                       weight_norm=None,
                       normalize_fwd=False,
                       real_filter=False)
 neg_a = epo_a["negative"]
 neg_b = epo_b["negative"]
 pos_a = epo_a["positive"]
 pos_b = epo_b["positive"]
 # csd_pos_a = csd_morlet(pos, frequencies=freqs, n_jobs=8, n_cycles=9, decim=3)
 # csd_neg_a = csd_morlet(neg, frequencies=freqs, n_jobs=8, n_cycles=9, decim=3)
 csd_pos_a = csd_multitaper(pos_a, fmin=7, fmax=14, bandwidth=1)
 stc_pos_a, freqs_pos_a = apply_dics_csd(
     csd_pos_a, filters_a
 )  # in mne tutorial they use csd.mean() for the whole freq band
 csd_pos_b = csd_multitaper(pos_b, fmin=7, fmax=14, bandwidth=1)
 stc_pos_b, freqs_pos_b = apply_dics_csd(csd_pos_b, filters_b)
 csd_neg_a = csd_multitaper(neg_a, fmin=7, fmax=14, bandwidth=1)
 stc_neg_a, freqs_neg_a = apply_dics_csd(
     csd_neg_a, filters_a
 )  # in mne tutorial they use csd.mean() for the whole freq band
 csd_neg_b = csd_multitaper(neg_b, fmin=7, fmax=14, bandwidth=1)
 stc_neg_b, freqs_neg_b = apply_dics_csd(csd_neg_b, filters_b)
 stc_pos = (stc_pos_a + stc_pos_b) / 2
 stc_neg = (stc_neg_a + stc_neg_b) / 2
 stc_diff = stc_neg - stc_pos
 # plot the difference between conditions
 stc_diff.plot(subjects_dir=mri_dir,
               subject=mri,
예제 #27
0
# We are interested in the beta band. Define a range of frequencies, using a
# log scale, from 12 to 30 Hz.
freqs = np.logspace(np.log10(12), np.log10(30), 9)

###############################################################################
# Computing the cross-spectral density matrix for the beta frequency band, for
# different time intervals. We use a decim value of 20 to speed up the
# computation in this example at the loss of accuracy.
csd = csd_morlet(epochs, freqs, tmin=-1, tmax=1.5, decim=20)
csd_baseline = csd_morlet(epochs, freqs, tmin=-1, tmax=0, decim=20)
# ERS activity starts at 0.5 seconds after stimulus onset
csd_ers = csd_morlet(epochs, freqs, tmin=0.5, tmax=1.5, decim=20)

###############################################################################
# Computing DICS spatial filters using the CSD that was computed on the entire
# timecourse.
filters = make_dics(epochs.info, fwd, csd.mean(), pick_ori='max-power')

###############################################################################
# Applying DICS spatial filters separately to the CSD computed using the
# baseline and the CSD computed during the ERS activity.
baseline_source_power, freqs = apply_dics_csd(csd_baseline.mean(), filters)
beta_source_power, freqs = apply_dics_csd(csd_ers.mean(), filters)

###############################################################################
# Visualizing source power during ERS activity relative to the baseline power.
stc = beta_source_power / baseline_source_power
message = 'DICS source power in the 12-30 Hz frequency band'
brain = stc.plot(hemi='both', views='par', subjects_dir=subjects_dir,
                 time_label=message)
예제 #28
0
#     normalization instead of normalizing the forward solution.

# Estimate the cross-spectral density (CSD) matrix on the trial containing the
# signal.
csd_signal = csd_morlet(epochs['signal'], frequencies=[10])

# Compute the spatial filters for each vertex, using two approaches.
filters_approach1 = make_dics(
    info, fwd, csd_signal, reg=0.05, pick_ori='max-power', normalize_fwd=True,
    inversion='single', weight_norm=None)
filters_approach2 = make_dics(
    info, fwd, csd_signal, reg=0.05, pick_ori='max-power', normalize_fwd=False,
    inversion='matrix', weight_norm='unit-noise-gain')

# Compute the DICS power map by applying the spatial filters to the CSD matrix.
power_approach1, f = apply_dics_csd(csd_signal, filters_approach1)
power_approach2, f = apply_dics_csd(csd_signal, filters_approach2)

# Plot the DICS power maps for both approaches.
for approach, power in enumerate([power_approach1, power_approach2], 1):
    brain = power.plot('sample', subjects_dir=subjects_dir, hemi='both',
                       figure=approach + 1, size=600)

    # Indicate the true locations of the source activity on the plot.
    brain.add_foci(source_vert1, coords_as_verts=True, hemi='lh')
    brain.add_foci(source_vert2, coords_as_verts=True, hemi='rh')

    # Rotate the view and add a title.
    mlab.view(0, 0, 550, [0, 0, 0])
    mlab.title('DICS power map, approach %d' % approach, height=0.9)
예제 #29
0
csd_baseline = csd_baseline.mean()
csd_ers = csd_ers.mean()

###############################################################################
# Computing DICS spatial filters using the CSD that was computed on the entire
# timecourse.
filters = make_dics(epochs.info,
                    fwd,
                    csd,
                    noise_csd=csd_baseline,
                    pick_ori='max-power')

###############################################################################
# Applying DICS spatial filters separately to the CSD computed using the
# baseline and the CSD computed during the ERS activity.
baseline_source_power, freqs = apply_dics_csd(csd_baseline, filters)
beta_source_power, freqs = apply_dics_csd(csd_ers, filters)

###############################################################################
# Visualizing source power during ERS activity relative to the baseline power.
stc = beta_source_power / baseline_source_power
message = 'DICS source power in the 12-30 Hz frequency band'
brain = stc.plot(hemi='both',
                 views='par',
                 subjects_dir=subjects_dir,
                 subject=subject,
                 time_label=message)

###############################################################################
# References
# ----------
                         weight_norm=None,
                         normalize_fwd=True,
                         real_filter=False)
 del epo_exp, fwd_exp, csd_exp
 filters_bas = make_dics(epo_bas.info,
                         fwd_base,
                         csd_bas,
                         pick_ori='max-power',
                         rank=None,
                         inversion='single',
                         weight_norm=None,
                         normalize_fwd=True,
                         real_filter=False)
 del epo_bas, fwd_base, csd_bas
 # apply the DICS beamformers to get source Estimates for (base) rest, tonbas & (exp) ton, neg, pos using common filters & save to file
 stc_rest, freqs_rest = apply_dics_csd(csd_rest, filters_bas)
 del csd_rest
 stc_rest.save(fname=meg_dir + "nc_{}_stc_rest_1-90".format(meg))
 stc_tonbas, freqs_tonbas = apply_dics_csd(csd_ton, filters_bas)
 stc_tonbas.save(fname=meg_dir + "nc_{}_stc_tonbas_1-90".format(meg))
 del filters_bas
 stc_ton, freqs_ton = apply_dics_csd(csd_ton, filters_exp)
 stc_ton.save(fname=meg_dir + "nc_{}_stc_ton_1-90".format(meg))
 del csd_ton
 stc_neg, freqs_neg = apply_dics_csd(csd_neg, filters_exp)
 del csd_neg
 stc_neg.save(fname=meg_dir + "nc_{}_stc_neg_1-90".format(meg))
 stc_pos, freqs_pos = apply_dics_csd(csd_pos, filters_exp)
 del csd_pos
 stc_pos.save(fname=meg_dir + "nc_{}_stc_pos_1-90".format(meg))
 # calculate the difference between conditions div. by baseline & save to file (for base and for exp)
예제 #31
0
def test_tf_dics():
    """Test 5D time-frequency beamforming based on DICS."""
    fwd_free, fwd_surf, fwd_fixed, fwd_vol, label = _load_forward()
    epochs, evoked, _, source_vertno = _simulate_data(fwd_fixed)
    vertices = np.intersect1d(label.vertices, fwd_free['src'][0]['vertno'])
    source_ind = vertices.tolist().index(source_vertno)
    reg = 1  # Lots of regularization for our toy dataset

    tmin = 0
    tmax = 9
    tstep = 4
    win_lengths = [5, 5]
    frequencies = [10, 20]
    freq_bins = [(8, 12), (18, 22)]

    # Compute DICS for two time windows and two frequencies
    for mode in ['fourier', 'multitaper', 'cwt_morlet']:
        stcs = tf_dics(epochs, fwd_surf, None, tmin, tmax, tstep, win_lengths,
                       mode=mode, freq_bins=freq_bins, frequencies=frequencies,
                       decim=10, reg=reg, label=label)

        # Did we find the true source at 20 Hz?
        assert np.argmax(stcs[1].data[:, 0]) == source_ind
        assert np.argmax(stcs[1].data[:, 1]) == source_ind

        # 20 Hz power should decrease over time
        assert stcs[1].data[source_ind, 0] > stcs[1].data[source_ind, 1]

        # 20 Hz power should be more than 10 Hz power at the true source
        assert stcs[1].data[source_ind, 0] > stcs[0].data[source_ind, 0]

    # Manually compute source power and compare with the last tf_dics result.
    source_power = []
    time_windows = [(0, 5), (4, 9)]
    for time_window in time_windows:
        csd = csd_morlet(epochs, frequencies=[frequencies[1]],
                         tmin=time_window[0], tmax=time_window[1], decim=10)
        csd = csd.sum()
        csd._data /= csd.n_fft
        filters = make_dics(epochs.info, fwd_surf, csd, reg=reg, label=label)
        stc_source_power, _ = apply_dics_csd(csd, filters)
        source_power.append(stc_source_power.data)

    # Comparing tf_dics results with dics_source_power results
    assert_allclose(stcs[1].data, np.array(source_power).squeeze().T, atol=0)

    # Test using noise csds. We're going to use identity matrices. That way,
    # since we're using unit-noise-gain weight normalization, there should be
    # no effect.
    stcs = tf_dics(epochs, fwd_surf, None, tmin, tmax, tstep, win_lengths,
                   mode='cwt_morlet', frequencies=frequencies, decim=10,
                   reg=reg, label=label, normalize_fwd=False,
                   weight_norm='unit-noise-gain')
    noise_csd = csd.copy()
    inds = np.triu_indices(csd.n_channels)
    # Using [:, :] syntax for in-place broadcasting
    noise_csd._data[:, :] = 2 * np.eye(csd.n_channels)[inds][:, np.newaxis]
    noise_csd.n_fft = 2  # Dividing by n_fft should yield an identity CSD
    noise_csds = [noise_csd, noise_csd]  # Two frequency bins
    stcs_norm = tf_dics(epochs, fwd_surf, noise_csds, tmin, tmax, tstep,
                        win_lengths, mode='cwt_morlet',
                        frequencies=frequencies, decim=10, reg=reg,
                        label=label, normalize_fwd=False,
                        weight_norm='unit-noise-gain')
    assert_allclose(stcs_norm[0].data, stcs[0].data, atol=0)
    assert_allclose(stcs_norm[1].data, stcs[1].data, atol=0)

    # Test invalid parameter combinations
    raises(ValueError, tf_dics, epochs, fwd_surf, None, tmin, tmax, tstep,
           win_lengths, mode='fourier', freq_bins=None)
    raises(ValueError, tf_dics, epochs, fwd_surf, None, tmin, tmax, tstep,
           win_lengths, mode='cwt_morlet', frequencies=None)

    # Test if incorrect number of noise CSDs is detected
    raises(ValueError, tf_dics, epochs, fwd_surf, [noise_csds[0]], tmin, tmax,
           tstep, win_lengths, freq_bins=freq_bins)

    # Test if freq_bins and win_lengths incompatibility is detected
    raises(ValueError, tf_dics, epochs, fwd_surf, None, tmin, tmax, tstep,
           win_lengths=[0, 1, 2], freq_bins=freq_bins)

    # Test if time step exceeding window lengths is detected
    raises(ValueError, tf_dics, epochs, fwd_surf, None, tmin, tmax, tstep=0.15,
           win_lengths=[0.2, 0.1], freq_bins=freq_bins)

    # Test if incorrent number of n_ffts is detected
    raises(ValueError, tf_dics, epochs, fwd_surf, None, tmin, tmax, tstep,
           win_lengths, freq_bins=freq_bins, n_ffts=[1])

    # Test if incorrect number of mt_bandwidths is detected
    raises(ValueError, tf_dics, epochs, fwd_surf, None, tmin, tmax, tstep,
           win_lengths=win_lengths, freq_bins=freq_bins, mode='multitaper',
           mt_bandwidths=[20])

    # Test if subtracting evoked responses yields NaN's, since we only have one
    # epoch. Suppress division warnings.
    with pytest.warns(RuntimeWarning, match='[invalid|empty]'):
        stcs = tf_dics(epochs, fwd_surf, None, tmin, tmax, tstep, win_lengths,
                       mode='cwt_morlet', frequencies=frequencies,
                       subtract_evoked=True, reg=reg, label=label, decim=20)
    assert np.all(np.isnan(stcs[0].data))
예제 #32
0
                                      inversion='single',
                                      weight_norm=None,
                                      normalize_fwd=True,
                                      real_filter=False)
    filters_bas_gamma = make_dics(epo_bas.info,
                                  fwd_base,
                                  csd_bas_gamma,
                                  pick_ori='max-power',
                                  rank=None,
                                  inversion='single',
                                  weight_norm=None,
                                  normalize_fwd=True,
                                  real_filter=False)

    # apply the DICS beamformers to get source Estimates for ton, rest using common filters & save to file
    stc_ton_alpha, freqs_ton_alpha = apply_dics_csd(csd_ton_alpha,
                                                    filters_bas_alpha)
    stc_ton_theta, freqs_ton_theta = apply_dics_csd(csd_ton_theta,
                                                    filters_bas_theta)
    stc_ton_beta_low, freqs_ton_beta_low = apply_dics_csd(
        csd_ton_beta_low, filters_bas_beta_low)
    stc_ton_beta_high, freqs_ton_beta_high = apply_dics_csd(
        csd_ton_beta_high, filters_bas_beta_high)
    stc_ton_gamma, freqs_ton_gamma = apply_dics_csd(csd_ton_gamma,
                                                    filters_bas_gamma)
    stc_ton_alpha.save(fname=meg_dir + "nc_{}_stc_tonbas_alpha".format(meg))
    stc_ton_theta.save(fname=meg_dir + "nc_{}_stc_tonbas_theta".format(meg))
    stc_ton_beta_low.save(fname=meg_dir +
                          "nc_{}_stc_tonbas_beta_low".format(meg))
    stc_ton_beta_high.save(fname=meg_dir +
                           "nc_{}_stc_tonbas_beta_high".format(meg))
    stc_ton_gamma.save(fname=meg_dir + "nc_{}_stc_tonbas_gamma".format(meg))