import matplotlib.pyplot as plt
import numpy as np
import utils as ut
from definitions import SAVE_PATH_FIGURES
"""
Plot the mean coherence over subjects. select for every subject the channel with the largest amplitude in coherence. 
"""

# load data
suffix = ''
window_length = 1024
data = ut.load_data_analysis('coh_icoh_allsubjects_w{}_{}.p'.format(
    window_length, suffix))
# now make a plot of all selected channels and the histogram over peaks
f = data['frequs']
mask = ut.get_array_mask(f > 1, f < 30)
coh_mat = data['coh_mat'][:, :, mask]
icoh_mat = data['icoh_mat'][:, :, mask]
n_subjects, n_channels, n_frequ_samples = coh_mat.shape

max_coh_channels = np.zeros((n_subjects, n_frequ_samples))
max_icoh_channels = np.zeros((n_subjects, n_frequ_samples))

for subject_idx in range(n_subjects):
    # select the channel with the largest coherence
    channel_idx = np.argmax(np.max(coh_mat[subject_idx, ], axis=1))

    max_coh_channels[subject_idx, ] = coh_mat[subject_idx, channel_idx, :]
    max_icoh_channels[subject_idx, ] = icoh_mat[subject_idx, channel_idx, :]

# take mean and SE over subjects
    # look at the pac data and select useful frequency ranges for every condition, hemisphere and mean channel
    # look at left and right values separately
    pac_left = pac_matrix[left_channel_idx, ].mean(
        axis=(0, 2))  # mean over channels within a hemisphere
    pac_right = pac_matrix[right_channel_idx, ].mean(
        axis=(0, 2))  # , and over amp f?
    # new shape: (phase-f)

    # goal: find bands for every hemisphere
    bands = dict(left=[], right=[])
    for condition_idx, condition in enumerate(conditions):

        # for left
        # consider reasonable beta range
        mask = ut.get_array_mask(f_phase > 10, f_phase < 40).squeeze()
        f_mask = f_phase[mask]
        data = pac_left[condition_idx, mask]
        # smooth the mean PAC
        smoother_pac_left = ut.smooth_with_mean_window(data, window_size=5)
        max_idx = np.argmax(smoother_pac_left)

        # plt.subplot(1, 2, 1)
        # plt.title('Subject {}, {}'.format(subject_id, 'left'))
        # plt.plot(f_mask, data, alpha=.5)
        # plt.plot(f_mask, smoother_pac_left, label=condition)
        # plt.plot(f_mask[max_idx], smoother_pac_left[max_idx], 'ro')
        # plt.legend()
        # select the band +-5 Hz around the peak
        bands['left'].append([f_mask[max_idx] - 5, f_mask[max_idx] + 5])
Beispiel #3
0
    rdsr = np.zeros(n_epochs)
    mpl = np.zeros(n_epochs)  # mean phase vector length
    mpa = np.zeros(n_epochs)  # amplitude
    beta_amp = np.zeros(n_epochs)

    # for every epoch
    for epoch_idx, epoch in enumerate(channel_lfp.T):
        # do preprocessing a la Cole et al
        # low pass filter
        lfp_pre = ut.low_pass_filter(y=epoch, fs=fs, cutoff=100, numtaps=250)

        # extract beta amplitude
        # calculate psd
        frequs, psd = ut.calculate_psd(lfp_pre, fs=fs, window_length=1024)
        # get the mask of the current band
        band_mask = ut.get_array_mask(frequs >= beta_bands[subject_idx][0],
                                      frequs <= beta_bands[subject_idx][1])
        # calculate beta amplitude
        beta_amp[epoch_idx] = np.mean(psd[band_mask])

        # band pass filter
        lfp_band = ut.band_pass_iir(y=lfp_pre,
                                    fs=fs,
                                    band=beta_bands[subject_idx])
        # remove potential ringing artifacts
        idx_167ms = int((fs / 1000) * 167)
        lfp_band = lfp_band[idx_167ms:-idx_167ms]
        lfp_band -= lfp_band.mean()

        lfp_pre = lfp_pre[idx_167ms:-idx_167ms]
        lfp_pre -= lfp_pre.mean()
Beispiel #4
0
                for epoch_idx, epoch in enumerate(channel_lfp.T):

                    # do preprocessing a la Cole et al
                    # low pass filter
                    lfp_pre = ut.low_pass_filter(y=epoch,
                                                 fs=fs,
                                                 cutoff=100,
                                                 numtaps=250)

                    # extract beta amplitude
                    # calculate psd
                    frequs, psd = ut.calculate_psd(lfp_pre,
                                                   fs=fs,
                                                   window_length=1024)
                    # get the mask of the current band
                    band_mask = ut.get_array_mask(frequs >= current_band[0],
                                                  frequs <= current_band[1])
                    # calculate beta amplitude
                    beta_amp[epoch_idx] = np.mean(psd[band_mask])

                    # band pass filter
                    lfp_band = ut.band_pass_iir(y=lfp_pre,
                                                fs=fs,
                                                band=current_band)
                    # remove potential ringing artifacts
                    idx_167ms = int((fs / 1000) * 167)
                    lfp_band = lfp_band[idx_167ms:-idx_167ms]
                    lfp_band -= lfp_band.mean()

                    lfp_pre = lfp_pre[idx_167ms:-idx_167ms]
                    lfp_pre -= lfp_pre.mean()
Beispiel #5
0
def plot_beta_band_selection_illustration_for_poster(pac_matrix_sig,
                                                     pac_matrix_nonsig,
                                                     sig_matrix1,
                                                     sig_matrix2,
                                                     n_phase,
                                                     n_amplitude,
                                                     f_phase,
                                                     f_amp,
                                                     mask,
                                                     smoother_pac,
                                                     max_idx,
                                                     current_lfp_epochs,
                                                     subject_id,
                                                     fs,
                                                     save=False):

    # plot both, the sig and the smoothed pac mean
    fontsize = 20
    y_tick_steps = 3
    x_tick_steps = 5
    tick_size = 15
    legend_size = 15

    vmin = pac_matrix_sig.min()
    vmax = pac_matrix_sig.max()

    plt.figure(figsize=(15, 6))
    # plot the PAC matrix
    plt.subplot2grid((2, 4), (0, 0), rowspan=2)
    current_pac_data = pac_matrix_nonsig
    plt.imshow(current_pac_data,
               interpolation='None',
               origin='lower',
               vmin=vmin,
               vmax=vmax)

    # plot contours of significance
    contours = measure.find_contours(sig_matrix2, 0)
    for n, contour in enumerate(contours):
        plt.plot(contour[:, 1], contour[:, 0], linewidth=.5, color='orange')

    plt.xticks(np.linspace(0, n_phase, y_tick_steps),
               np.linspace(f_phase.min(),
                           f_phase.max(),
                           y_tick_steps,
                           dtype=int),
               fontsize=tick_size)
    plt.yticks(np.linspace(0, n_amplitude, x_tick_steps),
               np.linspace(f_amp.min(), f_amp.max(), x_tick_steps, dtype=int),
               fontsize=tick_size)
    plt.xlabel('Phase frequency [Hz]', fontsize=fontsize)
    plt.ylabel('Amplitude frequency [Hz]', fontsize=fontsize)
    plt.title('PAC, discarded', fontsize=fontsize)
    plt.colorbar(
        pad=0.02,
        fraction=.09,
        ticks=np.round(
            [vmin + 0.01,
             np.mean((vmin + 0.01, vmax - 0.01)), vmax - 0.01], 2))

    plt.subplot2grid((2, 4), (0, 1), rowspan=2)
    current_pac_data = pac_matrix_sig
    plt.imshow(current_pac_data,
               interpolation='None',
               origin='lower',
               vmin=vmin,
               vmax=vmax)
    # plot contours of significance
    contours = measure.find_contours(sig_matrix1, 0)
    for n, contour in enumerate(contours):
        plt.plot(contour[:, 1], contour[:, 0], linewidth=.5, color='orange')

    plt.xticks(np.linspace(0, n_phase, y_tick_steps),
               np.linspace(f_phase.min(),
                           f_phase.max(),
                           y_tick_steps,
                           dtype=int),
               fontsize=tick_size)
    plt.yticks(np.linspace(0, n_amplitude, x_tick_steps),
               np.linspace(f_amp.min(), f_amp.max(), x_tick_steps, dtype=int),
               fontsize=tick_size)
    plt.xlabel('Phase frequency [Hz]', fontsize=fontsize)
    plt.title('PAC, accepted', fontsize=fontsize)
    plt.tight_layout()

    # plot the smoothed PAC values averaged over amplitude frequencies:
    plt.subplot2grid((2, 4), (0, 2), colspan=2)
    plt.title('Peak PAC and selected beta range', fontsize=fontsize)
    plt.plot(f_phase[mask], smoother_pac)
    plt.ylabel('PAC', fontsize=fontsize)
    xtick_vals_smoothed = np.linspace(f_phase[mask].min(),
                                      f_phase[mask].max(),
                                      x_tick_steps,
                                      dtype=int)
    plt.xticks(np.linspace(f_phase[mask].min(), f_phase[mask].max(),
                           x_tick_steps),
               xtick_vals_smoothed,
               fontsize=tick_size)
    y_tick_steps = 3
    plt.yticks(np.linspace(smoother_pac.min(), smoother_pac.max(),
                           y_tick_steps),
               np.round(
                   np.linspace(smoother_pac.min(), smoother_pac.max(),
                               y_tick_steps), 2),
               fontsize=tick_size)
    # plot the peak
    plt.axvline(f_phase[mask][max_idx],
                smoother_pac[max_idx],
                alpha=.3,
                color='C1')
    plt.plot(f_phase[mask][max_idx],
             smoother_pac[max_idx],
             'o',
             markersize=8,
             label='peak PAC')
    plt.legend(frameon=False, prop={'size': legend_size})

    # plot the PSD of the corresponding LFP
    plt.subplot2grid((2, 4), (1, 2), colspan=2)
    # calculate psd for every epoch, average across epochs
    f_psd, psd = ut.calculate_psd(y=current_lfp_epochs[:, 0],
                                  fs=fs,
                                  window_length=1024)  # to get the dims
    for epoch_idx, lfp_epoch in enumerate(current_lfp_epochs[:, 1:].T):
        f_psd, psd_tmp = ut.calculate_psd(y=lfp_epoch,
                                          fs=fs,
                                          window_length=1024)
        psd += psd_tmp
    # divide by n epochs to average
    psd /= current_lfp_epochs.shape[1]
    # interpolate the psd to have the same sample point as in the PAC phase dimensions:
    psd_inter_f = scipy.interpolate.interp1d(f_psd, psd)
    psd = psd_inter_f(f_phase)

    plt.plot(f_phase[mask], psd[mask])

    plt.xticks(np.linspace(f_phase[mask].min(), f_phase[mask].max(),
                           x_tick_steps),
               xtick_vals_smoothed,
               fontsize=tick_size)
    plt.yticks(np.linspace(psd[mask].min(), psd[mask].max(), y_tick_steps),
               np.round(
                   np.linspace(psd[mask].min(), psd[mask].max(), y_tick_steps),
                   1),
               fontsize=tick_size)
    plt.xlabel('Frequency [Hz]', fontsize=fontsize)
    plt.ylabel('PSD', fontsize=fontsize)

    # plot the peak and the selected range
    plt.axvline(f_phase[mask][max_idx],
                smoother_pac[max_idx],
                alpha=.5,
                color='C1')
    fill_mask = ut.get_array_mask(f_phase >= (f_phase[mask][max_idx] - 6),
                                  f_phase <= (f_phase[mask][max_idx] + 6))
    plt.fill_between(f_phase,
                     psd[mask].min(),
                     psd[mask].max(),
                     where=fill_mask,
                     color='C1',
                     alpha=0.1,
                     label='selected')
    plt.legend(prop={'size': legend_size}, frameon=False)
    plt.tight_layout()
    if save:
        plt.savefig(
            os.path.join(
                SAVE_PATH_FIGURES,
                'example_beta_range_selection_subj{}.pdf'.format(subject_id)))
    plt.show()
Beispiel #6
0
import matplotlib.pyplot as plt
import numpy as np
import utils as ut
from definitions import SAVE_PATH_FIGURES
"""
Plot figure figure 1A from the Neumann et al 2017 paper manuscript: the average psd over subjects
as well as the histogram over psd peaks in beta and in theta range 
"""

# load data
suffix = '_linear_search_and_amp'
data = ut.load_data_analysis('psd_maxamp_theta_beta{}.p'.format(suffix))
# now make a plot of all selected channels and the histogram over peaks
frequs = data['frequs']

mask = ut.get_array_mask(frequs > 4, frequs < 40)
plt.figure(figsize=(7, 5))
# plot individual stectra
# plt.plot(frequs[mask], data['psd_beta'][:, mask].T, linewidth=.7, color='C1', alpha=.5)
# plt.plot(frequs[mask], data['psd_theta'][:, mask].T, linewidth=.7, color='C4', alpha=.5)

# plot std envelope
joined_psd_mean = np.mean(np.vstack((data['psd_theta'], data['psd_beta'])),
                          axis=0)
se = ut.standard_error(np.vstack((data['psd_theta'], data['psd_beta'])),
                       axis=0)
plt.fill_between(frequs[mask],
                 joined_psd_mean[mask] + se[mask],
                 joined_psd_mean[mask] - se[mask],
                 alpha=.2,
                 color='C3',
# for every subject file
for sub, sub_file in enumerate(file_list):
    # load data
    d = ut.load_data_analysis(sub_file, data_folder=data_folder)
    # make new entries in the dict
    d['freqs'] = {}
    d['psd'] = {}

    for i, c in enumerate(d['conditions']):
        # notch filter around artefact in 24-26 Hz subharmonics of 50Hz noise
        d['lfp'][c] = ut.band_stop_filter(d['lfp'][c], d['fs'][c], band=[23, 27])
        # get psd and save it
        freqs, psd = ut.calculate_psd(d['lfp'][c], d['fs'][c])
        # interpolate between the neighboring bins to remove the dip
        mask = ut.get_array_mask(freqs > 23, freqs < 27)
        psd[mask] = np.mean(psd[[np.where(mask)[0][0]-1, np.where(mask)[0][-1]+1]])
        d['freqs'][c], d['psd'][c] = freqs, psd

        # plotting
        mask = ut.get_array_mask(freqs > 2, freqs < 40)
        plt.plot(d['freqs'][c][mask], d['psd'][c][mask], label=c)
        plt.ylabel('power ')
        plt.xlabel('Frequency [Hz]')

    plt.title('Subject file {}, id {}'.format(sub_file[:-2], d['id']['rest']))
    plt.legend()

    # save data
    ut.save_data(data_dict=d,
                 filename='subject_{}_cleaned_psd.p'.format(d['number']),
# collect the psd of this mask in a matrix over subjects
# prelocate with mask around the mean peak
mean_peak_theta = data['theta_peaks_all'].mean()
mean_peak_beta = data['beta_peaks_all'].mean()

frequ_samples = 12

psd_range_mat_theta = -1 * np.ones((subject_mask.sum(), frequ_samples))
psd_range_mat_beta = -1 * np.ones((n_subjects, frequ_samples))

for sub in range(n_subjects):
    # get the peak
    peak_beta = data['beta_peaks_max'][sub]

    # build a mask -3, +8 Hz around the peak
    mask_beta = ut.get_array_mask(frequs > (peak_beta - 3), frequs <
                                  (peak_beta + 8))

    beta_frequs = frequs[mask_beta]

    # collect the psd of this mask in a matrix
    psd_range_mat_beta[sub, ] = data['psd_beta'][sub, mask_beta]

for sub in range(np.sum(subject_mask)):
    # get the peak
    peak_theta = theta_peaks[sub]

    # build a mask -3, +8 Hz around the peak
    mask_theta = ut.get_array_mask(frequs > peak_theta - 3,
                                   frequs < peak_theta + 8)

    # collect the psd of this mask in a matrix
Beispiel #9
0
for file in file_list:
    if file.startswith('spmeeg_'):
        d = ut.load_data_spm(file)
        fs = d['fsample'][0][0]
        channel_labels = d['chanlabels'][0]

        fig = plt.figure(figsize=(15, 8))
        for i, lfp in enumerate(d['data']):

            f, t, sxx = ut.calculate_spectrogram(lfp, fs=fs)

            # transform to log
            ssx_log = np.log(sxx)

            # define a mask and build a grid
            mask = ut.get_array_mask(f > 4, f < 12)
            xgrid, ygrid = np.meshgrid(f[mask], t)

            # plotting
            ax = fig.add_subplot(3, 2, i + 1, projection='3d')

            surf = ax.plot_surface(X=xgrid, Y=ygrid, Z=ssx_log[mask, :].T, cmap='viridis')
            ax.set_xlabel('Frequency [Hz]')
            ax.set_ylabel('Time [s]')
            ax.set_zlabel('log power ')
            fig.colorbar(surf, shrink=0.5, aspect=5)

        # save figure
        filename_save = file[:-4] + '_spectro.pdf'
        plt.savefig(os.path.join(SAVE_PATH_FIGURES, filename_save))
        # plt.show()
        lfp = d['data'][idx]

if lfp is None:
    raise ValueError(
        'Could not find the specified channel in the data file: {}'.format(
            channel_name))

# remove mean
lfp = lfp - np.mean(lfp)

# filter in theta range:
lfp_filt = band_pass_filter(y=lfp, fs=fs, band=[4, 12], plot_response=False)

# construct the time vector
dt = 1 / fs
t = np.arange(0, d['data'].shape[1] * dt, dt)

# design plotting mask
window_length = 3  # in sec
window_start = 250
mask = get_array_mask(t > window_start, t < window_start + window_length)
plt.figure(figsize=(7, 3))
plt.plot(t[mask], lfp[mask], label='raw')
plt.plot(t[mask], lfp_filt[mask], label='filtered')
plt.ylabel('[$\muV]')
plt.xlabel('time [s]')
plt.title('contact pair GPiR23 from case 19')
plt.legend()
plt.savefig(os.path.join(SAVE_PATH_FIGURES, 'figure_1C.pdf'))
# plt.show()
Beispiel #11
0
        psds = np.zeros((n_channels, n_frequ_samples))
        theta_peak_frequency = np.zeros(n_channels)
        beta_peak_frequency = np.zeros(n_channels)

        plt.figure(figsize=(10, 5))
        for channel_idx, lfp in enumerate(d['data']):
            # remove 50Hz noise
            lfp_clean = lfp
            # lfp_clean = ut.band_stop_filter(lfp, fs, band=[49, 51], plot_response=False)
            # calculate psd
            frequs, psd = ut.calculate_psd(lfp_clean,
                                           fs=fs,
                                           window_length=window_length)

            # normalize like in the paper: take sd of the psd between 4-45 and 55-95Hz
            mask = np.logical_or(ut.get_array_mask(frequs > 5, frequs < 45),
                                 ut.get_array_mask(frequs > 55, frequs < 95))
            psd /= np.std(psd[mask])

            # remove 1 / f component
            # frequs_linear, psd_linear = ut.remove_1f_component(frequs, psd)

            # save for later
            psds[channel_idx, ] = psd
            # find peak in theta: use the linearized spectra for finding peaks
            idx_theta, peak_amp_theta, ftheta, psd_theta = ut.find_peak_in_band(
                frequs, psd, [4, 12], linearize=True)
            # save the frequency at which the peak occured, in one long list for the histogram
            theta_peaks[electrode_idx] = ftheta[idx_theta]
            # save it in a matrix to select it per subject for the alignment
            theta_peak_frequency[channel_idx] = ftheta[idx_theta]
    # best band selection illustration plot
    for channel_idx, channel_label in enumerate(channel_labels):

        # the customized freqeuncy bands are saved per hemisphere, therefore we have to find the current hemi
        current_hemi = 'left' if channel_label in left_channels else 'right'

        # add a new list for condition bands of the current channel
        bands[current_hemi][channel_label] = []

        for condition_idx, condition in enumerate(conditions):

            # get current lfp data
            current_lfp_epochs = lfp_dict[condition]['data'][channel_idx]

            # consider reasonable beta range
            mask = ut.get_array_mask(f_phase >= 12, f_phase <= 40).squeeze()
            f_mask = f_phase[mask]
            data = pac_phase[channel_idx, condition_idx, mask]
            # smooth the mean PAC
            smoother_pac = ut.smooth_with_mean_window(data, window_size=3)
            max_idx = np.argmax(smoother_pac)
            # sum logical significance values across the amplitude frequency dimension
            # calculate the binary groups in the significance map
            lw, num = measurements.label(sig_matrix[channel_idx,
                                                    condition_idx, :, :])
            # calculate the area of the clusters:
            # from http://stackoverflow.com/questions/25664682/how-to-find-cluster-sizes-in-2d-numpy-array
            area = measurements.sum(sig_matrix[channel_idx, condition_idx, ],
                                    lw,
                                    index=np.arange(lw.max() + 1))
            # get the size of the largest group
    # or conditions
    # or both

    bands = hemi_dict['bands']
    f_phase = hemi_dict['f_phase']
    # do it for every band
    for band_idx, band in enumerate(bands):
        # for PAC analysis
        # average across low beta and high and across all HFO amplitude frequencies
        # then average across channels
        # or look at channels independently
        # or conditions
        # or both

        # get the mask for the current band
        phase_band_mask = ut.get_array_mask(f_phase >= band[0],
                                            f_phase <= band[1]).squeeze()

        # extract pac values for the current phase band
        pac_phase_band = hemi_dict['pac_matrix'][:, :, :, phase_band_mask]

        # average over frequency amplitude and over low beta frequencies
        pac_phase_band = pac_phase_band.mean(axis=(-2, -1))

        # save per condition and channel
        pac_results['per_cond_channel'][band_idx,
                                        hemi_idx, :, :] = pac_phase_band

        # save pac per channel
        pac_results['per_channel'][band_idx,
                                   hemi_idx, :] = pac_phase_band.mean(
                                       axis=1)  # average over conditions