Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 32 additions & 8 deletions .github/workflows/test_and_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ jobs:
fail-fast: false
matrix:
platform: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}

Expand All @@ -60,19 +60,43 @@ jobs:
PLATFORM: ${{ matrix.platform }}

- name: Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v6

test-cellpose3:
name: cellpose v3 compat (ubuntu, py3.11)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
with:
python-version: "3.11"

- uses: tlambert03/setup-qt-libs@v1

- name: Install dependencies (cellpose v3 pinned)
run: |
python -m pip install --upgrade pip
python -m pip install ".[testing]" "cellpose>=3,<4"

- name: Test with pytest
uses: aganders3/headless-gui@v2
with:
run: pytest -v --color=yes
env:
CI: true

deploy:
# this will run when you have tagged a commit, starting with "v*"
# and requires that you have put your twine API key in your
# and requires that you have put your twine API key in your
# github secrets (see readme for details)
needs: [test]
needs: [test, test-cellpose3]
runs-on: ubuntu-latest
if: contains(github.ref, 'tags')
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v6
with:
python-version: "3.x"
- name: Install dependencies
Expand Down
6 changes: 0 additions & 6 deletions MANIFEST.in

This file was deleted.

3 changes: 0 additions & 3 deletions cellpose_napari/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,3 @@
from ._version import version as __version__
except ImportError:
__version__ = "unknown"

from ._dock_widget import napari_experimental_provide_dock_widget
from ._sample_data import napari_provide_sample_data
534 changes: 330 additions & 204 deletions cellpose_napari/_dock_widget.py

Large diffs are not rendered by default.

70 changes: 29 additions & 41 deletions cellpose_napari/_sample_data.py
Original file line number Diff line number Diff line change
@@ -1,48 +1,36 @@
import os
import pathlib
from functools import partial

from napari.utils.translations import trans
from napari_plugin_engine import napari_hook_implementation
def extract_zip(cached_file, url, data_path):
import zipfile
from cellpose import utils

CELLPOSE_DATA = [
('rgb_3D.tif', trans._('Cells (3D+2Ch)')),
('rgb_2D.png', trans._('Cells 2D')),
]

def _load_cellpose_data(image_name, dname):
# Import when users select one of sample data
import numpy as np
from cellpose.io import imread
from cellpose.utils import download_url_to_file
if not cached_file.exists():
utils.download_url_to_file(url, cached_file)
with zipfile.ZipFile(cached_file,"r") as zip_ref:
zip_ref.extractall(data_path)

def _get_data_dir():
cp_dir = pathlib.Path.home().joinpath('.cellpose')
cp_dir.mkdir(exist_ok=True)
zip_path = cp_dir.joinpath('data.zip')
data_dir = cp_dir.joinpath('data')
data_dir.mkdir(exist_ok=True)
data_dir_2D = data_dir.joinpath('2D')
data_dir_2D.mkdir(exist_ok=True)
data_dir_3D = data_dir.joinpath('3D')
data_dir_3D.mkdir(exist_ok=True)

url = 'http://www.cellpose.org/static/data/' + image_name
if '2D' in image_name:
cached_file = str(data_dir_2D.joinpath(image_name))
else:
cached_file = str(data_dir_3D.joinpath(image_name))
if not os.path.exists(cached_file):
download_url_to_file(url, cached_file, progress=True)
data = imread(cached_file)
if '3D' in image_name:
data = np.moveaxis(data, 0, 1)
return [(data, {'name': dname})]

_DATA = {
key: {'data': partial(_load_cellpose_data, key, dname), 'display_name': dname}
for (key, dname) in CELLPOSE_DATA
}
globals().update({k: v['data'] for k, v in _DATA.items()})

@napari_hook_implementation
def napari_provide_sample_data():
return _DATA
extract_zip(zip_path, 'https://osf.io/download/s52q3/', cp_dir)
return data_dir


def make_rgb_2d_sample():
from cellpose.io import imread

data_dir = _get_data_dir()
data = imread(str(data_dir / '2D' / 'rgb_2D_tif.tif'))
return [(data, {'name': 'Cells (2D+2Ch)'})]


def make_rgb_3d_sample():
from cellpose.io import imread

data_dir = _get_data_dir()
data = imread(str(data_dir / '3D' / 'rgb_3D.tif')) # shape (Z, C, Y, X)
# to get display in napari with channels, use channel_axis=1

return [(data, {'name': 'Cells (3D+2Ch)', "axis_labels": ("z", "c", "y", "x")})]
11 changes: 5 additions & 6 deletions cellpose_napari/napari.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@ contributions:
- id: cellpose-napari.widget_wrapper
title: Create cellpose
python_name: cellpose_napari._dock_widget:widget_wrapper
# samples
- id: cellpose-napari.data.rgb_3D
title: Generate RGB 3D sample
python_name: cellpose_napari._sample_data:rgb_3D.tif
python_name: cellpose_napari._sample_data:make_rgb_3d_sample
- id: cellpose-napari.data.rgb_2D
title: Generate RGB 2D sample
python_name: cellpose_napari._sample_data:rgb_2D.png
python_name: cellpose_napari._sample_data:make_rgb_2d_sample
widgets:
- command: cellpose-napari.widget_wrapper
display_name: cellpose
sample_data:
- display_name: Cells (2D+2Ch)
key: rgb_2D
command: cellpose-napari.data.rgb_2D
- display_name: Cells (3D+2Ch)
key: rgb_3D
command: cellpose-napari.data.rgb_3D
- display_name: Cells 2D
key: rgb_2D
command: cellpose-napari.data.rgb_2D
18 changes: 0 additions & 18 deletions environment.yml

This file was deleted.

96 changes: 94 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,98 @@
[build-system]
requires = ["setuptools", "wheel", "setuptools_scm"]
requires = ["setuptools>=64", "setuptools_scm>=7"]
build-backend = "setuptools.build_meta"

[project]
name = "cellpose-napari"
description = "a generalist algorithm for anatomical segmentation"
readme = "README.md"
license = { text = "BSD-3-Clause" }
authors = [{ name = "Carsen Stringer", email = "stringerc@janelia.hhmi.org" }]
requires-python = ">=3.10"
classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Operating System :: OS Independent",
"License :: OSI Approved :: BSD License",
"Framework :: napari",
]
dependencies = [
"napari>=0.6",
"magicgui",
"cellpose>=3",
"imagecodecs",
]
dynamic = ["version"]

[project.urls]
Homepage = "https://github.com/Mouseland/cellpose-napari"

[project.optional-dependencies]
docs = [
"sphinx>=3.0",
"sphinxcontrib-apidoc",
"sphinx_rtd_theme",
"sphinx-prompt",
"sphinx-autodoc-typehints",
]
testing = [
"tox",
"pytest",
"pytest-cov",
"pytest-qt",
"napari",
"pyqt5",
]

[project.entry-points."napari.manifest"]
cellpose-napari = "cellpose_napari:napari.yaml"

[tool.setuptools_scm]
write_to = "cellpose_napari/_version.py"
version_file = "cellpose_napari/_version.py"

[tool.setuptools.packages.find]
exclude = ["tests", "tests.*"]

[tool.setuptools.package-data]
cellpose_napari = ["napari.yaml"]

[tool.tox]
legacy_tox_ini = """
[tox]
envlist = py{310,311,312}-{linux,macos,windows}
isolated_build = true
toxworkdir = /tmp/.tox

[gh-actions]
python =
3.10: py310
3.11: py311
3.12: py312

[gh-actions:env]
PLATFORM =
ubuntu-latest: linux
macos-latest: macos
windows-latest: windows

[testenv]
platform =
macos: darwin
linux: linux
windows: win32
passenv =
CI
GITHUB_ACTIONS
DISPLAY
XAUTHORITY
NUMPY_EXPERIMENTAL_ARRAY_FUNCTION
PYVISTA_OFF_SCREEN
setenv =
TORCHINDUCTOR_CACHE_DIR = {envtmpdir}/torchinductor
extras =
testing
commands = pytest -v --color=yes --cov=cellpose_napari --cov-report=xml
"""
4 changes: 0 additions & 4 deletions requirements.txt

This file was deleted.

59 changes: 0 additions & 59 deletions setup.cfg

This file was deleted.

3 changes: 3 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# torch must be imported before PyQt on Windows to avoid DLL init failure
# https://github.com/pytorch/pytorch/issues/166628
import torch # noqa: F401
Loading