summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMario Mulansky <mario.mulansky@gmx.net>2016-06-18 16:32:39 -0700
committerMario Mulansky <mario.mulansky@gmx.net>2016-06-18 16:32:39 -0700
commita63839708d6574567bcd518a822a9f10629ed80b (patch)
tree02c28e0856b62c08fd4d3622ee68d145d8eee6eb
parentd9e2125dcc76693056ab04264add29227f398f4f (diff)
parent4691d0e77a024fbc73d1098ee557d65f8f2ddc89 (diff)
Merge branch 'import_time_series' into develop
Conflicts: pyspike/__init__.py resolved
-rw-r--r--Readme.rst16
-rw-r--r--doc/conf.py4
-rw-r--r--doc/tutorial.rst54
-rw-r--r--examples/averages.py2
-rw-r--r--examples/merge.py6
-rw-r--r--examples/multivariate.py4
-rw-r--r--examples/performance.py27
-rw-r--r--examples/plot.py5
-rw-r--r--examples/profiles.py4
-rw-r--r--examples/spike_sync.py2
-rw-r--r--pyspike/__init__.py3
-rw-r--r--pyspike/isi_distance.py149
-rw-r--r--pyspike/spike_distance.py155
-rw-r--r--pyspike/spike_sync.py152
-rw-r--r--pyspike/spikes.py25
-rw-r--r--setup.py4
-rw-r--r--test/test_generic_interfaces.py105
-rw-r--r--test/test_regression/test_regression_15.py1
-rw-r--r--test/test_spikes.py19
19 files changed, 561 insertions, 176 deletions
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 <https://github.com/mariomulansky/PySp
Important Changelog
-----------------------------
+With version 0.5.0, the interfaces have been unified and the specific functions for multivariate computations have become deprecated.
+
With version 0.2.0, the :code:`SpikeTrain` class has been introduced to represent spike trains.
This is a breaking change in the function interfaces.
Hence, programs written for older versions of PySpike (0.1.x) will not run with newer versions.
@@ -76,7 +78,7 @@ Therefore, add your :code:`/path/to/PySpike` to the :code:`$PYTHONPATH` environm
Examples
-----------------------------
-The following code loads some exemplary spike trains, computes the dissimilarity profile of the ISI-distance of the first two :code:`SpikeTrain` s, and plots it with matplotlib:
+The following code loads some exemplary spike trains, computes the dissimilarity profile of the ISI-distance of the first two :code:`SpikeTrain` objects, and plots it with matplotlib:
.. code:: python
@@ -92,15 +94,15 @@ The following code loads some exemplary spike trains, computes the dissimilarity
plt.show()
-The following example computes the multivariate ISI-, SPIKE- and SPIKE-Sync-profile for a list of spike trains using the :code:`isi_profile_multi`, :code:`spike_profile_multi`, :code:`spike_sync_profile_multi` functions:
+The following example computes the multivariate ISI-, SPIKE- and SPIKE-Sync-profile for a list of spike trains loaded from a text file:
.. 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)
More examples with detailed descriptions can be found in the `tutorial section <http://mariomulansky.github.io/PySpike/#tutorial>`_.
diff --git a/doc/conf.py b/doc/conf.py
index 7e13eae..807dec6 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -64,9 +64,9 @@ copyright = u'2014-2015, Mario Mulansky'
# built documents.
#
# The short X.Y version.
-version = '0.4'
+version = '0.5'
# The full version, including alpha/beta/rc tags.
-release = '0.4.0'
+release = '0.5.1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
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/examples/averages.py b/examples/averages.py
index c3e81e2..8b405d0 100644
--- a/examples/averages.py
+++ b/examples/averages.py
@@ -12,7 +12,7 @@ from __future__ import print_function
import pyspike as spk
spike_trains = spk.load_spike_trains_from_txt("PySpike_testdata.txt",
- time_interval=(0, 4000))
+ edges=(0, 4000))
f = spk.isi_profile(spike_trains[0], spike_trains[1])
diff --git a/examples/merge.py b/examples/merge.py
index 2ea96ea..b4437a3 100644
--- a/examples/merge.py
+++ b/examples/merge.py
@@ -21,9 +21,9 @@ merged_spike_train = spk.merge_spike_trains([spike_trains[0], spike_trains[1]])
print(merged_spike_train.spikes)
-plt.plot(spike_trains[0].spikes, np.ones_like(spike_trains[0].spikes), 'o')
-plt.plot(spike_trains[1].spikes, np.ones_like(spike_trains[1].spikes), 'x')
+plt.plot(spike_trains[0], np.ones_like(spike_trains[0]), 'o')
+plt.plot(spike_trains[1], np.ones_like(spike_trains[1]), 'x')
plt.plot(merged_spike_train.spikes,
- 2*np.ones_like(merged_spike_train.spikes), 'o')
+ 2*np.ones_like(merged_spike_train), 'o')
plt.show()
diff --git a/examples/multivariate.py b/examples/multivariate.py
index 93f8516..e9579a5 100644
--- a/examples/multivariate.py
+++ b/examples/multivariate.py
@@ -28,7 +28,7 @@ num_of_spikes = sum([len(spike_trains[i])
print("Number of spikes: %d" % num_of_spikes)
# calculate the multivariate spike distance
-f = spk.spike_profile_multi(spike_trains)
+f = spk.spike_profile(spike_trains)
t_spike = time.clock()
@@ -39,7 +39,7 @@ print("Spike distance from average: %.8f" % avrg)
t_avrg = time.clock()
# compute average distance directly, should give the same result as above
-spike_dist = spk.spike_distance_multi(spike_trains)
+spike_dist = spk.spike_distance(spike_trains)
print("Spike distance directly: %.8f" % spike_dist)
t_dist = time.clock()
diff --git a/examples/performance.py b/examples/performance.py
index ec6c830..30691f8 100644
--- a/examples/performance.py
+++ b/examples/performance.py
@@ -31,38 +31,41 @@ for i in range(M):
t_end = datetime.now()
runtime = (t_end-t_start).total_seconds()
+sort_by = 'tottime'
+# sort_by = 'cumtime'
+
print("Spike generation runtime: %.3fs" % runtime)
print()
print("================ ISI COMPUTATIONS ================")
print(" MULTIVARIATE DISTANCE")
-cProfile.run('spk.isi_distance_multi(spike_trains)', 'performance.stat')
+cProfile.run('spk.isi_distance(spike_trains)', 'performance.stat')
p = pstats.Stats('performance.stat')
-p.strip_dirs().sort_stats('tottime').print_stats(5)
+p.strip_dirs().sort_stats(sort_by).print_stats(5)
print(" MULTIVARIATE PROFILE")
-cProfile.run('spk.isi_profile_multi(spike_trains)', 'performance.stat')
+cProfile.run('spk.isi_profile(spike_trains)', 'performance.stat')
p = pstats.Stats('performance.stat')
-p.strip_dirs().sort_stats('tottime').print_stats(5)
+p.strip_dirs().sort_stats(sort_by).print_stats(5)
print("================ SPIKE COMPUTATIONS ================")
print(" MULTIVARIATE DISTANCE")
-cProfile.run('spk.spike_distance_multi(spike_trains)', 'performance.stat')
+cProfile.run('spk.spike_distance(spike_trains)', 'performance.stat')
p = pstats.Stats('performance.stat')
-p.strip_dirs().sort_stats('tottime').print_stats(5)
+p.strip_dirs().sort_stats(sort_by).print_stats(5)
print(" MULTIVARIATE PROFILE")
-cProfile.run('spk.spike_profile_multi(spike_trains)', 'performance.stat')
+cProfile.run('spk.spike_profile(spike_trains)', 'performance.stat')
p = pstats.Stats('performance.stat')
-p.strip_dirs().sort_stats('tottime').print_stats(5)
+p.strip_dirs().sort_stats(sort_by).print_stats(5)
print("================ SPIKE-SYNC COMPUTATIONS ================")
print(" MULTIVARIATE DISTANCE")
-cProfile.run('spk.spike_sync_multi(spike_trains)', 'performance.stat')
+cProfile.run('spk.spike_sync(spike_trains)', 'performance.stat')
p = pstats.Stats('performance.stat')
-p.strip_dirs().sort_stats('tottime').print_stats(5)
+p.strip_dirs().sort_stats(sort_by).print_stats(5)
print(" MULTIVARIATE PROFILE")
-cProfile.run('spk.spike_sync_profile_multi(spike_trains)', 'performance.stat')
+cProfile.run('spk.spike_sync_profile(spike_trains)', 'performance.stat')
p = pstats.Stats('performance.stat')
-p.strip_dirs().sort_stats('tottime').print_stats(5)
+p.strip_dirs().sort_stats(sort_by).print_stats(5)
diff --git a/examples/plot.py b/examples/plot.py
index 1922939..a0e04da 100644
--- a/examples/plot.py
+++ b/examples/plot.py
@@ -24,7 +24,8 @@ spike_trains = spk.load_spike_trains_from_txt("PySpike_testdata.txt",
for (i, spike_train) in enumerate(spike_trains):
plt.scatter(spike_train, i*np.ones_like(spike_train), marker='|')
-f = spk.isi_profile(spike_trains[0], spike_trains[1])
+# profile of the first two spike trains
+f = spk.isi_profile(spike_trains, indices=[0, 1])
x, y = f.get_plottable_data()
plt.figure()
@@ -32,7 +33,7 @@ plt.plot(x, np.abs(y), '--k', label="ISI-profile")
print("ISI-distance: %.8f" % f.avrg())
-f = spk.spike_profile(spike_trains[0], spike_trains[1])
+f = spk.spike_profile(spike_trains, indices=[0, 1])
x, y = f.get_plottable_data()
plt.plot(x, y, '-b', label="SPIKE-profile")
diff --git a/examples/profiles.py b/examples/profiles.py
index 05494bd..8412ffb 100644
--- a/examples/profiles.py
+++ b/examples/profiles.py
@@ -29,7 +29,7 @@ print("Average ISI distance:", f.avrg())
print()
# compute the multivariate ISI profile
-f = spk.isi_profile_multi(spike_trains)
+f = spk.isi_profile(spike_trains)
t = 1200
print("Multivariate ISI value at t =", t, ":", f(t))
@@ -56,7 +56,7 @@ print("Average SPIKE distance:", f.avrg())
print()
# compute the multivariate SPIKE profile
-f = spk.spike_profile_multi(spike_trains)
+f = spk.spike_profile(spike_trains)
# SPIKE values at certain points
t = 1200
diff --git a/examples/spike_sync.py b/examples/spike_sync.py
index 37dbff4..13ca0ce 100644
--- a/examples/spike_sync.py
+++ b/examples/spike_sync.py
@@ -31,7 +31,7 @@ plt.figure()
plt.subplot(211)
-f = spk.spike_sync_profile_multi(spike_trains)
+f = spk.spike_sync_profile(spike_trains)
x, y = f.get_plottable_data()
plt.plot(x, y, '-b', alpha=0.7, label="SPIKE-Sync profile")
diff --git a/pyspike/__init__.py b/pyspike/__init__.py
index 4d75786..08253fb 100644
--- a/pyspike/__init__.py
+++ b/pyspike/__init__.py
@@ -24,7 +24,8 @@ from .spike_sync import spike_sync_profile, spike_sync,\
from .psth import psth
from .spikes import load_spike_trains_from_txt, save_spike_trains_to_txt, \
- spike_train_from_string, merge_spike_trains, generate_poisson_spikes
+ spike_train_from_string, import_spike_trains_from_time_series, \
+ merge_spike_trains, generate_poisson_spikes
# define the __version__ following
# http://stackoverflow.com/questions/17583443
diff --git a/pyspike/isi_distance.py b/pyspike/isi_distance.py
index 0ae7393..e91dce2 100644
--- a/pyspike/isi_distance.py
+++ b/pyspike/isi_distance.py
@@ -13,11 +13,48 @@ from pyspike.generic import _generic_profile_multi, _generic_distance_multi, \
############################################################
# isi_profile
############################################################
-def isi_profile(spike_train1, spike_train2):
- """ Computes the isi-distance profile :math:`I(t)` of the two given
- spike trains. Retruns the profile as a PieceWiseConstFunc object. The
+def isi_profile(*args, **kwargs):
+ """ Computes the isi-distance profile :math:`I(t)` of the given
+ spike trains. Returns the profile as a PieceWiseConstFunc object. The
ISI-values are defined positive :math:`I(t)>=0`.
+ Valid call structures::
+
+ 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, 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:: <I(t)> = \\frac{2}{N(N-1)} \\sum_{<i,j>} I^{i,j},
+
+ where the sum goes over all pairs <i,j>
+
+
+ :returns: The isi-distance profile :math:`I(t)`
+ :rtype: :class:`.PieceWiseConstFunc`
+ """
+ if len(args) == 1:
+ return isi_profile_multi(args[0], **kwargs)
+ elif len(args) == 2:
+ return isi_profile_bi(args[0], args[1])
+ else:
+ return isi_profile_multi(args)
+
+
+############################################################
+# isi_profile_bi
+############################################################
+def isi_profile_bi(spike_train1, spike_train2):
+ """ 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`
:param spike_train2: Second spike train.
@@ -52,15 +89,76 @@ Falling back to slow python backend.")
############################################################
+# isi_profile_multi
+############################################################
+def isi_profile_multi(spike_trains, indices=None):
+ """ 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.
+
+
+ :param spike_trains: list of :class:`.SpikeTrain`
+ :param indices: list of indices defining which spike trains to use,
+ if None all given spike trains are used (default=None)
+ :type state: list or None
+ :returns: The averaged isi profile :math:`<I(t)>`
+ :rtype: :class:`.PieceWiseConstFunc`
+ """
+ average_dist, M = _generic_profile_multi(spike_trains, isi_profile_bi,
+ indices)
+ average_dist.mul_scalar(1.0/M) # normalize
+ return average_dist
+
+
+############################################################
# isi_distance
############################################################
-def isi_distance(spike_train1, spike_train2, interval=None):
+def isi_distance(*args, **kwargs):
""" 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.
+ 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,j>} I^{i,j},
+
+ where the sum goes over all pairs <i,j>
+
+
+
+ Valid call structures::
+
+ isi_distance(st1, st2) # returns the bi-variate distance
+ isi_distance(st1, st2, st3) # multi-variate distance of 3 spike trains
+
+ spike_trains = [st1, st2, st3, st4] # list of spike trains
+ isi_distance(spike_trains) # distance of the list of spike trains
+ isi_distance(spike_trains, indices=[0, 1]) # use only the spike trains
+ # given by the indices
+
+ :returns: The isi-distance :math:`D_I`.
+ :rtype: double
+ """
+
+ if len(args) == 1:
+ return isi_distance_multi(args[0], **kwargs)
+ elif len(args) == 2:
+ return isi_distance_bi(args[0], args[1], **kwargs)
+ else:
+ return isi_distance_multi(args, **kwargs)
+
+
+############################################################
+# _isi_distance_bi
+############################################################
+def isi_distance_bi(spike_train1, spike_train2, interval=None):
+ """ 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`
:param spike_train2: Second spike train.
@@ -84,46 +182,19 @@ def isi_distance(spike_train1, spike_train2, interval=None):
spike_train1.t_start, spike_train1.t_end)
except ImportError:
# Cython backend not available: fall back to profile averaging
- return isi_profile(spike_train1, spike_train2).avrg(interval)
+ return isi_profile_bi(spike_train1, spike_train2).avrg(interval)
else:
# some specific interval is provided: use profile
- return isi_profile(spike_train1, spike_train2).avrg(interval)
-
-
-############################################################
-# 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:
-
- .. math:: <I(t)> = \\frac{2}{N(N-1)} \\sum_{<i,j>} I^{i,j},
-
- where the sum goes over all pairs <i,j>
-
- :param spike_trains: list of :class:`.SpikeTrain`
- :param indices: list of indices defining which spike trains to use,
- if None all given spike trains are used (default=None)
- :type state: list or None
- :returns: The averaged isi profile :math:`<I(t)>`
- :rtype: :class:`.PieceWiseConstFunc`
- """
- average_dist, M = _generic_profile_multi(spike_trains, isi_profile,
- indices)
- average_dist.mul_scalar(1.0/M) # normalize
- return average_dist
+ return isi_profile_bi(spike_train1, spike_train2).avrg(interval)
############################################################
# 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,j>} I^{i,j},
-
- where the sum goes over all pairs <i,j>
+ """ 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,
@@ -134,7 +205,7 @@ def isi_distance_multi(spike_trains, indices=None, interval=None):
:returns: The time-averaged multivariate ISI distance :math:`D_I`
:rtype: double
"""
- return _generic_distance_multi(spike_trains, isi_distance, indices,
+ return _generic_distance_multi(spike_trains, isi_distance_bi, indices,
interval)
@@ -155,5 +226,5 @@ def isi_distance_matrix(spike_trains, indices=None, interval=None):
:math:`D_{I}^{ij}`
:rtype: np.array
"""
- return _generic_distance_matrix(spike_trains, isi_distance,
- indices, interval)
+ return _generic_distance_matrix(spike_trains, isi_distance_bi,
+ indices=indices, interval=interval)
diff --git a/pyspike/spike_distance.py b/pyspike/spike_distance.py
index e418283..0fd86c1 100644
--- a/pyspike/spike_distance.py
+++ b/pyspike/spike_distance.py
@@ -13,10 +13,46 @@ from pyspike.generic import _generic_profile_multi, _generic_distance_multi, \
############################################################
# spike_profile
############################################################
-def spike_profile(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`.
+def spike_profile(*args, **kwargs):
+ """ Computes the spike-distance profile :math:`S(t)` of the given
+ spike trains. Returns the profile as a PieceWiseConstLin object. The
+ SPIKE-values are defined positive :math:`S(t)>=0`.
+
+ Valid call structures::
+
+ spike_profile(st1, st2) # returns the bi-variate profile
+ spike_profile(st1, st2, st3) # multi-variate profile of 3 spike trains
+
+ spike_trains = [st1, st2, st3, st4] # list of spike trains
+ spike_profile(spike_trains) # profile of the list of spike trains
+ 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:: <S(t)> = \\frac{2}{N(N-1)} \\sum_{<i,j>} S^{i, j}`,
+
+ where the sum goes over all pairs <i,j>
+
+ :returns: The spike-distance profile :math:`S(t)`
+ :rtype: :class:`.PieceWiseConstLin`
+ """
+ if len(args) == 1:
+ return spike_profile_multi(args[0], **kwargs)
+ elif len(args) == 2:
+ return spike_profile_bi(args[0], args[1])
+ else:
+ return spike_profile_multi(args)
+
+
+############################################################
+# spike_profile_bi
+############################################################
+def spike_profile_bi(spike_train1, spike_train2):
+ """ 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`
@@ -54,14 +90,74 @@ Falling back to slow python backend.")
############################################################
+# spike_profile_multi
+############################################################
+def spike_profile_multi(spike_trains, indices=None):
+ """ 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,
+ if None all given spike trains are used (default=None)
+ :type indices: list or None
+ :returns: The averaged spike profile :math:`<S>(t)`
+ :rtype: :class:`.PieceWiseLinFunc`
+
+ """
+ average_dist, M = _generic_profile_multi(spike_trains, spike_profile_bi,
+ indices)
+ average_dist.mul_scalar(1.0/M) # normalize
+ return average_dist
+
+
+############################################################
# spike_distance
############################################################
-def spike_distance(spike_train1, spike_train2, interval=None):
- """ Computes the spike-distance :math:`D_S` of the given spike trains. The
+def spike_distance(*args, **kwargs):
+ """ 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(t)`:
+
+ .. math:: D_S = \\int_{T_0}^{T_1} S(t) dt.
+
- .. math:: D_S = \int_{T_0}^{T_1} S(t) dt.
+ Valid call structures::
+
+ spike_distance(st1, st2) # returns the bi-variate distance
+ spike_distance(st1, st2, st3) # multi-variate distance of 3 spike trains
+
+ spike_trains = [st1, st2, st3, st4] # list of spike trains
+ spike_distance(spike_trains) # distance of the list of spike trains
+ 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_{<i,j>}
+ S^{i, j} dt
+
+ :returns: The spike-distance :math:`D_S`.
+ :rtype: double
+ """
+
+ if len(args) == 1:
+ return spike_distance_multi(args[0], **kwargs)
+ elif len(args) == 2:
+ return spike_distance_bi(args[0], args[1], **kwargs)
+ else:
+ return spike_distance_multi(args, **kwargs)
+
+
+############################################################
+# spike_distance_bi
+############################################################
+def spike_distance_bi(spike_train1, spike_train2, interval=None):
+ """ 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`
@@ -86,48 +182,19 @@ def spike_distance(spike_train1, spike_train2, interval=None):
spike_train1.t_end)
except ImportError:
# Cython backend not available: fall back to average profile
- return spike_profile(spike_train1, spike_train2).avrg(interval)
+ return spike_profile_bi(spike_train1, spike_train2).avrg(interval)
else:
# some specific interval is provided: compute the whole profile
- return spike_profile(spike_train1, spike_train2).avrg(interval)
-
-
-############################################################
-# 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:: <S(t)> = \\frac{2}{N(N-1)} \\sum_{<i,j>} S^{i, j}`,
-
- where the sum goes over all pairs <i,j>
-
- :param spike_trains: list of :class:`.SpikeTrain`
- :param indices: list of indices defining which spike trains to use,
- if None all given spike trains are used (default=None)
- :type indices: list or None
- :returns: The averaged spike profile :math:`<S>(t)`
- :rtype: :class:`.PieceWiseLinFunc`
-
- """
- average_dist, M = _generic_profile_multi(spike_trains, spike_profile,
- indices)
- average_dist.mul_scalar(1.0/M) # normalize
- return average_dist
+ return spike_profile_bi(spike_train1, spike_train2).avrg(interval)
############################################################
# 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_{<i,j>}
- S^{i, j} dt
-
- where the sum goes over all pairs <i,j>
+ """ 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,
@@ -139,7 +206,7 @@ def spike_distance_multi(spike_trains, indices=None, interval=None):
:returns: The averaged multi-variate spike distance :math:`D_S`.
:rtype: double
"""
- return _generic_distance_multi(spike_trains, spike_distance, indices,
+ return _generic_distance_multi(spike_trains, spike_distance_bi, indices,
interval)
@@ -160,5 +227,5 @@ def spike_distance_matrix(spike_trains, indices=None, interval=None):
:math:`D_S^{ij}`
:rtype: np.array
"""
- return _generic_distance_matrix(spike_trains, spike_distance,
+ return _generic_distance_matrix(spike_trains, spike_distance_bi,
indices, interval)
diff --git a/pyspike/spike_sync.py b/pyspike/spike_sync.py
index 802b98c..80f7805 100644
--- a/pyspike/spike_sync.py
+++ b/pyspike/spike_sync.py
@@ -15,11 +15,48 @@ from pyspike.generic import _generic_profile_multi, _generic_distance_matrix
############################################################
# spike_sync_profile
############################################################
-def spike_sync_profile(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.
+def spike_sync_profile(*args, **kwargs):
+ """ Computes the spike-synchronization profile S_sync(t) of the given
+ spike trains. Returns the profile as a DiscreteFunction object. In the
+ bivariate case, he S_sync values are either 1 or 0, indicating the presence
+ or absence of a coincidence. For multi-variate cases, each spike in the set
+ of spike trains, the 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).
+
+ Valid call structures::
+
+ spike_sync_profile(st1, st2) # returns the bi-variate profile
+ spike_sync_profile(st1, st2, st3) # multi-variate profile of 3 sts
+
+ sts = [st1, st2, st3, st4] # list of spike trains
+ spike_sync_profile(sts) # profile of the list of spike trains
+ 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`
+ """
+ if len(args) == 1:
+ return spike_sync_profile_multi(args[0], **kwargs)
+ elif len(args) == 2:
+ return spike_sync_profile_bi(args[0], args[1])
+ else:
+ return spike_sync_profile_multi(args)
+
+
+############################################################
+# spike_sync_profile_bi
+############################################################
+def spike_sync_profile_bi(spike_train1, spike_train2, max_tau=None):
+ """ 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`
@@ -27,7 +64,7 @@ def spike_sync_profile(spike_train1, spike_train2, max_tau=None):
:type spike_train2: :class:`pyspike.SpikeTrain`
:param max_tau: Maximum coincidence window size. If 0 or `None`, the
coincidence window has no upper bound.
- :returns: The spike-distance profile :math:`S_{sync}(t)`.
+ :returns: The spike-sync profile :math:`S_{sync}(t)`.
:rtype: :class:`pyspike.function.DiscreteFunction`
"""
@@ -62,6 +99,31 @@ Falling back to slow python backend.")
############################################################
+# spike_sync_profile_multi
+############################################################
+def spike_sync_profile_multi(spike_trains, indices=None, max_tau=None):
+ """ 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,
+ if None all given spike trains are used (default=None)
+ :type indices: list or None
+ :param max_tau: Maximum coincidence window size. If 0 or `None`, the
+ coincidence window has no upper bound.
+ :returns: The multi-variate spike sync profile :math:`<S_{sync}>(t)`
+ :rtype: :class:`pyspike.function.DiscreteFunction`
+
+ """
+ prof_func = partial(spike_sync_profile_bi, max_tau=max_tau)
+ average_prof, M = _generic_profile_multi(spike_trains, prof_func,
+ indices)
+ # average_dist.mul_scalar(1.0/M) # no normalization here!
+ return average_prof
+
+
+############################################################
# _spike_sync_values
############################################################
def _spike_sync_values(spike_train1, spike_train2, interval, max_tau):
@@ -87,24 +149,58 @@ def _spike_sync_values(spike_train1, spike_train2, interval, max_tau):
return c, mp
except ImportError:
# Cython backend not available: fall back to profile averaging
- return spike_sync_profile(spike_train1, spike_train2,
- max_tau).integral(interval)
+ return spike_sync_profile_bi(spike_train1, spike_train2,
+ max_tau).integral(interval)
else:
# some specific interval is provided: use profile
- return spike_sync_profile(spike_train1, spike_train2,
- max_tau).integral(interval)
+ return spike_sync_profile_bi(spike_train1, spike_train2,
+ max_tau).integral(interval)
############################################################
# spike_sync
############################################################
-def spike_sync(spike_train1, spike_train2, interval=None, max_tau=None):
+def spike_sync(*args, **kwargs):
""" 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.
+
+ Valid call structures::
+
+ spike_sync(st1, st2) # returns the bi-variate spike synchronization
+ spike_sync(st1, st2, st3) # multi-variate result for 3 spike trains
+
+ spike_trains = [st1, st2, st3, st4] # list of spike trains
+ spike_sync(spike_trains) # spike-sync of the list of spike trains
+ 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`
+ """
+
+ if len(args) == 1:
+ return spike_sync_multi(args[0], **kwargs)
+ elif len(args) == 2:
+ return spike_sync_bi(args[0], args[1], **kwargs)
+ else:
+ return spike_sync_multi(args, **kwargs)
+
+
+############################################################
+# spike_sync_bi
+############################################################
+def spike_sync_bi(spike_train1, spike_train2, interval=None, max_tau=None):
+ """ 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`
:param spike_train2: Second spike train.
@@ -126,38 +222,12 @@ def spike_sync(spike_train1, spike_train2, interval=None, 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).
-
- :param spike_trains: list of :class:`pyspike.SpikeTrain`
- :param indices: list of indices defining which spike trains to use,
- if None all given spike trains are used (default=None)
- :type indices: list or None
- :param max_tau: Maximum coincidence window size. If 0 or `None`, the
- coincidence window has no upper bound.
- :returns: The multi-variate spike sync profile :math:`<S_{sync}>(t)`
- :rtype: :class:`pyspike.function.DiscreteFunction`
-
- """
- prof_func = partial(spike_sync_profile, max_tau=max_tau)
- average_prof, M = _generic_profile_multi(spike_trains, prof_func,
- indices)
- # average_dist.mul_scalar(1.0/M) # no normalization here!
- return average_prof
-
-
-############################################################
# 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,
@@ -217,6 +287,6 @@ def spike_sync_matrix(spike_trains, indices=None, interval=None, max_tau=None):
:rtype: np.array
"""
- dist_func = partial(spike_sync, max_tau=max_tau)
+ dist_func = partial(spike_sync_bi, max_tau=max_tau)
return _generic_distance_matrix(spike_trains, dist_func,
indices, interval)
diff --git a/pyspike/spikes.py b/pyspike/spikes.py
index ab6d4c4..486a4a0 100644
--- a/pyspike/spikes.py
+++ b/pyspike/spikes.py
@@ -62,6 +62,31 @@ def load_spike_trains_from_txt(file_name, edges,
return spike_trains
+def import_spike_trains_from_time_series(file_name, start_time, time_bin,
+ separator=None, comment='#'):
+ """ Imports spike trains from time series consisting of 0 and 1 denoting
+ the absence or presence of a spike. Each line in the data file represents
+ one spike train.
+
+ :param file_name: The name of the data file containing the time series.
+ :param edges: A pair (T_start, T_end) of values representing the
+ start and end time of the spike train measurement
+ or a single value representing the end time, the
+ T_start is then assuemd as 0.
+ :param separator: The character used to seprate the values in the text file
+ :param comment: Lines starting with this character are ignored.
+
+ """
+ data = np.loadtxt(file_name, comments=comment, delimiter=separator)
+ time_points = start_time + time_bin + np.arange(len(data[0, :]))*time_bin
+ spike_trains = []
+ for time_series in data:
+ spike_trains.append(SpikeTrain(time_points[time_series > 0],
+ edges=[start_time,
+ time_points[-1]]))
+ return spike_trains
+
+
############################################################
# save_spike_trains_to_txt
############################################################
diff --git a/setup.py b/setup.py
index 8ef431a..b53304b 100644
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@ to compile cython files:
python setup.py build_ext --inplace
-Copyright 2014-2015, Mario Mulansky <mario.mulansky@gmx.net>
+Copyright 2014-2016, Mario Mulansky <mario.mulansky@gmx.net>
Distributed under the BSD License
@@ -55,7 +55,7 @@ elif use_c: # c files are there, compile to binaries
setup(
name='pyspike',
packages=find_packages(exclude=['doc']),
- version='0.4.0',
+ version='0.5.1',
cmdclass=cmdclass,
ext_modules=ext_modules,
include_dirs=[numpy.get_include()],
diff --git a/test/test_generic_interfaces.py b/test/test_generic_interfaces.py
new file mode 100644
index 0000000..7f08067
--- /dev/null
+++ b/test/test_generic_interfaces.py
@@ -0,0 +1,105 @@
+""" test_generic_interface.py
+
+Tests the generic interfaces of the profile and distance functions
+
+Copyright 2016, Mario Mulansky <mario.mulansky@gmx.net>
+
+Distributed under the BSD License
+
+"""
+
+from __future__ import print_function
+from numpy.testing import assert_equal
+
+import pyspike as spk
+from pyspike import SpikeTrain
+
+
+class dist_from_prof:
+ """ Simple functor that turns profile function into distance function by
+ calling profile.avrg().
+ """
+ def __init__(self, prof_func):
+ self.prof_func = prof_func
+
+ def __call__(self, *args, **kwargs):
+ if "interval" in kwargs:
+ # forward interval arg into avrg function
+ interval = kwargs.pop("interval")
+ return self.prof_func(*args, **kwargs).avrg(interval=interval)
+ else:
+ return self.prof_func(*args, **kwargs).avrg()
+
+
+def check_func(dist_func):
+ """ generic checker that tests the given distance function.
+ """
+ # generate spike trains:
+ t1 = SpikeTrain([0.2, 0.4, 0.6, 0.7], 1.0)
+ t2 = SpikeTrain([0.3, 0.45, 0.8, 0.9, 0.95], 1.0)
+ t3 = SpikeTrain([0.2, 0.4, 0.6], 1.0)
+ t4 = SpikeTrain([0.1, 0.4, 0.5, 0.6], 1.0)
+ spike_trains = [t1, t2, t3, t4]
+
+ isi12 = dist_func(t1, t2)
+ isi12_ = dist_func([t1, t2])
+ assert_equal(isi12, isi12_)
+
+ isi12_ = dist_func(spike_trains, indices=[0, 1])
+ assert_equal(isi12, isi12_)
+
+ isi123 = dist_func(t1, t2, t3)
+ isi123_ = dist_func([t1, t2, t3])
+ assert_equal(isi123, isi123_)
+
+ isi123_ = dist_func(spike_trains, indices=[0, 1, 2])
+ assert_equal(isi123, isi123_)
+
+ # run the same test with an additional interval parameter
+
+ isi12 = dist_func(t1, t2, interval=[0.0, 0.5])
+ isi12_ = dist_func([t1, t2], interval=[0.0, 0.5])
+ assert_equal(isi12, isi12_)
+
+ isi12_ = dist_func(spike_trains, indices=[0, 1], interval=[0.0, 0.5])
+ assert_equal(isi12, isi12_)
+
+ isi123 = dist_func(t1, t2, t3, interval=[0.0, 0.5])
+ isi123_ = dist_func([t1, t2, t3], interval=[0.0, 0.5])
+ assert_equal(isi123, isi123_)
+
+ isi123_ = dist_func(spike_trains, indices=[0, 1, 2], interval=[0.0, 0.5])
+ assert_equal(isi123, isi123_)
+
+
+def test_isi_profile():
+ check_func(dist_from_prof(spk.isi_profile))
+
+
+def test_isi_distance():
+ check_func(spk.isi_distance)
+
+
+def test_spike_profile():
+ check_func(dist_from_prof(spk.spike_profile))
+
+
+def test_spike_distance():
+ check_func(spk.spike_distance)
+
+
+def test_spike_sync_profile():
+ check_func(dist_from_prof(spk.spike_sync_profile))
+
+
+def test_spike_sync():
+ check_func(spk.spike_sync)
+
+
+if __name__ == "__main__":
+ test_isi_profile()
+ test_isi_distance()
+ test_spike_profile()
+ test_spike_distance()
+ test_spike_sync_profile()
+ test_spike_sync()
diff --git a/test/test_regression/test_regression_15.py b/test/test_regression/test_regression_15.py
index dcacae2..54adf23 100644
--- a/test/test_regression/test_regression_15.py
+++ b/test/test_regression/test_regression_15.py
@@ -20,6 +20,7 @@ import os
TEST_PATH = os.path.dirname(os.path.realpath(__file__))
TEST_DATA = os.path.join(TEST_PATH, "..", "SPIKE_Sync_Test.txt")
+
def test_regression_15_isi():
# load spike trains
spike_trains = spk.load_spike_trains_from_txt(TEST_DATA, edges=[0, 4000])
diff --git a/test/test_spikes.py b/test/test_spikes.py
index 609a819..bcface2 100644
--- a/test/test_spikes.py
+++ b/test/test_spikes.py
@@ -17,6 +17,10 @@ import os
TEST_PATH = os.path.dirname(os.path.realpath(__file__))
TEST_DATA = os.path.join(TEST_PATH, "PySpike_testdata.txt")
+TIME_SERIES_DATA = os.path.join(TEST_PATH, "time_series.txt")
+TIME_SERIES_SPIKES = os.path.join(TEST_PATH, "time_series_spike_trains.txt")
+
+
def test_load_from_txt():
spike_trains = spk.load_spike_trains_from_txt(TEST_DATA, edges=(0, 4000))
assert len(spike_trains) == 40
@@ -33,6 +37,21 @@ def test_load_from_txt():
assert spike_train.t_end == 4000
+def test_load_time_series():
+ spike_trains = spk.import_spike_trains_from_time_series(TIME_SERIES_DATA,
+ start_time=0,
+ time_bin=1)
+ assert len(spike_trains) == 40
+ spike_trains_check = spk.load_spike_trains_from_txt(TIME_SERIES_SPIKES,
+ edges=(0, 4000))
+
+ # check spike trains
+ for n in range(len(spike_trains)):
+ assert_equal(spike_trains[n].spikes, spike_trains_check[n].spikes)
+ assert_equal(spike_trains[n].t_start, 0)
+ assert_equal(spike_trains[n].t_end, 4000)
+
+
def check_merged_spikes(merged_spikes, spike_trains):
# create a flat array with all spike events
all_spikes = np.array([])