Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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