Skip to content

Commit

Permalink
explain and ignore warnings during the tests (NeuralEnsemble#238)
Browse files Browse the repository at this point in the history
* explain and ignore warnings during the tests

* scipy v0.18.0

* fixed min-req tests: scipy v0.19.0

* exclude min-requirements tests back

* fixed division by zero
  • Loading branch information
dizcza authored and mdenker committed Aug 13, 2019
1 parent 19d3c7b commit caa2110
Show file tree
Hide file tree
Showing 13 changed files with 374 additions and 254 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ matrix:
python: 3.7
env: DISTRIB="conda"

exclude:
- name: "pip 3.6 requirements-extras min version"
# excluded due to unrelated unittest assertWarn bug error
python: 3.6
env: DISTRIB="pip"
before_install:
Expand Down
59 changes: 27 additions & 32 deletions elephant/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,6 @@
# =============================================================================


def _xrange(x, *args):
'''
Auxiliary function to use both in python 3 and python 2 to have a range
function as a generator.
'''
try:
return xrange(x, *args)
except NameError:
return range(x, *args)


def _signals_same_tstart(signals):
'''
Check whether a list of signals (AnalogSignals or SpikeTrains) have same
Expand Down Expand Up @@ -248,7 +237,7 @@ def _transactions(spiketrains, binsize, t_start=None, t_stop=None, ids=None):

# Compute and return the transaction list
return [[train_id for train_id, b in zip(ids, filled_bins)
if bin_id in b] for bin_id in _xrange(Nbins)]
if bin_id in b] for bin_id in range(Nbins)]


def _analog_signal_step_interp(signal, times):
Expand Down Expand Up @@ -482,8 +471,8 @@ def intersection_matrix(

# Compute the intersection matrix imat
N_bins = len(spikes_per_bin_x)
imat = np.zeros((N_bins, N_bins)) * 1.
for ii in _xrange(N_bins):
imat = np.zeros((N_bins, N_bins), dtype=float)
for ii in range(N_bins):
# Compute the ii-th row of imat
bin_ii = bsts_x[:, ii].reshape(-1, 1)
imat[ii, :] = (bin_ii * bsts_y).sum(axis=0)
Expand All @@ -508,7 +497,7 @@ def intersection_matrix(
for y_id in ybins_equal_0:
imat[:, y_id] = 0

imat[_xrange(N_bins), _xrange(N_bins)] = 1.
np.fill_diagonal(imat, val=1.)

except MemoryError: # use the memory-efficient version
# Compute the list spiking neurons per bin, along both axes
Expand All @@ -520,8 +509,8 @@ def intersection_matrix(
# Generate the intersection matrix
N_bins = len(ids_per_bin_x)
imat = np.zeros((N_bins, N_bins))
for ii in _xrange(N_bins):
for jj in _xrange(N_bins):
for ii in range(N_bins):
for jj in range(N_bins):
if len(ids_per_bin_x[ii]) * len(ids_per_bin_y[jj]) != 0:
imat[ii, jj] = len(set(ids_per_bin_x[ii]).intersection(
set(ids_per_bin_y[jj])))
Expand Down Expand Up @@ -589,9 +578,11 @@ def _reference_diagonal(x_edges, y_edges):
if diag_id is None:
return diag_id, np.array([])
elif diag_id >= 0:
elements = np.array([_xrange(m - diag_id), _xrange(diag_id, m)]).T
elements = np.column_stack([np.arange(m - diag_id),
np.arange(diag_id, m)])
else:
elements = np.array([_xrange(diag_id, m), _xrange(m - diag_id)]).T
elements = np.column_stack([np.arange(diag_id, m),
np.arange(m - diag_id)])

return diag_id, elements

Expand Down Expand Up @@ -680,19 +671,23 @@ def _stretched_metric_2d(x, y, stretch, ref_angle):
D = scipy.spatial.distance_matrix(points, points)

# Compute the angular coefficients of the line between each pair of points
x_array = 1. * np.vstack([x for i in x])
y_array = 1. * np.vstack([y for i in y])
x_array = np.tile(x, reps=(len(x), 1))
y_array = np.tile(y, reps=(len(y), 1))
dX = x_array.T - x_array # dX[i,j]: x difference between points i and j
dY = y_array.T - y_array # dY[i,j]: y difference between points i and j
AngCoeff = dY / dX

# Compute the matrix Theta of angles between each pair of points
Theta = np.arctan(AngCoeff)
n = Theta.shape[0]
Theta[_xrange(n), _xrange(n)] = 0 # set angle to 0 if points identical
theta = np.arctan2(dY, dX)

# Transform [-pi, pi] back to [-pi/2, pi/2]
theta[theta < -np.pi / 2] += np.pi
theta[theta > np.pi / 2] -= np.pi
assert np.allclose(np.diagonal(theta), 0), \
"Diagonal elements should be zero due to `np.arctan2(0, 0) == 0` " \
"convention."

# Compute the matrix of stretching factors for each pair of points
stretch_mat = (1 + ((stretch - 1.) * np.abs(np.sin(alpha - Theta))))
stretch_mat = 1 + (stretch - 1.) * np.abs(np.sin(alpha - theta))

# Return the stretched distance matrix
return D * stretch_mat
Expand Down Expand Up @@ -877,7 +872,7 @@ def probability_matrix_montecarlo(
if verbose:
# todo: move to tqdm
print('pmat_bootstrap(): begin of bootstrap...')
for i in _xrange(n_surr): # For each surrogate id i
for i in range(n_surr): # For each surrogate id i
if verbose:
print(' surr %d' % i)
surrs_i = [st[i] for st in surrs] # Take each i-th surrogate
Expand Down Expand Up @@ -994,7 +989,7 @@ def probability_matrix_analytical(
# to absence of spikes beyond the borders. Replace the first and last
# (k//2) elements with the (k//2)-th / (n-k//2)-th ones, respectively
k2 = k // 2
for i in _xrange(fir_rate_x.shape[0]):
for i in range(fir_rate_x.shape[0]):
fir_rate_x[i, :k2] = fir_rate_x[i, k2]
fir_rate_x[i, -k2:] = fir_rate_x[i, -k2 - 1]
fir_rate_y[i, :k2] = fir_rate_y[i, k2]
Expand Down Expand Up @@ -1064,8 +1059,8 @@ def probability_matrix_analytical(
t_start_y=t_start_y)

pmat = np.zeros(imat.shape)
for i in _xrange(imat.shape[0]):
for j in _xrange(imat.shape[1]):
for i in range(imat.shape[0]):
for j in range(imat.shape[1]):
pmat[i, j] = scipy.stats.poisson.cdf(imat[i, j] - 1, Mu[i, j])

# Substitute 0.5 to the elements along the main diagonal
Expand Down Expand Up @@ -1123,7 +1118,7 @@ def _jsf_uniform_orderstat_3d(u, alpha, n):

# Define ranges [1,...,n], [2,...,n], ..., [d,...,n] for the mute variables
# used to compute the integral as a sum over several possibilities
lists = [_xrange(j, n + 1) for j in _xrange(d, 0, -1)]
lists = [range(j, n + 1) for j in range(d, 0, -1)]

# Compute the log of the integral's coefficient
logK = np.sum(np.log(np.arange(1, n + 1))) - n * np.log(1 - alpha)
Expand Down Expand Up @@ -1399,7 +1394,7 @@ def extract_sse(spiketrains, x_edges, y_edges, cmat, ids=None):

# Reconstruct each worm, link by link
sse_dict = {}
for k in _xrange(1, nr_worms + 1): # for each worm
for k in range(1, nr_worms + 1): # for each worm
worm_k = {} # worm k is a list of links (each link will be 1 sublist)
pos_worm_k = np.array(np.where(cmat == k)).T # position of all links
# if no link lies on the reference diagonal
Expand Down
37 changes: 18 additions & 19 deletions elephant/signal_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,25 +111,24 @@ def zscore(signal, inplace=True):
signal = [signal]

# Calculate mean and standard deviation
m = np.mean(np.concatenate(signal), axis=0)
s = np.std(np.concatenate(signal), axis=0)

if not inplace:
# Create new signal instance
result = []
for sig in signal:
sig_dimless = sig.duplicate_with_new_data(
(sig.magnitude - m.magnitude) / s.magnitude) / sig.units
result.append(sig_dimless)
else:
result = []
# Overwrite signal
for sig in signal:
sig[:] = pq.Quantity(
(sig.magnitude - m.magnitude) / s.magnitude,
units=sig.units)
sig_dimless = sig / sig.units
result.append(sig_dimless)
signal_stacked = np.vstack(signal)
m = np.mean(signal_stacked, axis=0)
s = np.std(signal_stacked, axis=0)

result = []
for sig in signal:
sig_normalized = sig.magnitude - m.magnitude
sig_normalized = np.divide(sig_normalized, s.magnitude,
out=np.zeros_like(sig_normalized),
where=s.magnitude != 0)
if inplace:
sig[:] = pq.Quantity(sig_normalized, units=sig.units)
sig_normalized = sig
else:
sig_normalized = sig.duplicate_with_new_data(sig_normalized)
sig_dimless = sig_normalized / sig.units
result.append(sig_dimless)

# Return single object, or list of objects
if len(result) == 1:
return result[0]
Expand Down
3 changes: 2 additions & 1 deletion elephant/spike_train_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ def homogeneous_poisson_process(rate, t_start=0.0 * ms, t_stop=1000.0 * ms,
np.random.exponential, (mean_interval,), rate, t_start, t_stop,
as_array)


def inhomogeneous_poisson_process(rate, as_array=False):
"""
Returns a spike train whose spikes are a realization of an inhomogeneous
Expand Down Expand Up @@ -469,7 +470,7 @@ def homogeneous_gamma_process(a, b, t_start=0.0 * ms, t_stop=1000.0 * ms,
"""
if not isinstance(t_start, Quantity) or not isinstance(t_stop, Quantity):
raise ValueError("t_start and t_stop must be of type pq.Quantity")
b = b.rescale((1 / t_start).units).simplified
b = b.rescale(1 / t_start.units).simplified
rate = b / a
k, theta = a, (1 / b.magnitude)
return _homogeneous_process(np.random.gamma, (k, theta), rate, t_start, t_stop, as_array)
Expand Down
21 changes: 14 additions & 7 deletions elephant/test/test_cubic.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@
:license: Modified BSD, see LICENSE.txt for details.
"""

import sys
import unittest
import elephant.cubic as cubic
import quantities as pq

import neo
import numpy
import quantities as pq

import elephant.cubic as cubic

python_version_major = sys.version_info.major


class CubicTestCase(unittest.TestCase):
Expand Down Expand Up @@ -104,10 +109,12 @@ def test_cubic(self):
# Check the output for test_aborted
self.assertEqual(test_aborted, False)

@unittest.skipUnless(python_version_major == 3, "assertWarns requires 3.2")
def test_cubic_ximax(self):
# Test exceeding ximax
xi_ximax, p_vals_ximax, k_ximax, test_aborted = cubic.cubic(
self.data_signal, alpha=1, ximax=self.ximax)
with self.assertWarns(UserWarning):
xi_ximax, p_vals_ximax, k_ximax, test_aborted = cubic.cubic(
self.data_signal, alpha=1, ximax=self.ximax)

self.assertEqual(test_aborted, True)
self.assertEqual(xi_ximax - 1, self.ximax)
Expand All @@ -121,12 +128,12 @@ def test_cubic_errors(self):
ValueError, cubic.cubic, neo.AnalogSignal(
[]*pq.dimensionless, sampling_period=10*pq.ms))

dummy_data = numpy.tile([1, 2, 3], reps=3)
# Multidimensional array
self.assertRaises(ValueError, cubic.cubic, neo.AnalogSignal(
[[1, 2, 3], [1, 2, 3]] * pq.dimensionless,
dummy_data * pq.dimensionless,
sampling_period=10 * pq.ms))
self.assertRaises(ValueError, cubic.cubic, numpy.array(
[[1, 2, 3], [1, 2, 3]]))
self.assertRaises(ValueError, cubic.cubic, dummy_data.copy())

# Negative alpha
self.assertRaises(ValueError, cubic.cubic, self.data_array, alpha=-0.1)
Expand Down
31 changes: 22 additions & 9 deletions elephant/test/test_pandas_bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,25 @@
from __future__ import division, print_function

import unittest
import warnings
from distutils.version import StrictVersion
from itertools import chain

from neo.test.generate_datasets import fake_neo
import numpy as np
from numpy.testing import assert_array_equal
import quantities as pq
from neo.test.generate_datasets import fake_neo
from numpy.testing import assert_array_equal

try:
import pandas as pd
from pandas.util.testing import assert_frame_equal, assert_index_equal
except ImportError:
HAVE_PANDAS = False
pandas_version = StrictVersion('0.0.0')
else:
import elephant.pandas_bridge as ep
HAVE_PANDAS = True
pandas_version = StrictVersion(pd.__version__)

if HAVE_PANDAS:
# Currying, otherwise the unittest will break with pandas>=0.16.0
Expand All @@ -39,19 +43,19 @@ def assert_index_equal(left, right):
return pd.util.testing.assert_index_equal(left, right)


@unittest.skipUnless(HAVE_PANDAS, 'requires pandas')
@unittest.skipUnless(pandas_version >= '0.24.0', 'requires pandas v0.24.0')
class MultiindexFromDictTestCase(unittest.TestCase):
def test__multiindex_from_dict(self):
inds = {'test1': 6.5,
'test2': 5,
'test3': 'test'}
targ = pd.MultiIndex(levels=[[6.5], [5], ['test']],
labels=[[0], [0], [0]],
codes=[[0], [0], [0]],
names=['test1', 'test2', 'test3'])
res0 = ep._multiindex_from_dict(inds)
self.assertEqual(targ.levels, res0.levels)
self.assertEqual(targ.names, res0.names)
self.assertEqual(targ.labels, res0.labels)
self.assertEqual(targ.codes, res0.codes)


def _convert_levels(levels):
Expand Down Expand Up @@ -2703,7 +2707,10 @@ def test_single_t_start(self):
res1_stop = res1.columns.get_level_values('t_stop').values

targ = self.obj.values
targ[targ < targ_start] = np.nan
with warnings.catch_warnings():
warnings.simplefilter("ignore")
# targ already has nan values, ignore comparing with nan
targ[targ < targ_start] = np.nan

self.assertFalse(res0 is targ)
self.assertFalse(res1 is targ)
Expand Down Expand Up @@ -2731,7 +2738,10 @@ def test_single_t_stop(self):
res1_stop = res1.columns.get_level_values('t_stop').unique().tolist()

targ = self.obj.values
targ[targ > targ_stop] = np.nan
with warnings.catch_warnings():
warnings.simplefilter("ignore")
# targ already has nan values, ignore comparing with nan
targ[targ > targ_stop] = np.nan

self.assertFalse(res0 is targ)
self.assertFalse(res1 is targ)
Expand All @@ -2757,8 +2767,11 @@ def test_single_both(self):
res0_stop = res0.columns.get_level_values('t_stop').unique().tolist()

targ = self.obj.values
targ[targ < targ_start] = np.nan
targ[targ > targ_stop] = np.nan
with warnings.catch_warnings():
warnings.simplefilter("ignore")
# targ already has nan values, ignore comparing with nan
targ[targ < targ_start] = np.nan
targ[targ > targ_stop] = np.nan

self.assertFalse(res0 is targ)

Expand Down
11 changes: 6 additions & 5 deletions elephant/test/test_signal_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,14 +206,15 @@ def test_zscore_single_multidim_inplace(self):

m = np.mean(signal.magnitude, axis=0, keepdims=True)
s = np.std(signal.magnitude, axis=0, keepdims=True)
target = (signal.magnitude - m) / s
ground_truth = np.divide(signal.magnitude - m, s,
out=np.zeros_like(signal.magnitude),
where=s != 0)
result = elephant.signal_processing.zscore(signal, inplace=True)

assert_array_almost_equal(
elephant.signal_processing.zscore(
signal, inplace=True).magnitude, target, decimal=9)
assert_array_almost_equal(result.magnitude, ground_truth, decimal=8)

# Assert original signal is overwritten
self.assertEqual(signal[0, 0].magnitude, target[0, 0])
self.assertAlmostEqual(signal[0, 0].magnitude, ground_truth[0, 0])

def test_zscore_single_dup_int(self):
"""
Expand Down

0 comments on commit caa2110

Please sign in to comment.