def load(self, channel_colors=None, channel_groups=None, channel_names=None, group_colors=None, group_names=None, background={}): if group_names is None or channel_colors is None: return # Create the tree. # go through all groups for groupidx, groupname in group_names.iteritems(): groupitem = self.add_group_node(groupidx=groupidx, name=groupname, color=select( group_colors, groupidx)) # go through all channels for channelidx, color in channel_colors.iteritems(): # add channel bgcolor = background.get(channelidx, None) channelitem = self.add_channel(name=channel_names[channelidx], channelidx=channelidx, color=color, bgcolor=None, parent=self.get_group( select(channel_groups, channelidx)))
def test_select_array(): # All spikes in cluster 1. indices = [10, 20, 25] # Indices in data excerpt. indices_data = [5, 10, 15, 20] # Generate clusters and data. clusters = generate_clusters(indices) data_raw = generate_data2D() data = pd.DataFrame(data_raw) # Excerpt of the data. data_excerpt = select(data, indices_data) # Get all spike indices in cluster 1. spikes_inclu1 = get_spikes_in_clusters([1], clusters) # We want to select all clusters in cluster 1 among those in data excerpt. data_excerpt_inclu1 = select(data_excerpt, spikes_inclu1) # There should be two rows: 4 in the excerpt, among which two are in # cluster 1. assert data_excerpt_inclu1.shape == (2, 5)
def split_clusters_undo(self, clusters, clusters_old, cluster_groups, cluster_colors, clusters_new): if not hasattr(clusters, '__len__'): clusters = [clusters] spikes = get_indices(clusters_old) # Find groups and colors of old clusters. cluster_indices_old = np.unique(clusters_old) cluster_indices_new = np.unique(clusters_new) # Add clusters that were removed after the split operation. clusters_empty = sorted(set(cluster_indices_old) - set(cluster_indices_new)) self.loader.add_clusters( clusters_empty, select(cluster_groups, clusters_empty), # select(cluster_colors, clusters_empty), ) # Set the new clusters to the corresponding spikes. self.loader.set_cluster(spikes, clusters_old) # Remove empty clusters. clusters_empty = self.loader.remove_empty_clusters() self.loader.unselect() return dict(clusters_to_split=clusters, clusters_split=get_array(cluster_indices_new), # clusters_empty=clusters_empty )
def split_clusters_undo(self, clusters, clusters_old, cluster_groups, cluster_colors, clusters_new): if not hasattr(clusters, '__len__'): clusters = [clusters] spikes = get_indices(clusters_old) # Find groups and colors of old clusters. cluster_indices_old = np.unique(clusters_old) cluster_indices_new = np.unique(clusters_new) # Add clusters that were removed after the split operation. clusters_empty = sorted( set(cluster_indices_old) - set(cluster_indices_new)) self.loader.add_clusters( clusters_empty, select(cluster_groups, clusters_empty), # select(cluster_colors, clusters_empty), ) # Set the new clusters to the corresponding spikes. self.loader.set_cluster(spikes, clusters_old) # Remove empty clusters. clusters_empty = self.loader.remove_empty_clusters() self.loader.unselect() return dict( clusters_to_split=clusters, clusters_split=get_array(cluster_indices_new), # clusters_empty=clusters_empty )
def test_select_pytables(): a = np.random.randn(100, 10) path = generate_earray(a) f = tb.openFile(path, 'r') arr = f.root.arr s = select(arr, slice(0, 10, 2)) assert isinstance(s, pd.DataFrame) assert s.shape == (5, 10) assert np.array_equal(select(arr, 10), arr[[10], :]) assert np.array_equal(select(arr, [10]), arr[[10], :]) assert np.array_equal(select(arr, [10, 20]), arr[[10, 20], :]) assert np.array_equal(select(arr, slice(10, 20)), arr[10:20, :]) f.close() os.remove(path)
def cluster_quality(waveforms, features, clusters, masks, clusters_selected=None): # clusters = select(clusters, spikes) # features = select(features, spikes) # waveforms = select(waveforms, spikes) # masks = select(masks, spikes) nspikes, nsamples, nchannels = waveforms.shape quality = {} for cluster in clusters_selected: spikes = get_spikes_in_clusters(cluster, clusters) w = select(waveforms, spikes) m = select(masks, spikes) q = 1. / nsamples * ((w ** 2).sum(axis=1) * 1).mean(axis=1).max() quality[cluster] = q return quality
def load(self, cluster_colors=None, cluster_groups=None, group_colors=None, group_names=None, cluster_sizes=None, cluster_quality=None, background={}): if group_names is None or cluster_colors is None: return # Create the tree. # go through all groups for groupidx, groupname in group_names.iteritems(): spkcount = np.sum(cluster_sizes[cluster_groups == groupidx]) groupitem = self.add_group_node( groupidx=groupidx, name=groupname, # color=group_colors[groupidx], spkcount=spkcount) color=select(group_colors, groupidx), spkcount=spkcount) # go through all clusters for clusteridx, color in cluster_colors.iteritems(): if cluster_quality is not None: try: quality = get_array(select(cluster_quality, clusteridx))[0] except IndexError: quality = 0. else: quality = 0. # add cluster bgcolor = background.get(clusteridx, None) clusteritem = self.add_cluster( clusteridx=clusteridx, # name=info.names[clusteridx], color=color, bgcolor=bgcolor, quality=quality, # spkcount=cluster_sizes[clusteridx], spkcount=select(cluster_sizes, clusteridx), # assign the group as a parent of this cluster parent=self.get_group(select(cluster_groups, clusteridx)))
def auto_projection(self, target): fet = get_array(select(self.data_manager.features, self.data_manager.clusters == target)) n = fet.shape[1] fet = np.abs(fet[:,0:n-self.nextrafet:self.fetdim]).mean(axis=0) channels_best = np.argsort(fet)[::-1] channel0 = channels_best[0] channel1 = channels_best[1] self.set_projection(0, channel0, 0) self.set_projection(1, channel1, 0) self.parent.projectionChanged.emit(0, channel0, 0) self.parent.projectionChanged.emit(1, channel1, 0)
def auto_projection(self, target): fet = select(self.data_manager.features, self.data_manager.clusters == target) n = fet.shape[1] fet = np.abs(fet.values[:, 0:n - self.nextrafet:self.fetdim]).mean(axis=0) channels_best = np.argsort(fet)[::-1] channel0 = channels_best[0] channel1 = channels_best[1] self.set_projection(0, channel0, 0) self.set_projection(1, channel1, 0) self.parent.projectionChanged.emit(0, channel0, 0) self.parent.projectionChanged.emit(1, channel1, 0)
def load(self, channel_colors=None, channel_groups=None, channel_names=None, group_colors=None, group_names=None, background={}): if group_names is None or channel_colors is None: return # Create the tree. # go through all groups for groupidx, groupname in group_names.iteritems(): groupitem = self.add_group_node(groupidx=groupidx, name=groupname, color=select(group_colors, groupidx)) # go through all channels for channelidx, color in channel_colors.iteritems(): # add channel bgcolor = background.get(channelidx, None) channelitem = self.add_channel( name=channel_names[channelidx], channelidx=channelidx, color=color, bgcolor=None, parent=self.get_group(select(channel_groups, channelidx)))
def load(self, cluster_colors=None, cluster_groups=None, group_colors=None, group_names=None, cluster_sizes=None, cluster_quality=None, background={}): if group_names is None or cluster_colors is None: return # Create the tree. # go through all groups for groupidx, groupname in group_names.iteritems(): spkcount = np.sum(cluster_sizes[cluster_groups == groupidx]) groupitem = self.add_group_node(groupidx=groupidx, name=groupname, # color=group_colors[groupidx], spkcount=spkcount) color=select(group_colors, groupidx), spkcount=spkcount) # go through all clusters for clusteridx, color in cluster_colors.iteritems(): if cluster_quality is not None: try: quality = select(cluster_quality, clusteridx) except IndexError: quality = 0. else: quality = 0. # add cluster bgcolor = background.get(clusteridx, None) clusteritem = self.add_cluster( clusteridx=clusteridx, # name=info.names[clusteridx], color=color, bgcolor=bgcolor, quality=quality, # spkcount=cluster_sizes[clusteridx], spkcount=select(cluster_sizes, clusteridx), # assign the group as a parent of this cluster parent=self.get_group(select(cluster_groups, clusteridx)))
def test_select_pandas(): indices = [10, 20, 25] clusters = generate_clusters(indices) # test selection of Series (1D) clusters = pd.Series(clusters) assert np.array_equal(select(clusters, [9, 11]), [0, 0]) assert np.array_equal(select(clusters, [10, 99]), [1, 0]) assert np.array_equal(select(clusters, [20, 25, 25]), [1, 1, 1]) # test selection of Series (3D) clusters = pd.DataFrame(clusters) assert np.array_equal(np.array(select(clusters, [9, 11])).ravel(), [0, 0]) assert np.array_equal(np.array(select(clusters, [10, 99])).ravel(), [1, 0]) assert np.array_equal(np.array(select(clusters, [20, 25, 25])).ravel(), [1, 1, 1]) # test selection of Panel (4D) clusters = pd.Panel(np.expand_dims(clusters, 3)) assert np.array_equal(np.array(select(clusters, [9, 11])).ravel(), [0, 0]) assert np.array_equal(np.array(select(clusters, [10, 99])).ravel(), [1, 0])
def test_select_pandas(): indices = [10, 20, 25] clusters = generate_clusters(indices) # test selection of Series (1D) clusters = pd.Series(clusters) assert np.array_equal(select(clusters, [9, 11]), [0, 0]) assert np.array_equal(select(clusters, [10, 99]), [1, 0]) assert np.array_equal(select(clusters, [20, 25, 25]), [1, 1, 1]) # test selection of Series (3D) clusters = pd.DataFrame(clusters) assert np.array_equal(np.array(select(clusters, [9, 11])).ravel(), [0, 0]) assert np.array_equal(np.array(select(clusters, [10, 99])).ravel(), [1, 0]) assert np.array_equal( np.array(select(clusters, [20, 25, 25])).ravel(), [1, 1, 1]) # test selection of Panel (4D) clusters = pd.Panel(np.expand_dims(clusters, 3)) assert np.array_equal(np.array(select(clusters, [9, 11])).ravel(), [0, 0]) assert np.array_equal(np.array(select(clusters, [10, 99])).ravel(), [1, 0])
def set_data(self, waveforms=None, masks=None, clusters=None, # list of clusters that are selected, the order matters clusters_selected=None, cluster_colors=None, geometrical_positions=None, keep_order=None, autozoom=None, ): self.autozoom = autozoom if clusters_selected is None: clusters_selected = [] if waveforms is None: waveforms = np.zeros((0, 1, 1)) masks = np.zeros((0, 1)) clusters = np.zeros(0, dtype=np.int32) cluster_colors = np.zeros(0, dtype=np.int32) clusters_selected = [] self.keep_order = keep_order # Not all waveforms have been selected, so select the appropriate # samples in clusters and masks. self.waveform_indices = get_indices(waveforms) self.waveform_indices_array = get_array(self.waveform_indices) masks = select(masks, self.waveform_indices) clusters = select(clusters, self.waveform_indices) # Convert from Pandas into raw NumPy arrays. self.waveforms_array = get_array(waveforms) self.masks_array = get_array(masks) self.clusters_array = get_array(clusters) # Relative indexing. if len(clusters_selected) > 0: self.clusters_rel = np.array(np.digitize(self.clusters_array, sorted(clusters_selected)) - 1, dtype=np.int32) self.clusters_rel_ordered = (np.argsort(clusters_selected) [self.clusters_rel]).astype(np.int32) else: self.clusters_rel = np.zeros(0, dtype=np.int32) self.clusters_rel_ordered = np.zeros(0, dtype=np.int32) if self.keep_order: self.clusters_rel_ordered2 = self.clusters_rel_ordered self.cluster_colors_array = get_array(cluster_colors, dosort=True)[np.argsort(clusters_selected)] self.clusters_selected2 = clusters_selected else: self.clusters_rel_ordered2 = self.clusters_rel self.cluster_colors_array = get_array(cluster_colors, dosort=True) self.clusters_selected2 = sorted(clusters_selected) self.nspikes, self.nsamples, self.nchannels = self.waveforms_array.shape self.npoints = self.waveforms_array.size self.geometrical_positions = geometrical_positions self.clusters_selected = clusters_selected self.clusters_unique = sorted(clusters_selected) self.nclusters = len(clusters_selected) self.waveforms = waveforms self.clusters = clusters # self.cluster_colors = cluster_colors self.masks = masks # Prepare GPU data. self.data = self.prepare_waveform_data() self.masks_full = np.repeat(self.masks_array.T.ravel(), self.nsamples) self.clusters_full = np.tile(np.repeat(self.clusters_rel_ordered2, self.nsamples), self.nchannels) self.clusters_full_depth = np.tile(np.repeat(self.clusters_rel_ordered, self.nsamples), self.nchannels) self.channels_full = np.repeat(np.arange(self.nchannels, dtype=np.int32), self.nspikes * self.nsamples) # Compute average waveforms. self.data_avg = self.prepare_average_waveform_data() self.masks_full_avg = np.repeat(self.masks_avg.T.ravel(), self.nsamples_avg) self.clusters_full_avg = np.tile(np.repeat(self.clusters_rel_ordered_avg2, self.nsamples_avg), self.nchannels_avg) self.clusters_full_depth_avg = np.tile(np.repeat(self.clusters_rel_ordered_avg, self.nsamples_avg), self.nchannels_avg) self.channels_full_avg = np.repeat(np.arange(self.nchannels_avg, dtype=np.int32), self.nspikes_avg * self.nsamples_avg) # position waveforms self.position_manager.set_info(self.nchannels, self.nclusters, geometrical_positions=self.geometrical_positions,) # update the highlight manager self.highlight_manager.initialize()
def test_select_single(): indices = [10, 20, 25] clusters = generate_clusters(indices) assert select(clusters, 10) == 1
def test_select_numpy(): indices = [10, 20, 25] clusters = generate_clusters(indices) assert np.array_equal(select(clusters, [9, 11]), [0, 0]) assert np.array_equal(select(clusters, [10, 99]), [1, 0]) assert np.array_equal(select(clusters, [20, 25, 25]), [1, 1, 1])
def set_data(self, waveforms=None, channels=None, masks=None, clusters=None, # list of clusters that are selected, the order matters clusters_selected=None, cluster_colors=None, geometrical_positions=None, keep_order=None, autozoom=None, ): self.autozoom = autozoom if clusters_selected is None: clusters_selected = [] if waveforms is None: waveforms = np.zeros((0, 1, 1)) masks = np.zeros((0, 1)) clusters = np.zeros(0, dtype=np.int32) cluster_colors = np.zeros(0, dtype=np.int32) clusters_selected = [] self.keep_order = keep_order # Not all waveforms have been selected, so select the appropriate # samples in clusters and masks. self.waveform_indices = get_indices(waveforms) self.waveform_indices_array = get_array(self.waveform_indices) masks = select(masks, self.waveform_indices) clusters = select(clusters, self.waveform_indices) # Convert from Pandas into raw NumPy arrays. self.waveforms_array = get_array(waveforms) self.masks_array = get_array(masks) self.clusters_array = get_array(clusters) # Relative indexing. if len(clusters_selected) > 0 and len(self.waveform_indices) > 0: self.clusters_rel = np.array(np.digitize(self.clusters_array, sorted(clusters_selected)) - 1, dtype=np.int32) self.clusters_rel_ordered = (np.argsort(clusters_selected) [self.clusters_rel]).astype(np.int32) else: self.clusters_rel = np.zeros(0, dtype=np.int32) self.clusters_rel_ordered = np.zeros(0, dtype=np.int32) if self.keep_order: self.clusters_rel_ordered2 = self.clusters_rel_ordered self.cluster_colors_array = get_array(cluster_colors, dosort=True)[np.argsort(clusters_selected)] self.clusters_selected2 = clusters_selected else: self.clusters_rel_ordered2 = self.clusters_rel self.cluster_colors_array = get_array(cluster_colors, dosort=True) self.clusters_selected2 = sorted(clusters_selected) self.nspikes, self.nsamples, self.nchannels = self.waveforms_array.shape if channels is None: channels = range(self.nchannels) self.channels = channels self.npoints = self.waveforms_array.size self.geometrical_positions = geometrical_positions self.clusters_selected = clusters_selected self.clusters_unique = sorted(clusters_selected) self.nclusters = len(clusters_selected) self.waveforms = waveforms self.clusters = clusters # self.cluster_colors = cluster_colors self.masks = masks # Prepare GPU data. self.data = self.prepare_waveform_data() self.masks_full = np.repeat(self.masks_array.T.ravel(), self.nsamples) self.clusters_full = np.tile(np.repeat(self.clusters_rel_ordered2, self.nsamples), self.nchannels) self.clusters_full_depth = np.tile(np.repeat(self.clusters_rel_ordered, self.nsamples), self.nchannels) self.channels_full = np.repeat(np.arange(self.nchannels, dtype=np.int32), self.nspikes * self.nsamples) # Compute average waveforms. self.data_avg = self.prepare_average_waveform_data() self.masks_full_avg = np.repeat(self.masks_avg.T.ravel(), self.nsamples_avg) self.clusters_full_avg = np.tile(np.repeat(self.clusters_rel_ordered_avg2, self.nsamples_avg), self.nchannels_avg) self.clusters_full_depth_avg = np.tile(np.repeat(self.clusters_rel_ordered_avg, self.nsamples_avg), self.nchannels_avg) self.channels_full_avg = np.repeat(np.arange(self.nchannels_avg, dtype=np.int32), self.nspikes_avg * self.nsamples_avg) # position waveforms self.position_manager.set_info(self.nchannels, self.nclusters, geometrical_positions=self.geometrical_positions,) # update the highlight manager self.highlight_manager.initialize()
def prepare_average_waveform_data(self): waveforms_avg = np.zeros((self.nclusters, self.nsamples, self.nchannels)) waveforms_std = np.zeros((self.nclusters, self.nsamples, self.nchannels)) self.masks_avg = np.zeros((self.nclusters, self.nchannels)) for i, cluster in enumerate(self.clusters_unique): spike_indices = get_spikes_in_clusters(cluster, self.clusters) w = select(self.waveforms, spike_indices) m = select(self.masks, spike_indices) waveforms_avg[i,...] = w.mean(axis=0) waveforms_std[i,...] = w.std(axis=0).mean() self.masks_avg[i,...] = m.mean(axis=0) # create X coordinates X = np.tile(np.linspace(-1., 1., self.nsamples), (self.nchannels * self.nclusters, 1)) # create Y coordinates if self.nclusters == 0: Y = np.array([], dtype=np.float32) thickness = np.array([], dtype=np.float32) else: Y = np.vstack(waveforms_avg) thickness = np.vstack(waveforms_std).T.ravel() # concatenate data data = np.empty((X.size, 2), dtype=np.float32) data[:,0] = X.ravel() data[:,1] = Y.T.ravel() if self.nclusters > 0: # thicken w = thickness.reshape((-1, 1)) n = waveforms_avg.size Y = np.zeros((2 * n, 2)) u = np.zeros((n, 2)) u[1:,0] = -np.diff(data[:,1]) u[1:,1] = data[1,0] - data[0,0] u[0,:] = u[1,:] r = (u[:,0] ** 2 + u[:,1] ** 2) ** .5 r[r == 0.] = 1 u[:,0] /= r u[:,1] /= r Y[::2,:] = data - w * u Y[1::2,:] = data + w * u data_thickened = Y else: n = 0 data_thickened = data self.nsamples_avg = self.nsamples * 2 self.npoints_avg = waveforms_avg.size * 2 self.nspikes_avg = self.nclusters self.nclusters_avg = self.nclusters self.nchannels_avg = self.nchannels self.clusters_rel_avg = np.arange(self.nclusters, dtype=np.int32) self.clusters_rel_ordered_avg = np.argsort(self.clusters_selected)[self.clusters_rel_avg] if self.keep_order: self.clusters_rel_ordered_avg2 = self.clusters_rel_ordered_avg else: self.clusters_rel_ordered_avg2 = self.clusters_rel_avg return data_thickened
def set_data(self, features=None, features_background=None, spiketimes=None, # a subset of all spikes, disregarding cluster masks=None, # masks for all spikes in selected clusters clusters=None, # clusters for all spikes in selected clusters clusters_selected=None, cluster_colors=None, fetdim=None, nchannels=None, channels=None, nextrafet=None, autozoom=None, # None, or the target cluster duration=None, freq=None, alpha_selected=.75, alpha_background=.25, time_unit=None, ): if features is None: features = np.zeros((0, 2)) features_background = np.zeros((0, 2)) masks = np.zeros((0, 1)) clusters = np.zeros(0, dtype=np.int32) clusters_selected = [] cluster_colors = np.zeros(0, dtype=np.int32) fetdim = 2 nchannels = 1 nextrafet = 0 if features.shape[1] == 1: features = np.tile(features, (1, 4)) if features_background.shape[1] == 1: features_background = np.tile(features_background, (1, 4)) assert fetdim is not None self.duration = duration self.spiketimes = spiketimes self.freq = freq self.interaction_manager.get_processor('grid').update_viewbox() # Feature background alpha value. self.alpha_selected = alpha_selected self.alpha_background = alpha_background # can be 'second' or 'samples' self.time_unit = time_unit # Extract the relevant spikes, but keep the other ones in features_full self.clusters = clusters # Contains all spikes, needed for splitting. self.features_full = features self.features_full_array = get_array(features) # Keep a subset of all spikes in the view. self.nspikes_full = len(features) # > features_nspikes_per_cluster_max spikes ==> take a selection nspikes_max = USERPREF.get('features_nspikes_per_cluster_max', 1000) k = self.nspikes_full // nspikes_max + 1 # self.features = features[::k] subsel = slice(None, None, k) self.features = select(features, subsel) self.features_array = get_array(self.features) # self.features_background contains all non-selected spikes self.features_background = features_background self.features_background_array = get_array(self.features_background) # Background spikes are those which do not belong to the selected clusters self.npoints_background = self.features_background_array.shape[0] self.nspikes_background = self.npoints_background if channels is None: channels = range(nchannels) self.nspikes, self.ndim = self.features.shape self.fetdim = fetdim self.nchannels = nchannels self.channels = channels self.nextrafet = nextrafet self.npoints = self.features.shape[0] if masks is None: masks = np.ones_like(self.features, dtype=np.float32) self.masks = masks # Subselection self.masks = select(self.masks, subsel) self.masks_array = get_array(self.masks) if self.spiketimes is not None: self.spiketimes = select(self.spiketimes, subsel) self.clusters = select(self.clusters, subsel) self.clusters_array = get_array(self.clusters) self.feature_indices = get_indices(self.features) self.feature_full_indices = get_indices(self.features_full) self.feature_indices_array = get_array(self.feature_indices) self.cluster_colors = get_array(cluster_colors, dosort=True) # Relative indexing. if self.npoints > 0: self.clusters_rel = np.digitize(self.clusters_array, sorted(clusters_selected)) - 1 self.clusters_rel_ordered = np.argsort(clusters_selected)[self.clusters_rel] else: self.clusters_rel = np.zeros(0, dtype=np.int32) self.clusters_rel_ordered = np.zeros(0, dtype=np.int32) self.clusters_unique = sorted(clusters_selected) self.nclusters = len(clusters_selected) self.masks_full = self.masks_array.T.ravel() self.clusters_full_depth = self.clusters_rel_ordered self.clusters_full = self.clusters_rel # prepare GPU data self.data = np.empty((self.nspikes, 2), dtype=np.float32) self.data_full = np.empty((self.nspikes_full, 2), dtype=np.float32) self.data_background = np.empty((self.nspikes_background, 2), dtype=np.float32) # set initial projection self.projection_manager.set_data() self.autozoom = autozoom if autozoom is None: self.projection_manager.reset_projection() else: self.projection_manager.auto_projection(autozoom) # update the highlight manager self.highlight_manager.initialize() self.selection_manager.initialize() self.selection_manager.cancel_selection()