diff --git a/Readme.rst b/Readme.rst index 69a86e8..542f4b3 100644 --- a/Readme.rst +++ b/Readme.rst @@ -7,8 +7,8 @@ PySpike :target: https://travis-ci.org/mariomulansky/PySpike PySpike is a Python library for the numerical analysis of spike train similarity. -Its core functionality is the implementation of the bivariate ISI_ and SPIKE_ distance [#]_ [#]_ as well as SPIKE-Synchronization_ [#]_. -Additionally, it provides functions to compute multivariate profiles, distance matrices, as well as averaging and general spike train processing. +Its core functionality is the implementation of the ISI_ and SPIKE_ distance [#]_ [#]_ as well as SPIKE-Synchronization_ [#]_. +It provides functions to compute multivariate profiles, distance matrices, as well as averaging and general spike train processing. All computation intensive parts are implemented in C via cython_ to reach a competitive performance (factor 100-200 over plain Python). PySpike provides the same fundamental functionality as the SPIKY_ framework for Matlab, which additionally contains spike-train generators, more spike train distance measures and many visualization routines. @@ -24,6 +24,8 @@ All source codes are available on `Github `_. diff --git a/doc/tutorial.rst b/doc/tutorial.rst index f7fc20b..aff03a8 100644 --- a/doc/tutorial.rst +++ b/doc/tutorial.rst @@ -88,10 +88,9 @@ If you are only interested in the scalar ISI-distance and not the profile, you c .. code:: python - isi_dist = spk.isi_distance(spike_trains[0], spike_trains[1], interval) - -where :code:`interval` is optional, as above, and if omitted the ISI-distance is computed for the complete spike trains. + isi_dist = spk.isi_distance(spike_trains[0], spike_trains[1], interval=(0, 1000)) +where :code:`interval` is optional, as above, and if omitted the ISI-distance is computed for the complete spike train. SPIKE-distance .............. @@ -113,19 +112,20 @@ But the general approach is very similar: plt.show() This short example computes and plots the SPIKE-profile of the first two spike trains in the file :code:`PySpike_testdata.txt`. + In contrast to the ISI-profile, a SPIKE-profile is a piece-wise *linear* function and is therefore represented by a :class:`.PieceWiseLinFunc` object. Just like the :class:`.PieceWiseConstFunc` for the ISI-profile, the :class:`.PieceWiseLinFunc` provides a :meth:`.PieceWiseLinFunc.get_plottable_data` member function that returns arrays that can be used directly to plot the function. Furthermore, the :meth:`.PieceWiseLinFunc.avrg` member function returns the average of the profile defined as the overall SPIKE distance. As above, you can provide an interval as a pair of floats as well as a sequence of such pairs to :code:`avrg` to specify the averaging interval if required. -Again, you can use +Again, you can use: .. code:: python - spike_dist = spk.spike_distance(spike_trains[0], spike_trains[1], interval) + spike_dist = spk.spike_distance(spike_trains[0], spike_trains[1], interval=ival) to compute the SPIKE distance directly, if you are not interested in the profile at all. -The parameter :code:`interval` is optional and if neglected the whole spike train is used. +The parameter :code:`interval` is optional and if neglected the whole time interval is used. SPIKE synchronization @@ -164,26 +164,47 @@ For the direct computation of the overall spike synchronization value within som .. code:: python - spike_sync = spk.spike_sync(spike_trains[0], spike_trains[1], interval) - + spike_sync = spk.spike_sync(spike_trains[0], spike_trains[1], interval=ival) Computing multivariate profiles and distances ---------------------------------------------- -To compute the multivariate ISI-profile, SPIKE-profile or SPIKE-Synchronization profile f a set of spike trains, PySpike provides multi-variate version of the profile function. -The following example computes the multivariate ISI-, SPIKE- and SPIKE-Sync-profile for a list of spike trains using the :func:`.isi_profile_multi`, :func:`.spike_profile_multi`, :func:`.spike_sync_profile_multi` functions: +To compute the multivariate ISI-profile, SPIKE-profile or SPIKE-Synchronization profile for a set of spike trains, simply provide a list of spike trains to the profile or distance functions. +The following example computes the multivariate ISI-, SPIKE- and SPIKE-Sync-profile for a list of spike trains: .. code:: python spike_trains = spk.load_spike_trains_from_txt("PySpike_testdata.txt", edges=(0, 4000)) - avrg_isi_profile = spk.isi_profile_multi(spike_trains) - avrg_spike_profile = spk.spike_profile_multi(spike_trains) - avrg_spike_sync_profile = spk.spike_sync_profile_multi(spike_trains) + avrg_isi_profile = spk.isi_profile(spike_trains) + avrg_spike_profile = spk.spike_profile(spike_trains) + avrg_spike_sync_profile = spk.spike_sync_profile(spike_trains) + +All functions also take an optional parameter :code:`indices`, a list of indices that allows to define the spike trains that should be used for the multivariate profile. +As before, if you are only interested in the distance values, and not in the profile, you can call the functions: :func:`.isi_distance`, :func:`.spike_distance` and :func:`.spike_sync` with a list of spike trains. +They return the scalar overall multivariate ISI-, SPIKE-distance or the SPIKE-Synchronization value. + +The following code is equivalent to the bivariate example above, computing the ISI-Distance between the first two spike trains in the given interval using the :code:`indices` parameter: + +.. code:: python + + isi_dist = spk.isi_distance(spike_trains, indices=[0, 1], interval=(0, 1000)) + +As you can see, the distance functions also accept an :code:`interval` parameter that can be used to specify the begin and end of the averaging interval as a pair of floats, if neglected the complete interval is used. + +**Note:** + +------------------------------ + + Instead of providing lists of spike trains to the profile or distance functions, you can also call those functions with many spike trains as (unnamed) parameters, e.g.: + + .. code:: python + + # st1, st2, st3, st4 are spike trains + spike_prof = spk.spike_profile(st1, st2, st3, st4) + +------------------------------ -All functions take an optional parameter :code:`indices`, a list of indices that allows to define the spike trains that should be used for the multivariate profile. -As before, if you are only interested in the distance values, and not in the profile, PySpike offers the functions: :func:`.isi_distance_multi`, :func:`.spike_distance_multi` and :func:`.spike_sync_multi`, that return the scalar overall multivariate ISI- and SPIKE-distance as well as the SPIKE-Synchronization value. -Those functions also accept an :code:`interval` parameter that can be used to specify the begin and end of the averaging interval as a pair of floats, if neglected the complete interval is used. Another option to characterize large sets of spike trains are distance matrices. Each entry in the distance matrix represents a bivariate distance (similarity for SPIKE-Synchronization) of two spike trains. @@ -210,4 +231,3 @@ The following example computes and plots the ISI- and SPIKE-distance matrix as w plt.title("SPIKE-Sync") plt.show() - diff --git a/pyspike/isi_distance.py b/pyspike/isi_distance.py index 122e11d..e91dce2 100644 --- a/pyspike/isi_distance.py +++ b/pyspike/isi_distance.py @@ -20,14 +20,22 @@ def isi_profile(*args, **kwargs): Valid call structures:: - isi_profile(st1, st2) # returns the bi-variate profile + isi_profile(st1, st2) # returns the bi-variate profile isi_profile(st1, st2, st3) # multi-variate profile of 3 spike trains spike_trains = [st1, st2, st3, st4] # list of spike trains - isi_profile(spike_trains) # profile of the list of spike trains + isi_profile(spike_trains) # profile of the list of spike trains isi_profile(spike_trains, indices=[0, 1]) # use only the spike trains # given by the indices + The multivariate ISI distance profile for a set of spike trains is defined + as the average ISI-profile of all pairs of spike-trains: + + .. math:: = \\frac{2}{N(N-1)} \\sum_{} I^{i,j}, + + where the sum goes over all pairs + + :returns: The isi-distance profile :math:`I(t)` :rtype: :class:`.PieceWiseConstFunc` """ @@ -43,10 +51,9 @@ def isi_profile(*args, **kwargs): # isi_profile_bi ############################################################ def isi_profile_bi(spike_train1, spike_train2): - """ Bi-variate ISI-profile. - Computes the isi-distance profile :math:`I(t)` of the two given - spike trains. Returns the profile as a PieceWiseConstFunc object. - See :func:`.isi_profile`. + """ Specific function to compute a bivariate ISI-profile. This is a + deprecated function and should not be called directly. Use + :func:`.isi_profile` to compute ISI-profiles. :param spike_train1: First spike train. :type spike_train1: :class:`.SpikeTrain` @@ -85,12 +92,10 @@ def isi_profile_bi(spike_train1, spike_train2): # isi_profile_multi ############################################################ def isi_profile_multi(spike_trains, indices=None): - """ computes the multi-variate isi distance profile for a set of spike - trains. That is the average isi-distance of all pairs of spike-trains: + """ Specific function to compute the multivariate ISI-profile for a set of + spike trains. This is a deprecated function and should not be called + directly. Use :func:`.isi_profile` to compute ISI-profiles. - .. math:: = \\frac{2}{N(N-1)} \\sum_{} I^{i,j}, - - where the sum goes over all pairs :param spike_trains: list of :class:`.SpikeTrain` :param indices: list of indices defining which spike trains to use, @@ -115,6 +120,14 @@ def isi_distance(*args, **kwargs): .. math:: D_I = \\int_{T_0}^{T_1} I(t) dt. + In the multivariate case it is the integral over the multivariate + ISI-profile, i.e. the average profile over all spike train pairs: + + .. math:: D_I = \\int_0^T \\frac{2}{N(N-1)} \\sum_{} I^{i,j}, + + where the sum goes over all pairs + + Valid call structures:: @@ -139,14 +152,12 @@ def isi_distance(*args, **kwargs): ############################################################ -# isi_distance_bi +# _isi_distance_bi ############################################################ def isi_distance_bi(spike_train1, spike_train2, interval=None): - """ Computes the ISI-distance :math:`D_I` of the given spike trains. The - isi-distance is the integral over the isi distance profile - :math:`I(t)`: - - .. math:: D_I = \\int_{T_0}^{T_1} I(t) dt. + """ Specific function to compute the bivariate ISI-distance. + This is a deprecated function and should not be called directly. Use + :func:`.isi_distance` to compute ISI-distances. :param spike_train1: First spike train. :type spike_train1: :class:`.SpikeTrain` @@ -181,12 +192,9 @@ def isi_distance_bi(spike_train1, spike_train2, interval=None): # isi_distance_multi ############################################################ def isi_distance_multi(spike_trains, indices=None, interval=None): - """ computes the multi-variate isi-distance for a set of spike-trains. - That is the time average of the multi-variate spike profile: - - .. math:: D_I = \\int_0^T \\frac{2}{N(N-1)} \\sum_{} I^{i,j}, - - where the sum goes over all pairs + """ Specific function to compute the multivariate ISI-distance. + This is a deprecfated function and should not be called directly. Use + :func:`.isi_distance` to compute ISI-distances. :param spike_trains: list of :class:`.SpikeTrain` :param indices: list of indices defining which spike trains to use, diff --git a/pyspike/spike_distance.py b/pyspike/spike_distance.py index 7acb959..0fd86c1 100644 --- a/pyspike/spike_distance.py +++ b/pyspike/spike_distance.py @@ -28,6 +28,13 @@ def spike_profile(*args, **kwargs): spike_profile(spike_trains, indices=[0, 1]) # use only the spike trains # given by the indices + The multivariate spike-distance profile is defined as the average of all + pairs of spike-trains: + + .. math:: = \\frac{2}{N(N-1)} \\sum_{} S^{i, j}`, + + where the sum goes over all pairs + :returns: The spike-distance profile :math:`S(t)` :rtype: :class:`.PieceWiseConstLin` """ @@ -43,9 +50,9 @@ def spike_profile(*args, **kwargs): # spike_profile_bi ############################################################ def spike_profile_bi(spike_train1, spike_train2): - """ Computes the spike-distance profile :math:`S(t)` of the two given spike - trains. Returns the profile as a PieceWiseLinFunc object. The SPIKE-values - are defined positive :math:`S(t)>=0`. + """ Specific function to compute a bivariate SPIKE-profile. This is a + deprecated function and should not be called directly. Use + :func:`.spike_profile` to compute SPIKE-profiles. :param spike_train1: First spike train. :type spike_train1: :class:`.SpikeTrain` @@ -86,12 +93,9 @@ def spike_profile_bi(spike_train1, spike_train2): # spike_profile_multi ############################################################ def spike_profile_multi(spike_trains, indices=None): - """ Computes the multi-variate spike distance profile for a set of spike - trains. That is the average spike-distance of all pairs of spike-trains: - - .. math:: = \\frac{2}{N(N-1)} \\sum_{} S^{i, j}`, - - where the sum goes over all pairs + """ Specific function to compute a multivariate SPIKE-profile. This is a + deprecated function and should not be called directly. Use + :func:`.spike_profile` to compute SPIKE-profiles. :param spike_trains: list of :class:`.SpikeTrain` :param indices: list of indices defining which spike trains to use, @@ -128,6 +132,13 @@ def spike_distance(*args, **kwargs): spike_distance(spike_trains, indices=[0, 1]) # use only the spike trains # given by the indices + In the multivariate case, the spike distance is given as the integral over + the multivariate profile, that is the average profile of all spike train + pairs: + + .. math:: D_S = \\int_0^T \\frac{2}{N(N-1)} \\sum_{} + S^{i, j} dt + :returns: The spike-distance :math:`D_S`. :rtype: double """ @@ -144,11 +155,9 @@ def spike_distance(*args, **kwargs): # spike_distance_bi ############################################################ def spike_distance_bi(spike_train1, spike_train2, interval=None): - """ Computes the spike-distance :math:`D_S` of the given spike trains. The - spike-distance is the integral over the spike distance profile - :math:`S(t)`: - - .. math:: D_S = \int_{T_0}^{T_1} S(t) dt. + """ Specific function to compute a bivariate SPIKE-distance. This is a + deprecated function and should not be called directly. Use + :func:`.spike_distance` to compute SPIKE-distances. :param spike_train1: First spike train. :type spike_train1: :class:`.SpikeTrain` @@ -183,13 +192,9 @@ def spike_distance_bi(spike_train1, spike_train2, interval=None): # spike_distance_multi ############################################################ def spike_distance_multi(spike_trains, indices=None, interval=None): - """ Computes the multi-variate spike distance for a set of spike trains. - That is the time average of the multi-variate spike profile: - - .. math:: D_S = \\int_0^T \\frac{2}{N(N-1)} \\sum_{} - S^{i, j} dt - - where the sum goes over all pairs + """ Specific function to compute a multivariate SPIKE-distance. This is a + deprecated function and should not be called directly. Use + :func:`.spike_distance` to compute SPIKE-distances. :param spike_trains: list of :class:`.SpikeTrain` :param indices: list of indices defining which spike trains to use, diff --git a/pyspike/spike_sync.py b/pyspike/spike_sync.py index ccb09d9..617dd86 100644 --- a/pyspike/spike_sync.py +++ b/pyspike/spike_sync.py @@ -34,6 +34,11 @@ def spike_sync_profile(*args, **kwargs): spike_sync_profile(sts, indices=[0, 1]) # use only the spike trains # given by the indices + In the multivariate case, the profile is defined as the number of + coincidences for each spike in the set of spike trains divided by the + number of spike trains pairs involving the spike train of containing this + spike, which is the number of spike trains minus one (N-1). + :returns: The spike-sync profile :math:`S_{sync}(t)`. :rtype: :class:`pyspike.function.DiscreteFunction` """ @@ -49,10 +54,9 @@ def spike_sync_profile(*args, **kwargs): # spike_sync_profile_bi ############################################################ def spike_sync_profile_bi(spike_train1, spike_train2, max_tau=None): - """ Computes the spike-synchronization profile S_sync(t) of the two given - spike trains. Returns the profile as a DiscreteFunction object. The S_sync - values are either 1 or 0, indicating the presence or absence of a - coincidence. + """ Specific function to compute a bivariate SPIKE-Sync-profile. This is a + deprecated function and should not be called directly. Use + :func:`.spike_sync_profile` to compute SPIKE-Sync-profiles. :param spike_train1: First spike train. :type spike_train1: :class:`pyspike.SpikeTrain` @@ -98,11 +102,9 @@ def spike_sync_profile_bi(spike_train1, spike_train2, max_tau=None): # spike_sync_profile_multi ############################################################ def spike_sync_profile_multi(spike_trains, indices=None, max_tau=None): - """ Computes the multi-variate spike synchronization profile for a set of - spike trains. For each spike in the set of spike trains, the multi-variate - profile is defined as the number of coincidences divided by the number of - spike trains pairs involving the spike train of containing this spike, - which is the number of spike trains minus one (N-1). + """ Specific function to compute a multivariate SPIKE-Sync-profile. + This is a deprecated function and should not be called directly. Use + :func:`.spike_sync_profile` to compute SPIKE-Sync-profiles. :param spike_trains: list of :class:`pyspike.SpikeTrain` :param indices: list of indices defining which spike trains to use, @@ -176,6 +178,9 @@ def spike_sync(*args, **kwargs): spike_sync(spike_trains, indices=[0, 1]) # use only the spike trains # given by the indices + The multivariate SPIKE-Sync is again defined as the overall ratio of all + coincidence values divided by the total number of spikes. + :returns: The spike synchronization value. :rtype: `double` """ @@ -192,11 +197,9 @@ def spike_sync(*args, **kwargs): # spike_sync_bi ############################################################ def spike_sync_bi(spike_train1, spike_train2, interval=None, max_tau=None): - """ Computes the spike synchronization value SYNC of the given spike - trains. The spike synchronization value is the computed as the total number - of coincidences divided by the total number of spikes: - - .. math:: SYNC = \sum_n C_n / N. + """ Specific function to compute a bivariate SPIKE-Sync value. + This is a deprecated function and should not be called directly. Use + :func:`.spike_sync` to compute SPIKE-Sync values. :param spike_train1: First spike train. :type spike_train1: :class:`pyspike.SpikeTrain` @@ -219,8 +222,9 @@ def spike_sync_bi(spike_train1, spike_train2, interval=None, max_tau=None): # spike_sync_multi ############################################################ def spike_sync_multi(spike_trains, indices=None, interval=None, max_tau=None): - """ Computes the multi-variate spike synchronization value for a set of - spike trains. + """ Specific function to compute a multivariate SPIKE-Sync value. + This is a deprecated function and should not be called directly. Use + :func:`.spike_sync` to compute SPIKE-Sync values. :param spike_trains: list of :class:`pyspike.SpikeTrain` :param indices: list of indices defining which spike trains to use,