internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: scikit-image/scikit-image

Issue:
Sporadic pooch failures in CI
## Description

Sometimes, the hash of the downloaded files doesn't match the expected hash, see e.g.

https://dev.azure.com/scikit-image/scikit-image/_build/results?buildId=3987&view=logs&j=bc76316b-1dff-5b05-0ff1-0b85ce9c0f8b&t=dc06b1ce-f667-542e-9f00-54b6784edf0a&l=6713

Other builds in the same group passed fine, so I don't think that this is an issue with the data. Rather, it seems pooch doesn't know to retry if it's failed. (Or even if it's failed.) @leouieda do you think this is something that pooch should handle, or should we somehow wrap it to include retries?

Incidentally maybe this means the earlier errors we were seeing had nothing to do with github vs gitlab bandwidth. 😬 Or, they did but we are hitting gitlab bandwidth limits also. I don't know, this is hard. 😭 


Discussion:
@sciunto sorry, I missed this entirely. The logs for that build are no longer available 😢 

I would guess that it might have been something with the bandwidth that caused the download to be incomplete (in which case the hash wouldn't match). 

Right now, pooch doesn't retry failed downloads and we don't have an option for that. We could add a configuration parameter for the `Pooch` class like `retry_if_failed` that can be 0 by default to retain the current behaviour.  This seems reasonable, particularly for CIs where most of the failures end up happening. 

I created https://github.com/fatiando/pooch/issues/205, feel free to chime in there with any requirements you'd have for this feature.
Thanks thanks!
@jni Pooch 1.3.0 is out now on PyPI and conda-forge including the `retry_if_failed` option. Give it a shot and let me know if anything doesn't work as expected 🙂 https://www.fatiando.org/pooch/latest/advanced.html#retry-failed-downloads

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -131,7 +131,7 @@ def parse_requirements_file(filename):
 # for the platforms we wish to support.
 extras_require = {
     dep: parse_requirements_file('requirements/' + dep + '.txt')
-    for dep in ['docs', 'optional', 'test']
+    for dep in ['docs', 'optional', 'test', 'data']
 }
 
 # requirements for those browsing PyPI
diff --git a/skimage/data/__init__.py b/skimage/data/__init__.py
--- a/skimage/data/__init__.py
+++ b/skimage/data/__init__.py
@@ -141,6 +141,7 @@ def create_image_fetcher():
         env="SKIMAGE_DATADIR",
         registry=registry,
         urls=registry_urls,
+        retry_if_failed=3,
     )
 
     data_dir = osp.join(str(image_fetcher.abspath), 'data')


Test patch:
diff --git a/requirements/test.txt b/requirements/test.txt
--- a/requirements/test.txt
+++ b/requirements/test.txt
@@ -4,4 +4,4 @@ pytest-localserver
 pytest-faulthandler
 flake8
 codecov
-pooch>=1.0.0
+pooch>=1.3.0
Repository: scikit-image/scikit-image

Issue:
filters.farid missing from skimage.filters documentation
## Description

The `filters.farid{,_h,_v}` functions are missing from the [`skimage.filters` documentation](https://scikit-image.org/docs/dev/api/skimage.filters.html). I presume this is because they are not it `__all__`? (No time to investigate right now.)


Discussion:

Resolving patch:
diff --git a/skimage/filters/__init__.py b/skimage/filters/__init__.py
--- a/skimage/filters/__init__.py
+++ b/skimage/filters/__init__.py
@@ -43,6 +43,9 @@
            'roberts_pos_diag',
            'roberts_neg_diag',
            'laplace',
+           'farid',
+           'farid_h',
+           'farid_v',
            'rank_order',
            'gabor_kernel',
            'gabor',


Test patch:
Repository: scikit-image/scikit-image

Issue:
pre builds broken by scipy 1.6.0rc1 
## Description

The release of scipy 1.6.0rc1 has broken our builds, see e.g. [here](https://github.com/scikit-image/scikit-image/pull/5129/checks?check_run_id=1540462654#step:5:442). The failing test is `skimage/segmentation/tests/test_boundaries.py::test_mark_boundaries_subpixel`. As I recall that function depends on a rather precise interpretation of the sizes given to `ndi.zoom`, so I expect that the culprit lies in recent (positive!) changes by @grlee77 to how SciPy handles interpolation. Probably a +1 can be removed somewhere and we can move on! 🤞 


Discussion:
It looks like inside `mark_boundaries` there is a call to `ndi.zoom` with `mode='reflect'`. This mode has had a long-standing bug in SciPy that was finally resolved with 1.6 in scipy/scipy#12767.  In short the behavior of reflect was fixed from behaving like the top left panel in https://github.com/scipy/scipy/issues/2640#issuecomment-554873759 to the expected behavior in the top middle panel.

Do you know how the expected result for this test was originally generated? If it relied on this erroneous behavior then we probably just need to regenerate the reference. I will take a closer look in a bit, but if it is only this boundary change then the central part of the image should still match the refernce, but a couple pixel width at the border could be different.

Resolving patch:
diff --git a/skimage/segmentation/boundaries.py b/skimage/segmentation/boundaries.py
--- a/skimage/segmentation/boundaries.py
+++ b/skimage/segmentation/boundaries.py
@@ -221,7 +221,7 @@ def mark_boundaries(image, label_img, color=(1, 1, 0),
         # the RGB information. ``ndi.zoom`` then performs the (cubic)
         # interpolation, filling in the values of the interposed pixels
         marked = ndi.zoom(marked, [2 - 1/s for s in marked.shape[:-1]] + [1],
-                          mode='reflect')
+                          mode='mirror')
     boundaries = find_boundaries(label_img, mode=mode,
                                  background=background_label)
     if outline_color is not None:


Test patch:
Repository: scikit-image/scikit-image

Issue:
DOCS: Return dtype of _label2rgb_avg function
## Description

With skimage release 0.18.0, and in particular after PR #4840, there is a mismatch between the return dtype of function `_label2rgb_avg` in the `color/colorlabel` module: it is stated to be the same dtype as the image, but using `np.zeros` instead of `np.zeros_like` makes the return type always to be float



Discussion:

Resolving patch:
diff --git a/skimage/color/colorlabel.py b/skimage/color/colorlabel.py
--- a/skimage/color/colorlabel.py
+++ b/skimage/color/colorlabel.py
@@ -223,7 +223,7 @@ def _label2rgb_avg(label_field, image, bg_label=0, bg_color=(0, 0, 0)):
     out : array, same shape and type as `image`
         The output visualization.
     """
-    out = np.zeros(label_field.shape + (3,))
+    out = np.zeros(label_field.shape + (3,), dtype=image.dtype)
     labels = np.unique(label_field)
     bg = (labels == bg_label)
     if bg.any():


Test patch:
Repository: scikit-image/scikit-image

Issue:
Small typo in utils.py
## Description
Small typo in the docs

The class docs have the argument name as `arg_mapping`
https://github.com/scikit-image/scikit-image/blob/87a8806cca7fb5366b6e5ddbe5e46364b44f90fe/skimage/_shared/utils.py#L119
However, the actual `__init__` method takes the argument with the name `kwarg_mapping`
https://github.com/scikit-image/scikit-image/blob/87a8806cca7fb5366b6e5ddbe5e46364b44f90fe/skimage/_shared/utils.py#L131



Discussion:
Good catch, thank you for the report @Devanshu24 :wink: 
@rfezzani You're welcome! I'll send a PR right away :) 

Resolving patch:
diff --git a/skimage/_shared/utils.py b/skimage/_shared/utils.py
--- a/skimage/_shared/utils.py
+++ b/skimage/_shared/utils.py
@@ -119,7 +119,7 @@ class deprecate_kwarg:
 
     Parameters
     ----------
-    arg_mapping: dict
+    kwarg_mapping: dict
         Mapping between the function's old argument names and the new
         ones.
     warning_msg: str


Test patch:
Repository: scikit-image/scikit-image

Issue:
3.7 minimum requirements test builds are failing
Example failed run:

https://github.com/scikit-image/scikit-image/runs/1801995691?check_suite_focus=true


Discussion:

Resolving patch:
diff --git a/skimage/filters/_gaussian.py b/skimage/filters/_gaussian.py
--- a/skimage/filters/_gaussian.py
+++ b/skimage/filters/_gaussian.py
@@ -117,13 +117,10 @@ def gaussian(image, sigma=1, output=None, mode='nearest', cval=0,
         if len(sigma) != image.ndim:
             sigma = np.concatenate((np.asarray(sigma), [0]))
     image = convert_to_float(image, preserve_range)
-    if output is None:
-        output = np.empty_like(image)
-    elif not np.issubdtype(output.dtype, np.floating):
+    if (output is not None) and (not np.issubdtype(output.dtype, np.floating)):
         raise ValueError("Provided output data type is not float")
-    ndi.gaussian_filter(image, sigma, output=output, mode=mode, cval=cval,
-                        truncate=truncate)
-    return output
+    return ndi.gaussian_filter(image, sigma, output=output, 
+                               mode=mode, cval=cval, truncate=truncate)
 
 
 def _guess_spatial_dimensions(image):
diff --git a/skimage/segmentation/random_walker_segmentation.py b/skimage/segmentation/random_walker_segmentation.py
--- a/skimage/segmentation/random_walker_segmentation.py
+++ b/skimage/segmentation/random_walker_segmentation.py
@@ -42,12 +42,6 @@ def new_del(self):
 from ..util import img_as_float
 
 from scipy.sparse.linalg import cg, spsolve
-import scipy
-from distutils.version import LooseVersion as Version
-import functools
-
-if Version(scipy.__version__) >= Version('1.1'):
-    cg = functools.partial(cg, atol=0)
 
 
 def _make_graph_edges_3d(n_x, n_y, n_z):
@@ -197,7 +191,8 @@ def _solve_linear_system(lap_sparse, B, tol, mode):
             M = ml.aspreconditioner(cycle='V')
             maxiter = 30
         cg_out = [
-            cg(lap_sparse, B[:, i].toarray(), tol=tol, M=M, maxiter=maxiter)
+            cg(lap_sparse, B[:, i].toarray(),
+               tol=tol, atol=0, M=M, maxiter=maxiter)
             for i in range(B.shape[1])]
         if np.any([info > 0 for _, info in cg_out]):
             warn("Conjugate gradient convergence to tolerance not achieved. "


Test patch:
Repository: scikit-image/scikit-image

Issue:
Error in documentation for watershed
The [documentation for watershed](https://scikit-image.org/docs/dev/api/skimage.segmentation.html#skimage.segmentation.watershed) says

> image : ndarray (2-D, 3-D, …) of integers
> Data array where the lowest value points are labeled first.

But when I look into the code and the [official example](https://scikit-image.org/docs/dev/auto_examples/segmentation/plot_watershed.html), it seems that watershed is actually dealing with float arrays, not integer arrays. I think this might be a mistake in the documentation. If not, please explain how so. If so, I would be happy if someone - who knows how - could correct the documentation.


Discussion:

Resolving patch:
diff --git a/skimage/segmentation/_watershed.py b/skimage/segmentation/_watershed.py
--- a/skimage/segmentation/_watershed.py
+++ b/skimage/segmentation/_watershed.py
@@ -98,7 +98,7 @@ def watershed(image, markers=None, connectivity=1, offset=None, mask=None,
 
     Parameters
     ----------
-    image : ndarray (2-D, 3-D, ...) of integers
+    image : ndarray (2-D, 3-D, ...)
         Data array where the lowest value points are labeled first.
     markers : int, or ndarray of int, same shape as `image`, optional
         The desired number of markers, or an array marking the basins with the


Test patch:
Repository: scikit-image/scikit-image

Issue:
sphinx: role 'arxiv' is already registered
## Description
in main,

```
Warning, treated as error:
role 'arxiv' is already registered, it will be overridden
make[1]: *** [Makefile:58: html] Error 2
make[1]: Leaving directory '/home/runner/work/scikit-image/scikit-image/doc'
```



Discussion:
To me, this is related to https://github.com/scikit-image/scikit-image/blob/5ed9bd65ab1e7d98f024d36c33e4ad39d7924160/doc/ext/doi_role.py#L33
but I don't see a related change in sphinx changes...
Fix: https://github.com/scipy/scipy/commit/3817289aec12ad3c31e81675023e859e6e1cf9ea


Resolving patch:
diff --git a/doc/ext/doi_role.py b/doc/ext/doi_role.py
--- a/doc/ext/doi_role.py
+++ b/doc/ext/doi_role.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 """
     doilinks
-    ~~~~~~~~~~~~~~~~~~~
+    ~~~~~~~~
     Extension to add links to DOIs. With this extension you can use e.g.
     :doi:`10.1016/S0022-2836(05)80360-2` in your documents. This will
     create a link to a DOI resolver
@@ -41,10 +41,10 @@ def arxiv_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
 
 
 def setup_link_role(app):
-    app.add_role('doi', doi_role)
-    app.add_role('DOI', doi_role)
-    app.add_role('arXiv', arxiv_role)
-    app.add_role('arxiv', arxiv_role)
+    app.add_role('doi', doi_role, override=True)
+    app.add_role('DOI', doi_role, override=True)
+    app.add_role('arXiv', arxiv_role, override=True)
+    app.add_role('arxiv', arxiv_role, override=True)
 
 
 def setup(app):


Test patch:
Repository: scikit-image/scikit-image

Issue:
`regionprops` multichannel measurements don't work for `extra_properties`
## Description

`regionprops` measurments have been supporting multi-channel intensity images as of recently.
However, when combined with `extra_properties`-functions that also rely on intensity the `extra_properties` only appear to be dispatched for one channel (at least the result is not multi-channel).   

## Way to reproduce

Call `regionprops` with a multi-channel `intensity_image` and an `extra_properties`-function that relies on intensity.
Observe the result.
(will fill in more detail if needed, a bit in a rush atm).


## Version information
```python
3.8.5 (default, Sep  4 2020, 07:30:14) 
[GCC 7.3.0]
Linux-5.8.0-48-generic-x86_64-with-glibc2.10
scikit-image version: 0.18.1
numpy version: 1.18.1
```



Discussion:

Resolving patch:
diff --git a/skimage/measure/_regionprops.py b/skimage/measure/_regionprops.py
--- a/skimage/measure/_regionprops.py
+++ b/skimage/measure/_regionprops.py
@@ -255,7 +255,14 @@ def __getattr__(self, attr):
             # determine whether func requires intensity image
             if n_args == 2:
                 if self._intensity_image is not None:
-                    return func(self.image, self.intensity_image)
+                    if self._multichannel:
+                        multichannel_list = [func(self.image,
+                                                  self.intensity_image[..., i])
+                                             for i in range(
+                            self.intensity_image.shape[-1])]
+                        return np.stack(multichannel_list, axis=-1)
+                    else:
+                        return func(self.image, self.intensity_image)
                 else:
                     raise AttributeError(
                         f"intensity image required to calculate {attr}"


Test patch:
diff --git a/skimage/measure/tests/test_regionprops.py b/skimage/measure/tests/test_regionprops.py
--- a/skimage/measure/tests/test_regionprops.py
+++ b/skimage/measure/tests/test_regionprops.py
@@ -722,9 +722,16 @@ def test_multichannel():
     labels = slic(astro.astype(float), start_label=1)
 
     segment_idx = np.max(labels) // 2
-    region = regionprops(labels, astro_green)[segment_idx]
-    region_multi = regionprops(labels, astro)[segment_idx]
-    for prop in PROPS:
+    region = regionprops(labels,
+                         astro_green,
+                         extra_properties=[median_intensity]
+                         )[segment_idx]
+    region_multi = regionprops(labels,
+                               astro,
+                               extra_properties=[median_intensity]
+                               )[segment_idx]
+
+    for prop in list(PROPS.keys()) + ["median_intensity"]:
         p = region[prop]
         p_multi = region_multi[prop]
         if np.shape(p) == np.shape(p_multi):
Repository: scikit-image/scikit-image

Issue:
Add rolling ball example for ECG data
## Description

The demo I made for this response in the PyWavelets google group would be nice to include in our gallery to show that the "n-dimensional" implementation of rolling ball allows application to signals as well:
https://groups.google.com/g/pywavelets/c/b3ErI_GmNBo

Fortunately, the short ECG waveform used for the example there is already bundled by PyWavelets.




Discussion:
Hello :) May I take this issue?
sure, that would be great! Please let us know if you need help/guidance. The current rolling ball example is located at `doc/examples/segmentation/plot_rolling_ball.py`. I think it may make sense to extend that one, but another possibility is making a new file.

Resolving patch:
diff --git a/doc/examples/segmentation/plot_rolling_ball.py b/doc/examples/segmentation/plot_rolling_ball.py
--- a/doc/examples/segmentation/plot_rolling_ball.py
+++ b/doc/examples/segmentation/plot_rolling_ball.py
@@ -39,6 +39,7 @@
 import imageio
 import matplotlib.pyplot as plt
 import numpy as np
+import pywt
 
 from skimage import (
     data, restoration, util
@@ -294,3 +295,23 @@ def plot_result(image, background):
 
 plot_result(image[30, ...], background[30, ...])
 plt.show()
+
+######################################################################
+# 1D Signal Filtering
+# -------------------
+#
+# As another example of the n-dimensional feature of
+# ``rolling_ball``, we show an implementation for 1D data. Here,
+# we are interested in removing the background signal of an ECG waveform
+# to detect prominent peaks (higher values than the local baseline).
+# Smoother peaks can be removed with smaller values of the radius.
+
+x = pywt.data.ecg()
+background = restoration.rolling_ball(x, radius=80)
+background2 = restoration.rolling_ball(x, radius=10)
+plt.figure()
+plt.plot(x, label='original')
+plt.plot(x - background, label='radius=80')
+plt.plot(x - background2, label='radius=10')
+plt.legend()
+plt.show()


Test patch:
Repository: scikit-image/scikit-image

Issue:
Incorrect link for `label` in regionprops gallery example
## Description

In the regionprops gallery example:

https://scikit-image.org/docs/0.18.x/auto_examples/segmentation/plot_regionprops.html

The "label" function links to Python's int documentation. I think that's because later in the example label (the function measure.label) gets redefined as `label = props[i].label`, which is indeed an int.

Probably this needs a fix in sphinx-gallery but in the meantime perhaps renaming some variables would help.


Discussion:

Resolving patch:
diff --git a/doc/examples/segmentation/plot_regionprops.py b/doc/examples/segmentation/plot_regionprops.py
--- a/doc/examples/segmentation/plot_regionprops.py
+++ b/doc/examples/segmentation/plot_regionprops.py
@@ -59,7 +59,7 @@
 plt.show()
 
 #####################################################################
-# We use the :py:func:`skimage.measure.regionprops_table` to compute
+# We use the :py:func:`skimage.measure.regionprops_table` function to compute
 # (selected) properties for each region. Note that
 # ``skimage.measure.regionprops_table`` actually computes the properties,
 # whereas ``skimage.measure.regionprops`` computes them when they come in use
@@ -83,6 +83,7 @@
 # This example uses plotly in order to display properties when
 # hovering over the objects.
 
+import plotly
 import plotly.express as px
 import plotly.graph_objects as go
 from skimage import data, filters, measure, morphology
@@ -104,15 +105,15 @@
 # For each label, add a filled scatter trace for its contour,
 # and display the properties of the label in the hover of this trace.
 for index in range(1, labels.max()):
-    label = props[index].label
-    contour = measure.find_contours(labels == label, 0.5)[0]
+    label_i = props[index].label
+    contour = measure.find_contours(labels == label_i, 0.5)[0]
     y, x = contour.T
     hoverinfo = ''
     for prop_name in properties:
         hoverinfo += f'<b>{prop_name}: {getattr(props[index], prop_name):.2f}</b><br>'
     fig.add_trace(go.Scatter(
-        x=x, y=y, name=label,
+        x=x, y=y, name=label_i,
         mode='lines', fill='toself', showlegend=False,
         hovertemplate=hoverinfo, hoveron='points+fills'))
 
-fig
+plotly.io.show(fig)


Test patch:
Repository: scikit-image/scikit-image

Issue:
Wrong threshold value in threshold_otsu when passing a precomputed histogram
## Description

When the histogram has bins with zero counts at the beginning, it returns zero as threshold.

## Way to reproduce
```python
import numpy as np
from skimage.filters import threshold_otsu

x = np.array([1, 2])

>>> threshold_otsu(x)
1
>>> threshold_otsu(hist=np.bincount(x))
0
```


## Version information
```python
# Paste the output of the following python commands
from __future__ import print_function
import sys; print(sys.version)
import platform; print(platform.platform())
import skimage; print("scikit-image version: {}".format(skimage.__version__))
import numpy; print("numpy version: {}".format(numpy.__version__))
```

```python
3.9.6 | packaged by conda-forge | (default, Jul 11 2021, 03:39:48) [GCC 9.3.0]
Linux-5.8.0-63-generic-x86_64-with-glibc2.31
scikit-image version: 0.19.0.dev0
numpy version: 1.21.1
```



Discussion:

Resolving patch:
diff --git a/skimage/filters/thresholding.py b/skimage/filters/thresholding.py
--- a/skimage/filters/thresholding.py
+++ b/skimage/filters/thresholding.py
@@ -284,6 +284,14 @@ def _validate_image_histogram(image, hist, nbins=None):
         else:
             counts = hist
             bin_centers = np.arange(counts.size)
+        
+        if counts[0] == 0 or counts[-1] == 0:
+            # Trim histogram from both ends by removing starting and
+            # ending zeroes as in histogram(..., source_range="image")
+            cond = counts > 0
+            start = np.argmax(cond)
+            end = cond.size - np.argmax(cond[::-1])
+            counts, bin_centers = counts[start:end], bin_centers[start:end]
     else:
         counts, bin_centers = histogram(
                 image.ravel(), nbins, source_range='image'


Test patch:
diff --git a/skimage/filters/tests/test_thresholding.py b/skimage/filters/tests/test_thresholding.py
--- a/skimage/filters/tests/test_thresholding.py
+++ b/skimage/filters/tests/test_thresholding.py
@@ -268,6 +268,19 @@ def test_otsu_camera_image_counts():
     camera = util.img_as_ubyte(data.camera())
     counts, bin_centers = histogram(camera.ravel(), 256, source_range='image')
     assert 101 < threshold_otsu(hist=counts) < 103
+    
+    
+def test_otsu_zero_count_histogram():
+    """Issue #5497.
+    
+    As the histogram returned by np.bincount starts with zero,
+    it resulted in NaN-related issues.
+    """
+    x = np.array([1, 2])
+
+    t1 = threshold_otsu(x)
+    t2 = threshold_otsu(hist=np.bincount(x))
+    assert t1 == t2
 
 
 def test_otsu_coins_image():