Move ensure_spacing into skimage2#8067
Conversation
Since that function isn't used anywhere else for now.
This comment was marked as outdated.
This comment was marked as outdated.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (5)
src/skimage2/feature/_peaks.py (1)
117-119: Consider handling 1D coordinate input explicitly.When
coordsis a 1D array (single point like[1, 2, 3]),np.atleast_2dconverts it to shape(1, 3)which is correct. However, the initial assignmentoutput = coordson line 117 means iflen(coords) == 0returns the original input type (could be a list[]), but non-empty inputs return an ndarray. This inconsistency is minor but could surprise callers.♻️ Optional: ensure consistent return type
- output = coords - if len(coords): + if len(coords) == 0: + return np.zeros((0, 1), dtype=float) + else: coords = np.atleast_2d(coords)tests/skimage2/feature/test_peaks.py (4)
19-35: Consider using a fixed random seed for reproducibility.The test uses
np.random.randnwithout setting a seed, which makes test results non-deterministic. If a test fails, it may be difficult to reproduce. Consider usingnp.random.default_rng(seed)for reproducible tests.♻️ Proposed fix
`@pytest.mark.parametrize`("p", [1, 2, np.inf]) `@pytest.mark.parametrize`("size", [30, 50, None]) def test_ensure_spacing_trivial(p, size): + rng = np.random.default_rng(42) # --- Empty input assert _ensure_spacing([], p_norm=p) == [] # --- A unique point - coord = np.random.randn(1, 2) + coord = rng.standard_normal((1, 2)) assert np.array_equal(coord, _ensure_spacing(coord, p_norm=p, min_split_size=size)) # --- Verified spacing - coord = np.random.randn(100, 2) + coord = rng.standard_normal((100, 2))
48-60: Consider setting a random seed for reproducibility.Same concern as
test_ensure_spacing_trivial- usingnp.random.randnwithout a seed makes the test non-deterministic.Also, minor grammar nit: Line 53 comment says "between the point" but should be "between the points" (plural).
♻️ Proposed fix
`@pytest.mark.parametrize`("p", [1, 2, np.inf]) `@pytest.mark.parametrize`("size", [50, 100, None]) def test_ensure_spacing_batch_processing(p, size): - coord = np.random.randn(100, 2) + rng = np.random.default_rng(123) + coord = rng.standard_normal((100, 2)) - # --- Consider the average distance between the point as spacing + # --- Consider the average distance between the points as spacing spacing = np.median(pdist(coord, metric=minkowski, p=p))
63-81: Timing-based test may still be flaky on resource-constrained CI.While the relaxed assertion (
dur1 < 1.33 * dur2) helps, timing-based tests remain inherently sensitive to system load. Consider either:
- Using
pytest.mark.slowto optionally skip in CI- Increasing the tolerance further if flakiness persists
- Using a fixed seed for
np.random.randintfor reproducibility♻️ Optional: add slow marker and fixed seed
+@pytest.mark.slow def test_ensure_spacing_max_batch_size(): """Small batches are slow, large batches -> large allocations -> also slow. https://github.com/scikit-image/scikit-image/pull/6035#discussion_r751518691 """ - coords = np.random.randint(low=0, high=1848, size=(40000, 2)) + rng = np.random.default_rng(0) + coords = rng.integers(low=0, high=1848, size=(40000, 2))
84-93: Same recommendations: fixed seed and grammar fix.Consider using a fixed random seed for reproducibility, and update the comment on line 89 to "between the points" (plural).
♻️ Proposed fix
`@pytest.mark.parametrize`("p", [1, 2, np.inf]) `@pytest.mark.parametrize`("size", [30, 50, None]) def test_ensure_spacing_p_norm(p, size): - coord = np.random.randn(100, 2) + rng = np.random.default_rng(456) + coord = rng.standard_normal((100, 2)) - # --- Consider the average distance between the point as spacing + # --- Consider the average distance between the points as spacing spacing = np.median(pdist(coord, metric=minkowski, p=p))
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/skimage/_shared/coord.pysrc/skimage/_shared/meson.buildsrc/skimage2/feature/_peaks.pytests/skimage/_shared/test_coord.pytests/skimage2/feature/test_peaks.py
💤 Files with no reviewable changes (3)
- tests/skimage/_shared/test_coord.py
- src/skimage/_shared/meson.build
- src/skimage/_shared/coord.py
* origin/main: (27 commits) Move `_shared` to `_skimage2` (#8102) Port `pad_footprint` & `mirror_footprint` to `skimage2` (#8094) Add rescaling API to skimage2 (#8075) Move `skimage2` implementation into `_skimage2` (#8093) Undo (double) mirroring in `ski2.morphology.dilation` (#8060) Grammar (#8091) Move `ensure_spacing` into `skimage2` (#8067) Ensure that `skimage2` does not eagerly import `skimage` (#8087) Use lazy-loader 0.5 (#8080) MAINT: make ellipse fitting forward compatible (#8054) Avoid deprecated assign to ndarray.shape (#8020) Avoid circular import in `feature/corner.py` (#8077) Turn off coderabbit auto-labeling & label checks (#8070) Fix GIL being re-enabled by C++ extensions (#8059) Fix conventions following docstub and misc. (#8055) Port grayscale morphology operators to skimage2 (#8046) Add revised `peak_local_max` to `skimage2` (#8039) Allow read-only arrays as input to remap (#7535) Add `prescale` parameter to "blob functions" (#7858) Try to make coderabbit respect exisiting type labels (#8042) ...
Description
When pitching this, I actually thought that
ensure_spacingwas a public function. Turns out it is not. That made porting it easy.It's not used anywhere else besides
peak_local_max. So_shareddidn't seem like a good fit and I just moved it into the same module aspeak_local_max.Checklist
./doc/examplesfor new featuresRelease note
For maintainers and optionally contributors, please refer to the instructions on how to document this PR for the release notes.