Repository: mne-tools/mne-python

Issue:
connectivity issues with numpy 1.3
```
    691             if indices is None:
    692                 # only compute r for lower-triangular region

--> 693                 indices_use = np.tril_indices(n_signals, -1)
    694             else:
    695                 indices_use = check_indices(indices)

AttributeError: 'module' object has no attribute 'tril_indices'
WARNING: Failure executing file: <plot_sensor_connectivity.py>
```

we need to backport this...



Discussion:
Is it necessary to support such an old numpy version? 1.4 was released ~3 years ago.

> Is it necessary to support such an old numpy version? 1.4 was released ~3 years ago.

I have had the problem today at neurospin that runs on "stable"
ubuntu… I could not demo the all new connectivity module :(

also might be an issue for debian stable.. can check that later / tomorrow

On 05.12.2012, at 21:45, Alexandre Gramfort notifications@github.com wrote:

> > Is it necessary to support such an old numpy version? 1.4 was released ~3 years ago. 
> 
> I have had the problem today at neurospin that runs on "stable" 
> ubuntu… I could not demo the all new connectivity module :(
> —
> Reply to this email directly or view it on GitHub.

so the debian package table says 1.4 for current stable:

 http://packages.debian.org/search?keywords=python-numpy

however the neurospin argument is a good one.

On 05.12.2012, at 21:45, Alexandre Gramfort notifications@github.com wrote:

> > Is it necessary to support such an old numpy version? 1.4 was released ~3 years ago. 
> 
> I have had the problem today at neurospin that runs on "stable" 
> ubuntu… I could not demo the all new connectivity module :(
> —
> Reply to this email directly or view it on GitHub.

Argh.. another reason to dislike Ubuntu ;).

Can you try running the tests on Ubuntu stable at neurospin? I would be very surprised if there are not other breakages because of the old numpy (and scipy?) versions. Once we know what breaks we can decide if back porting things makes sense. If it is only a few functions, we can do it but if we have to back port half of numpy we shouldn't attempt to support numpy 1.3.

Good decision algorithm, +1

On Wed, Dec 5, 2012 at 10:45 PM, Martin Luessi notifications@github.comwrote:

> Argh.. another reason to dislike Ubuntu ;).
> 
> Can you try running the tests on Ubuntu stable at neurospin? I would be
> very surprised if there are not other breakages because of the old numpy
> (and scipy?) versions. Once we know what breaks we can decide if back
> porting things makes sense. If it is only a few functions, we can do it but
> if we have to back port half of numpy we shouldn't attempt to support numpy
> 1.3.
> 
> —
> Reply to this email directly or view it on GitHubhttps://github.com/mne-tools/mne-python/issues/228#issuecomment-11062023.

I backported in1d and whatever is in fixes.py already for this reason so tril_indices should be the only problem.

I will look into it


Resolving patch:
diff --git a/mne/connectivity/spectral.py b/mne/connectivity/spectral.py
--- a/mne/connectivity/spectral.py
+++ b/mne/connectivity/spectral.py
@@ -13,6 +13,7 @@
 
 
 from .utils import check_indices
+from ..fixes import tril_indices
 from ..parallel import parallel_func
 from .. import Epochs, SourceEstimate
 from ..time_frequency.multitaper import dpss_windows, _mt_spectra,\
@@ -690,7 +691,7 @@ def spectral_connectivity(data, method='coh', indices=None, sfreq=2 * np.pi,
 
             if indices is None:
                 # only compute r for lower-triangular region
-                indices_use = np.tril_indices(n_signals, -1)
+                indices_use = tril_indices(n_signals, -1)
             else:
                 indices_use = check_indices(indices)
 
diff --git a/mne/fixes.py b/mne/fixes.py
--- a/mne/fixes.py
+++ b/mne/fixes.py
@@ -168,6 +168,19 @@ def _in1d(ar1, ar2, assume_unique=False):
     in1d = np.in1d
 
 
+def _tril_indices(n, k=0):
+    """Replacement for tril_indices that is provided for numpy >= 1.4"""
+    mask = np.greater_equal(np.subtract.outer(np.arange(n), np.arange(n)), -k)
+    indices = np.where(mask)
+
+    return indices
+
+if not hasattr(np, 'tril_indices'):
+    tril_indices = _tril_indices
+else:
+    tril_indices = np.tril_indices
+
+
 def _unravel_index(indices, dims):
     """Add support for multiple indices in unravel_index that is provided
     for numpy >= 1.4"""


Test patch:
diff --git a/mne/connectivity/tests/test_spectral.py b/mne/connectivity/tests/test_spectral.py
--- a/mne/connectivity/tests/test_spectral.py
+++ b/mne/connectivity/tests/test_spectral.py
@@ -2,6 +2,7 @@
 from numpy.testing import assert_array_almost_equal
 from nose.tools import assert_true, assert_raises
 
+from mne.fixes import tril_indices
 from mne.connectivity import spectral_connectivity
 from mne.connectivity.spectral import _CohEst
 
@@ -137,7 +138,7 @@ def test_spectral_connectivity():
 
                 # compute same connections using indices and 2 jobs,
                 # also add a second method
-                indices = np.tril_indices(n_signals, -1)
+                indices = tril_indices(n_signals, -1)
 
                 test_methods = (method, _CohEst)
                 stc_data = _stc_gen(data, sfreq, tmin)
diff --git a/mne/tests/test_fixes.py b/mne/tests/test_fixes.py
--- a/mne/tests/test_fixes.py
+++ b/mne/tests/test_fixes.py
@@ -8,7 +8,7 @@
 from nose.tools import assert_equal
 from numpy.testing import assert_array_equal
 
-from ..fixes import _in1d, _copysign, _unravel_index
+from ..fixes import _in1d, _tril_indices, _copysign, _unravel_index
 
 
 def test_in1d():
@@ -18,6 +18,22 @@ def test_in1d():
     assert_equal(_in1d(a, b).sum(), 5)
 
 
+def test_tril_indices():
+    """Test numpy.tril_indices() replacement"""
+    il1 = _tril_indices(4)
+    il2 = _tril_indices(4, -1)
+
+    a = np.array([[1, 2, 3, 4],
+                  [5, 6, 7, 8],
+                  [9, 10, 11, 12],
+                  [13, 14, 15, 16]])
+
+    assert_array_equal(a[il1],
+                       np.array([1,  5,  6,  9, 10, 11, 13, 14, 15, 16]))
+
+    assert_array_equal(a[il2], np.array([5, 9, 10, 13, 14, 15]))
+
+
 def test_unravel_index():
     """Test numpy.unravel_index() replacement"""
     assert_equal(_unravel_index(2, (2, 3)), (0, 2))