diff --git a/core/lls_core/models/deskew.py b/core/lls_core/models/deskew.py index de741b47..59135ed0 100644 --- a/core/lls_core/models/deskew.py +++ b/core/lls_core/models/deskew.py @@ -184,8 +184,17 @@ def read_image(cls, values: dict): aics = AICSImage(fspath(img)) elif isinstance(img, AICSImage): aics = img + elif isinstance(img, DataArray): + if set(img.dims) >= {"Z", "Y", "X"}: + # If it's already a DataArray with the right dimensions, we're done + return values + else: + raise ValueError("If passing a DataArray, it should at least have Z Y and X dimensions, appropriately labelled.") elif is_arraylike(img): - values["input_image"] = DataArray(img) + if len(img.shape) == 3: + values["input_image"] = DataArray(img, dims=["Z", "Y", "X"]) + else: + raise ValueError("Only 3D numpy arrays are currently supported. If you have a different shape, please use a DataArray and name your dimensions C, T, Z, Y and/or Z.") else: raise ValueError("Value of input_image was neither a path, an AICSImage, or array-like.") diff --git a/core/tests/conftest.py b/core/tests/conftest.py index 8eaf5022..0fefc07a 100644 --- a/core/tests/conftest.py +++ b/core/tests/conftest.py @@ -17,6 +17,11 @@ def runner() -> CliRunner: return CliRunner() +@pytest.fixture +def lls7_t1_ch1(): + with as_file(resources / "LLS7_t1_ch1.czi") as image_path: + yield image_path + @pytest.fixture def rbc_tiny(): with as_file(resources / "RBC_tiny.czi") as image_path: diff --git a/core/tests/test_process.py b/core/tests/test_process.py index cd5c1432..1a31721b 100644 --- a/core/tests/test_process.py +++ b/core/tests/test_process.py @@ -10,6 +10,7 @@ from napari_workflows import Workflow from pytest import FixtureRequest + from .params import parameterized root = Path(__file__).parent / "data" @@ -86,31 +87,33 @@ def test_process_time_range(multi_channel_time: Path): @pytest.mark.parametrize(["background"], [(1,), ("auto",), ("second_last",)]) -@parameterized -def test_process_deconvolution(args: dict, background: Any): - for slice in ( - LatticeData.parse_obj( - { - "input_image": root / "raw.tif", - "deconvolution": { - "psf": [root / "psf.tif"], - "background": background, - }, - **args, - } - ) - .process() - .slices - ): - assert slice.data.ndim == 3 +def test_process_deconvolution(background: Any): + import numpy as np + with tempfile.TemporaryDirectory() as outdir: + for slice in ( + LatticeData.parse_obj( + { + # Use random sample data here, since we're not testing the correctness of the deconvolution + # but rather that all the code paths are functional + "input_image": np.random.random_sample((128, 128, 64)), + "deconvolution": { + "psf": [np.random.random_sample((28, 28, 28))], + "background": background, + }, + "save_dir": outdir + } + ) + .process() + .slices + ): + assert slice.data.ndim == 3 -@parameterized @pytest.mark.parametrize( ["workflow_name"], [("image_workflow",), ("table_workflow",)] ) def test_process_workflow( - args: dict, request: FixtureRequest, workflow_name: str + request: FixtureRequest, lls7_t1_ch1: Path, workflow_name: str ): from pandas import DataFrame @@ -119,10 +122,9 @@ def test_process_workflow( for output in ( LatticeData.parse_obj( { - "input_image": root / "raw.tif", + "input_image": lls7_t1_ch1, "workflow": workflow, - "save_dir": tmpdir, - **args, + "save_dir": tmpdir } ) .process_workflow() @@ -132,19 +134,19 @@ def test_process_workflow( assert isinstance(output.data, (Path, DataFrame)) def test_table_workflow( - rbc_tiny: Path, table_workflow: Workflow + lls7_t1_ch1: Path, table_workflow: Workflow ): with tempfile.TemporaryDirectory() as _tmpdir: tmpdir = Path(_tmpdir) results = set(LatticeData.parse_obj( { - "input_image": rbc_tiny, + "input_image": lls7_t1_ch1, "workflow": table_workflow, "save_dir": tmpdir } ).process_workflow().save()) # There should be one output for each element of the tuple - assert {result.name for result in results} == {'RBC_tiny_deskewed_output_3.csv', 'RBC_tiny_deskewed.h5', 'RBC_tiny_deskewed_output_1.csv', 'RBC_tiny_deskewed_output_2.csv'} + assert {result.name for result in results} == {'LLS7_t1_ch1_deskewed_output_3.csv', 'LLS7_t1_ch1_deskewed.h5', 'LLS7_t1_ch1_deskewed_output_1.csv', 'LLS7_t1_ch1_deskewed_output_2.csv'} @pytest.mark.parametrize( ["roi_subset"], diff --git a/core/tests/test_workflows.py b/core/tests/test_workflows.py index aceb5a96..18ff171e 100644 --- a/core/tests/test_workflows.py +++ b/core/tests/test_workflows.py @@ -55,22 +55,22 @@ def test_workflow_cli(workflow_config_cli: dict, save_func: Callable, cli_param: assert label_img.shape == (3, 14, 5) assert label_img[1, 6, 2] == 1 -def test_image_workflow(minimal_image_path: Path, image_workflow: Workflow): +def test_image_workflow(lls7_t1_ch1: Path, image_workflow: Workflow): # Test that a regular workflow that returns an image directly works with tempfile.TemporaryDirectory() as tmpdir: for output in LatticeData( - input_image = minimal_image_path, + input_image = lls7_t1_ch1, workflow = image_workflow, save_dir = tmpdir ).process_workflow().process(): assert isinstance(output.data, Path) assert valid_image_path(output.data) -def test_table_workflow(minimal_image_path: Path, table_workflow: Workflow): +def test_table_workflow(lls7_t1_ch1: Path, table_workflow: Workflow): # Test a complex workflow that returns a tuple of images and data with tempfile.TemporaryDirectory() as tmpdir: params = LatticeData( - input_image = minimal_image_path, + input_image = lls7_t1_ch1, workflow = table_workflow, save_dir = tmpdir ) @@ -111,12 +111,12 @@ def test_sum_preview(rbc_tiny: Path): assert len(previews) == 1, "There should be 1 preview when cropping is disabled" assert previews[0].ndim == 3, "A preview should be a 3D image" -def test_crop_workflow(rbc_tiny: Path): +def test_crop_workflow(lls7_t1_ch1: Path): # Tests that crop workflows only process each ROI lazily with tempfile.TemporaryDirectory() as tmpdir: params = LatticeData( - input_image = rbc_tiny, + input_image = lls7_t1_ch1, workflow = "core/tests/workflows/binarisation/workflow.yml", save_dir = tmpdir, crop=CropParams( diff --git a/plugin/tests/test_dock_widget.py b/plugin/tests/test_dock_widget.py index ef846cfb..6fde3b6a 100644 --- a/plugin/tests/test_dock_widget.py +++ b/plugin/tests/test_dock_widget.py @@ -35,7 +35,7 @@ def image_data(request: pytest.FixtureRequest): Fixture function that yields test images as file paths """ with as_file(resources / request.param) as image_path: - yield AICSImage(image_path) + yield AICSImage(image_path, ) def set_debug(cls: MagicTemplate): """