summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/changelog40
-rw-r--r--debian/control29
-rw-r--r--debian/copyright36
-rw-r--r--debian/patches/0001-Use-assert_allclose-instead-of-assert_equal-in-tests.patch675
-rw-r--r--debian/patches/0002-Python-3.10-compatibility-fix.patch109
-rw-r--r--debian/patches/series2
-rwxr-xr-xdebian/rules9
-rw-r--r--debian/source/format1
-rw-r--r--debian/tests/control3
-rwxr-xr-xdebian/tests/upstream.sh14
-rw-r--r--debian/upstream/metadata13
-rw-r--r--debian/watch4
12 files changed, 935 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..60edbf7
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,40 @@
+python-pyspike (0.6.0-6) unstable; urgency=medium
+
+ * Call dh_numpy3.
+
+ -- Gard Spreemann <gspr@nonempty.org> Sat, 27 Nov 2021 16:52:29 +0100
+
+python-pyspike (0.6.0-5) unstable; urgency=medium
+
+ * Add patch to fix Python 3.10 compatibility.
+
+ -- Gard Spreemann <gspr@nonempty.org> Sun, 21 Nov 2021 15:14:28 +0100
+
+python-pyspike (0.6.0-4) unstable; urgency=medium
+
+ * Fix broken watch file.
+ * Correct typo in upstream/metadata file.
+ * Standards-version 4.6.0.1. No changes needed.
+
+ -- Gard Spreemann <gspr@nonempty.org> Fri, 15 Oct 2021 11:02:13 +0200
+
+python-pyspike (0.6.0-3) unstable; urgency=medium
+
+ * Move git repository to Salsa.
+ * DH compat 13.
+ * Start upstream/metadata file.
+ * Standards-version 4.5.1. No changes needed.
+
+ -- Gard Spreemann <gspr@nonempty.org> Sat, 23 Jan 2021 18:55:01 +0100
+
+python-pyspike (0.6.0-2) unstable; urgency=medium
+
+ * Add patch to allow floating point behavior differences in tests.
+
+ -- Gard Spreemann <gspr@nonempty.org> Sat, 07 Mar 2020 18:53:50 +0100
+
+python-pyspike (0.6.0-1) unstable; urgency=medium
+
+ * Initial release. (Closes: #932726)
+
+ -- Gard Spreemann <gspr@nonempty.org> Thu, 06 Feb 2020 09:47:07 +0100
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..db9461c
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,29 @@
+Source: python-pyspike
+Maintainer: Gard Spreemann <gspr@nonempty.org>
+Section: python
+Priority: optional
+Standards-Version: 4.6.0.1
+Build-Depends: cython3,
+ debhelper-compat (= 13),
+ dh-python,
+ python3-all-dev,
+ python3-nose,
+ python3-numpy,
+ python3-setuptools
+Rules-Requires-Root: no
+Homepage: https://mariomulansky.github.io/PySpike/
+Vcs-Browser: https://salsa.debian.org/gspr/python-pyspike
+Vcs-Git: https://salsa.debian.org/gspr/python-pyspike.git -b debian/sid
+
+Package: python3-pyspike
+Section: python
+Architecture: any
+Depends: ${misc:Depends},
+ ${python3:Depends},
+ ${shlibs:Depends}
+Description: Python 3 library for the numerical analysis of spike train similarity
+ PySpike is a Python library for the numerical analysis of spike train
+ similarity. Its core functionality is the implementation of the
+ ISI-distance 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.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..cb9d82d
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,36 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: pyspike
+Source: https://mariomulansky.github.io/PySpike/
+
+Files: *
+Copyright: 2014-2021 Mario Mulansky <mario.mulansky@gmx.net>
+License: BSD-2-clause
+
+Files: debian/*
+Copyright: 2019-2021 Gard Spreemann <gspr@nonempty.org>
+License: BSD-2-clause
+
+License: BSD-2-clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ .
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ .
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
diff --git a/debian/patches/0001-Use-assert_allclose-instead-of-assert_equal-in-tests.patch b/debian/patches/0001-Use-assert_allclose-instead-of-assert_equal-in-tests.patch
new file mode 100644
index 0000000..b03409d
--- /dev/null
+++ b/debian/patches/0001-Use-assert_allclose-instead-of-assert_equal-in-tests.patch
@@ -0,0 +1,675 @@
+From: Gard Spreemann <gspr@nonempty.org>
+Date: Sat, 7 Mar 2020 18:51:42 +0100
+Subject: Use assert_allclose instead of assert_equal in tests.
+
+---
+ test/test_distance.py | 70 +++++++++++++++---------------
+ test/test_empty.py | 36 +++++++--------
+ test/test_function.py | 52 +++++++++++-----------
+ test/test_generic_interfaces.py | 18 ++++----
+ test/test_regression/test_regression_15.py | 20 ++++-----
+ test/test_spikes.py | 10 ++---
+ test/test_sync_filter.py | 32 +++++++-------
+ 7 files changed, 119 insertions(+), 119 deletions(-)
+
+diff --git a/test/test_distance.py b/test/test_distance.py
+index fe09f34..7ec3a72 100644
+--- a/test/test_distance.py
++++ b/test/test_distance.py
+@@ -11,7 +11,7 @@ Distributed under the BSD License
+ from __future__ import print_function
+ import numpy as np
+ from copy import copy
+-from numpy.testing import assert_equal, assert_almost_equal, \
++from numpy.testing import assert_allclose, assert_almost_equal, \
+ assert_array_almost_equal
+
+ import pyspike as spk
+@@ -41,10 +41,10 @@ def test_isi():
+ # print("ISI: ", f.y)
+ print("ISI value:", expected_isi_val)
+
+- assert_equal(f.x, expected_times)
++ assert_allclose(f.x, expected_times)
+ assert_array_almost_equal(f.y, expected_isi, decimal=15)
+- assert_equal(f.avrg(), expected_isi_val)
+- assert_equal(spk.isi_distance(t1, t2), expected_isi_val)
++ assert_allclose(f.avrg(), expected_isi_val)
++ assert_allclose(spk.isi_distance(t1, t2), expected_isi_val)
+
+ # check with some equal spike times
+ t1 = SpikeTrain([0.2, 0.4, 0.6], [0.0, 1.0])
+@@ -60,10 +60,10 @@ def test_isi():
+
+ f = spk.isi_profile(t1, t2)
+
+- assert_equal(f.x, expected_times)
++ assert_allclose(f.x, expected_times)
+ assert_array_almost_equal(f.y, expected_isi, decimal=15)
+- assert_equal(f.avrg(), expected_isi_val)
+- assert_equal(spk.isi_distance(t1, t2), expected_isi_val)
++ assert_allclose(f.avrg(), expected_isi_val)
++ assert_allclose(spk.isi_distance(t1, t2), expected_isi_val)
+
+
+ def test_spike():
+@@ -75,7 +75,7 @@ def test_spike():
+
+ f = spk.spike_profile(t1, t2)
+
+- assert_equal(f.x, expected_times)
++ assert_allclose(f.x, expected_times)
+
+ # from SPIKY:
+ y_all = np.array([0.000000000000000000, 0.555555555555555580,
+@@ -89,7 +89,7 @@ def test_spike():
+ assert_array_almost_equal(f.y2, y_all[1::2])
+
+ assert_almost_equal(f.avrg(), 0.186309523809523814, decimal=15)
+- assert_equal(spk.spike_distance(t1, t2), f.avrg())
++ assert_allclose(spk.spike_distance(t1, t2), f.avrg())
+
+ 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)
+@@ -118,7 +118,7 @@ def test_spike():
+
+ f = spk.spike_profile(t1, t2)
+
+- assert_equal(f.x, expected_times)
++ assert_allclose(f.x, expected_times)
+ assert_array_almost_equal(f.y1, expected_y1, decimal=15)
+ assert_array_almost_equal(f.y2, expected_y2, decimal=15)
+ assert_almost_equal(f.avrg(), expected_spike_val, decimal=15)
+@@ -157,7 +157,7 @@ def test_spike():
+
+ f = spk.spike_profile(t1, t2)
+
+- assert_equal(f.x, expected_times)
++ assert_allclose(f.x, expected_times)
+ assert_array_almost_equal(f.y1, expected_y1, decimal=14)
+ assert_array_almost_equal(f.y2, expected_y2, decimal=14)
+ assert_almost_equal(f.avrg(), expected_spike_val, decimal=16)
+@@ -236,8 +236,8 @@ def test_spike_sync():
+ f.add(f2)
+ i12 = f.integral()
+
+- assert_equal(i1[0]+i2[0], i12[0])
+- assert_equal(i1[1]+i2[1], i12[1])
++ assert_allclose(i1[0]+i2[0], i12[0])
++ assert_allclose(i1[1]+i2[1], i12[1])
+
+
+ def check_multi_profile(profile_func, profile_func_multi, dist_func_multi):
+@@ -258,7 +258,7 @@ def check_multi_profile(profile_func, profile_func_multi, dist_func_multi):
+ f_multi = profile_func_multi(spike_trains, [0, 1])
+ assert f_multi.almost_equal(f12, decimal=14)
+ d = dist_func_multi(spike_trains, [0, 1])
+- assert_equal(f_multi.avrg(), d)
++ assert_allclose(f_multi.avrg(), d)
+
+ f_multi1 = profile_func_multi(spike_trains, [1, 2, 3])
+ f_multi2 = profile_func_multi(spike_trains[1:])
+@@ -329,11 +329,11 @@ def test_multi_spike_sync():
+
+ f = spk.spike_sync_profile_multi(spike_trains)
+
+- assert_equal(spike_times, f.x[1:-1])
+- assert_equal(len(f.x), len(f.y))
++ assert_allclose(spike_times, f.x[1:-1])
++ assert_allclose(len(f.x), len(f.y))
+
+- assert_equal(np.sum(f.y[1:-1]), 39932)
+- assert_equal(np.sum(f.mp[1:-1]), 85554)
++ assert_allclose(np.sum(f.y[1:-1]), 39932)
++ assert_allclose(np.sum(f.mp[1:-1]), 85554)
+
+ # example with 2 empty spike trains
+ sts = []
+@@ -365,16 +365,16 @@ def check_dist_matrix(dist_func, dist_matrix_func):
+ f_matrix = dist_matrix_func(spike_trains)
+ # check zero diagonal
+ for i in range(4):
+- assert_equal(0.0, f_matrix[i, i])
++ assert_allclose(0.0, f_matrix[i, i])
+ for i in range(4):
+ for j in range(i+1, 4):
+- assert_equal(f_matrix[i, j], f_matrix[j, i])
+- assert_equal(f12, f_matrix[1, 0])
+- assert_equal(f13, f_matrix[2, 0])
+- assert_equal(f14, f_matrix[3, 0])
+- assert_equal(f23, f_matrix[2, 1])
+- assert_equal(f24, f_matrix[3, 1])
+- assert_equal(f34, f_matrix[3, 2])
++ assert_allclose(f_matrix[i, j], f_matrix[j, i])
++ assert_allclose(f12, f_matrix[1, 0])
++ assert_allclose(f13, f_matrix[2, 0])
++ assert_allclose(f14, f_matrix[3, 0])
++ assert_allclose(f23, f_matrix[2, 1])
++ assert_allclose(f24, f_matrix[3, 1])
++ assert_allclose(f34, f_matrix[3, 2])
+
+
+ def test_isi_matrix():
+@@ -397,13 +397,13 @@ def test_regression_spiky():
+ isi_dist = spk.isi_distance(st1, st2)
+ assert_almost_equal(isi_dist, 9.0909090909090939e-02, decimal=15)
+ isi_profile = spk.isi_profile(st1, st2)
+- assert_equal(isi_profile.y, 0.1/1.1 * np.ones_like(isi_profile.y))
++ assert_allclose(isi_profile.y, 0.1/1.1 * np.ones_like(isi_profile.y))
+
+ spike_dist = spk.spike_distance(st1, st2)
+- assert_equal(spike_dist, 0.211058782487353908)
++ assert_allclose(spike_dist, 0.211058782487353908)
+
+ spike_sync = spk.spike_sync(st1, st2)
+- assert_equal(spike_sync, 8.6956521739130432e-01)
++ assert_allclose(spike_sync, 8.6956521739130432e-01)
+
+ # multivariate check
+
+@@ -414,7 +414,7 @@ def test_regression_spiky():
+ assert_almost_equal(isi_dist, 0.17051816816999129656, decimal=15)
+
+ spike_profile = spk.spike_profile_multi(spike_trains)
+- assert_equal(len(spike_profile.y1)+len(spike_profile.y2), 1252)
++ assert_allclose(len(spike_profile.y1)+len(spike_profile.y2), 1252)
+
+ spike_dist = spk.spike_distance_multi(spike_trains)
+ # get the full precision from SPIKY
+@@ -422,7 +422,7 @@ def test_regression_spiky():
+
+ spike_sync = spk.spike_sync_multi(spike_trains)
+ # get the full precision from SPIKY
+- assert_equal(spike_sync, 0.7183531505298066)
++ assert_allclose(spike_sync, 0.7183531505298066)
+
+ # Eero's edge correction example
+ st1 = SpikeTrain([0.5, 1.5, 2.5], 6.0)
+@@ -439,7 +439,7 @@ def test_regression_spiky():
+ expected_y1 = y_all[::2]
+ expected_y2 = y_all[1::2]
+
+- assert_equal(f.x, expected_times)
++ assert_allclose(f.x, expected_times)
+ assert_array_almost_equal(f.y1, expected_y1, decimal=14)
+ assert_array_almost_equal(f.y2, expected_y2, decimal=14)
+
+@@ -452,15 +452,15 @@ def test_multi_variate_subsets():
+
+ v1 = spk.isi_distance_multi(spike_trains_sub_set)
+ v2 = spk.isi_distance_multi(spike_trains, sub_set)
+- assert_equal(v1, v2)
++ assert_allclose(v1, v2)
+
+ v1 = spk.spike_distance_multi(spike_trains_sub_set)
+ v2 = spk.spike_distance_multi(spike_trains, sub_set)
+- assert_equal(v1, v2)
++ assert_allclose(v1, v2)
+
+ v1 = spk.spike_sync_multi(spike_trains_sub_set)
+ v2 = spk.spike_sync_multi(spike_trains, sub_set)
+- assert_equal(v1, v2)
++ assert_allclose(v1, v2)
+
+
+ if __name__ == "__main__":
+diff --git a/test/test_empty.py b/test/test_empty.py
+index 4d0a5cf..93fd2c1 100644
+--- a/test/test_empty.py
++++ b/test/test_empty.py
+@@ -10,7 +10,7 @@ Distributed under the BSD License
+
+ from __future__ import print_function
+ import numpy as np
+-from numpy.testing import assert_equal, assert_almost_equal, \
++from numpy.testing import assert_allclose, assert_almost_equal, \
+ assert_array_equal, assert_array_almost_equal
+
+ import pyspike as spk
+@@ -33,18 +33,18 @@ def test_isi_empty():
+ st1 = SpikeTrain([], edges=(0.0, 1.0))
+ st2 = SpikeTrain([], edges=(0.0, 1.0))
+ d = spk.isi_distance(st1, st2)
+- assert_equal(d, 0.0)
++ assert_allclose(d, 0.0)
+ prof = spk.isi_profile(st1, st2)
+- assert_equal(d, prof.avrg())
++ assert_allclose(d, prof.avrg())
+ assert_array_equal(prof.x, [0.0, 1.0])
+ assert_array_equal(prof.y, [0.0, ])
+
+ st1 = SpikeTrain([], edges=(0.0, 1.0))
+ st2 = SpikeTrain([0.4, ], edges=(0.0, 1.0))
+ d = spk.isi_distance(st1, st2)
+- assert_equal(d, 0.6*0.4+0.4*0.6)
++ assert_allclose(d, 0.6*0.4+0.4*0.6)
+ prof = spk.isi_profile(st1, st2)
+- assert_equal(d, prof.avrg())
++ assert_allclose(d, prof.avrg())
+ assert_array_equal(prof.x, [0.0, 0.4, 1.0])
+ assert_array_equal(prof.y, [0.6, 0.4])
+
+@@ -53,7 +53,7 @@ def test_isi_empty():
+ d = spk.isi_distance(st1, st2)
+ assert_almost_equal(d, 0.2/0.6*0.4 + 0.0 + 0.2/0.6*0.4, decimal=15)
+ prof = spk.isi_profile(st1, st2)
+- assert_equal(d, prof.avrg())
++ assert_allclose(d, prof.avrg())
+ assert_array_almost_equal(prof.x, [0.0, 0.4, 0.6, 1.0], decimal=15)
+ assert_array_almost_equal(prof.y, [0.2/0.6, 0.0, 0.2/0.6], decimal=15)
+
+@@ -62,9 +62,9 @@ def test_spike_empty():
+ st1 = SpikeTrain([], edges=(0.0, 1.0))
+ st2 = SpikeTrain([], edges=(0.0, 1.0))
+ d = spk.spike_distance(st1, st2)
+- assert_equal(d, 0.0)
++ assert_allclose(d, 0.0)
+ prof = spk.spike_profile(st1, st2)
+- assert_equal(d, prof.avrg())
++ assert_allclose(d, prof.avrg())
+ assert_array_equal(prof.x, [0.0, 1.0])
+ assert_array_equal(prof.y1, [0.0, ])
+ assert_array_equal(prof.y2, [0.0, ])
+@@ -75,7 +75,7 @@ def test_spike_empty():
+ d_expect = 2*0.4*0.4*1.0/(0.4+1.0)**2 + 2*0.6*0.4*1.0/(0.6+1.0)**2
+ assert_almost_equal(d, d_expect, decimal=15)
+ prof = spk.spike_profile(st1, st2)
+- assert_equal(d, prof.avrg())
++ assert_allclose(d, prof.avrg())
+ assert_array_equal(prof.x, [0.0, 0.4, 1.0])
+ assert_array_almost_equal(prof.y1, [2*0.4*1.0/(0.4+1.0)**2,
+ 2*0.4*1.0/(0.6+1.0)**2],
+@@ -100,7 +100,7 @@ def test_spike_empty():
+
+ assert_almost_equal(d, expected_spike_val, decimal=15)
+ prof = spk.spike_profile(st1, st2)
+- assert_equal(d, prof.avrg())
++ assert_allclose(d, prof.avrg())
+ assert_array_almost_equal(prof.x, [0.0, 0.4, 0.6, 1.0], decimal=15)
+ assert_array_almost_equal(prof.y1, expected_y1, decimal=15)
+ assert_array_almost_equal(prof.y2, expected_y2, decimal=15)
+@@ -110,18 +110,18 @@ def test_spike_sync_empty():
+ st1 = SpikeTrain([], edges=(0.0, 1.0))
+ st2 = SpikeTrain([], edges=(0.0, 1.0))
+ d = spk.spike_sync(st1, st2)
+- assert_equal(d, 1.0)
++ assert_allclose(d, 1.0)
+ prof = spk.spike_sync_profile(st1, st2)
+- assert_equal(d, prof.avrg())
++ assert_allclose(d, prof.avrg())
+ assert_array_equal(prof.x, [0.0, 1.0])
+ assert_array_equal(prof.y, [1.0, 1.0])
+
+ st1 = SpikeTrain([], edges=(0.0, 1.0))
+ st2 = SpikeTrain([0.4, ], edges=(0.0, 1.0))
+ d = spk.spike_sync(st1, st2)
+- assert_equal(d, 0.0)
++ assert_allclose(d, 0.0)
+ prof = spk.spike_sync_profile(st1, st2)
+- assert_equal(d, prof.avrg())
++ assert_allclose(d, prof.avrg())
+ assert_array_equal(prof.x, [0.0, 0.4, 1.0])
+ assert_array_equal(prof.y, [0.0, 0.0, 0.0])
+
+@@ -130,7 +130,7 @@ def test_spike_sync_empty():
+ d = spk.spike_sync(st1, st2)
+ assert_almost_equal(d, 1.0, decimal=15)
+ prof = spk.spike_sync_profile(st1, st2)
+- assert_equal(d, prof.avrg())
++ assert_allclose(d, prof.avrg())
+ assert_array_almost_equal(prof.x, [0.0, 0.4, 0.6, 1.0], decimal=15)
+ assert_array_almost_equal(prof.y, [1.0, 1.0, 1.0, 1.0], decimal=15)
+
+@@ -139,7 +139,7 @@ def test_spike_sync_empty():
+ d = spk.spike_sync(st1, st2)
+ assert_almost_equal(d, 0.0, decimal=15)
+ prof = spk.spike_sync_profile(st1, st2)
+- assert_equal(d, prof.avrg())
++ assert_allclose(d, prof.avrg())
+ assert_array_almost_equal(prof.x, [0.0, 0.2, 0.8, 1.0], decimal=15)
+ assert_array_almost_equal(prof.y, [0.0, 0.0, 0.0, 0.0], decimal=15)
+
+@@ -148,9 +148,9 @@ def test_spike_sync_empty():
+ st2 = SpikeTrain([2.1, 7.0], [0, 10.0])
+ st3 = SpikeTrain([5.1, 6.0], [0, 10.0])
+ res = spk.spike_sync_profile(st1, st2).avrg(interval=[3.0, 4.0])
+- assert_equal(res, 1.0)
++ assert_allclose(res, 1.0)
+ res = spk.spike_sync(st1, st2, interval=[3.0, 4.0])
+- assert_equal(res, 1.0)
++ assert_allclose(res, 1.0)
+
+ sync_matrix = spk.spike_sync_matrix([st1, st2, st3], interval=[3.0, 4.0])
+ assert_array_equal(sync_matrix, np.ones((3, 3)) - np.diag(np.ones(3)))
+diff --git a/test/test_function.py b/test/test_function.py
+index 6c04839..ba10ae7 100644
+--- a/test/test_function.py
++++ b/test/test_function.py
+@@ -11,7 +11,7 @@ from __future__ import print_function
+ import numpy as np
+ from copy import copy
+ from nose.tools import raises
+-from numpy.testing import assert_equal, assert_almost_equal, \
++from numpy.testing import assert_allclose, assert_almost_equal, \
+ assert_array_equal, assert_array_almost_equal
+
+ import pyspike as spk
+@@ -24,14 +24,14 @@ def test_pwc():
+ f = spk.PieceWiseConstFunc(x, y)
+
+ # function values
+- assert_equal(f(0.0), 1.0)
+- assert_equal(f(0.5), 1.0)
+- assert_equal(f(1.0), 0.25)
+- assert_equal(f(2.0), 0.5)
+- assert_equal(f(2.25), 1.5)
+- assert_equal(f(2.5), 2.25/2)
+- assert_equal(f(3.5), 0.75)
+- assert_equal(f(4.0), 0.75)
++ assert_allclose(f(0.0), 1.0)
++ assert_allclose(f(0.5), 1.0)
++ assert_allclose(f(1.0), 0.25)
++ assert_allclose(f(2.0), 0.5)
++ assert_allclose(f(2.25), 1.5)
++ assert_allclose(f(2.5), 2.25/2)
++ assert_allclose(f(3.5), 0.75)
++ assert_allclose(f(4.0), 0.75)
+
+ assert_array_equal(f([0.0, 0.5, 1.0, 2.0, 2.25, 2.5, 3.5, 4.0]),
+ [1.0, 1.0, 0.25, 0.5, 1.5, 2.25/2, 0.75, 0.75])
+@@ -131,21 +131,21 @@ def test_pwc_integral():
+
+ # test full interval
+ full = 1.0*1.0 + 1.0*-0.5 + 0.5*1.5 + 1.5*0.75;
+- assert_equal(f1.integral(), full)
+- assert_equal(f1.integral((np.min(x),np.max(x))), full)
++ assert_allclose(f1.integral(), full)
++ assert_allclose(f1.integral((np.min(x),np.max(x))), full)
+ # test part interval, spanning an edge
+- assert_equal(f1.integral((0.5,1.5)), 0.5*1.0 + 0.5*-0.5)
++ assert_allclose(f1.integral((0.5,1.5)), 0.5*1.0 + 0.5*-0.5)
+ # test part interval, just over two edges
+ assert_almost_equal(f1.integral((1.0-1e-16,2+1e-16)), 1.0*-0.5, decimal=14)
+ # test part interval, between two edges
+- assert_equal(f1.integral((1.0,2.0)), 1.0*-0.5)
+- assert_equal(f1.integral((1.2,1.7)), (1.7-1.2)*-0.5)
++ assert_allclose(f1.integral((1.0,2.0)), 1.0*-0.5)
++ assert_allclose(f1.integral((1.2,1.7)), (1.7-1.2)*-0.5)
+ # test part interval, start to before and after edge
+- assert_equal(f1.integral((0.0,0.7)), 0.7*1.0)
+- assert_equal(f1.integral((0.0,1.1)), 1.0*1.0+0.1*-0.5)
++ assert_allclose(f1.integral((0.0,0.7)), 0.7*1.0)
++ assert_allclose(f1.integral((0.0,1.1)), 1.0*1.0+0.1*-0.5)
+ # test part interval, before and after edge till end
+- assert_equal(f1.integral((2.6,4.0)), (4.0-2.6)*0.75)
+- assert_equal(f1.integral((2.4,4.0)), (2.5-2.4)*1.5+(4-2.5)*0.75)
++ assert_allclose(f1.integral((2.6,4.0)), (4.0-2.6)*0.75)
++ assert_allclose(f1.integral((2.4,4.0)), (2.5-2.4)*1.5+(4-2.5)*0.75)
+
+ @raises(ValueError)
+ def test_pwc_integral_bad_bounds_inv():
+@@ -178,14 +178,14 @@ def test_pwl():
+ f = spk.PieceWiseLinFunc(x, y1, y2)
+
+ # function values
+- assert_equal(f(0.0), 1.0)
+- assert_equal(f(0.5), 1.25)
+- assert_equal(f(1.0), 0.5)
+- assert_equal(f(2.0), 1.1/2)
+- assert_equal(f(2.25), 1.5)
+- assert_equal(f(2.5), 2.25/2)
+- assert_equal(f(3.5), 0.75-0.5*1.0/1.5)
+- assert_equal(f(4.0), 0.25)
++ assert_allclose(f(0.0), 1.0)
++ assert_allclose(f(0.5), 1.25)
++ assert_allclose(f(1.0), 0.5)
++ assert_allclose(f(2.0), 1.1/2)
++ assert_allclose(f(2.25), 1.5)
++ assert_allclose(f(2.5), 2.25/2)
++ assert_allclose(f(3.5), 0.75-0.5*1.0/1.5)
++ assert_allclose(f(4.0), 0.25)
+
+ assert_array_equal(f([0.0, 0.5, 1.0, 2.0, 2.25, 2.5, 3.5, 4.0]),
+ [1.0, 1.25, 0.5, 0.55, 1.5, 2.25/2, 0.75-0.5/1.5, 0.25])
+diff --git a/test/test_generic_interfaces.py b/test/test_generic_interfaces.py
+index 7f08067..553f3f4 100644
+--- a/test/test_generic_interfaces.py
++++ b/test/test_generic_interfaces.py
+@@ -9,7 +9,7 @@ Distributed under the BSD License
+ """
+
+ from __future__ import print_function
+-from numpy.testing import assert_equal
++from numpy.testing import assert_allclose
+
+ import pyspike as spk
+ from pyspike import SpikeTrain
+@@ -43,33 +43,33 @@ def check_func(dist_func):
+
+ isi12 = dist_func(t1, t2)
+ isi12_ = dist_func([t1, t2])
+- assert_equal(isi12, isi12_)
++ assert_allclose(isi12, isi12_)
+
+ isi12_ = dist_func(spike_trains, indices=[0, 1])
+- assert_equal(isi12, isi12_)
++ assert_allclose(isi12, isi12_)
+
+ isi123 = dist_func(t1, t2, t3)
+ isi123_ = dist_func([t1, t2, t3])
+- assert_equal(isi123, isi123_)
++ assert_allclose(isi123, isi123_)
+
+ isi123_ = dist_func(spike_trains, indices=[0, 1, 2])
+- assert_equal(isi123, isi123_)
++ assert_allclose(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_)
++ assert_allclose(isi12, isi12_)
+
+ isi12_ = dist_func(spike_trains, indices=[0, 1], interval=[0.0, 0.5])
+- assert_equal(isi12, isi12_)
++ assert_allclose(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_)
++ assert_allclose(isi123, isi123_)
+
+ isi123_ = dist_func(spike_trains, indices=[0, 1, 2], interval=[0.0, 0.5])
+- assert_equal(isi123, isi123_)
++ assert_allclose(isi123, isi123_)
+
+
+ def test_isi_profile():
+diff --git a/test/test_regression/test_regression_15.py b/test/test_regression/test_regression_15.py
+index 54adf23..81b5bb0 100644
+--- a/test/test_regression/test_regression_15.py
++++ b/test/test_regression/test_regression_15.py
+@@ -11,7 +11,7 @@ Distributed under the BSD License
+ from __future__ import division
+
+ import numpy as np
+-from numpy.testing import assert_equal, assert_almost_equal, \
++from numpy.testing import assert_allclose, assert_almost_equal, \
+ assert_array_almost_equal
+
+ import pyspike as spk
+@@ -28,15 +28,15 @@ def test_regression_15_isi():
+ N = len(spike_trains)
+
+ dist_mat = spk.isi_distance_matrix(spike_trains)
+- assert_equal(dist_mat.shape, (N, N))
++ assert_allclose(dist_mat.shape, (N, N))
+
+ ind = np.arange(N//2)
+ dist_mat = spk.isi_distance_matrix(spike_trains, ind)
+- assert_equal(dist_mat.shape, (N//2, N//2))
++ assert_allclose(dist_mat.shape, (N//2, N//2))
+
+ ind = np.arange(N//2, N)
+ dist_mat = spk.isi_distance_matrix(spike_trains, ind)
+- assert_equal(dist_mat.shape, (N//2, N//2))
++ assert_allclose(dist_mat.shape, (N//2, N//2))
+
+
+ def test_regression_15_spike():
+@@ -46,15 +46,15 @@ def test_regression_15_spike():
+ N = len(spike_trains)
+
+ dist_mat = spk.spike_distance_matrix(spike_trains)
+- assert_equal(dist_mat.shape, (N, N))
++ assert_allclose(dist_mat.shape, (N, N))
+
+ ind = np.arange(N//2)
+ dist_mat = spk.spike_distance_matrix(spike_trains, ind)
+- assert_equal(dist_mat.shape, (N//2, N//2))
++ assert_allclose(dist_mat.shape, (N//2, N//2))
+
+ ind = np.arange(N//2, N)
+ dist_mat = spk.spike_distance_matrix(spike_trains, ind)
+- assert_equal(dist_mat.shape, (N//2, N//2))
++ assert_allclose(dist_mat.shape, (N//2, N//2))
+
+
+ def test_regression_15_sync():
+@@ -64,15 +64,15 @@ def test_regression_15_sync():
+ N = len(spike_trains)
+
+ dist_mat = spk.spike_sync_matrix(spike_trains)
+- assert_equal(dist_mat.shape, (N, N))
++ assert_allclose(dist_mat.shape, (N, N))
+
+ ind = np.arange(N//2)
+ dist_mat = spk.spike_sync_matrix(spike_trains, ind)
+- assert_equal(dist_mat.shape, (N//2, N//2))
++ assert_allclose(dist_mat.shape, (N//2, N//2))
+
+ ind = np.arange(N//2, N)
+ dist_mat = spk.spike_sync_matrix(spike_trains, ind)
+- assert_equal(dist_mat.shape, (N//2, N//2))
++ assert_allclose(dist_mat.shape, (N//2, N//2))
+
+
+ if __name__ == "__main__":
+diff --git a/test/test_spikes.py b/test/test_spikes.py
+index ee505b5..579f8e1 100644
+--- a/test/test_spikes.py
++++ b/test/test_spikes.py
+@@ -9,7 +9,7 @@ Distributed under the BSD License
+
+ from __future__ import print_function
+ import numpy as np
+-from numpy.testing import assert_equal
++from numpy.testing import assert_allclose
+
+ import pyspike as spk
+
+@@ -29,7 +29,7 @@ def test_load_from_txt():
+ spike_times = [64.886, 305.81, 696, 937.77, 1059.7, 1322.2, 1576.1,
+ 1808.1, 2121.5, 2381.1, 2728.6, 2966.9, 3223.7, 3473.7,
+ 3644.3, 3936.3]
+- assert_equal(spike_times, spike_trains[0].spikes)
++ assert_allclose(spike_times, spike_trains[0].spikes)
+
+ # check auxiliary spikes
+ for spike_train in spike_trains:
+@@ -47,9 +47,9 @@ def test_load_time_series():
+
+ # 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)
++ assert_allclose(spike_trains[n].spikes, spike_trains_check[n].spikes)
++ assert_allclose(spike_trains[n].t_start, 0)
++ assert_allclose(spike_trains[n].t_end, 4000)
+
+
+ def check_merged_spikes(merged_spikes, spike_trains):
+diff --git a/test/test_sync_filter.py b/test/test_sync_filter.py
+index e259903..0b915db 100644
+--- a/test/test_sync_filter.py
++++ b/test/test_sync_filter.py
+@@ -10,7 +10,7 @@ Distributed under the BSD License
+
+ from __future__ import print_function
+ import numpy as np
+-from numpy.testing import assert_equal, assert_almost_equal, \
++from numpy.testing import assert_allclose, assert_almost_equal, \
+ assert_array_almost_equal
+
+ import pyspike as spk
+@@ -36,21 +36,21 @@ def test_single_prof():
+ coincidences = np.array(coincidence_impl(st1, st2, 0, 5.0, 0.0))
+ print(coincidences)
+ for i, t in enumerate(st1):
+- assert_equal(coincidences[i], sync_prof.y[sync_prof.x == t],
+- "At index %d" % i)
++ assert_allclose(coincidences[i], sync_prof.y[sync_prof.x == t],
++ err_msg="At index %d" % i)
+
+ coincidences = np.array(coincidence_impl(st2, st1, 0, 5.0, 0.0))
+ for i, t in enumerate(st2):
+- assert_equal(coincidences[i], sync_prof.y[sync_prof.x == t],
+- "At index %d" % i)
++ assert_allclose(coincidences[i], sync_prof.y[sync_prof.x == t],
++ err_msg="At index %d" % i)
+
+ sync_prof = spk.spike_sync_profile(SpikeTrain(st1, 5.0),
+ SpikeTrain(st3, 5.0))
+
+ coincidences = np.array(coincidence_impl(st1, st3, 0, 5.0, 0.0))
+ for i, t in enumerate(st1):
+- assert_equal(coincidences[i], sync_prof.y[sync_prof.x == t],
+- "At index %d" % i)
++ assert_allclose(coincidences[i], sync_prof.y[sync_prof.x == t],
++ err_msg="At index %d" % i)
+
+ st1 = np.array([1.0, 2.0, 3.0, 4.0])
+ st2 = np.array([1.0, 2.0, 4.0])
+@@ -61,8 +61,8 @@ def test_single_prof():
+ coincidences = np.array(coincidence_impl(st1, st2, 0, 5.0, 0.0))
+ for i, t in enumerate(st1):
+ expected = sync_prof.y[sync_prof.x == t]/sync_prof.mp[sync_prof.x == t]
+- assert_equal(coincidences[i], expected,
+- "At index %d" % i)
++ assert_allclose(coincidences[i], expected,
++ err_msg="At index %d" % i)
+
+
+ def test_filter():
+@@ -72,22 +72,22 @@ def test_filter():
+
+ # filtered_spike_trains = spk.filter_by_spike_sync([st1, st2], 0.5)
+
+- # assert_equal(filtered_spike_trains[0].spikes, [1.0, 2.0, 4.0])
+- # assert_equal(filtered_spike_trains[1].spikes, [1.1, 2.1, 3.8])
++ # assert_allclose(filtered_spike_trains[0].spikes, [1.0, 2.0, 4.0])
++ # assert_allclose(filtered_spike_trains[1].spikes, [1.1, 2.1, 3.8])
+
+ # filtered_spike_trains = spk.filter_by_spike_sync([st2, st1], 0.5)
+
+- # assert_equal(filtered_spike_trains[0].spikes, [1.1, 2.1, 3.8])
+- # assert_equal(filtered_spike_trains[1].spikes, [1.0, 2.0, 4.0])
++ # assert_allclose(filtered_spike_trains[0].spikes, [1.1, 2.1, 3.8])
++ # assert_allclose(filtered_spike_trains[1].spikes, [1.0, 2.0, 4.0])
+
+ filtered_spike_trains = spk.filter_by_spike_sync([st1, st2, st3], 0.75)
+
+ for st in filtered_spike_trains:
+ print(st.spikes)
+
+- assert_equal(filtered_spike_trains[0].spikes, [1.0, 4.0])
+- assert_equal(filtered_spike_trains[1].spikes, [1.1, 3.8])
+- assert_equal(filtered_spike_trains[2].spikes, [0.9, 4.1])
++ assert_allclose(filtered_spike_trains[0].spikes, [1.0, 4.0])
++ assert_allclose(filtered_spike_trains[1].spikes, [1.1, 3.8])
++ assert_allclose(filtered_spike_trains[2].spikes, [0.9, 4.1])
+
+
+ if __name__ == "main":
diff --git a/debian/patches/0002-Python-3.10-compatibility-fix.patch b/debian/patches/0002-Python-3.10-compatibility-fix.patch
new file mode 100644
index 0000000..52ffb09
--- /dev/null
+++ b/debian/patches/0002-Python-3.10-compatibility-fix.patch
@@ -0,0 +1,109 @@
+From: Gard Spreemann <gspr@nonempty.org>
+Date: Sun, 21 Nov 2021 15:12:18 +0100
+Subject: Python 3.10 compatibility fix
+
+Importing Sequence et al. from collections has been deprecated since
+Python 3.7.
+---
+ pyspike/DiscreteFunc.py | 6 +++---
+ pyspike/PieceWiseConstFunc.py | 8 ++++----
+ pyspike/PieceWiseLinFunc.py | 8 ++++----
+ 3 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/pyspike/DiscreteFunc.py b/pyspike/DiscreteFunc.py
+index caad290..48bc787 100644
+--- a/pyspike/DiscreteFunc.py
++++ b/pyspike/DiscreteFunc.py
+@@ -5,7 +5,7 @@
+ from __future__ import absolute_import, print_function
+
+ import numpy as np
+-import collections
++import collections.abc
+ import pyspike
+
+
+@@ -155,11 +155,11 @@ class DiscreteFunc(object):
+ multiplicity = np.sum(self.mp[1:-1])
+ else:
+ # check if interval is as sequence
+- assert isinstance(interval, collections.Sequence), \
++ assert isinstance(interval, collections.abc.Sequence), \
+ "Invalid value for `interval`. None, Sequence or Tuple \
+ expected."
+ # check if interval is a sequence of intervals
+- if not isinstance(interval[0], collections.Sequence):
++ if not isinstance(interval[0], collections.abc.Sequence):
+ # find the indices corresponding to the interval
+ start_ind, end_ind = get_indices(interval)
+ value = np.sum(self.y[start_ind:end_ind])
+diff --git a/pyspike/PieceWiseConstFunc.py b/pyspike/PieceWiseConstFunc.py
+index 17fdd3f..e33c61d 100644
+--- a/pyspike/PieceWiseConstFunc.py
++++ b/pyspike/PieceWiseConstFunc.py
+@@ -5,7 +5,7 @@
+ from __future__ import absolute_import, print_function
+
+ import numpy as np
+-import collections
++import collections.abc
+ import pyspike
+
+
+@@ -39,7 +39,7 @@ class PieceWiseConstFunc(object):
+
+ ind = np.searchsorted(self.x, t, side='right')
+
+- if isinstance(t, collections.Sequence):
++ if isinstance(t, collections.abc.Sequence):
+ # t is a sequence of values
+ # correct the cases t == x[0], t == x[-1]
+ ind[ind == 0] = 1
+@@ -173,10 +173,10 @@ class PieceWiseConstFunc(object):
+ return self.integral() / (self.x[-1]-self.x[0])
+
+ # check if interval is as sequence
+- assert isinstance(interval, collections.Sequence), \
++ assert isinstance(interval, collections.abc.Sequence), \
+ "Invalid value for `interval`. None, Sequence or Tuple expected."
+ # check if interval is a sequence of intervals
+- if not isinstance(interval[0], collections.Sequence):
++ if not isinstance(interval[0], collections.abc.Sequence):
+ # just one interval
+ a = self.integral(interval) / (interval[1]-interval[0])
+ else:
+diff --git a/pyspike/PieceWiseLinFunc.py b/pyspike/PieceWiseLinFunc.py
+index 8faaec4..b3b503b 100644
+--- a/pyspike/PieceWiseLinFunc.py
++++ b/pyspike/PieceWiseLinFunc.py
+@@ -5,7 +5,7 @@
+ from __future__ import absolute_import, print_function
+
+ import numpy as np
+-import collections
++import collections.abc
+ import pyspike
+
+
+@@ -46,7 +46,7 @@ class PieceWiseLinFunc:
+
+ ind = np.searchsorted(self.x, t, side='right')
+
+- if isinstance(t, collections.Sequence):
++ if isinstance(t, collections.abc.Sequence):
+ # t is a sequence of values
+ # correct the cases t == x[0], t == x[-1]
+ ind[ind == 0] = 1
+@@ -211,10 +211,10 @@ class PieceWiseLinFunc:
+ return self.integral() / (self.x[-1]-self.x[0])
+
+ # check if interval is as sequence
+- assert isinstance(interval, collections.Sequence), \
++ assert isinstance(interval, collections.abc.Sequence), \
+ "Invalid value for `interval`. None, Sequence or Tuple expected."
+ # check if interval is a sequence of intervals
+- if not isinstance(interval[0], collections.Sequence):
++ if not isinstance(interval[0], collections.abc.Sequence):
+ # just one interval
+ a = self.integral(interval) / (interval[1]-interval[0])
+ else:
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..b13244f
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,2 @@
+0001-Use-assert_allclose-instead-of-assert_equal-in-tests.patch
+0002-Python-3.10-compatibility-fix.patch
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..c24083a
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,9 @@
+#!/usr/bin/make -f
+
+#export DH_VERBOSE = 1
+
+export PYBUILD_NAME = pyspike
+
+%:
+ dh $@ --with numpy3,python3 --buildsystem=pybuild
+
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debian/tests/control b/debian/tests/control
new file mode 100644
index 0000000..1ba8a7b
--- /dev/null
+++ b/debian/tests/control
@@ -0,0 +1,3 @@
+Tests: upstream.sh
+Depends: python3-all, python3-nose, python3-pyspike
+Restrictions: allow-stderr
diff --git a/debian/tests/upstream.sh b/debian/tests/upstream.sh
new file mode 100755
index 0000000..918c91e
--- /dev/null
+++ b/debian/tests/upstream.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -e
+
+cwd=$(pwd)
+cd test
+
+for py3ver in $(py3versions -vs)
+do
+ echo "Running tests with Python ${py3ver}."
+ /usr/bin/python${py3ver} -B -c "import nose; nose.main()"
+done
+
+cd $cwd
diff --git a/debian/upstream/metadata b/debian/upstream/metadata
new file mode 100644
index 0000000..05d51bb
--- /dev/null
+++ b/debian/upstream/metadata
@@ -0,0 +1,13 @@
+Bug-Database: https://github.com/mariomulansky/PySpike/issues
+Bug-Submit: https://github.com/mariomulansky/PySpike/issues/new
+Repository: https://github.com/mariomulansky/PySpike.git
+Repository-Browse: https://github.com/mariomulansky/PySpike
+Cite-As: >
+ Mario Mulansky, Thomas Kreuz, PySpike - A Python library for analyzing spike train synchrony, SoftwareX, (2016), ISSN 2352-7110
+Reference:
+ Title: PySpike - A Python library for analyzing spike train synchrony
+ Author: Mario Mulansky and Thomas Kreuz
+ Journal: SoftwareX
+ Volume: 5
+ Pages: 183–189
+ Year: 2016
diff --git a/debian/watch b/debian/watch
new file mode 100644
index 0000000..428dcec
--- /dev/null
+++ b/debian/watch
@@ -0,0 +1,4 @@
+version=4
+opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%@PACKAGE@-$1.tar.gz%" \
+ https://github.com/mariomulansky/PySpike/tags \
+ (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate