Skip to content

Commit

Permalink
Merge branch 'main' into set_3d_checkbox
Browse files Browse the repository at this point in the history
  • Loading branch information
psobolewskiPhD authored Oct 1, 2024
2 parents e69ec3f + c129834 commit 2054bf7
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 42 deletions.
27 changes: 11 additions & 16 deletions .github/workflows/test_and_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,26 @@ on:
- main
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
name: ${{ matrix.platform }} ${{ matrix.python-version }}
runs-on: ${{ matrix.platform }}
defaults:
run:
shell: bash -l {0}
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest]#, macos-latest, windows-latest]
python-version: ["3.9", "3.10", "3.11"]
backend: [pyqt5]
platform: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4
- uses: conda-incubator/setup-miniconda@v2

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
miniconda-version: "latest"
channels: conda-forge
channel-priority: strict
python-version: ${{ matrix.python-version }}

- uses: tlambert03/setup-qt-libs@v1
Expand All @@ -51,18 +50,14 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade setuptools tox tox-conda tox-gh-actions
python -m pip install --upgrade setuptools tox tox-gh-actions
- name: Test with tox
uses: aganders3/headless-gui@v1.2
uses: aganders3/headless-gui@v2
with:
shell: bash -el {0}
run: python -m tox
env:
PLATFORM: ${{ matrix.platform }}
PYTHON: ${{ matrix.python-version }}
PYVISTA_OFF_SCREEN: True
BACKEND: ${{ matrix.backend }}

- name: Codecov
uses: codecov/codecov-action@v3
Expand Down
16 changes: 6 additions & 10 deletions cellpose_napari/_dock_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ def run_cellpose(image, model_type, custom_model, channels, channel_axis, diamet
CP = models.CellposeModel(pretrained_model=custom_model, gpu=True)
else:
CP = models.CellposeModel(model_type=model_type, gpu=True)

print(cellprob_threshold, flow_threshold)
masks, flows_orig, _ = CP.eval(image,
channels=channels,
channel_axis=channel_axis,
Expand Down Expand Up @@ -105,22 +107,16 @@ def compute_diameter(image, channels, model_type):

@thread_worker
def compute_masks(masks_orig, flows_orig, cellprob_threshold, flow_threshold):
import cv2
from cellpose.utils import fill_holes_and_remove_small_masks
from cellpose.dynamics import get_masks
from cellpose.transforms import resize_image
from cellpose.dynamics import resize_and_compute_masks

#print(flows_orig[3].shape, flows_orig[2].shape, masks_orig.shape)
flow_threshold = (31.0 - flow_threshold) / 10.
if flow_threshold==0.0:
flow_threshold = 0.0
logger.debug('flow_threshold=0 => no masks thrown out due to model mismatch')
logger.debug(f'computing masks with cellprob_threshold={cellprob_threshold}, flow_threshold={flow_threshold}')
maski = get_masks(flows_orig[3].copy(), iscell=(flows_orig[2] > cellprob_threshold),
flows=flows_orig[1], threshold=flow_threshold*(masks_orig.ndim<3))
maski = fill_holes_and_remove_small_masks(maski)
maski = resize_image(maski, masks_orig.shape[-2], masks_orig.shape[-1],
interpolation=cv2.INTER_NEAREST)
maski, _ = resize_and_compute_masks(flows_orig[1], cellprob=flows_orig[2], cellprob_threshold=cellprob_threshold,
flow_threshold=flow_threshold, resize=(masks_orig.shape[-2], masks_orig.shape[-1]))

return maski

@magicgui(
Expand Down
30 changes: 16 additions & 14 deletions tests/test_plugin.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import os
import sys
from pathlib import Path
from math import isclose
from typing import Callable

import cellpose_napari
import napari
import pytest
import torch # for ubuntu tests on CI, see https://github.com/pytorch/pytorch/issues/75912
from cellpose_napari._dock_widget import widget_wrapper

# this is your plugin name declared in your napari.plugins entry point
PLUGIN_NAME = "cellpose-napari"
Expand All @@ -17,6 +14,14 @@

SAMPLE = Path(__file__).parent / "sample.tif"

@pytest.fixture(autouse=True)
def patch_mps_on_CI(monkeypatch):
# https://github.com/actions/runner-images/issues/9918
if os.getenv('CI'):
monkeypatch.setattr("torch.backends.mps.is_available", lambda: False)
monkeypatch.setattr("cellpose.core.assign_device", lambda **kwargs: (torch.device("cpu"), False))


@pytest.fixture
def viewer_widget(make_napari_viewer: Callable[..., napari.Viewer]):
viewer = make_napari_viewer()
Expand All @@ -32,11 +37,7 @@ def test_basic_function(qtbot, viewer_widget):
viewer.open_sample(PLUGIN_NAME, 'rgb_2D')
viewer.layers[0].data = viewer.layers[0].data[0:128, 0:128]

#if os.getenv("CI"):
# return
# actually running cellpose like this takes too long and always timesout on CI
# need to figure out better strategy

widget.model_type.value = "cyto3"
widget() # run segmentation with all default parameters

def check_widget():
Expand All @@ -47,10 +48,9 @@ def check_widget():
assert len(viewer.layers) == 5
assert "cp_masks" in viewer.layers[-1].name

# check that the segmentation was proper, should yield 11 cells
# check that the segmentation was proper, cyto3 yields 10 cells
assert viewer.layers[-1].data.max() == 10

@pytest.mark.skipif(sys.platform.startswith('linux'), reason="ubuntu stalls with two cellpose tests")
def test_compute_diameter(qtbot, viewer_widget):
viewer, widget = viewer_widget
viewer.open_sample(PLUGIN_NAME, 'rgb_2D')
Expand All @@ -63,9 +63,10 @@ def test_compute_diameter(qtbot, viewer_widget):
with qtbot.waitSignal(widget.diameter.changed, timeout=60_000) as blocker:
widget.compute_diameter_button.changed(None)

assert isclose(float(widget.diameter.value), 24.1, abs_tol=10**-1)
# local on macOS with MPS, get 20.37, with CPU-only it's 20.83, same as CI
# so choosing a target that works for both
assert isclose(float(widget.diameter.value), 20.6, abs_tol=0.3)

@pytest.mark.skipif(sys.platform.startswith('linux'), reason="ubuntu stalls with >1 cellpose tests")
def test_3D_segmentation(qtbot, viewer_widget):
viewer, widget = viewer_widget
# by default the widget loads with `process_3D` set to False
Expand All @@ -75,6 +76,7 @@ def test_3D_segmentation(qtbot, viewer_widget):
# check that 3D processing is set correctly after opening a 3D image
assert widget.process_3D.value == True

widget.model_type.value = "cyto3"
widget() # run segmentation with all default parameters

def check_widget():
Expand All @@ -85,5 +87,5 @@ def check_widget():
assert len(viewer.layers) == 5
assert "cp_masks" in viewer.layers[-1].name

# check that the segmentation was proper, should yield 7 cells
assert viewer.layers[-1].data.max() == 7
# check that the segmentation was proper, `cyto3` should yield 9 cells
assert viewer.layers[-1].data.max() == 9
5 changes: 3 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# For more information about tox, see https://tox.readthedocs.io/en/latest/
[tox]
envlist = py{38,39,310}-{linux,macos,windows}
envlist = py{39,310,311,312}-{linux,macos,windows}
isolated_build=true
toxworkdir = /tmp/.tox

[gh-actions]
python =
3.8: py38
3.9: py39
3.10: py310
3.11: py311
3.12: py312

[gh-actions:env]
PLATFORM =
Expand Down

0 comments on commit 2054bf7

Please sign in to comment.