Пример #1
0
    def test_dither_spike_train_empty_train(self):

        st = neo.SpikeTrain([] * pq.ms, t_stop=500 * pq.ms)

        shift = 10 * pq.ms
        surrog = surr.dither_spike_train(st, shift=shift, n=1)[0]
        self.assertEqual(len(surrog), 0)
Пример #2
0
    def test_dither_spike_train_empty_train(self):

        spiketrain = neo.SpikeTrain([] * pq.ms, t_stop=500 * pq.ms)

        shift = 10 * pq.ms
        surrogate_train = surr.dither_spike_train(
            spiketrain, shift=shift, n_surrogates=1)[0]
        self.assertEqual(len(surrogate_train), 0)
Пример #3
0
    def test_dither_spike_train_output_decimals(self):
        st = neo.SpikeTrain([90, 150, 180, 350] * pq.ms, t_stop=500 * pq.ms)

        nr_surr = 2
        shift = 10 * pq.ms
        surrs = surr.dither_spike_train(st, shift=shift, n=nr_surr, decimals=3)

        for surrog in surrs:
            for i in range(len(surrog)):
                self.assertNotEqual(surrog[i] - int(surrog[i]) * pq.ms,
                                    surrog[i] - surrog[i])
Пример #4
0
    def test_dither_spike_train_false_edges(self):

        st = neo.SpikeTrain([90, 150, 180, 350] * pq.ms, t_stop=500 * pq.ms)

        nr_surr = 2
        shift = 10 * pq.ms
        surrs = surr.dither_spike_train(st, shift=shift, n=nr_surr, edges=False)

        for surrog in surrs:
            for i in range(len(surrog)):
                self.assertLessEqual(surrog[i], st.t_stop)
Пример #5
0
    def test_dither_spike_train_false_edges(self):

        spiketrain = neo.SpikeTrain(
            [90, 150, 180, 350] * pq.ms, t_stop=500 * pq.ms)

        n_surrogates = 2
        shift = 10 * pq.ms
        surrogate_trains = surr.dither_spike_train(
            spiketrain, shift=shift, n_surrogates=n_surrogates, edges=False)

        for surrogate_train in surrogate_trains:
            for i in range(len(surrogate_train)):
                self.assertLessEqual(surrogate_train[i], spiketrain.t_stop)
Пример #6
0
    def test_dither_spike_train_output_format(self):

        st = neo.SpikeTrain([90, 150, 180, 350] * pq.ms, t_stop=500 * pq.ms)

        nr_surr = 2
        shift = 10 * pq.ms
        surrs = surr.dither_spike_train(st, shift=shift, n=nr_surr)

        self.assertIsInstance(surrs, list)
        self.assertEqual(len(surrs), nr_surr)

        for surrog in surrs:
            self.assertIsInstance(surrs[0], neo.SpikeTrain)
            self.assertEqual(surrog.units, st.units)
            self.assertEqual(surrog.t_start, st.t_start)
            self.assertEqual(surrog.t_stop, st.t_stop)
            self.assertEqual(len(surrog), len(st))
Пример #7
0
    def test_dither_spike_train_output_format(self):

        spiketrain = neo.SpikeTrain(
            [90, 150, 180, 350] * pq.ms, t_stop=500 * pq.ms)

        n_surrogates = 2
        shift = 10 * pq.ms
        surrogate_trains = surr.dither_spike_train(
            spiketrain, shift=shift, n_surrogates=n_surrogates)

        self.assertIsInstance(surrogate_trains, list)
        self.assertEqual(len(surrogate_trains), n_surrogates)

        self.assertIsInstance(surrogate_trains[0], neo.SpikeTrain)
        for surrogate_train in surrogate_trains:
            self.assertEqual(surrogate_train.units, spiketrain.units)
            self.assertEqual(surrogate_train.t_start, spiketrain.t_start)
            self.assertEqual(surrogate_train.t_stop, spiketrain.t_stop)
            self.assertEqual(len(surrogate_train), len(spiketrain))
Пример #8
0
def compound_poisson_process(rate, A, t_stop, shift=None, t_start=0 * ms):
    """
    Generate a Compound Poisson Process (CPP; see [1]) with a given amplitude
    distribution A and stationary marginal rates r.

    The CPP process is a model for parallel, correlated processes with Poisson
    spiking statistics at pre-defined firing rates. It is composed of len(A)-1
    spike trains with a correlation structure determined by the amplitude
    distribution A: A[j] is the probability that a spike occurs synchronously
    in any j spike trains.

    The CPP is generated by creating a hidden mother Poisson process, and then
    copying spikes of the mother process to j of the output spike trains with
    probability A[j].

    Note that this function decorrelates the firing rate of each SpikeTrain
    from the probability for that SpikeTrain to participate in a synchronous
    event (which is uniform across SpikeTrains).

    Parameters
    ----------
    rate : quantities.Quantity
        Average rate of each spike train generated. Can be:
          - a single value, all spike trains will have same rate rate
          - an array of values (of length len(A)-1), each indicating the
            firing rate of one process in output
    A : array
        CPP's amplitude distribution. A[j] represents the probability of
        a synchronous event of size j among the generated spike trains.
        The sum over all entries of A must be equal to one.
    t_stop : quantities.Quantity
        The end time of the output spike trains.
    shift : None or quantities.Quantity, optional
        If None, the injected synchrony is exact. If shift is a Quantity, all
        the spike trains are shifted independently by a random amount in
        the interval [-shift, +shift].
        Default: None
    t_start : quantities.Quantity, optional
        The t_start time of the output spike trains.
        Default: 0 s

    Returns
    -------
    List of neo.SpikeTrains
        SpikeTrains with specified firing rates forming the CPP with amplitude
        distribution A.

    References
    ----------
    [1] Staude, Rotter, Gruen (2010) J Comput Neurosci 29:327-350.
    """
    # Check A is a probability distribution (it sums to 1 and is positive)
    if abs(sum(A) - 1) > np.finfo('float').eps:
        raise ValueError('A must be a probability vector, sum(A)= %f !=1' %
                         (sum(A)))
    if any([a < 0 for a in A]):
        raise ValueError(
            'A must be a probability vector, all the elements of must be >0')
    # Check that the rate is not an empty Quantity
    if rate.ndim == 1 and len(rate.magnitude) == 0:
        raise ValueError('Rate is an empty Quantity array')
    # Return empty spike trains for specific parameters
    elif A[0] == 1 or np.sum(np.abs(rate.magnitude)) == 0:
        return [
            SpikeTrain([] * t_stop.units, t_stop=t_stop, t_start=t_start)
            for i in range(len(A) - 1)
        ]
    else:
        # Homogeneous rates
        if rate.ndim == 0:
            cpp = _cpp_hom_stat(A=A, t_stop=t_stop, rate=rate, t_start=t_start)
        # Heterogeneous rates
        else:
            cpp = _cpp_het_stat(A=A, t_stop=t_stop, rate=rate, t_start=t_start)

        if shift is None:
            return cpp
        # Dither the output spiketrains
        else:
            cpp = [
                dither_spike_train(cp, shift=shift, edges=True)[0]
                for cp in cpp
            ]
            return cpp
Пример #9
0
def compound_poisson_process(rate, A, t_stop, shift=None, t_start=0 * ms):
    """
    Generate a Compound Poisson Process (CPP; see [1]) with a given amplitude
    distribution A and stationary marginal rates r.

    The CPP process is a model for parallel, correlated processes with Poisson
    spiking statistics at pre-defined firing rates. It is composed of len(A)-1
    spike trains with a correlation structure determined by the amplitude
    distribution A: A[j] is the probability that a spike occurs synchronously
    in any j spike trains.

    The CPP is generated by creating a hidden mother Poisson process, and then
    copying spikes of the mother process to j of the output spike trains with
    probability A[j].

    Note that this function decorrelates the firing rate of each SpikeTrain
    from the probability for that SpikeTrain to participate in a synchronous
    event (which is uniform across SpikeTrains).

    Parameters
    ----------
    rate : quantities.Quantity
        Average rate of each spike train generated. Can be:
          - a single value, all spike trains will have same rate rate
          - an array of values (of length len(A)-1), each indicating the
            firing rate of one process in output
    A : array
        CPP's amplitude distribution. A[j] represents the probability of
        a synchronous event of size j among the generated spike trains.
        The sum over all entries of A must be equal to one.
    t_stop : quantities.Quantity
        The end time of the output spike trains.
    shift : None or quantities.Quantity, optional
        If None, the injected synchrony is exact. If shift is a Quantity, all
        the spike trains are shifted independently by a random amount in
        the interval [-shift, +shift].
        Default: None
    t_start : quantities.Quantity, optional
        The t_start time of the output spike trains.
        Default: 0 s

    Returns
    -------
    List of neo.SpikeTrains
        SpikeTrains with specified firing rates forming the CPP with amplitude
        distribution A.

    References
    ----------
    [1] Staude, Rotter, Gruen (2010) J Comput Neurosci 29:327-350.
    """
    # Check A is a probability distribution (it sums to 1 and is positive)
    if abs(sum(A) - 1) > np.finfo('float').eps:
        raise ValueError(
            'A must be a probability vector, sum(A)= %f !=1' % (sum(A)))
    if any([a < 0 for a in A]):
        raise ValueError(
            'A must be a probability vector, all the elements of must be >0')
    # Check that the rate is not an empty Quantity
    if rate.ndim == 1 and len(rate.magnitude) == 0:
        raise ValueError('Rate is an empty Quantity array')
    # Return empty spike trains for specific parameters
    elif A[0] == 1 or np.sum(np.abs(rate.magnitude)) == 0:
        return [
            SpikeTrain([] * t_stop.units, t_stop=t_stop,
                       t_start=t_start) for i in range(len(A) - 1)]
    else:
        # Homogeneous rates
        if rate.ndim == 0:
            cpp = _cpp_hom_stat(A=A, t_stop=t_stop, rate=rate, t_start=t_start)
        # Heterogeneous rates
        else:
            cpp = _cpp_het_stat(A=A, t_stop=t_stop, rate=rate, t_start=t_start)

        if shift is None:
            return cpp
        # Dither the output spiketrains
        else:
            cpp = [
                dither_spike_train(cp, shift=shift, edges=True)[0]
                for cp in cpp]
            return cpp