def test_recompute_correlation(): l, c = load() clusters_unique = l.get_clusters_unique() # Select three clusters clusters_selected = [2, 4, 6] spikes = l.get_spikes(clusters=clusters_selected) # cluster_spikes = l.get_clusters(clusters=clusters_selected) # Select half of the spikes in these clusters. spikes_sample = spikes[::2] # Get the correlation matrix parameters. features = get_array(l.get_features('all')) masks = get_array(l.get_masks('all', full=True)) clusters0 = get_array(l.get_clusters('all')) clusters_all = l.get_clusters_unique() similarity_matrix = CacheMatrix() correlations0 = compute_correlations(features, clusters0, masks) similarity_matrix.update(clusters_unique, correlations0) matrix0 = normalize(similarity_matrix.to_array().copy()) # Merge these clusters. action, output = c.merge_clusters(clusters_selected) cluster_new = output['cluster_merged'] # Compute the new matrix similarity_matrix.invalidate([2, 4, 6, cluster_new]) clusters1 = get_array(l.get_clusters('all')) correlations1 = compute_correlations(features, clusters1, masks,#) [cluster_new]) similarity_matrix.update([cluster_new], correlations1) matrix1 = normalize(similarity_matrix.to_array().copy()) # Undo. assert c.can_undo() action, output = c.undo() # Compute the new matrix similarity_matrix.invalidate([2, 4, 6, cluster_new]) clusters2 = get_array(l.get_clusters('all')) correlations2 = compute_correlations(features, clusters2, masks,) correlations2b = compute_correlations(features, clusters2, masks,#) clusters_selected) for (clu0, clu1) in correlations2b.keys(): assert np.allclose(correlations2[clu0, clu1], correlations2b[clu0, clu1]), (clu0, clu1, correlations2[clu0, clu1], correlations2b[clu0, clu1]) similarity_matrix.update(clusters_selected, correlations2b) matrix2 = normalize(similarity_matrix.to_array().copy()) assert np.array_equal(clusters0, clusters2) # assert np.allclose(matrix0, matrix2) l.close()
def _compute_correlograms(self, clusters_selected): # Get the correlograms parameters. spiketimes = get_array(self.loader.get_spiketimes('all')) # Make a copy of the array so that it does not change before the # computation of the correlograms begins. clusters = np.array(get_array(self.loader.get_clusters('all'))) # corrbin = self.loader.corrbin # ncorrbins = self.loader.ncorrbins corrbin = SETTINGS.get('correlograms.corrbin', .001) ncorrbins = SETTINGS.get('correlograms.ncorrbins', 100) # Get cluster indices that need to be updated. clusters_to_update = ( self.statscache.correlograms.not_in_key_indices(clusters_selected)) # If there are pairs that need to be updated, launch the task. if len(clusters_to_update) > 0: # Set wait cursor. self.mainwindow.set_busy(computing_correlograms=True) # Launch the task. self.tasks.correlograms_task.compute( spiketimes, clusters, clusters_to_update=clusters_to_update, clusters_selected=clusters_selected, ncorrbins=ncorrbins, corrbin=corrbin) # Otherwise, update directly the correlograms view without launching # the task in the external process. else: # self.update_correlograms_view() return '_update_correlograms_view'
def split_clusters(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) # Get group and color of the new clusters, from the old clusters. groups = self.loader.get_cluster_groups(cluster_indices_old) # colors = self.loader.get_cluster_colors(cluster_indices_old) # Add clusters. self.loader.add_clusters(cluster_indices_new, # HACK: take the group of the first cluster for all new clusters get_array(groups)[0]*np.ones(len(cluster_indices_new)), random_color(len(cluster_indices_new))) # Set the new clusters to the corresponding spikes. self.loader.set_cluster(spikes, clusters_new) # Remove empty clusters. clusters_empty = self.loader.remove_empty_clusters() self.loader.unselect() clusters_to_select = sorted(set(cluster_indices_old).union( set(cluster_indices_new)) - set(clusters_empty)) return dict(clusters_to_split=clusters, clusters_split=get_array(cluster_indices_new), clusters_empty=clusters_empty)
def _compute_correlograms(self, clusters_selected): # Get the correlograms parameters. spiketimes = get_array(self.loader.get_spiketimes('all')) # Make a copy of the array so that it does not change before the # computation of the correlograms begins. clusters = np.array(get_array(self.loader.get_clusters('all'))) # corrbin = self.loader.corrbin # ncorrbins = self.loader.ncorrbins corrbin = SETTINGS.get('correlograms.corrbin', .001) ncorrbins = SETTINGS.get('correlograms.ncorrbins', 100) # Get cluster indices that need to be updated. clusters_to_update = (self.statscache.correlograms. not_in_key_indices(clusters_selected)) # If there are pairs that need to be updated, launch the task. if len(clusters_to_update) > 0: # Set wait cursor. self.mainwindow.set_busy(computing_correlograms=True) # Launch the task. self.tasks.correlograms_task.compute(spiketimes, clusters, clusters_to_update=clusters_to_update, clusters_selected=clusters_selected, ncorrbins=ncorrbins, corrbin=corrbin) # Otherwise, update directly the correlograms view without launching # the task in the external process. else: # self.update_correlograms_view() return '_update_correlograms_view'
def split_clusters(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) # Get group and color of the new clusters, from the old clusters. groups = self.loader.get_cluster_groups(cluster_indices_old) # colors = self.loader.get_cluster_colors(cluster_indices_old) # Add clusters. self.loader.add_clusters(cluster_indices_new, # HACK: take the group of the first cluster for all new clusters get_array(groups)[0]*np.ones(len(cluster_indices_new)), ) # Set the new clusters to the corresponding spikes. self.loader.set_cluster(spikes, clusters_new) # Remove empty clusters. clusters_empty = self.loader.remove_empty_clusters() self.loader.unselect() clusters_to_select = sorted(set(cluster_indices_old).union( set(cluster_indices_new)) - set(clusters_empty)) return dict(clusters_to_split=clusters, clusters_split=get_array(cluster_indices_new), clusters_empty=clusters_empty)
def _compute_similarity_matrix(self, target_next=None): similarity_measure = self.loader.similarity_measure features = self.loader.background_features masks = self.loader.background_masks clusters = get_array(self.loader.get_clusters( spikes=self.loader.background_spikes)) cluster_groups = get_array(self.loader.get_cluster_groups('all')) clusters_all = self.loader.get_clusters_unique() # Get cluster indices that need to be updated. # if clusters_to_update is None: # NOTE: not specifying explicitely clusters_to_update ensures that # all clusters that need to be updated are updated. # Allows to fix a bug where the matrix is not updated correctly # when multiple calls to this functions are called quickly. clusters_to_update = (self.statscache.similarity_matrix. not_in_key_indices(clusters_all)) log.debug("Clusters to update: {0:s}".format(str(clusters_to_update))) # If there are pairs that need to be updated, launch the task. if len(clusters_to_update) > 0: self.mainwindow.set_busy(computing_matrix=True) # Launch the task. self.tasks.similarity_matrix_task.compute(features, clusters, cluster_groups, masks, clusters_to_update, target_next=target_next, similarity_measure=similarity_measure) # Otherwise, update directly the correlograms view without launching # the task in the external process. else: return [('_wizard_update', (target_next,)), ('_update_similarity_matrix_view',), ]
def compute_done(self, features, clusters, cluster_groups, masks, clusters_selected, target_next=None, similarity_measure=None, _result=None): correlations = _result self.correlationMatrixComputed.emit(np.array(clusters_selected), correlations, get_array(clusters, copy=True), get_array(cluster_groups, copy=True), target_next)
def set_data(self, cluster_groups=None, similarity_matrix=None): """Update the data.""" if cluster_groups is not None: self.clusters_unique = get_array(get_indices(cluster_groups)) self.cluster_groups = get_array(cluster_groups) if (similarity_matrix is not None and similarity_matrix.size > 0): self.matrix = similarity_matrix self.quality = np.diag(self.matrix) assert len(self.cluster_groups) == self.matrix.shape[0]
def features_spikes_selected_callback(self, spikes): self.spikes_selected = spikes self.update_action_enabled() [ view.highlight_spikes(get_array(spikes)) for view in self.get_views('WaveformView') ]
def split2_clusters(self, spikes, clusters): # clusters is new # Old clusters for all spikes to split. clusters_old = self.loader.get_clusters(spikes=spikes) # assert np.all(np.in1d(clusters_old, clusters)) # Old cluster indices. cluster_indices_old = np.unique(clusters_old) nclusters = len(cluster_indices_old) # Renumber output of klustakwik. clu_idx = np.unique(clusters) nclusters_new = len(clu_idx) # Get new clusters indices. clusters_indices_new = self.loader.get_new_clusters(nclusters_new) clu_renumber = np.zeros(clu_idx.max() + 1, dtype=np.int32) clu_renumber[clu_idx] = clusters_indices_new clusters_new = clu_renumber[clusters] cluster_groups = self.loader.get_cluster_groups(cluster_indices_old) cluster_colors = self.loader.get_cluster_colors(cluster_indices_old) return self._process('split_clusters', get_array(cluster_indices_old), clusters_old, cluster_groups, cluster_colors, clusters_new, _description='Split2')
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 set_data(self, cluster_groups=None, similarity_matrix=None): """Update the data.""" if cluster_groups is not None: self.clusters_unique = get_array(get_indices(cluster_groups)) self.cluster_groups = get_array(cluster_groups) if (similarity_matrix is not None and similarity_matrix.size > 0): if len(get_array(cluster_groups)) != similarity_matrix.shape[0]: log.warn(("Cannot update the wizard: cluster_groups " "has {0:d} elements whereas the similarity matrix has {1:d}.").format( len(get_array(cluster_groups)), similarity_matrix.shape[0])) return self.matrix = similarity_matrix self.quality = np.diag(self.matrix)
def set_data(self, cluster_groups=None, similarity_matrix=None): """Update the data.""" if cluster_groups is not None: self.clusters_unique = get_array(get_indices(cluster_groups)) self.cluster_groups = get_array(cluster_groups) if (similarity_matrix is not None and similarity_matrix.size > 0): if len(get_array(cluster_groups)) != similarity_matrix.shape[0]: log.warn(( "Cannot update the wizard: cluster_groups " "has {0:d} elements whereas the similarity matrix has {1:d}." ).format(len(get_array(cluster_groups)), similarity_matrix.shape[0])) return self.matrix = similarity_matrix self.quality = np.diag(self.matrix)
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 _compute_similarity_matrix(self, target_next=None): similarity_measure = self.loader.similarity_measure features = self.loader.background_features masks = self.loader.background_masks clusters = get_array( self.loader.get_clusters(spikes=self.loader.background_spikes)) cluster_groups = get_array(self.loader.get_cluster_groups('all')) clusters_all = self.loader.get_clusters_unique() # Get cluster indices that need to be updated. # if clusters_to_update is None: # NOTE: not specifying explicitely clusters_to_update ensures that # all clusters that need to be updated are updated. # Allows to fix a bug where the matrix is not updated correctly # when multiple calls to this functions are called quickly. clusters_to_update = ( self.statscache.similarity_matrix.not_in_key_indices(clusters_all)) log.debug("Clusters to update: {0:s}".format(str(clusters_to_update))) # If there are pairs that need to be updated, launch the task. if len(clusters_to_update) > 0: self.mainwindow.set_busy(computing_matrix=True) # Launch the task. self.tasks.similarity_matrix_task.compute( features, clusters, cluster_groups, masks, clusters_to_update, target_next=target_next, similarity_measure=similarity_measure) # Otherwise, update directly the correlograms view without launching # the task in the external process. else: return [ ('_wizard_update', (target_next, )), ('_update_similarity_matrix_view', ), ]
def merge_clusters(self, clusters_old, cluster_groups, cluster_colors, cluster_merged): # Get spikes in clusters to merge. # spikes = self.loader.get_spikes(clusters=clusters_to_merge) spikes = get_indices(clusters_old) clusters_to_merge = get_indices(cluster_groups) group = np.max(get_array(cluster_groups)) # color_old = get_array(cluster_colors)[0] color_new = random_color() self.loader.add_cluster(cluster_merged, group, color_new) # Set the new cluster to the corresponding spikes. self.loader.set_cluster(spikes, cluster_merged) # Remove old clusters. for cluster in clusters_to_merge: self.loader.remove_cluster(cluster) self.loader.unselect() return dict(clusters_to_merge=clusters_to_merge, cluster_merged=cluster_merged, cluster_merged_colors=(color_new, color_new),)
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()
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 features_spikes_highlighted_callback(self, spikes): self.spikes_highlighted = spikes [view.highlight_spikes(get_array(spikes)) for view in self.get_views('WaveformView')]
def features_spikes_selected_callback(self, spikes): self.spikes_selected = spikes self.update_action_enabled() [view.highlight_spikes(get_array(spikes)) for view in self.get_views('WaveformView')]
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, 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 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 # # Indices of all subset spikes. # indices_all = get_indices(features) # # Select only the clusters for subset of spikes. # clusters = select(clusters, indices_all) # # Indices of subset spikes in selected clusters. # indices_selection = get_indices(clusters) # # Indices of subset spikes that are not in selected clusters. # indices_background = np.setdiff1d(indices_all, indices_selection, True) # Extract the relevant spikes, but keep the other ones in features_full self.clusters = clusters self.clusters_array = get_array(self.clusters) # self.features contains selected spikes. # self.features = select(features, indices_selection) self.features = features self.features_array = get_array(self.features) # self.features_background contains all non-selected spikes # self.features_background = select(features, indices_background) 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 self.nspikes, self.ndim = self.features.shape self.fetdim = fetdim self.nchannels = nchannels self.nextrafet = nextrafet self.npoints = self.features.shape[0] self.masks = masks self.feature_indices = get_indices(self.features) self.feature_indices_array = get_array(self.feature_indices) self.masks_array = get_array(self.masks) 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_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()
def set_data(self, correlograms=None, cluster_colors=None, baselines=None, clusters_selected=None, ncorrbins=None, corrbin=None, keep_order=None, normalization='row'): if correlograms is None: correlograms = IndexedMatrix(shape=(0, 0, 0)) baselines = np.zeros(0) cluster_colors = np.zeros(0) clusters_selected = [] ncorrbins = 0 corrbin = 0 self.keep_order = keep_order # self.correlograms_array = get_correlograms_array(correlograms, # clusters_selected=clusters_selected, ncorrbins=ncorrbins) self.correlograms = correlograms # Copy the original arrays for normalization. self.baselines = baselines self.baselines0 = baselines.copy() self.correlograms_array = correlograms.to_array() self.correlograms_array0 = self.correlograms_array.copy() nclusters, nclusters, self.nbins = self.correlograms_array.shape self.ncorrelograms = nclusters * nclusters self.nticks = (ncorrbins + 1) * self.ncorrelograms self.ncorrbins = ncorrbins self.corrbin = corrbin self.clusters_selected = np.array(clusters_selected, dtype=np.int32) self.clusters_unique = np.array(sorted(clusters_selected), dtype=np.int32) self.nclusters = len(clusters_selected) assert nclusters == self.nclusters self.cluster_colors = cluster_colors self.cluster_colors_array = get_array(cluster_colors, dosort=True) if keep_order: self.permutation = np.argsort(clusters_selected) else: self.permutation = np.arange(self.nclusters) self.cluster_colors_array_ordered = self.cluster_colors_array[ self.permutation] # HACK: if correlograms is empty, ncorrelograms == 1 here! if self.correlograms_array.size == 0: self.ncorrelograms = 0 # cluster i and j for each histogram in the view clusters = [(i, j) for j in self.permutation for i in self.permutation] self.clusters = np.array(clusters, dtype=np.int32) self.clusters0 = self.clusters # baselines of the correlograms self.nprimitives = self.ncorrelograms # index 0 = heterogeneous clusters, index>0 ==> cluster index + 1 # self.cluster_colors = get_array(cluster_colors) # normalize and update the data position self.normalize(normalization) # indices of correlograms on the diagonal if self.nclusters: identity = self.clusters[:, 0] == self.clusters[:, 1] else: identity = [] color_array_index = np.zeros(self.ncorrelograms, dtype=np.int32) color_array_index[identity] = np.array(self.cluster_colors_array + 1, dtype=np.int32) # very first color in color map = white (cross-correlograms) self.color = np.vstack((np.ones((1, 3)), COLORMAP)) self.color_array_index = color_array_index self.clusters = np.repeat(self.clusters, self.nsamples, axis=0) self.color_array_index = np.repeat(self.color_array_index, self.nsamples, axis=0)
def test_recompute_correlation(): l, c = load() clusters_unique = l.get_clusters_unique() # Select three clusters clusters_selected = [2, 4, 6] spikes = l.get_spikes(clusters=clusters_selected) # cluster_spikes = l.get_clusters(clusters=clusters_selected) # Select half of the spikes in these clusters. spikes_sample = spikes[::2] # Get the correlation matrix parameters. features = get_array(l.get_features('all')) masks = get_array(l.get_masks('all', full=True)) clusters0 = get_array(l.get_clusters('all')) clusters_all = l.get_clusters_unique() similarity_matrix = CacheMatrix() correlations0 = compute_correlations(features, clusters0, masks) similarity_matrix.update(clusters_unique, correlations0) matrix0 = normalize(similarity_matrix.to_array().copy()) # Merge these clusters. action, output = c.merge_clusters(clusters_selected) cluster_new = output['cluster_merged'] # Compute the new matrix similarity_matrix.invalidate([2, 4, 6, cluster_new]) clusters1 = get_array(l.get_clusters('all')) correlations1 = compute_correlations( features, clusters1, masks, #) [cluster_new]) similarity_matrix.update([cluster_new], correlations1) matrix1 = normalize(similarity_matrix.to_array().copy()) # Undo. assert c.can_undo() action, output = c.undo() # Compute the new matrix similarity_matrix.invalidate([2, 4, 6, cluster_new]) clusters2 = get_array(l.get_clusters('all')) correlations2 = compute_correlations( features, clusters2, masks, ) correlations2b = compute_correlations( features, clusters2, masks, #) clusters_selected) for (clu0, clu1) in correlations2b.keys(): assert np.allclose(correlations2[clu0, clu1], correlations2b[clu0, clu1]), (clu0, clu1, correlations2[clu0, clu1], correlations2b[clu0, clu1]) similarity_matrix.update(clusters_selected, correlations2b) matrix2 = normalize(similarity_matrix.to_array().copy()) assert np.array_equal(clusters0, clusters2) assert np.allclose(matrix0, matrix2) l.close()
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 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, 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 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 # # Indices of all subset spikes. # indices_all = get_indices(features) # # Select only the clusters for subset of spikes. # clusters = select(clusters, indices_all) # # Indices of subset spikes in selected clusters. # indices_selection = get_indices(clusters) # # Indices of subset spikes that are not in selected clusters. # indices_background = np.setdiff1d(indices_all, indices_selection, True) # Extract the relevant spikes, but keep the other ones in features_full self.clusters = clusters self.clusters_array = get_array(self.clusters) # self.features contains selected spikes. # self.features = select(features, indices_selection) self.features = features self.features_array = get_array(self.features) # self.features_background contains all non-selected spikes # self.features_background = select(features, indices_background) 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 self.nspikes, self.ndim = self.features.shape self.fetdim = fetdim self.nchannels = nchannels self.nextrafet = nextrafet self.npoints = self.features.shape[0] self.masks = masks self.feature_indices = get_indices(self.features) self.feature_indices_array = get_array(self.feature_indices) self.masks_array = get_array(self.masks) 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_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()
def set_data(self, correlograms=None, cluster_colors=None, baselines=None, clusters_selected=None, ncorrbins=None, corrbin=None, keep_order=None, normalization='row'): if correlograms is None: correlograms = IndexedMatrix(shape=(0, 0, 0)) baselines = np.zeros(0) cluster_colors = np.zeros(0) clusters_selected = [] ncorrbins = 0 corrbin = 0 self.keep_order = keep_order # self.correlograms_array = get_correlograms_array(correlograms, # clusters_selected=clusters_selected, ncorrbins=ncorrbins) self.correlograms = correlograms # Copy the original arrays for normalization. self.baselines = baselines self.baselines0 = baselines.copy() self.correlograms_array = correlograms.to_array() self.correlograms_array0 = self.correlograms_array.copy() nclusters, nclusters, self.nbins = self.correlograms_array.shape self.ncorrelograms = nclusters * nclusters self.nticks = (ncorrbins + 1) * self.ncorrelograms self.ncorrbins = ncorrbins self.corrbin = corrbin self.clusters_selected = np.array(clusters_selected, dtype=np.int32) self.clusters_unique = np.array(sorted(clusters_selected), dtype=np.int32) self.nclusters = len(clusters_selected) assert nclusters == self.nclusters self.cluster_colors = cluster_colors self.cluster_colors_array = get_array(cluster_colors, dosort=True) if keep_order: self.permutation = np.argsort(clusters_selected) else: self.permutation = np.arange(self.nclusters) self.cluster_colors_array_ordered = self.cluster_colors_array[self.permutation] # HACK: if correlograms is empty, ncorrelograms == 1 here! if self.correlograms_array.size == 0: self.ncorrelograms = 0 # cluster i and j for each histogram in the view clusters = [(i,j) for j in self.permutation for i in self.permutation] self.clusters = np.array(clusters, dtype=np.int32) self.clusters0 = self.clusters # baselines of the correlograms self.nprimitives = self.ncorrelograms # index 0 = heterogeneous clusters, index>0 ==> cluster index + 1 # self.cluster_colors = get_array(cluster_colors) # normalize and update the data position self.normalize(normalization) # indices of correlograms on the diagonal if self.nclusters: identity = self.clusters[:,0] == self.clusters[:,1] else: identity = [] color_array_index = np.zeros(self.ncorrelograms, dtype=np.int32) color_array_index[identity] = np.array(self.cluster_colors_array + 1, dtype=np.int32) # very first color in color map = white (cross-correlograms) self.color = np.vstack((np.ones((1, 3)), COLORMAP)) self.color_array_index = color_array_index self.clusters = np.repeat(self.clusters, self.nsamples, axis=0) self.color_array_index = np.repeat(self.color_array_index, self.nsamples, axis=0)
def features_spikes_highlighted_callback(self, spikes): self.spikes_highlighted = spikes [ view.highlight_spikes(get_array(spikes)) for view in self.get_views('WaveformView') ]