def on_select(self, cluster_ids=None): super(CorrelogramView, self).on_select(cluster_ids) cluster_ids = self.cluster_ids n_clusters = len(cluster_ids) if n_clusters == 0: return ccg = self.correlograms(tuple(cluster_ids), self.bin_size, self.window_size, ) ylim = [ccg.max()] if not self.uniform_normalization else None colors = _spike_colors(np.arange(n_clusters), alpha=1.) self.grid.shape = (n_clusters, n_clusters) with self.building(): for i in range(n_clusters): for j in range(n_clusters): hist = ccg[i, j, :] color = colors[i] if i == j else np.ones(4) self[i, j].hist(hist, color=color, ylim=ylim, ) # Cluster labels. if i == (n_clusters - 1): self[i, j].text(pos=[0., -1.], text=str(cluster_ids[j]), anchor=[0., -1.04], data_bounds=None, )
def on_select(self, cluster_ids=None): super(CorrelogramView, self).on_select(cluster_ids) cluster_ids = self.cluster_ids n_clusters = len(cluster_ids) if n_clusters == 0: return ccg = self._compute_correlograms(cluster_ids) ylim = [ccg.max()] if not self.uniform_normalization else None colors = _spike_colors(np.arange(n_clusters), alpha=1.) self.grid.shape = (n_clusters, n_clusters) with self.building(): for i in range(n_clusters): for j in range(n_clusters): hist = ccg[i, j, :] color = colors[i] if i == j else np.ones(4) self[i, j].hist(hist, color=color, ylim=ylim, ) # Cluster labels. if i == (n_clusters - 1): self[i, j].text(pos=[0., -1.], text=str(cluster_ids[j]), anchor=[0., -1.04], )
def _update(clusters): colors = _spike_colors(np.arange(len(clusters))) ax.clear() for i in range(len(clusters)): new_x = set_interp3(controller._get_spike_times(clusters[i], 'None').data) new_y = set_interp4(controller._get_spike_times(clusters[i], 'None').data) ax.plot(new_x, new_y, '.', c=colors[i],alpha=0.6) if my_file.is_file(): ax.plot(opto_x, opto_y, '.', c='w',alpha=0.8) f.canvas.draw()
def _plot_correlograms(self, ccg): n_clusters = ccg.shape[0] ylim = [ccg.max()] if not self.uniform_normalization else None colors = _spike_colors(np.arange(n_clusters), alpha=1.) for i, j in self._iter_subplots(n_clusters): hist = ccg[i, j, :] color = colors[i] if i == j else np.ones(4) self[i, j].hist(hist, color=color, ylim=ylim, )
def _update(clusters): colors = _spike_colors(np.arange(len(clusters))) ax.clear() for i in range(len(clusters)): new_x = set_interp3( controller._get_spike_times(clusters[i], 'None').data) new_y = set_interp4( controller._get_spike_times(clusters[i], 'None').data) ax.plot(new_x, new_y, '.', c=colors[i], alpha=0.6) ax.plot(new_x, new_y + 2 * np.pi, '.', c=colors[i], alpha=0.6) f.canvas.draw()
def _plot_features(self, i, j, x_dim, y_dim, x, y, masks=None, spike_clusters_rel=None): """Plot the features in a subplot.""" assert x.shape == y.shape n_spikes = x.shape[0] sc = spike_clusters_rel if sc is not None: assert sc.shape == (n_spikes,) n_clusters = len(self.cluster_ids) # Retrieve the data bounds. data_bounds = self._get_dim_bounds(x_dim[i, j], y_dim[i, j]) # Retrieve the masks and depth. mx, dx = _project_mask_depth(x_dim[i, j], masks, spike_clusters_rel=sc, n_clusters=n_clusters) my, dy = _project_mask_depth(y_dim[i, j], masks, spike_clusters_rel=sc, n_clusters=n_clusters) assert mx.shape == my.shape == dx.shape == dy.shape == (n_spikes,) d = np.maximum(dx, dy) m = np.maximum(mx, my) # Get the color of the markers. color = _spike_colors(sc, masks=m) assert color.shape == (n_spikes, 4) # Create the scatter plot for the current subplot. # The marker size is smaller for background spikes. ms = (self._default_marker_size if spike_clusters_rel is not None else 1.) self[i, j].scatter(x=x, y=y, color=color, depth=d, data_bounds=data_bounds, size=ms * np.ones(n_spikes), ) if i == (self.n_cols - 1): dim = x_dim[i, j] if j < (self.n_cols - 1) else x_dim[i, 0] self[i, j].text(pos=[0., -1.], text=str(dim), anchor=[0., -1.04], ) if j == 0: self[i, j].text(pos=[-1., 0.], text=str(y_dim[i, j]), anchor=[-1.03, 0.], )
def _update(clusters): colors = _spike_colors(np.arange(len(clusters))) ax.clear() ax.plot(pos_x, pos_y, c='w', linestyle='-', alpha=0.2) ax.plot(opto_x, opto_y, 'o', c='w', alpha=0.5) for i in range(len(clusters)): new_x = set_interp1( controller._get_spike_times( clusters[i], 'None').data) # controller.spike_times(clusters[i]) new_y = set_interp2( controller._get_spike_times(clusters[i], 'None').data) ax.plot(new_x, new_y, '.', c=colors[i], alpha=0.1) f.canvas.draw()
def on_select(self, cluster_ids=None): super(ScatterView, self).on_select(cluster_ids) cluster_ids = self.cluster_ids n_clusters = len(cluster_ids) if n_clusters == 0: return # Get the spike times and amplitudes data = self.coords(cluster_ids) if data is None: self.clear() return spike_ids = data.spike_ids spike_clusters = data.spike_clusters x = data.x y = data.y n_spikes = len(spike_ids) assert n_spikes > 0 assert spike_clusters.shape == (n_spikes, ) assert x.shape == (n_spikes, ) assert y.shape == (n_spikes, ) # Get the spike clusters. sc = _index_of(spike_clusters, cluster_ids) # Plot the amplitudes. with self.building(): m = np.ones(n_spikes) # Get the color of the markers. color = _spike_colors(sc, masks=m) assert color.shape == (n_spikes, 4) ms = (self._default_marker_size if sc is not None else 1.) self.scatter( x=x, y=y, color=color, size=ms * np.ones(n_spikes), )
def on_select(self, cluster_ids=None): super(ScatterView, self).on_select(cluster_ids) cluster_ids = self.cluster_ids n_clusters = len(cluster_ids) if n_clusters == 0: return # Get the spike times and amplitudes data = self.coords(cluster_ids) if data is None: self.clear() return spike_ids = data.spike_ids spike_clusters = data.spike_clusters x = data.x y = data.y n_spikes = len(spike_ids) assert n_spikes > 0 assert spike_clusters.shape == (n_spikes,) assert x.shape == (n_spikes,) assert y.shape == (n_spikes,) # Get the spike clusters. sc = _index_of(spike_clusters, cluster_ids) # Plot the amplitudes. with self.building(): m = np.ones(n_spikes) # Get the color of the markers. color = _spike_colors(sc, masks=m) assert color.shape == (n_spikes, 4) ms = (self._default_marker_size if sc is not None else 1.) self.scatter(x=x, y=y, color=color, data_bounds=self.data_bounds, size=ms * np.ones(n_spikes), )
def _plot_correlograms(self, ccg): n_clusters = ccg.shape[0] normalized = self.uniform_normalization ylim = [ccg.max()] if not normalized else None colors = _spike_colors(np.arange(n_clusters), alpha=1.) for i, j in self._iter_subplots(n_clusters): hist = ccg[i, j, :] color = colors[i] if i == j else np.ones(4) self[i, j].hist( hist, color=color, ylim=ylim, ) pos1ms = 2. / (self[i, j].window_size * 1000) self[i, j].lines(pos=[[-pos1ms, -1, -pos1ms, 0], [pos1ms, -1, pos1ms, 0]], color=(1., 1., 1., .5)) if i == j: # Only ACG, not crossCG plot_ACG_features(self[i, j], hist.copy()) elif i != j: plot_CCG_features(self[i, j], hist.copy())
def on_select(clusters, tf=f, tax=ax, bins=bins, **kwargs): # We clear the figure. tax.clear() colors = _spike_colors(np.arange(len(clusters))) for i in range(len(clusters)): if len(clusters) == 1: colors[i][3] = 1 spikes = 1000 * controller.model.spike_times[ controller.model.spike_clusters == clusters[i]] #hist,bin_edges=np.histogram(np.diff(spikes), bins=bins) #ax.bar(bin_edges[:-1], hist, width = 1, edgecolor = 'None', facecolor = colors[i]) #ax.plot(bin_edges[:-1], hist, color = colors[i]) #ax.plot([0, 1], [0, 1], color='r') tax.hist(np.diff(spikes), bins, edgecolor='None', facecolor=colors[i]) ymin, ymax = tax.get_ylim() tax.vlines(1, ymin, ymax, colors='w', linestyles='dashed') # We update the figure. tf.canvas.draw()
def _update(clusters): ax.clear() colors = _spike_colors(np.arange(len(clusters))) maxs = np.zeros(len(clusters)) was_fit = np.zeros(len(clusters), dtype=bool) percent_missing_ndtr = np.zeros(len(clusters), dtype=float) for i in range(len(clusters)): #plot the amplitude histogram coords = controller._get_amplitudes(clusters[i]) if len(clusters) == 1: colors[i][3] = 1 num, bins, patches = ax.hist(coords.y, bins=50, facecolor=colors[i], edgecolor='none', orientation='horizontal') #fit a gaussian to the histogram mean_seed = coords.y.mean() mean_seed = bins[np.argmax(num)] # mode of mean_seed bin_steps = np.diff(bins[:2])[0] x = bins[:-1] + bin_steps / 2 next_low_bin = x[0] - bin_steps add_points = np.flipud(np.arange(next_low_bin, 0, -bin_steps)) x = np.append(add_points, x) num = np.append(np.zeros(len(add_points)), num) if 0: #old way, gaussian fit popt, pcov = curve_fit(gaussian, x, num, p0=(num.max(), mean_seed, 2 * coords.y.std())) n_fit = gaussian(x, popt[0], popt[1], popt[2]) min_amplitude = coords.y.min() was_fit[i] = True else: #new way, cutoff gaussian fit p0 = (num.max(), mean_seed, 2 * coords.y.std(), np.percentile(coords.y, 1)) try: popt, pcov = curve_fit(gaussian_cut, x, num, p0=p0, maxfev=100000) was_fit[i] = True except Exception as e: # try: # logger.info("Fitting failed with maxfev=10000" # ", trying maxfev=1000000") # popt, pcov = curve_fit(gaussian_cut, x, num, # p0=p0, maxfev=1000000) # was_fit[i] = True # except Exception as e: # logger.info("Fitting error: %s", e) was_fit[i] = False if was_fit[i]: n_fit = gaussian_cut(x, popt[0], popt[1], popt[2], popt[3]) min_amplitude = popt[3] n_fit_no_cut = gaussian_cut(x, popt[0], popt[1], popt[2], 0) ax.plot(n_fit_no_cut, x, c='w', linestyle='--') if was_fit[i]: maxs[i] = n_fit.max() ax.plot(n_fit, x, c='w') # norm area calculated by fit parameters norm_area_ndtr = ndtr((popt[1] - min_amplitude) / popt[2]) percent_missing_ndtr[i] = 100 * (1 - norm_area_ndtr) logger.debug('Cluster %d is missing %.1f of spikes', clusters[i], percent_missing_ndtr[i]) if any(was_fit): ax.set_xlim([0, maxs.max() * 1.3]) offset = 0 r = f.canvas.get_renderer() for i in range(len(clusters)): if was_fit[i]: str = '{:.1f}%'.format(percent_missing_ndtr[i]) else: str = 'NaN' t = ax.text(maxs.max() * .01 + offset, ax.get_ylim()[1], str, color=np.append(colors[i][:3], 1), fontsize=12, verticalalignment='top') ext = t.get_window_extent(r) offset = ext.transformed(ax.transData.inverted()).x1 offset = offset + maxs.max() * .02 xt = ax.get_xticks() ax.set_xticks((xt[0], xt[-1])) f.canvas.draw()
def _update(clusters): ax.clear() colors = _spike_colors(np.arange(len(clusters))) maxs = np.zeros(len(clusters)) was_fit = np.zeros(len(clusters), dtype=bool) for i in range(len(clusters)): #plot the amplitude histogram coords = controller._get_amplitudes(clusters[i]) if len(clusters) == 1: colors[i][3] = 1 num, bins, patches = ax.hist(coords.y, bins=50, facecolor=colors[i], edgecolor='none', orientation='horizontal') #fit a gaussian to the histogram mean_seed = coords.y.mean() mean_seed = bins[np.argmax(num)] # mode of mean_seed bin_steps = np.diff(bins[:2])[0] x = bins[:-1] + bin_steps / 2 next_low_bin = x[0] - bin_steps add_points = np.flipud(np.arange(next_low_bin, 0, -bin_steps)) x = np.append(add_points, x) num = np.append(np.zeros(len(add_points)), num) if 0: #old way, gaussian fit popt, pcov = curve_fit(gaussian, x, num, p0=(num.max(), mean_seed, 2 * coords.y.std())) n_fit = gaussian(x, popt[0], popt[1], popt[2]) min_amplitude = coords.y.min() was_fit[i] = True else: #new way, cutoff gaussian fit p0 = (num.max(), mean_seed, 2 * coords.y.std(), np.percentile(coords.y, 1)) try: popt, pcov = curve_fit(gaussian_cut, x, num, p0=p0, maxfev=10000) was_fit[i] = True except Exception as e: try: logger.info("Fitting failed with maxfev=10000" ", trying maxfev=1000000") popt, pcov = curve_fit(gaussian_cut, x, num, p0=p0, maxfev=1000000) was_fit[i] = True except Exception as e: logger.info("Fitting error: %s", str(e)) was_fit[i] = False if was_fit[i]: n_fit = gaussian_cut(x, popt[0], popt[1], popt[2], popt[3]) min_amplitude = popt[3] n_fit_no_cut = gaussian_cut(x, popt[0], popt[1], popt[2], 0) ax.plot(n_fit_no_cut, x, c='w', linestyle='--') if was_fit[i]: maxs[i] = n_fit.max() ax.plot(n_fit, x, c='w') # norm area calculated by fit parameters norm_area_ndtr = ndtr((popt[1] - min_amplitude) / popt[2]) percent_missing_ndtr = 100 * (1 - norm_area_ndtr) logger.debug('Cluster %d is missing %.1f of spikes', clusters[i], percent_missing_ndtr) if any(was_fit): ax.set_xlim([0, maxs.max() * 1.3]) xt = ax.get_xticks() ax.set_xticks((xt[0], xt[-1])) f.canvas.draw()
def on_select(self, cluster_ids=None): super(WaveformView, self).on_select(cluster_ids) cluster_ids = self.cluster_ids n_clusters = len(cluster_ids) if n_clusters == 0: return # Load the waveform subset. data = self.waveforms(cluster_ids) # Take one element in the list. data = data[self.data_index % len(data)] alpha = data.get('alpha', .5) spike_ids = data.spike_ids spike_clusters = data.spike_clusters w = data.data masks = data.masks n_spikes = len(spike_ids) assert w.ndim == 3 n_samples = w.shape[1] assert w.shape == (n_spikes, n_samples, self.n_channels) assert masks.shape == (n_spikes, self.n_channels) # Relative spike clusters. spike_clusters_rel = _index_of(spike_clusters, cluster_ids) assert spike_clusters_rel.shape == (n_spikes,) # Fetch the waveforms. t = _get_linear_x(n_spikes, n_samples) # Overlap. if not self.overlap: t = t + 2.5 * (spike_clusters_rel[:, np.newaxis] - (n_clusters - 1) / 2.) # The total width should not depend on the number of clusters. t /= n_clusters # Plot all waveforms. # OPTIM: avoid the loop. with self.building(): for ch in range(self.n_channels): m = masks[:, ch] depth = _get_depth(m, spike_clusters_rel=spike_clusters_rel, n_clusters=n_clusters) color = _spike_colors(spike_clusters_rel, masks=m, alpha=alpha, ) self[ch].plot(x=t, y=w[:, :, ch], color=color, depth=depth, data_bounds=self.data_bounds, ) # Add channel labels. self[ch].text(pos=[[t[0, 0], 0.]], text=str(ch), anchor=[-1.01, -.25], data_bounds=self.data_bounds, ) # Zoom on the best channels when selecting clusters. channels = self.best_channels(cluster_ids) if channels is not None and self.do_zoom_on_channels: self.zoom_on_channels(channels)