Ejemplo n.º 1
0
def test_multitaper_psd():
    """Test multi-taper PSD computation."""
    import nitime as ni
    for n_times in (100, 101):
        n_channels = 5
        data = np.random.RandomState(0).randn(n_channels, n_times)
        sfreq = 500
        info = create_info(n_channels, sfreq, 'eeg')
        raw = RawArray(data, info)
        pytest.raises(ValueError, psd_multitaper, raw, sfreq,
                      normalization='foo')
        ni_5 = (LooseVersion(ni.__version__) >= LooseVersion('0.5'))
        norm = 'full' if ni_5 else 'length'
        for adaptive, n_jobs in zip((False, True, True), (1, 1, 2)):
            psd, freqs = psd_multitaper(raw, adaptive=adaptive,
                                        n_jobs=n_jobs,
                                        normalization=norm)
            with warnings.catch_warnings(record=True):  # nitime integers
                freqs_ni, psd_ni, _ = ni.algorithms.spectral.multi_taper_psd(
                    data, sfreq, adaptive=adaptive, jackknife=False)
            assert_array_almost_equal(psd, psd_ni, decimal=4)
            if n_times % 2 == 0:
                # nitime's frequency definitions must be incorrect,
                # they give the same values for 100 and 101 samples
                assert_array_almost_equal(freqs, freqs_ni)
        with pytest.raises(ValueError, match='use a value of at least'):
            psd_multitaper(raw, bandwidth=4.9)
def calc_psd_epochs(epochs, plot=False):
    """Calculate PSD for epoch.

    Parameters
    ----------
    epochs : list of epochs
    plot : bool
        To show plot of the psds.
        It will be average for each condition that is shown.

    Returns
    -------
    psds_vol : numpy array
        The psds for the voluntary condition.
    psds_invol : numpy array
        The psds for the involuntary condition.
    """
    tmin, tmax = -0.5, 0.5
    fmin, fmax = 2, 90
    # n_fft = 2048  # the FFT size (n_fft). Ideally a power of 2
    psds_vol, freqs = psd_multitaper(epochs["voluntary"],
                                     tmin=tmin, tmax=tmax,
                                     fmin=fmin, fmax=fmax)
    psds_inv, freqs = psd_multitaper(epochs["involuntary"],
                                     tmin=tmin, tmax=tmax,
                                     fmin=fmin, fmax=fmax)

    psds_vol = 20 * np.log10(psds_vol)  # scale to dB
    psds_inv = 20 * np.log10(psds_inv)  # scale to dB

    if plot:
        def my_callback(ax, ch_idx):
            """Executed once you click on one of the channels in the plot."""
            ax.plot(freqs, psds_vol_plot[ch_idx], color='red',
                    label="voluntary")
            ax.plot(freqs, psds_inv_plot[ch_idx], color='blue',
                    label="involuntary")
            ax.set_xlabel = 'Frequency (Hz)'
            ax.set_ylabel = 'Power (dB)'
            ax.legend()

        psds_vol_plot = psds_vol.copy().mean(axis=0)
        psds_inv_plot = psds_inv.copy().mean(axis=0)

        for ax, idx in iter_topography(epochs.info,
                                       fig_facecolor='k',
                                       axis_facecolor='k',
                                       axis_spinecolor='k',
                                       on_pick=my_callback):
            ax.plot(psds_vol_plot[idx], color='red', label="voluntary")
            ax.plot(psds_inv_plot[idx], color='blue', label="involuntary")
        plt.legend()
        plt.gcf().suptitle('Power spectral densities')
        plt.show()

    return psds_vol, psds_inv, freqs
Ejemplo n.º 3
0
def compute_and_save_psd(epochs_fname, fmin=0, fmax=120,
                         method='welch', n_fft=256, n_overlap=0, 
                         picks=None, proj=False, n_jobs=1, verbose=None):
    """
    Load epochs from file,
    compute psd and save the result in numpy arrays
    """
    import numpy as np
    import os
    from mne import read_epochs
    epochs = read_epochs(epochs_fname)
    epochs_meg = epochs.pick_types(meg=True, eeg=False, eog=False, ecg=False)
    if method == 'welch':
        from mne.time_frequency import psd_welch
        psds, freqs = psd_welch(epochs_meg)
    elif method == 'multitaper':
        from mne.time_frequency import psd_multitaper
        psds, freqs = psd_multitaper(epochs_meg)
    else:
        raise Exception('nonexistent method for psd computation')
    path, name = os.path.split(epochs_fname)
    base, ext = os.path.splitext(name)
    psds_fname = base + '-psds.npz'
    # freqs_fname = base + '-freqs.npy'
    psds_fname = os.path.abspath(psds_fname)
    # print(psds.shape)
    np.savez(psds_fname, psds=psds, freqs=freqs)
    # np.save(freqs_file, freqs)
    return psds_fname
Ejemplo n.º 4
0
def test_multitaper_psd():
    """ Test multi-taper PSD computation """

    import nitime as ni
    n_times = 1000
    n_channels = 5
    data = np.random.RandomState(0).randn(n_channels, n_times)
    sfreq = 500
    info = create_info(n_channels, sfreq, 'eeg')
    raw = RawArray(data, info)
    assert_raises(ValueError, psd_multitaper, raw, sfreq, normalization='foo')
    ni_5 = (LooseVersion(ni.__version__) >= LooseVersion('0.5'))
    norm = 'full' if ni_5 else 'length'

    for adaptive, n_jobs in zip((False, True, True), (1, 1, 2)):
        psd, freqs = psd_multitaper(raw, adaptive=adaptive,
                                    n_jobs=n_jobs,
                                    normalization=norm)
        freqs_ni, psd_ni, _ = ni.algorithms.spectral.multi_taper_psd(
            data, sfreq, adaptive=adaptive, jackknife=False)

        # for some reason nitime returns n_times + 1 frequency points
        # causing the value at 0 to be different
        assert_array_almost_equal(psd[:, 1:], psd_ni[:, 1:-1], decimal=3)
        assert_array_almost_equal(freqs, freqs_ni[:-1])
Ejemplo n.º 5
0
def test_csd_multitaper():
    """Test computing cross-spectral density using multitapers."""
    epochs = _generate_coherence_data()
    sfreq = epochs.info['sfreq']
    _test_fourier_multitaper_parameters(epochs, csd_multitaper,
                                        csd_array_multitaper)

    # Compute CSDs using various parameters
    times = [(None, None), (1, 9)]
    as_arrays = [False, True]
    adaptives = [False, True]
    parameters = product(times, as_arrays, adaptives)
    for (tmin, tmax), as_array, adaptive in parameters:
        if as_array:
            csd = csd_array_multitaper(epochs.get_data(), sfreq, epochs.tmin,
                                       adaptive=adaptive, fmin=9, fmax=23,
                                       tmin=tmin, tmax=tmax,
                                       ch_names=epochs.ch_names)
        else:
            csd = csd_multitaper(epochs, adaptive=adaptive, fmin=9, fmax=23,
                                 tmin=tmin, tmax=tmax)
        if tmin is None and tmax is None:
            assert csd.tmin == 0 and csd.tmax == 9.98
        else:
            assert csd.tmin == tmin and csd.tmax == tmax
        csd = csd.mean([9.9, 14.9, 21.9], [10.1, 15.1, 22.1])
        _test_csd_matrix(csd)

    # Test equivalence with PSD
    psd, psd_freqs = psd_multitaper(epochs, fmin=1e-3,
                                    normalization='full')  # omit DC
    csd = csd_multitaper(epochs)
    assert_allclose(psd_freqs, csd.frequencies)
    csd = np.array([np.diag(csd.get_data(index=ii))
                    for ii in range(len(csd))]).T
    assert_allclose(psd[0], csd)

    # For the next test, generate a simple sine wave with a known power
    times = np.arange(20 * sfreq) / sfreq  # 20 seconds of signal
    signal = np.sin(2 * np.pi * 10 * times)[None, None, :]  # 10 Hz wave
    signal_power_per_sample = sum_squared(signal) / len(times)

    # Power per sample should not depend on time window length
    for tmax in [12, 18]:
        t_mask = (times <= tmax)
        n_samples = sum(t_mask)
        n_fft = len(times)

        # Power per sample should not depend on number of tapers
        for n_tapers in [1, 2, 5]:
            bandwidth = sfreq / float(n_samples) * (n_tapers + 1)
            csd_mt = csd_array_multitaper(signal, sfreq, tmax=tmax,
                                          bandwidth=bandwidth,
                                          n_fft=n_fft).sum().get_data()
            mt_power_per_sample = np.abs(csd_mt[0, 0]) * sfreq / n_fft
            assert abs(signal_power_per_sample - mt_power_per_sample) < 0.001
Ejemplo n.º 6
0
###############################################################################
# Let's first check out all channel types by averaging across epochs.
epochs.plot_psd(fmin=2., fmax=40., average=True, spatial_colors=False)

###############################################################################
# Now let's take a look at the spatial distributions of the PSD.
epochs.plot_psd_topomap(ch_type='grad', normalize=True)

###############################################################################
# Alternatively, you can also create PSDs from Epochs objects with functions
# that start with ``psd_`` such as
# :func:`mne.time_frequency.psd_multitaper` and
# :func:`mne.time_frequency.psd_welch`.

f, ax = plt.subplots()
psds, freqs = psd_multitaper(epochs, fmin=2, fmax=40, n_jobs=1)
psds = 10. * np.log10(psds)
psds_mean = psds.mean(0).mean(0)
psds_std = psds.mean(0).std(0)

ax.plot(freqs, psds_mean, color='k')
ax.fill_between(freqs, psds_mean - psds_std, psds_mean + psds_std,
                color='k', alpha=.5)
ax.set(title='Multitaper PSD (gradiometers)', xlabel='Frequency (Hz)',
       ylabel='Power Spectral Density (dB)')
plt.show()

###############################################################################
# Notably, :func:`mne.time_frequency.psd_welch` supports the keyword argument
# ``average``, which specifies how to estimate the PSD based on the individual
# windowed segments. The default is ``average='mean'``, which simply calculates
Ejemplo n.º 7
0
 def transform(self, x, y=None):
     psds, freqs = psd_multitaper(x, **self.kwargs)
     self.freqs = freqs
     return psds
"""
Created on Sat Aug 25 14:50:05 2018

@author: Malte Gueth
"""

import mne
from mne.time_frequency import psd_multitaper

# Load epoched data segments and compute power spectral density for all genres
# as alternative input for the rsa script
file = './epochs/sub-03-reordered-epo.fif'
epochs = mne.read_epochs(file)

picks = mne.pick_types(epochs.info, eeg=True)
tmin, tmax = 0, 1  # Pick time window within each epoch
fmin, fmax = 1, 60  # Pick frequency range

# Besides frequencies, the function returns an array of 320 epochs x 64 electrodes x 59 frequencies
psds, freqs = psd_multitaper(epochs,
                             tmin=tmin,
                             tmax=tmax,
                             fmin=fmin,
                             fmax=fmax,
                             picks=picks)
# And now do the same with SSP applied
raw.plot_psd(tmin=tmin, tmax=tmax, fmin=fmin, fmax=fmax, n_fft=n_fft,
             n_jobs=1, proj=True, ax=ax, color=(0, 1, 0), picks=picks,
             show=False)

# And now do the same with SSP + notch filtering
# Pick all channels for notch since the SSP projection mixes channels together
raw.notch_filter(np.arange(60, 241, 60), n_jobs=1)
raw.plot_psd(tmin=tmin, tmax=tmax, fmin=fmin, fmax=fmax, n_fft=n_fft,
             n_jobs=1, proj=True, ax=ax, color=(1, 0, 0), picks=picks,
             show=False)

ax.set_title('Four left-temporal magnetometers')
plt.legend(['Without SSP', 'With SSP', 'SSP + Notch'])

# Alternatively, you may also create PSDs from Raw objects with psd_XXX
f, ax = plt.subplots()
psds, freqs = psd_multitaper(raw, low_bias=True, tmin=tmin, tmax=tmax,
                             fmin=fmin, fmax=fmax, proj=True, picks=picks,
                             n_jobs=1)
psds = 10 * np.log10(psds)
psds_mean = psds.mean(0)
psds_std = psds.std(0)

ax.plot(freqs, psds_mean, color='k')
ax.fill_between(freqs, psds_mean - psds_std, psds_mean + psds_std,
                color='k', alpha=.5)
ax.set(title='Multitaper PSD', xlabel='Frequency',
       ylabel='Power Spectral Density (dB)')
plt.show()
Ejemplo n.º 10
0
def compute_PSD(epochs, freqlist=FREQS, method="multitaper", tmin=0, tmax=0.8):
    epochs_psds = []

    # Compute PSD
    if method == "multitaper":
        psds, freqs = psd_multitaper(
            epochs, fmin=min(min(freqlist)), fmax=max(max(freqlist)), n_jobs=1
        )
    if method == "pwelch":
        psds, freqs = psd_welch(
            epochs,
            average="median",
            fmin=min(min(freqlist)),
            fmax=max(max(freqlist)),
            n_jobs=1,
        )
    if method == "pwelch" or method == "multitaper":
        psds = 10.0 * np.log10(psds)  # Convert power to dB scale.
        # Average in freq bands
        for low, high in freqlist:
            freq_idx = [i for i, x in enumerate(freqs) if x >= low and x <= high]
            psd = np.mean(psds[:, :, freq_idx], axis=2)
            epochs_psds.append(psd)
        epochs_psds = np.array(epochs_psds).swapaxes(2, 0).swapaxes(1, 0)

        # TODO : compute via hilbert
    if method == "hilbert":
        for low, high in freqlist:
            # Filter continuous data
            data = epochs.copy().filter(low, high)  # Here epochs is a raw file
            hilbert = data.apply_hilbert(envelope=True)
            hilbert_pow = hilbert.copy()
            hilbert_pow._data = hilbert._data**2

            # Segment them
            picks = mne.pick_types(
                epochs.info, meg=True, ref_meg=False, eeg=False, eog=False, stim=False
            )
            try:
                events = mne.find_events(
                    epochs, min_duration=1 / epochs.info["sfreq"], verbose=False
                )
            except ValueError:
                events = mne.find_events(
                    epochs, min_duration=2 / epochs.info["sfreq"], verbose=False
                )
            event_id = {"Freq": 21, "Rare": 31}
            epochs = mne.Epochs(
                hilbert_pow,
                events=events,
                event_id=event_id,
                tmin=tmin,
                tmax=tmax,
                baseline=None,
                reject=None,
                picks=picks,
                preload=True,
            )
            epochs.drop(ARlog.bad_epochs)
            epochs_psds.append(epochs.get_data())
        epochs_psds = np.array(epochs_psds)
        epochs_psds = np.mean(epochs_psds, axis=3).transpose(1, 2, 0)
        print(epochs_psds.shape)
    return epochs_psds
Ejemplo n.º 11
0
epochs.plot_psd(fmin=2, fmax=200)

# picks MEG gradiometers
picks = mne.pick_types(raw.info,
                       meg='grad',
                       eeg=False,
                       eog=False,
                       stim=False,
                       exclude='bads')

# Now let's take a look at the spatial distributions of the psd.
epochs.plot_psd_topomap(ch_type='grad', normalize=True)

# Alternatively, you may also create PSDs from Epochs objects with psd_XXX
f, ax = plt.subplots()
psds, freqs = psd_multitaper(epochs, fmin=2, fmax=200, picks=picks, n_jobs=1)
psds = 10 * np.log10(psds)
psds_mean = psds.mean(0).mean(0)
psds_std = psds.mean(0).std(0)

ax.plot(freqs, psds_mean, color='k')
ax.fill_between(freqs,
                psds_mean - psds_std,
                psds_mean + psds_std,
                color='k',
                alpha=.5)
ax.set(title='Multitaper PSD (gradiometers)',
       xlabel='Frequency',
       ylabel='Power Spectral Density (dB)')
plt.show()
Ejemplo n.º 12
0
def preprocess(args):
    f_high = 128
    f_low = 1

    blink_removal = not args.no_blink_removal
    save_epochs = args.save_epochs

    # number_bad_channels = []

    montage = load_montage()
    montage_fig = montage.plot(scale_factor=20,
                               show_names=True,
                               kind='topomap',
                               show=False)
    montage_fig.savefig(data_dir + '/results/montage_2D.png', dpi=500)
    plt.close(montage_fig)
    montage_fig2 = montage.plot(scale_factor=20,
                                show_names=True,
                                kind='3d',
                                show=False)
    montage_fig2.savefig(data_dir + '/results/montagefig_3D.png', dpi=500)
    plt.close(montage_fig2)

    # fooof_fig, fooof_axes = plt.subplots(nrows=10, ncols=4, sharex=True, sharey=False, squeeze=False, figsize=(24, 40))
    # power_fig, power_axes = plt.subplots(nrows=10, ncols=4, sharex=True, sharey=False, squeeze=False, figsize=(24, 40))
    # topo_fig, topo_axes = plt.subplots(nrows=10, ncols=4, sharex=True, sharey=True, squeeze=False, figsize=(24, 40))

    all_fooofs = []

    fooof_r2s = np.zeros((n_participants, n_sessions))
    filter_r2s = np.zeros((n_participants, n_sessions))

    for participant_idx, participant in enumerate(participants):
        plt.close()

        # evoked_fig_filtered, evoked_ax_filtered = plt.subplots(nrows=10, ncols=3, sharex=True, sharey=False, squeeze=False, figsize=(10, 40))
        # evoked_fig_amplified, evoked_ax_amplified = plt.subplots(nrows=10, ncols=3, sharex=True, sharey=False, squeeze=False, figsize=(10, 40))

        for session_idx, session_name in enumerate(sessions):
            print('Participant', participant_idx + 1, '/', len(participants),
                  'session', session_idx + 1, '/', len(sessions))

            filename = data_dir + participant + '/' + participant + session_name + '.bdf'

            eeg = read_raw_edf(filename,
                               montage=montage,
                               eog=eog_channels,
                               preload=True,
                               verbose=0)
            # mne.set_eeg_reference(eeg, ref_channels='average', copy=True, projection=False)

            events = mne.find_events(eeg, verbose=0)
            reject = dict(eeg=80e-5, eog=60e-4)  # manually tuned argh

            eeg.pick_channels(channel_names)

            filter_eeg = eeg.copy()
            filter_eeg = filter_eeg.filter(1,
                                           40,
                                           picks=list(range(132)),
                                           n_jobs=7,
                                           verbose=0)  # band-pass

            print('Bandpass Filter')
            if blink_removal:
                print('ICA')
                eeg = ica_preprocessing(eeg, filter_eeg, participant,
                                        session_name, eog_channels[0], reject,
                                        f_low, f_high)
                eeg.set_eeg_reference('average', projection=True, verbose=0)
                eeg.apply_proj()

            if save_epochs:
                print('Saving Epochs')
                face_epochs, noise_epochs = save_epochs_as(
                    eeg, 'Raw', events, reject, participant, session_name)
                # plot_evoked(face_epochs, noise_epochs, evoked_ax_filtered, session_idx)

                if args.connectivity:
                    plot_connectivity(face_epochs, participant, session_name,
                                      'face', 'raw')
                    plot_connectivity(noise_epochs, participant, session_name,
                                      'noise', 'raw')

                del (face_epochs)
                del (noise_epochs)

            if save_epochs:
                print('Saving Epochs')
                condition = 'Bandpass'
                if not blink_removal:
                    condition = condition + ' (blinks)'

                face_epochs, noise_epochs = save_epochs_as(
                    filter_eeg, condition, events, reject, participant,
                    session_name)
                # plot_evoked(face_epochs, noise_epochs, evoked_ax_filtered, session_idx)

                if args.connectivity:
                    plot_connectivity(face_epochs, participant, session_name,
                                      'face', condition)
                    plot_connectivity(noise_epochs, participant, session_name,
                                      'noise', condition)

                del face_epochs
                del noise_epochs
                del filter_eeg

            if save_epochs:
                print('Highpass Filter')
                filter_eeg = eeg.copy()
                filter_eeg = filter_eeg.filter(1,
                                               None,
                                               picks=list(range(132)),
                                               n_jobs=7,
                                               verbose=0)

                condition = 'Highpass'
                if not blink_removal:
                    condition = condition + ' (blinks)'

                print('Saving Epochs')
                face_epochs, noise_epochs = save_epochs_as(
                    filter_eeg, condition, events, reject, participant,
                    session_name)
                # plot_evoked(face_epochs, noise_epochs, evoked_ax_filtered, session_idx)

                if args.connectivity:
                    plot_connectivity(face_epochs, participant, session_name,
                                      'face', condition)
                    plot_connectivity(noise_epochs, participant, session_name,
                                      'noise', condition)

                del face_epochs
                del noise_epochs
                del filter_eeg

            # print('Plot Power')
            # eeg.plot_psd(tmin=100, fmin=0.1, fmax=256, picks=list(range(128)), ax=power_axes[session_idx][participant_idx], area_mode='std', area_alpha=0.33, dB=True, estimate='auto', average=False, show=False, n_jobs=7, spatial_colors=True, verbose=0)

            # eeg.pick_channels(channel_names[0:128])
            # eeg.plot_psd_topo(tmin=100, dB=True, show=False, block=False, n_jobs=1, axes=topo_axes[session_idx][participant_idx], verbose=0)
            eeg = eeg.pick_channels(channel_names[0:132])

            print('Computing power spectrum for entire session...')
            start_time = time.time()
            psds, freqs = psd_multitaper(eeg, f_low, 45, n_jobs=7, verbose=0)
            print('Took', (time.time() - start_time) // 60, 'mins')

            print('Frequencies shape:', freqs.shape,
                  'Power spectrum distribution shape:', psds.shape)
            # psds, freqs = psd_welch(channel_rejected_eeg, fmin=0, fmax=n_freqs, tmin=500, tmax=2000, n_fft=2048, n_overlap=512, n_jobs=7)

            print('Fitting FOOOF...')
            start_time = time.time()
            fooof = FOOOF(min_peak_amplitude=0.05,
                          peak_width_limits=[3, 15],
                          background_mode='knee')
            fooof.fit(freqs, np.mean(psds, axis=0), freq_range=[f_low / 2, 45])
            print('FOOOF fit in', (time.time() - start_time) // 60, 'mins')
            # fooof.plot(plt_log=False, save_fig=True, file_name='FOOOF_' + participant + '_' + session_name, file_path=data_dir + '/results/')
            # fooof.plot(plt_log=False, ax=fooof_axes[session_idx][participant_idx])

            fooof_r2s[participant_idx][session_idx] = fooof.r_squared_
            all_fooofs.append(fooof)

            # amplify time series
            print('Amplifying Time')

            eeg_time_series = eeg.get_data(picks=list(range(132)))

            amplified_time_series = np.zeros_like(eeg_time_series)
            print('Learning Filters')
            log_filter_coeffs, gaussian_filter_coeffs, log_amplitudes, gaussian_amplitudes, amp_figs, ideal_gains, log_offset = fooof.learn_filters(
                512, 5)

            amplitudes = log_amplitudes + gaussian_amplitudes
            filter_coeffs = log_filter_coeffs + gaussian_filter_coeffs

            for plot_idx, amp_fig in enumerate(amp_figs):
                # amp_fig.savefig(data_dir + '/results/' + participant + session_name + '_amplifier_' + str(plot_idx) + '.png')
                plt.close(amp_fig)

            fig, fig2, filter_r2 = plot_amplifier(
                log_filter_coeffs, log_amplitudes, gaussian_filter_coeffs,
                gaussian_amplitudes, 512, ideal_gains, fooof, log_offset)
            filter_r2s[participant_idx][session_idx] = filter_r2

            # fig3, filter_responses = plt.subplots(1, 2, figsize=(12, 4))
            # amplified_spectra = []

            print('Applying Filters')
            for i, (coeffs,
                    amplitude) in enumerate(zip(filter_coeffs, amplitudes)):
                if coeffs is not None:
                    if isinstance(coeffs[0], np.float64):
                        # fun = partial(lfilter, b=coeffs, a=[1.0], axis=-1)
                        fun = partial(filtfilt, b=coeffs, a=[1.0], axis=-1)
                    else:
                        fun = partial(filtfilt,
                                      b=coeffs[0],
                                      a=coeffs[1],
                                      axis=-1)
                        # fun = partial(lfilter, b=coeffs[0], a=coeffs[1], axis=-1)

                    parallel, p_fun, _ = parallel_func(fun, 7)
                    filtered_eeg = parallel(
                        p_fun(x=eeg_time_series[p]) for p in range(132))

                    # filtered_eeg = filtered_eeg - np.mean(filtered_eeg, axis=0)

                    # print('yet another power spectrum')
                    # frequencies, pxx = welch(filtered_eeg, 512)
                    # amplified_spectra.append(pxx)
                    # filter_responses[0].plot(frequencies, np.log10(np.mean(pxx, axis=0)))

                    for p in range(132):
                        amplified_time_series[p] += (filtered_eeg[p] *
                                                     amplitude)

            # filter_responses[-1].plot(frequencies, np.log10(np.mean(sum(amplified_spectra), axis=0)))
            # fig3.savefig(data_dir + '/results/' + participant + session_name + '_psd_filters.png')
            # plt.close(fig3)

            epoch_info = mne.pick_info(eeg.info,
                                       sel=(list(range(132))),
                                       copy=True)

            eeg = mne.io.RawArray(np.float64(amplified_time_series),
                                  epoch_info,
                                  verbose=0)

            amped_psds, freqs = psd_multitaper(eeg,
                                               f_low,
                                               45,
                                               n_jobs=7,
                                               verbose=0)

            last_subfig = fig.axes[-1]
            last_subfig.plot(freqs,
                             np.log10(np.mean(psds, axis=0)),
                             color='k',
                             label='Original Spectrum')
            last_subfig.plot(freqs,
                             np.log10(np.mean(amped_psds, axis=0)),
                             color='blue',
                             linewidth=2,
                             label='Normalized Spectrum')
            last_subfig.legend(loc="lower right",
                               fontsize=16,
                               shadow=True,
                               fancybox=True)
            # last_subfig.plot(freqs, np.log10(np.mean(amped_psds, axis=0) - np.mean(psds, axis=0)), color='red', linewidth=1)

            last_subfig.set_ylabel('Power', fontsize=16)
            last_subfig.set_xlabel('Frequency (Hz)', fontsize=16)
            last_subfig.set_title('Normalized\nPower Spectrum', fontsize=20)

            for tick in last_subfig.xaxis.get_major_ticks():
                tick.label.set_fontsize(16)
            for tick in last_subfig.yaxis.get_major_ticks():
                tick.label.set_fontsize(16)

            fig.savefig(data_dir + '/results/' + participant + session_name +
                        '_amplifier.png',
                        dpi=500,
                        bbox_inches='tight')
            fig2.savefig(data_dir + '/results/' + participant + session_name +
                         '_log_approx.png',
                         dpi=500,
                         bbox_inches='tight')
            plt.close(fig)
            plt.close(fig2)

            if save_epochs:
                print('Saving Amplified Epochs')
                condition = 'NPA'
                if not blink_removal:
                    condition = condition + ' (blinks)'

                face_epochs, noise_epochs = save_epochs_as(
                    eeg, condition, events, None, participant, session_name)
                # plot_evoked(face_epochs, noise_epochs, evoked_ax_amplified, session_idx)

                if args.connectivity:
                    plot_connectivity(face_epochs, participant, session_name,
                                      'face', condition)
                    plot_connectivity(noise_epochs, participant, session_name,
                                      'noise', condition)

                del (face_epochs)
                del (noise_epochs)

        # evoked_fig_filtered.savefig(data_dir + '/results/evoked_filtered' + participant + '.png', dpi=500, bbox_inches='tight')
        # evoked_fig_amplified.savefig(data_dir + '/results/evoked_amplified' + participant + '.png', dpi=500, bbox_inches='tight')

        # for preproc_type in preproc_types:
        #     evoked_fig = evoked_fig[preproc_type]
        #     evoked_fig.savefig(data_dir + '/results/evoked_' + preproc_type + participant + '.png', dpi=500, bbox_inches='tight')

    # fooof_fig.savefig(data_dir + '/results/fooofs.png', dpi=500, bbox_inches='tight')
    # power_fig.savefig(data_dir + '/results/power.png', dpi=500, bbox_inches='tight')

    print('FOOOF r squared')
    print(fooof_r2s)

    print('NPA r squared')
    print(filter_r2s)

    print('NPA r2 stats:', np.mean(filter_r2s), np.var(filter_r2s))

    r2_fig, r2_ax = plt.subplots(1, 2, figsize=(12, 4), sharey=True)

    r2_boxes1 = r2_ax[0].boxplot(fooof_r2s.T, patch_artist=True)
    r2_boxes2 = r2_ax[1].boxplot(filter_r2s.T, patch_artist=True)

    r2_ax[0].set_ylabel('$r^2$', fontsize=16)
    # r2_ax[1].set_ylabel('$r^2$', fontsize=16)

    r2_ax[0].set_xticklabels(['1', '2', '3', '4'])
    r2_ax[1].set_xticklabels(['1', '2', '3', '4'])

    r2_ax[0].set_xlabel('Participant', fontsize=16)
    r2_ax[1].set_xlabel('Participant', fontsize=16)

    for tick in r2_ax[0].xaxis.get_major_ticks():
        tick.label.set_fontsize(16)
    for tick in r2_ax[1].xaxis.get_major_ticks():
        tick.label.set_fontsize(16)

    for tick in r2_ax[0].yaxis.get_major_ticks():
        tick.label.set_fontsize(16)
    for tick in r2_ax[1].yaxis.get_major_ticks():
        tick.label.set_fontsize(16)

    r2_ax[0].yaxis.grid(True)
    r2_ax[1].yaxis.grid(True)

    for patch, colour in zip(r2_boxes1['boxes'], colours):
        patch.set_facecolor(colour)

    for patch, colour in zip(r2_boxes2['boxes'], colours):
        patch.set_facecolor(colour)

    r2_fig.savefig(data_dir + '/results/r2.png')

    all_slopes = []
    all_knees = []

    # scatter plot of slope/knee

    for fm in all_fooofs:
        all_slopes.append(fm.background_params_[2])
        all_knees.append(fm.background_params_[1])

    slope_knee_fig, slope_knee_ax = plt.subplots(1, 1, figsize=(6, 4))

    print('Min/Max slope:', np.min(np.array(all_slopes)),
          np.max(np.array(all_slopes)))
    print('Min/Max knee:', np.min(np.array(all_knees)),
          np.max(np.array(all_knees)))

    slope_knee_ax.scatter(all_slopes[0:9],
                          all_knees[0:9],
                          label='Participant 1')
    slope_knee_ax.scatter(all_slopes[10:19],
                          all_knees[10:19],
                          marker='d',
                          label='Participant 2')
    slope_knee_ax.scatter(all_slopes[20:29],
                          all_knees[20:29],
                          marker='x',
                          label='Participant 3')
    slope_knee_ax.scatter(all_slopes[30:39],
                          all_knees[30:39],
                          marker='+',
                          label='Participant 4')

    slope_knee_ax.set_xlabel('Slope ($\chi$)', fontsize=16)
    slope_knee_ax.set_ylabel('Knee ($k$)', fontsize=16)
    slope_knee_ax.legend(loc='center left',
                         bbox_to_anchor=(1, 0.5),
                         fancybox=True,
                         shadow=True)

    slope_knee_ax.set_yscale('log')

    for tick in slope_knee_ax.xaxis.get_major_ticks():
        tick.label.set_fontsize(16)
    for tick in slope_knee_ax.yaxis.get_major_ticks():
        tick.label.set_fontsize(16)

    slope_knee_fig.savefig(data_dir + '/results/' + 'slope_knee_fig.png',
                           dpi=500,
                           bbox_inches='tight')
Ejemplo n.º 13
0
set_log_level(verbose="ERROR")

ch_type = "grad"
# load the data
X, y = assemble_epochs("answer")  # dict with subj -> epochs mapping

info_src = bp.epochs.fpath(subject="01")
info = read_info(info_src)
sel_idx = pick_types(info, meg="grad")
info.pick_channels([info.ch_names[s] for s in sel_idx])

ep_low = EpochsArray(X[y == LOW_CONF_EPOCH, ...], info, tmin=-1)
ep_high = EpochsArray(X[y == HIGH_CONF_EPOCH, ...], info, tmin=-1)
# erf_diff = combine_evoked([ep_low, -ep_high], weights="equal")

psds_high, freqs = psd_multitaper(ep_high, tmin=0, tmax=1, fmax=50)
psds_low, freqs = psd_multitaper(ep_low, tmin=0, tmax=1, fmax=50)

theta_mask = np.logical_and(4 <= freqs, freqs < 8)
theta_power_low = psds_low[:, :, theta_mask].mean(axis=2)
theta_power_high = psds_high[:, :, theta_mask].mean(axis=2)

(
    picks,
    pos,
    merge_channels,
    names,
    ch_type,
    sphere,
    clip_origin,
) = _prepare_topomap_plot(ep_low, ch_type, sphere=None)
Ejemplo n.º 14
0
###############################################################################
# Alternative functions for PSDs
# ------------------------------
#
# There are also several functions in MNE that create a PSD using a Raw
# object. These are in the :mod:`mne.time_frequency` module and begin with
# ``psd_*``. For example, we'll use a multitaper method to compute the PSD
# below.

f, ax = plt.subplots()
psds, freqs = psd_multitaper(raw,
                             low_bias=True,
                             tmin=tmin,
                             tmax=tmax,
                             fmin=fmin,
                             fmax=fmax,
                             proj=True,
                             picks=picks,
                             n_jobs=1)
psds = 10 * np.log10(psds)
psds_mean = psds.mean(0)
psds_std = psds.std(0)

ax.plot(freqs, psds_mean, color='k')
ax.fill_between(freqs,
                psds_mean - psds_std,
                psds_mean + psds_std,
                color='k',
                alpha=.5)
ax.set(title='Multitaper PSD',
Ejemplo n.º 15
0
def _generate_report(raw, ica, subj_name, basename, ecg_evoked, ecg_scores,
                     ecg_inds, ecg_ch_name, eog_evoked, eog_scores, eog_inds,
                     eog_ch_name):
    """Generate report for ica solution."""
    import matplotlib.pyplot as plt

    report = Report()

    ica_title = 'Sources related to %s artifacts (red)'
    is_show = False

    # ------------------- Generate report for ECG ------------------------ #
    fig_ecg_scores = ica.plot_scores(ecg_scores,
                                     exclude=ecg_inds,
                                     title=ica_title % 'ecg',
                                     show=is_show)

    # Pick the five largest ecg_scores and plot them
    show_picks = np.abs(ecg_scores).argsort()[::-1][:5]

    # Plot estimated latent sources given the unmixing matrix.
    fig_ecg_ts = ica.plot_sources(raw,
                                  show_picks,
                                  exclude=ecg_inds,
                                  title=ica_title % 'ecg' + ' in 30s',
                                  start=0,
                                  stop=30,
                                  show=is_show)

    # topoplot of unmixing matrix columns
    fig_ecg_comp = ica.plot_components(show_picks,
                                       title=ica_title % 'ecg',
                                       colorbar=True,
                                       show=is_show)

    # plot ECG sources + selection
    fig_ecg_src = ica.plot_sources(ecg_evoked, exclude=ecg_inds, show=is_show)
    fig = [fig_ecg_scores, fig_ecg_ts, fig_ecg_comp, fig_ecg_src]
    report.add_figs_to_section(fig,
                               captions=[
                                   'Scores of ICs related to ECG',
                                   'Time Series plots of ICs (ECG)',
                                   'TopoMap of ICs (ECG)',
                                   'Time-locked ECG sources'
                               ],
                               section='ICA - ECG')
    # -------------------- end generate report for ECG ---------------------- #

    # -------------------------- Generate report for EoG -------------------- #
    # check how many EoG ch we have
    if set(eog_ch_name.split(',')).issubset(set(raw.info['ch_names'])):
        fig_eog_scores = ica.plot_scores(eog_scores,
                                         exclude=eog_inds,
                                         title=ica_title % 'eog',
                                         show=is_show)

        report.add_figs_to_section(fig_eog_scores,
                                   captions=['Scores of ICs related to EOG'],
                                   section='ICA - EOG')

        n_eogs = np.shape(eog_scores)
        if len(n_eogs) > 1:
            n_eog0 = n_eogs[0]
            show_picks = [
                np.abs(eog_scores[i][:]).argsort()[::-1][:5]
                for i in range(n_eog0)
            ]
            for i in range(n_eog0):
                fig_eog_comp = ica.plot_components(show_picks[i][:],
                                                   title=ica_title % 'eog',
                                                   colorbar=True,
                                                   show=is_show)

                fig = [fig_eog_comp]
                report.add_figs_to_section(fig,
                                           captions=['Scores of EoG ICs'],
                                           section='ICA - EOG')
        else:
            show_picks = np.abs(eog_scores).argsort()[::-1][:5]
            fig_eog_comp = ica.plot_components(show_picks,
                                               title=ica_title % 'eog',
                                               colorbar=True,
                                               show=is_show)

            fig = [fig_eog_comp]
            report.add_figs_to_section(fig,
                                       captions=['TopoMap of ICs (EOG)'],
                                       section='ICA - EOG')

        fig_eog_src = ica.plot_sources(eog_evoked,
                                       exclude=eog_inds,
                                       show=is_show)

        fig = [fig_eog_src]
        report.add_figs_to_section(fig,
                                   captions=['Time-locked EOG sources'],
                                   section='ICA - EOG')
    # ----------------- end generate report for EoG ---------- #
    ic_nums = list(range(ica.n_components_))
    fig = ica.plot_components(picks=ic_nums, show=False)
    report.add_figs_to_section(fig,
                               captions=['All IC topographies'],
                               section='ICA - muscles')

    fig = ica.plot_sources(raw,
                           start=0,
                           stop=None,
                           show=False,
                           title='All IC time series')
    report.add_figs_to_section(fig,
                               captions=['All IC time series'],
                               section='ICA - muscles')

    psds_fig = []
    captions_psd = []
    ica_src = ica.get_sources(raw)
    for i_ic in ic_nums:

        psds, freqs = psd_multitaper(ica_src, picks=i_ic, fmax=140, tmax=60)
        psds = np.squeeze(psds)

        f, ax = plt.subplots()
        psds = 10 * np.log10(psds)

        ax.plot(freqs, psds, color='k')
        ax.set(title='PSD',
               xlabel='Frequency',
               ylabel='Power Spectral Density (dB)')

        psds_fig.append(f)
        captions_psd.append('IC #' + str(i_ic))

    report.add_figs_to_section(figs=psds_fig,
                               captions=captions_psd,
                               section='ICA - muscles')

    report_filename = os.path.join(basename + "-report.html")
    print(('******* ' + report_filename))
    report.save(report_filename, open_browser=False, overwrite=True)
    return report_filename
 for file_to_read in list_file_to_read:    
     raw=mne.io.read_raw_fif(file_to_read[:-5]+'.fif',preload=True,add_eeg_ref=False)
     result[file_to_read[:-5]]=dict()
     channelList = ['F3','F4','C3','C4','O1','O2']
     raw.pick_channels(channelList)
     picks = mne.pick_types(raw.info,eeg=True,eog=False)
     raw.filter(1,None,picks=picks,l_trans_bandwidth=0.5)
     fmin=0;fmax=50;epoch_length=30
     epochs = eegPinelineDesign.make_overlap_windows(raw,epoch_length=epoch_length)
     psd_dict=dict()
     for names in channelList:
         psd_dict[names]=[]
     for ii,epch in enumerate(epochs):
         eegPinelineDesign.update_progress(ii,len(epochs))
         psds, freqs = psd_multitaper(raw, low_bias=True, tmin=epch[0], tmax=epch[1],
                          fmin=fmin, fmax=fmax, proj=False, picks=picks,
                          n_jobs=-1)
         psds = 10 * np.log10(psds)
         for jj,names in enumerate(channelList):
             psd_dict[names].append(psds[jj,:])
     psd_by_channel=dict()
     temp_total=[]
     fig=plt.figure(figsize=(30,30))
     ax0=fig.add_subplot(331)
     for jj,names in enumerate(channelList):
         temp_total.append(psd_dict[names])
         temp = np.vstack(psd_dict[names])
         psd_by_channel[names]=[temp.mean(0),temp.std(0)]
         if jj == 0:
             ax = ax0
         else:
Ejemplo n.º 17
0
def calc_psd_epochs(epochs, plot=False):
    """Calculate PSD for epoch.

    Parameters
    ----------
    epochs : list of epochs
    plot : bool
        To show plot of the psds.
        It will be average for each condition that is shown.

    Returns
    -------
    psds_vol : numpy array
        The psds for the voluntary condition.
    psds_invol : numpy array
        The psds for the involuntary condition.
    """
    tmin, tmax = -0.5, 0.5
    fmin, fmax = 2, 90
    # n_fft = 2048  # the FFT size (n_fft). Ideally a power of 2
    psds_vol, freqs = psd_multitaper(epochs["voluntary"],
                                     tmin=tmin,
                                     tmax=tmax,
                                     fmin=fmin,
                                     fmax=fmax)
    psds_inv, freqs = psd_multitaper(epochs["involuntary"],
                                     tmin=tmin,
                                     tmax=tmax,
                                     fmin=fmin,
                                     fmax=fmax)

    psds_vol = 20 * np.log10(psds_vol)  # scale to dB
    psds_inv = 20 * np.log10(psds_inv)  # scale to dB

    if plot:

        def my_callback(ax, ch_idx):
            """Executed once you click on one of the channels in the plot."""
            ax.plot(freqs,
                    psds_vol_plot[ch_idx],
                    color='red',
                    label="voluntary")
            ax.plot(freqs,
                    psds_inv_plot[ch_idx],
                    color='blue',
                    label="involuntary")
            ax.set_xlabel = 'Frequency (Hz)'
            ax.set_ylabel = 'Power (dB)'
            ax.legend()

        psds_vol_plot = psds_vol.copy().mean(axis=0)
        psds_inv_plot = psds_inv.copy().mean(axis=0)

        for ax, idx in iter_topography(epochs.info,
                                       fig_facecolor='k',
                                       axis_facecolor='k',
                                       axis_spinecolor='k',
                                       on_pick=my_callback):
            ax.plot(psds_vol_plot[idx], color='red', label="voluntary")
            ax.plot(psds_inv_plot[idx], color='blue', label="involuntary")
        plt.legend()
        plt.gcf().suptitle('Power spectral densities')
        plt.show()

    return psds_vol, psds_inv, freqs
Ejemplo n.º 18
0
epochs = mne.Epochs(raw, events, event_id, tmin, tmax,
                    proj=True, baseline=(None, 0), preload=True,
                    reject=dict(grad=4000e-13, eog=150e-6))
# Pull 2**n points to speed up computation
tmax = tmin + 1023. / raw.info['sfreq']
epochs.crop(None, tmax)

# Let's first check out all channel types by averaging across epochs.
epochs.plot_psd(fmin=2, fmax=200)

# picks MEG gradiometers
picks = mne.pick_types(raw.info, meg='grad', eeg=False, eog=False,
                       stim=False, exclude='bads')

# Now let's take a look at the spatial distributions of the psd.
epochs.plot_psd_topomap(ch_type='grad', normalize=True)

# Alternatively, you may also create PSDs from Epochs objects with psd_XXX
f, ax = plt.subplots()
psds, freqs = psd_multitaper(epochs, fmin=2, fmax=200, picks=picks, n_jobs=1)
psds = 10 * np.log10(psds)
psds_mean = psds.mean(0).mean(0)
psds_std = psds.mean(0).std(0)

ax.plot(freqs, psds_mean, color='k')
ax.fill_between(freqs, psds_mean - psds_std, psds_mean + psds_std,
                color='k', alpha=.5)
ax.set(title='Multitaper PSD (gradiometers)', xlabel='Frequency',
       ylabel='Power Spectral Density (dB)')
plt.show()
Ejemplo n.º 19
0
def Analyse_EEG(df):
    """
    Analyses a dataframe containing raw EEG data
    """

    #  First we have to create the Raw MNE object to be
    # able to use the MNE library for the analysis

    eegchannels = df.iloc[:, 0:8]
    ch_names = list(eegchannels.columns)
    sfreq = 250
    ch_types = ['eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg']
    info = mne.create_info(ch_names, sfreq, ch_types=ch_types)

    raw = mne.io.RawArray(eegchannels.T, info)

    tmin, tmax = 0, len(raw.get_data('Ch1')[0])

    #  Data was already notch filtered during recording at around 50Hz.

    #  psd_multitaper returns power spectral densities in psd (in this case
    #  in shape (n_channels, n_freqs). The freqs contains information at
    #  which frequency we had this power. The frequencies are spread between
    #  the values defined below:

    fmin, fmax = 1, 100

    psds, freqs = psd_multitaper(raw,
                                 low_bias=True,
                                 tmin=tmin,
                                 tmax=tmax,
                                 fmin=fmin,
                                 fmax=fmax,
                                 proj=True,
                                 picks=['all'],
                                 n_jobs=1)
    psds = 10 * np.log10(psds)

    psds_mean = psds.mean(0)
    psds_std = psds.std(0)

    #  To convert the data into sensible band powers, we need to convert to Hz and extract the bands
    # The Hz conversion is data_length divided by (1/sampling freq)
    fft_freq = np.fft.rfftfreq((len(raw.get_data('Ch1')[0])), 1.0 / sfreq)

    # Define EEG bands
    eeg_bands = {
        'Delta': (0, 4),
        'Theta': (4, 8),
        'Alpha': (8, 12),
        'Beta': (12, 30),
        'Gamma_low': (30, 45),
        'Gamma_high': (55, 80)
    }

    eeg_band_fft = dict()
    for band in eeg_bands:
        freq_ix = np.where((fft_freq >= eeg_bands[band][0])
                           & (fft_freq <= eeg_bands[band][1]))[0]
        eeg_band_fft[band] = np.mean(psds[:, freq_ix], axis=1)

    for band in eeg_bands:
        freq_ix = np.where((fft_freq >= eeg_bands[band][0])
                           & (fft_freq <= eeg_bands[band][1]))[0]
        eeg_band_fft[band + '_std'] = np.std(psds[:, freq_ix], axis=1)

    #  create a Pandas DataFrame, and normalize the values for each participant
    eeg_df = pd.DataFrame.from_dict(eeg_band_fft)

    #  Lets normalize each participant: we are only interested in the relative differences between
    # electrodes

    overall_power_mean = np.mean(np.mean(eeg_df.iloc[:, 0:6]))
    eeg_df.iloc[:, 0:6] = eeg_df.iloc[:, 0:6] / overall_power_mean
    overall_std_mean = np.mean(np.mean(eeg_df.iloc[:, 6:]))
    eeg_df.iloc[:, 6:] = eeg_df.iloc[:, 6:] / overall_std_mean
    return eeg_df
###############################################################################
# Let's first check out all channel types by averaging across epochs.
epochs.plot_psd(fmin=2., fmax=40.)

###############################################################################
# Now let's take a look at the spatial distributions of the PSD.
epochs.plot_psd_topomap(ch_type='grad', normalize=True)

###############################################################################
# Alternatively, you can also create PSDs from Epochs objects with functions
# that start with ``psd_`` such as
# :func:`mne.time_frequency.psd_multitaper` and
# :func:`mne.time_frequency.psd_welch`.

f, ax = plt.subplots()
psds, freqs = psd_multitaper(epochs, fmin=2, fmax=40, n_jobs=1)
psds = 10. * np.log10(psds)
psds_mean = psds.mean(0).mean(0)
psds_std = psds.mean(0).std(0)

ax.plot(freqs, psds_mean, color='k')
ax.fill_between(freqs, psds_mean - psds_std, psds_mean + psds_std,
                color='k', alpha=.5)
ax.set(title='Multitaper PSD (gradiometers)', xlabel='Frequency',
       ylabel='Power Spectral Density (dB)')
plt.show()

###############################################################################
# Time-frequency analysis: power and inter-trial coherence
# --------------------------------------------------------
#
Ejemplo n.º 21
0
    def __init__(self,
                 epochs,
                 fmin=0,
                 fmax=1500,
                 tmin=None,
                 tmax=None,
                 method='multitaper',
                 picks=None,
                 montage=None,
                 **kwargs):
        """
        Computes the PSD of the epochs with the correct method multitaper or welch
        """

        self.fmin, self.fmax = fmin, fmax
        self.tmin, self.tmax = tmin, tmax
        self.info = epochs.info
        self.method = method
        self.bandwidth = kwargs.get('bandwidth', 4.)
        self.n_fft = kwargs.get('n_fft', 256)
        self.n_per_seg = kwargs.get('n_per_seg', self.n_fft)
        self.n_overlap = kwargs.get('n_overlap', 0)
        self.cmap = 'inferno'

        if picks is not None:
            self.picks = picks
        else:
            self.picks = range(0, len(epochs.info['ch_names']))

        if montage is not None:
            # First we create variable head_pos for a correct plotting
            self.pos = montage.get_pos2d()
            scale = 0.85 / (self.pos.max(axis=0) - self.pos.min(axis=0))
            center = 0.5 * (self.pos.max(axis=0) + self.pos.min(axis=0))
            self.head_pos = {'scale': scale, 'center': center}

            # Handling of possible channels without any known coordinates
            no_coord_channel = False
            try:
                names = montage.ch_names
                indices = [
                    names.index(epochs.info['ch_names'][i]) for i in self.picks
                ]
                self.pos = self.pos[indices, :]
            except:
                no_coord_channel = True

            # If there is not as much positions as the number of Channels
            # we have to eliminate some channels from the data of topomaps
            if no_coord_channel:
                print('got here')
                from mne.channels import read_montage
                from numpy import array

                index = 0
                self.pos = []  # positions
                self.with_coord = []  # index in the self.data of channels
                # with a cooordinate
                for i in self.picks:
                    ch_name = epochs.info['ch_names'][i]
                    try:
                        ch_montage = read_montage(montage.kind,
                                                  ch_names=[ch_name])
                        coord = ch_montage.get_pos2d()
                        self.pos.append(coord[0])
                        self.with_coord.append(index)
                    except:
                        pass
                    index += 1
                self.pos = array(self.pos)

            else:
                self.with_coord = [i for i in range(len(self.picks))]

        else:  # If there is no montage available
            self.head_pos = None

        if method == 'multitaper':
            from mne.time_frequency import psd_multitaper

            print(
                "Computing Mulitaper PSD with parameter bandwidth = {}".format(
                    self.bandwidth))
            self.data, self.freqs = psd_multitaper(epochs,
                                                   fmin=fmin,
                                                   fmax=fmax,
                                                   tmin=tmin,
                                                   tmax=tmax,
                                                   normalization='full',
                                                   bandwidth=self.bandwidth,
                                                   picks=self.picks)

        if method == 'welch':
            from mne.time_frequency import psd_welch

            print("Computing Welch PSD with parameters" +
                  " n_fft = {}, n_per_seg = {}, n_overlap = {}".format(
                      self.n_fft, self.n_per_seg, self.n_overlap))
            self.data, self.freqs = psd_welch(epochs,
                                              fmin=fmin,
                                              fmax=fmax,
                                              tmin=tmin,
                                              tmax=tmax,
                                              n_fft=self.n_fft,
                                              n_overlap=self.n_overlap,
                                              n_per_seg=self.n_per_seg,
                                              picks=self.picks)
Ejemplo n.º 22
0
def frequency_analysis(epochs,
                       states=[
                           'meditate', 'baseline', 'lent', 'rapide', 'libre',
                           'resting1', 'val'
                       ],
                       show=True,
                       pick='C4'):
    '''
    Function to return psd of each state
    
    Parameters
    ---------- 
    epochs : Epoch object 
    states: list of strings (default all)
    show : wether do plot the psd (default = True)
    pick : if show = True, the channel to plot (string) 
    
    Return 
    ------ 
    list_alphas := list of alpha powers[{'C4': [.....], 'P4' : [....]},{'C4': ....} ] (len(list_alphas) = len(states))
    list_betas :=  list of beta powers
    list_thetas := list of theta powers
    list_baratio := list of Beta/alpha ratios 
                
    '''
    states = states
    nstate = [len(epochs[state]) for state in states]
    pick = pick

    alpha_band = 9.3

    list_alphas, list_betas, list_thetas, list_ab = [], [], [], []
    chan_alphas, chan_betas, chan_thetas, chan_ab = {
        'C4': [],
        'P4': [],
        'O2': [],
        'Fp': []
    }, {
        'C4': [],
        'P4': [],
        'O2': [],
        'Fp': []
    }, {
        'C4': [],
        'P4': [],
        'O2': [],
        'Fp': []
    }, {
        'C4': [],
        'P4': [],
        'O2': [],
        'Fp': []
    }

    for index, state in enumerate(states):
        print(state)
        for channel in ['C4', 'P4', 'O2', 'Fp']:
            if channel == 'Fp':
                raw = epochs[state].copy().pick_channels(['Fp2'])
            else:
                raw = epochs[state].copy().pick_channels([channel])

            psds, freqs = psd_multitaper(raw,
                                         low_bias=True,
                                         fmin=2,
                                         fmax=40,
                                         n_jobs=1)
            psds = 10 * np.log10(psds)
            psds = psds.mean(1)
            test = psds.mean(0)
            psds_std = psds.mean(0).std(0)

            if channel == pick and (state not in []):

                plt.plot(freqs, test)
                plt.legend(states)
                plt.title('PSD of electrode ' + pick)
                plt.xlabel('frequency (Hz)')
                plt.ylabel('Power (dB)')
                plt.fill_between(freqs,
                                 test - psds_std,
                                 test + psds_std,
                                 alpha=.1)

            for t, epochspsds in enumerate(psds):

                xx = freqs[((freqs > alpha_band - 2) &
                            (freqs < alpha_band + 2))]
                yy = epochspsds[(freqs > alpha_band - 2)
                                & (freqs < alpha_band + 2)]
                alphach = (auc(xx, yy))
                chan_alphas[channel].append(alphach)

                xx = freqs[((freqs < alpha_band - 2) &
                            (freqs > alpha_band - 6))]
                yy = epochspsds[((freqs < alpha_band - 2) &
                                 (freqs > alpha_band - 6))]

                thetach = (auc(xx, yy))

                chan_thetas[channel].append(thetach)

                xx = freqs[((freqs > alpha_band + 2) & (freqs < 40))]
                yy = epochspsds[((freqs > alpha_band + 2) & (freqs < 40))]

                betach = (auc(xx, yy))

                chan_betas[channel].append(betach)
                chan_ab[channel].append((betach / alphach))

        list_alphas.append(chan_alphas)
        list_betas.append(chan_betas)
        list_thetas.append(chan_thetas)
        list_ab.append(chan_ab)
        chan_alphas, chan_betas, chan_thetas, chan_ab = {
            'C4': [],
            'P4': [],
            'O2': [],
            'Fp': []
        }, {
            'C4': [],
            'P4': [],
            'O2': [],
            'Fp': []
        }, {
            'C4': [],
            'P4': [],
            'O2': [],
            'Fp': []
        }, {
            'C4': [],
            'P4': [],
            'O2': [],
            'Fp': []
        }

    print('MAR : ' + str(len(list_alphas)))

    alphas = [
        round(
            mean(list_alphas[i]['C4'] + list_alphas[i]['P4'] +
                 list_alphas[i]['O2'] + list_alphas[i]['Fp']), 2)
        for i in range(len(states) - 1)
    ]
    betas = [
        round(
            mean(list_betas[i]['C4'] + list_betas[i]['P4'] +
                 list_betas[i]['O2'] + list_betas[i]['Fp']), 2)
        for i in range(len(states) - 1)
    ]
    thetas = [
        round(
            mean(list_thetas[i]['C4'] + list_thetas[i]['P4'] +
                 list_thetas[i]['O2'] + list_thetas[i]['Fp']), 2)
        for i in range(len(states) - 1)
    ]
    ab = [
        round(
            mean(list_ab[i]['C4'] + list_ab[i]['P4'] + list_ab[i]['O2'] +
                 list_ab[i]['Fp']), 2) for i in range(len(states) - 1)
    ]

    plt.show()
    return list_alphas, list_betas, list_thetas, list_ab, alphas, betas, thetas, ab
#our recording standard: 10-20
montage = mne.channels.read_montage('standard_1020')
k = 0
#i is the subject id
for i in range(1, 6):

    for j in range(1, 5):
        #read for word-task, j is the trial code
        fname = data_path + "/Dataset/d" + str(i) + "-ep1-" + str(j) + ".set"
        raw = io.eeglab.read_raw_eeglab(fname, montage=montage)

        #measure the distribution of low-beta
        psds, freqs = psd_multitaper(raw,
                                     low_bias=True,
                                     fmin=12,
                                     fmax=16,
                                     proj=True,
                                     n_jobs=1)
        psds = 10 * np.log10(psds)
        low_beta_count[k][0] = psds.mean()
        low_beta_count[k][1] = psds.std()

        #measure the distribution of middle-beta
        psds, freqs = psd_multitaper(raw,
                                     low_bias=True,
                                     fmin=16,
                                     fmax=22,
                                     proj=True,
                                     n_jobs=1)
        psds = 10 * np.log10(psds)
        middle_beta_count[k][0] = psds.mean()