diff --git a/.github/workflows/test_and_deploy.yml b/.github/workflows/test_and_deploy.yml index dd33112..f23e39e 100644 --- a/.github/workflows/test_and_deploy.yml +++ b/.github/workflows/test_and_deploy.yml @@ -53,16 +53,38 @@ jobs: # setup-miniconda: https://github.com/conda-incubator/setup-miniconda # and # tox-conda: https://github.com/tox-dev/tox-conda + - name: Set up conda ${{ matrix.python-version }} + uses: conda-incubator/setup-miniconda@v2.2.0 + with: + auto-update-conda: true + activate-environment: test + python-version: ${{ matrix.python-version }} + channels: conda-forge + - name: Conda info + shell: bash -l {0} + run: conda info + - name: Install pocl + if: runner.os == 'Linux' + shell: bash -l {0} + run: conda install -y pocl - name: Install dependencies + shell: bash -l {0} run: | - python -m pip install --upgrade pip - pip install setuptools tox tox-gh-actions + python --version + conda install -y pip setuptools wheel pytest pytest-cov pytest-benchmark pytest-qt pyqt pytest-xvfb + # pip install setuptools tox tox-gh-actions + pip install -e . # this runs the platform-specific tests declared in tox.ini - - name: Test with tox - run: tox - env: - PLATFORM: ${{ matrix.platform }} + #- name: Install tox-conda + # run: pip install tox-conda + #- name: Test with tox + # run: tox + # env: + # PLATFORM: ${{ matrix.platform }} + - name: Test + shell: bash -l {0} + run: pytest -v --cov=./ --cov-report=xml - name: Coverage uses: codecov/codecov-action@v1 diff --git a/src/napari_time_slicer/_function.py b/src/napari_time_slicer/_function.py index 249f1ee..d4c64fa 100644 --- a/src/napari_time_slicer/_function.py +++ b/src/napari_time_slicer/_function.py @@ -4,19 +4,15 @@ import numpy as np from typing_extensions import Annotated from napari_plugin_engine import napari_hook_implementation -from napari.layers import Image, Labels, Layer from napari_tools_menu import register_function, register_action -import napari -import tempfile - -LayerInput = Annotated[Layer, {"label": "Image"}] @napari_hook_implementation def napari_experimental_provide_function(): return [convert_to_2d_timelapse] @register_function(menu="Utilities > Convert 3D stack to 2D timelapse (time-slicer)") -def convert_to_2d_timelapse(layer : LayerInput, viewer:napari.Viewer = None) -> Layer: +def convert_to_2d_timelapse(layer : "napari.layers.Layer", viewer:"napari.Viewer" = None) -> "napari.layers.Layer": + from napari.layers import Image, Labels, Layer if isinstance(layer, Labels): result = Labels(layer.data[:,np.newaxis,:,:], name="2d+t " + layer.name) else: @@ -29,11 +25,13 @@ def convert_to_2d_timelapse(layer : LayerInput, viewer:napari.Viewer = None) -> return result @register_function(menu="Utilities > Convert on-the-fly processed timelapse to 4D stack (time-slicer)") -def convert_to_stack4d(layer : LayerInput, viewer: napari.Viewer) -> Layer: +def convert_to_stack4d(layer : "napari.layers.Layer", viewer: "napari.Viewer") -> "napari.layers.Layer": """ Go through time (by moving the time-slider in napari) and copy 3D frames of a given layer and store them in a new 4D layer in napari. """ + from napari.layers import Image, Labels, Layer + # in case of 4D-data (timelapse) crop out the current 3D timepoint if len(viewer.dims.current_step) != 4: raise NotImplementedError("Processing all frames only supports 4D-data") @@ -77,17 +75,20 @@ def convert_to_stack4d(layer : LayerInput, viewer: napari.Viewer) -> Layer: @register_function(menu="Utilities > Convert to file-backed timelapse data (time-slicer)", folder_name = dict(widget_type='FileEdit', mode='d')) -def convert_to_file_backed_timelapse(layer : LayerInput, +def convert_to_file_backed_timelapse(layer : "napari.layers.Layer", folder_name: "magicgui.types.PathLike" = "", - viewer: napari.Viewer = None) -> Layer: + viewer: "napari.Viewer" = None) -> "napari.layers.Layer": """ Save a 4D stack to disk and create a new layer that reads only the current timepoint from disk """ + from napari.layers import Image, Labels, Layer + from skimage.io import imsave + import os + import tempfile + if len(viewer.dims.current_step) != 4: raise NotImplementedError("Convert to file-backed timelapse data only supports 4D-data") - from skimage.io import imsave - import os folder_name = str(folder_name) if len(folder_name) == 0 or folder_name == ".": @@ -143,10 +144,12 @@ def convert_to_file_backed_timelapse(layer : LayerInput, def load_file_backed_timelapse(folder_name: "magicgui.types.PathLike" = "", is_labels:bool = False, name:str = "", - viewer: napari.Viewer = None) -> Layer: + viewer: "napari.Viewer" = None) -> "napari.layers.Layer": """ Load a folder of tif-images where every tif-file corresponds to a frame in a 4D stack. """ + from napari.layers import Image, Labels, Layer + import os from skimage.io import imsave from functools import partial diff --git a/tox.ini b/tox.ini index 7d4923f..4654ea2 100644 --- a/tox.ini +++ b/tox.ini @@ -22,7 +22,8 @@ platform = passenv = CI GITHUB_ACTIONS - DISPLAY XAUTHORITY + DISPLAY + XAUTHORITY NUMPY_EXPERIMENTAL_ARRAY_FUNCTION PYVISTA_OFF_SCREEN deps =