code: def _do_assign(self, spike_ids, new_spike_clusters):
          
  
          # Ensure spike_clusters has the right shape.
          spike_ids = _as_array(spike_ids)
          if len(new_spike_clusters) == 1 and len(spike_ids) > 1:
              new_spike_clusters = (np.ones(len(spike_ids), dtype=np.int64) *
                                    new_spike_clusters[0])
          old_spike_clusters = self._spike_clusters[spike_ids]
  
          assert len(spike_ids) == len(old_spike_clusters)
          assert len(new_spike_clusters) == len(spike_ids)
  
          # Update the spikes per cluster structure.
          old_clusters = _unique(old_spike_clusters)
  
          # NOTE: shortcut to a merge if this assignment is effectively a merge
          # i.e. if all spikes are assigned to a single cluster.
          # The fact that spike selection has been previously extended to
          # whole clusters is critical here.
          new_clusters = _unique(new_spike_clusters)
          if len(new_clusters) == 1:
              return self._do_merge(spike_ids, old_clusters, new_clusters[0])
  
          # We return the UpdateInfo structure.
          up = _assign_update_info(spike_ids,
                                   old_spike_clusters,
                                   new_spike_clusters)
  
          # We update the new cluster id (strictly increasing during a session).
          self._new_cluster_id = max(self._new_cluster_id, max(up.added) + 1)
  
          # We make the assignments.
          self._spike_clusters[spike_ids] = new_spike_clusters
          # OPTIM: we update spikes_per_cluster manually.
          new_spc = _spikes_per_cluster(new_spike_clusters, spike_ids)
          self._update_cluster_ids(to_remove=old_clusters, to_add=new_spc)
          return up
docs: Make spike-cluster assignments after the spike selection has
          been extended to full clusters.