Пример #1
0
def concatenate_spike_trains(trains):
    """ Concatenates spike trains.

    :param sequence trains: :class:`neo.core.SpikeTrain` objects to
        concatenate.
    :returns: A spike train consisting of the concatenated spike trains. The
        spikes will be in the order of the given spike trains and ``t_start``
        and ``t_stop`` will be set to the minimum and maximum value.
    :rtype: :class:`neo.core.SpikeTrain`
    """

    t_start, t_stop = maximum_spike_train_interval({0: trains})
    return neo.SpikeTrain(
        spq.concatenate([train.view(type=pq.Quantity) for train in trains]),
        t_start=t_start, t_stop=t_stop)
def event_synchronization(
        trains, tau=None,
        kernel=sigproc.RectangularKernel(1.0, normalize=False), sort=True):
    """ event_synchronization(trains, tau=None, kernel=signal_processing.RectangularKernel(1.0, normalize=False), sort=True)

    Calculates the event synchronization.

    Let :math:`d(x|y)` be the count of spikes in :math:`y` which occur shortly
    before an event in :math:`x` with a time difference of less than
    :math:`\\tau`. Moreover, let :math:`n_x` and :math:`n_y` be the number of
    total spikes in the spike trains :math:`x` and :math:`y`. The event
    synchrony is then defined as :math:`Q_T = \\frac{d(x|y)
    + d(y|x)}{\\sqrt{n_x n_y}}`.

    The time maximum time lag :math:`\\tau` can be determined automatically for
    each pair of spikes :math:`t^x_i` and :math:`t^y_j` by the formula
    :math:`\\tau_{ij} = \\frac{1}{2} \\min\{t^x_{i+1} - t^x_i, t^x_i - t^x_{i-1},
    t^y_{j+1} - t^y_j, t^y_j - t^y_{j-1}\}`

    Further and more detailed information can be found in
    *Quiroga, R. Q., Kreuz, T., & Grassberger, P. (2002). Event
    synchronization: a simple and fast method to measure synchronicity and time
    delay patterns. Physical Review E, 66(4), 041904.*

    :param sequence trains: Sequence of :class:`neo.core.SpikeTrain` objects of
        which the van Rossum distance will be calculated pairwise.
    :param tau: The maximum time lag for two spikes to be considered coincident
        or synchronous as time scalar. To have it determined automatically by
        above formula set it to `None`.
    :type tau: Quantity scalar
    :param kernel: Kernel to use in the calculation of the distance.
    :type kernel: :class:`.signal_processing.Kernel`
    :param bool sort: Spike trains with sorted spike times are be needed for
        the calculation. You can set `sort` to `False` if you know that your
        spike trains are already sorted to decrease calculation time.
    :returns: Matrix containing the event synchronization for all pairs of spike
        trains.
    :rtype: 2-D array
    """

    trains = [st.view(type=pq.Quantity) for st in trains]
    if sort:
        trains = [sp.sort(st) for st in trains]

    if tau is None:
        inf_array = sp.array([sp.inf])
        isis = [spq.concatenate(
                (inf_array * st.units, sp.diff(st), inf_array * st.units))
                for st in trains]
        auto_taus = [spq.minimum(t[:-1], t[1:]) for t in isis]

    def compute(i, j):
        if i == j:
            return 1.0
        else:
            if tau is None:
                tau_mat = spq.minimum(*spq.meshgrid(
                    auto_taus[i], auto_taus[j])) / 2.0
            else:
                tau_mat = sp.tile(tau, (trains[j].size, trains[i].size))
            coincidence = sp.sum(kernel(
                (trains[i] - sp.atleast_2d(trains[j]).T) / tau_mat))
            normalization = 1.0 / sp.sqrt(trains[i].size * trains[j].size)
            return normalization * coincidence

    return _create_matrix_from_indexed_function(
        (len(trains), len(trains)), compute, kernel.is_symmetric())
def _merge_trains_and_label_spikes(trains):
    labels = sp.concatenate(
        [sp.zeros(st.size, dtype=int) + i for i, st in enumerate(trains)])
    trains = spq.concatenate([st.view(dtype=pq.Quantity) for st in trains])
    sorted_indices = sp.argsort(trains)
    return trains[sorted_indices], labels[sorted_indices]
Пример #4
0
def _merge_trains_and_label_spikes(trains):
    labels = sp.concatenate(
        [sp.zeros(st.size, dtype=int) + i for i, st in enumerate(trains)])
    trains = spq.concatenate([st.view(dtype=pq.Quantity) for st in trains])
    sorted_indices = sp.argsort(trains)
    return trains[sorted_indices], labels[sorted_indices]
Пример #5
0
def event_synchronization(trains,
                          tau=None,
                          kernel=sigproc.RectangularKernel(1.0,
                                                           normalize=False),
                          sort=True):
    """ event_synchronization(trains, tau=None, kernel=signal_processing.RectangularKernel(1.0, normalize=False), sort=True)

    Calculates the event synchronization.

    Let :math:`d(x|y)` be the count of spikes in :math:`y` which occur shortly
    before an event in :math:`x` with a time difference of less than
    :math:`\\tau`. Moreover, let :math:`n_x` and :math:`n_y` be the number of
    total spikes in the spike trains :math:`x` and :math:`y`. The event
    synchrony is then defined as :math:`Q_T = \\frac{d(x|y)
    + d(y|x)}{\\sqrt{n_x n_y}}`.

    The time maximum time lag :math:`\\tau` can be determined automatically for
    each pair of spikes :math:`t^x_i` and :math:`t^y_j` by the formula
    :math:`\\tau_{ij} = \\frac{1}{2} \\min\{t^x_{i+1} - t^x_i, t^x_i - t^x_{i-1},
    t^y_{j+1} - t^y_j, t^y_j - t^y_{j-1}\}`

    Further and more detailed information can be found in
    *Quiroga, R. Q., Kreuz, T., & Grassberger, P. (2002). Event
    synchronization: a simple and fast method to measure synchronicity and time
    delay patterns. Physical Review E, 66(4), 041904.*

    :param sequence trains: Sequence of :class:`neo.core.SpikeTrain` objects of
        which the van Rossum distance will be calculated pairwise.
    :param tau: The maximum time lag for two spikes to be considered coincident
        or synchronous as time scalar. To have it determined automatically by
        above formula set it to `None`.
    :type tau: Quantity scalar
    :param kernel: Kernel to use in the calculation of the distance.
    :type kernel: :class:`.signal_processing.Kernel`
    :param bool sort: Spike trains with sorted spike times are be needed for
        the calculation. You can set `sort` to `False` if you know that your
        spike trains are already sorted to decrease calculation time.
    :returns: Matrix containing the event synchronization for all pairs of spike
        trains.
    :rtype: 2-D array
    """

    trains = [st.view(type=pq.Quantity) for st in trains]
    if sort:
        trains = [sp.sort(st) for st in trains]

    if tau is None:
        inf_array = sp.array([sp.inf])
        isis = [
            spq.concatenate(
                (inf_array * st.units, sp.diff(st), inf_array * st.units))
            for st in trains
        ]
        auto_taus = [spq.minimum(t[:-1], t[1:]) for t in isis]

    def compute(i, j):
        if i == j:
            return 1.0
        else:
            if tau is None:
                tau_mat = spq.minimum(
                    *spq.meshgrid(auto_taus[i], auto_taus[j])) / 2.0
            else:
                tau_mat = sp.tile(tau, (trains[j].size, trains[i].size))
            coincidence = sp.sum(
                kernel((trains[i] - sp.atleast_2d(trains[j]).T) / tau_mat))
            normalization = 1.0 / sp.sqrt(trains[i].size * trains[j].size)
            return normalization * coincidence

    return _create_matrix_from_indexed_function((len(trains), len(trains)),
                                                compute, kernel.is_symmetric())
def gen_homogeneous_poisson(rate,
                            t_start=0 * pq.s,
                            t_stop=None,
                            max_spikes=None,
                            refractory=0 * pq.s):
    """ Generate a homogeneous Poisson spike train. The length is controlled
    with `t_stop` and `max_spikes`. Either one or both of these arguments have
    to be given.

    :param rate: Average firing rate of the spike train to generate as
        frequency scalar.
    :type rate: Quantity scalar
    :param t_start: Time at which the spike train begins as time scalar. The
        first actual spike will be greater than this time.
    :type t_start: Quantity scalar
    :param t_stop: Time at which the spike train ends as time scalar. All
        generated spikes will be lower or equal than this time. If set to None,
        the number of generated spikes is controlled by `max_spikes` and
        `t_stop` will be equal to the last generated spike.
    :type t_stop: Quantity scalar
    :param max_spikes: Maximum number of spikes to generate. Fewer spikes might
        be generated in case `t_stop` is also set.
    :param refractory: Absolute refractory period as time scalar. No spike will
        follow another spike for the given duration. Afterwards the firing rate
        will instantaneously be set to `rate` again.
    :type refractory: Quantity scalar

    :returns: The generated spike train.
    :rtype: :class:`neo.core.SpikeTrain`
    """

    if t_stop is None and max_spikes is None:
        raise ValueError('Either t_stop or max_spikes has to be set.')

    if max_spikes is not None:
        spike_times = sp.cumsum(numpy.random.exponential(
            rate**-1, max_spikes)) * (rate.units**-1).simplified
        spike_times += t_start
        if refractory > 0:
            spike_times += sp.arange(spike_times.size) * refractory
        if t_stop is not None:
            spike_times = spike_times[spike_times <= t_stop]
    else:
        scale = (rate**-1).rescale(t_stop.units)
        trains = []
        last_spike = t_start.rescale(t_stop.units)
        while last_spike < t_stop:
            # Generate a bit more than the average number of expected spike to
            # be finished in most cases in one loop. The factor was determined
            # empirically.
            num_spikes = int(1.7 *
                             ((t_stop - last_spike) * rate).simplified) + 1
            train = sp.cumsum(numpy.random.exponential(scale, num_spikes)) * \
                scale.units + last_spike
            if refractory > 0:
                train += sp.arange(train.size) * refractory
            if train.size > 0:
                last_spike = train[-1]
                if last_spike >= t_stop:
                    train = train[train < t_stop]
                trains.append(train)
        spike_times = spq.concatenate(trains)

    if t_stop is None:
        t_stop = spike_times[-1]
    return neo.SpikeTrain(spike_times, t_start=t_start, t_stop=t_stop)
def gen_homogeneous_poisson(
        rate, t_start=0 * pq.s, t_stop=None, max_spikes=None,
        refractory=0 * pq.s):
    """ Generate a homogeneous Poisson spike train. The length is controlled
    with `t_stop` and `max_spikes`. Either one or both of these arguments have
    to be given.

    :param rate: Average firing rate of the spike train to generate as
        frequency scalar.
    :type rate: Quantity scalar
    :param t_start: Time at which the spike train begins as time scalar. The
        first actual spike will be greater than this time.
    :type t_start: Quantity scalar
    :param t_stop: Time at which the spike train ends as time scalar. All
        generated spikes will be lower or equal than this time. If set to None,
        the number of generated spikes is controlled by `max_spikes` and
        `t_stop` will be equal to the last generated spike.
    :type t_stop: Quantity scalar
    :param max_spikes: Maximum number of spikes to generate. Fewer spikes might
        be generated in case `t_stop` is also set.
    :param refractory: Absolute refractory period as time scalar. No spike will
        follow another spike for the given duration. Afterwards the firing rate
        will instantaneously be set to `rate` again.
    :type refractory: Quantity scalar

    :returns: The generated spike train.
    :rtype: :class:`neo.core.SpikeTrain`
    """

    if t_stop is None and max_spikes is None:
        raise ValueError('Either t_stop or max_spikes has to be set.')

    if max_spikes is not None:
        spike_times = sp.cumsum(numpy.random.exponential(
            rate ** -1, max_spikes)) * (rate.units ** -1).simplified
        spike_times += t_start
        if refractory > 0:
            spike_times += sp.arange(spike_times.size) * refractory
        if t_stop is not None:
            spike_times = spike_times[spike_times <= t_stop]
    else:
        scale = (rate ** -1).rescale(t_stop.units)
        trains = []
        last_spike = t_start.rescale(t_stop.units)
        while last_spike < t_stop:
            # Generate a bit more than the average number of expected spike to
            # be finished in most cases in one loop. The factor was determined
            # empirically.
            num_spikes = int(1.7 * (
                (t_stop - last_spike) * rate).simplified) + 1
            train = sp.cumsum(numpy.random.exponential(scale, num_spikes)) * \
                scale.units + last_spike
            if refractory > 0:
                train += sp.arange(train.size) * refractory
            if train.size > 0:
                last_spike = train[-1]
                if last_spike >= t_stop:
                    train = train[train < t_stop]
                trains.append(train)
        spike_times = spq.concatenate(trains)

    if t_stop is None:
        t_stop = spike_times[-1]
    return neo.SpikeTrain(spike_times, t_start=t_start, t_stop=t_stop)