def get_freqs(sample_rate, window_length=0.060, increment=None): if increment is None: increment = 2.0 / sample_rate nt = int(window_length*2*sample_rate) s = np.random.randn(nt) pfreq,psd1,ps_var,phase = power_spectrum_jn(s, sample_rate, window_length, increment) return pfreq
def compute_filt_power_spectra(filts, sample_rate, lags_ms): filt_freq = None psds = list() # fi = (lags_ms > 8.) & (lags_ms < 125.) # fi = (lags_ms > 8.) fi = (lags_ms > -1) for f in filts: filt_freq,filt_ps,filt_ps_var,filt_phase = power_spectrum_jn(f[fi], sample_rate, 0.250, 0.025) psds.append(filt_ps) psds = np.array(psds) psds /= psds.max() # log_transform(psds) fi = filt_freq < 40. return filt_freq[fi], psds[:, fi]
def get_env_psds(rp): # compute the stim amp envelope stim_env = rp.U.sum(axis=1) stim_env /= stim_env.max() # grab the amplitude envelope for each stimulus print 'Computing psds...' stim_ids = rp.event_df.stim_id.unique() env_data = {'stim_id': list(), 'stim_type': list(), 'duration': list(), 'xindex': list()} env_psds = list() env_freq = None duration_thresh = 1.1 for stim_id in stim_ids: i = rp.event_df.stim_id == stim_id stim_type = rp.event_df[i].stim_type.values[0] stime = rp.event_df[i].start_time.values[0] etime = rp.event_df[i].end_time.values[0] dur = etime - stime if dur < duration_thresh: print 'Stim %d (%s) is too short: %0.3fs' % (stim_id, stim_type, dur) continue si = int(stime * rp.sample_rate) ei = int(etime * rp.sample_rate) u = stim_env[si:ei] env_freq, env_ps, env_ps_var, env_phase = power_spectrum_jn(u, rp.sample_rate, window_length=1.0, increment=0.200) env_data['stim_id'].append(stim_id) env_data['stim_type'].append(stim_type) env_data['duration'].append(etime - stime) env_data['xindex'].append(len(env_psds)) env_psds.append(env_ps) env_psds = np.array(env_psds) fi = (env_freq >= 2.) & (env_freq <= 30.) env_psds = env_psds[:, fi] env_freq = env_freq[fi] env_df = pd.DataFrame(env_data) return env_freq,env_psds,env_df
def testFFT(self): sr = 1000. freqs = [35.] dur = 0.500 nt = int(dur * sr) t = np.arange(nt) / sr # create a psth that has the specific frequencies psth = np.zeros([nt]) for f in freqs: psth += np.sin(2 * np.pi * f * t) max_spike_rate = 0.1 psth /= psth.max() psth += 1. psth /= 2.0 psth *= max_spike_rate # simulate a spike train with a variety of frequencies in it trials = simulate_poisson(psth, dur, num_trials=10) bin_size = 0.001 binned_trials = spike_trains_to_matrix(trials, bin_size, 0.0, dur) mean_psth = binned_trials.mean(axis=0) # compute the power spectrum of each spike train psds = list() pfreq = None win_len = 0.090 inc = 0.010 for st in binned_trials: pfreq, psd, ps_var, phase = power_spectrum_jn( st, 1.0 / bin_size, win_len, inc) nz = psd > 0 psd[nz] = 20 * np.log10(psd[nz]) + 100 psd[psd < 0] = 0 psds.append(psd) psds = np.array(psds) mean_psd = psds.mean(axis=0) pfreq, mean_psd2, ps_var, phase = power_spectrum_jn( mean_psth, 1.0 / bin_size, win_len, inc) nz = mean_psd2 > 0 mean_psd2[nz] = 20 * np.log10(mean_psd2[nz]) + 100 mean_psd2[mean_psd2 < 0] = 0 plt.figure() ax = plt.subplot(2, 1, 1) plot_raster(trials, ax=ax, duration=dur, bin_size=0.001, time_offset=0.0, ylabel='Trial #', bgcolor=None, spike_color='k') ax = plt.subplot(2, 1, 2) plt.plot(pfreq, mean_psd, 'k-', linewidth=3.0) for psd in psds: plt.plot(pfreq, psd, '-', linewidth=2.0, alpha=0.75) plt.plot(pfreq, mean_psd2, 'k--', linewidth=3.0, alpha=0.60) plt.axis('tight') plt.xlabel('Frequency (Hz)') plt.ylabel('Power (dB)') plt.xlim(0, 100.) plt.show()
def testFFT(self): sr = 1000. freqs = [35.] dur = 0.500 nt = int(dur*sr) t = np.arange(nt) / sr # create a psth that has the specific frequencies psth = np.zeros([nt]) for f in freqs: psth += np.sin(2*np.pi*f*t) max_spike_rate = 0.1 psth /= psth.max() psth += 1. psth /= 2.0 psth *= max_spike_rate # simulate a spike train with a variety of frequencies in it trials = simulate_poisson(psth, dur, num_trials=10) bin_size = 0.001 binned_trials = spike_trains_to_matrix(trials, bin_size, 0.0, dur) mean_psth = binned_trials.mean(axis=0) # compute the power spectrum of each spike train psds = list() pfreq = None win_len = 0.090 inc = 0.010 for st in binned_trials: pfreq,psd,ps_var,phase = power_spectrum_jn(st, 1.0 / bin_size, win_len, inc) nz = psd > 0 psd[nz] = 20*np.log10(psd[nz]) + 100 psd[psd < 0] = 0 psds.append(psd) psds = np.array(psds) mean_psd = psds.mean(axis=0) pfreq,mean_psd2,ps_var,phase = power_spectrum_jn(mean_psth, 1.0/bin_size, win_len, inc) nz = mean_psd2 > 0 mean_psd2[nz] = 20*np.log10(mean_psd2[nz]) + 100 mean_psd2[mean_psd2 < 0] = 0 plt.figure() ax = plt.subplot(2, 1, 1) plot_raster(trials, ax=ax, duration=dur, bin_size=0.001, time_offset=0.0, ylabel='Trial #', bgcolor=None, spike_color='k') ax = plt.subplot(2, 1, 2) plt.plot(pfreq, mean_psd, 'k-', linewidth=3.0) for psd in psds: plt.plot(pfreq, psd, '-', linewidth=2.0, alpha=0.75) plt.plot(pfreq, mean_psd2, 'k--', linewidth=3.0, alpha=0.60) plt.axis('tight') plt.xlabel('Frequency (Hz)') plt.ylabel('Power (dB)') plt.xlim(0, 100.) plt.show()
def compute_spectra_and_coherence_single_electrode(lfp1, lfp2, sample_rate, e1, e2, window_length=0.060, increment=None, log=True, window_fraction=0.60, noise_floor_db=25, lags=np.arange(-20, 21, 1), psd_stats=None): """ :param lfp1: An array of shape (ntrials, nt) :param lfp2: An array of shape (ntrials, nt) :return: """ # compute the mean (locked) spectra lfp1_mean = lfp1.mean(axis=0) lfp2_mean = lfp2.mean(axis=0) if increment is None: increment = 2.0 / sample_rate pfreq,psd1,ps_var,phase = power_spectrum_jn(lfp1_mean, sample_rate, window_length, increment) pfreq,psd2,ps_var,phase = power_spectrum_jn(lfp2_mean, sample_rate, window_length, increment) if log: log_transform(psd1) log_transform(psd2) c12 = coherency(lfp1_mean, lfp2_mean, lags, window_fraction=window_fraction, noise_floor_db=noise_floor_db) # compute the nonlocked spectra coherence c12_pertrial = list() ntrials,nt = lfp1.shape psd1_ms_all = list() psd2_ms_all = list() for k in range(ntrials): i = np.ones([ntrials], dtype='bool') i[k] = False lfp1_jn_mean = lfp1[i, :].mean(axis=0) lfp2_jn_mean = lfp2[i, :].mean(axis=0) lfp1_ms = lfp1[k, :] - lfp1_jn_mean lfp2_ms = lfp2[k, :] - lfp2_jn_mean pfreq,psd1_ms,ps_var_ms,phase_ms = power_spectrum_jn(lfp1_ms, sample_rate, window_length, increment) pfreq,psd2_ms,ps_var_ms,phase_ms = power_spectrum_jn(lfp2_ms, sample_rate, window_length, increment) if log: log_transform(psd1_ms) log_transform(psd2_ms) psd1_ms_all.append(psd1_ms) psd2_ms_all.append(psd2_ms) c12_ms = coherency(lfp1_ms, lfp2_ms, lags, window_fraction=window_fraction, noise_floor_db=noise_floor_db) c12_pertrial.append(c12_ms) psd1_ms_all = np.array(psd1_ms_all) psd2_ms_all = np.array(psd2_ms_all) psd1_ms = psd1_ms_all.mean(axis=0) psd2_ms = psd2_ms_all.mean(axis=0) if psd_stats is not None: psd_mean1,psd_std1 = psd_stats[e1] psd_mean2,psd_std2 = psd_stats[e2] psd1 -= psd_mean1 psd1 /= psd_std1 psd2 -= psd_mean2 psd2 /= psd_std2 psd1_ms -= psd_mean1 psd1_ms /= psd_std1 psd2_ms -= psd_mean2 psd2_ms /= psd_std2 c12_pertrial = np.array(c12_pertrial) c12_nonlocked = c12_pertrial.mean(axis=0) # compute the coherence per trial then take the average c12_totals = list() for k in range(ntrials): c12 = coherency(lfp1[k, :], lfp2[k, :], lags, window_fraction=window_fraction, noise_floor_db=noise_floor_db) c12_totals.append(c12) c12_totals = np.array(c12_totals) c12_total = c12_totals.mean(axis=0) return pfreq, psd1, psd2, psd1_ms, psd2_ms, c12, c12_nonlocked, c12_total
def compute_spectra_and_coherence_multi_electrode_single_trial(lfps, sample_rate, electrode_indices, electrode_order, window_length=0.060, increment=None, log=True, window_fraction=0.60, noise_floor_db=25, lags=np.arange(-20, 21, 1), psd_stats=None): """ :param lfps: an array of shape (ntrials, nelectrodes, nt) :return: """ if increment is None: increment = 2.0 / sample_rate nelectrodes,nt = lfps.shape freqs = get_freqs(sample_rate, window_length, increment) lags_ms = get_lags_ms(sample_rate, lags) spectra = np.zeros([nelectrodes, len(freqs)]) cross_mat = np.zeros([nelectrodes, nelectrodes, len(lags_ms)]) for k in range(nelectrodes): _e1 = electrode_indices[k] i1 = electrode_order.index(_e1) lfp1 = lfps[k, :] freqs,psd1,ps_var,phase = power_spectrum_jn(lfp1, sample_rate, window_length, increment) if log: log_transform(psd1) if psd_stats is not None: psd_mean,psd_std = psd_stats[_e1] """ plt.figure() plt.subplot(2, 2, 1) plt.plot(freqs, psd1, 'k-') plt.title('PSD (%d)' % _e1) plt.axis('tight') plt.subplot(2, 2, 3) plt.plot(freqs, psd_mean, 'g-') plt.title('Mean') plt.axis('tight') plt.subplot(2, 2, 4) plt.plot(freqs, psd_std, 'c-') plt.title('STD') plt.axis('tight') plt.subplot(2, 2, 2) psd1_z = deepcopy(psd1) psd1_z -= psd_mean psd1_z /= psd_std plt.plot(freqs, psd1_z, 'r-') plt.title('Zscored') plt.axis('tight') """ psd1 -= psd_mean psd1 /= psd_std spectra[i1, :] = psd1 for j in range(k): _e2 = electrode_indices[j] i2 = electrode_order.index(_e2) lfp2 = lfps[j, :] cf = coherency(lfp1, lfp2, lags, window_fraction=window_fraction, noise_floor_db=noise_floor_db) """ freqs,c12,c_var_amp,c_phase,c_phase_var,coherency,coherency_t = coherence_jn(lfp1, lfp2, sample_rate, window_length, increment, return_coherency=True) """ cross_mat[i1, i2] = cf cross_mat[i2, i1] = cf[::-1] return spectra, cross_mat