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}
def cl_corr(x, phase, min_slope, max_slope, ci=.05, bootstrap_iter=1000, return_pval=False): ''' Function to (1) fit a line to circular-linear data and (2) determine the circular-linear correlation coefficient Parameters ---------- x : array real-valued vector of `linear' instances (e.g. places, attenuations, frequencies, etc.) phase : array vector of phases at instances x in rad (values need NOT be restricted to the interval [0, 2pi) [min_slope, max_slope]: float interval of slopes in which the best_slope is determined. In contrast to linear regression, we MUST restrict the range of slopes to some `useful' range determined by prior knowledge. ATTENTION ! because this is a possible source of errors, in particular for low numbers of data points. ci : float level of confidence desired, e.g. .05 for 95 % confidence bootstrap_iter : int number of bootstrap iterations (number of samples if None) return_pval : bool return pvalue instead of confidence interval See also -------- pycircstat.corrcc Returns ------- circ_lin_corr : float circular-linear correlation coefficient ci/pval : array confidence interval slope : float slope of the fitted line in rad phi0_deg : float phase offset of the fitted line in deg RR : float goodness of fit ''' phi0, slope, RR = cl_regression(x, phase, min_slope, max_slope) # fit line to data circ_x = np.mod(2 * np.pi * abs(slope) * x, 2 * np.pi) # convert linear variable to circular one if return_pval: p_uniform = 0.5 pval_x, _ = rayleigh(circ_x) pval_y, _ = rayleigh(phase) if (pval_x > p_uniform) or (pval_y > p_uniform): circ_lin_corr, pval, _ = corr_cc_uniform(circ_x, phase) else: circ_lin_corr, pval, _ = corr_cc(circ_x, phase) return circ_lin_corr, pval, slope, phi0, RR else: circ_lin_corr, ci_out = corrcc(circ_x, phase, ci=ci, bootstrap_iter=bootstrap_iter) return circ_lin_corr, ci_out, slope, phi0, RR
def _compute_novel_rep_spike_stats(novel_phases, rep_phases): # compute rayleigh test for each condition p_novel, z_novel = pycircstat.rayleigh(novel_phases, axis=0) p_rep, z_rep = pycircstat.rayleigh(rep_phases, axis=0) # test whether the means are different ww_pvals, ww_tables = pycircstat.watson_williams(novel_phases, rep_phases, axis=0) ww_fstat = np.array([x.loc['Columns'].F for x in ww_tables]) # test whether the medians are different med_pvals, med_stat = pycircstat.cmtest(novel_phases, rep_phases, axis=0) # finall run kuiper test for difference in mean and/or dispersion p_kuiper, stat_kuiper = pycircstat.kuiper(novel_phases, rep_phases, axis=0) return p_novel, z_novel, p_rep, z_rep, ww_pvals, ww_fstat, med_pvals, med_stat, p_kuiper, stat_kuiper
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
def plot_SAC(): #fig, ax = plt.subplots(len(pattern_list)+1, 3) fig = plt.figure() gs_outer = gridspec.GridSpec(4, 1) # 4 rows, one column gs_inner = [] ax = {} for i, outer in enumerate(gs_outer): gs_inner.append(gridspec.GridSpecFromSubplotSpec(4, 4, subplot_spec=outer)) ax1 = plt.Subplot(fig, gs_inner[-1][:-1, 0]) fig.add_subplot(ax1) ax2 = plt.Subplot(fig, gs_inner[-1][3, 0]) fig.add_subplot(ax2) ax3 = plt.Subplot(fig, gs_inner[-1][:, 1]) fig.add_subplot(ax3) ax4 = plt.Subplot(fig, gs_inner[-1][:, 2]) fig.add_subplot(ax4) ax5 = plt.Subplot(fig, gs_inner[-1][:, 3]) fig.add_subplot(ax5) ax[i] = [ax1, ax2, ax3, ax4, ax5] for a in ax[i]: PH.nice_plot(a) #PH.noaxes(ax1, 'x') #fig.tight_layout() # plt.show() # exit() # d[cell] has keys: ['inputSpikeTimes', 'somaVoltage', 'spikeTimes', 'time', 'dendriteVoltage', 'stimInfo', 'stimWaveform'] #print 'data keys: ', d.keys() #print len(d['time']) fmod = d[patterns[0]]['stimInfo']['mod'] # modulation frequency sacht = 2.5 sacmax = 100 phaseht = 15 #print d['spikeTimes'] for j, pattern in enumerate(patterns): w = d[patterns[j]]['stimWaveform'][0][0].generate() t = d[patterns[j]]['stimWaveform'][0][0].time ax[j][1].plot(t, w) # stimulus underneath for i, st in enumerate(d[pattern]['spikeTimes'].keys()): ax[j][0].plot(d[pattern]['spikeTimes'][st]/1000., i*np.ones(len( d[pattern]['spikeTimes'][st])), 'o', markersize=2.5, color='b') inputs = len(d[pattern]['inputSpikeTimes'][st]) # for j in range(inputs): # t = (d['ref']['inputSpikeTimes'][st][j])/1000. # y = (i+0.1+j*0.05)*np.ones(len(t)) # ax[0,].plot(t, y, 'o', markersize=2.5, color='r') #for i, st in enumerate(d['ref']['somaVoltage'].keys()): # ax[2,].plot(d['ref']['time'], d['ref']['somaVoltage'][st], color='k') ax[j][0].set_xlim((0, 0.8)) ax[j][1].set_xlim((0, 0.8)) sac = SAC.SAC() xf = [] dt = 0.1 u = 2.0*np.pi/(1000.0/fmod) for j, pattern in enumerate(patterns): X = [] R = {} pars = {'twin': 500., 'binw': 1., 'ntestrep': 20, 'baseper': 1.0, 'stimdur': 800., 'delay': 100., 'dur': 1000., 'ddur': 200.} pars_x = pars = {'twin': 500., 'binw': 1., 'ntestrep': 20, 'baseper': 1.0, 'stimdur': 800., 'delay': 100., 'dur': 1000., 'ddur': 200.} tsynch = np.arange(0., 1000., dt) x_spl = [] y_spl = [] Nspikes = 0 for i, st in enumerate(d[pattern]['spikeTimes'].keys()): X.append(d[pattern]['spikeTimes'][st]) xw = np.zeros(tsynch.shape[0]) # print [int(xx/dt) for xx in X[-1]] Nspikes += np.shape(X[-1])[0] # calculate vector strength as well. x_spl.append(np.cos(np.array(X[-1])*u)) y_spl.append(np.sin(np.array(X[-1])*u)) x_spl = np.hstack(x_spl) y_spl = np.hstack(y_spl) vs = np.sqrt(np.sum(x_spl)**2 + np.sum(y_spl)**2)/Nspikes th = np.arctan2(y_spl, x_spl) p, z = PCS.rayleigh(th, w=None, d=None, axis=None) if j == 0: X0 = X # save the X yh, bins = sac.SAC_asm(X, pars) print ('mean vs: for %s at fMod = %.2f: %f angle: %f' % (pattern, fmod, vs, th.mean())) print ('rayleigh: p=%f z=%f (p > 0.05 means data is uniformly distributed)' % (p, z)) ax[j][2].bar(bins[:-1], yh) ax[j][2].set_xlim((-sacmax, sacmax)) ax[j][2].set_ylim((0, sacht)) phasebinnum = 101 phasebins = np.linspace(-0.5, 0.5, num=phasebinnum) thhist, thbins = np.histogram(th/np.pi, bins=phasebins, density=False) ax[j][3].bar(thbins[:-1]+0.5, thhist, width=1.0/phasebinnum) ax[j][3].set_ylim((0, phaseht)) if j == 0: continue ycc, ccbins = sac.XAC(X0, X, pars_x, trialbased=True) ax[j][4].bar(ccbins[:-1], ycc) ax[j][4].set_xlim((-sacmax, sacmax)) # now cross-correlate data... #PH.nice_plot(ax.flatten().tolist()) plt.show()
def show_SAC(self): sac = SAC.SAC() f, ax = plt.figure() d = {} for p in self.Params['patterns']: h = open(os.path.join(self.bp[p], self.fn[p])) d[p] = pickle.load(h) h.close() fmod = d['patterns'[0]]['stimInfo']['fmod'] # modulation frequency #sacht = 2.5 sacmax = 100 #phaseht = 15 f, ax2 = plt.subplots(1) u = 2.0*np.pi/(1000.0/fmod) for j, pattern in enumerate(self.Params['patterns']): X = [] pars = {'twin': 500., 'binw': 1., 'ntestrep': 20, 'baseper': 1.0, 'stimdur': 800., 'delay': 100., 'dur': 1000., 'ddur': 200.} pars_x = pars = {'twin': 500., 'binw': 1., 'ntestrep': 20, 'baseper': 1.0, 'stimdur': 800., 'delay': 100., 'dur': 1000., 'ddur': 200.} x_spl = [] y_spl = [] Nspikes = 0 for i, st in enumerate(d[pattern]['spikeTimes'].keys()): X.append(d[pattern]['spikeTimes'][st]) Nspikes += np.shape(X[-1])[0] # calculate vector strength as well. x_spl.append(np.cos(np.array(X[-1])*u)) y_spl.append(np.sin(np.array(X[-1])*u)) x_spl = np.hstack(x_spl) y_spl = np.hstack(y_spl) vs = np.sqrt(np.sum(x_spl)**2 + np.sum(y_spl)**2)/Nspikes th = np.arctan2(y_spl, x_spl) p, z = PCS.rayleigh(th, w=None, d=None, axis=None) if j == 0: X0 = X # save the X yh, bins = sac.SAC_asm(X, pars) print('mean vs: for %s at fMod = %.2f: %f angle: %f' % (pattern, fmod, vs, th.mean())) print('rayleigh: p=%f z=%f (p > 0.05 means data is uniformly distributed)' % (p, z)) ax[j][2].bar(bins[:-1], yh) ax[j][2].set_xlim((-sacmax, sacmax)) # ax[j][2].set_ylim((0, sacht)) phasebinnum = 101 phasebins = np.linspace(-0.5, 0.5, num=phasebinnum) thhist, thbins = np.histogram(th/np.pi, bins=phasebins, density=False) ax[j][3].bar(thbins[:-1]+0.5, thhist, width=1.0/phasebinnum) # ax[j][3].set_ylim((0, phaseht)) if j == 0: continue ycc, ccbins = sac.XAC(X0, X, pars_x, trialbased=True) ax[j][4].bar(ccbins[:-1], ycc) ax[j][4].set_xlim((-sacmax, sacmax)) # now cross-correlate data... #PH.nice_plot(ax.flatten().tolist()) plt.show()
def compute_rayleigh_stat(phase_data): # run rayleight test for this frequency ps, zs = pycircstat.rayleigh(phase_data.data, axis=1) return ps, zs, phase_data.time.data
# average angles: XXX THEORETICALLY INCORRECT angle_error = np.mean(probas * operator, axis=3) # XXX NB we should average in complex space but somehow it doesnt work #xy = np.mean(probas * (np.cos(operator) + 1j *sin(operator)), axis=3) #angle_error, _ = cart2pol(real(xy), imag(xy)) else: angle_error = np.argmax(probas, axis=3) * np.pi / 3 - np.pi / 6 ####### STATS WITHIN SUBJECTS # Apply v test and retrieve statistics that is independent of the number of # trials. p_val_v, v = vtest(angle_error, 0, axis=2) # trials x time # apply Rayleigh test (better for of diagonal with distribution shifts, e.g. # on the n200, the prediction may reverse) p_val_z, z = rayleigh(angle_error, axis=2) # trials x time # append scores V.append(v) Z.append(z) p_values_v.append(p_val_v) p_values_z.append(p_val_z) angle_errors.append(np.mean(angle_error, axis=2)) # divide by visibility if s ==0: angle_errors_vis = np.zeros([len(subjects), n_time, n_test_time, 4]) for v, vis in enumerate(arange(1, 5)): indx = np.array(events['response_visibilityCode'][sel]==vis) angle_errors_vis[s,:,:,v] = np.mean(angle_error[:,:,indx],axis=2)
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