Пример #1
0
def compute_surface_laplacian(epochs: Epochs, verbose: bool = True) -> Epochs:
    """
    Performs the surface Laplacian transform on the Epochs instance
    For more information about the transform parameters please refer to
    Cohen, M. X. (2014). Analyzing neural time series data: theory and practice
    . MIT press. For more information about this function in particular,
    visit the MNE documentation at:
    https://mne.tools/dev/generated/mne.preprocessing.compute_current_source_density.html
    Parameters
    ----------
    epochs: the epochs to be transformed
    verbose: whether to visualize the power spectral densities before and after
    the Laplacian transform

    Returns
    -------
    Raw instance
    """

    epochs_csd = compute_current_source_density(epochs.copy())

    if verbose:
        fig, axes_subplot = plt.subplots(
            nrows=2, ncols=1, sharex="all", sharey="all", dpi=220
        )

        epochs.plot_psd(ax=axes_subplot[0], show=False, fmax=60)
        epochs_csd.plot_psd(ax=axes_subplot[1], show=False, fmax=60)
        fig.show()

    return epochs_csd
Пример #2
0
def test_csd_matlab(evoked_csd_sphere):
    """Test replication of the CSD MATLAB toolbox."""
    evoked, csd, sphere = evoked_csd_sphere
    evoked_csd = compute_current_source_density(evoked, sphere=sphere)
    assert_allclose(linalg.norm(csd), 0.00177, atol=1e-5)
    # If we don't project onto the sphere, we get 1e-12 accuracy here,
    # but it's a bad assumption for real data!
    # Also, we divide by (radius ** 2) to get to units of V/m², unclear
    # why this isn't done in the upstream implementation
    evoked_csd_data = evoked_csd.data * sphere[-1] ** 2
    assert_allclose(evoked_csd_data, csd, atol=2e-7)

    with pytest.raises(ValueError, match=('CSD already applied, '
                                          'should not be reapplied')):
        compute_current_source_density(evoked_csd, sphere=sphere)

    # 1e-5 here if we don't project...
    assert_allclose(evoked_csd_data.sum(), 0.02455, atol=2e-3)
Пример #3
0
def test_csd_epochs(tmp_path):
    """Test making epochs, saving to disk and loading."""
    raw = read_raw_fif(raw_fname)
    raw.pick_types(eeg=True, stim=True).load_data()
    events = find_events(raw)
    epochs = Epochs(raw, events, reject=dict(eeg=1e-4), preload=True)
    epochs = compute_current_source_density(epochs)
    epo_fname = tmp_path / 'test_csd_epo.fif'
    epochs.save(epo_fname)
    epochs2 = read_epochs(epo_fname, preload=True)
    assert_allclose(epochs._data, epochs2._data)
Пример #4
0
def test_pick_types_csd():
    """Test pick_types(csd=True)."""
    # info with laplacian/CSD channels at indices 1, 2
    names = ['F1', 'F2', 'C1', 'C2', 'A1', 'A2', 'misc1', 'CSD1']
    info1 = create_info(
        names, 256, ["eeg", "eeg", "eeg", "eeg", "mag", "mag", 'misc', 'csd'])
    raw = RawArray(np.zeros((8, 512)), info1)
    raw.set_montage(make_standard_montage('standard_1020'), verbose='error')
    raw_csd = compute_current_source_density(raw, verbose='error')

    assert_array_equal(pick_types(info1, csd=True), [7])

    # pick from the raw object
    assert raw_csd.copy().pick_types(csd=True).ch_names == [
        'F1', 'F2', 'C1', 'C2', 'CSD1'
    ]
Пример #5
0
def test_csd_matlab(raw_epochs_sphere):
    """Test replication of the CSD MATLAB toolbox."""
    raw, epochs, sphere = raw_epochs_sphere
    n_epochs = len(epochs)
    picks = pick_types(epochs.info, meg=False, eeg=True, eog=False,
                       stim=False, exclude='bads')

    csd_data = sio.loadmat(csd_fname)

    montage = make_standard_montage('EGI_256', head_size=0.100004)
    positions = np.array([montage.dig[pick]['r'] * 10 for pick in picks])
    cosang = np.dot(positions, positions.T)
    G = _calc_g(cosang)
    assert_allclose(G, csd_data['G'], atol=1e-3)
    H = _calc_h(cosang)
    assert_allclose(H, csd_data['H'], atol=1e-3)
    for i in range(n_epochs):
        epochs_csd = compute_current_source_density(epochs, sphere=sphere)
        assert_allclose(epochs_csd.get_data(), csd_data['X'], atol=1e-3)

    # test raw
    csd_raw = compute_current_source_density(raw, sphere=sphere)

    with pytest.raises(ValueError, match=('CSD already applied, '
                                          'should not be reapplied')):
        compute_current_source_density(csd_raw, sphere=sphere)

    csd_raw_test_array = np.array([[2.29938168e-07, 1.55737642e-07],
                                   [-9.63976630e-09, 8.31646698e-09],
                                   [-2.30898926e-07, -1.56250505e-07],
                                   [-1.81081104e-07, -5.46661150e-08],
                                   [-9.08835568e-08, 1.61788422e-07],
                                   [5.38295661e-09, 3.75240220e-07]])
    assert_allclose(csd_raw._data[:, 100:102], csd_raw_test_array, atol=1e-3)

    csd_epochs = compute_current_source_density(epochs, sphere=sphere)
    assert_allclose(csd_epochs._data, csd_data['X'], atol=1e-3)

    csd_epochs = compute_current_source_density(epochs, sphere=sphere)

    csd_evoked = compute_current_source_density(epochs.average(),
                                                sphere=sphere)
    assert_allclose(csd_evoked.data, csd_data['X'].mean(0), atol=1e-3)
    assert_allclose(csd_evoked.data, csd_epochs._data.mean(0), atol=1e-3)
Пример #6
0
def test_csd_fif():
    """Test applying CSD to FIF data."""
    raw = read_raw_fif(raw_fname).load_data()
    raw.info['bads'] = []
    picks = pick_types(raw.info, meg=False, eeg=True)
    assert 'csd' not in raw
    orig_eeg = raw.get_data('eeg')
    assert len(orig_eeg) == 60
    raw_csd = compute_current_source_density(raw)
    assert 'eeg' not in raw_csd
    new_eeg = raw_csd.get_data('csd')
    assert not (orig_eeg == new_eeg).any()

    # reset the only things that should change, and assert objects are the same
    assert raw_csd.info['custom_ref_applied'] == FIFF.FIFFV_MNE_CUSTOM_REF_CSD
    raw_csd.info['custom_ref_applied'] = 0
    for pick in picks:
        ch = raw_csd.info['chs'][pick]
        assert ch['coil_type'] == FIFF.FIFFV_COIL_EEG_CSD
        assert ch['unit'] == FIFF.FIFF_UNIT_V_M2
        ch.update(coil_type=FIFF.FIFFV_COIL_EEG, unit=FIFF.FIFF_UNIT_V)
        raw_csd._data[pick] = raw._data[pick]
    assert object_diff(raw.info, raw_csd.info) == ''
Пример #7
0
def test_csd_degenerate(evoked_csd_sphere):
    """Test degenerate conditions."""
    evoked, csd, sphere = evoked_csd_sphere
    warn_evoked = evoked.copy()
    warn_evoked.info['bads'].append(warn_evoked.ch_names[3])
    with pytest.raises(ValueError, match='Either drop.*or interpolate'):
        compute_current_source_density(warn_evoked)

    with pytest.raises(TypeError, match='must be an instance of'):
        compute_current_source_density(None)

    fail_evoked = evoked.copy()
    with pytest.raises(ValueError, match='Zero or infinite position'):
        for ch in fail_evoked.info['chs']:
            ch['loc'][:3] = np.array([0, 0, 0])
        compute_current_source_density(fail_evoked, sphere=sphere)

    with pytest.raises(ValueError, match='Zero or infinite position'):
        fail_evoked.info['chs'][3]['loc'][:3] = np.inf
        compute_current_source_density(fail_evoked, sphere=sphere)

    with pytest.raises(ValueError, match='No EEG channels found.'):
        fail_evoked = evoked.copy()
        fail_evoked.set_channel_types({ch_name: 'ecog' for ch_name in
                                       fail_evoked.ch_names})
        compute_current_source_density(fail_evoked, sphere=sphere)

    with pytest.raises(TypeError, match='lambda2'):
        compute_current_source_density(evoked, lambda2='0', sphere=sphere)

    with pytest.raises(ValueError, match='lambda2 must be between 0 and 1'):
        compute_current_source_density(evoked, lambda2=2, sphere=sphere)

    with pytest.raises(TypeError, match='stiffness must be'):
        compute_current_source_density(evoked, stiffness='0', sphere=sphere)

    with pytest.raises(ValueError, match='stiffness must be non-negative'):
        compute_current_source_density(evoked, stiffness=-2, sphere=sphere)

    with pytest.raises(TypeError, match='n_legendre_terms must be'):
        compute_current_source_density(evoked, n_legendre_terms=0.1,
                                       sphere=sphere)

    with pytest.raises(ValueError, match=('n_legendre_terms must be '
                                          'greater than 0')):
        compute_current_source_density(evoked, n_legendre_terms=0,
                                       sphere=sphere)

    with pytest.raises(ValueError, match='sphere must be'):
        compute_current_source_density(evoked, sphere=-0.1)

    with pytest.raises(ValueError, match=('sphere radius must be '
                                          'greater than 0')):
        compute_current_source_density(evoked, sphere=(-0.1, 0., 0., -1.))

    with pytest.raises(TypeError):
        compute_current_source_density(evoked, copy=2, sphere=sphere)

    # gh-7859
    raw = RawArray(evoked.data, evoked.info)
    epochs = Epochs(
        raw, [[0, 0, 1]], tmin=0, tmax=evoked.times[-1] - evoked.times[0],
        baseline=None, preload=False, proj=False)
    epochs.drop_bad()
    assert len(epochs) == 1
    assert_allclose(epochs.get_data()[0], evoked.data)
    with pytest.raises(RuntimeError, match='Computing CSD requires.*preload'):
        compute_current_source_density(epochs)
    epochs.load_data()
    raw = compute_current_source_density(raw)
    assert not np.allclose(raw.get_data(), evoked.data)
    evoked = compute_current_source_density(evoked)
    assert_allclose(raw.get_data(), evoked.data)
    epochs = compute_current_source_density(epochs)
    assert_allclose(epochs.get_data()[0], evoked.data)
Пример #8
0
def test_csd_degenerate(evoked_csd_sphere):
    """Test degenerate conditions."""
    evoked, csd, sphere = evoked_csd_sphere
    warn_evoked = evoked.copy()
    warn_evoked.info['bads'].append(warn_evoked.ch_names[3])
    with pytest.raises(ValueError, match='Either drop.*or interpolate'):
        compute_current_source_density(warn_evoked)

    with pytest.raises(TypeError, match='must be an instance of'):
        compute_current_source_density(None)

    fail_evoked = evoked.copy()
    with pytest.raises(ValueError, match='Zero or infinite position'):
        for ch in fail_evoked.info['chs']:
            ch['loc'][:3] = np.array([0, 0, 0])
        compute_current_source_density(fail_evoked, sphere=sphere)

    with pytest.raises(ValueError, match='Zero or infinite position'):
        fail_evoked.info['chs'][3]['loc'][:3] = np.inf
        compute_current_source_density(fail_evoked, sphere=sphere)

    with pytest.raises(ValueError, match='No EEG channels found.'):
        fail_evoked = evoked.copy()
        fail_evoked.set_channel_types(
            {ch_name: 'ecog'
             for ch_name in fail_evoked.ch_names})
        compute_current_source_density(fail_evoked, sphere=sphere)

    with pytest.raises(TypeError, match='lambda2'):
        compute_current_source_density(evoked, lambda2='0', sphere=sphere)

    with pytest.raises(ValueError, match='lambda2 must be between 0 and 1'):
        compute_current_source_density(evoked, lambda2=2, sphere=sphere)

    with pytest.raises(TypeError, match='stiffness must be'):
        compute_current_source_density(evoked, stiffness='0', sphere=sphere)

    with pytest.raises(ValueError, match='stiffness must be non-negative'):
        compute_current_source_density(evoked, stiffness=-2, sphere=sphere)

    with pytest.raises(TypeError, match='n_legendre_terms must be'):
        compute_current_source_density(evoked,
                                       n_legendre_terms=0.1,
                                       sphere=sphere)

    with pytest.raises(ValueError,
                       match=('n_legendre_terms must be '
                              'greater than 0')):
        compute_current_source_density(evoked,
                                       n_legendre_terms=0,
                                       sphere=sphere)

    with pytest.raises(ValueError, match='sphere must be'):
        compute_current_source_density(evoked, sphere=-0.1)

    with pytest.raises(ValueError,
                       match=('sphere radius must be '
                              'greater than 0')):
        compute_current_source_density(evoked, sphere=(-0.1, 0., 0., -1.))

    with pytest.raises(TypeError):
        compute_current_source_density(evoked, copy=2, sphere=sphere)
Пример #9
0
    window = .5
    points = (epochs.tmax - epochs.tmin) * sfreq

    for i in range(points):
        t_start = epochs.tmin + (i / sfreq)
        t_end = t_start + window
        print(t_start, t_end)

        if t_end > epochs.tmax:
            break

        window_epoch = epochs.copy().crop(tmin=t_start, tmax=t_end)
        window_epoch = window_epoch.copy().resample(sfreq=500)

        # hjort-csd centered at c3 at 500Hz
        csd = compute_current_source_density(window_epoch,
                                             sphere=sphere_center)
        csd_data = csd.get_data()

        # fir forward-backward filter 8-12 Hz
        from mne.filter import create_filter
        filt = create_filter(data=csd_data,
                             sfreq=sfreq,
                             l_freq=8,
                             h_freq=12,
                             method='iir')

        csd_filtered = csd.filter(l_freq=8, h_freq=12, method='iir')

        # trimming of 64 ms start and end

        # AR prediction Yule-Walker order = 30