diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b92b0e..ebb2cdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ -# 0.6.1 (June 2024) +# 0.6.1 (June 2025) - Fix version -# 0.6.0 (June 2024) +# 0.6.0 (June 2025) - Support --name_by option ([#147](https://github.com/ome/omero-cli-zarr/pull/147)) - Fix export of Plate labels ([#173](https://github.com/ome/omero-cli-zarr/pull/173)) diff --git a/src/omero_zarr/masks.py b/src/omero_zarr/masks.py index e403a07..cc97f43 100644 --- a/src/omero_zarr/masks.py +++ b/src/omero_zarr/masks.py @@ -293,12 +293,13 @@ def save(self, masks: List[omero.model.Shape], name: str) -> None: # Figure out whether we can flatten some dimensions unique_dims: Dict[str, Set[int]] = { "T": {unwrap(mask.theT) for shapes in masks for mask in shapes}, + "C": {unwrap(mask.theC) for shapes in masks for mask in shapes}, "Z": {unwrap(mask.theZ) for shapes in masks for mask in shapes}, } ignored_dimensions: Set[str] = set() - # We always ignore the C dimension - ignored_dimensions.add("C") print(f"Unique dimensions: {unique_dims}") + if unique_dims["C"] == {None} or len(unique_dims["C"]) == 1: + ignored_dimensions.add("C") for d in "TZ": if unique_dims[d] == {None}: @@ -308,8 +309,6 @@ def save(self, masks: List[omero.model.Shape], name: str) -> None: # Verify that we are linking this mask to a real ome-zarr source_image = self.source_image - print(f"source_image ??? needs to be None to use filename: {source_image}") - print(f"filename: {filename}", self.output, self.name_by) source_image_link = self.source_image if source_image is None: # Assume that we're using the output directory @@ -320,11 +319,11 @@ def save(self, masks: List[omero.model.Shape], name: str) -> None: assert self.plate_path, "Need image path within the plate" source_image = f"{source_image}/{self.plate_path}" - print(f"source_image {source_image}") image_path = source_image if self.output: image_path = os.path.join(self.output, source_image) src = parse_url(image_path) + print(f"Writing labels to image at: {image_path}") assert src, f"Source image does not exist at {image_path}" input_pyramid = Node(src, []) assert input_pyramid.load(Multiscales), "No multiscales metadata found" @@ -578,7 +577,7 @@ def masks_to_labels( if check_overlaps: raise Exception( f"Shape {shape.roi.id.val} overlaps " - "with existing labels" + "with existing labels. Use --overlaps=dtype_max" ) else: # set overlapping region to max(dtype) diff --git a/test/integration/clitest/test_export.py b/test/integration/clitest/test_export.py index d6145cc..d474c07 100644 --- a/test/integration/clitest/test_export.py +++ b/test/integration/clitest/test_export.py @@ -192,20 +192,21 @@ def test_export_masks( img_id = images[0].id.val size_xy = 512 - # Create a mask + # Create a mask for each channel from skimage.data import binary_blobs - blobs = binary_blobs(length=size_xy, volume_fraction=0.1, n_dim=2).astype( - "int8" - ) red = [255, 0, 0, 255] - mask = mask_from_binary_image(blobs, rgba=red, z=0, c=0, t=0) - - roi = RoiI() - roi.setImage(images[0]) - roi.addShape(mask) - updateService = self.client.sf.getUpdateService() - updateService.saveAndReturnObject(roi) + green = [0, 255, 0, 255] + for ch, color in enumerate([red, green]): + blobs = binary_blobs(length=size_xy, volume_fraction=0.1, n_dim=2).astype( + "int8" + ) + mask = mask_from_binary_image(blobs, rgba=color, z=0, c=ch, t=0) + roi = RoiI() + roi.setImage(images[0]) + roi.addShape(mask) + updateService = self.client.sf.getUpdateService() + updateService.saveAndReturnObject(roi) print("tmp_path", tmp_path) @@ -232,19 +233,22 @@ def test_export_masks( all_lines = ", ".join(lines) assert "Exporting to" in all_lines assert "Finished" in all_lines - assert "Found 1 mask shapes in 1 ROIs" in all_lines + assert "Found 2 mask shapes in 2 ROIs" in all_lines labels_text = (tmp_path / zarr_name / "labels" / "0" / ".zattrs").read_text( encoding="utf-8" ) labels_json = json.loads(labels_text) - assert labels_json["image-label"]["colors"] == [{"label-value": 1, "rgba": red}] + assert labels_json["image-label"]["colors"] == [ + {"label-value": 1, "rgba": red}, + {"label-value": 2, "rgba": green}, + ] arr_text = (tmp_path / zarr_name / "labels" / "0" / "0" / ".zarray").read_text( encoding="utf-8" ) arr_json = json.loads(arr_text) - assert arr_json["shape"] == [1, 512, 512] + assert arr_json["shape"] == [2, 512, 512] @pytest.mark.parametrize("name_by", ["id", "name"]) def test_export_plate_polygons(