def calc_latency_by_stim(rast, stimparams): stim_psth, _ = Spikes.calc_psth_by_stim(rast, stimparams, bins = np.arange(0, 0.334, 0.001)) stim_psth_smoo = np.apply_along_axis(myconv, 2, stim_psth) stim_peak_times = np.apply_along_axis(np.argmax, 2, stim_psth_smoo) return stim_peak_times
def circ_psth(rast_, rr, npips, onset = 0.05, bins = 20, color = 'b', remove_first = False, ax = None): ''' Input: rast_ : subset of block raster corresponding to only the stimuli you want plotted rr : the repetition rate npips : number of pips presented at this rate onset : in seconds, onset time of first pip bins : number of bins to include remove_first : exclude the respose to the first pip ''' spktimes_ = Spikes.rast2spktimes(rast_) period = 1. / rr train_end = float(npips) / rr spktimes_chunk = spktimes_ - onset spktimes_chunk = spktimes_chunk[spktimes_chunk > 0] spktimes_chunk = spktimes_chunk[spktimes_chunk < train_end] if remove_first: spktimes_chunk = spktimes_chunk[spktimes_chunk > period] spktimes_pol = spktimes_chunk * 2*np.pi * rr # convert to radians spktimes_pol = np.mod(spktimes_pol, 2*np.pi) # force range 0-2pi nspks = spktimes_pol.size r, V, theta = circ_stat(spktimes_pol) ax, fig = misc.axis_check(ax, polar = True) if spktimes_pol.size > 0: ax.hist(spktimes_pol, bins = bins, color = color, histtype = 'stepfilled') ax.plot([0, theta], [0, V], 'r.-') ax.plot([0, 0], [0, V*np.cos(theta)], 'r.-') return r, V, theta
def calc_vR_dist_intertrain(spktimes_, spktrials_, trials, rr, nbins, npips = 6): ''' Calculates the reliability of firing to each PIP in the train Input: spktimes_ : spike times for the trials involved spktrials_ : spike trials for the above spike times stimparams : stimulus parameters for the trials ''' dist = [] # loop through each trial for t, trial in enumerate(trials): spktimes__ = spktimes_[spktrials_ == trial] # compare all pairwise combinations of pips for m in combinations(range(1, npips), 2): train_start_1 = 0.05 + (m[0] / rr) train_end_1 = 0.05 + ((m[0]+1) / rr) train_start_2 = 0.05 + (m[1] / rr) train_end_2 = 0.05 + ((m[1]+1) / rr) duration = npips / rr spktimes_1 = spktimes__[misc.isbetween(spktimes__, train_start_1, train_end_1)] - train_start_1 spktimes_2 = spktimes__[misc.isbetween(spktimes__, train_start_2, train_end_2)] - train_start_2 dist.append(Spikes.vR_dist(spktimes_1, spktimes_2, nbins) / duration) return np.mean(dist)
def aligned_psth_separate(psth, rr, npips, onset = 0.050, wind_offset = -0.020, ax = None, nshow = 6): ccycle = plt.rcParams['axes.color_cycle'] period = 1./rr # period in ms nbins_period = np.round(1000*period).astype(int) wind_start = onset+wind_offset show_ix = np.round(np.linspace(0, npips-1, nshow)).astype(int) aligned_psth = np.empty((nshow, nbins_period)) for i, ix in enumerate(show_ix): start_ix = np.round(1000*(wind_start+ix*period)).astype(int) stop_ix = start_ix+nbins_period aligned_psth[i, :] = psth[start_ix : stop_ix] if not ax is None: for i in xrange(nshow): color = ccycle[(nshow-(i+1))] lw = 7.25-(1.25*i) alpha = (2/7.)+(i/7.) ax.plot(Spikes.exp_smoo(aligned_psth[-(i+1), :]), color = color, lw = lw, alpha = alpha) ax.set_xlim((1000*(wind_start-0.010), 150)) return aligned_psth
def calc_fake_strf(rast, stimparams): ''' 2-d matrix no.freqs x no.time bins, values are spontaneous firing rate. basically each row is a psth for a particular frequency ''' stim_psth, _ = Spikes.calc_psth_by_stim(rast, stimparams) fake_strf = stim_psth.mean(1) return fake_strf
def plot_stim_psth(stim_psth, stim_params): fig = plt.figure(); nfreqs, nrrs, nbins = stim_psth.shape i = 0 rrs = stim_params[1] for r in xrange(nrrs): for f in xrange(nfreqs): i += 1 ax = fig.add_subplot(nrrs, nfreqs, i) ax.plot(Spikes.exp_smoo(stim_psth[f, r, :])) plot_tone_pips(rrs[r], rrs[r], 0.05, 0.025) plt.show();
def plot_fake_strf(rast, stimparams): fig = plt.figure(figsize = (15, 10)) ax1 = fig.add_axes([0.05, 0.2, 0.9, 0.75]) ax2 = fig.add_axes([0.05, 0.05, 0.9, 0.15]) fake_strf = calc_fake_strf(rast, stimparams) RF.plot_rf(fake_strf, ax = ax1, axes_on = False) psth = fake_strf.mean(0) psth_smoo = Spikes.hamming_smoo(psth, windlen = 5) ax2.plot(psth_smoo) ax2.set_xlim([0, rast.shape[1]]) plt.draw(); plt.show(); return fig
def calc_vR_dist_intertrial(spktimes, spktrials, trials, rr, nbins, npips = 6.): ntrials = trials.size dist = [] # compare all pairwise combinations of trials for m in combinations(range(ntrials), 2): spktimes_1 = spktimes[spktrials == trials[m[0]]] spktimes_2 = spktimes[spktrials == trials[m[1]]] # remove response to first pip train_start = 0.05 + 1./rr train_end = 0.05 + 6./rr spktimes_1 = spktimes_1[misc.isbetween(spktimes_1, train_start, train_end)] spktimes_2 = spktimes_2[misc.isbetween(spktimes_2, train_start, train_end)] duration = npips / rr dist.append(Spikes.vR_dist(spktimes_1, spktimes_2, nbins) / duration) return np.mean(dist)
def calc_vs(rast_, rr, npips, onset = 0.05, analysistype = 'mean', remove_first = False): ix_times = np.arange(rast_.shape[1]) / 1000. spktimes_ = Spikes.rast2spktimes(rast_, ix_times) spktimes_ = spktimes_ - onset train_end = npips / rr # end at last pip if remove_first: train_start = 1./rr else: train_start = 0. spktimes_chunk = spktimes_[np.logical_and(train_start<spktimes_, spktimes_<train_end)] v = np.exp(1j * 2*np.pi * rr * spktimes_chunk) # v = np.cos(2 * np.pi * rr * spktimes_chunk) + 1j * np.sin(2 * np.pi * rr * spktimes_chunk) if analysistype == 'mean': vs = np.abs(v.mean()) #/ duration if analysistype == 'sum': vs = np.abs(v.sum()) alpha = np.angle(v) p = rayleigh_test(np.angle(v)) return vs, p
# perform analysis if len(rr_path) > 0: rr_file = h5py.File(rr_path, 'r') rr_rast = rr_file['rast'].value rr_stimparams = rr_file['stimID'].value rr_file.close() # rr_rast = rr_rast[1:, :] # rr_stimparams = rr_stimparams[:-1, :] ufreqs = np.unique(rr_stimparams[:, 0]) urrs = np.unique(rr_stimparams[:, 1]) freq_played, freq_ix_played, _ = misc.closest(ufreqs, cf, log = True) rr_bins = np.arange(0, 6, 0.05) rr_psth_stim, usp = Spikes.calc_psth_by_stim(rr_rast, rr_stimparams, bins = rr_bins) cf_psth = rr_psth_stim[freq_ix_played, :, :] noise_psth = rr_psth_stim[0, :, :] fig = plt.figure() nrrs = cf_psth.shape[0] ax = [] for i in range(nrrs): ax.append(fig.add_subplot(nrrs, 1, i+1)) ax[-1].plot(rr_bins[:-1], cf_psth[i, :]) RR.plot_tone_pips(urrs[i], 6, 0.05, 0.025, ax = ax[-1], color = 'r') if i>0: ax[-1].set_xticklabels('') misc.sameyaxis(ax)
rast = frr['rast'].value stimparams = frr['stimID'].value frr.close() # if not np.isnan(spktimes[0]): cf = cfs[cfs[:, 0]==unitnum, 1][0] cf_hz = ix2freq[20:][int(cf)] freqs = stimparams[:, 0] rrs = stimparams[:, 1] ufreqs = np.unique(freqs) urrs = np.unique(rrs) nrrs = urrs.size # now we determine which of the frequencies we played is closest to this neuron's CF thisfreq, thisfreq_ix, thisfreq_err = misc.closest(ufreqs, cf_hz, log = True) if np.abs(thisfreq_err) > 0.2: print 'No close frequency found!' thisfreq = ufreqs[thisfreq_ix] # isolate the parts of the raster for this frequency and build a psth for each RR ix = RF.get_trials(stimparams, np.array([thisfreq, np.nan])) thisrast = rast[ix, :1050] thisstims = stimparams[ix, :] psths, ustims = Spikes.calc_psth_by_stim(thisrast, thisstims) rrtf = RR.calc_rrtf_all(thisrast, thisstims, thisfreq, urrs) db.resize(db.size+1) db[-1] = np.array((gen, exp, sess, unitnum, cf_hz, rrtf, urrs), dtype = dtype) np.savez(savepath, db)
def plot_rrtf(t, psth, rr, npips, onset = 0.05, duration = 0.025, ax = None): ax, fig = misc.axis_check(ax) ax.plot(t, Spikes.exp_smoo(psth)) plot_tone_pips(rr, npips, onset = onset, duration = duration, ax = ax, color = 'r')
def add_field(): savepath = '/Users/robert/Documents/Work/Bao/Fmr1_RR/Analysis/RRTFs.h5' fsave = h5py.File(savepath, 'a') sessnames = fsave.keys() for sessname in sessnames: fsess = fsave[sessname] rrblocks = fsess.keys() for rrblock in rrblocks: rrpath = os.path.join(basedir, 'Sessions', 'full_window', 'good', sessname, 'fileconversion', rrblock + '.h5') p = re.compile('RR') rfpath_ = p.sub('RF', rrblock) rfpath = os.path.join(basedir, 'Sessions', 'full_window', 'good', sessname, 'fileconversion', rfpath_+'.h5') p = re.compile('(\d+)') unitnum = np.int32(p.findall(rrblock)[0]) funit = fsess[rrblock] # d = funit.require_dataset('unit', (), 'i4') # d.write_direct(np.array([unitnum])) if verbose: print rrblock print rfpath # LOAD RF FILECONVERSION FILE frf = h5py.File(rfpath, 'r') cf_ix = np.int32(frf['cf'].value) frf.close() cf = ix2freq[20:][cf_ix] # LOAD RR FILECONVERSION FILE frr = h5py.File(rrpath, 'r') rast = frr['rast'].value stimparams = frr['stimID'].value frr.close() # CALCULATE FREQ PLAYED TO THIS UNIT'S CF freqs = np.unique(stimparams[:, 0]) rrs = np.unique(stimparams[:, 1]) freq, _, freq_err = misc.closest(freqs, cf, log = True) freq = np.round(freq, 0) assert freq_err<0.3 # COMPUTE NEW FIELD on, off = Spikes.calc_on_off(funit['ev_psth'].value) # vs, vs_p = RR.calc_vs_all(rast, stimparams, [0.], rrs) # rrtf = RR.calc_rrtf_all(rast, stimparams, freq, rrs) # ADD NEW FIELD d = funit.require_dataset('on_halfmax', (1,), float) d.write_direct(np.array([on])) d = funit.require_dataset('off_halfmax', (1,), float) d.write_direct(np.array([off])) # open the RR file, get rast and stimparams, then close it # frf = h5py.File(rfpath, 'r') # RF.add_rf_analysis(frf, funit) # frf.close() fsave.close()
def rr_make_contactsheets(): ''' loop through all the sessions and plot the rrtfs ''' fig = plt.figure(figsize = (30, 18)); txt_suptitle = fig.suptitle('') ax_cfrrtf = fig.add_axes((0.76, 0.76, 0.24, 0.23)); ax_cfvs = ax_cfrrtf.twinx(); ax_cfcircpsthall = fig.add_axes((0.62, (11/14.)-0.02, 0.1, (1/7.)+0.04), polar = True) ax_cfcircpsthall.set_xticklabels(''); ax_cfcircpsthall.set_yticklabels(''); ax_rf = fig.add_axes((0.67, 0.51, 0.33, 0.23)); ax_rfrast = fig.add_axes((0.67, 0.25, 0.33, 0.24)); ax_rfrast.set_xticklabels(''); ax_rfpsth = fig.add_axes((0.67, 0.01, 0.33, 0.24)); ax_cfrr = [fig.add_axes((0.03, 1-((i+1)/7.), 0.35, 1/7.)) for i in np.arange(nrrs)] ax_cfalignedpsth = [fig.add_axes((0.38, 1-((i+1)/7.), 0.17, 1/7.)) for i in np.arange(nrrs)] ax_cfcircpsth = [fig.add_axes((0.53, 1-((i+1)/7.), 0.1, 1/7.), polar = True) for i in np.arange(nrrs)] # ax_noiserr = [fig.add_subplot(nrrs, 3, i) for i in np.arange(1, 3*nrrs, 3)] for sessionpath in sessionpaths: session = os.path.split(sessionpath)[1] unitinfos = fileconversion.get_session_unitinfo(sessionpath, onlycomplete = ('RF', 'RR', 'VOC')) for unitkey in unitinfos.keys(): txt_suptitle.set_text('%s %s' % (session, unitkey)) unitinfo = unitinfos[unitkey] rf_ix = unitinfo['stimtype'].index('RF') f_rf = h5py.File(unitinfo['fpath'][rf_ix], 'r') rf_rast = f_rf['rast'].value rf_stimparams = f_rf['stimID'].value cf_ix = f_rf['cf'].value f_rf.close() cf = ix2freq[20:][int(cf_ix)] ''' calculate and plot RF, psth, and sorted raster''' rf = RF.calc_rf(rf_rast, rf_stimparams) rf_psth = Spikes.calc_psth(rf_rast) RF.plot_rf(rf, cf = cf_ix, axes_on = False, ax = ax_rf) # plot RF ax_rf.axvline(cf_ix, color = 'r', lw = 1.5) Spikes.plot_sorted_raster(rf_rast, rf_stimparams, ax = ax_rfrast) # plot raster ax_rfpsth.plot(t_rf, Spikes.exp_smoo(rf_psth, tau = 0.005)) # plot PSTH ''' calcualte and plot RRTFs for CF and noise stimuli ''' rr_ix = unitinfo['stimtype'].index('RR') f_rr = h5py.File(unitinfo['fpath'][rr_ix], 'r') rr_rast = f_rr['rast'].value rr_stimparams = f_rr['stimID'].value f_rr.close() # find the played CF rr_ufreqs = np.unique(rr_stimparams[:, 0]) urrs = np.unique(rr_stimparams[:, 1]) npips = (urrs*4).astype(int) rr_freq, rr_ufreq_ix, _ = misc.closest(rr_ufreqs, cf, log = True) ax_rf.axvline(RF.calc_freq2ix(rr_freq), color = 'g', lw = 1.5) # calculate the PSTHs for each repetition rate tmp = Spikes.calc_psth_by_stim(rr_rast, rr_stimparams) rr_cfpth = tmp[0][rr_ufreq_ix, :, :] # rrtf_noisepsth = tmp[0][0, :, :] # plot the aligned psths RR.aligned_psth_separate_all(rr_rast, rr_stimparams, rr_freq, npips, axs = ax_cfalignedpsth) [a.set_yticklabels('') for a in ax_cfalignedpsth] [a.set_xticklabels('') for a in ax_cfalignedpsth[:-1]] # plot circular psths r, V, theta = RR.circ_psth_all(rr_rast, rr_stimparams, rr_freq, npips, axs = ax_cfcircpsth) [a.set_yticklabels('') for a in ax_cfcircpsth] [a.set_xticklabels('') for a in ax_cfcircpsth] # plot all circular summed vector strengths ax_cfcircpsthall.plot(theta, V, '.-') [ax_cfcircpsthall.plot([0, th], [0, v], color = 'b', alpha = 1-(i/10.)) for i, (th, v) in enumerate(zip(theta, V))] # plot RRTF rrtf = RR.calc_rrtf_all(rr_rast, rr_stimparams, rr_freq, urrs, npips) ax_cfrrtf.plot(rrtf, '.-', ms = 10) ax_cfvs.plot(V*np.cos(theta), 'g.-', ms = 10) for tick in ax_cfvs.yaxis.get_major_ticks(): tick.set_pad(-5) tick.label2.set_horizontalalignment('right') # plot repetition rate PSTHs for i in xrange(nrrs): # RR.plot_rrtf(t_rrtf, rrtf_noisepsth[i, :], urrs[i], int(4*urrs[i]), onset = 0.05, duration = 0.025, ax = ax_noiserr[i]) RR.plot_rrtf(t_rrtf, rr_cfpth[i, :], urrs[i], int(4*urrs[i]), onset = 0.05, duration = 0.025, ax = ax_cfrr[i]) # ax_noiserr[0].set_title('Noise RRTFs') ax_cfrr[0].set_title('CF RRTFs (%.0f kHz)' % (cf/1000)) # [a.set_xlim(0, 4.5) for a in ax_noiserr] [a.set_xlim(0, 4.5) for a in ax_cfrr] misc.sameyaxis(ax_cfrr+ax_cfalignedpsth) figsavepath = os.path.join(studydir, 'Sheets', 'RRTFs', '%s_%s_RRTF.png' % (session, unitkey)) print figsavepath fig.savefig(figsavepath) [a.cla() for a in fig.get_axes()] # clear all axes
def unit(u_, Data0, cc, blockID): # number of time bins to include in the LFP array nlfpsamp = 0 for tt, trial in enumerate(Data0['trial'][0][0][0]): thislfpsamp = trial['LFP'].shape[1] if thislfpsamp>nlfpsamp: nlfpsamp = thislfpsamp ntrials = Data0['trial'][0][0][0].size # find number of trials nstimID = Data0['trial'][0][0][0][0]['Epoch_Value'][0].size # initialze LFP, spike times, spike trials, spike waveform lfp = np.ndarray((0, nlfpsamp), dtype = 'float32') spktimes = np.ndarray(0) spktrials = np.ndarray(0) spkwaveform = np.ndarray((0, 22)) # initialize frequency and attenuation IDs stimID = np.ndarray((0, nstimID), dtype = 'float32') ttt = 0 # valid trial counter for tt in range(ntrials): trial = Data0['trial'][0][0][0][tt] thisstimID = np.float32(trial['Epoch_Value'][0]) # if not ((blockID.startswith('b')) and (thisstimID[0] < 2)): # get the LFP for this trial and pad it with nans so it can fit in a matrix (since # some of the trials have +/-1 data point for LFP) lfpchannel = trial['LFP'][cc] lfpchannel = np.concatenate((lfpchannel, np.zeros(nlfpsamp - len(lfpchannel)) * np.nan)) lfp = np.vstack((lfp, lfpchannel)) spktime = trial['CH'][0][cc]['latency'] if np.prod(spktime.shape) > 0: spktimes = np.append(spktimes, spktime) spktrials = np.append(spktrials, np.ones(spktime.size) * ttt) spkwaveform = np.concatenate((spkwaveform, trial['CH'][0][cc]['spkwaveform'].T), 0) # add to Epoch_Value stimID = np.vstack((stimID, thisstimID)) ttt += 1 # increment valid trial counter # end if valid ID # end trial loop if spktimes.size == 0: # if no spikes print 'No spikes detected for this unit.' spktimes = np.array([np.nan]) spktrials = np.array([np.nan]) spkwaveform = np.array([np.nan]) rast = np.array([np.nan]) else: # filter out unwanted trials remID = np.array([np.nan, np.nan]) if blockID.startswith('b'): remID = np.array([1., 70.]) elif blockID.startswith('r'): remID = np.array([0., 0.]) spktimes, spktrials, spkwaveform, lfp, stimID = \ remove_trials(spktimes, spktrials, spkwaveform, lfp, stimID, remID) # create raster ntrials = stimID.shape[0] nbins = np.ceil(1000 * spktimes.max())+1 rast = Spikes.calc_rast(spktimes, spktrials, ntrials, nbins) # save out to file u_.create_dataset('chan', data = cc) u_.create_dataset('blockID', data = blockID) # add stimulus ID datasets to this stimset on this unit u_.create_dataset('stimID', data = stimID) u_.create_dataset('lfp', data = lfp, compression = 'gzip') u_.create_dataset('spktimes', data = spktimes, compression = 'gzip') u_.create_dataset('spktrials', data = spktrials, compression = 'gzip') u_.create_dataset('spkwaveform', data = spkwaveform, compression = 'gzip') u_.create_dataset('rast', data = rast, compression = 'gzip') if blockID.startswith('b'): rf = RF.calc_rf(rast, stimID) u_.create_dataset('rf', data = rf, compression = 'gzip')
def add_rf_analysis(frf, funit, stimparams): rast = frf['rast'].value # stimparams = frf['stimID'].value # calculate, smooth, threshold, and cluster RF rf = calc_rf(rast, stimparams, normed = True, smooth = False) rf[:, :5] = 0 nan_ix = np.isnan(rf) if nan_ix.sum() > 0: print 'NaNs found in rf! Converting NaNs to zeros...' print nan_ix.sum() rf[np.isnan(rf)] = 0 rf_smoo = gaussian_filter(rf, 0.5) rf_thresh = rf_smoo.copy() rf_mask = rf_thresh<0.25*rf_thresh.max() rf_thresh[rf_mask] = 0 (rf_clust, max_clust_size) = findmaxcluster(rf_thresh) if max_clust_size < 10: print 'F*****G SMALL RF dude' # baseline_mean : mean firing rate 0-50ms for all trials baseline_psth = 1000 * rast[:, :50].mean(0) baseline_mean = baseline_psth.mean() baseline_std = baseline_psth.std() fr_thresh = baseline_mean + 2*baseline_std # evoked and spontaneous psths ev_psth = calc_evoked_psth(rast, stimparams, rf_clust>0) ev_psth_smoo = Spikes.hamming_smoo(ev_psth, windlen = 5) spont_psth = calc_evoked_psth(rast, stimparams, rf_clust==0) # psth properties # peak firing rate resp_max = ev_psth_smoo.max() peak_time_ix = ev_psth_smoo.argmax() # first millisecond after the final sub-threshold millisecond resp_on_ix_ = (ev_psth_smoo[57:peak_time_ix]<fr_thresh).nonzero()[0] if not resp_on_ix_.any(): resp_on_ix = peak_time_ix else: resp_on_ix = resp_on_ix_.max() + 58 resp_off_ix = np.empty(3) resp_off_ix[0] = (ev_psth_smoo[peak_time_ix:]<resp_max/2).nonzero()[0].min() + peak_time_ix resp_off_ix[1] = (ev_psth_smoo[peak_time_ix:]<resp_max/4).nonzero()[0].min() + peak_time_ix resp_off_ix[2] = (ev_psth_smoo[peak_time_ix:]<fr_thresh).nonzero()[0].min() + peak_time_ix peak_time = peak_time_ix / 1000. resp_on = resp_on_ix / 1000. resp_off = resp_off_ix / 1000. # calculate a decay constant from the peak to the post-peak sub-threshold y = np.log(ev_psth[peak_time_ix:resp_off_ix[2]]) tmp = linregress(np.arange(y.size), y) decay_const = tmp[0] # firing rate statistics on the rf rf_spont_mean = rf[rf_clust==0].mean() rf_resp_max = rf[rf_clust>0].max() - rf_spont_mean rf_resp_median = np.median(rf[rf_clust>0]) - rf_spont_mean rf_resp_mean = rf[rf_clust>0].mean() - rf_spont_mean rf_size = (rf_clust>0).sum() # automated CF measures (center-of-mass and auto) # automated BW measures cf_com = calc_rf_com(rf_clust) cf_auto = calc_cf(rf_clust) (bw, bw_lr, thresh) = calc_bw_thresh(rf_clust) # # PSTH for freq/attens in RF # fig = plt.figure() # ax = fig.add_subplot(111) # ax.plot(ev_psth_smoo, 'b.-') # ax.axhline(baseline_mean+3*baseline_std, color = 'r', ls = '--') # ax.axvline(resp_on_ix, color = 'r', ls = '--') # ax.axvline(resp_off_ix[0], color = 'r', ls = '--') # ax.axvline(resp_off_ix[1], color = 'r', ls = '--') # ax.axvline(resp_off_ix[2], color = 'r', ls = '--') rf_shape = rf.shape d = funit.require_dataset('rf', rf_shape, float) d.write_direct(rf) d = funit.require_dataset('rf_clust', rf_shape, float) d.write_direct(rf_clust) d = funit.require_dataset('rf_spont_mean', (), float) d.write_direct(np.array([rf_spont_mean])) d = funit.require_dataset('rf_resp_median', (), float) d.write_direct(np.array([rf_resp_median])) d = funit.require_dataset('rf_resp_mean', (), float) d.write_direct(np.array([rf_resp_mean])) d = funit.require_dataset('rf_resp_max', (), float) d.write_direct(np.array([rf_resp_max])) d = funit.require_dataset('resp_max', (), float) d.write_direct(np.array([resp_max])) d = funit.require_dataset('peak_time', (), float) d.write_direct(np.array([peak_time])) d = funit.require_dataset('resp_on', (), float) d.write_direct(np.array([resp_on])) d = funit.require_dataset('resp_off', (3,), float) d.write_direct(np.array([resp_off])) d = funit.require_dataset('decay_const', (), float) d.write_direct(np.array([decay_const])) d = funit.require_dataset('rf_size', (), int) d.write_direct(np.array([rf_size])) d = funit.require_dataset('baseline_mean', (), float) d.write_direct(np.array([baseline_mean])) d = funit.require_dataset('cf_auto', (), float) d.write_direct(np.array([cf_auto])) d = funit.require_dataset('cf_com', (), float) d.write_direct(np.array([cf_com])) d = funit.require_dataset('bw', (8,), float) d.write_direct(bw) d = funit.require_dataset('bw_lr', (8,2), float) d.write_direct(bw_lr) d = funit.require_dataset('thresh', (), int) d.write_direct(np.array([thresh])) d = funit.require_dataset('ev_psth', (333,), float) d.write_direct(ev_psth[:333])
def characterize(sesss = sesss, experiment = 'Fmr1_RR', pplot = True, verbose = False): if type(sesss) == str: sesss = [sesss] # set up figure figsize = (12, 12) fig = plt.figure(figsize = figsize) # loop through sesss for sess in sesss: DB = np.empty(0, dtype = dtype) print '%s\n%s\n\n' % (sess, '-'*50) # build the output directory path savedir = os.path.join(basedir, experiment, 'Sessions', sess, 'analysis') if not os.path.exists(savedir): os.mkdir(savedir) # WT or KO / CTL or EXP gen, exp, date = sess.split('_') # find the RF blocks pens = glob.glob(os.path.join(basedir, experiment, 'Sessions', sess, 'fileconversion', 'RF*.h5')) # load the cfs for this sess cfs = np.loadtxt(os.path.join(basedir, experiment, 'Sessions', sess, 'cfs.txt'), ndmin = 1) # loop through blocks in this sess for pen in pens: absol, relat = os.path.split(pen) blockname = os.path.splitext(relat)[0] # get unit number from filename unitnum = np.int32(p.findall(relat))[0] # unit number ix = cfs[:, 0] == unitnum if ix.sum() > 0: cf_man = cfs[ix, 1][0] if verbose: print pen # load the RF block f = h5py.File(pen, 'r') spktimes = f['spktimes'].value # if not np.isnan(spktimes[0]): '''--------RF--------''' # load the RF block to get the RF rf = f['rf'].value; rast = f['rast'].value; spktimes = f['spktimes'].value; stimparams = f['stimID'].value; spktrials = f['spktrials'].value; coord = f['coord'].value; ntrials = f['rast'].shape[0]; f.close() # calculate the psth (spk/s*trial, normalized by number of trials psth = Spikes.calc_psth(rast, normed = True) # spk/s # baseline firing rate base_mean = psth[:stim_on].mean() # spk/s # response onset/offset psth_smoo = Spikes.exp_smoo(psth, tau = 0.003) resp_on, resp_off = Spikes.calc_on_off(psth_smoo, stim_on = stim_on) # rewindowed RF rf_rewin = RF.calc_rf(rast, stimparams, resp_on = resp_on + stim_on - 3, resp_off = resp_off + stim_on + 3, normed = True) # thresholded RF rf_thresh = rf_rewin.copy() rf_threshold = np.percentile(rf_thresh, 66)# upper quartile rf_peak = rf_rewin.max() rf_thresh[rf_thresh < rf_threshold] = 0 # find maximum RF cluster (rf_clust, clust_sizes) = RF.findmaxcluster(rf_thresh, cf = cf_man, include_diagonal = False) # if clust_sizes.max() < 10: # if it's a tiny RF, set it to nans # rf_clust = np.empty(rf_clust.shape) * np.nan rf_mask = rf_clust > 0 # find evoked psth ev_psth = RF.calc_evoked_psth(rast, stimparams, rf_mask) ev_psth_smoo = Spikes.exp_smoo(ev_psth, tau = 0.003) ev_resp_on, ev_resp_off = Spikes.calc_on_off(ev_psth_smoo, stim_on = stim_on) ev_mean = ev_psth[ev_resp_on : ev_resp_off].mean() # bandwidth and threshold bw, bw_lr, _, thresh = RF.calc_bw_cf_thresh(rf_mask) # center of mass com = RF.calc_rf_com(rf_clust) tip_top = np.max([thresh-2, 0]) tip_bottom = thresh com_tip = RF.calc_rf_com(rf_clust[tip_top:tip_bottom, :]) '''PLOT''' if pplot: rf1_ax = fig.add_subplot(221) rf2_ax = fig.add_subplot(222) psth1_ax = fig.add_subplot(223) psth2_ax = fig.add_subplot(224) RF.plot_RF(rf, bw_lr = bw_lr, thresh = thresh, cf = cf_man, ax = rf1_ax) RF.plot_RF(rf_clust, bw_lr = bw_lr, thresh = thresh, cf = cf_man, ax = rf2_ax) rf2_ax.axvline(com, color = 'g', ls = '--') rf2_ax.axvline(com_tip, color = 'b', ls = '--') psth1_ax.plot(psth_smoo) psth2_ax.plot(ev_psth_smoo) psth1_ax.axvline(resp_on+stim_on, color = 'r', ls = '--') psth1_ax.axvline(resp_off+stim_on, color = 'r', ls = '--') figpath = os.path.join(savedir, blockname + '.png') fig.savefig(figpath); fig.clf() '''PLOT''' DB.resize(DB.size + 1) DB[-1] = np.array((gen, exp, sess, unitnum, \ psth[:333], ev_psth[:333], \ rf, rf_clust, \ cf_man, com, com_tip, \ bw, bw_lr, thresh, coord, \ resp_on, resp_off, ev_resp_on, ev_resp_off, \ base_mean, ev_mean), dtype = dtype) # end unit loop np.savez(os.path.join(basedir, experiment, 'Sessions', sess, sess + '_RF.npz'), DB = DB) if verbose: print '\n'*4