def cluster(self, clustering=None, algorithm='klustakwik', spike_ids=None, channel_group=None, **kwargs): """Run an automatic clustering algorithm on all or some of the spikes. Parameters ---------- clustering : str The name of the clustering in which to save the results. algorithm : str The algorithm name. Only `klustakwik` currently. spike_ids : array-like Array of spikes to cluster. Returns ------- spike_clusters : array The spike_clusters assignements returned by the algorithm. """ if clustering is None: clustering = 'main' if channel_group is not None: self.change_channel_group(channel_group) kk2_dir = op.join(self.settings.exp_settings_dir, 'klustakwik2') _ensure_dir_exists(kk2_dir) # Take KK2's default parameters. from klustakwik2.default_parameters import default_parameters params = default_parameters.copy() # Update the PRM ones, by filtering them. params.update({ k: v for k, v in self.model.metadata.items() if k in default_parameters }) # Update the ones passed to the function. params.update(kwargs) # Original spike_clusters array. if self.model.spike_clusters is None: n_spikes = (len(spike_ids) if spike_ids is not None else self.model.n_spikes) spike_clusters_orig = np.zeros(n_spikes, dtype=np.int32) else: spike_clusters_orig = self.model.spike_clusters.copy() # HACK: there needs to be one clustering. if 'empty' not in self.model.clusterings: self.model.add_clustering('empty', spike_clusters_orig) # Instantiate the KlustaKwik instance. kk = KlustaKwik(**params) # Save the current clustering in the Kwik file. @kk.connect def on_iter(sc): # Update the original spike clusters. spike_clusters = spike_clusters_orig.copy() spike_clusters[spike_ids] = sc # Save to a text file. path = op.join(kk2_dir, 'spike_clusters.txt') # Backup. if op.exists(path): shutil.copy(path, path + '~') np.savetxt(path, spike_clusters, fmt='%d') info("Running {}...".format(algorithm)) # Run KK. sc = kk.cluster(model=self.model, spike_ids=spike_ids) info("The automatic clustering process has finished.") # Save the results in the Kwik file. spike_clusters = spike_clusters_orig.copy() spike_clusters[spike_ids] = sc # Add a new clustering and switch to it. if clustering in self.model.clusterings: self.change_clustering('empty') self.model.delete_clustering(clustering) self.model.add_clustering(clustering, spike_clusters) # Copy the main clustering to original (only if this is the very # first run of the clustering algorithm). if clustering == 'main': self.model.copy_clustering('main', 'original') self.change_clustering(clustering) # Set the new clustering metadata. params = kk.params params['version'] = kk.version metadata = { '{}_{}'.format(algorithm, name): value for name, value in params.items() } self.model.clustering_metadata.update(metadata) self.save() info("The clustering has been saved in the " "`{}` clustering in the `.kwik` file.".format(clustering)) self.model.delete_clustering('empty') return sc
def cluster(self, clustering=None, algorithm='klustakwik', spike_ids=None, **kwargs): """Run an automatic clustering algorithm on all or some of the spikes. Parameters ---------- clustering : str The name of the clustering in which to save the results. algorithm : str The algorithm name. Only `klustakwik` currently. spike_ids : array-like Array of spikes to cluster. Returns ------- spike_clusters : array The spike_clusters assignements returned by the algorithm. """ if clustering is None: clustering = 'main' # Make sure the clustering name does not exist already. if clustering in self.model.clusterings: raise ValueError("The clustering `{}` ".format(clustering) + "already exists.") # Take KK2's default parameters. from klustakwik2.default_parameters import default_parameters params = default_parameters.copy() # Update the PRM ones, by filtering them. params.update({k: v for k, v in self.model.metadata.items() if k in default_parameters}) # Update the ones passed to the function. params.update(kwargs) # Original spike_clusters array. if self.model.spike_clusters is None: n_spikes = (len(spike_ids) if spike_ids is not None else self.model.n_spikes) spike_clusters_orig = np.zeros(n_spikes, dtype=np.int32) else: spike_clusters_orig = self.model.spike_clusters.copy() # HACK: there needs to be one clustering. if not self.model.clusterings: self.model.add_clustering('empty', spike_clusters_orig) # Instantiate the KlustaKwik instance. kk = KlustaKwik(**kwargs) # Save the current clustering in the Kwik file. @kk.connect def on_iter(sc): # Update the original spike clusters. spike_clusters = spike_clusters_orig.copy() spike_clusters[spike_ids] = sc # Replace the kk2_current clustering. if 'kk2_current' in self.model.clusterings: self.model.delete_clustering('kk2_current') self.model.add_clustering('kk2_current', spike_clusters) info("Updated `kk2_current` clustering in the `.kwik` file.") info("Running {}...".format(algorithm)) # Run KK. sc = kk.cluster(model=self.model, spike_ids=spike_ids) info("The automatic clustering process has finished.") # Save the results in the Kwik file. spike_clusters = spike_clusters_orig.copy() spike_clusters[spike_ids] = sc # Add a new clustering and switch to it. self.model.add_clustering(clustering, spike_clusters) # Copy the main clustering to original (only if this is the very # first run of the clustering algorithm). if clustering == 'main': self.model.copy_clustering('main', 'original') self.change_clustering(clustering) # Set the new clustering metadata. params = kk.params params['version'] = kk.version metadata = {'{}_{}'.format(algorithm, name): value for name, value in params.items()} self.model.clustering_metadata.update(metadata) self.save() info("The clustering has been saved in the " "`{}` clustering in the `.kwik` file.".format(clustering)) return sc
def cluster(self, clustering=None, algorithm='klustakwik', spike_ids=None, channel_group=None, **kwargs): """Run an automatic clustering algorithm on all or some of the spikes. Parameters ---------- clustering : str The name of the clustering in which to save the results. algorithm : str The algorithm name. Only `klustakwik` currently. spike_ids : array-like Array of spikes to cluster. Returns ------- spike_clusters : array The spike_clusters assignements returned by the algorithm. """ if clustering is None: clustering = 'main' if channel_group is not None: self.change_channel_group(channel_group) kk2_dir = op.join(self.settings.exp_settings_dir, 'klustakwik2') _ensure_dir_exists(kk2_dir) # Take KK2's default parameters. from klustakwik2.default_parameters import default_parameters params = default_parameters.copy() # Update the PRM ones, by filtering them. params.update({k: v for k, v in self.model.metadata.items() if k in default_parameters}) # Update the ones passed to the function. params.update(kwargs) # Original spike_clusters array. if self.model.spike_clusters is None: n_spikes = (len(spike_ids) if spike_ids is not None else self.model.n_spikes) spike_clusters_orig = np.zeros(n_spikes, dtype=np.int32) else: spike_clusters_orig = self.model.spike_clusters.copy() # HACK: there needs to be one clustering. if 'empty' not in self.model.clusterings: self.model.add_clustering('empty', spike_clusters_orig) # Instantiate the KlustaKwik instance. kk = KlustaKwik(**params) # Save the current clustering in the Kwik file. @kk.connect def on_iter(sc): # Update the original spike clusters. spike_clusters = spike_clusters_orig.copy() spike_clusters[spike_ids] = sc # Save to a text file. path = op.join(kk2_dir, 'spike_clusters.txt') # Backup. if op.exists(path): shutil.copy(path, path + '~') np.savetxt(path, spike_clusters, fmt='%d') info("Running {}...".format(algorithm)) # Run KK. sc = kk.cluster(model=self.model, spike_ids=spike_ids) info("The automatic clustering process has finished.") # Save the results in the Kwik file. spike_clusters = spike_clusters_orig.copy() spike_clusters[spike_ids] = sc # Add a new clustering and switch to it. if clustering in self.model.clusterings: self.change_clustering('empty') self.model.delete_clustering(clustering) self.model.add_clustering(clustering, spike_clusters) # Copy the main clustering to original (only if this is the very # first run of the clustering algorithm). if clustering == 'main': self.model.copy_clustering('main', 'original') self.change_clustering(clustering) # Set the new clustering metadata. params = kk.params params['version'] = kk.version metadata = {'{}_{}'.format(algorithm, name): value for name, value in params.items()} self.model.clustering_metadata.update(metadata) self.save() info("The clustering has been saved in the " "`{}` clustering in the `.kwik` file.".format(clustering)) self.model.delete_clustering('empty') return sc