diff options
author | Mario Mulansky <mario.mulansky@gmx.net> | 2015-08-26 12:10:01 +0200 |
---|---|---|
committer | Mario Mulansky <mario.mulansky@gmx.net> | 2015-08-26 12:10:01 +0200 |
commit | 53fdbb7ddb2a3a5e8d6f75ad69f0da90d3b6b5e6 (patch) | |
tree | 10f1d220b07ca5b73f2d91c49cec7dd00618d284 | |
parent | 691bf73c06322a2c47c37a5c48d085b789c8e8bf (diff) |
reorganized directionality module
-rw-r--r-- | pyspike/__init__.py | 9 | ||||
-rw-r--r-- | pyspike/cython/cython_directionality.pyx (renamed from pyspike/directionality/cython/cython_directionality.pyx) | 0 | ||||
-rw-r--r-- | pyspike/cython/directionality_python_backend.py (renamed from pyspike/directionality/cython/directionality_python_backend.py) | 0 | ||||
-rw-r--r-- | pyspike/directionality/__init__.py | 13 | ||||
-rw-r--r-- | pyspike/directionality/cython/__init__.py | 0 | ||||
-rw-r--r-- | pyspike/spike_directionality.py (renamed from pyspike/directionality/spike_train_order.py) | 178 | ||||
-rw-r--r-- | setup.py | 12 | ||||
-rw-r--r-- | test/test_directionality.py (renamed from test/test_spike_delay_asymmetry.py) | 9 |
8 files changed, 96 insertions, 125 deletions
diff --git a/pyspike/__init__.py b/pyspike/__init__.py index 8d92ea4..a37174c 100644 --- a/pyspike/__init__.py +++ b/pyspike/__init__.py @@ -5,8 +5,8 @@ Distributed under the BSD License """ __all__ = ["isi_distance", "spike_distance", "spike_sync", "psth", - "spikes", "SpikeTrain", "PieceWiseConstFunc", "PieceWiseLinFunc", - "DiscreteFunc", "directionality"] + "spikes", "spike_directionality", "SpikeTrain", + "PieceWiseConstFunc", "PieceWiseLinFunc", "DiscreteFunc"] from PieceWiseConstFunc import PieceWiseConstFunc from PieceWiseLinFunc import PieceWiseLinFunc @@ -24,7 +24,10 @@ from psth import psth from spikes import load_spike_trains_from_txt, spike_train_from_string, \ merge_spike_trains, generate_poisson_spikes -import directionality as drct +from spike_directionality import spike_directionality, \ + spike_directionality_matrix, spike_train_order_profile, \ + optimal_spike_train_order_from_matrix, optimal_spike_train_order, \ + permutate_matrix # define the __version__ following # http://stackoverflow.com/questions/17583443 diff --git a/pyspike/directionality/cython/cython_directionality.pyx b/pyspike/cython/cython_directionality.pyx index e1f63c4..e1f63c4 100644 --- a/pyspike/directionality/cython/cython_directionality.pyx +++ b/pyspike/cython/cython_directionality.pyx diff --git a/pyspike/directionality/cython/directionality_python_backend.py b/pyspike/cython/directionality_python_backend.py index e14238f..e14238f 100644 --- a/pyspike/directionality/cython/directionality_python_backend.py +++ b/pyspike/cython/directionality_python_backend.py diff --git a/pyspike/directionality/__init__.py b/pyspike/directionality/__init__.py deleted file mode 100644 index 6f74c50..0000000 --- a/pyspike/directionality/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -""" -Copyright 2015, Mario Mulansky <mario.mulansky@gmx.net> - -Distributed under the BSD License -""" - -__all__ = ["spike_train_order"] - -from spike_train_order import spike_train_order_profile, \ - spike_train_order, spike_train_order_profile_multi, \ - spike_train_order_matrix, spike_order_values, \ - optimal_spike_train_order, optimal_spike_train_order_from_matrix, \ - permutate_matrix diff --git a/pyspike/directionality/cython/__init__.py b/pyspike/directionality/cython/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/pyspike/directionality/cython/__init__.py +++ /dev/null diff --git a/pyspike/directionality/spike_train_order.py b/pyspike/spike_directionality.py index 892ffd0..0e69cb5 100644 --- a/pyspike/directionality/spike_train_order.py +++ b/pyspike/spike_directionality.py @@ -1,72 +1,20 @@ -# Module containing functions to compute multivariate spike train order +# Module containing functions to compute the SPIKE directionality and the +# spike train order profile # Copyright 2015, Mario Mulansky <mario.mulansky@gmx.net> # Distributed under the BSD License import numpy as np from math import exp -from functools import partial import pyspike from pyspike import DiscreteFunc -from pyspike.generic import _generic_profile_multi ############################################################ -# spike_train_order_profile -############################################################ -def spike_train_order_profile(spike_train1, spike_train2, max_tau=None): - """ Computes the spike delay asymmetry profile A(t) of the two given - spike trains. Returns the profile as a DiscreteFunction object. - - :param spike_train1: First spike train. - :type spike_train1: :class:`pyspike.SpikeTrain` - :param spike_train2: Second spike train. - :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)`. - :rtype: :class:`pyspike.function.DiscreteFunction` - - """ - # check whether the spike trains are defined for the same interval - assert spike_train1.t_start == spike_train2.t_start, \ - "Given spike trains are not defined on the same interval!" - assert spike_train1.t_end == spike_train2.t_end, \ - "Given spike trains are not defined on the same interval!" - - # cython implementation - try: - from cython.cython_directionality import \ - spike_train_order_profile_cython as \ - spike_train_order_profile_impl - except ImportError: - # raise NotImplementedError() - if not(pyspike.disable_backend_warning): - print("Warning: spike_distance_cython not found. Make sure that \ -PySpike is installed by running\n 'python setup.py build_ext --inplace'!\n \ -Falling back to slow python backend.") - # use python backend - from cython.directionality_python_backend import \ - spike_train_order_python as spike_train_order_profile_impl - - if max_tau is None: - max_tau = 0.0 - - times, coincidences, multiplicity \ - = spike_train_order_profile_impl(spike_train1.spikes, - spike_train2.spikes, - spike_train1.t_start, - spike_train1.t_end, - max_tau) - - return DiscreteFunc(times, coincidences, multiplicity) - - +# spike_directionality ############################################################ -# spike_train_order -############################################################ -def spike_train_order(spike_train1, spike_train2, normalize=True, - interval=None, max_tau=None): - """ Computes the overall spike delay asymmetry value for two spike trains. +def spike_directionality(spike_train1, spike_train2, normalize=True, + interval=None, max_tau=None): + """ Computes the overall spike directionality for two spike trains. """ if interval is None: # distance over the whole interval is requested: use specific function @@ -83,8 +31,9 @@ def spike_train_order(spike_train1, spike_train2, normalize=True, max_tau) except ImportError: # Cython backend not available: fall back to profile averaging - c, mp = spike_train_order_profile(spike_train1, spike_train2, - max_tau).integral(interval) + c, mp = _spike_directionality_profile(spike_train1, + spike_train2, + max_tau).integral(interval) if normalize: return 1.0*c/mp else: @@ -95,39 +44,11 @@ def spike_train_order(spike_train1, spike_train2, normalize=True, ############################################################ -# spike_train_order_profile_multi -############################################################ -def spike_train_order_profile_multi(spike_trains, indices=None, - max_tau=None): - """ Computes the multi-variate spike delay asymmetry profile for a set of - spike trains. For each spike in the set of spike trains, the multi-variate - profile is defined as the sum of asymmetry values 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_train_order_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_train_order_matrix +# spike_directionality_matrix ############################################################ -def spike_train_order_matrix(spike_trains, normalize=True, indices=None, - interval=None, max_tau=None): - """ Computes the spike delay asymmetry matrix for the given spike trains. +def spike_directionality_matrix(spike_trains, normalize=True, indices=None, + interval=None, max_tau=None): + """ Computes the spike directionaity matrix for the given spike trains. """ if indices is None: indices = np.arange(len(spike_trains)) @@ -141,18 +62,18 @@ def spike_train_order_matrix(spike_trains, normalize=True, indices=None, distance_matrix = np.zeros((len(indices), len(indices))) for i, j in pairs: - d = spike_train_order(spike_trains[i], spike_trains[j], normalize, - interval, max_tau=max_tau) + d = spike_directionality(spike_trains[i], spike_trains[j], normalize, + interval, max_tau=max_tau) distance_matrix[i, j] = d distance_matrix[j, i] = -d return distance_matrix ############################################################ -# spike_order_values +# spike_train_order_profile ############################################################ -def spike_order_values(spike_trains, indices=None, - interval=None, max_tau=None): +def spike_train_order_profile(spike_trains, indices=None, + interval=None, max_tau=None): """ Computes the spike train symmetry value for each spike in each spike train. """ @@ -199,7 +120,7 @@ def spike_order_values(spike_trains, indices=None, ############################################################ -# optimal_asymmetry_order_from_matrix +# optimal_spike_train_order_from_matrix ############################################################ def optimal_spike_train_order_from_matrix(D, full_output=False): """ finds the best sorting via simulated annealing. @@ -248,7 +169,9 @@ def optimal_spike_train_order(spike_trains, indices=None, interval=None, annealing. Returns the optimal permutation p and A value. """ - D = spike_train_order_matrix(spike_trains, indices, interval, max_tau) + D = spike_directionality_matrix(spike_trains, normalize=False, + indices=indices, interval=interval, + max_tau=max_tau) return optimal_spike_train_order_from_matrix(D, full_output) @@ -256,9 +179,66 @@ def optimal_spike_train_order(spike_trains, indices=None, interval=None, # permutate_matrix ############################################################ def permutate_matrix(D, p): + """ Applies the permutation p to the columns and rows of matrix D. + Return the new permutated matrix. + """ N = len(D) D_p = np.empty_like(D) for n in xrange(N): for m in xrange(N): D_p[n, m] = D[p[n], p[m]] return D_p + + +# internal helper functions + +############################################################ +# _spike_directionality_profile +############################################################ +def _spike_directionality_profile(spike_train1, spike_train2, + max_tau=None): + """ Computes the spike delay asymmetry profile A(t) of the two given + spike trains. Returns the profile as a DiscreteFunction object. + + :param spike_train1: First spike train. + :type spike_train1: :class:`pyspike.SpikeTrain` + :param spike_train2: Second spike train. + :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)`. + :rtype: :class:`pyspike.function.DiscreteFunction` + + """ + # check whether the spike trains are defined for the same interval + assert spike_train1.t_start == spike_train2.t_start, \ + "Given spike trains are not defined on the same interval!" + assert spike_train1.t_end == spike_train2.t_end, \ + "Given spike trains are not defined on the same interval!" + + # cython implementation + try: + from cython.cython_directionality import \ + spike_train_order_profile_cython as \ + spike_train_order_profile_impl + except ImportError: + # raise NotImplementedError() + if not(pyspike.disable_backend_warning): + print("Warning: spike_distance_cython not found. Make sure that \ +PySpike is installed by running\n 'python setup.py build_ext --inplace'!\n \ +Falling back to slow python backend.") + # use python backend + from cython.directionality_python_backend import \ + spike_train_order_python as spike_train_order_profile_impl + + if max_tau is None: + max_tau = 0.0 + + times, coincidences, multiplicity \ + = spike_train_order_profile_impl(spike_train1.spikes, + spike_train2.spikes, + spike_train1.t_start, + spike_train1.t_end, + max_tau) + + return DiscreteFunc(times, coincidences, multiplicity) @@ -24,7 +24,7 @@ else: if os.path.isfile("pyspike/cython/cython_add.c") and \ os.path.isfile("pyspike/cython/cython_profiles.c") and \ os.path.isfile("pyspike/cython/cython_distances.c") and \ - os.path.isfile("pyspike/directionality/cython/cython_directionality.c"): + os.path.isfile("pyspike/cython/cython_directionality.c"): use_c = True else: use_c = False @@ -40,8 +40,8 @@ if use_cython: # Cython is available, compile .pyx -> .c ["pyspike/cython/cython_profiles.pyx"]), Extension("pyspike.cython.cython_distances", ["pyspike/cython/cython_distances.pyx"]), - Extension("pyspike.directionality.cython.cython_directionality", - ["pyspike/directionality/cython/cython_directionality.pyx"]) + Extension("pyspike.cython.cython_directionality", + ["pyspike/cython/cython_directionality.pyx"]) ] cmdclass.update({'build_ext': build_ext}) elif use_c: # c files are there, compile to binaries @@ -52,8 +52,8 @@ elif use_c: # c files are there, compile to binaries ["pyspike/cython/cython_profiles.c"]), Extension("pyspike.cython.cython_distances", ["pyspike/cython/cython_distances.c"]), - Extension("pyspike.directionality.cython.cython_directionality", - ["pyspike/directionality/cython/cython_directionality.c"]) + Extension("pyspike.cython.cython_directionality", + ["pyspike/cython/cython_directionality.c"]) ] # neither cython nor c files available -> automatic fall-back to python backend @@ -93,7 +93,7 @@ train similarity', package_data={ 'pyspike': ['cython/cython_add.c', 'cython/cython_profiles.c', 'cython/cython_distances.c', - 'directionality/cython/cython_directionality.c'], + 'cython/cython_directionality.c'], 'test': ['Spike_testdata.txt'] } ) diff --git a/test/test_spike_delay_asymmetry.py b/test/test_directionality.py index 9de16e5..5c3da00 100644 --- a/test/test_spike_delay_asymmetry.py +++ b/test/test_directionality.py @@ -14,6 +14,7 @@ from numpy.testing import assert_equal, assert_almost_equal, \ import pyspike as spk from pyspike import SpikeTrain, DiscreteFunc +from pyspike.spike_directionality import _spike_directionality_profile def test_profile(): @@ -23,12 +24,12 @@ def test_profile(): expected_y = np.array([1, 1, 1, 1, 1, 0, 0]) expected_mp = np.array([1, 1, 1, 1, 1, 2, 2]) - f = spk.drct.spike_train_order_profile(st1, st2) + f = _spike_directionality_profile(st1, st2) assert f.almost_equal(DiscreteFunc(expected_x, expected_y, expected_mp)) assert_almost_equal(f.avrg(), 2.0/3.0) - assert_almost_equal(spk.drct.spike_train_order(st1, st2), 2.0/3.0) - assert_almost_equal(spk.drct.spike_train_order(st1, st2, normalize=False), + assert_almost_equal(spk.spike_directionality(st1, st2), 2.0/3.0) + assert_almost_equal(spk.spike_directionality(st1, st2, normalize=False), 4.0) st3 = SpikeTrain([105, 195, 500], [0, 1000]) @@ -36,5 +37,5 @@ def test_profile(): expected_y = np.array([1, 1, 1, -1, -1, 0, 0, 0]) expected_mp = np.array([1, 1, 1, 1, 1, 1, 1, 1]) - f = spk.drct.spike_train_order_profile(st1, st3) + f = _spike_directionality_profile(st1, st3) assert f.almost_equal(DiscreteFunc(expected_x, expected_y, expected_mp)) |