Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Synchrotool failes to annotate spikes if spike time == spiketrain.t_stop #101

Open
jo460464 opened this issue Oct 20, 2023 · 2 comments
Assignees

Comments

@jo460464
Copy link

Describe the bug

Spiketrains can contain spikes with spiketimes <= spiketrain.t_stop. The Synchrotool can only annotate Spikes with a spike time <= spiketrain.t_stop - (0.5/sampling_rate). If the spike time is larger you get an IndexError.

To Reproduce

  1. Create a neo.spiketrain with a spike at t_stop
  2. Access the Sychrotool
  3. Use Synchrotool.annotate_synchrofacts() or Synchrotool.delete_synchrofacts()
from elephant.spike_train_synchrony import Synchrotool
import quantities as pq
import neo

sts = [neo.SpikeTrain([0., 0.5, 1.0] *pq.s, t_start=0*pq.s, t_stop=1.*pq.s),
       neo.SpikeTrain([0.1, 0.5, 0.9] *pq.s, t_start=0*pq.s, t_stop=1.*pq.s)]
synch= Synchrotool(sts, sampling_rate=30*pq.kHz)
synch.annotate_synchrofacts()

Expected behavior

Annotate all spikes with the correct complexity

Environment

  • OS: Linux, Ubuntu 22.04.3
  • How you installed elephant: conda
  • Python version: 3.12.0
  • neo python package version: 0.12.0
  • elephant python package version: 0.13.0
@Moritz-Alexander-Kern
Copy link

Hi,
thanks for the report.
I believe this is very similar to Issue NeuralEnsemble#493 .

@skrausse
Copy link

Hi, thanks for the report. I believe this is very similar to Issue NeuralEnsemble#493 .

Indeed it is, @jo460464 already found the relevant code in the complexity class, where the t_stop bin is excluded and therefore leads to a failure.

    def _epoch_no_spread(self):
        """
        Get an epoch object of the complexity distribution with `spread` = 0
        """
        left_edges = self.time_histogram.times
        durations = self.bin_size * np.ones(self.time_histogram.shape)

        if self.sampling_rate:
            # ensure that spikes are not on the bin edges
            bin_shift = .5 / self.sampling_rate
            left_edges -= bin_shift

            # Ensure that an epoch does not start before the minimum t_start.
            # Note: all spike trains share the same t_start and t_stop.
            if left_edges[0] < self.t_start:
                left_edges[0] = self.t_start
                durations[0] -= bin_shift
        else:
            warnings.warn('No sampling rate specified. '
                          'Note that using the complexity epoch to get '
                          'precise spike times can lead to rounding errors.')

        complexity = self.time_histogram.magnitude.flatten()
        complexity = complexity.astype(np.uint16)

        epoch = neo.Epoch(left_edges,
                          durations=durations,
                          array_annotations={'complexity': complexity})
        return epoch

Shifting the bins by half a sampling period leaves events at t_stop to be out of bounds.

Jonas and I will start working on a fix which we could maybe discuss next elephant meeting

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants