From 3a6a10f82cdf0d6d09fcb781d3fc6ca9753a0f3c Mon Sep 17 00:00:00 2001 From: Jonas Teuwen <2347927+jonasteuwen@users.noreply.github.com> Date: Mon, 5 Aug 2024 13:03:06 +0200 Subject: [PATCH] Allow annotation files with raster type (yet not supported) (#245) Allow the reading of newer Darwin v7 annotations, Expand tests for annotations --------- Co-authored-by: Ajey Pai K --- dlup/annotations.py | 10 +++++ tests/files/.v7/metadata.json | 82 +++++++++++++++++++++++++++++++++++ tests/files/103S.json | 12 ++--- tests/files/raster.json | 52 ++++++++++++++++++++++ tests/test_annotations.py | 7 +++ 5 files changed, 157 insertions(+), 6 deletions(-) create mode 100644 tests/files/.v7/metadata.json create mode 100644 tests/files/raster.json diff --git a/dlup/annotations.py b/dlup/annotations.py index 540e0fc9..80351c19 100644 --- a/dlup/annotations.py +++ b/dlup/annotations.py @@ -78,6 +78,7 @@ class AnnotationType(str, Enum): BOX = "BOX" POLYGON = "POLYGON" TAG = "TAG" + RASTER = "RASTER" class AnnotationSorting(str, Enum): @@ -152,6 +153,9 @@ def _get_v7_metadata(filename: pathlib.Path) -> Optional[dict[str, DarwinV7Metad output = {} for sample in v7_metadata["classes"]: annotation_type = _v7_annotation_type_to_dlup_annotation_type(sample["type"]) + # This is not implemented and can be skipped. The main function will raise a NonImplementedError + if annotation_type == AnnotationType.RASTER: + continue label = sample["name"] color = sample["color"][5:-1].split(",") @@ -936,6 +940,9 @@ def from_darwin_json( annotation_type = _v7_annotation_type_to_dlup_annotation_type( curr_annotation.annotation_class.annotation_type ) + if annotation_type == AnnotationType.RASTER: + raise NotImplementedError("Raster annotations are not supported.") + annotation_color = v7_metadata[name].color if v7_metadata else None if annotation_type == AnnotationType.TAG: @@ -1241,4 +1248,7 @@ def _v7_annotation_type_to_dlup_annotation_type(annotation_type: str) -> Annotat if annotation_type == "tag": return AnnotationType.TAG + if annotation_type == "raster_layer": + return AnnotationType.RASTER + raise NotImplementedError(f"annotation_type {annotation_type} is not implemented or not a valid dlup type.") diff --git a/tests/files/.v7/metadata.json b/tests/files/.v7/metadata.json new file mode 100644 index 00000000..626b5998 --- /dev/null +++ b/tests/files/.v7/metadata.json @@ -0,0 +1,82 @@ +{ + "classes": [ + { + "name": "lymphocyte (cell)", + "type": "keypoint", + "description": null, + "color": "rgba(0,236,123,1.0)", + "sub_types": [ + "inference" + ], + "properties": [] + }, + { + "name": "tumor (cell)", + "type": "bounding_box", + "description": null, + "color": "rgba(255,46,0,1.0)", + "sub_types": [ + "inference" + ], + "properties": [] + }, + { + "name": "tumor (cell)", + "type": "keypoint", + "description": null, + "color": "rgba(255,92,0,1.0)", + "sub_types": [ + "inference" + ], + "properties": [] + }, + { + "name": "lymphocyte (cell)", + "type": "bounding_box", + "description": null, + "color": "rgba(0,236,123,1.0)", + "sub_types": [ + "inference" + ], + "properties": [] + }, + { + "name": "tumor (area)", + "type": "polygon", + "description": null, + "color": "rgba(255,46,0,1.0)", + "sub_types": [ + "inference" + ], + "properties": [] + }, + { + "name": "stroma (area)", + "type": "polygon", + "description": null, + "color": "rgba(0,236,123,1.0)", + "sub_types": [ + "inference" + ], + "properties": [] + }, + { + "name": "ROI (segmentation)", + "type": "bounding_box", + "description": null, + "color": "rgba(143,0,255,1.0)", + "sub_types": [ + "inference" + ], + "properties": [] + }, + { + "name": "__raster_layer__", + "type": "raster_layer", + "description": "System class for all team's annotations with raster_layer type", + "color": null, + "sub_types": [], + "properties": [] + } + ] +} diff --git a/tests/files/103S.json b/tests/files/103S.json index b290648c..396b0eb4 100644 --- a/tests/files/103S.json +++ b/tests/files/103S.json @@ -8,14 +8,14 @@ "dataset": { "name": "PlayGround", "slug": "playground", - "dataset_management_url": "https://darwin.v7labs.com/datasets/669752/dataset-management" + "dataset_management_url": "dummy-url" }, "item_id": "0189bfc8-4487-4b1f-5516-30150df25cc6", "team": { - "name": "Ellogon AI", - "slug": "ellogon-ai" + "name": "test-team", + "slug": "test-team" }, - "workview_url": "https://darwin.v7labs.com/workview?dataset=669752&item=0189bfc8-4487-4b1f-5516-30150df25cc6" + "workview_url": "dummy-workview-url" }, "slots": [ { @@ -23,11 +23,11 @@ "slot_name": "0", "width": 63488, "height": 40064, - "thumbnail_url": "https://darwin.v7labs.com/api/v2/teams/ellogon-ai/files/1d10a9da-81c0-403f-98a4-98e65e5e80e4/thumbnail", + "thumbnail_url": "dummy-url", "source_files": [ { "file_name": "103S.tif", - "url": "https://darwin.v7labs.com/api/v2/teams/ellogon-ai/uploads/65969e74-60b3-49b8-99de-c7af68a77860" + "url": "dummy-url" } ] } diff --git a/tests/files/raster.json b/tests/files/raster.json new file mode 100644 index 00000000..2e424e85 --- /dev/null +++ b/tests/files/raster.json @@ -0,0 +1,52 @@ +{ + "version": "2.0", + "schema_ref": "https://darwin-public.s3.eu-west-1.amazonaws.com/darwin_json/2.0/schema.json", + "item": { + "name": "dummy.tif", + "path": "/", + "source_info": { + "dataset": { + "name": "PlayGround", + "slug": "playground", + "dataset_management_url": "dummy-url" + }, + "item_id": "0189bfc8-4487-4b1f-5516-30150df25cc6", + "team": { + "name": "test-team", + "slug": "test-team" + }, + "workview_url": "dummy-url" + }, + "slots": [ + { + "type": "image", + "slot_name": "0", + "width": 63488, + "height": 40064, + "thumbnail_url": "dummy-url", + "source_files": [ + { + "file_name": "103S.tif", + "url": "dummy-url" + } + ] + } + ] + }, + "annotations": [ + { + "raster_layer": { + "dense_rle":"placeholder", + "total_pixels": 1000, + "mask_annotation_ids_mapping": { + "0": "A random ID" + } + }, + "id": "A random ID", + "name": "placeholder", + "slot_names": [ + "0" + ] + } + ] +} diff --git a/tests/test_annotations.py b/tests/test_annotations.py index a0541af6..6eee0632 100644 --- a/tests/test_annotations.py +++ b/tests/test_annotations.py @@ -53,6 +53,7 @@ class TestAnnotations: geojson_annotations = WsiAnnotations.from_geojson([pathlib.Path(geojson_out.name)]) _v7_annotations = None + _v7_raster_annotations = None @property def v7_annotations(self): @@ -61,6 +62,12 @@ def v7_annotations(self): self._v7_annotations = WsiAnnotations.from_darwin_json(pathlib.Path(__file__).parent / "files/103S.json") return self._v7_annotations + def test_raster_annotations(self): + if self._v7_raster_annotations is None: + assert pathlib.Path(pathlib.Path(__file__).parent / "files/raster.json").exists() + with pytest.raises(NotImplementedError): + WsiAnnotations.from_darwin_json(pathlib.Path(__file__).parent / "files/raster.json") + def test_conversion_geojson(self): # We need to read the asap annotations and compare them to the geojson annotations v7_region = self.v7_annotations.read_region((15300, 19000), 1.0, (2500.0, 2500.0))