From bd07d0f812c6fd78b0449ffa4dc436c334fba2a0 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 09:20:14 +0200 Subject: [PATCH 01/21] Move tasks to subpackage (ref #378) --- fractal_tasks_core/tasks/__init__.py | 0 fractal_tasks_core/{ => tasks}/_utils.py | 0 fractal_tasks_core/{ => tasks}/cellpose_segmentation.py | 0 fractal_tasks_core/{ => tasks}/compress_tif.py | 0 fractal_tasks_core/{ => tasks}/copy_ome_zarr.py | 0 fractal_tasks_core/{ => tasks}/create_ome_zarr.py | 0 fractal_tasks_core/{ => tasks}/create_ome_zarr_multiplex.py | 0 fractal_tasks_core/{ => tasks}/illumination_correction.py | 0 fractal_tasks_core/{ => tasks}/maximum_intensity_projection.py | 0 fractal_tasks_core/{ => tasks}/napari_workflows_wrapper.py | 0 fractal_tasks_core/{ => tasks}/yokogawa_to_ome_zarr.py | 0 11 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 fractal_tasks_core/tasks/__init__.py rename fractal_tasks_core/{ => tasks}/_utils.py (100%) rename fractal_tasks_core/{ => tasks}/cellpose_segmentation.py (100%) rename fractal_tasks_core/{ => tasks}/compress_tif.py (100%) rename fractal_tasks_core/{ => tasks}/copy_ome_zarr.py (100%) rename fractal_tasks_core/{ => tasks}/create_ome_zarr.py (100%) rename fractal_tasks_core/{ => tasks}/create_ome_zarr_multiplex.py (100%) rename fractal_tasks_core/{ => tasks}/illumination_correction.py (100%) rename fractal_tasks_core/{ => tasks}/maximum_intensity_projection.py (100%) rename fractal_tasks_core/{ => tasks}/napari_workflows_wrapper.py (100%) rename fractal_tasks_core/{ => tasks}/yokogawa_to_ome_zarr.py (100%) diff --git a/fractal_tasks_core/tasks/__init__.py b/fractal_tasks_core/tasks/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/fractal_tasks_core/_utils.py b/fractal_tasks_core/tasks/_utils.py similarity index 100% rename from fractal_tasks_core/_utils.py rename to fractal_tasks_core/tasks/_utils.py diff --git a/fractal_tasks_core/cellpose_segmentation.py b/fractal_tasks_core/tasks/cellpose_segmentation.py similarity index 100% rename from fractal_tasks_core/cellpose_segmentation.py rename to fractal_tasks_core/tasks/cellpose_segmentation.py diff --git a/fractal_tasks_core/compress_tif.py b/fractal_tasks_core/tasks/compress_tif.py similarity index 100% rename from fractal_tasks_core/compress_tif.py rename to fractal_tasks_core/tasks/compress_tif.py diff --git a/fractal_tasks_core/copy_ome_zarr.py b/fractal_tasks_core/tasks/copy_ome_zarr.py similarity index 100% rename from fractal_tasks_core/copy_ome_zarr.py rename to fractal_tasks_core/tasks/copy_ome_zarr.py diff --git a/fractal_tasks_core/create_ome_zarr.py b/fractal_tasks_core/tasks/create_ome_zarr.py similarity index 100% rename from fractal_tasks_core/create_ome_zarr.py rename to fractal_tasks_core/tasks/create_ome_zarr.py diff --git a/fractal_tasks_core/create_ome_zarr_multiplex.py b/fractal_tasks_core/tasks/create_ome_zarr_multiplex.py similarity index 100% rename from fractal_tasks_core/create_ome_zarr_multiplex.py rename to fractal_tasks_core/tasks/create_ome_zarr_multiplex.py diff --git a/fractal_tasks_core/illumination_correction.py b/fractal_tasks_core/tasks/illumination_correction.py similarity index 100% rename from fractal_tasks_core/illumination_correction.py rename to fractal_tasks_core/tasks/illumination_correction.py diff --git a/fractal_tasks_core/maximum_intensity_projection.py b/fractal_tasks_core/tasks/maximum_intensity_projection.py similarity index 100% rename from fractal_tasks_core/maximum_intensity_projection.py rename to fractal_tasks_core/tasks/maximum_intensity_projection.py diff --git a/fractal_tasks_core/napari_workflows_wrapper.py b/fractal_tasks_core/tasks/napari_workflows_wrapper.py similarity index 100% rename from fractal_tasks_core/napari_workflows_wrapper.py rename to fractal_tasks_core/tasks/napari_workflows_wrapper.py diff --git a/fractal_tasks_core/yokogawa_to_ome_zarr.py b/fractal_tasks_core/tasks/yokogawa_to_ome_zarr.py similarity index 100% rename from fractal_tasks_core/yokogawa_to_ome_zarr.py rename to fractal_tasks_core/tasks/yokogawa_to_ome_zarr.py From a7cda9a47c5b987863e82142477a0125c4d2af15 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 09:24:26 +0200 Subject: [PATCH 02/21] Update `executable`s in manifest (ref #378) --- fractal_tasks_core/__FRACTAL_MANIFEST__.json | 43 ++++++++++++++++---- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/fractal_tasks_core/__FRACTAL_MANIFEST__.json b/fractal_tasks_core/__FRACTAL_MANIFEST__.json index 9e33785ee..5da16a84c 100644 --- a/fractal_tasks_core/__FRACTAL_MANIFEST__.json +++ b/fractal_tasks_core/__FRACTAL_MANIFEST__.json @@ -76,7 +76,13 @@ "title": "CreateOmeZarr", "type": "object" }, - "executable": "create_ome_zarr.py", + "default_args": { + "coarsening_xy": 2, + "image_extension": "tif", + "metadata_table": "mrf_mlf", + "num_levels": 2 + }, + "executable": "tasks/create_ome_zarr.py", "input_type": "image", "meta": { "cpus_per_task": 1, @@ -128,7 +134,7 @@ "title": "YokogawaToOmeZarr", "type": "object" }, - "executable": "yokogawa_to_ome_zarr.py", + "executable": "tasks/yokogawa_to_ome_zarr.py", "input_type": "zarr", "meta": { "cpus_per_task": 1, @@ -175,7 +181,6 @@ "type": "boolean" }, "suffix": { - "default": "mip", "description": "The suffix that is used to transform ``plate.zarr`` into ``plate_suffix.zarr``. Note that `None` is not currently supported.", "title": "Suffix", "type": "string" @@ -189,7 +194,11 @@ "title": "CopyOmeZarr", "type": "object" }, - "executable": "copy_ome_zarr.py", + "default_args": { + "project_to_2D": true, + "suffix": "mip" + }, + "executable": "tasks/copy_ome_zarr.py", "input_type": "zarr", "meta": { "cpus_per_task": 1, @@ -235,7 +244,7 @@ "title": "MaximumIntensityProjection", "type": "object" }, - "executable": "maximum_intensity_projection.py", + "executable": "tasks/maximum_intensity_projection.py", "input_type": "zarr", "meta": { "cpus_per_task": 1, @@ -394,7 +403,7 @@ "title": "CellposeSegmentation", "type": "object" }, - "executable": "cellpose_segmentation.py", + "executable": "tasks/cellpose_segmentation.py", "input_type": "zarr", "meta": { "cpus_per_task": 4, @@ -465,7 +474,11 @@ "title": "IlluminationCorrection", "type": "object" }, - "executable": "illumination_correction.py", + "default_args": { + "background": 100, + "overwrite": false + }, + "executable": "tasks/illumination_correction.py", "input_type": "zarr", "meta": { "cpus_per_task": 1, @@ -566,7 +579,13 @@ "title": "NapariWorkflowsWrapper", "type": "object" }, - "executable": "napari_workflows_wrapper.py", + "default_args": { + "expected_dimensions": 3, + "input_ROI_table": "FOV_ROI_table", + "level": 0, + "relabeling": true + }, + "executable": "tasks/napari_workflows_wrapper.py", "input_type": "zarr", "meta": { "cpus_per_task": 8, @@ -664,7 +683,13 @@ "title": "CreateOmeZarrMultiplex", "type": "object" }, - "executable": "create_ome_zarr_multiplex.py", + "default_args": { + "coarsening_xy": 2, + "image_extension": "tif", + "metadata_table": "mrf_mlf", + "num_levels": 2 + }, + "executable": "tasks/create_ome_zarr_multiplex.py", "input_type": "image", "meta": { "cpus_per_task": 1, From 7ab70182b30696d93b954022bbc02ad371206101 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 09:32:46 +0200 Subject: [PATCH 03/21] Update use of `executable`s in dev tools --- fractal_tasks_core/dev/lib_args_schemas.py | 7 ++++--- .../dev/{create_args_schemas.py => new_args_schema.py} | 0 2 files changed, 4 insertions(+), 3 deletions(-) rename fractal_tasks_core/dev/{create_args_schemas.py => new_args_schema.py} (100%) diff --git a/fractal_tasks_core/dev/lib_args_schemas.py b/fractal_tasks_core/dev/lib_args_schemas.py index 96303fe11..642db44d0 100644 --- a/fractal_tasks_core/dev/lib_args_schemas.py +++ b/fractal_tasks_core/dev/lib_args_schemas.py @@ -83,11 +83,12 @@ def _get_args_descriptions(executable) -> dict[str, str]: """ # Read docstring (via ast) module_path = Path(fractal_tasks_core.__file__).parent / executable + module_name = module_path.with_suffix("").name tree = ast.parse(module_path.read_text()) function = next( f for f in ast.walk(tree) - if (isinstance(f, ast.FunctionDef) and f.name == executable[:-3]) + if (isinstance(f, ast.FunctionDef) and f.name == module_name) ) docstring = ast.get_docstring(function) # Parse docstring (via docstring_parser) and prepare output @@ -126,8 +127,8 @@ def create_schema_for_single_task(executable: str) -> _Schema: if not executable.endswith(".py"): raise ValueError(f"Invalid {executable=} (it must end with `.py`).") # Import function - module_name = executable[:-3] - module = import_module(f"fractal_tasks_core.{module_name}") + module_name = Path(executable).with_suffix("").name + module = import_module(f"fractal_tasks_core.tasks.{module_name}") task_function = getattr(module, module_name) # Create and clean up schema diff --git a/fractal_tasks_core/dev/create_args_schemas.py b/fractal_tasks_core/dev/new_args_schema.py similarity index 100% rename from fractal_tasks_core/dev/create_args_schemas.py rename to fractal_tasks_core/dev/new_args_schema.py From 46d98c3daf054cd68c9321d0bfb599d7b81ec72e Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 09:34:03 +0200 Subject: [PATCH 04/21] Update tests --- tests/test_unit_compression.py | 2 +- tests/test_unit_illumination_correction.py | 9 ++-- tests/test_unit_napari_workflows_wrapper.py | 2 +- tests/test_unit_task.py | 2 +- tests/test_valid_args_schemas.py | 4 +- tests/test_workflows.py | 12 ++--- tests/test_workflows_cellpose_segmentation.py | 45 ++++++++++--------- tests/test_workflows_multiplexing.py | 12 ++--- tests/test_workflows_napari_workflows.py | 2 +- 9 files changed, 49 insertions(+), 41 deletions(-) diff --git a/tests/test_unit_compression.py b/tests/test_unit_compression.py index 6a013c8eb..54c4d156b 100644 --- a/tests/test_unit_compression.py +++ b/tests/test_unit_compression.py @@ -16,7 +16,7 @@ import pytest from PIL import Image -from fractal_tasks_core.compress_tif import compress_tif +from fractal_tasks_core.tasks.compress_tif import compress_tif in_path = "" out_path = "" diff --git a/tests/test_unit_illumination_correction.py b/tests/test_unit_illumination_correction.py index e8d82f8e6..fcf856c58 100644 --- a/tests/test_unit_illumination_correction.py +++ b/tests/test_unit_illumination_correction.py @@ -11,12 +11,14 @@ from pytest import LogCaptureFixture from pytest import MonkeyPatch -from fractal_tasks_core.illumination_correction import correct -from fractal_tasks_core.illumination_correction import illumination_correction from fractal_tasks_core.lib_regions_of_interest import ( convert_ROI_table_to_indices, ) from fractal_tasks_core.lib_zattrs_utils import extract_zyx_pixel_sizes +from fractal_tasks_core.tasks.illumination_correction import correct +from fractal_tasks_core.tasks.illumination_correction import ( + illumination_correction, +) @pytest.mark.parametrize("overwrite", [True]) @@ -82,7 +84,8 @@ def patched_correct(*args, **kwargs): return correct(*args, **kwargs) monkeypatch.setattr( - "fractal_tasks_core.illumination_correction.correct", patched_correct + "fractal_tasks_core.tasks.illumination_correction.correct", + patched_correct, ) # Call illumination correction task, with patched correct() diff --git a/tests/test_unit_napari_workflows_wrapper.py b/tests/test_unit_napari_workflows_wrapper.py index bcd472bc1..db55fe75b 100644 --- a/tests/test_unit_napari_workflows_wrapper.py +++ b/tests/test_unit_napari_workflows_wrapper.py @@ -2,7 +2,7 @@ import pytest -from fractal_tasks_core.napari_workflows_wrapper import ( +from fractal_tasks_core.tasks.napari_workflows_wrapper import ( napari_workflows_wrapper, ) diff --git a/tests/test_unit_task.py b/tests/test_unit_task.py index 646acbd8d..cdf674187 100644 --- a/tests/test_unit_task.py +++ b/tests/test_unit_task.py @@ -4,7 +4,7 @@ from devtools import debug import fractal_tasks_core -from fractal_tasks_core.create_ome_zarr import create_ome_zarr +from fractal_tasks_core.tasks.create_ome_zarr import create_ome_zarr # Load manifest diff --git a/tests/test_valid_args_schemas.py b/tests/test_valid_args_schemas.py index 65a45b61e..160a5f3b7 100644 --- a/tests/test_valid_args_schemas.py +++ b/tests/test_valid_args_schemas.py @@ -38,8 +38,8 @@ def _extract_function(executable: str): if not executable.endswith(".py"): raise ValueError(f"Invalid {executable=}") - module_name = executable[:-3] - module = import_module(f"fractal_tasks_core.{module_name}") + module_name = Path(executable).with_suffix("").name + module = import_module(f"fractal_tasks_core.tasks.{module_name}") task_function = getattr(module, module_name) return task_function diff --git a/tests/test_workflows.py b/tests/test_workflows.py index 2aac038a5..7faebb872 100644 --- a/tests/test_workflows.py +++ b/tests/test_workflows.py @@ -23,13 +23,15 @@ from .utils import check_file_number from .utils import validate_schema -from fractal_tasks_core.copy_ome_zarr import copy_ome_zarr -from fractal_tasks_core.create_ome_zarr import create_ome_zarr -from fractal_tasks_core.illumination_correction import illumination_correction -from fractal_tasks_core.maximum_intensity_projection import ( +from fractal_tasks_core.tasks.copy_ome_zarr import copy_ome_zarr +from fractal_tasks_core.tasks.create_ome_zarr import create_ome_zarr +from fractal_tasks_core.tasks.illumination_correction import ( + illumination_correction, +) +from fractal_tasks_core.tasks.maximum_intensity_projection import ( maximum_intensity_projection, ) # noqa -from fractal_tasks_core.yokogawa_to_ome_zarr import yokogawa_to_ome_zarr +from fractal_tasks_core.tasks.yokogawa_to_ome_zarr import yokogawa_to_ome_zarr allowed_channels = [ diff --git a/tests/test_workflows_cellpose_segmentation.py b/tests/test_workflows_cellpose_segmentation.py index eb54dab7b..6263ae565 100644 --- a/tests/test_workflows_cellpose_segmentation.py +++ b/tests/test_workflows_cellpose_segmentation.py @@ -28,19 +28,21 @@ from devtools import debug from pytest import MonkeyPatch -import fractal_tasks_core +import fractal_tasks_core.tasks from .lib_empty_ROI_table import _add_empty_ROI_table from .utils import check_file_number from .utils import validate_schema -from fractal_tasks_core.cellpose_segmentation import cellpose_segmentation -from fractal_tasks_core.copy_ome_zarr import ( +from fractal_tasks_core.tasks.cellpose_segmentation import ( + cellpose_segmentation, +) +from fractal_tasks_core.tasks.copy_ome_zarr import ( copy_ome_zarr, ) # noqa -from fractal_tasks_core.create_ome_zarr import create_ome_zarr -from fractal_tasks_core.maximum_intensity_projection import ( +from fractal_tasks_core.tasks.create_ome_zarr import create_ome_zarr +from fractal_tasks_core.tasks.maximum_intensity_projection import ( maximum_intensity_projection, ) # noqa -from fractal_tasks_core.yokogawa_to_ome_zarr import yokogawa_to_ome_zarr +from fractal_tasks_core.tasks.yokogawa_to_ome_zarr import yokogawa_to_ome_zarr allowed_channels = [ @@ -172,12 +174,12 @@ def test_failures( ): monkeypatch.setattr( - "fractal_tasks_core.cellpose_segmentation.cellpose.core.use_gpu", + "fractal_tasks_core.tasks.cellpose_segmentation.cellpose.core.use_gpu", patched_cellpose_core_use_gpu, ) monkeypatch.setattr( - "fractal_tasks_core.cellpose_segmentation.segment_ROI", + "fractal_tasks_core.tasks.cellpose_segmentation.segment_ROI", patched_segment_ROI, ) @@ -235,12 +237,12 @@ def test_workflow_with_per_FOV_labeling( ): monkeypatch.setattr( - "fractal_tasks_core.cellpose_segmentation.cellpose.core.use_gpu", + "fractal_tasks_core.tasks.cellpose_segmentation.cellpose.core.use_gpu", patched_cellpose_core_use_gpu, ) monkeypatch.setattr( - "fractal_tasks_core.cellpose_segmentation.segment_ROI", + "fractal_tasks_core.tasks.cellpose_segmentation.segment_ROI", patched_segment_ROI, ) @@ -297,12 +299,12 @@ def test_workflow_with_multi_channel_input( # wavelength_id_c2 monkeypatch.setattr( - "fractal_tasks_core.cellpose_segmentation.cellpose.core.use_gpu", + "fractal_tasks_core.tasks.cellpose_segmentation.cellpose.core.use_gpu", patched_cellpose_core_use_gpu, ) monkeypatch.setattr( - "fractal_tasks_core.cellpose_segmentation.segment_ROI", + "fractal_tasks_core.tasks.cellpose_segmentation.segment_ROI", patched_segment_ROI, ) @@ -354,13 +356,13 @@ def test_workflow_with_per_FOV_labeling_2D( ): monkeypatch.setattr( - "fractal_tasks_core.cellpose_segmentation.cellpose.core.use_gpu", + "fractal_tasks_core.tasks.cellpose_segmentation.cellpose.core.use_gpu", patched_cellpose_core_use_gpu, ) # Do not use cellpose monkeypatch.setattr( - "fractal_tasks_core.cellpose_segmentation.segment_ROI", + "fractal_tasks_core.tasks.cellpose_segmentation.segment_ROI", patched_segment_ROI, ) @@ -407,13 +409,13 @@ def test_workflow_with_per_well_labeling_2D( ): monkeypatch.setattr( - "fractal_tasks_core.cellpose_segmentation.cellpose.core.use_gpu", + "fractal_tasks_core.tasks.cellpose_segmentation.cellpose.core.use_gpu", patched_cellpose_core_use_gpu, ) # Do not use cellpose monkeypatch.setattr( - "fractal_tasks_core.cellpose_segmentation.segment_ROI", + "fractal_tasks_core.tasks.cellpose_segmentation.segment_ROI", patched_segment_ROI, ) @@ -501,12 +503,12 @@ def test_workflow_bounding_box( ): monkeypatch.setattr( - "fractal_tasks_core.cellpose_segmentation.cellpose.core.use_gpu", + "fractal_tasks_core.tasks.cellpose_segmentation.cellpose.core.use_gpu", patched_cellpose_core_use_gpu, ) monkeypatch.setattr( - "fractal_tasks_core.cellpose_segmentation.segment_ROI", + "fractal_tasks_core.tasks.cellpose_segmentation.segment_ROI", patched_segment_ROI, ) NUM_LABELS = 4 @@ -558,12 +560,12 @@ def test_workflow_bounding_box_with_overlap( ): monkeypatch.setattr( - "fractal_tasks_core.cellpose_segmentation.cellpose.core.use_gpu", + "fractal_tasks_core.tasks.cellpose_segmentation.cellpose.core.use_gpu", patched_cellpose_core_use_gpu, ) monkeypatch.setattr( - "fractal_tasks_core.cellpose_segmentation.segment_ROI", + "fractal_tasks_core.tasks.cellpose_segmentation.segment_ROI", patched_segment_ROI_overlapping_organoids, ) @@ -612,7 +614,8 @@ def test_workflow_with_per_FOV_labeling_via_script( python_path = sys.executable task_path = ( - Path(fractal_tasks_core.__file__).parent / "cellpose_segmentation.py" + Path(fractal_tasks_core.tasks.__file__).parent + / "tasks/cellpose_segmentation.py" ) args_path = tmp_path / "args.json" out_path = tmp_path / "out.json" diff --git a/tests/test_workflows_multiplexing.py b/tests/test_workflows_multiplexing.py index 4998c38c9..97256f64d 100644 --- a/tests/test_workflows_multiplexing.py +++ b/tests/test_workflows_multiplexing.py @@ -19,16 +19,16 @@ from .utils import check_file_number from .utils import validate_schema -from fractal_tasks_core.copy_ome_zarr import ( +from fractal_tasks_core.tasks.copy_ome_zarr import ( copy_ome_zarr, -) # noqa -from fractal_tasks_core.create_ome_zarr_multiplex import ( +) +from fractal_tasks_core.tasks.create_ome_zarr_multiplex import ( create_ome_zarr_multiplex, ) -from fractal_tasks_core.maximum_intensity_projection import ( +from fractal_tasks_core.tasks.maximum_intensity_projection import ( maximum_intensity_projection, -) # noqa -from fractal_tasks_core.yokogawa_to_ome_zarr import yokogawa_to_ome_zarr +) +from fractal_tasks_core.tasks.yokogawa_to_ome_zarr import yokogawa_to_ome_zarr single_cycle_allowed_channels_no_label = [ diff --git a/tests/test_workflows_napari_workflows.py b/tests/test_workflows_napari_workflows.py index f37134978..064d41352 100644 --- a/tests/test_workflows_napari_workflows.py +++ b/tests/test_workflows_napari_workflows.py @@ -26,7 +26,7 @@ from .utils import check_file_number from .utils import validate_labels_and_measurements from .utils import validate_schema -from fractal_tasks_core.napari_workflows_wrapper import ( +from fractal_tasks_core.tasks.napari_workflows_wrapper import ( napari_workflows_wrapper, ) From 963acb20f995aaf0f0726e7bedd9ee4eb4ecae60 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 09:37:04 +0200 Subject: [PATCH 05/21] Update imports from `tasks._utils.py` --- fractal_tasks_core/tasks/cellpose_segmentation.py | 2 +- fractal_tasks_core/tasks/copy_ome_zarr.py | 2 +- fractal_tasks_core/tasks/create_ome_zarr.py | 2 +- fractal_tasks_core/tasks/create_ome_zarr_multiplex.py | 2 +- fractal_tasks_core/tasks/illumination_correction.py | 2 +- fractal_tasks_core/tasks/maximum_intensity_projection.py | 2 +- fractal_tasks_core/tasks/napari_workflows_wrapper.py | 2 +- fractal_tasks_core/tasks/yokogawa_to_ome_zarr.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/fractal_tasks_core/tasks/cellpose_segmentation.py b/fractal_tasks_core/tasks/cellpose_segmentation.py index b5af6320d..61bb3efdb 100644 --- a/fractal_tasks_core/tasks/cellpose_segmentation.py +++ b/fractal_tasks_core/tasks/cellpose_segmentation.py @@ -663,7 +663,7 @@ def cellpose_segmentation( if __name__ == "__main__": - from fractal_tasks_core._utils import run_fractal_task + from fractal_tasks_core.tasks._utils import run_fractal_task run_fractal_task( task_function=cellpose_segmentation, diff --git a/fractal_tasks_core/tasks/copy_ome_zarr.py b/fractal_tasks_core/tasks/copy_ome_zarr.py index 630355c05..19b73873d 100644 --- a/fractal_tasks_core/tasks/copy_ome_zarr.py +++ b/fractal_tasks_core/tasks/copy_ome_zarr.py @@ -197,7 +197,7 @@ def copy_ome_zarr( if __name__ == "__main__": - from fractal_tasks_core._utils import run_fractal_task + from fractal_tasks_core.tasks._utils import run_fractal_task run_fractal_task( task_function=copy_ome_zarr, diff --git a/fractal_tasks_core/tasks/create_ome_zarr.py b/fractal_tasks_core/tasks/create_ome_zarr.py index 9ac5d7fd9..9bb69a086 100644 --- a/fractal_tasks_core/tasks/create_ome_zarr.py +++ b/fractal_tasks_core/tasks/create_ome_zarr.py @@ -430,7 +430,7 @@ def create_ome_zarr( if __name__ == "__main__": - from fractal_tasks_core._utils import run_fractal_task + from fractal_tasks_core.tasks._utils import run_fractal_task run_fractal_task( task_function=create_ome_zarr, diff --git a/fractal_tasks_core/tasks/create_ome_zarr_multiplex.py b/fractal_tasks_core/tasks/create_ome_zarr_multiplex.py index dc3e306f0..7e1498405 100644 --- a/fractal_tasks_core/tasks/create_ome_zarr_multiplex.py +++ b/fractal_tasks_core/tasks/create_ome_zarr_multiplex.py @@ -481,7 +481,7 @@ def create_ome_zarr_multiplex( if __name__ == "__main__": - from fractal_tasks_core._utils import run_fractal_task + from fractal_tasks_core.tasks._utils import run_fractal_task run_fractal_task( task_function=create_ome_zarr_multiplex, diff --git a/fractal_tasks_core/tasks/illumination_correction.py b/fractal_tasks_core/tasks/illumination_correction.py index 9a997c024..1b0fce189 100644 --- a/fractal_tasks_core/tasks/illumination_correction.py +++ b/fractal_tasks_core/tasks/illumination_correction.py @@ -271,7 +271,7 @@ def illumination_correction( if __name__ == "__main__": - from fractal_tasks_core._utils import run_fractal_task + from fractal_tasks_core.tasks._utils import run_fractal_task run_fractal_task( task_function=illumination_correction, diff --git a/fractal_tasks_core/tasks/maximum_intensity_projection.py b/fractal_tasks_core/tasks/maximum_intensity_projection.py index 4f47cc5b3..77008e626 100644 --- a/fractal_tasks_core/tasks/maximum_intensity_projection.py +++ b/fractal_tasks_core/tasks/maximum_intensity_projection.py @@ -132,7 +132,7 @@ def maximum_intensity_projection( if __name__ == "__main__": - from fractal_tasks_core._utils import run_fractal_task + from fractal_tasks_core.tasks._utils import run_fractal_task run_fractal_task( task_function=maximum_intensity_projection, diff --git a/fractal_tasks_core/tasks/napari_workflows_wrapper.py b/fractal_tasks_core/tasks/napari_workflows_wrapper.py index aa9dcb088..28be86522 100644 --- a/fractal_tasks_core/tasks/napari_workflows_wrapper.py +++ b/fractal_tasks_core/tasks/napari_workflows_wrapper.py @@ -603,7 +603,7 @@ def napari_workflows_wrapper( if __name__ == "__main__": - from fractal_tasks_core._utils import run_fractal_task + from fractal_tasks_core.tasks._utils import run_fractal_task run_fractal_task( task_function=napari_workflows_wrapper, diff --git a/fractal_tasks_core/tasks/yokogawa_to_ome_zarr.py b/fractal_tasks_core/tasks/yokogawa_to_ome_zarr.py index 564d3fd67..d949e7603 100644 --- a/fractal_tasks_core/tasks/yokogawa_to_ome_zarr.py +++ b/fractal_tasks_core/tasks/yokogawa_to_ome_zarr.py @@ -216,7 +216,7 @@ def yokogawa_to_ome_zarr( if __name__ == "__main__": - from fractal_tasks_core._utils import run_fractal_task + from fractal_tasks_core.tasks._utils import run_fractal_task run_fractal_task( task_function=yokogawa_to_ome_zarr, From 71ccf77a132181af549716977a63cea21863e76c Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 09:37:19 +0200 Subject: [PATCH 06/21] Update test --- tests/test_valid_task_interface.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_valid_task_interface.py b/tests/test_valid_task_interface.py index 64cc27959..2d964a817 100644 --- a/tests/test_valid_task_interface.py +++ b/tests/test_valid_task_interface.py @@ -48,8 +48,7 @@ def test_task_interface(task, tmp_path): args = dict(wrong_arg_1=123, wrong_arg_2=[1, 2, 3]) json.dump(args, fout, indent=4) - executable = task["executable"] - task_path = f"{str(module_dir)}/{executable}" + task_path = (module_dir / task["executable"]).as_posix() cmd = ( f"python {task_path} " f"-j {tmp_file_args} " From 7d361bbad558e86f1752934fb64bcd11d7c82eee Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 09:44:16 +0200 Subject: [PATCH 07/21] update test --- tests/test_workflow_executable.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_workflow_executable.py b/tests/test_workflow_executable.py index 15f78e96f..cc49b4d4c 100644 --- a/tests/test_workflow_executable.py +++ b/tests/test_workflow_executable.py @@ -5,7 +5,7 @@ from devtools import debug -import fractal_tasks_core +import fractal_tasks_core.tasks allowed_channels = [ @@ -59,7 +59,7 @@ def test_workflow_yokogawa_to_ome_zarr(tmp_path: Path, zenodo_images: str): img_path = zenodo_images zarr_path = str(tmp_path / "tmp_out/") metadata = {} - tasks_path = str(Path(fractal_tasks_core.__file__).parent) + tasks_path = str(Path(fractal_tasks_core.tasks.__file__).parent) # Create zarr structure args_create_zarr = dict( From ff9dd3a3d5adbda68e5f9467efcc9f611d2d955f Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 10:40:57 +0200 Subject: [PATCH 08/21] Update manifest --- fractal_tasks_core/__FRACTAL_MANIFEST__.json | 1 + fractal_tasks_core/dev/new_args_schema.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fractal_tasks_core/__FRACTAL_MANIFEST__.json b/fractal_tasks_core/__FRACTAL_MANIFEST__.json index 5da16a84c..330761f86 100644 --- a/fractal_tasks_core/__FRACTAL_MANIFEST__.json +++ b/fractal_tasks_core/__FRACTAL_MANIFEST__.json @@ -181,6 +181,7 @@ "type": "boolean" }, "suffix": { + "default": "mip", "description": "The suffix that is used to transform ``plate.zarr`` into ``plate_suffix.zarr``. Note that `None` is not currently supported.", "title": "Suffix", "type": "string" diff --git a/fractal_tasks_core/dev/new_args_schema.py b/fractal_tasks_core/dev/new_args_schema.py index 0906280a2..9dadd2b89 100644 --- a/fractal_tasks_core/dev/new_args_schema.py +++ b/fractal_tasks_core/dev/new_args_schema.py @@ -12,7 +12,7 @@ University of Zurich. -Script to generate JSON schemas for task arguments afresh, and writes them +Script to generate JSON schemas for task arguments afresh, and write them to the package manifest. """ import json From d9a34eb340433ff8d5c3fa2431e07dc235b3084e Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 10:50:19 +0200 Subject: [PATCH 09/21] Update test --- tests/test_workflows_cellpose_segmentation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_workflows_cellpose_segmentation.py b/tests/test_workflows_cellpose_segmentation.py index 6263ae565..75e9d3425 100644 --- a/tests/test_workflows_cellpose_segmentation.py +++ b/tests/test_workflows_cellpose_segmentation.py @@ -615,7 +615,7 @@ def test_workflow_with_per_FOV_labeling_via_script( python_path = sys.executable task_path = ( Path(fractal_tasks_core.tasks.__file__).parent - / "tasks/cellpose_segmentation.py" + / "cellpose_segmentation.py" ) args_path = tmp_path / "args.json" out_path = tmp_path / "out.json" From d26259f802a7acfd7af7b38c303dfd527bb16573 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 10:55:37 +0200 Subject: [PATCH 10/21] Move several dependencies to `fractal_tasks` extra (ref #390) --- poetry.lock | 145 +++++++++++++++++++++++++------------------------ pyproject.toml | 30 ++++++---- 2 files changed, 92 insertions(+), 83 deletions(-) diff --git a/poetry.lock b/poetry.lock index bd2e973db..d109f1e03 100644 --- a/poetry.lock +++ b/poetry.lock @@ -196,7 +196,7 @@ test = ["boltons", "dask[array]", "joblib", "loompy (>=3.0.5)", "matplotlib", "o name = "anyio" version = "3.6.2" description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false +optional = true python-versions = ">=3.6.2" files = [ {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"}, @@ -238,7 +238,7 @@ files = [ name = "argon2-cffi" version = "21.3.0" description = "The secure Argon2 password hashing algorithm." -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "argon2-cffi-21.3.0.tar.gz", hash = "sha256:d384164d944190a7dd7ef22c6aa3ff197da12962bd04b17f64d4e93d934dba5b"}, @@ -257,7 +257,7 @@ tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pytest"] name = "argon2-cffi-bindings" version = "21.2.0" description = "Low-level CFFI bindings for Argon2" -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"}, @@ -294,7 +294,7 @@ tests = ["pytest"] name = "arrow" version = "1.2.3" description = "Better dates & times for Python" -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "arrow-1.2.3-py3-none-any.whl", hash = "sha256:5a49ab92e3b7b71d96cd6bfcc4df14efefc9dfa96ea19045815914a6ab6b1fe2"}, @@ -378,7 +378,7 @@ Sphinx = ">=2.2,<7.0" name = "autopep8" version = "2.0.1" description = "A tool that automatically formats Python code to conform to the PEP 8 style guide" -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "autopep8-2.0.1-py2.py3-none-any.whl", hash = "sha256:be5bc98c33515b67475420b7b1feafc8d32c1a69862498eda4983b45bffd2687"}, @@ -415,7 +415,7 @@ files = [ name = "beautifulsoup4" version = "4.11.2" description = "Screen-scraping library" -optional = false +optional = true python-versions = ">=3.6.0" files = [ {file = "beautifulsoup4-4.11.2-py3-none-any.whl", hash = "sha256:0e79446b10b3ecb499c1556f7e228a53e64a2bfcebd455f370d8927cb5b59e39"}, @@ -433,7 +433,7 @@ lxml = ["lxml"] name = "bleach" version = "6.0.0" description = "An easy safelist-based HTML-sanitizing tool." -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"}, @@ -526,7 +526,7 @@ heapdict = "*" name = "cellpose" version = "2.2" description = "anatomical segmentation algorithm" -optional = false +optional = true python-versions = "*" files = [ {file = "cellpose-2.2-py3-none-any.whl", hash = "sha256:7a49723ddc3e359e69fc74204af0c8f237651047d4172af59320ffd1d050a45a"}, @@ -815,7 +815,7 @@ test = ["pytest"] name = "contourpy" version = "1.0.7" description = "Python library for calculating contours of 2D quadrilateral grids" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:95c3acddf921944f241b6773b767f1cbce71d03307270e2d769fd584d5d1092d"}, @@ -954,7 +954,7 @@ toml = ["tomli"] name = "cycler" version = "0.11.0" description = "Composable style cycles" -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, @@ -1156,7 +1156,7 @@ files = [ name = "fastjsonschema" version = "2.16.3" description = "Fastest Python implementation of JSON schema" -optional = false +optional = true python-versions = "*" files = [ {file = "fastjsonschema-2.16.3-py3-none-any.whl", hash = "sha256:04fbecc94300436f628517b05741b7ea009506ce8f946d40996567c669318490"}, @@ -1170,7 +1170,7 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc name = "fastremap" version = "1.13.4" description = "Remap, mask, renumber, unique, and in-place transposition of 3D labeled images. Point cloud too." -optional = false +optional = true python-versions = "~=3.6" files = [ {file = "fastremap-1.13.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8a8f8b70d783ad7832b4cc149499a7d2c5168d0ac54e95fd917ff1b7bddee3eb"}, @@ -1232,7 +1232,7 @@ testing = ["covdefaults (>=2.2.2)", "coverage (>=7.0.1)", "pytest (>=7.2)", "pyt name = "fonttools" version = "4.38.0" description = "Tools to manipulate font files" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "fonttools-4.38.0-py3-none-any.whl", hash = "sha256:820466f43c8be8c3009aef8b87e785014133508f0de64ec469e4efb643ae54fb"}, @@ -1257,7 +1257,7 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] name = "fqdn" version = "1.5.1" description = "Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers" -optional = false +optional = true python-versions = ">=2.7, !=3.0, !=3.1, !=3.2, !=3.3, !=3.4, <4" files = [ {file = "fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014"}, @@ -1488,7 +1488,7 @@ files = [ name = "imagecodecs" version = "2023.1.23" description = "Image transformation, compression, and decompression codecs" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "imagecodecs-2023.1.23-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c40c16551c149a4f7d0e50085c1e771eb4919c0dfa9671392ffd0e74658987e0"}, @@ -1558,7 +1558,7 @@ tifffile = ["tifffile"] name = "imageio-ffmpeg" version = "0.4.8" description = "FFMPEG wrapper for Python" -optional = false +optional = true python-versions = ">=3.5" files = [ {file = "imageio-ffmpeg-0.4.8.tar.gz", hash = "sha256:fdaa05ad10fe070b7fa8e5f615cb0d28f3b9b791d00af6d2a11e694158d10aa9"}, @@ -1603,7 +1603,7 @@ testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packag name = "importlib-resources" version = "5.12.0" description = "Read resources from Python packages" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"}, @@ -1632,7 +1632,7 @@ files = [ name = "ipycanvas" version = "0.13.1" description = "Interactive widgets library exposing the browser's Canvas API" -optional = false +optional = true python-versions = "*" files = [ {file = "ipycanvas-0.13.1-py2.py3-none-any.whl", hash = "sha256:53771e27a86de5b153873a4ffd495fddbf530990fb5609f20fb59ab95ce33035"}, @@ -1648,7 +1648,7 @@ pillow = ">=6.0" name = "ipyevents" version = "2.0.1" description = "A custom widget for returning mouse and keyboard events to Python" -optional = false +optional = true python-versions = "*" files = [ {file = "ipyevents-2.0.1-py2.py3-none-any.whl", hash = "sha256:9f255fdab40e7598b1143ace90153c5f4e52be15dc6f1b94f575a043a5970c17"}, @@ -1748,7 +1748,7 @@ files = [ name = "ipywidgets" version = "8.0.4" description = "Jupyter interactive widgets" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "ipywidgets-8.0.4-py3-none-any.whl", hash = "sha256:ebb195e743b16c3947fe8827190fb87b4d00979c0fbf685afe4d2c4927059fa1"}, @@ -1769,7 +1769,7 @@ test = ["jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] name = "isoduration" version = "20.11.0" description = "Operations with ISO 8601 durations" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042"}, @@ -1830,7 +1830,7 @@ files = [ name = "jsonpointer" version = "2.3" description = "Identify specific nodes in a JSON document (RFC 6901)" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ {file = "jsonpointer-2.3-py2.py3-none-any.whl", hash = "sha256:51801e558539b4e9cd268638c078c6c5746c9ac96bc38152d443400e4f3793e9"}, @@ -1868,7 +1868,7 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "jupyter" version = "1.0.0" description = "Jupyter metapackage. Install all the Jupyter components in one go." -optional = false +optional = true python-versions = "*" files = [ {file = "jupyter-1.0.0-py2.py3-none-any.whl", hash = "sha256:5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78"}, @@ -1911,7 +1911,7 @@ test = ["codecov", "coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-co name = "jupyter-console" version = "6.6.2" description = "Jupyter terminal console" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "jupyter_console-6.6.2-py3-none-any.whl", hash = "sha256:0ba2da017be36bfae489f233f031f251da5b88b0ceafabea240b465ee474944a"}, @@ -1955,7 +1955,7 @@ test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] name = "jupyter-events" version = "0.6.3" description = "Jupyter Event System library" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "jupyter_events-0.6.3-py3-none-any.whl", hash = "sha256:57a2749f87ba387cd1bfd9b22a0875b889237dbf2edc2121ebb22bde47036c17"}, @@ -1979,7 +1979,7 @@ test = ["click", "coverage", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>= name = "jupyter-server" version = "2.3.0" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "jupyter_server-2.3.0-py3-none-any.whl", hash = "sha256:b15078954120886d580e19d1746e2b62a3dc7bd082cb4716115c25fcd7061b00"}, @@ -2014,7 +2014,7 @@ test = ["ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", " name = "jupyter-server-terminals" version = "0.4.4" description = "A Jupyter Server Extension Providing Terminals." -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "jupyter_server_terminals-0.4.4-py3-none-any.whl", hash = "sha256:75779164661cec02a8758a5311e18bb8eb70c4e86c6b699403100f1585a12a36"}, @@ -2033,7 +2033,7 @@ test = ["coverage", "jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-cov", name = "jupyterlab-pygments" version = "0.2.2" description = "Pygments theme using JupyterLab CSS variables" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "jupyterlab_pygments-0.2.2-py2.py3-none-any.whl", hash = "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f"}, @@ -2044,7 +2044,7 @@ files = [ name = "jupyterlab-widgets" version = "3.0.5" description = "Jupyter interactive widgets for JupyterLab" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "jupyterlab_widgets-3.0.5-py3-none-any.whl", hash = "sha256:a04a42e50231b355b7087e16a818f541e53589f7647144ea0344c4bf16f300e5"}, @@ -2055,7 +2055,7 @@ files = [ name = "jupytext" version = "1.14.5" description = "Jupyter notebooks as Markdown documents, Julia, Python or R scripts" -optional = false +optional = true python-versions = "~=3.6" files = [ {file = "jupytext-1.14.5-py3-none-any.whl", hash = "sha256:a5dbe60d0ea158bbf82c2bce74aba8d0c220ad7edcda09e017c5eba229b34dc8"}, @@ -2180,7 +2180,7 @@ files = [ name = "llvmlite" version = "0.39.1" description = "lightweight wrapper around basic LLVM functionality" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "llvmlite-0.39.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6717c7a6e93c9d2c3d07c07113ec80ae24af45cde536b34363d4bcd9188091d9"}, @@ -2228,7 +2228,7 @@ files = [ name = "loguru" version = "0.6.0" description = "Python logging made (stupidly) simple" -optional = false +optional = true python-versions = ">=3.5" files = [ {file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"}, @@ -2453,7 +2453,7 @@ files = [ name = "matplotlib" version = "3.7.0" description = "Python plotting package" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "matplotlib-3.7.0-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:3da8b9618188346239e51f1ea6c0f8f05c6e218cfcc30b399dd7dd7f52e8bceb"}, @@ -2572,7 +2572,7 @@ psutil = "*" name = "mistune" version = "2.0.5" description = "A sane Markdown parser with useful plugins and renderers" -optional = false +optional = true python-versions = "*" files = [ {file = "mistune-2.0.5-py2.py3-none-any.whl", hash = "sha256:bad7f5d431886fcbaf5f758118ecff70d31f75231b34024a1341120340a65ce8"}, @@ -2763,7 +2763,7 @@ testing = ["babel (>=2.9.0)", "fsspec", "hypothesis (>=6.8.0)", "lxml", "matplot name = "napari-assistant" version = "0.4.4" description = "A pocket calculator like interface to image processing in napari" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "napari-assistant-0.4.4.tar.gz", hash = "sha256:7f3963283f9172cfeb7ab29a23e9efe46d465dea134a4134c511f230a80b501a"}, @@ -2838,7 +2838,7 @@ test = ["pytest", "pytest-cov"] name = "napari-segment-blobs-and-things-with-membranes" version = "0.3.4" description = "A plugin based on scikit-image for segmenting nuclei and cells based on fluorescent microscopy images with high intensity in nuclei and/or membranes" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "napari-segment-blobs-and-things-with-membranes-0.3.4.tar.gz", hash = "sha256:849d6ac0a6a24d506b522ccc5b94404f7645c6035bb01fb37c3a4c5aa42b7e45"}, @@ -2859,7 +2859,7 @@ stackview = ">=0.3.2" name = "napari-skimage-regionprops" version = "0.8.1" description = "A regionprops table widget plugin for napari" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "napari-skimage-regionprops-0.8.1.tar.gz", hash = "sha256:9f9910f36345d849f6e16204453d01d9f6c5e3a5d716b4a8cb61907248de5db6"}, @@ -2900,7 +2900,7 @@ testing = ["napari (>=0.4)", "pyqt5", "pytest", "pytest-cov"] name = "napari-time-slicer" version = "0.4.9" description = "A meta plugin for processing timelapse data in napari timepoint by timepoint" -optional = false +optional = true python-versions = ">=3.8" files = [ {file = "napari-time-slicer-0.4.9.tar.gz", hash = "sha256:329f7b04952d56aeb9c446fc1d034850d417367e3eaa0d1dd74fa596b5e73fd7"}, @@ -2918,7 +2918,7 @@ toolz = "*" name = "napari-tools-menu" version = "0.1.19" description = "Attaches a customizable Tools menu to napari" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "napari-tools-menu-0.1.19.tar.gz", hash = "sha256:6b58ac45d7fe84bc5975e7a53142340d5d62beff9ade0f2f58d7a3a4a0a8e8f8"}, @@ -2934,7 +2934,7 @@ numpy = "*" name = "napari-workflows" version = "0.2.8" description = "Data structures for managing image processing workflows in napari" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "napari-workflows-0.2.8.tar.gz", hash = "sha256:048558d60e8f82ec7a6ab759e8fb03388d42f44f8385581a4303f143b741c184"}, @@ -2966,7 +2966,7 @@ icu = ["PyICU (>=1.0.0)"] name = "nbclassic" version = "0.5.2" description = "Jupyter Notebook as a Jupyter Server extension." -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "nbclassic-0.5.2-py3-none-any.whl", hash = "sha256:6403a996562dadefa7fee9c49e17b663b5fd508241de5df655b90011cf3342d9"}, @@ -3001,7 +3001,7 @@ test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-jupyter", "pytest-p name = "nbclient" version = "0.7.2" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." -optional = false +optional = true python-versions = ">=3.7.0" files = [ {file = "nbclient-0.7.2-py3-none-any.whl", hash = "sha256:d97ac6257de2794f5397609df754fcbca1a603e94e924eb9b99787c031ae2e7c"}, @@ -3023,7 +3023,7 @@ test = ["ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>= name = "nbconvert" version = "7.2.9" description = "Converting Jupyter Notebooks" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "nbconvert-7.2.9-py3-none-any.whl", hash = "sha256:495638c5e06005f4a5ce828d8a81d28e34f95c20f4384d5d7a22254b443836e7"}, @@ -3061,7 +3061,7 @@ webpdf = ["pyppeteer (>=1,<1.1)"] name = "nbformat" version = "5.7.3" description = "The Jupyter Notebook format" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "nbformat-5.7.3-py3-none-any.whl", hash = "sha256:22a98a6516ca216002b0a34591af5bcb8072ca6c63910baffc901cfa07fefbf0"}, @@ -3125,7 +3125,7 @@ setuptools = "*" name = "notebook" version = "6.5.2" description = "A web-based notebook environment for interactive computing" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "notebook-6.5.2-py3-none-any.whl", hash = "sha256:e04f9018ceb86e4fa841e92ea8fb214f8d23c1cedfde530cc96f92446924f0e4"}, @@ -3159,7 +3159,7 @@ test = ["coverage", "nbval", "pytest", "pytest-cov", "requests", "requests-unixs name = "notebook-shim" version = "0.2.2" description = "A shim layer for notebook traits and config" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "notebook_shim-0.2.2-py3-none-any.whl", hash = "sha256:9c6c30f74c4fbea6fce55c1be58e7fd0409b1c681b075dcedceb005db5026949"}, @@ -3203,7 +3203,7 @@ testing = ["jsonschema", "magicgui", "napari-plugin-engine", "napari-svg", "nump name = "numba" version = "0.56.4" description = "compiling Python code using LLVM" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "numba-0.56.4-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:9f62672145f8669ec08762895fe85f4cf0ead08ce3164667f2b94b2f62ab23c3"}, @@ -3353,7 +3353,7 @@ zarr = ">=2.8.1" name = "opencv-python-headless" version = "4.7.0.72" description = "Wrapper package for OpenCV python bindings." -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "opencv-python-headless-4.7.0.72.tar.gz", hash = "sha256:eea59caa92b28b197f9d2a2dd8275ca3869718b2a857c8e53203de6ef3f9f4db"}, @@ -3439,7 +3439,7 @@ test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] name = "pandocfilters" version = "1.5.0" description = "Utilities for writing pandoc filters in python" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ {file = "pandocfilters-1.5.0-py2.py3-none-any.whl", hash = "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f"}, @@ -3680,7 +3680,7 @@ virtualenv = ">=20.10.0" name = "prometheus-client" version = "0.16.0" description = "Python client for the Prometheus monitoring system." -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "prometheus_client-0.16.0-py3-none-any.whl", hash = "sha256:0836af6eb2c8f4fed712b2f279f6c0a8bbab29f9f4aa15276b91c7cb0d1616ab"}, @@ -3806,7 +3806,7 @@ tests = ["pytest"] name = "pycodestyle" version = "2.10.0" description = "Python style guide checker" -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"}, @@ -3906,7 +3906,7 @@ files = [ name = "pyparsing" version = "3.0.9" description = "pyparsing module - Classes and methods to define and execute parsing grammars" -optional = false +optional = true python-versions = ">=3.6.8" files = [ {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, @@ -3920,7 +3920,7 @@ diagrams = ["jinja2", "railroad-diagrams"] name = "pyperclip" version = "1.8.2" description = "A cross-platform clipboard module for Python. (Only handles plain text for now.)" -optional = false +optional = true python-versions = "*" files = [ {file = "pyperclip-1.8.2.tar.gz", hash = "sha256:105254a8b04934f0bc84e9c24eb360a591aaf6535c9def5f29d92af107a9bf57"}, @@ -4049,7 +4049,7 @@ six = ">=1.5" name = "python-json-logger" version = "2.0.7" description = "A python library adding a json log formatter" -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "python-json-logger-2.0.7.tar.gz", hash = "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c"}, @@ -4181,7 +4181,7 @@ files = [ name = "pywinpty" version = "2.0.10" description = "Pseudo terminal support for Windows from Python." -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "pywinpty-2.0.10-cp310-none-win_amd64.whl", hash = "sha256:4c7d06ad10f6e92bc850a467f26d98f4f30e73d2fe5926536308c6ae0566bc16"}, @@ -4397,7 +4397,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "rfc3339-validator" version = "0.1.4" description = "A pure python RFC3339 validator" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ {file = "rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa"}, @@ -4411,7 +4411,7 @@ six = "*" name = "rfc3986-validator" version = "0.1.1" description = "Pure python rfc3986 validator" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ {file = "rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9"}, @@ -4599,7 +4599,7 @@ test = ["asv", "gmpy2", "mpmath", "pytest", "pytest-cov", "pytest-xdist", "sciki name = "send2trash" version = "1.8.0" description = "Send file to trash natively under Mac OS X, Windows and Linux." -optional = false +optional = true python-versions = "*" files = [ {file = "Send2Trash-1.8.0-py3-none-any.whl", hash = "sha256:f20eaadfdb517eaca5ce077640cb261c7d2698385a6a0f072a4a5447fd49fa08"}, @@ -4642,7 +4642,7 @@ files = [ name = "sniffio" version = "1.3.0" description = "Sniff out which async library your code is running under" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, @@ -4664,7 +4664,7 @@ files = [ name = "soupsieve" version = "2.4" description = "A modern CSS selector implementation for Beautiful Soup." -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "soupsieve-2.4-py3-none-any.whl", hash = "sha256:49e5368c2cda80ee7e84da9dbe3e110b70a4575f196efb74e51b94549d921955"}, @@ -4888,7 +4888,7 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] name = "stackview" version = "0.5.2" description = "Interactive image stack viewing in jupyter notebooks" -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "stackview-0.5.2-py3-none-any.whl", hash = "sha256:ee13d4a342aa25f1e982d8c00bda350fee97548eddc402818fdcae24c8469c44"}, @@ -4938,7 +4938,7 @@ test = ["pint", "pytest", "pytest-cov", "pytest-qt", "tox", "tox-conda"] name = "terminado" version = "0.17.1" description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "terminado-0.17.1-py3-none-any.whl", hash = "sha256:8650d44334eba354dd591129ca3124a6ba42c3d5b70df5051b6921d506fdaeae"}, @@ -4975,7 +4975,7 @@ all = ["defusedxml", "fsspec", "imagecodecs (>=2023.1.23)", "lxml", "matplotlib" name = "tinycss2" version = "1.2.1" description = "A tiny CSS parser" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"}, @@ -5026,7 +5026,7 @@ files = [ name = "torch" version = "1.12.1" description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" -optional = false +optional = true python-versions = ">=3.7.0" files = [ {file = "torch-1.12.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:9c038662db894a23e49e385df13d47b2a777ffd56d9bcd5b832593fab0a7e286"}, @@ -5144,7 +5144,7 @@ files = [ name = "uri-template" version = "1.2.0" description = "RFC 6570 URI Template Processor" -optional = false +optional = true python-versions = ">=3.6" files = [ {file = "uri_template-1.2.0-py3-none-any.whl", hash = "sha256:f1699c77b73b925cf4937eae31ab282a86dc885c333f2e942513f08f691fc7db"}, @@ -5251,7 +5251,7 @@ files = [ name = "webcolors" version = "1.12" description = "A library for working with color names and color values formats defined by HTML and CSS." -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "webcolors-1.12-py3-none-any.whl", hash = "sha256:d98743d81d498a2d3eaf165196e65481f0d2ea85281463d856b1e51b09f62dce"}, @@ -5262,7 +5262,7 @@ files = [ name = "webencodings" version = "0.5.1" description = "Character encoding aliases for legacy web content" -optional = false +optional = true python-versions = "*" files = [ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, @@ -5273,7 +5273,7 @@ files = [ name = "websocket-client" version = "1.5.1" description = "WebSocket client for Python with low level API options" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "websocket-client-1.5.1.tar.gz", hash = "sha256:3f09e6d8230892547132177f575a4e3e73cfdf06526e20cc02aa1c3b47184d40"}, @@ -5299,7 +5299,7 @@ files = [ name = "widgetsnbextension" version = "4.0.5" description = "Jupyter interactive widgets for Jupyter Notebook" -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "widgetsnbextension-4.0.5-py3-none-any.whl", hash = "sha256:eaaaf434fb9b08bd197b2a14ffe45ddb5ac3897593d43c69287091e5f3147bf7"}, @@ -5310,7 +5310,7 @@ files = [ name = "win32-setctime" version = "1.1.0" description = "A small Python utility to set file creation time on Windows" -optional = false +optional = true python-versions = ">=3.5" files = [ {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, @@ -5541,7 +5541,10 @@ files = [ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +[extras] +fractal-tasks = ["Pillow", "cellpose", "imageio-ffmpeg", "llvmlite", "napari-segment-blobs-and-things-with-membranes", "napari-skimage-regionprops", "napari-tools-menu", "napari-workflows", "scikit-image", "torch"] + [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "9dfa9c162847daa1e436ce2d4fd27bed0a57b8ba98cd713f97e6a2d5b9fbd6d8" +content-hash = "324d58f6c3be1fb4c7170db86215fc356edbd9b3d60ff266cd6ecf1fcd737182" diff --git a/pyproject.toml b/pyproject.toml index c34ccd035..d2fd150c1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,27 +15,33 @@ homepage = "https://github.com/fractal-analytics-platform/fractal-tasks-core" documentation = "https://fractal-tasks-core.readthedocs.io" [tool.poetry.dependencies] + +# Required dependencies python = "^3.9" dask = "~2023.1.0" zarr = "~2.13.6" numpy = "~1.23.5" -scikit-image = ">=0.19" -cellpose = "~2.2" pandas = "^1.2.0" defusedxml = "^0.7.1" -napari-workflows = "^0.2.8" -napari-skimage-regionprops = "^0.8.1" -napari-tools-menu = "^0.1.19" -anndata = "^0.8.0" -llvmlite = "^0.39.1" -imageio-ffmpeg = "^0.4.7" lxml = "^4.9.1" -napari-segment-blobs-and-things-with-membranes = "^0.3.3" -Pillow = "^9.1.1" -pydantic = "^1.10.2" -torch = "1.12.1" +pydantic = "~1.10.2" docstring-parser = "^0.15" +anndata = "^0.8.0" + +# Optional dependencies (used in extras) +Pillow = { version = "^9.1.1", optional = true } +imageio-ffmpeg = { version = "^0.4.7", optional = true } +scikit-image = { version = ">=0.19", optional = true } +llvmlite = { version = "^0.39.1", optional = true } +napari-segment-blobs-and-things-with-membranes = { version = "^0.3.3", optional = true } +napari-workflows = { version = "^0.2.8", optional = true } +napari-skimage-regionprops = { version = "^0.8.1", optional = true } +napari-tools-menu = { version = "^0.1.19", optional = true } +cellpose = { version = "~2.2", optional = true } +torch = { version = "1.12.1", optional = true } +[tool.poetry.extras] +fractal_tasks = ["Pillow", "imageio-ffmpeg", "scikit-image", "llvmlite", "napari-segment-blobs-and-things-with-membranes", "napari-workflows", "napari-skimage-regionprops", "napari-tools-menu", "cellpose", "torch"] [tool.poetry.group.dev] optional = true From 3142f6ee3221972a337bad72653949e342634fe9 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 12:55:58 +0200 Subject: [PATCH 11/21] Remove dev/lib_metadata_checks.py (close #380) 1. Move main functionality into lib_ROI_overlaps.py 2. Update test_unit_parse_yokogawa_metadata.py 3. Move the plotting part into examples/tools/show_FOV_ROIs --- .../MeasurementData_2x2_well.mlf | 123 ++++++++++++++++++ .../MeasurementDetail_2x2_well.mrf | 7 + examples/tools/show_FOV_ROIs/README.md | 1 + examples/tools/show_FOV_ROIs/fig_tol_0.pdf | Bin 0 -> 11258 bytes .../tools/show_FOV_ROIs/fig_tol_1e-10.pdf | Bin 0 -> 11142 bytes examples/tools/show_FOV_ROIs/show_FOV_ROIs.py | 83 ++++++++++++ fractal_tasks_core/dev/lib_metadata_checks.py | 107 --------------- fractal_tasks_core/lib_ROI_overlaps.py | 91 +++++++++++++ tests/test_unit_parse_yokogawa_metadata.py | 2 +- 9 files changed, 306 insertions(+), 108 deletions(-) create mode 100755 examples/tools/show_FOV_ROIs/MeasurementData_2x2_well.mlf create mode 100755 examples/tools/show_FOV_ROIs/MeasurementDetail_2x2_well.mrf create mode 100644 examples/tools/show_FOV_ROIs/README.md create mode 100644 examples/tools/show_FOV_ROIs/fig_tol_0.pdf create mode 100644 examples/tools/show_FOV_ROIs/fig_tol_1e-10.pdf create mode 100644 examples/tools/show_FOV_ROIs/show_FOV_ROIs.py delete mode 100644 fractal_tasks_core/dev/lib_metadata_checks.py diff --git a/examples/tools/show_FOV_ROIs/MeasurementData_2x2_well.mlf b/examples/tools/show_FOV_ROIs/MeasurementData_2x2_well.mlf new file mode 100755 index 000000000..b1af1b8f7 --- /dev/null +++ b/examples/tools/show_FOV_ROIs/MeasurementData_2x2_well.mlf @@ -0,0 +1,123 @@ + + +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z01C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z01C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z02C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z02C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z03C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z03C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z04C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z04C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z05C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z05C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z06C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z06C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z07C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z07C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z08C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z08C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z09C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z09C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z10C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A01Z10C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A02Z01C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A02Z02C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A02Z03C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A02Z04C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A02Z05C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A02Z06C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A02Z07C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A02Z08C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A02Z09C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F001L01A02Z10C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z01C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z01C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z02C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z02C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z03C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z03C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z04C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z04C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z05C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z05C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z06C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z06C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z07C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z07C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z08C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z08C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z09C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z09C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z10C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A01Z10C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A02Z01C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A02Z02C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A02Z03C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A02Z04C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A02Z05C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A02Z06C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A02Z07C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A02Z08C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A02Z09C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F002L01A02Z10C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z01C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z01C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z02C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z02C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z03C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z03C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z04C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z04C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z05C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z05C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z06C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z06C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z07C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z07C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z08C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z08C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z09C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z09C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z10C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A01Z10C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A02Z01C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A02Z02C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A02Z03C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A02Z04C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A02Z05C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A02Z06C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A02Z07C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A02Z08C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A02Z09C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F009L01A02Z10C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z01C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z01C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z02C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z02C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z03C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z03C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z04C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z04C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z05C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z05C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z06C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z06C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z07C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z07C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z08C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z08C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z09C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z09C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z10C01.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A01Z10C02.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A02Z01C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A02Z02C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A02Z03C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A02Z04C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A02Z05C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A02Z06C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A02Z07C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A02Z08C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A02Z09C03.tif +20200812-CardiomyocyteDifferentiation14-Cycle1_B03_T0002F010L01A02Z10C03.tif + diff --git a/examples/tools/show_FOV_ROIs/MeasurementDetail_2x2_well.mrf b/examples/tools/show_FOV_ROIs/MeasurementDetail_2x2_well.mrf new file mode 100755 index 000000000..2f93963c6 --- /dev/null +++ b/examples/tools/show_FOV_ROIs/MeasurementDetail_2x2_well.mrf @@ -0,0 +1,7 @@ + + + + + + + diff --git a/examples/tools/show_FOV_ROIs/README.md b/examples/tools/show_FOV_ROIs/README.md new file mode 100644 index 000000000..e26f7da75 --- /dev/null +++ b/examples/tools/show_FOV_ROIs/README.md @@ -0,0 +1 @@ +NOTE: running this script requires `matplotlib` diff --git a/examples/tools/show_FOV_ROIs/fig_tol_0.pdf b/examples/tools/show_FOV_ROIs/fig_tol_0.pdf new file mode 100644 index 0000000000000000000000000000000000000000..21e7c00ff9bf3a7e5210fec050366d4809bf50f9 GIT binary patch literal 11258 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 ToxwbsXcX+O%gAUMX(Rpz6HWiq literal 0 HcmV?d00001 diff --git a/examples/tools/show_FOV_ROIs/fig_tol_1e-10.pdf b/examples/tools/show_FOV_ROIs/fig_tol_1e-10.pdf new file mode 100644 index 0000000000000000000000000000000000000000..02a45f0fd3a32e3fbf6e976d0859eb563a0cba7b GIT binary patch literal 11142 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 E0D%v|ZU6uP literal 0 HcmV?d00001 diff --git a/examples/tools/show_FOV_ROIs/show_FOV_ROIs.py b/examples/tools/show_FOV_ROIs/show_FOV_ROIs.py new file mode 100644 index 000000000..f6fe7360e --- /dev/null +++ b/examples/tools/show_FOV_ROIs/show_FOV_ROIs.py @@ -0,0 +1,83 @@ +""" +An example of visualizing FOV ROIs and their overlaps. +""" +import matplotlib.pyplot as plt + +from fractal_tasks_core.lib_metadata_parsing import parse_yokogawa_metadata +from fractal_tasks_core.lib_ROI_overlaps import run_overlap_check + + +def _plot_rectangle(min_x, min_y, max_x, max_y, overlapping): + x = [min_x, max_x, max_x, min_x, min_x] + y = [min_y, min_y, max_y, max_y, min_y] + if overlapping: + plt.plot(x, y, ",-", lw=2.5, zorder=2) + else: + plt.plot(x, y, ",-", lw=0.3, c="k", zorder=1) + + +def _plotting_function( + xmin, xmax, ymin, ymax, list_overlapping_FOVs, selected_well +): + plt.figure() + num_lines = len(xmin) + for line in range(num_lines): + min_x, max_x = [a[line] for a in [xmin, xmax]] + min_y, max_y = [a[line] for a in [ymin, ymax]] + + _plot_rectangle( + min_x, min_y, max_x, max_y, line in list_overlapping_FOVs + ) + plt.text( + 0.5 * (min_x + max_x), + 0.5 * (min_y + max_y), + f"{line + 1}", + ha="center", + va="center", + fontsize=14, + ) + + plt.gca().set_aspect(1) + plt.xlabel("x (um)", fontsize=12) + plt.ylabel("y (um)", fontsize=12) + plt.title(f"Well {selected_well}") + + plt.figure() + for line in range(num_lines): + min_x, max_x = [a[line] for a in [xmin, xmax]] + min_y, max_y = [a[line] for a in [ymin, ymax]] + + _plot_rectangle( + min_x, min_y, max_x, max_y, line in list_overlapping_FOVs + ) + plt.text( + 0.5 * (min_x + max_x), + 0.5 * (min_y + max_y), + f"{line + 1}", + ha="center", + va="center", + fontsize=14, + ) + + plt.gca().set_aspect(1) + plt.xlabel("x (um)", fontsize=12) + plt.ylabel("y (um)", fontsize=12) + plt.title(f"Well {selected_well}") + + +if __name__ == "__main__": + mlf_path = "MeasurementData_2x2_well.mlf" + mrf_path = "MeasurementDetail_2x2_well.mrf" + site_metadata, total_files = parse_yokogawa_metadata(mrf_path, mlf_path) + + plt.close() + run_overlap_check( + site_metadata, tol=0, plotting_function=_plotting_function + ) + plt.savefig("fig_tol_0.pdf") + + plt.close() + run_overlap_check( + site_metadata, tol=1e-10, plotting_function=_plotting_function + ) + plt.savefig("fig_tol_1e-10.pdf") diff --git a/fractal_tasks_core/dev/lib_metadata_checks.py b/fractal_tasks_core/dev/lib_metadata_checks.py deleted file mode 100644 index 9977b7ec7..000000000 --- a/fractal_tasks_core/dev/lib_metadata_checks.py +++ /dev/null @@ -1,107 +0,0 @@ -""" -Copyright 2022 (C) - Friedrich Miescher Institute for Biomedical Research and - University of Zurich - - Original authors: - Joel Lüthi - - This file is part of Fractal and was originally developed by eXact lab - S.r.l. under contract with Liberali Lab from the Friedrich - Miescher Institute for Biomedical Research and Pelkmans Lab from the - University of Zurich. - -Helper functions to inspect a metadata dataframe from Yokogawa files -""" -import matplotlib.pyplot as plt -import pandas as pd - -from fractal_tasks_core.lib_ROI_overlaps import is_overlapping_2D - - -def _plot_rectangle(min_x, min_y, max_x, max_y, overlapping): - x = [min_x, max_x, max_x, min_x, min_x] - y = [min_y, min_y, max_y, max_y, min_y] - if overlapping: - plt.plot(x, y, ",-", lw=2.5, zorder=2) - else: - plt.plot(x, y, ",-", lw=0.3, c="k", zorder=1) - - -def check_well_for_FOV_overlap( - site_metadata: pd.DataFrame, - selected_well: str, - always_plot: bool = False, - tol: float = 0, -): - df = site_metadata.loc[selected_well].copy() - df["xmin"] = df["x_micrometer"] - df["ymin"] = df["y_micrometer"] - df["xmax"] = df["x_micrometer"] + df["pixel_size_x"] * df["x_pixel"] - df["ymax"] = df["y_micrometer"] + df["pixel_size_y"] * df["y_pixel"] - - xmin = list(df.loc[:, "xmin"]) - ymin = list(df.loc[:, "ymin"]) - xmax = list(df.loc[:, "xmax"]) - ymax = list(df.loc[:, "ymax"]) - num_lines = len(xmin) - - list_overlapping_FOVs = [] - for line_1 in range(num_lines): - min_x_1, max_x_1 = [a[line_1] for a in [xmin, xmax]] - min_y_1, max_y_1 = [a[line_1] for a in [ymin, ymax]] - for line_2 in range(line_1): - min_x_2, max_x_2 = [a[line_2] for a in [xmin, xmax]] - min_y_2, max_y_2 = [a[line_2] for a in [ymin, ymax]] - overlap = is_overlapping_2D( - (min_x_1, min_y_1, max_x_1, max_y_1), - (min_x_2, min_y_2, max_x_2, max_y_2), - tol=tol, - ) - if overlap: - list_overlapping_FOVs.append(line_1) - list_overlapping_FOVs.append(line_2) - - if always_plot or (len(list_overlapping_FOVs) > 0): - plt.figure() - for line in range(num_lines): - min_x, max_x = [a[line] for a in [xmin, xmax]] - min_y, max_y = [a[line] for a in [ymin, ymax]] - - _plot_rectangle( - min_x, min_y, max_x, max_y, line in list_overlapping_FOVs - ) - plt.text( - 0.5 * (min_x + max_x), - 0.5 * (min_y + max_y), - f"{line + 1}", - ha="center", - va="center", - fontsize=14, - ) - - plt.gca().set_aspect(1) - plt.xlabel("x (um)", fontsize=12) - plt.ylabel("y (um)", fontsize=12) - plt.title(f"Well {selected_well}") - - # Increase values by one to switch from index to the label plotted - return {selected_well: [x + 1 for x in list_overlapping_FOVs]} - - -def run_overlap_check(site_metadata: pd.DataFrame, tol: float = 0): - """ - Runs an overlap check over all wells, plots overlaps & returns - """ - - wells = site_metadata.index.unique(level="well_id") - overlapping_FOVs = [] - for selected_well in wells: - overlap_curr_well = check_well_for_FOV_overlap( - site_metadata, selected_well=selected_well, tol=tol - ) - if overlap_curr_well: - print(selected_well) - overlapping_FOVs.append(overlap_curr_well) - - return overlapping_FOVs diff --git a/fractal_tasks_core/lib_ROI_overlaps.py b/fractal_tasks_core/lib_ROI_overlaps.py index 92c312c0c..4b146c52f 100644 --- a/fractal_tasks_core/lib_ROI_overlaps.py +++ b/fractal_tasks_core/lib_ROI_overlaps.py @@ -5,6 +5,7 @@ Original authors: Tommaso Comparin + Joel Lüthi This file is part of Fractal and was originally developed by eXact lab S.r.l. under contract with Liberali Lab from the Friedrich @@ -14,6 +15,7 @@ Functions to identify and remove overlaps between regions of interest """ import logging +from typing import Callable from typing import Optional from typing import Sequence @@ -382,3 +384,92 @@ def find_overlaps_in_ROI_indices( if _is_overlapping_3D_int(box_1, box_2): return (ind_1, ind_2) return None + + +def check_well_for_FOV_overlap( + site_metadata: pd.DataFrame, + selected_well: str, + plotting_function: Callable, + tol: float = 0, +): + """ + This function is currently only used in tests and examples. + + The ``plotting_function`` parameter is exposed so that other tools (see + examples in this repository) may use it to show the FOV ROIs. + """ + + df = site_metadata.loc[selected_well].copy() + df["xmin"] = df["x_micrometer"] + df["ymin"] = df["y_micrometer"] + df["xmax"] = df["x_micrometer"] + df["pixel_size_x"] * df["x_pixel"] + df["ymax"] = df["y_micrometer"] + df["pixel_size_y"] * df["y_pixel"] + + xmin = list(df.loc[:, "xmin"]) + ymin = list(df.loc[:, "ymin"]) + xmax = list(df.loc[:, "xmax"]) + ymax = list(df.loc[:, "ymax"]) + num_lines = len(xmin) + + list_overlapping_FOVs = [] + for line_1 in range(num_lines): + min_x_1, max_x_1 = [a[line_1] for a in [xmin, xmax]] + min_y_1, max_y_1 = [a[line_1] for a in [ymin, ymax]] + for line_2 in range(line_1): + min_x_2, max_x_2 = [a[line_2] for a in [xmin, xmax]] + min_y_2, max_y_2 = [a[line_2] for a in [ymin, ymax]] + overlap = is_overlapping_2D( + (min_x_1, min_y_1, max_x_1, max_y_1), + (min_x_2, min_y_2, max_x_2, max_y_2), + tol=tol, + ) + if overlap: + list_overlapping_FOVs.append(line_1) + list_overlapping_FOVs.append(line_2) + + # Call plotting_function + plotting_function( + xmin, xmax, ymin, ymax, list_overlapping_FOVs, selected_well + ) + + if len(list_overlapping_FOVs) > 0: + # Increase values by one to switch from index to the label plotted + return {selected_well: [x + 1 for x in list_overlapping_FOVs]} + + +def run_overlap_check( + site_metadata: pd.DataFrame, + tol: float = 0, + plotting_function: Optional[Callable] = None, +): + """ + Run an overlap check over all wells and optionally plots overlaps + + This function is currently only used in tests and examples. + + The ``plotting_function`` parameter is exposed so that other tools (see + examples in this repository) may use it to show the FOV ROIs. Its arguments + are: ``[xmin, xmax, ymin, ymax, list_overlapping_FOVs, selected_well]``. + """ + + if plotting_function is None: + + def plotting_function( + xmin, xmax, ymin, ymax, list_overlapping_FOVs, selected_well + ): + pass + + wells = site_metadata.index.unique(level="well_id") + overlapping_FOVs = [] + for selected_well in wells: + overlap_curr_well = check_well_for_FOV_overlap( + site_metadata, + selected_well=selected_well, + tol=tol, + plotting_function=plotting_function, + ) + if overlap_curr_well: + print(selected_well) + overlapping_FOVs.append(overlap_curr_well) + + return overlapping_FOVs diff --git a/tests/test_unit_parse_yokogawa_metadata.py b/tests/test_unit_parse_yokogawa_metadata.py index 96c115544..77fc0c8e7 100644 --- a/tests/test_unit_parse_yokogawa_metadata.py +++ b/tests/test_unit_parse_yokogawa_metadata.py @@ -19,9 +19,9 @@ from devtools import debug from pandas import Timestamp -from fractal_tasks_core.dev.lib_metadata_checks import run_overlap_check from fractal_tasks_core.lib_metadata_parsing import parse_yokogawa_metadata from fractal_tasks_core.lib_ROI_overlaps import remove_FOV_overlaps +from fractal_tasks_core.lib_ROI_overlaps import run_overlap_check # General variables and paths (relative to the test folder) testdir = os.path.dirname(__file__) From eb617e4206f7bfddf5385f611479a382789a9fc2 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 13:28:20 +0200 Subject: [PATCH 12/21] Rename extra from `fractal_tasks` to `fractal-tasks` (ref #378) --- poetry.lock | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/poetry.lock b/poetry.lock index d109f1e03..9ee1171af 100644 --- a/poetry.lock +++ b/poetry.lock @@ -5547,4 +5547,4 @@ fractal-tasks = ["Pillow", "cellpose", "imageio-ffmpeg", "llvmlite", "napari-seg [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "324d58f6c3be1fb4c7170db86215fc356edbd9b3d60ff266cd6ecf1fcd737182" +content-hash = "7b90f3b88fa7065fc330d2e064231f549300ddaa25d56545d681d8a9aac3848e" diff --git a/pyproject.toml b/pyproject.toml index d2fd150c1..316b43043 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ cellpose = { version = "~2.2", optional = true } torch = { version = "1.12.1", optional = true } [tool.poetry.extras] -fractal_tasks = ["Pillow", "imageio-ffmpeg", "scikit-image", "llvmlite", "napari-segment-blobs-and-things-with-membranes", "napari-workflows", "napari-skimage-regionprops", "napari-tools-menu", "cellpose", "torch"] +fractal-tasks = ["Pillow", "imageio-ffmpeg", "scikit-image", "llvmlite", "napari-segment-blobs-and-things-with-membranes", "napari-workflows", "napari-skimage-regionprops", "napari-tools-menu", "cellpose", "torch"] [tool.poetry.group.dev] optional = true From 416e3a9a9243f7076d1b34b01600921d63bb53c7 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 13:29:10 +0200 Subject: [PATCH 13/21] Add first version of pip_install.yml file --- .github/workflows/pip_install.yml | 41 +++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/pip_install.yml diff --git a/.github/workflows/pip_install.yml b/.github/workflows/pip_install.yml new file mode 100644 index 000000000..6c38cfa27 --- /dev/null +++ b/.github/workflows/pip_install.yml @@ -0,0 +1,41 @@ +name: pip_install + +on: + push: + branches: ["main"] + pull_request: + branches: ["main"] + +jobs: + + tests: + name: "Python ${{ matrix.python-version }}" + runs-on: ubuntu-20.04 + timeout-minutes: 10 + + strategy: + matrix: + python-version: ["3.9", "3.10"] + + steps: + + - uses: actions/checkout@v3 + with: + submodules: "recursive" + fetch-depth: 1 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + cache: "pip" + + - name: Install package without extra + run: + pip install -e . + python -c 'import fractal_tasks_core' + + - name: Install package with fractal_tasks extra + run: + pip install -e .[fractal_tasks] + python -c 'import cellpose' From e3fb24719dbed8156eb43594753c4e10bbfd50a3 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 13:30:59 +0200 Subject: [PATCH 14/21] Update pip_install.yml --- .github/workflows/pip_install.yml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/workflows/pip_install.yml b/.github/workflows/pip_install.yml index 6c38cfa27..7dbde6e77 100644 --- a/.github/workflows/pip_install.yml +++ b/.github/workflows/pip_install.yml @@ -30,12 +30,14 @@ jobs: python-version: ${{ matrix.python-version }} cache: "pip" - - name: Install package without extra - run: - pip install -e . - python -c 'import fractal_tasks_core' - - - name: Install package with fractal_tasks extra - run: - pip install -e .[fractal_tasks] - python -c 'import cellpose' + - name: Install package (without extra) + run: pip install -e . + + - name: Test package import (without extra) + - run: python -c 'import fractal_tasks_core' + + - name: Install package (with fractal_tasks extra) + run: pip install -e .[fractal_tasks] + + - name: Test package import (with extra) + - run: python -c 'import cellpose' From 977a823414fe94224415c3360d11fbbb12b5dee5 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 13:32:13 +0200 Subject: [PATCH 15/21] Update pip_install.yml --- .github/workflows/pip_install.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pip_install.yml b/.github/workflows/pip_install.yml index 7dbde6e77..3c9490dd2 100644 --- a/.github/workflows/pip_install.yml +++ b/.github/workflows/pip_install.yml @@ -31,13 +31,13 @@ jobs: cache: "pip" - name: Install package (without extra) - run: pip install -e . + run: python -m pip install -e . - name: Test package import (without extra) - run: python -c 'import fractal_tasks_core' - name: Install package (with fractal_tasks extra) - run: pip install -e .[fractal_tasks] + - run: python -m pip install -e .[fractal_tasks] - name: Test package import (with extra) - run: python -c 'import cellpose' From 8f0b4b6025f1fded3864d3a77a942debadb3b3e6 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 13:33:07 +0200 Subject: [PATCH 16/21] Update pip_install.yml --- .github/workflows/pip_install.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pip_install.yml b/.github/workflows/pip_install.yml index 3c9490dd2..8026b1362 100644 --- a/.github/workflows/pip_install.yml +++ b/.github/workflows/pip_install.yml @@ -34,10 +34,10 @@ jobs: run: python -m pip install -e . - name: Test package import (without extra) - - run: python -c 'import fractal_tasks_core' + run: python -c 'import fractal_tasks_core' - name: Install package (with fractal_tasks extra) - - run: python -m pip install -e .[fractal_tasks] + run: python -m pip install -e .[fractal_tasks] - name: Test package import (with extra) - - run: python -c 'import cellpose' + run: python -c 'import cellpose' From 16fc272c2635a08cbe342e8dc63daa236db244c2 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 13:34:32 +0200 Subject: [PATCH 17/21] Update pip_install.yml --- .github/workflows/pip_install.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pip_install.yml b/.github/workflows/pip_install.yml index 8026b1362..f3b65533e 100644 --- a/.github/workflows/pip_install.yml +++ b/.github/workflows/pip_install.yml @@ -36,8 +36,8 @@ jobs: - name: Test package import (without extra) run: python -c 'import fractal_tasks_core' - - name: Install package (with fractal_tasks extra) - run: python -m pip install -e .[fractal_tasks] + - name: Install package (with fractal-tasks extra) + run: python -m pip install -e .[fractal-tasks] - - name: Test package import (with extra) + - name: Test package import (with fractal-tasks extra) run: python -c 'import cellpose' From 5cff7b99844fb4e55d13b27dd1b7d4ea746549e5 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 13:39:26 +0200 Subject: [PATCH 18/21] Update pip_install.yml --- .github/workflows/pip_install.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pip_install.yml b/.github/workflows/pip_install.yml index f3b65533e..8915ab2e6 100644 --- a/.github/workflows/pip_install.yml +++ b/.github/workflows/pip_install.yml @@ -34,10 +34,10 @@ jobs: run: python -m pip install -e . - name: Test package import (without extra) - run: python -c 'import fractal_tasks_core' + run: python -c 'import fractal_tasks_core; print("OK")' - name: Install package (with fractal-tasks extra) run: python -m pip install -e .[fractal-tasks] - name: Test package import (with fractal-tasks extra) - run: python -c 'import cellpose' + run: python -c 'import fractal_tasks_core.task.cellpose_segmentation; print("OK")' From ce16e3ed2e0699de6956fba8c69c7aaa4433a019 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 13:40:29 +0200 Subject: [PATCH 19/21] Try pip install with python 3.11 --- .github/workflows/pip_install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pip_install.yml b/.github/workflows/pip_install.yml index 8915ab2e6..e73984509 100644 --- a/.github/workflows/pip_install.yml +++ b/.github/workflows/pip_install.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: - python-version: ["3.9", "3.10"] + python-version: ["3.9", "3.10", "3.11"] steps: From ff742dade2663d13a2023df33bd6492fe4e3a8c6 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 13:48:20 +0200 Subject: [PATCH 20/21] Revert "Try pip install with python 3.11" This reverts commit ce16e3ed2e0699de6956fba8c69c7aaa4433a019. --- .github/workflows/pip_install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pip_install.yml b/.github/workflows/pip_install.yml index e73984509..8915ab2e6 100644 --- a/.github/workflows/pip_install.yml +++ b/.github/workflows/pip_install.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: - python-version: ["3.9", "3.10", "3.11"] + python-version: ["3.9", "3.10"] steps: From 9dc266f143c1a587519ed3b0514bf0e1677b6d86 Mon Sep 17 00:00:00 2001 From: Tommaso Comparin <3862206+tcompa@users.noreply.github.com> Date: Tue, 6 Jun 2023 13:49:40 +0200 Subject: [PATCH 21/21] Update pip_install.yml --- .github/workflows/pip_install.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pip_install.yml b/.github/workflows/pip_install.yml index 8915ab2e6..3a585a68d 100644 --- a/.github/workflows/pip_install.yml +++ b/.github/workflows/pip_install.yml @@ -40,4 +40,4 @@ jobs: run: python -m pip install -e .[fractal-tasks] - name: Test package import (with fractal-tasks extra) - run: python -c 'import fractal_tasks_core.task.cellpose_segmentation; print("OK")' + run: python -c 'import fractal_tasks_core.tasks.cellpose_segmentation; print("OK")'