def calc_circ_stats(elec_pair_phase_diff, recalled, do_perm=False):
    if do_perm:
        recalled = np.random.permutation(recalled)

    # compute rayleigh on the phase difference
    elec_pair_pval, elec_pair_z = pycircstat.rayleigh(elec_pair_phase_diff, axis=0)

    # compute rvl on the phase difference
    elec_pair_rvl = pycircstat.resultant_vector_length(elec_pair_phase_diff, axis=0)

    # also compute for recalled and not recalled items
    elec_pair_pval_rec, elec_pair_z_rec = pycircstat.rayleigh(elec_pair_phase_diff[recalled], axis=0)
    elec_pair_pval_nrec, elec_pair_z_nrec = pycircstat.rayleigh(elec_pair_phase_diff[~recalled], axis=0)

    # and also compute resultant vector length
    elec_pair_rvl_rec = pycircstat.resultant_vector_length(elec_pair_phase_diff[recalled], axis=0)
    elec_pair_rvl_nrec = pycircstat.resultant_vector_length(elec_pair_phase_diff[~recalled], axis=0)

    return {'elec_pair_pval': elec_pair_pval,
            'elec_pair_z': elec_pair_z,
            'elec_pair_rvl': elec_pair_rvl,
            'elec_pair_pval_rec': elec_pair_pval_rec,
            'elec_pair_z_rec': elec_pair_z_rec,
            'elec_pair_pval_nrec': elec_pair_pval_nrec,
            'elec_pair_z_nrec': elec_pair_z_nrec,
            'elec_pair_rvl_rec': elec_pair_rvl_rec,
            'elec_pair_rvl_nrec': elec_pair_rvl_nrec}
Пример #2
0
def calc_circ_stats(elec_pair_phase_diff, recalled, do_perm=False):
    if do_perm:
        recalled = np.random.permutation(recalled)

    # compute rayleigh on the phase difference
    elec_pair_pval, elec_pair_z = pycircstat.rayleigh(elec_pair_phase_diff, axis=0)

    # compute rvl on the phase difference
    elec_pair_rvl = pycircstat.resultant_vector_length(elec_pair_phase_diff, axis=0)

    # also compute for recalled and not recalled items
    elec_pair_pval_rec, elec_pair_z_rec = pycircstat.rayleigh(elec_pair_phase_diff[recalled], axis=0)
    elec_pair_pval_nrec, elec_pair_z_nrec = pycircstat.rayleigh(elec_pair_phase_diff[~recalled], axis=0)

    # and also compute resultant vector length
    elec_pair_rvl_rec = pycircstat.resultant_vector_length(elec_pair_phase_diff[recalled], axis=0)
    elec_pair_rvl_nrec = pycircstat.resultant_vector_length(elec_pair_phase_diff[~recalled], axis=0)

    return {'elec_pair_pval': elec_pair_pval,
            'elec_pair_z': elec_pair_z,
            'elec_pair_rvl': elec_pair_rvl,
            'elec_pair_pval_rec': elec_pair_pval_rec,
            'elec_pair_z_rec': elec_pair_z_rec,
            'elec_pair_pval_nrec': elec_pair_pval_nrec,
            'elec_pair_z_nrec': elec_pair_z_nrec,
            'elec_pair_rvl_rec': elec_pair_rvl_rec,
            'elec_pair_rvl_nrec': elec_pair_rvl_nrec}
Пример #3
0
def head_direction_stats(head_angle_bins, rate):
    """
    Calculeate firing rate at head direction in head angles for time t

    Parameters
    ----------
    head_angle_bins : quantities.Quantity array in degrees
        binned head directions
    rate : np.ndarray
        firing rate magnitude coresponding to angles

    Returns
    -------
    out : float, float
        mean angle, mean vector length
    """
    import math
    import pycircstat as pc
    if head_angle_bins.units == pq.degrees:
        head_angle_bins = [math.radians(deg)
                           for deg in head_angle_bins] * pq.radians
    nanIndices = np.where(np.isnan(rate))[0]
    nanIndices = np.unique(nanIndices)
    rate = np.delete(rate, nanIndices)
    head_angle_bins = np.delete(head_angle_bins, nanIndices)
    mean_ang = pc.mean(head_angle_bins, w=rate)
    mean_vec_len = pc.resultant_vector_length(head_angle_bins, w=rate)
    # ci_lim = pc.mean_ci_limits(head_angle_bins, w=rate)
    return math.degrees(mean_ang), mean_vec_len
Пример #4
0
    def _make_tuples(self, key):

        repeats, poisson_rate, alpha, kappa = \
            (PowerParameters() & key).fetch1['repeats', 'poisson_rate','alpha','kappa']
        p = stats.poisson(poisson_rate)
        v = stats.vonmises(kappa)
        for trials in range(2, 15):
            print('Trials', trials)
            cut_off = self.compute_cutoff(poisson_rate, alpha, trials)
            beta = []
            for r in range(repeats):
                n = p.rvs(trials)

                vs = np.mean([circ.resultant_vector_length(v.rvs(m) % (2*np.pi)) for m in n])
                beta.append(vs < cut_off)
            self.insert1(dict(key, n=trials, power=1 - np.mean(beta)))
Пример #5
0
    def _make_tuples(self, key):

        repeats, poisson_rate, alpha, kappa = \
            (PowerParameters() & key).fetch1('repeats', 'poisson_rate','alpha','kappa')
        p = stats.poisson(poisson_rate)
        v = stats.vonmises(kappa)
        for trials in range(2, 15):
            print('Trials', trials)
            cut_off = self.compute_cutoff(poisson_rate, alpha, trials)
            beta = []
            for r in range(repeats):
                n = p.rvs(trials)

                vs = np.mean([
                    circ.resultant_vector_length(v.rvs(m) % (2 * np.pi))
                    for m in n
                ])
                beta.append(vs < cut_off)
            self.insert1(dict(key, n=trials, power=1 - np.mean(beta)))
Пример #6
0
def test_vector_strength_spectrum():
    T = 3  # 2s
    sampling_rate = 10000.
    firing_rate = 10  # 1000Hz

    s = T * np.random.rand(np.random.poisson(firing_rate * T))

    w, vs_spec = es.vector_strength_spectrum(s, sampling_rate)

    F0 = []
    R = []
    lowcut, highcut = 500, 550
    idx = (w >= lowcut) & (w <= highcut)
    for i in np.where(idx)[0]:
        f0 = w[i]
        p0 = 1 / f0
        rho = pycircstat.resultant_vector_length((s % p0) / p0 * 2 * np.pi)

        F0.append(f0)
        R.append(rho)
    assert_allclose(R, vs_spec[idx])
Пример #7
0
def test_vector_strength_spectrum():
    T = 3  # 2s
    sampling_rate = 10000.
    firing_rate = 10  # 1000Hz

    s = T * np.random.rand(np.random.poisson(firing_rate * T))

    w, vs_spec = es.vector_strength_spectrum(s, sampling_rate)

    F0 = []
    R = []
    lowcut, highcut = 500, 550
    idx = (w >= lowcut) & (w <= highcut)
    for i in np.where(idx)[0]:
        f0 = w[i]
        p0 = 1 / f0
        rho = pycircstat.resultant_vector_length((s % p0) / p0 * 2 * np.pi)

        F0.append(f0)
        R.append(rho)
    assert_allclose(R, vs_spec[idx])
Пример #8
0
def gaborbank_orientation_variance(d):
    """ Compute the orientation variance. Orientation variance
    can be any value from 0 (no variance, all responses point
    in one direction) to 1 (no dominant direction). Computed
    using pycircstat's mean resultant vector function.

    """
    res = d['res']
    theta = d['theta']

    e = res.real**2 + res.imag**2
    e = e.sum(axis=2)  # sum energy over scales.

    # reshape the angles into an image plane for each angle:
    t = np.tile(theta, e.shape[0] * e.shape[1])
    t = np.reshape(t, e.shape)
    # t has the same shape as e, with each orientation along axis 2.
    """compute orientation variance with energy as weights. Axial correction
    is to change direction 0-pi --> orientation 0-2*pi. Correct afterward
    by folding orientations > pi back around.
    """
    out = circ.resultant_vector_length(t, w=e, axis=2, axial_correction=2)
    return 1 - out
Пример #9
0
def head_direction_score(head_angle_bins, rate):
    """
    Calculeate firing rate at head direction in head angles for time t

    Parameters
    ----------
    head_angle_bins : array in radians
        binned head directions
    rate : array
        firing rate magnitude coresponding to angles

    Returns
    -------
    out : float, float
        mean angle, mean vector length
    """
    import math
    import pycircstat as pc
    nanIndices = np.where(np.isnan(rate))
    head_angle_bins = np.delete(head_angle_bins, nanIndices)
    mean_ang = pc.mean(head_angle_bins, w=rate)
    mean_vec_len = pc.resultant_vector_length(head_angle_bins, w=rate)
    # ci_lim = pc.mean_ci_limits(head_angle_bins, w=rate)
    return mean_ang, mean_vec_len
Пример #10
0
def gaborbank_orientation_variance(d):
    """ Compute the orientation variance. Orientation variance
    can be any value from 0 (no variance, all responses point
    in one direction) to 1 (no dominant direction). Computed
    using pycircstat's mean resultant vector function.

    """
    res = d['res']
    theta = d['theta']

    e = res.real**2 + res.imag**2
    e = e.sum(axis=2)  # sum energy over scales.

    # reshape the angles into an image plane for each angle:
    t = np.tile(theta, e.shape[0]*e.shape[1])
    t = np.reshape(t, e.shape)
    # t has the same shape as e, with each orientation along axis 2.

    """compute orientation variance with energy as weights. Axial correction
    is to change direction 0-pi --> orientation 0-2*pi. Correct afterward
    by folding orientations > pi back around.
    """
    out = circ.resultant_vector_length(t, w=e, axis=2, axial_correction=2)
    return 1 - out
Пример #11
0
    def plot_cluster_stats(self, cluster_name):
        """
        Multi panel plot showing:

        1. brain map of electrodes in the cluster, color-coded by phase
        2. brain map of electrodes in the cluster, color-coded by subsequent memory effect
        3. timecourse of resultant vector length of wave direction, averaged across trials
        4. timecourse of r^2, averaged across trials
        5. polor plot of left-frontal and hippocampal electrode phases
        6/7. same as 5, but for recalled and not recalled items only

        Data are taken from the timepoint with the highest r-square value.

        Figure creation code is so ugly sorry.
        """

        ############################
        # GET TIME TIME FOR X-AXIS #
        ############################
        time_axis = self.res['traveling_waves'][cluster_name]['time']

        #####################
        # SET UP THE FIGURE #
        #####################
        gs = gridspec.GridSpec(6, 3)
        ax1 = plt.subplot(gs[0, :])
        ax2 = plt.subplot(gs[2, :])
        ax3 = plt.subplot(gs[3, :])
        ax4 = plt.subplot(gs[4, 0], projection='polar')
        ax6 = plt.subplot(gs[4, 1], projection='polar')
        ax7 = plt.subplot(gs[4, 2], projection='polar')
        ax8 = plt.subplot(gs[5, 0], projection='polar')
        ax9 = plt.subplot(gs[5, 1], projection='polar')
        ax10 = plt.subplot(gs[5, 2], projection='polar')
        ax5 = plt.subplot(gs[1, :])

        # some figure parameters
        fig = plt.gcf()
        fig.set_size_inches(15, 30)
        mpl.rcParams['xtick.labelsize'] = 18
        mpl.rcParams['ytick.labelsize'] = 18

        #############################################
        # INFO ABOUT THE ELECTRODES IN THIS CLUSTER #
        #############################################
        cluster_rows = self.res['clusters'][cluster_name].notna()
        regions_all = self.get_electrode_roi_by_hemi()
        regions = regions_all[cluster_rows]['merged_col'].unique()
        regions_str = ', '.join(regions)
        xyz = self.res['clusters'][cluster_rows][['x', 'y', 'z']].values

        ###############################
        # ROW 1: electrodes and phase #
        ###############################
        mean_r2 = np.nanmean(self.res['traveling_waves'][cluster_name]['cluster_r2_adj'], axis=1)
        argmax_r2 = np.argmax(mean_r2)
        print(argmax_r2)
        phases = self.res['traveling_waves'][cluster_name]['phase_data'][:, argmax_r2]
        #     phases = (phases + np.pi) % (2 * np.pi) - np.pi
        #     phases[phases<0] += np.pi*2
        #     phases *= 180. / np.pi
        #     phases -= phases.min() - 1
        colors = np.stack([[0., 0., 0., 0.]] * len(phases))
        cm = clrs.LinearSegmentedColormap.from_list('cm', cc.cyclic_mrybm_35_75_c68_s25)
        cNorm = clrs.Normalize(vmin=0, vmax=np.pi * 2)
        colors[~np.isnan(phases)] = cmx.ScalarMappable(norm=cNorm, cmap=cm).to_rgba(phases[~np.isnan(phases)])
        ni_plot.plot_connectome(np.eye(xyz.shape[0]), xyz,
                                node_kwargs={'alpha': 0.7, 'edgecolors': None},
                                node_size=45, node_color=colors, display_mode='lzr',
                                axes=ax1)
        mean_freq = self.res['traveling_waves'][cluster_name]['mean_freq']
        plt.suptitle('{0} ({1:.2f} Hz): {2}'.format(self.subject, mean_freq, regions_str), y=.9)
        divider = make_axes_locatable(ax1)
        cax = divider.append_axes('right', size='6%', pad=15)
        cb1 = mpl.colorbar.ColorbarBase(cax, cmap=cm,
                                        norm=cNorm,
                                        orientation='vertical', ticks=[0, np.pi / 2, np.pi, np.pi * 3 / 2, np.pi * 2])
        cb1.ax.yaxis.set_ticklabels(['0°', '90°', '180°', '270°', '360°'])
        cb1.ax.tick_params(labelsize=14)
        for label in cb1.ax.yaxis.get_majorticklabels():
            label.set_transform(label.get_transform() + mpl.transforms.ScaledTranslation(0.15, 0, fig.dpi_scale_trans))

        ##################################################
        # ROW 2: electrodes and subsequent memory effect #
        ##################################################
        sme = self.res['traveling_waves'][cluster_name]['sme_t'][:, argmax_r2]
        colors = np.stack([[0., 0., 0., 0.]] * len(sme))
        cm = plt.get_cmap('RdBu_r')
        clim = np.max(np.abs(sme))
        cNorm = clrs.Normalize(vmin=-clim, vmax=clim)
        colors[~np.isnan(sme)] = cmx.ScalarMappable(norm=cNorm, cmap=cm).to_rgba(sme[~np.isnan(sme)])
        ni_plot.plot_connectome(np.eye(xyz.shape[0]), xyz,
                                node_kwargs={'alpha': 0.7, 'edgecolors': None},
                                node_size=45, node_color=colors, display_mode='lzr',
                                axes=ax5)
        divider = make_axes_locatable(ax5)
        cax = divider.append_axes('right', size='6%', pad=15)
        cb2 = mpl.colorbar.ColorbarBase(cax, cmap='RdBu_r',
                                        norm=cNorm,
                                        orientation='vertical')
        cb2.ax.tick_params(labelsize=14)
        for label in cb2.ax.yaxis.get_majorticklabels():
            label.set_transform(label.get_transform() + mpl.transforms.ScaledTranslation(0.15, 0, fig.dpi_scale_trans))

        ############################
        # ROW 3: timecourse of RVL #
        ############################
        rvl = pycircstat.resultant_vector_length(self.res['traveling_waves'][cluster_name]['cluster_wave_ang'], axis=1)
        ax2.plot(time_axis, rvl, lw=2)
        ax2.set_ylabel('RVL', fontsize=20)

        ##################################
        # ROW 4: timecourse of r-squared #
        ##################################
        ax3.plot(time_axis, np.nanmean(self.res['traveling_waves'][cluster_name]['cluster_r2_adj'], axis=1), lw=2)
        ax3.set_xlabel('Time (ms)', fontsize=20)
        ax3.set_ylabel('mean($R^{2}$)', fontsize=20)

        ############################
        # ROW 5a: phase polar plots #
        ############################
        #     phases = np.deg2rad(phases)
        cluster_regions = regions_all[cluster_rows]['merged_col']
        phases_left_front = phases[cluster_regions == 'left-Frontal']
        phases_hipp = phases[(cluster_regions == 'left-Hipp') | (cluster_regions == 'right-Hipp')]
        phases_other = phases[~cluster_regions.isin(['left-Frontal', 'left-Hipp', 'right-Hipp'])]

        for this_phase in phases_left_front:
            ax4.plot([this_phase, this_phase], [0, 1], lw=3, c='#67a9cf', alpha=.5)
        for this_phase in phases_hipp:
            ax4.plot([this_phase, this_phase], [0, 1], lw=3, c='#ef8a62', alpha=.5)
        for this_phase in phases_other:
            ax4.plot([this_phase, this_phase], [0, .7], lw=2, c='k', alpha=.4, zorder=-1)
        ax4.grid()
        for r in np.linspace(0, 2 * np.pi, 5)[:-1]:
            ax4.plot([r, r], [0, 1.3], lw=1, c=[.7, .7, .7], zorder=-2)
        ax4.spines['polar'].set_visible(False)
        ax4.set_ylim(0, 1.3)
        ax4.set_yticklabels([])
        ax4.set_aspect('equal', 'box')
        red_patch = mpatches.Patch(color='#67a9cf', label='L. Frontal')
        blue_patch = mpatches.Patch(color='#ef8a62', label='Hipp')
        _ = ax4.legend(handles=[red_patch, blue_patch], loc='lower left', bbox_to_anchor=(0.9, 0.9),
                       frameon=False, fontsize=16)

        ################################################
        # ROW 5b: phase polar plots for recalled items #
        ################################################
        phases = self.res['traveling_waves'][cluster_name]['phase_data_recalled'][:, argmax_r2]
        #     phases = (phases + np.pi) % (2 * np.pi) - np.pi
        #     phases *= 180. / np.pi
        #     phases -= phases.min() - 1
        #     phases = np.deg2rad(phases)
        phases_left_front = phases[cluster_regions == 'left-Frontal']
        phases_hipp = phases[(cluster_regions == 'left-Hipp') | (cluster_regions == 'right-Hipp')]
        phases_other = phases[~cluster_regions.isin(['left-Frontal', 'left-Hipp', 'right-Hipp'])]

        for this_phase in phases_left_front:
            ax6.plot([this_phase, this_phase], [0, 1], lw=3, c='#67a9cf', alpha=.5)
        for this_phase in phases_hipp:
            ax6.plot([this_phase, this_phase], [0, 1], lw=3, c='#ef8a62', alpha=.5)
        for this_phase in phases_other:
            ax6.plot([this_phase, this_phase], [0, .7], lw=2, c='k', alpha=.4, zorder=-1)
        ax6.grid()
        for r in np.linspace(0, 2 * np.pi, 5)[:-1]:
            ax6.plot([r, r], [0, 1.3], lw=1, c=[.7, .7, .7], zorder=-2)
        ax6.spines['polar'].set_visible(False)
        ax6.set_ylim(0, 1.3)
        ax6.set_yticklabels([])
        ax6.set_aspect('equal', 'box')
        ax6.set_title('Recalled items', y=1.12)

        ####################################################
        # ROW 5c: phase polar plots for not recalled items #
        ####################################################
        phases = self.res['traveling_waves'][cluster_name]['phase_data_not_recalled'][:, argmax_r2]
        #     phases = (phases + np.pi) % (2 * np.pi) - np.pi
        #     phases *= 180. / np.pi
        #     phases -= phases.min() - 1
        #     phases = np.deg2rad(phases)
        phases_left_front = phases[cluster_regions == 'left-Frontal']
        phases_hipp = phases[(cluster_regions == 'left-Hipp') | (cluster_regions == 'right-Hipp')]
        phases_other = phases[~cluster_regions.isin(['left-Frontal', 'left-Hipp', 'right-Hipp'])]

        for this_phase in phases_left_front:
            ax7.plot([this_phase, this_phase], [0, 1], lw=3, c='#67a9cf', alpha=.5)
        for this_phase in phases_hipp:
            ax7.plot([this_phase, this_phase], [0, 1], lw=3, c='#ef8a62', alpha=.5)
        for this_phase in phases_other:
            ax7.plot([this_phase, this_phase], [0, .7], lw=2, c='k', alpha=.4, zorder=-1)
        ax7.grid()
        for r in np.linspace(0, 2 * np.pi, 5)[:-1]:
            ax7.plot([r, r], [0, 1.3], lw=1, c=[.7, .7, .7], zorder=-2)
        ax7.spines['polar'].set_visible(False)
        ax7.set_ylim(0, 1.3)
        ax7.set_yticklabels([])
        ax7.set_aspect('equal', 'box')
        ax7.set_title('Not recalled items', y=1.12)

        ####################################################
        # ROW 6:
        ####################################################
        recalled = self.res['traveling_waves']['cluster1']['recalled']
        if ('left-Frontal' in self.res['traveling_waves'][cluster_name]['phase_by_roi']) & \
                ('both-Hipp' in self.res['traveling_waves'][cluster_name]['phase_by_roi']):

            phase_by_roi = self.res['traveling_waves'][cluster_name]['phase_by_roi']

            phase_left_front_roi = phase_by_roi['left-Frontal'][:, argmax_r2]
            #         phase_left_front_roi = (phase_left_front_roi + np.pi) % (2 * np.pi)
            phase_hipp_roi = phase_by_roi['both-Hipp'][:, argmax_r2]
            #         phase_hipp_roi = (phase_hipp_roi + np.pi) % (2 * np.pi)
            #         phase_left_front_roi = (phase_left_front_roi + np.pi) % (2 * np.pi) - np.pi
            #         phase_left_front_roi *= 180. / np.pi
            #         phase_left_front_roi -= phase_left_front_roi.min() - 1
            #         phase_left_front_roi = np.deg2rad(phase_left_front_roi)
            #         phase_hipp_roi = (phase_hipp_roi + np.pi) % (2 * np.pi) - np.pi
            #         phase_hipp_roi *= 180. / np.pi
            #         phase_hipp_roi -= phase_hipp_roi.min() - 1
            #         phase_hipp_roi = np.deg2rad(phase_hipp_roi)

            # LEFT
            ax8 = self.rose_plot(phase_left_front_roi, n_bins=30, ax=ax8)
            ax8 = self.rose_plot(phase_hipp_roi, n_bins=30, ax=ax8)
            ax8.spines['polar'].set_visible(False)
            ax8.set_yticks([ax8.get_ylim()[1]])
            ax8.set_aspect('equal', 'box')
            ax8.tick_params(axis='y', colors=[.7, .7, .7])
            for r in np.linspace(0, 2 * np.pi, 5)[:-1]:
                ax8.plot([r, r], [0, ax8.get_ylim()[1]], lw=1, c=[.7, .7, .7], zorder=-2)
            ax8.grid()

            # MIDDLE
            ax9 = self.rose_plot(phase_left_front_roi[recalled], n_bins=30, ax=ax9)
            ax9 = self.rose_plot(phase_hipp_roi[recalled], n_bins=30, ax=ax9)
            ax9.spines['polar'].set_visible(False)
            ax9.set_yticks([ax9.get_ylim()[1]])
            ax9.set_aspect('equal', 'box')
            ax9.tick_params(axis='y', colors=[.7, .7, .7])
            for r in np.linspace(0, 2 * np.pi, 5)[:-1]:
                ax9.plot([r, r], [0, ax9.get_ylim()[1]], lw=1, c=[.7, .7, .7], zorder=-2)
            ax9.grid()

            # RIGHT
            ax10 = self.rose_plot(phase_left_front_roi[~recalled], n_bins=30, ax=ax10)
            ax10 = self.rose_plot(phase_hipp_roi[~recalled], n_bins=30, ax=ax10)
            ax10.spines['polar'].set_visible(False)
            ax10.set_yticks([ax10.get_ylim()[1]])
            ax10.set_aspect('equal', 'box')
            ax10.tick_params(axis='y', colors=[.7, .7, .7])
            for r in np.linspace(0, 2 * np.pi, 5)[:-1]:
                ax10.plot([r, r], [0, ax10.get_ylim()[1]], lw=1, c=[.7, .7, .7], zorder=-2)
            ax10.grid()

        plt.subplots_adjust(hspace=.5)
        return fig
def compute_phase_stats_with_shuffle(events, spike_rel_times, phase_data_hilbert, phase_bin_start,
                                     phase_bin_stop, do_permute=False, shuffle_type=1):

    spike_rel_times_tmp = spike_rel_times.copy()
    e_tmp = events.copy()

    if do_permute:

        if shuffle_type == 1:

            # permute the novel
            novel_events = np.where(events.isFirst.values)[0]
            perm_novel_events = np.random.permutation(novel_events)
            spike_rel_times_tmp[novel_events] = spike_rel_times_tmp[perm_novel_events]

            # and repeated separately
            rep_events = np.where(~events.isFirst.values)[0]
            perm_rep_events = np.random.permutation(rep_events)
            spike_rel_times_tmp[rep_events] = spike_rel_times_tmp[perm_rep_events]

        else:

            e_tmp['isFirst'] = np.random.permutation(e_tmp.isFirst)

    # get the phases at which the spikes occurred and bin into novel and repeated items for each hilbert band
    spike_phases_hilbert = _compute_spike_phase_by_freq(spike_rel_times_tmp,
                                                        phase_bin_start,
                                                        phase_bin_stop,
                                                        phase_data_hilbert,
                                                        events)

    # bin into repeated and novel phases
    novel_phases, rep_phases = _bin_phases_into_cond(spike_phases_hilbert, e_tmp)

    if (len(novel_phases) > 0) & (len(rep_phases) > 0):

        # test phase locking for all spikes comboined
        all_spikes_phases = np.vstack([novel_phases, rep_phases])
        rayleigh_pval_all, rayleigh_z_all = pycircstat.rayleigh(all_spikes_phases, axis=0)
        rvl_all = pycircstat.resultant_vector_length(all_spikes_phases, axis=0)

        # rayleigh test for uniformity
        rvl_novel = pycircstat.resultant_vector_length(novel_phases, axis=0)
        rvl_rep = pycircstat.resultant_vector_length(rep_phases, axis=0)
        rvl_diff = rvl_novel - rvl_rep

        # compute rayleigh test for each condition
        rayleigh_pval_novel, rayleigh_z_novel = pycircstat.rayleigh(novel_phases, axis=0)
        rayleigh_pval_rep, rayleigh_z_rep = pycircstat.rayleigh(rep_phases, axis=0)
        rayleigh_diff = rayleigh_z_novel - rayleigh_z_rep

        # watson williams test for equal means
        ww_pval, ww_tables = pycircstat.watson_williams(novel_phases, rep_phases, axis=0)
        ww_fstat = np.array([x.loc['Columns'].F for x in ww_tables])

        # kuiper test, to test for difference in dispersion (not mean, because I'm making them equal)
        kuiper_pval, stat_kuiper = pycircstat.kuiper(novel_phases - pycircstat.mean(novel_phases),
                                                     rep_phases - pycircstat.mean(rep_phases), axis=0)

        return (rvl_novel, rvl_rep, rvl_diff, ww_fstat, stat_kuiper, rayleigh_z_novel, rayleigh_z_rep, rayleigh_diff,
                rayleigh_z_all, rvl_all), \
               (rayleigh_pval_novel, rayleigh_pval_rep, ww_pval, kuiper_pval, rayleigh_pval_all), novel_phases, rep_phases

    else:
        return (np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2])), \
               (np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2])), novel_phases, rep_phases
Пример #13
0
def compute_rvl_by_memory(recalled, data, do_perm=False):
    if do_perm:
        recalled = np.random.permutation(recalled)
    rec_rvl = pycircstat.resultant_vector_length(data[:, recalled], axis=1)
    nrec_rvl = pycircstat.resultant_vector_length(data[:, ~recalled], axis=1)
    return rec_rvl, nrec_rvl
Пример #14
0
    def analysis(self):
        """
        For each cluster in res['clusters']:

        1.

        """

        # make sure we have data
        if self.subject_data is None:
            print('%s: compute or load data first with .load_data()!' % self.subject)
            return

        # we must have 'clusters' in self.res
        if 'clusters' in self.res:
            self.res['traveling_waves'] = {}

            # get cluster names from dataframe columns
            cluster_names = list(filter(re.compile('cluster[0-9]+').match, self.res['clusters'].columns))

            # get circular-linear regression parameters
            theta_r, params = self.compute_grid_parameters()

            # compute cluster stats for each cluster
            with Parallel(n_jobs=12, verbose=5) as parallel:
                for this_cluster_name in cluster_names:
                    cluster_res = {}

                    # get the names of the channels in this cluster
                    cluster_elecs = self.res['clusters'][self.res['clusters'][this_cluster_name].notna()]['label']

                    # for the channels in this cluster, bandpass and then hilbert to get the phase info
                    phase_data, power_data, cluster_mean_freq = self.compute_hilbert_for_cluster(this_cluster_name)

                    # reduce to only time inverval of interest
                    time_inds = (phase_data.time >= self.cluster_stat_start_time) & (
                            phase_data.time <= self.cluster_stat_end_time)
                    phase_data = phase_data[:, :, time_inds]

                    # get electrode coordinates in 2d
                    norm_coords = self.compute_2d_elec_coords(this_cluster_name)

                    # run the cluster stats for time-averaged data
                    mean_rel_phase = pycircstat.mean(phase_data.data, axis=2)
                    mean_cluster_wave_ang, mean_cluster_wave_freq, mean_cluster_r2_adj = \
                        circ_lin_regress(mean_rel_phase.T, norm_coords, theta_r, params)
                    cluster_res['mean_cluster_wave_ang'] = mean_cluster_wave_ang
                    cluster_res['mean_cluster_wave_freq'] = mean_cluster_wave_freq
                    cluster_res['mean_cluster_r2_adj'] = mean_cluster_r2_adj

                    # and run it for each time point
                    num_times = phase_data.shape[-1]
                    data_as_list = zip(phase_data.T, [norm_coords] * num_times, [theta_r] * num_times, [params] * num_times)

                    res_as_list = parallel(delayed(circ_lin_regress)(x[0].data, x[1], x[2], x[3]) for x in data_as_list)
                    cluster_res['cluster_wave_ang'] = np.stack([x[0] for x in res_as_list], axis=0).astype('float32')
                    cluster_res['cluster_wave_freq'] = np.stack([x[1] for x in res_as_list], axis=0).astype('float32')
                    cluster_res['cluster_r2_adj'] = np.stack([x[2] for x in res_as_list], axis=0).astype('float32')
                    cluster_res['mean_freq'] = cluster_mean_freq
                    cluster_res['channels'] = cluster_elecs.values
                    cluster_res['time'] = phase_data.time.data
                    cluster_res['phase_data'] = pycircstat.mean(phase_data, axis=1).astype('float32')
                    cluster_res['phase_rvl'] = pycircstat.resultant_vector_length(phase_data, axis=1).astype('float32')

                    # finally, compute the subsequent memory effect
                    if hasattr(self, 'recall_filter_func') and callable(self.recall_filter_func):
                        recalled = self.recall_filter_func(self.subject_data)
                        cluster_res['recalled'] = recalled
                        delta_z, ts, ps = self.compute_sme_for_cluster(power_data)
                        cluster_res['sme_t'] = ts
                        cluster_res['sme_z'] = delta_z
                        cluster_res['ps'] = ps
                        cluster_res['phase_data_recalled'] = pycircstat.mean(phase_data[:, recalled], axis=1).astype(
                            'float32')
                        cluster_res['phase_data_not_recalled'] = pycircstat.mean(phase_data[:, ~recalled], axis=1).astype(
                            'float32')

                        # compute resultant vector length for recalled and not recalled. Then take the difference
                        # between recalled and not recalled
                        rec_rvl, not_rec_rvl = compute_rvl_by_memory(recalled, phase_data, False)
                        rvl_sme = rec_rvl - not_rec_rvl

                        # compute a null distribution of rvl_sme vules
                        rvl_shuff_list = parallel(delayed(compute_rvl_by_memory)(recalled, phase_data, True) for _ in range(self.num_perms))
                        rvl_sme_shuff = np.stack([x[0] - x[1] for x in rvl_shuff_list])

                        # get the rank of the real sme values compared to the shuffled data
                        rvl_sme_shuff_perc = (rvl_sme > rvl_sme_shuff).mean(axis=0)
                        rvl_sme_shuff_perc[rvl_sme_shuff_perc == 0] += 1 / self.num_perms
                        rvl_sme_shuff_perc[rvl_sme_shuff_perc == 1] -= 1 / self.num_perms

                        # convert the ranks to a zscore
                        z = norm.ppf(rvl_sme_shuff_perc)

                        # store in res along with the number of significant electrodes in each direction
                        cluster_res['rvl_sme_z'] = z.astype('float32')
                        cluster_res['rvl_sme_sig_pos_n'] = np.sum(rvl_sme_shuff_perc > 0.975, axis=0)
                        cluster_res['rvl_sme_sig_neg_n'] = np.sum(rvl_sme_shuff_perc < 0.025, axis=0)

                    # finally finally, bin phase by roi
                    cluster_res['phase_by_roi'] = self.bin_phase_by_region(phase_data, this_cluster_name)
                    self.res['traveling_waves'][this_cluster_name] = cluster_res

        else:
            print('{}: self.res must have a clusters entry before running.'.format(self.subject))
            return
Пример #15
0
            fdata = open(drpath + "/" + dirname + "_Summary.txt", 'w')
            fdata.write("Directory used: \n" + updir + dirname +
                        "\nFiles analysed: \n")
            for filename in os.listdir(drpath):
                if "_sep_log.csv" in filename:
                    fdata.write(filename + "\n")
                    file_data = pd.read_csv(drpath + "/" + filename)
                    principal_angle = file_data['principal_angle']
                    Rad_angle = np.deg2rad(principal_angle)
                    Rad_angle2 = (np.deg2rad(principal_angle)) * 2
                    circ_mean = np.rad2deg(
                        stats.circmean(Rad_angle, high=np.pi, low=0))
                    circ_std = np.rad2deg(
                        stats.circstd(Rad_angle, high=np.pi, low=0))
                    RVL = pycircstat.resultant_vector_length(Rad_angle2)
                    ani_mean = np.mean(file_data['anisotropy'])
                    ani_std = np.std(file_data['anisotropy'])
                    fdata.write("Circ_Mean Angle to x (+-Std) --> " +
                                str(circ_mean) + "+-" + str(circ_std) +
                                " degrees\nResultant_vector_length " +
                                str(RVL) + "\nMean Anisotropy (+-Std) --> " +
                                str(ani_mean) + "+-" + str(ani_std) + "\n\n")
                    Crack_data_[dirname].append(file_data)

            data = pd.concat(Crack_data_[dirname], ignore_index=True)
            principal_angles = data['principal_angle']
            Rad_angles = np.deg2rad(principal_angles)
            Rad_angles2 = (np.deg2rad(principal_angles)) * 2
            circ_mean_all = np.rad2deg(
                stats.circmean(Rad_angles, high=np.pi, low=0))
def test_resultant_vector_length_axis():
    data = np.ones((10, 2))
    assert_allclose(pycircstat.resultant_vector_length(data, axis=1),
                    np.ones(10))
def compute_phase_stats_with_shuffle(events, spike_rel_times, phase_data_hilbert, phase_bin_start,
                                     phase_bin_stop, do_permute=False):

    spike_rel_times_tmp = spike_rel_times.copy()
    if do_permute:

        # permute the novel
        novel_events = np.where(events.isFirst.values)[0]
        perm_novel_events = np.random.permutation(novel_events)
        spike_rel_times_tmp[novel_events] = spike_rel_times_tmp[perm_novel_events]

        # and repeated separately
        rep_events = np.where(~events.isFirst.values)[0]
        perm_rep_events = np.random.permutation(rep_events)
        spike_rel_times_tmp[rep_events] = spike_rel_times_tmp[perm_rep_events]

    # get the phases at which the spikes occurred and bin into novel and repeated items for each hilbert band
    spike_phases_hilbert = _compute_spike_phase_by_freq(spike_rel_times_tmp,
                                                        phase_bin_start,
                                                        phase_bin_stop,
                                                        phase_data_hilbert,
                                                        events)

    # bin into repeated and novel phases
    novel_phases, rep_phases = _bin_phases_into_cond(spike_phases_hilbert, events)

    if (len(novel_phases) > 0) & (len(rep_phases) > 0):

        # rayleigh test for uniformity
        rvl_novel = pycircstat.resultant_vector_length(novel_phases, axis=0)
        rvl_rep = pycircstat.resultant_vector_length(rep_phases, axis=0)
        rvl_diff = rvl_novel - rvl_rep

        # compute rayleigh test for each condition
        rayleigh_pval_novel, rayleigh_z_novel = pycircstat.rayleigh(novel_phases, axis=0)
        rayleigh_pval_rep, rayleigh_z_rep = pycircstat.rayleigh(rep_phases, axis=0)
        rayleigh_diff = rayleigh_z_novel - rayleigh_z_rep

        # watson williams test for equal means
        ww_pval, ww_tables = pycircstat.watson_williams(novel_phases, rep_phases, axis=0)
        ww_fstat = np.array([x.loc['Columns'].F for x in ww_tables])

        # kuiper test, to test for difference in dispersion (not mean, because I'm making them equal)
        kuiper_pval, stat_kuiper = pycircstat.kuiper(novel_phases - pycircstat.mean(novel_phases),
                                                     rep_phases - pycircstat.mean(rep_phases), axis=0)

        return (rvl_novel, rvl_rep, rvl_diff, ww_fstat, stat_kuiper, rayleigh_z_novel, rayleigh_z_rep, rayleigh_diff), \
               (rayleigh_pval_novel, rayleigh_pval_rep, ww_pval, kuiper_pval), novel_phases, rep_phases

    else:
        return (np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2])), \
               (np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2]),
                np.array([np.nan] * phase_data_hilbert.shape[2])), novel_phases, rep_phases
Пример #18
0
 #mean_angle=np.rad2deg(stats.circmean(Rad_angle_to_x, high = np.pi/2, low = -np.pi/2))
 #print np.mean(angle_to_x)
 #print np.std(angle_to_x)
 #print np.mean(anisotropy)
 #print np.std(anisotropy)
 fdata.write('Number of cells analysed: ' + str(len(angle_to_x)) +
             '\n' + 'Circ_Mean Angle to x (+-Std) --> ' + str(
                 np.rad2deg(
                     stats.circmean(
                         Rad_angle_pi_[filename], high=np.pi, low=0))) +
             '+-' + str(
                 np.rad2deg(
                     stats.circstd(
                         Rad_angle_pi_[filename], high=np.pi, low=0))) +
             ' degrees' + '\n' + 'Resultant_vector_length ' + str(
                 pycircstat.resultant_vector_length(
                     np.array(Rad_angle_pi_X2_[filename]))) + '\n' +
             'Mean Anisotropy (+-Std) --> ' + str(np.mean(anisotropy)) +
             '+-' + str(np.std(anisotropy)) + '\n' + '\n')
 ###Polar histogram
 figure = plt.figure()
 figure.clf()
 figure.patch.set_facecolor('k')
 ax = figure.add_subplot(111, polar=True)
 colormap = "plasma"
 n_bins = 36
 for offset in [0, np.pi]:
     histo, bins, patches = figure.gca().hist(
         offset + angle_to_x * np.pi / 180,
         bins=offset +
         np.linspace(-90, 90, n_bins / 2 + 1) * np.pi / 180.,
         ec='k',
Пример #19
0
    def plot_cluster_stats(self, cluster_name):
        """
        Multi panel plot showing:

        1. brain map of electrodes in the cluster, color-coded by phase
        2. brain map of electrodes in the cluster, color-coded by subsequent memory effect
        3. timecourse of resultant vector length of wave direction, averaged across trials
        4. timecourse of r^2, averaged across trials
        5. polor plot of left-frontal and hippocampal electrode phases
        6/7. same as 5, but for recalled and not recalled items only

        Data are taken from the timepoint with the highest r-square value.

        Figure creation code is so ugly sorry.
        """

        ############################
        # GET TIME TIME FOR X-AXIS #
        ############################
        time_axis = self.res['traveling_waves'][cluster_name]['time']

        #####################
        # SET UP THE FIGURE #
        #####################
        gs = gridspec.GridSpec(6, 3)
        ax1 = plt.subplot(gs[0, :])
        ax2 = plt.subplot(gs[2, :])
        ax3 = plt.subplot(gs[3, :])
        ax4 = plt.subplot(gs[4, 0], projection='polar')
        ax6 = plt.subplot(gs[4, 1], projection='polar')
        ax7 = plt.subplot(gs[4, 2], projection='polar')
        ax8 = plt.subplot(gs[5, 0], projection='polar')
        ax9 = plt.subplot(gs[5, 1], projection='polar')
        ax10 = plt.subplot(gs[5, 2], projection='polar')
        ax5 = plt.subplot(gs[1, :])

        # some figure parameters
        fig = plt.gcf()
        fig.set_size_inches(15, 30)
        mpl.rcParams['xtick.labelsize'] = 18
        mpl.rcParams['ytick.labelsize'] = 18

        #############################################
        # INFO ABOUT THE ELECTRODES IN THIS CLUSTER #
        #############################################
        cluster_rows = self.res['clusters'][cluster_name].notna()
        regions_all = self.get_electrode_roi_by_hemi()
        regions = regions_all[cluster_rows]['merged_col'].unique()
        regions_str = ', '.join(regions)
        xyz = self.res['clusters'][cluster_rows][['x', 'y', 'z']].values

        ###############################
        # ROW 1: electrodes and phase #
        ###############################
        mean_r2 = np.nanmean(
            self.res['traveling_waves'][cluster_name]['cluster_r2_adj'],
            axis=1)
        argmax_r2 = np.argmax(mean_r2)
        print(argmax_r2)
        phases = self.res['traveling_waves'][cluster_name][
            'phase_data'][:, argmax_r2]
        #     phases = (phases + np.pi) % (2 * np.pi) - np.pi
        #     phases[phases<0] += np.pi*2
        #     phases *= 180. / np.pi
        #     phases -= phases.min() - 1
        colors = np.stack([[0., 0., 0., 0.]] * len(phases))
        cm = clrs.LinearSegmentedColormap.from_list(
            'cm', cc.cyclic_mrybm_35_75_c68_s25)
        cNorm = clrs.Normalize(vmin=0, vmax=np.pi * 2)
        colors[~np.isnan(phases)] = cmx.ScalarMappable(
            norm=cNorm, cmap=cm).to_rgba(phases[~np.isnan(phases)])
        ni_plot.plot_connectome(np.eye(xyz.shape[0]),
                                xyz,
                                node_kwargs={
                                    'alpha': 0.7,
                                    'edgecolors': None
                                },
                                node_size=45,
                                node_color=colors,
                                display_mode='lzr',
                                axes=ax1)
        mean_freq = self.res['traveling_waves'][cluster_name]['mean_freq']
        plt.suptitle('{0} ({1:.2f} Hz): {2}'.format(self.subject, mean_freq,
                                                    regions_str),
                     y=.9)
        divider = make_axes_locatable(ax1)
        cax = divider.append_axes('right', size='6%', pad=15)
        cb1 = mpl.colorbar.ColorbarBase(
            cax,
            cmap=cm,
            norm=cNorm,
            orientation='vertical',
            ticks=[0, np.pi / 2, np.pi, np.pi * 3 / 2, np.pi * 2])
        cb1.ax.yaxis.set_ticklabels(['0°', '90°', '180°', '270°', '360°'])
        cb1.ax.tick_params(labelsize=14)
        for label in cb1.ax.yaxis.get_majorticklabels():
            label.set_transform(
                label.get_transform() +
                mpl.transforms.ScaledTranslation(0.15, 0, fig.dpi_scale_trans))

        ##################################################
        # ROW 2: electrodes and subsequent memory effect #
        ##################################################
        sme = self.res['traveling_waves'][cluster_name]['sme_t'][:, argmax_r2]
        colors = np.stack([[0., 0., 0., 0.]] * len(sme))
        cm = plt.get_cmap('RdBu_r')
        clim = np.max(np.abs(sme))
        cNorm = clrs.Normalize(vmin=-clim, vmax=clim)
        colors[~np.isnan(sme)] = cmx.ScalarMappable(
            norm=cNorm, cmap=cm).to_rgba(sme[~np.isnan(sme)])
        ni_plot.plot_connectome(np.eye(xyz.shape[0]),
                                xyz,
                                node_kwargs={
                                    'alpha': 0.7,
                                    'edgecolors': None
                                },
                                node_size=45,
                                node_color=colors,
                                display_mode='lzr',
                                axes=ax5)
        divider = make_axes_locatable(ax5)
        cax = divider.append_axes('right', size='6%', pad=15)
        cb2 = mpl.colorbar.ColorbarBase(cax,
                                        cmap='RdBu_r',
                                        norm=cNorm,
                                        orientation='vertical')
        cb2.ax.tick_params(labelsize=14)
        for label in cb2.ax.yaxis.get_majorticklabels():
            label.set_transform(
                label.get_transform() +
                mpl.transforms.ScaledTranslation(0.15, 0, fig.dpi_scale_trans))

        ############################
        # ROW 3: timecourse of RVL #
        ############################
        rvl = pycircstat.resultant_vector_length(
            self.res['traveling_waves'][cluster_name]['cluster_wave_ang'],
            axis=1)
        ax2.plot(time_axis, rvl, lw=2)
        ax2.set_ylabel('RVL', fontsize=20)

        ##################################
        # ROW 4: timecourse of r-squared #
        ##################################
        ax3.plot(
            time_axis,
            np.nanmean(
                self.res['traveling_waves'][cluster_name]['cluster_r2_adj'],
                axis=1),
            lw=2)
        ax3.set_xlabel('Time (ms)', fontsize=20)
        ax3.set_ylabel('mean($R^{2}$)', fontsize=20)

        ############################
        # ROW 5a: phase polar plots #
        ############################
        #     phases = np.deg2rad(phases)
        cluster_regions = regions_all[cluster_rows]['merged_col']
        phases_left_front = phases[cluster_regions == 'left-Frontal']
        phases_hipp = phases[(cluster_regions == 'left-Hipp') |
                             (cluster_regions == 'right-Hipp')]
        phases_other = phases[
            ~cluster_regions.isin(['left-Frontal', 'left-Hipp', 'right-Hipp'])]

        for this_phase in phases_left_front:
            ax4.plot([this_phase, this_phase], [0, 1],
                     lw=3,
                     c='#67a9cf',
                     alpha=.5)
        for this_phase in phases_hipp:
            ax4.plot([this_phase, this_phase], [0, 1],
                     lw=3,
                     c='#ef8a62',
                     alpha=.5)
        for this_phase in phases_other:
            ax4.plot([this_phase, this_phase], [0, .7],
                     lw=2,
                     c='k',
                     alpha=.4,
                     zorder=-1)
        ax4.grid()
        for r in np.linspace(0, 2 * np.pi, 5)[:-1]:
            ax4.plot([r, r], [0, 1.3], lw=1, c=[.7, .7, .7], zorder=-2)
        ax4.spines['polar'].set_visible(False)
        ax4.set_ylim(0, 1.3)
        ax4.set_yticklabels([])
        ax4.set_aspect('equal', 'box')
        red_patch = mpatches.Patch(color='#67a9cf', label='L. Frontal')
        blue_patch = mpatches.Patch(color='#ef8a62', label='Hipp')
        _ = ax4.legend(handles=[red_patch, blue_patch],
                       loc='lower left',
                       bbox_to_anchor=(0.9, 0.9),
                       frameon=False,
                       fontsize=16)

        ################################################
        # ROW 5b: phase polar plots for recalled items #
        ################################################
        phases = self.res['traveling_waves'][cluster_name][
            'phase_data_recalled'][:, argmax_r2]
        #     phases = (phases + np.pi) % (2 * np.pi) - np.pi
        #     phases *= 180. / np.pi
        #     phases -= phases.min() - 1
        #     phases = np.deg2rad(phases)
        phases_left_front = phases[cluster_regions == 'left-Frontal']
        phases_hipp = phases[(cluster_regions == 'left-Hipp') |
                             (cluster_regions == 'right-Hipp')]
        phases_other = phases[
            ~cluster_regions.isin(['left-Frontal', 'left-Hipp', 'right-Hipp'])]

        for this_phase in phases_left_front:
            ax6.plot([this_phase, this_phase], [0, 1],
                     lw=3,
                     c='#67a9cf',
                     alpha=.5)
        for this_phase in phases_hipp:
            ax6.plot([this_phase, this_phase], [0, 1],
                     lw=3,
                     c='#ef8a62',
                     alpha=.5)
        for this_phase in phases_other:
            ax6.plot([this_phase, this_phase], [0, .7],
                     lw=2,
                     c='k',
                     alpha=.4,
                     zorder=-1)
        ax6.grid()
        for r in np.linspace(0, 2 * np.pi, 5)[:-1]:
            ax6.plot([r, r], [0, 1.3], lw=1, c=[.7, .7, .7], zorder=-2)
        ax6.spines['polar'].set_visible(False)
        ax6.set_ylim(0, 1.3)
        ax6.set_yticklabels([])
        ax6.set_aspect('equal', 'box')
        ax6.set_title('Recalled items', y=1.12)

        ####################################################
        # ROW 5c: phase polar plots for not recalled items #
        ####################################################
        phases = self.res['traveling_waves'][cluster_name][
            'phase_data_not_recalled'][:, argmax_r2]
        #     phases = (phases + np.pi) % (2 * np.pi) - np.pi
        #     phases *= 180. / np.pi
        #     phases -= phases.min() - 1
        #     phases = np.deg2rad(phases)
        phases_left_front = phases[cluster_regions == 'left-Frontal']
        phases_hipp = phases[(cluster_regions == 'left-Hipp') |
                             (cluster_regions == 'right-Hipp')]
        phases_other = phases[
            ~cluster_regions.isin(['left-Frontal', 'left-Hipp', 'right-Hipp'])]

        for this_phase in phases_left_front:
            ax7.plot([this_phase, this_phase], [0, 1],
                     lw=3,
                     c='#67a9cf',
                     alpha=.5)
        for this_phase in phases_hipp:
            ax7.plot([this_phase, this_phase], [0, 1],
                     lw=3,
                     c='#ef8a62',
                     alpha=.5)
        for this_phase in phases_other:
            ax7.plot([this_phase, this_phase], [0, .7],
                     lw=2,
                     c='k',
                     alpha=.4,
                     zorder=-1)
        ax7.grid()
        for r in np.linspace(0, 2 * np.pi, 5)[:-1]:
            ax7.plot([r, r], [0, 1.3], lw=1, c=[.7, .7, .7], zorder=-2)
        ax7.spines['polar'].set_visible(False)
        ax7.set_ylim(0, 1.3)
        ax7.set_yticklabels([])
        ax7.set_aspect('equal', 'box')
        ax7.set_title('Not recalled items', y=1.12)

        ####################################################
        # ROW 6:
        ####################################################
        recalled = self.res['traveling_waves']['cluster1']['recalled']
        if ('left-Frontal' in self.res['traveling_waves'][cluster_name]['phase_by_roi']) & \
                ('both-Hipp' in self.res['traveling_waves'][cluster_name]['phase_by_roi']):

            phase_by_roi = self.res['traveling_waves'][cluster_name][
                'phase_by_roi']

            phase_left_front_roi = phase_by_roi['left-Frontal'][:, argmax_r2]
            #         phase_left_front_roi = (phase_left_front_roi + np.pi) % (2 * np.pi)
            phase_hipp_roi = phase_by_roi['both-Hipp'][:, argmax_r2]
            #         phase_hipp_roi = (phase_hipp_roi + np.pi) % (2 * np.pi)
            #         phase_left_front_roi = (phase_left_front_roi + np.pi) % (2 * np.pi) - np.pi
            #         phase_left_front_roi *= 180. / np.pi
            #         phase_left_front_roi -= phase_left_front_roi.min() - 1
            #         phase_left_front_roi = np.deg2rad(phase_left_front_roi)
            #         phase_hipp_roi = (phase_hipp_roi + np.pi) % (2 * np.pi) - np.pi
            #         phase_hipp_roi *= 180. / np.pi
            #         phase_hipp_roi -= phase_hipp_roi.min() - 1
            #         phase_hipp_roi = np.deg2rad(phase_hipp_roi)

            # LEFT
            ax8 = self.rose_plot(phase_left_front_roi, n_bins=30, ax=ax8)
            ax8 = self.rose_plot(phase_hipp_roi, n_bins=30, ax=ax8)
            ax8.spines['polar'].set_visible(False)
            ax8.set_yticks([ax8.get_ylim()[1]])
            ax8.set_aspect('equal', 'box')
            ax8.tick_params(axis='y', colors=[.7, .7, .7])
            for r in np.linspace(0, 2 * np.pi, 5)[:-1]:
                ax8.plot([r, r], [0, ax8.get_ylim()[1]],
                         lw=1,
                         c=[.7, .7, .7],
                         zorder=-2)
            ax8.grid()

            # MIDDLE
            ax9 = self.rose_plot(phase_left_front_roi[recalled],
                                 n_bins=30,
                                 ax=ax9)
            ax9 = self.rose_plot(phase_hipp_roi[recalled], n_bins=30, ax=ax9)
            ax9.spines['polar'].set_visible(False)
            ax9.set_yticks([ax9.get_ylim()[1]])
            ax9.set_aspect('equal', 'box')
            ax9.tick_params(axis='y', colors=[.7, .7, .7])
            for r in np.linspace(0, 2 * np.pi, 5)[:-1]:
                ax9.plot([r, r], [0, ax9.get_ylim()[1]],
                         lw=1,
                         c=[.7, .7, .7],
                         zorder=-2)
            ax9.grid()

            # RIGHT
            ax10 = self.rose_plot(phase_left_front_roi[~recalled],
                                  n_bins=30,
                                  ax=ax10)
            ax10 = self.rose_plot(phase_hipp_roi[~recalled],
                                  n_bins=30,
                                  ax=ax10)
            ax10.spines['polar'].set_visible(False)
            ax10.set_yticks([ax10.get_ylim()[1]])
            ax10.set_aspect('equal', 'box')
            ax10.tick_params(axis='y', colors=[.7, .7, .7])
            for r in np.linspace(0, 2 * np.pi, 5)[:-1]:
                ax10.plot([r, r], [0, ax10.get_ylim()[1]],
                          lw=1,
                          c=[.7, .7, .7],
                          zorder=-2)
            ax10.grid()

        plt.subplots_adjust(hspace=.5)
        return fig
Пример #20
0
    def analysis(self):
        """
        For each cluster in res['clusters']:

        1.

        """

        # make sure we have data
        if self.subject_data is None:
            print('%s: compute or load data first with .load_data()!' %
                  self.subject)
            return

        # we must have 'clusters' in self.res
        if 'clusters' in self.res:
            self.res['traveling_waves'] = {}

            # get cluster names from dataframe columns
            cluster_names = list(
                filter(
                    re.compile('cluster[0-9]+').match,
                    self.res['clusters'].columns))

            # get circular-linear regression parameters
            theta_r, params = self.compute_grid_parameters()

            # compute cluster stats for each cluster
            with Parallel(n_jobs=12, verbose=5) as parallel:
                for this_cluster_name in cluster_names:
                    cluster_res = {}

                    # get the names of the channels in this cluster
                    cluster_elecs = self.res['clusters'][self.res['clusters'][
                        this_cluster_name].notna()]['label']

                    # for the channels in this cluster, bandpass and then hilbert to get the phase info
                    phase_data, power_data, cluster_mean_freq = self.compute_hilbert_for_cluster(
                        this_cluster_name)

                    # reduce to only time inverval of interest
                    time_inds = (
                        phase_data.time >= self.cluster_stat_start_time) & (
                            phase_data.time <= self.cluster_stat_end_time)
                    phase_data = phase_data[:, :, time_inds]

                    # get electrode coordinates in 2d
                    norm_coords = self.compute_2d_elec_coords(
                        this_cluster_name)

                    # run the cluster stats for time-averaged data
                    mean_rel_phase = pycircstat.mean(phase_data.data, axis=2)
                    mean_cluster_wave_ang, mean_cluster_wave_freq, mean_cluster_r2_adj = \
                        circ_lin_regress(mean_rel_phase.T, norm_coords, theta_r, params)
                    cluster_res[
                        'mean_cluster_wave_ang'] = mean_cluster_wave_ang
                    cluster_res[
                        'mean_cluster_wave_freq'] = mean_cluster_wave_freq
                    cluster_res['mean_cluster_r2_adj'] = mean_cluster_r2_adj

                    # and run it for each time point
                    num_times = phase_data.shape[-1]
                    data_as_list = zip(phase_data.T, [norm_coords] * num_times,
                                       [theta_r] * num_times,
                                       [params] * num_times)

                    res_as_list = parallel(
                        delayed(circ_lin_regress)(x[0].data, x[1], x[2], x[3])
                        for x in data_as_list)
                    cluster_res['cluster_wave_ang'] = np.stack(
                        [x[0] for x in res_as_list], axis=0).astype('float32')
                    cluster_res['cluster_wave_freq'] = np.stack(
                        [x[1] for x in res_as_list], axis=0).astype('float32')
                    cluster_res['cluster_r2_adj'] = np.stack(
                        [x[2] for x in res_as_list], axis=0).astype('float32')
                    cluster_res['mean_freq'] = cluster_mean_freq
                    cluster_res['channels'] = cluster_elecs.values
                    cluster_res['time'] = phase_data.time.data
                    cluster_res['phase_data'] = pycircstat.mean(
                        phase_data, axis=1).astype('float32')
                    cluster_res[
                        'phase_rvl'] = pycircstat.resultant_vector_length(
                            phase_data, axis=1).astype('float32')

                    # finally, compute the subsequent memory effect
                    if hasattr(self, 'recall_filter_func') and callable(
                            self.recall_filter_func):
                        recalled = self.recall_filter_func(self.subject_data)
                        cluster_res['recalled'] = recalled
                        delta_z, ts, ps = self.compute_sme_for_cluster(
                            power_data)
                        cluster_res['sme_t'] = ts
                        cluster_res['sme_z'] = delta_z
                        cluster_res['ps'] = ps
                        cluster_res['phase_data_recalled'] = pycircstat.mean(
                            phase_data[:, recalled], axis=1).astype('float32')
                        cluster_res[
                            'phase_data_not_recalled'] = pycircstat.mean(
                                phase_data[:, ~recalled],
                                axis=1).astype('float32')

                        # compute resultant vector length for recalled and not recalled. Then take the difference
                        # between recalled and not recalled
                        rec_rvl, not_rec_rvl = compute_rvl_by_memory(
                            recalled, phase_data, False)
                        rvl_sme = rec_rvl - not_rec_rvl

                        # compute a null distribution of rvl_sme vules
                        rvl_shuff_list = parallel(
                            delayed(compute_rvl_by_memory)(recalled,
                                                           phase_data, True)
                            for _ in range(self.num_perms))
                        rvl_sme_shuff = np.stack(
                            [x[0] - x[1] for x in rvl_shuff_list])

                        # get the rank of the real sme values compared to the shuffled data
                        rvl_sme_shuff_perc = (rvl_sme > rvl_sme_shuff).mean(
                            axis=0)
                        rvl_sme_shuff_perc[rvl_sme_shuff_perc ==
                                           0] += 1 / self.num_perms
                        rvl_sme_shuff_perc[rvl_sme_shuff_perc ==
                                           1] -= 1 / self.num_perms

                        # convert the ranks to a zscore
                        z = norm.ppf(rvl_sme_shuff_perc)

                        # store in res along with the number of significant electrodes in each direction
                        cluster_res['rvl_sme_z'] = z.astype('float32')
                        cluster_res['rvl_sme_sig_pos_n'] = np.sum(
                            rvl_sme_shuff_perc > 0.975, axis=0)
                        cluster_res['rvl_sme_sig_neg_n'] = np.sum(
                            rvl_sme_shuff_perc < 0.025, axis=0)

                    # finally finally, bin phase by roi
                    cluster_res['phase_by_roi'] = self.bin_phase_by_region(
                        phase_data, this_cluster_name)
                    self.res['traveling_waves'][
                        this_cluster_name] = cluster_res

        else:
            print('{}: self.res must have a clusters entry before running.'.
                  format(self.subject))
            return
Пример #21
0
                imgpath = drpath + '/' + files
                #print 'image path: ' + imgpath
                Rad_angle_pi_X2_[files] = []
                DegAngles = np.genfromtxt(imgpath,
                                          delimiter='\t',
                                          usecols=5,
                                          dtype=None)
                RadAngles = np.deg2rad(DegAngles)
                #print RadAngles
                for a in RadAngles:
                    if a < 0:
                        a = a + (np.pi)
                    b = a * 2
                    Rad_angle_pi_X2_[files].append(b)
                #print Rad_angle_pi_X2_[files]
                RVL = pycircstat.resultant_vector_length(
                    np.array(Rad_angle_pi_X2_[files]))
                #fdata.write('Sample analysed: '+ imgpath +'\n' + 'Resultant vector length --> ' + str(RVL) + '\n'+ '\n')

                RVLdata_[dirname].append(RVL)
                #RVLdata.append(RVL)

        print str(dirname) + ' :' + str(RVLdata_[dirname])
        RVLdata.append(RVLdata_[dirname])
        fdata.write('Mean RVL' + str(dirname) + '(+-Std) --> ' +
                    str(np.mean(RVLdata_[dirname])) + '+-' +
                    str(np.std(RVLdata_[dirname])) + '\n')

###Comparaisons
sampleA = ['MBD_1%', 'MBD_1%', 'MBD_1%', 'MBD_2,5%', 'MBD_2,5%', 'qua1MBD_1%']
sampleB = [
    'MBD_2,5%', 'qua1MBD_1%', 'qua1MBD_2,5%', 'qua1MBD_1%', 'qua1MBD_2,5%',
Пример #22
0
def test_resultant_vector_length():
    data = np.ones(10)
    assert_allclose(pycircstat.resultant_vector_length(data), 1.0)
def test_resultant_vector_length():
    data = np.ones(10)
    assert_allclose(pycircstat.resultant_vector_length(data), 1.0)
Пример #24
0
def test_resultant_vector_length_axis():
    data = np.ones((10, 2))
    assert_allclose(pycircstat.resultant_vector_length(data, axis=1),
                    np.ones(10))
Пример #25
0
def compute_rvl_by_memory(recalled, data, do_perm=False):
    if do_perm:
        recalled = np.random.permutation(recalled)
    rec_rvl = pycircstat.resultant_vector_length(data[:, recalled], axis=1)
    nrec_rvl = pycircstat.resultant_vector_length(data[:, ~recalled], axis=1)
    return rec_rvl, nrec_rvl