Repository: scikit-image/scikit-image

Issue:
All Travis 3.x builds failing
For recent PRs, all Travis builds for Python 3.x are failing. This was limited to just Python 3.5, but now we're getting these three errors consistently for all 3.x branches. Seems related to fancy indexing, and I believe the rollout of NumPy 1.10 is correlated with their appearance.

``` python
======================================================================
ERROR: Test a grayscale float image
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/venv/lib/python3.3/site-packages/nose/case.py", line 198, in runTest
    self.test(*self.arg)
  File "/home/travis/build/scikit-image/scikit-image/skimage/exposure/tests/test_exposure.py", line 218, in test_adapthist_grayscale
    adapted = exposure.equalize_adapthist(img, kernel_size=(57, 51), clip_limit=0.01, nbins=128)
  File "/opt/python/3.3.5/lib/python3.3/contextlib.py", line 55, in __exit__
    next(self.gen)
  File "/home/travis/build/scikit-image/scikit-image/skimage/_shared/_warnings.py", line 112, in expected_warnings
    raise ValueError('Unexpected warning: %s' % str(warn.message))
ValueError: Unexpected warning: boolean index did not match indexed array along dimension 0; dimension is 128 but corresponding boolean dimension is 127
======================================================================
ERROR: Test an RGB color uint16 image
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/venv/lib/python3.3/site-packages/nose/case.py", line 198, in runTest
    self.test(*self.arg)
  File "/home/travis/build/scikit-image/scikit-image/skimage/exposure/tests/test_exposure.py", line 234, in test_adapthist_color
    adapted = exposure.equalize_adapthist(img, clip_limit=0.01)
  File "/opt/python/3.3.5/lib/python3.3/contextlib.py", line 55, in __exit__
    next(self.gen)
  File "/home/travis/build/scikit-image/scikit-image/skimage/_shared/_warnings.py", line 112, in expected_warnings
    raise ValueError('Unexpected warning: %s' % str(warn.message))
ValueError: Unexpected warning: boolean index did not match indexed array along dimension 0; dimension is 256 but corresponding boolean dimension is 86
======================================================================
ERROR: Test an RGBA color image
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/venv/lib/python3.3/site-packages/nose/case.py", line 198, in runTest
    self.test(*self.arg)
  File "/home/travis/build/scikit-image/scikit-image/skimage/exposure/tests/test_exposure.py", line 253, in test_adapthist_alpha
    adapted = exposure.equalize_adapthist(img)
  File "/opt/python/3.3.5/lib/python3.3/contextlib.py", line 55, in __exit__
    next(self.gen)
  File "/home/travis/build/scikit-image/scikit-image/skimage/_shared/_warnings.py", line 112, in expected_warnings
    raise ValueError('Unexpected warning: %s' % str(warn.message))
ValueError: Unexpected warning: boolean index did not match indexed array along dimension 0; dimension is 256 but corresponding boolean dimension is 86
----------------------------------------------------------------------
```



Discussion:

Resolving patch:
diff --git a/skimage/exposure/_adapthist.py b/skimage/exposure/_adapthist.py
--- a/skimage/exposure/_adapthist.py
+++ b/skimage/exposure/_adapthist.py
@@ -247,12 +247,14 @@ def clip_histogram(hist, clip_limit):
     while n_excess > 0:  # Redistribute remaining excess
         index = 0
         while n_excess > 0 and index < hist.size:
+            under_mask = hist < 0
             step_size = int(hist[hist < clip_limit].size / n_excess)
             step_size = max(step_size, 1)
             indices = np.arange(index, hist.size, step_size)
-            under = hist[indices] < clip_limit
-            hist[under] += 1
-            n_excess -= hist[under].size
+            under_mask[indices] = True
+            under_mask = (under_mask) & (hist < clip_limit)
+            hist[under_mask] += 1
+            n_excess -= under_mask.sum()
             index += 1
 
     return hist


Test patch:
diff --git a/skimage/exposure/tests/test_exposure.py b/skimage/exposure/tests/test_exposure.py
--- a/skimage/exposure/tests/test_exposure.py
+++ b/skimage/exposure/tests/test_exposure.py
@@ -199,9 +199,9 @@ def test_adapthist_scalar():
     full_scale = skimage.exposure.rescale_intensity(skimage.img_as_float(img))
 
     assert_almost_equal = np.testing.assert_almost_equal
-    assert_almost_equal(peak_snr(full_scale, adapted), 101.2295, 3)
+    assert_almost_equal(peak_snr(full_scale, adapted), 102.066, 3)
     assert_almost_equal(norm_brightness_err(full_scale, adapted),
-                        0.041, 3)
+                        0.038, 3)
     return img, adapted
 
 
@@ -217,8 +217,8 @@ def test_adapthist_grayscale():
                                                   nbins=128)
         adapted = exposure.equalize_adapthist(img, kernel_size=(57, 51), clip_limit=0.01, nbins=128)
     assert img.shape == adapted.shape
-    assert_almost_equal(peak_snr(img, adapted),  101.750, 3)
-    assert_almost_equal(norm_brightness_err(img, adapted), 0.0540, 3)
+    assert_almost_equal(peak_snr(img, adapted),  102.078, 3)
+    assert_almost_equal(norm_brightness_err(img, adapted), 0.0529, 3)
     return data, adapted
 
 
@@ -238,7 +238,7 @@ def test_adapthist_color():
     assert adapted.max() == 1.0
     assert img.shape == adapted.shape
     full_scale = skimage.exposure.rescale_intensity(img)
-    assert_almost_equal(peak_snr(full_scale, adapted), 109.6, 1)
+    assert_almost_equal(peak_snr(full_scale, adapted), 109.393, 1)
     assert_almost_equal(norm_brightness_err(full_scale, adapted), 0.02, 2)
     return data, adapted
 
@@ -256,8 +256,8 @@ def test_adapthist_alpha():
     full_scale = skimage.exposure.rescale_intensity(img)
     assert img.shape == adapted.shape
     assert_almost_equal = np.testing.assert_almost_equal
-    assert_almost_equal(peak_snr(full_scale, adapted), 109.60, 2)
-    assert_almost_equal(norm_brightness_err(full_scale, adapted), 0.0235, 3)
+    assert_almost_equal(peak_snr(full_scale, adapted), 109.393, 2)
+    assert_almost_equal(norm_brightness_err(full_scale, adapted), 0.0248, 3)
 
 
 def peak_snr(img1, img2):