def collect_data(self, which='scan'): if which == 'scan': ripple_rat = scan_ripple_rat noripple_rat = scan_noripple_rat elif which == 'pause': ripple_rat = pause_ripple_rat noripple_rat = pause_noripple_rat else: raise ValueError, 'bad event type: %s' % which for rat, ax in self.get_plot(rat_list): cdf = np.cumsum(distro(ripple_rat[rat])) cdf_null = np.cumsum(distro(noripple_rat[rat])) ax.plot(centers, cdf, 'b-', centers, cdf_null, 'r-') ax.set(xlim=(centers[0], centers[-1]), ylim=(0, 1)) ax.tick_params(top=False, right=False) quicktitle(ax, 'rat%03d' % rat) if self.firstonpage: ax.set_ylabel('CDF') else: ax.set_yticklabels([]) if self.lastonpage: ax.legend(['w/ ripples', 'no ripples'], loc=2, bbox_to_anchor=(1.1, 1)) ax.set_xlabel('Peak Z(P(Theta))') else: ax.set_xticklabels([])
def collect_data(self, sessions): """Display forward-running speed vs. tracking speed distributions for the sessions provided as a list of rds triplets. """ for rds, ax in self.get_plot(sessions): data = SessionData(rds=rds, load_clusters=False) # Trajectory data ts = data.trajectory.ts omega = data.trajectory.forward_velocity # Data initialization lower = np.empty((data.N_laps, ), 'd') upper = np.empty((data.N_laps, ), 'd') median = np.empty((data.N_laps, ), 'd') mean = np.empty((data.N_laps, ), 'd') # Compute the distribution stats for lap in xrange(data.N_laps): _t, lap_speed = time_slice_sample(ts, omega, start=data.laps[lap], end=data.laps[lap + 1]) lower[lap], upper[lap] = IQR(lap_speed, factor=0) median[lap] = np.median(lap_speed) mean[lap] = np.mean(lap_speed) # Plot the stats laps = np.arange(1, data.N_laps + 1) p = Polygon(np.c_[np.r_[laps, laps[::-1]], np.r_[lower, upper[::-1]]], alpha=0.5, ec='none', fc='c', zorder=-1) ax.add_artist(p) ax.plot(laps, median, 'k-', lw=2) ax.plot(laps, mean, 'k--', lw=1) ax.axhline(0, ls='-', c='k') ax.set_xticks(laps) ax.set_xlim(1, data.N_laps) ax.set_ylim(-50, 100) ax.set_xticklabels([]) quicktitle(ax, '%d-%02d-m%d' % rds, size='x-small') if self.firstonpage: ax.set_ylabel(u'Forward Speed (\u00b0CW/s)') else: ax.set_yticklabels([]) if self.lastonpage: ax.set_xlabel('Laps') self.out('All done!')
def plot_rat_distros(ax, data, label, xlim=plim): ax.imshow(data, interpolation='nearest', origin='upper', aspect='auto', extent=[xlim[0], xlim[1], 0, N]) ax.set(yticks=(np.arange(N) + 0.5), yticklabels=map(str, res.rat_number[::-1])) ax.tick_params(axis='y', right=False, labelsize='xx-small', direction='out', length=3) quicktitle(ax, '%s' % label)
def _plot_results(self, rds, tc, scan, S, P_xk, P_xk_scan, P_xk_diff, W_x): f = plt.figure() density_kwds = dict(cmask='c', cmap='gray') #, norm=False, cmin=0, cmax=1) diff_kwds = dict(cmask='w', cmap='RdBu', norm=False, cmin=-0.5, cmax=0.5) f.suptitle('rat%03d-%02d-m%d %s scan%02d\nS = %.5f' % (rds + (tc, scan['number'], S))) ax = densitymap(P_xk, (0, 360), (0, self.k_edges[-1] + 1), ax=plt.subplot(221), **density_kwds) quicktitle(ax, 'P_xk') ax = densitymap(P_xk_scan, (0, 360), (0, self.k_edges[-1] + 1), ax=plt.subplot(222), **density_kwds) quicktitle(ax, 'P_xk_scan') ax = densitymap(P_xk_diff, (0, 360), (0, self.k_edges[-1] + 1), ax=plt.subplot(223), **diff_kwds) quicktitle(ax, 'P_xk_diff') ax = f.add_subplot(224) centers = (lambda e: (e[:-1] + e[1:]) / 2)(self.H_bins[0]) ax.plot(centers, W_x.flatten(), 'b-o', mew=0, ms=6, mfc='b', lw=2) ax.set_xlim(0, 360) quicktitle(ax, 'W_x')
def plot_rat_spectra(ax, data, label): ax.imshow(data, interpolation='nearest', origin='upper', aspect='auto', extent=[F[0], F[-1] + (F[-1] - F[-2]), 0, rats.size]) ax.set(yticks=(np.arange(rats.size) + 0.5), yticklabels=map(str, rats[::-1])) ax.set_xlim(flim) ax.tick_params(axis='y', right=False, direction='out', labelsize='xx-small', length=3) quicktitle(ax, '%s spectra' % label, size='x-small')
def _plot_rat_average_correlations(): ax = f.add_subplot(321) ax.plot(lags, C_rat.T, 'k-', lw=1.5, alpha=0.5) ax.axhline(y=1.0, **line_fmt) ax.set(xlim=tlim, ylim=ylim, ylabel='Correlation') ax.tick_params(top=False, right=False) quicktitle(ax, 'per rat') ax = f.add_subplot(322) C_rat_star = medfilt(C_rat, kernel_size=[1, smoothing]) mu = C_rat_star.mean(axis=0) err = C_rat_star.std(axis=0) / np.sqrt(C_rat_star.shape[0]) ax.axhline(y=1.0, **line_fmt) ax.plot(lags, mu, 'k-', lw=2) shaded_error(lags, mu, err, alpha=0.4, ec='none', fc='slateblue') ax.tick_params(top=False, right=False) ax.set(xlim=tlim, ylim=ylim) quicktitle(ax, r'mean $\pm$ s.e.m.')
def plot_rat_distros(ax, data, label): rats = res.rat_number rat_distro = np.empty((rats.size, F.size), 'd') norm = lambda P: P / P.max() for i, rat in enumerate(rats): rat_distro[i] = norm(data[res.rat_number == rat].mean(axis=0)) ax.imshow(rat_distro, interpolation='nearest', origin='upper', aspect='auto', extent=[F[0], F[-1] + (F[-1] - F[-2]), 0, rats.size]) ax.set(yticks=(np.arange(N) + 0.5), yticklabels=map(str, rats[::-1])) ax.tick_params(axis='y', right=False, labelsize='xx-small', direction='out', length=3) quicktitle(ax, '%s p[%s]' % (label, res.distro))
def create_xcorr_figure(signal): f = self.new_figure('%s_xcorrs' % signal, 'Scan x %s Cross-Correlations' % signal, figsize=figsize) for i, point in enumerate(self.results['scan_points']): rat_averages = data_file.getNode( xcorr_data_group, self._get_xcorr_array_name(signal, point)).read() N_rats, N_t = rat_averages.shape mu = rat_averages.mean(axis=0) sem = rat_averages.std(axis=0) / np.sqrt(N_rats) t = np.linspace(-lag, lag, N_t) ax = f.add_subplot(nrows, ncols, i + 1) ax.plot(t, mu, '-', c=fc, zorder=1) shaded_error(t, mu, sem, ax=ax, fc=fc, alpha=0.3, zorder=0) ax.axhline(0.0, c='k', ls='-', zorder=-2) ax.set_xlim(-lag, lag) ax.set_ylim(ylim[signal]) ax.tick_params(top=False, right=False, left=False) ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) quicktitle(ax, point.title())
def plot(self, cmap='jet'): assert self.I_skaggs1 is not None, 'please run compare_tables_in_files first' f = plt.figure(figsize=(10, 10)) axlist = AxesList() axlist.make_grid((4, 4)) f.suptitle('1) %s\n2) %s' % (self.kfilepath1, self.kfilepath2)) I = (self.I_skaggs1, self.I_skaggs2, self.I_olypher1, self.I_olypher2) name = ('sk1', 'sk2', 'oly1', 'oly2') I_range = range(len(I)) D = reduce(op.mul, map(np.isfinite, I)) for i, j in outer_pairs(I_range, I_range): cmp_name = '%s - %s' % (name[j], name[i]) sys.stdout.write('Plotting %s...\n' % cmp_name) sys.stdout.flush() ax = axlist[j + len(I) * i] heatmap(I[j][D], I[i][D], bins=128, ax=ax, cmap=cmap) quicktitle(ax, cmp_name, size='x-small') return f
def process_data(self, disp_max_k=19.2, max_k=25, drange=(0, 1, 11), rrange=(0, 15, 4), srange=(0, 120, 3), which='spikes'): """Multi-variate likelihood estimation of scan spike counts up to max_k, for ranges specified in normalized field-traversal distance (drange), firing rate (rrange), and size (srange). Ranges specified as inclusive bin-edge tuples (low, high, N). Select spike counts from outbound, inbound, or whole-scan by setting *which* to 'out_spikes', 'in_spikes', or 'spikes'. """ assert which in ('out_spikes', 'in_spikes', 'spikes'), \ "invalid scan phase spikes argument" self.out.outfd = file(os.path.join(self.datadir, 'likelihood.log'), 'w') self.out.timestamp = False # Load results data data_file = self.get_data_file() scan_data = data_file.root.field_scans # 'field_distance' # 'traversal_distance' # 'spikes' # 'field_size' # 'traversal_size' # 'strength' # Compute empirical likelihood functions of scan spikes based on field # spiking data dbins = np.linspace(*drange) rbins = np.r_[np.linspace(*rrange), np.inf] # no upper bound on final bins sbins = np.r_[np.linspace(*srange), np.inf] # no upper bound on final bins edges = (dbins, rbins, sbins) N = (dbins.size - 1, rbins.size - 1, sbins.size - 1, max_k + 1) H = np.zeros(N, 'd') P = np.empty(N[:-1], object) def make_query(name, low, high): q = '(%s>=%f)' % (name, low) if np.isfinite(high): q += '&(%s<%f)' % (name, high) return q # Compute the multi-variate conditional probability distributions for d in xrange(N[0]): dquery = make_query('traversal_distance', dbins[d], dbins[d + 1]) self.out('%d: %s' % (d, dquery)) for r in xrange(N[1]): rquery = make_query('strength', rbins[r], rbins[r + 1]) self.out('%d: %s' % (r, rquery)) for s in xrange(N[2]): squery = make_query('traversal_size', sbins[s], sbins[s + 1]) self.out('%d: %s' % (s, squery)) query = '&'.join([dquery, rquery, squery]) spikes = [rec[which] for rec in scan_data.where(query)] k, histo = integer_hist(spikes, int_range=(0, max_k), open_range=True, relative=False) if not np.any(histo): histo[0] = 1 # set 0-mode for unsampled bins H[d, r, s] = histo P[d, r, s] = SampleDistribution(histo, k) self.out('-' * 3) self.out('-' * 3) self.out.outfd.close() self.close_data_file() # Save the likelihood data self.out('Saving edges...') edges_fd = file(os.path.join(self.datadir, 'edges.pickle'), 'w') cPickle.dump(edges, edges_fd) edges_fd.close() self.out('Saving histograms...') H_fd = file(os.path.join(self.datadir, 'H.pickle'), 'w') cPickle.dump(H, H_fd) H_fd.close() self.out('Saving distributions...') P_fd = file(os.path.join(self.datadir, 'P.pickle'), 'w') cPickle.dump(P, P_fd) P_fd.close() # Create distance x firing-rate figure kvals = np.arange(max_k + 1) self.figure = {} self.out('Bringing up distance x rate figure...') self.figure['bias_distance_rate'] = f = plt.figure(figsize=(10, 8)) axlist = AxesList() axlist.make_grid(N[2]) f.suptitle( 'Distribution Means for Scan-%s: Traversal Distance x Firing Rate' % which.replace('_', '-').title()) for s, ax in enumerate(axlist): M = np.empty((N[0], N[1]), 'd') for d in xrange(N[0]): for r in xrange(N[1]): M[d, r] = (kvals * (H[d, r, s] / H[d, r, s].sum())).sum() lrbt = [dbins[0], dbins[-1], rbins[0], 2 * rbins[-2] - rbins[-3]] ax.imshow(M.T, aspect='auto', origin='lower', vmin=(0, disp_max_k), interpolation='nearest', extent=lrbt) ax.set(xlim=lrbt[:2], ylim=lrbt[2:]) if s == 0: ax.set_ylabel('Traversal Rate') else: ax.set_yticklabels([]) if s == N[2] - 1: ax.set_xlabel('Traversal Distance') else: ax.set_xticklabels([]) textlabel(ax, '%.1f' % M.max()) quicktitle(ax, 'size > %d' % int(sbins[s])) # Create distance x size figure self.out('Bringing up distance x size figure...') self.figure['bias_distance_size'] = f = plt.figure(figsize=(10, 8)) axlist = AxesList() axlist.make_grid(N[1]) f.suptitle( 'Distribution Means for Scan-%s: Traversal Distance x Size' % which.replace('_', '-').title()) for r, ax in enumerate(axlist): M = np.empty((N[0], N[2]), 'd') for d in xrange(N[0]): for s in xrange(N[2]): M[d, s] = (kvals * (H[d, r, s] / H[d, r, s].sum())).sum() lrbt = [dbins[0], dbins[-1], sbins[0], 2 * sbins[-2] - sbins[-3]] ax.imshow(M.T, aspect='auto', origin='lower', vmin=(0, disp_max_k), interpolation='nearest', extent=lrbt) ax.set(xlim=lrbt[:2], ylim=lrbt[2:]) if r == 0: ax.set_ylabel('Traversal Size') else: ax.set_yticklabels([]) if r == N[1] - 1: ax.set_xlabel('Traversal Distance') else: ax.set_xticklabels([]) textlabel(ax, '%.1f' % M.max()) quicktitle(ax, 'rate > %.1f' % rbins[r]) # Create distance x size figure self.out('Bringing up rate x size figure...') self.figure['bias_rate_size'] = f = plt.figure(figsize=(10, 8)) axlist = AxesList() axlist.make_grid(N[0]) f.suptitle( 'Distribution Means for Scan-%s: Traversal Firing-rate x Size' % which.replace('_', '-').title()) for d, ax in enumerate(axlist): M = np.empty((N[1], N[2]), 'd') for r in xrange(N[1]): for s in xrange(N[2]): M[r, s] = (kvals * (H[d, r, s] / H[d, r, s].sum())).sum() lrbt = [ rbins[0], 2 * rbins[-2] - rbins[-3], sbins[0], 2 * sbins[-2] - sbins[-3] ] ax.imshow(M.T, aspect='auto', origin='lower', vmin=(0, disp_max_k), interpolation='nearest', extent=lrbt) ax.set(xlim=lrbt[:2], ylim=lrbt[2:]) if d == 0: ax.set_ylabel('Traversal Size') else: ax.set_yticklabels([]) if d == N[0] - 1: ax.set_xlabel('Traversal Firing-Rate') else: ax.set_xticklabels([]) textlabel(ax, '%.1f' % M.max()) quicktitle(ax, 'distance > %.2f' % dbins[d]) # View flattened distributions CDF_flat = np.empty((H.shape[0] * H.shape[1] * H.shape[2], H.shape[3]), 'd') PDF_flat = np.empty((H.shape[0] * H.shape[1] * H.shape[2], H.shape[3]), 'd') i = 0 for d in xrange(N[0]): for r in xrange(N[1]): for s in xrange(N[2]): CDF_flat[i] = np.cumsum(H[d, r, s]) / np.sum(H[d, r, s]) PDF_flat[i] = H[d, r, s] / np.max(H[d, r, s]) i += 1 self.figure['all_cdfs'] = f = plt.figure(figsize=(10, 8)) f.suptitle('Empirical CDFs for All %s Distributions' % which.replace('_', '-').title()) ax = f.add_subplot(111) ax.imshow(CDF_flat[:, :-1], origin='upper', interpolation='nearest', aspect='auto', vmin=(0, 1)) ax.set_xlabel('Spike Count') ax.set_ylabel('(distance, rate, size)') quicktitle(ax, 'Scan-Spike Bias ECDFs') self.figure['all_pdfs'] = f = plt.figure(figsize=(10, 8)) f.suptitle('Empirical PDFs for All %s Distributions' % which.replace('_', '-').title()) ax = f.add_subplot(111) ax.imshow(PDF_flat, origin='upper', interpolation='nearest', aspect='auto', vmin=(0, 1)) ax.set_xlabel('Spike Count') ax.set_ylabel('(distance, rate, size)') quicktitle(ax, 'Scan-Spike Bias EPDFs') self.out('All done!')
def process_data(self, use_max=False, zlim=(-3, 3), numbins=64, siglevel=0.05): """Compute scan-ripple event distributions use_max -- use the max z-power theta across event instead of average zlim -- z-power limits for distributions numbins -- number of histogram bins use to compute distributions """ self.out.outfd = file(os.path.join(self.datadir, 'figure.log'), 'w') # Load results data data_file = self.get_data_file() root = data_file.root # Overall and rat-specific scan/pause distributions contingent on ripples theta = use_max and 'theta_max' or 'theta_avg' pause_noripple = np.array( [rec[theta] for rec in root.pause_data.where('ripples==0')]) pause_ripple = np.array( [rec[theta] for rec in root.pause_data.where('ripples>0')]) scan_noripple = np.array( [rec[theta] for rec in root.scan_data.where('ripples==0')]) scan_ripple = np.array( [rec[theta] for rec in root.scan_data.where('ripples>0')]) rat_list = np.unique(root.scan_data.cols.rat[:]) pause_noripple_rat = {} pause_ripple_rat = {} scan_noripple_rat = {} scan_ripple_rat = {} for rat in rat_list: pause_noripple_rat[rat] = np.array([ rec[theta] for rec in root.pause_data.where('(ripples==0)&(rat==%d)' % rat) ]) pause_ripple_rat[rat] = np.array([ rec[theta] for rec in root.pause_data.where('(ripples>0)&(rat==%d)' % rat) ]) scan_noripple_rat[rat] = np.array([ rec[theta] for rec in root.scan_data.where('(ripples==0)&(rat==%d)' % rat) ]) scan_ripple_rat[rat] = np.array([ rec[theta] for rec in root.scan_data.where('(ripples>0)&(rat==%d)' % rat) ]) # Ripple distributions ripple_theta = root.ripple_data.cols.theta[:] ripple_running = np.array( [rec['theta'] for rec in root.ripple_data.where('running==True')]) ripple_pause = np.array( [rec['theta'] for rec in root.ripple_data.where('pause==True')]) ripple_scan = np.array( [rec['theta'] for rec in root.ripple_data.where('scan==True')]) ripple_theta_rat = {} ripple_running_rat = {} ripple_pause_rat = {} ripple_scan_rat = {} for rat in rat_list: ripple_theta_rat[rat] = np.array([ rec['theta'] for rec in root.ripple_data.where('rat==%d' % rat) ]) ripple_running_rat[rat] = np.array([ rec['theta'] for rec in root.ripple_data.where('(running==True)&(rat==%d)' % rat) ]) ripple_pause_rat[rat] = np.array([ rec['theta'] for rec in root.ripple_data.where('(pause==True)&(rat==%d)' % rat) ]) ripple_scan_rat[rat] = np.array([ rec['theta'] for rec in root.ripple_data.where('(scan==True)&(rat==%d)' % rat) ]) # Output statistics stat_msgs = [] stat_msgs += [ 'Pauses with ripples: %d / %d' % (len(pause_ripple), root.pause_data.nrows) ] stat_msgs += [ 'Scans with ripples: %d / %d' % (len(scan_ripple), root.scan_data.nrows) ] stat_msgs += ['--'] stat_msgs += [ 'Pause, ripple vs. no ripple: T = %.4f, p < %.5f' % t_welch(pause_ripple, pause_noripple) ] stat_msgs += [ 'Scan, ripple vs. no ripple: T = %.4f, p < %.5f' % t_welch(scan_ripple, scan_noripple) ] stat_msgs += ['--'] stat_msgs += [ 'Ripples during running: %d / %d' % (len(ripple_running), root.ripple_data.nrows) ] stat_msgs += [ 'Ripples during pause: %d / %d' % (len(ripple_pause), root.ripple_data.nrows) ] stat_msgs += [ 'Ripples during scan: %d / %d' % (len(ripple_scan), root.ripple_data.nrows) ] stat_msgs += ['--'] stat_msgs += [ 'Ripple, overall: %0.3f +/- %0.3f; T = %.4f, p < %.5f' % ((ripple_theta.mean(), ripple_theta.std()) + t_one_tailed(ripple_theta, 0)) ] stat_msgs += [ 'Ripple, running: %0.3f +/- %0.3f; T = %.4f, p < %.5f' % ((np.mean(ripple_running), np.std(ripple_running)) + t_one_tailed(ripple_running, 0)) ] stat_msgs += [ 'Ripple, pause: %0.3f +/- %0.3f; T = %.4f, p < %.5f' % ((np.mean(ripple_pause), np.std(ripple_pause)) + t_one_tailed(ripple_pause, 0)) ] stat_msgs += [ 'Ripple, scan: %0.3f +/- %0.3f; T = %.4f, p < %.5f' % ((np.mean(ripple_scan), np.std(ripple_scan)) + t_one_tailed(ripple_scan, 0)) ] stat_msgs += ['--'] stat_msgs += [ 'Ripple, scan vs. running: T = %.4f, p < %.5f' % t_welch(ripple_scan, ripple_running) ] stat_msgs += [ 'Ripple, scan vs. pause: T = %.4f, p < %.5f' % t_welch(ripple_scan, ripple_pause) ] self.out('\n'.join(stat_msgs)) # Histogram / distro bins = np.linspace(zlim[0], zlim[1], numbins + 1) centers = (bins[:-1] + bins[1:]) / 2 def distro(values): H = np.histogram(values, bins=bins)[0] return H.astype('d') / H.sum() # Create the event|ripple figure self.figure = {} self.figure['ripple_effect'] = f = plt.figure(figsize=(6, 8)) f.suptitle('Event Distributions of Theta Power Conditioned on Ripples') # Pauses ax = f.add_subplot(211) ax.plot(centers, distro(pause_ripple), 'b-', centers, distro(pause_noripple), 'r-') ax.legend(['w/ ripples', 'no ripples']) ax.set_xlim(*zlim) quicktitle(ax, 'Pauses') # Scans ax = f.add_subplot(212) ax.plot(centers, distro(scan_ripple), 'b-', centers, distro(scan_noripple), 'r-') ax.legend(['w/ ripples', 'no ripples']) ax.set_xlim(*zlim) quicktitle(ax, 'Scans') # Create the ripple|behavior figure self.figure['behavior'] = f = plt.figure(figsize=(9, 4)) f.suptitle( 'Ripple Distributions of Theta Power at Peak Across Behaviors') ax = f.add_subplot(111) ax.plot(centers, distro(ripple_theta), 'k--', label='overall') ax.plot(centers, distro(ripple_running), 'k-', label='running') ax.plot(centers, distro(ripple_pause), 'r-', label='pauses') ax.plot(centers, distro(ripple_scan), 'b-', label='scans') ax.legend() ax.set_xlim(*zlim) quicktitle(ax, 'Ripples') # Create per-rat plots of event distribution mean differences self.figure['across_rats'] = f = plt.figure(figsize=(11, 8)) f.suptitle('Mean Theta Power Difference Across Rats') pause_diff = np.zeros(len(rat_list), 'd') scan_diff = np.zeros(len(rat_list), 'd') pause_pval = np.ones(len(rat_list), 'd') scan_pval = np.ones(len(rat_list), 'd') for i, rat in enumerate(rat_list): if len(pause_ripple_rat[rat]) > 1 and len( pause_noripple_rat[rat]) > 1: pause_diff[i] = pause_ripple_rat[rat].mean( ) - pause_noripple_rat[rat].mean() pause_pval[i] = t_welch(pause_ripple_rat[rat], pause_noripple_rat[rat])[1] if len(scan_ripple_rat[rat]) > 1 and len( scan_noripple_rat[rat]) > 1: scan_diff[i] = scan_ripple_rat[rat].mean( ) - scan_noripple_rat[rat].mean() scan_pval[i] = t_welch(scan_ripple_rat[rat], scan_noripple_rat[rat])[1] pause_sig = pause_pval <= siglevel scan_sig = scan_pval <= siglevel N = len(rat_list) x = np.arange(N) for subp, sig, diff, label in [(221, pause_sig, pause_diff, 'pause'), (222, scan_sig, scan_diff, 'scan')]: ax = f.add_subplot(subp) h1 = ax.stem(x[sig], diff[sig], linefmt='k-', basefmt='k-', markerfmt='bo') h2 = ax.stem(x[True - sig], diff[True - sig], linefmt='k-', basefmt='k-', markerfmt='ro') h1[0].set_zorder(100) h2[0].set_zorder(100) ax.set(xticks=[], xlim=(-1, N)) ax.tick_params(top=False, right=False) ax.tick_params(axis='x', direction='out', labelsize='small') if label == "pause": ax.set_ylabel(r'$\Delta$[ripples, no ripples]') quicktitle(ax, '%ss' % label.title()) # Create per-rat plots of ripple distribution scan mean differences running_diff = np.zeros(len(rat_list), 'd') scanpause_diff = np.zeros(len(rat_list), 'd') running_pval = np.ones(len(rat_list), 'd') scanpause_pval = np.ones(len(rat_list), 'd') for i, rat in enumerate(rat_list): if len(ripple_scan_rat[rat]) > 1 and len( ripple_running_rat[rat]) > 1: running_diff[i] = ripple_scan_rat[rat].mean( ) - ripple_running_rat[rat].mean() running_pval[i] = t_welch(ripple_scan_rat[rat], ripple_running_rat[rat])[1] if len(ripple_scan_rat[rat]) > 1 and len( ripple_pause_rat[rat]) > 1: scanpause_diff[i] = ripple_scan_rat[rat].mean( ) - ripple_pause_rat[rat].mean() scanpause_pval[i] = t_welch(ripple_scan_rat[rat], ripple_pause_rat[rat])[1] running_sig = running_pval <= siglevel scanpause_sig = scanpause_pval <= siglevel for subp, sig, diff, label in [ (223, running_sig, running_diff, 'running'), (224, scanpause_sig, scanpause_diff, 'pause') ]: ax = f.add_subplot(subp) h1 = ax.stem(x[sig], diff[sig], linefmt='k-', basefmt='k-', markerfmt='bo') h2 = ax.stem(x[True - sig], diff[True - sig], linefmt='k-', basefmt='k-', markerfmt='ro') h1[0].set_zorder(100) h2[0].set_zorder(100) ax.set(xticks=x[::3], xticklabels=map(str, rat_list)[::3], xlim=(-1, N)) ax.tick_params(top=False, right=False) ax.tick_params(axis='x', direction='out', labelsize='small') if label == "running": ax.set_ylabel(r'$\Delta$[scan, non-scan]') quicktitle(ax, '%ss' % label.title()) # Create pdf reports of individual rat distributions of ripple vs # no-ripple peak z-power theta for both scan and pause events class ThetaRatReport(BaseReport): label = 'rat report' def collect_data(self, which='scan'): if which == 'scan': ripple_rat = scan_ripple_rat noripple_rat = scan_noripple_rat elif which == 'pause': ripple_rat = pause_ripple_rat noripple_rat = pause_noripple_rat else: raise ValueError, 'bad event type: %s' % which for rat, ax in self.get_plot(rat_list): cdf = np.cumsum(distro(ripple_rat[rat])) cdf_null = np.cumsum(distro(noripple_rat[rat])) ax.plot(centers, cdf, 'b-', centers, cdf_null, 'r-') ax.set(xlim=(centers[0], centers[-1]), ylim=(0, 1)) ax.tick_params(top=False, right=False) quicktitle(ax, 'rat%03d' % rat) if self.firstonpage: ax.set_ylabel('CDF') else: ax.set_yticklabels([]) if self.lastonpage: ax.legend(['w/ ripples', 'no ripples'], loc=2, bbox_to_anchor=(1.1, 1)) ax.set_xlabel('Peak Z(P(Theta))') else: ax.set_xticklabels([]) for which in 'scan', 'pause': reportdir = os.path.join(self.datadir, 'report') if not os.path.isdir(reportdir): os.makedirs(reportdir) report = ThetaRatReport(desc='%s events' % which, datadir=reportdir) report(which=which) report.open() os.rename(report.results['report'], os.path.join(self.datadir, 'rat_%s_cdfs.pdf' % which)) os.system('rm -rf %s' % reportdir) data_file.close()
def process_data(self, modelim=(0.0, 0.55), ymax=0.3, flim=(4, 12), fcrop=(2, 14)): """Display PSDs and statistics for scan/pause events """ self.out.outfd = file(os.path.join(self.datadir, 'figure.log'), 'w') self.out.timestamp = False plt.ioff() res = Reify(self.results) F = res.freqs rats = res.rat_list crop = (F >= fcrop[0]) * (F <= fcrop[1]) F_crop = F[crop] P_scan = res.scan_psd[:, crop] P_pause = res.pause_psd[:, crop] P_running = res.running_psd[:, crop] self.out('Found data for %d rats:\n%s' % (len(rats), str(rats))) c_scan = 'r' c_pause = 'b' c_running = 'k' def CI(P): return 1.96 * P.std(axis=0) / np.sqrt(P.shape[0]) def freq_mean(P): return F_crop, P.mean(axis=0) def freq_mean_error(P): return freq_mean(P) + (CI(P), ) if type(self.figure) is not dict: self.figure = {} self.figure['theta_power'] = f = plt.figure(num=25, figsize=(8, 10)) plt.clf() f.suptitle('Power Spectra During Scanning and Non-Scanning Behaviors') ax = f.add_subplot(311) ax.plot(*freq_mean(P_scan), c=c_scan, lw=2, label='Scan', zorder=10) shaded_error(*freq_mean_error(P_scan), ax=ax, fc=c_scan, alpha=0.3, zorder=10) ax.plot(*freq_mean(P_pause), c=c_pause, lw=2, label='Pause', zorder=5) shaded_error(*freq_mean_error(P_pause), ax=ax, fc=c_pause, alpha=0.3, zorder=5) ax.plot(*freq_mean(P_running), c=c_running, lw=2, label='Running', zorder=1) shaded_error(*freq_mean_error(P_running), ax=ax, fc=c_running, alpha=0.3, zorder=1) ax.set_xlim(flim) ax.set_ylim(0, ymax) ax.tick_params(top=False, right=False, direction='out') ax.legend(loc='upper right') theta = (F > 5) * (F < 12) scan_mode = np.max(res.scan_psd[:, theta], axis=1) pause_mode = np.max(res.pause_psd[:, theta], axis=1) running_mode = np.max(res.running_psd[:, theta], axis=1) self.out('Scan - running mode: T = %.3f, p < %e' % t_paired(scan_mode, running_mode)) self.out('Scan < running #: %d/%d rats' % (np.sum(scan_mode - running_mode < 0), len(rats))) self.out('Pause - running mode: T = %.3f, p < %e' % t_paired(pause_mode, running_mode)) self.out('Pause < running #: %d/%d rats' % (np.sum(pause_mode - running_mode < 0), len(rats))) self.out('Scan - pause mode: T = %.3f, p < %e' % t_paired(scan_mode, pause_mode)) self.out('Scan > pause #: %d/%d rats' % (np.sum(scan_mode - pause_mode > 0), len(rats))) ax = f.add_subplot(323) ax.scatter(running_mode, scan_mode, c=c_scan, s=24, marker='o', edgecolor='k', linewidths=0.5, zorder=5) for i in xrange(len(rats)): ax.plot([running_mode[i]] * 2, [scan_mode[i], pause_mode[i]], '-', c=c_pause, lw=0.75, zorder=-1) ax.scatter(running_mode, pause_mode, c=c_pause, s=18, marker='v', linewidths=0, zorder=0) ax.plot(modelim, modelim, '-', c='0.3', zorder=-2) ax.set_xlabel(r'running $\theta$ peak') # ax.tick_params(direction='out') ax.axis(modelim * 2) quicktitle(ax, r'scan/pause $\theta$ peak') self.figure['power_spectra_rats'] = f = plt.figure(num=26, figsize=(9, 8)) plt.clf() f.suptitle('Power Spectra For Individual Rats (N = %d)' % len(rats)) def plot_rat_spectra(ax, data, label): ax.imshow(data, interpolation='nearest', origin='upper', aspect='auto', extent=[F[0], F[-1] + (F[-1] - F[-2]), 0, rats.size]) ax.set(yticks=(np.arange(rats.size) + 0.5), yticklabels=map(str, rats[::-1])) ax.set_xlim(flim) ax.tick_params(axis='y', right=False, direction='out', labelsize='xx-small', length=3) quicktitle(ax, '%s spectra' % label, size='x-small') plot_rat_spectra(f.add_subplot(221), res.scan_psd, 'scan') plot_rat_spectra(f.add_subplot(222), res.pause_psd, 'pause') plot_rat_spectra(f.add_subplot(223), res.running_psd, 'running') plt.draw() plt.show() self.out.outfd.close()
def collect_data(self, dataset=(57, 1), lag=0.25): """Detect all ripples in dataset and plot EEG, ripple-band, and power signals along with detected event boundaries """ ripple_table = get_node('/physiology', 'ripples') tetrode_query = '(area=="CA1")&(EEG==True)' dataset_query = '(rat==%d)&(day==%d)' % dataset pyr_tetrodes = find_pyramidale_tetrodes(dataset, verbose=False) rat, day = dataset # Initialize accumulators time_slices = [] EEG_slices = [] power_slices = [] events = [] timestamps = [] Ripple = RippleFilter() # Loop through sessions, detecting and storing ripple slices for rds in unique_sessions(ripple_table, condn=dataset_query): data = SessionData.get(rds) self.out('Loading data for rat%03d-%02d-m%d...' % rds) ts = None EEG = None P = None for tt in pyr_tetrodes: X = get_eeg_timeseries(rds, tt) if X is None: continue if ts is None: ts = X[0] if EEG is None: EEG = X[1] else: EEG = np.vstack((EEG, X[1])) if P is None: P = Ripple.power(X[1]) else: P = np.vstack((P, Ripple.power(X[1]))) if P.ndim == 2: P = np.mean(P, axis=0) ts_ripples = [(rec['start'], rec['peak'], rec['end']) for rec in ripple_table.where(data.session_query)] t = data.T_(ts) for timing in ts_ripples: start, peak, end = data.T_(timing) chunk = time_slice(t, peak - lag, peak + lag) time_slices.append(t[chunk] - peak) EEG_slices.append(EEG[..., chunk]) power_slices.append(P[chunk]) events.append((start - peak, end - peak)) timestamps.append(timing[1]) self.out('Plotting EEG traces of ripple events...') LW = 0.4 norm = lambda x: x.astype('d') / float(CLIP) for i, ax in self.get_plot(range(len(time_slices))): t_chunk = time_slices[i] traces = EEG_slices[i] if traces.ndim == 1: ax.plot(t_chunk, norm(traces), 'k-', lw=1.5 * LW, alpha=1, zorder=0) else: ax.plot(t_chunk, norm(traces).T, 'k-', lw=LW, alpha=0.5, zorder=-1) ax.plot(t_chunk, norm(np.mean(traces, axis=0)), 'k-', lw=LW, alpha=1, zorder=0) ax.plot(t_chunk, power_slices[i] / power_slices[i].max(), 'b-', lw=1.5 * LW, alpha=1, zorder=1) ax.axhline(0, ls='-', c='k', lw=LW, zorder=0) ax.axvline(events[i][0], ls='-', c='k', lw=LW, zorder=2) ax.axvline(0, ls=':', c='k', lw=LW, zorder=2, alpha=0.5) ax.axvline(events[i][1], ls='-', c='k', lw=LW, zorder=2) ax.set_xlim(-lag, lag) ax.set_ylim(-1, 1) ax.set_axis_off() quicktitle(ax, '%d' % timestamps[i], size='xx-small') self.out.printf('.') self.out.printf('\n')
def process_data(self, cdf=False, sig_thresh=0.05): """Display LFP distributions and statistics for scan/pause events """ plt.ioff() # Load results data res = Reify(self.results) N = len(res.rat_number) F = res.centers self.out('Found data for %d rats.' % N) # Choose distribution function if cdf: running_df = res.running_cdf scan_df = res.scan_cdf pause_df = res.pause_cdf else: running_df = res.running_pdf scan_df = res.scan_pdf pause_df = res.pause_pdf def CI(P): return P.mean(axis=0), 1.96 * P.std(axis=0) / np.sqrt(P.shape[0]) def plot_rat_distros(ax, data, label): rats = res.rat_number rat_distro = np.empty((rats.size, F.size), 'd') norm = lambda P: P / P.max() for i, rat in enumerate(rats): rat_distro[i] = norm(data[res.rat_number == rat].mean(axis=0)) ax.imshow(rat_distro, interpolation='nearest', origin='upper', aspect='auto', extent=[F[0], F[-1] + (F[-1] - F[-2]), 0, rats.size]) ax.set(yticks=(np.arange(N) + 0.5), yticklabels=map(str, rats[::-1])) ax.tick_params(axis='y', right=False, labelsize='xx-small', direction='out', length=3) quicktitle(ax, '%s p[%s]' % (label, res.distro)) # Create the frequency distributions figure if type(self.figure) is not dict: self.figure = {} self.figure['%s_pdfs' % res.distro] = f = plt.figure(figsize=(9, 8)) f.suptitle('%s Distributions Across Rats During Behaviors' % res.distro.title()) running_label = 'Running' ax = f.add_subplot(221) ax.plot(F, running_df.mean(axis=0), 'k-', lw=1, label=running_label) ax.plot(F, pause_df.mean(axis=0), 'r-', lw=1, label='Pause') ax.plot(F, scan_df.mean(axis=0), 'b-', lw=1, label='Scan') shaded_error(*((F, ) + CI(running_df)), ax=ax, fc='k', alpha=0.4) shaded_error(*((F, ) + CI(pause_df)), ax=ax, fc='r', alpha=0.4) shaded_error(*((F, ) + CI(scan_df)), ax=ax, fc='b', alpha=0.4) ax.legend(loc=4) quicktitle(ax, 'all sessions') plot_rat_distros(f.add_subplot(222), scan_df, 'scan') plot_rat_distros(f.add_subplot(223), pause_df, 'pause') plot_rat_distros(f.add_subplot(224), running_df, 'running') # Create the statistical summary figure self.figure['%s_rats' % res.distro] = f = plt.figure(figsize=(10, 8)) f.suptitle('Statistical Summary of %s %s Differences' % (res.band.title(), res.distro.title())) all_labels = ['scan-running', 'pause-running', 'scan-pause'] all_df = [(res.scan_mu, res.running_mu), (res.pause_mu, res.running_mu), (res.scan_mu, res.pause_mu)] ax = f.add_subplot(221) for i, d in enumerate(zip(all_labels, all_df)): label, mu = d delta = mu[0] - mu[1] t, p = t_paired(mu[0], mu[1], 0) c = (p <= sig_thresh) and 'b' or 'r' ax.errorbar([i], [delta.mean()], yerr=CI(delta)[1], fmt=c + 's', ecolor='k', ms=6, mew=0) self.out('Rat means, %s differences: %s = %.4f, p < %.6f' % (res.distro, label, delta.mean(), p)) ax.axhline(0, c='k', ls='-') ax.set_xlim(-0.5, 2.5) ax.set(ylabel=r'$\Delta$f', xticks=[0, 1, 2], xticklabels=all_labels) ax.tick_params(axis='x', labelsize='x-small') quicktitle(ax, 'across rats') for i, d in enumerate(zip(all_labels, all_df)): label, mu = d df = mu[0] - mu[1] ax = f.add_subplot(222 + i) sig_ix = res.scan_p <= sig_thresh rats = np.arange(N) if np.any(sig_ix): h = ax.stem(rats[sig_ix], df[sig_ix], linefmt='k-', basefmt='k-', markerfmt='bo') h[0].set_zorder(100) if not np.all(sig_ix): h = ax.stem(rats[True - sig_ix], df[True - sig_ix], linefmt='k-', basefmt='k-', markerfmt='ro') h[0].set_zorder(100) ax.set(xticks=rats[::3], xticklabels=map(str, res.rat_number)[::3], xlim=(-1, N)) ax.tick_params(top=False, right=False) ax.tick_params(axis='x', direction='out', labelsize='small') if i == 1: ax.set_ylabel(r'$\Delta$f') quicktitle(ax, label) plt.draw() plt.show()
def run_signal_xcorrs(self, event='scans', ripple_nonscan=False, signal='ZP_theta', lag=3, fc='b', ylim=None): """Cross-correlations of behaviors with continuous signals """ data_file = self.get_data_file() session_table = data_file.root.sessions if event == 'scans': event_points = ScanPoints elif event == 'pauses': event_points = ('start', 'end') elif event == 'ripples': event_points = ('start', 'peak', 'end') else: raise ValueError, 'unknown event type "%s"'%event rat_averages = {} rat_slices = { k: {} for k in event_points } lag_samples = 2 * lag * Theta.fs for session in session_table.iterrows(): self.out.printf('.') t_theta = data_file.getNode('/arrays', session['t_theta'])[:] x_theta = data_file.getNode('/arrays', session[signal])[:] events = data_file.getNode('/arrays', session[event])[:] rat = session['rat'] # If analyzing ripples, need scans to restrict to scan-ripples if event == 'ripples': scans = data_file.getNode('/arrays', session['scans'])[:] for i, phase in enumerate(event_points): if events.size == 0: continue t_event_list = events[:,i] # Restrict events list if analyzing ripples to just scan-ripples if event == 'ripples': if ripple_nonscan: t_event_list = t_event_list[ exclude_from(t_event_list, scans[:,ScanPhases['related']])] else: t_event_list = t_event_list[ select_from(t_event_list, scans[:,ScanPhases['related']])] for t_scan in t_event_list: scan_ix = np.argmin(np.abs(t_theta - t_scan)) win_ix = scan_ix - lag_samples, scan_ix + lag_samples if win_ix[0] < 0 or win_ix[1] > x_theta.size: continue signal_slice = x_theta[win_ix[0]:win_ix[1]] if rat in rat_slices[phase]: if signal_slice.size != rat_slices[phase][rat].shape[1]: self.out('Bad signal size: rat%d @ t = %.2f'%(rat, t_scan)) continue rat_slices[phase][rat] = np.vstack( (rat_slices[phase][rat], signal_slice)) else: rat_slices[phase][rat] = signal_slice[np.newaxis] self.out.printf('\n') self.out('Averaging rat signal slices...') for phase in event_points: N_rats = len(rat_slices[phase].keys()) averages = [] for rat in rat_slices[phase].keys(): averages.append(rat_slices[phase][rat].mean(axis=0)) rat_averages[phase] = np.array(averages) plt.ioff() f = self.new_figure('%s_%s_xcorrs'%(signal, event[:-1]), '%s x %s Phase Cross-Correlations'%(signal, event[:-1].title()), size=(16,10)) nrows, ncols = 2, 3 for i, phase in enumerate(event_points): self.out('Plotting xcorrs for "%s" phase'%phase) N_rats, N_t = rat_averages[phase].shape mu = rat_averages[phase].mean(axis=0) - 0.2 sem = rat_averages[phase].std(axis=0) / np.sqrt(N_rats) t = np.linspace(-lag, lag, N_t) ax = f.add_subplot(nrows, ncols, i+1) ax.plot(t, mu, '-', c=fc, zorder=1) shaded_error(t, mu, sem, ax=ax, fc=fc, alpha=0.3, zorder=0) ax.axhline(0.0, c='k', ls='-', zorder=-2) ax.set_xlim(-lag, lag) if ylim is not None: ax.set_ylim(ylim) elif signal == 'ZP_theta': ax.set_ylim(-0.4, 0.4) elif signal == 'f_theta': ax.set_ylim(7.2, 7.7) ax.tick_params(top=False, right=False, left=False) quicktitle(ax, phase.title()) plt.ion() plt.show()
def process_data(self, bins=16): self.out.outfd = file( os.path.join(self.datadir, 'stats_%d.log' % bins), 'w') self.out.timestamp = False data_file = self.get_data_file() results = data_file.root.theta_velocity rat_list = unique_rats(results) velocity_moments = self.results['velocity_moments'] def find_velocity_bins(): vbins = {} for moment in velocity_moments: data = results.col(moment) lo, hi = CI(data, alpha=0.02) self.out('%s: range %f to %f' % (moment, lo, hi)) vbins[moment] = np.linspace(lo, hi, bins + 1) return vbins velocity_bins = find_velocity_bins() def generate_velocity_modulation_curves(): self.out('Generating velocity modulation curves...') P_v = np.empty((len(velocity_moments), len(rat_list), bins), 'd') f_v = np.empty_like(P_v) power = results.col('power') frequency = results.col('frequency') for i, moment in enumerate(velocity_moments): self.out('Computing %s...' % moment) for j, rat in enumerate(rat_list): self.out.printf('[%d] ' % rat, color='lightgreen') for k in xrange(bins): v_lo, v_hi = velocity_bins[moment][k:k + 2] query = '(rat==%d)&(%s>=%f)&(%s<%f)' % ( rat, moment, v_lo, moment, v_hi) ix = results.getWhereList(query) power_sample = power[ix] frequency_sample = frequency[ix] P_v[i, j, k] = np.median(power_sample) f_v[i, j, k] = np.median(frequency_sample) self.out.printf('\n') return P_v, f_v P_v_fn = os.path.join(self.datadir, 'P_v_%d.npy' % bins) f_v_fn = os.path.join(self.datadir, 'f_v_%d.npy' % bins) if os.path.exists(P_v_fn) and os.path.exists(f_v_fn): self.out('Loading previous velocity modulation data...') P_v, f_v = map(np.load, (P_v_fn, f_v_fn)) else: P_v, f_v = generate_velocity_modulation_curves() np.save(P_v_fn, P_v) np.save(f_v_fn, f_v) plt.ioff() if type(self.figure) is not dict: self.figure = {} self.figure['velocity_modulation_curves'] = f = plt.figure( num=20, figsize=(9, 10)) plt.clf() f.suptitle('Theta (Z-)Power, Frequency - Velocity Modulation') N_moments = len(velocity_moments) line_fmt = dict(ls='-', c='k', lw=2) shade_fmt = dict(ec='none', alpha=0.3, fill=True, fc='k', zorder=-1) def compute_error(M): return 1.96 * M.std(axis=0) / np.sqrt(M.shape[0]) def get_errlim(mu, err, factor=0.1): errmin, errmax = (mu - sem).min(), (mu + sem).max() derr = errmax - errmin return errmin - (factor / 2) * derr, errmax + (factor / 2) * derr labels = ('Z-Power', 'Frequency') for i, moment in enumerate(velocity_moments[:2]): centers = (lambda b: (b[1:] + b[:-1]) / 2)(velocity_bins[moment]) for j, X_v in enumerate([P_v, f_v]): ax = f.add_subplot(N_moments, 2, i * 2 + j + 1) mu = X_v[i].mean(axis=0) sem = compute_error(X_v[i]) ax.plot(centers, mu, **line_fmt) shaded_error(centers, mu, sem, ax=ax, **shade_fmt) self.out('%s: %s %s' % (moment.title(), labels[j], friedman_str(X_v[i]))) if i == 0: quicktitle(ax, labels[j], size='x-small') ax.set_xlabel(snake2title(moment)) ax.set_xlim(centers[0], centers[-1]) ax.set_ylim(get_errlim(mu, sem)) plt.ion() plt.show() self.close_data_file() self.out.outfd.close()
def run_ripple_xcorrs(self, lag=4, numbins=71, ripple_lock='peak'): """Compute scan-ripple cross-correlograms """ # Load results data data_file = self.get_data_file() sessions = data_file.root.sessions scan_table = get_node('/behavior', 'scans') # Correlogram bins edges = np.linspace(-lag, lag, numbins+1) centers = (edges[:-1] + edges[1:]) / 2 # Overall scanning xcorrs self.out("Computing ripple-scan cross-correlations...") r_ix = dict(start=0, peak=1, end=2)[ripple_lock] C = { k: np.zeros(numbins, 'd') for k in ScanPoints } C['pstart'] = np.zeros(numbins, 'd') C['pend'] = np.zeros(numbins, 'd') for session in sessions.iterrows(): scans = data_file.getNode('/arrays', session['scans']) pauses = data_file.getNode('/arrays', session['pauses']) ripples = data_file.getNode('/arrays', session['ripples']) if (len(scans) and len(ripples)): for i, pt in enumerate(ScanPoints): C[pt] += xcorr(scans[:,i], ripples[:,r_ix], maxlag=lag, bins=numbins)[0] if (len(pauses) and len(ripples)): C['pstart'] += xcorr(pauses[:,0], ripples[:,1], maxlag=lag, bins=numbins)[0] C['pend'] += xcorr(pauses[:,1], ripples[:,1], maxlag=lag, bins=numbins)[0] f = self.new_figure('xcorrs', 'Scan-Ripple Correlations', (11,12)) ax = f.add_subplot(321) ax.plot(centers, C['downshift'], drawstyle='steps-mid', label='down') ax.plot(centers, C['upshift'], drawstyle='steps-mid', label='up') ax.legend(loc=0) ax.set(xlim=(-lag, lag), xticks=[-lag, -lag/2., 0, lag/2., lag], yticks=[]) ax.set_ylim(bottom=0) ax.tick_params(top=False) quicktitle(ax, 'Gear Shifting x Ripples') ax = f.add_subplot(322) ax.plot(centers, C['start'], drawstyle='steps-mid', label='start') ax.plot(centers, C['end'], drawstyle='steps-mid', label='end') ax.legend(loc=0) ax.set(xlim=(-lag, lag), xticks=[-lag, -lag/2., 0, lag/2., lag], yticks=[]) ax.set_ylim(bottom=0) ax.tick_params(top=False) quicktitle(ax, 'Scans x Ripples') ax = f.add_subplot(323) ax.plot(centers, C['max'], drawstyle='steps-mid', label='max') ax.plot(centers, C['return'], drawstyle='steps-mid', label='return') ax.legend(loc=0) ax.set(xlim=(-lag, lag), xticks=[-lag, -lag/2., 0, lag/2., lag], yticks=[]) ax.set_ylim(bottom=0) ax.tick_params(top=False) quicktitle(ax, 'Dwells x Ripples') ax = f.add_subplot(324) ax.plot(centers, C['pstart'], drawstyle='steps-mid', label='pause start') ax.plot(centers, C['pend'], drawstyle='steps-mid', label='pause end') ax.legend(loc=0) ax.set(xlim=(-lag, lag), xticks=[-lag, -lag/2., 0, lag/2., lag], yticks=[]) ax.set_ylim(bottom=0) ax.tick_params(top=False) quicktitle(ax, 'Pauses x Ripples') # Ripple-event fractions across event and experiment types self.out("Computing ripple-event fractions...") event_types = ('gearshifts', 'scans', 'pauses') expt_types = ('DR', 'NOV') frac = np.empty((len(event_types)*len(expt_types),), 'd') frac_rat_mu = np.empty_like(frac) frac_rat_sem = np.empty_like(frac) labels = [] i = 0 for expt in expt_types: for event in event_types: hits = N = 0 hits_rat = {} N_rat = {} for session in sessions.where('type=="%s"'%expt): if event in ('gearshifts', 'scans'): events = data_file.getNode('/arrays', session['scans']) if event == 'scans': events = events[:,ScanPhases['scan']] # start -> end elif event == 'gearshifts': events = events[:,ScanPhases['related']] # down -> upshift else: events = data_file.getNode('/arrays', session[event]) ripples = data_file.getNode('/arrays', session['ripples']) N_events = events.shape[0] if N_events == 0: continue # Count hits based on ripple peaks and 1) pauses: start->end, # and 2) ripples: down->upshift and start->end H = 0 for v in events: H += int(np.any(np.logical_and( ripples[:,r_ix] >= v[0], ripples[:,r_ix] < v[-1]))) N += N_events hits += H if session['rat'] in N_rat: hits_rat[session['rat']] += H N_rat[session['rat']] += N_events else: hits_rat[session['rat']] = H N_rat[session['rat']] = N_events labels.append('%s %s'%(expt, event)) frac[i] = hits / float(N) frac_rat = [hits_rat[rat] / float(N_rat[rat]) for rat in N_rat] frac_rat_mu[i] = np.mean(frac_rat) frac_rat_sem[i] = np.std(frac_rat) / np.sqrt(len(N_rat)) i += 1 ax = f.add_subplot(325) x = np.array([0, 0.5, 1.0, 2, 2.5, 3.0]) fmt = dict(mfc='w', mec='k', mew=1, ms=6) ax.plot(x + 0.075, frac, 'o', label='overall', **fmt) ax.errorbar(x - 0.075, frac_rat_mu, yerr=frac_rat_sem, fmt='s', ecolor='k', elinewidth=1.5, capsize=5, label='across rats', **fmt) ax.set_xticks(x) ax.set_xticklabels(labels, size='small', rotation=45) ax.set_xlim(-0.5, 3.5) ax.set_ylim(bottom=0) ax.set_xlabel('Events') ax.set_ylabel('Fraction') ax.tick_params(top=False, right=False) quicktitle(ax, 'Fraction of Events with Ripples', size='small') # Fraction of behavior events across session type containing ripples self.out("Computing ripple-phase distributions...") phase_partition = ('downshift', 'out', 'dwell', 'inb', 'upshift') counts = np.zeros(len(phase_partition)) counts_rat = {} for i, phase in enumerate(phase_partition): for session in sessions.iterrows(): ripples = data_file.getNode('/arrays', session['ripples']) scans = data_file.getNode('/arrays', session['scans']) if not (len(ripples) and len(scans)): continue phase_events = scans[:,ScanPhases[phase]] hits = np.sum(select_from(ripples[:,r_ix], phase_events)) counts[i] += hits rat = session['rat'] if rat not in counts_rat: counts_rat[rat] = np.zeros(len(phase_partition)) counts_rat[rat][i] += hits N_rats = len(counts_rat) p_phase = np.empty((N_rats, len(phase_partition)), 'd') for i, rat in enumerate(counts_rat.keys()): p_phase[i] = counts_rat[rat] / counts_rat[rat].sum() p_phase_mu = p_phase.mean(axis=0) p_phase_sem = p_phase.std(axis=0) / np.sqrt(N_rats) ax = f.add_subplot(326) x = np.arange(len(phase_partition)) ax.plot(x + 0.1, counts / counts.sum(), 'o', label='overall', **fmt) ax.errorbar(x - 0.1, p_phase_mu, yerr=p_phase_sem, fmt='s', ecolor='k', elinewidth=1.5, capsize=5, label='across rats', **fmt) ax.set_xticks(x) ax.set_xticklabels(('Downshift', 'Outbound', 'Dwell', 'Inbound', 'Upshift'), size='small', rotation=45) ax.set_xlim(-0.5, len(phase_partition) - 0.5) ax.set_ylim(bottom=0) ax.set_xlabel('Head-Scan Phase') ax.set_ylabel('p[Phase]') ax.tick_params(top=False, right=False) ax.legend(loc=0) quicktitle(ax, 'P[phase|ripple]', size='small') plt.ion() plt.show()
def process_data(self): """Display frequency distributions and statistics for scan/pause events """ plt.ioff() # Load results data res = Reify(self.results) N = len(res.rat_number) F = res.phase_bins plim = F[0], F[-1] + (F[-1] - F[-2]) def CI(P): return P.mean(axis=0), 1.96 * P.std(axis=0) / np.sqrt(P.shape[0]) def plot_rat_distros(ax, data, label, xlim=plim): ax.imshow(data, interpolation='nearest', origin='upper', aspect='auto', extent=[xlim[0], xlim[1], 0, N]) ax.set(yticks=(np.arange(N) + 0.5), yticklabels=map(str, res.rat_number[::-1])) ax.tick_params(axis='y', right=False, labelsize='xx-small', direction='out', length=3) quicktitle(ax, '%s' % label) # Create the summary comparison figure self.figure = {} band_label = '%s-%s' % (res.phase_band.title(), res.amp_band.title()) self.figure['phase_modulations'] = f = plt.figure(figsize=(11, 8.5)) f.suptitle('%s Modulation During Running and Non-running Behaviors' % band_label) running_label = 'RUN' ax = f.add_subplot(221) ax.plot(F, res.running_distro.mean(axis=0), 'k-', lw=1, label=running_label) ax.plot(F, res.pause_distro.mean(axis=0), 'r-', lw=1, label='PAU') ax.plot(F, res.scan_distro.mean(axis=0), 'b-', lw=1, label='SCN') shaded_error(*((F, ) + CI(res.running_distro)), ax=ax, fc='k', alpha=0.4) shaded_error(*((F, ) + CI(res.pause_distro)), ax=ax, fc='r', alpha=0.4) shaded_error(*((F, ) + CI(res.scan_distro)), ax=ax, fc='b', alpha=0.4) ax.legend(loc=4) ax.set_xlim(plim) quicktitle(ax, 'all sessions') plot_rat_distros(f.add_subplot(222), res.scan_distro, 'scan phase distro') plot_rat_distros(f.add_subplot(223), res.pause_distro, 'pause phase distro') plot_rat_distros(f.add_subplot(224), res.running_distro, 'running phase distro') # Create the modulation index bar-plot figure self.figure['modulation_index'] = f = plt.figure(figsize=(11, 8.5)) f.suptitle('%s Modulation Index across Behaviors' % band_label) index_data = np.c_[res.running_index, res.scan_index, res.pause_index] index_labels = ['RUN', 'SCN', 'PAU'] width = 0.8 lefts = np.array([0, 1, 2]) - width / 2 bar_fmt = dict(ecolor='k', capsize=0, color=['k', 'b', 'r'], bottom=0, width=width) ax = f.add_subplot(221) ax.bar(lefts, index_data.mean(axis=0), yerr=CI(index_data)[1], **bar_fmt) ax.set(xticks=[0, 1, 2], xticklabels=index_labels, xlim=(-0.5, 2.5)) ax.tick_params(labelsize='x-small', top=False) quicktitle(ax, 'rats') ax = f.add_subplot(222) ax.plot([0, 1, 2], index_data.T, 'k-', lw=0.75, alpha=0.6) ax.set(xticks=[0, 1, 2], xticklabels=index_labels, xlim=(-0.5, 2.5)) ax.tick_params(labelsize='x-small', top=False) quicktitle( ax, 'rats [SCN>RUN: %d/%d]' % ((index_data[:, 1] > index_data[:, 0]).sum(), index_data.shape[0])) # Create the rat cross-correlations figure self.figure['correlations'] = f = plt.figure(figsize=(11, 8.5)) f.suptitle('Behavioral Cross-correlations of %s Modulation' % band_label) clim = (-plim[1] / 2, plim[1] / 2) running_acorr = np.empty_like(res.running_distro) scan_xcorrs = np.empty_like(res.running_distro) pause_xcorrs = np.empty_like(res.running_distro) scan_pause_xcorrs = np.empty_like(res.running_distro) for i in xrange(N): running_acorr[i] = np.correlate(res.running_distro[i], res.running_distro[i], mode='same') scan_xcorrs[i] = np.correlate(res.running_distro[i], res.scan_distro[i], mode='same') pause_xcorrs[i] = np.correlate(res.running_distro[i], res.pause_distro[i], mode='same') scan_pause_xcorrs[i] = np.correlate(res.pause_distro[i], res.scan_distro[i], mode='same') plot_rat_distros(f.add_subplot(221), scan_xcorrs, 'C[running]', xlim=clim) plot_rat_distros(f.add_subplot(222), scan_xcorrs, 'C[scan, running]', xlim=clim) plot_rat_distros(f.add_subplot(223), pause_xcorrs, 'C[pause, running]', xlim=clim) plot_rat_distros(f.add_subplot(224), scan_pause_xcorrs, 'C[scan, pause]', xlim=clim) plt.draw() plt.show()