diff --git a/ezomero/_ezomero.py b/ezomero/_ezomero.py index fbe65fa..17d881f 100644 --- a/ezomero/_ezomero.py +++ b/ezomero/_ezomero.py @@ -102,7 +102,7 @@ def put_map_annotation(conn: BlitzGateway, map_ann_id: int, kv_dict: dict, -------- # Change only the values of an existing map annotation: - >>> new_values = {'testkey': 'testvalue', 'testkey2': 'testvalue2'} + >>> new_values = {'key1': 'value1', 'key2': ['value2', 'value3']} >>> put_map_annotation(conn, 15, new_values) # Change both the values and namespace of an existing map annotation: @@ -124,8 +124,14 @@ def put_map_annotation(conn: BlitzGateway, map_ann_id: int, kv_dict: dict, kv_pairs = [] for k, v in kv_dict.items(): k = str(k) - v = str(v) - kv_pairs.append([k, v]) + if type(v) != list: + v = str(v) + kv_pairs.append([k, v]) + else: + for value in v: + value = str(value) + kv_pairs.append([k, value]) + map_ann.setValue(kv_pairs) map_ann.save() return None diff --git a/ezomero/_gets.py b/ezomero/_gets.py index 779211e..45574e4 100644 --- a/ezomero/_gets.py +++ b/ezomero/_gets.py @@ -1283,17 +1283,31 @@ def get_map_annotation(conn: BlitzGateway, map_ann_id: int, ------- kv_dict : dict The value of the specified map annotation object, as a Python dict. + If kv-pairs with the same key exist, the corresponding dict value + will be a list. Examples -------- >>> ma_dict = get_map_annotation(conn, 62) >>> print(ma_dict) - {'testkey': 'testvalue', 'testkey2': 'testvalue2'} + {'testkey': 'testvalue', 'testkey2': ['testvalue2'. 'testvalue3']} """ if type(map_ann_id) is not int: raise TypeError('Map annotation ID must be an integer') + + map_annotation_dict = {} + + map_annotation = conn.getObject('MapAnnotation', map_ann_id).getValue() + + for item in map_annotation: + if item[0] in map_annotation_dict: + if not isinstance(map_annotation_dict[item[0]], list): + map_annotation_dict[item[0]] = [map_annotation_dict[item[0]]] + map_annotation_dict[item[0]].append(item[1]) + else: + map_annotation_dict[item[0]] = item[1] - return dict(conn.getObject('MapAnnotation', map_ann_id).getValue()) + return map_annotation_dict @do_across_groups diff --git a/ezomero/_importer.py b/ezomero/_importer.py index 27aa1c2..1402750 100644 --- a/ezomero/_importer.py +++ b/ezomero/_importer.py @@ -166,8 +166,7 @@ def set_or_create_screen(conn: BlitzGateway, screen: Union[str, int], def multi_post_map_annotation(conn: BlitzGateway, object_type: str, object_ids: Union[int, List[int]], kv_dict: dict, - ns: str, across_groups: Optional[bool] = True - ) -> int: + ns: str) -> int: """Create a single new MapAnnotation and link to multiple images. Parameters ---------- @@ -192,7 +191,7 @@ def multi_post_map_annotation(conn: BlitzGateway, object_type: str, -------- >>> ns = 'jax.org/jax/example/namespace' >>> d = {'species': 'human', - 'occupation': 'time traveler' + 'occupation': ['time traveler', 'soldier'], 'first name': 'Kyle', 'surname': 'Reese'} >>> multi_post_map_annotation(conn, "Image", [23,56,78], d, ns) @@ -212,8 +211,13 @@ def multi_post_map_annotation(conn: BlitzGateway, object_type: str, kv_pairs = [] for k, v in kv_dict.items(): k = str(k) - v = str(v) - kv_pairs.append([k, v]) + if type(v) != list: + v = str(v) + kv_pairs.append([k, v]) + else: + for value in v: + value = str(value) + kv_pairs.append([k, value]) map_ann = MapAnnotationWrapper(conn) map_ann.setNs(str(ns)) diff --git a/ezomero/_posts.py b/ezomero/_posts.py index 86d746c..8e90f5e 100644 --- a/ezomero/_posts.py +++ b/ezomero/_posts.py @@ -252,6 +252,8 @@ def post_map_annotation(conn: BlitzGateway, object_type: str, object_id: int, Notes ----- All keys and values are converted to strings before saving in OMERO. + Passing a list of values will result in multiple instances of the key, + one for each value. Returns ------- @@ -262,7 +264,7 @@ def post_map_annotation(conn: BlitzGateway, object_type: str, object_id: int, -------- >>> ns = 'jax.org/jax/example/namespace' >>> d = {'species': 'human', - ... 'occupation': 'time traveler' + ... 'occupation': ['time traveler', 'soldier']. ... 'first name': 'Kyle', ... 'surname': 'Reese'} >>> post_map_annotation(conn, "Image", 56, d, ns) @@ -274,8 +276,13 @@ def post_map_annotation(conn: BlitzGateway, object_type: str, object_id: int, kv_pairs = [] for k, v in kv_dict.items(): k = str(k) - v = str(v) - kv_pairs.append([k, v]) + if type(v) != list: + v = str(v) + kv_pairs.append([k, v]) + else: + for value in v: + value = str(value) + kv_pairs.append([k, value]) obj = None if object_id is not None: if type(object_id) is not int: diff --git a/tests/test_gets.py b/tests/test_gets.py index 8fdef17..3ab07e8 100644 --- a/tests/test_gets.py +++ b/tests/test_gets.py @@ -582,7 +582,8 @@ def test_get_image_ids_params(conn): def test_get_map_annotation_and_ids(conn, project_structure): kv = {"key1": "value1", - "key2": "value2"} + "key2": "value2", + "key3": ["value3", "value4"]} ns = "jax.org/omeroutils/tests/v0" image_info = project_structure[2] im_id = image_info[0][1] @@ -610,7 +611,9 @@ def test_get_map_annotation_and_ids(conn, project_structure): with pytest.raises(TypeError): _ = ezomero.get_map_annotation(conn, '10') mpann = ezomero.get_map_annotation(conn, map_ann_ids[0]) - assert mpann == kv + assert mpann["key1"] == kv["key1"] + assert mpann["key2"] == kv["key2"] + assert sorted(mpann["key3"]) == sorted(kv["key3"]) conn.deleteObjects("Annotation", [map_ann_id, map_ann_id2, map_ann_id3, map_ann_id4], deleteAnns=True, diff --git a/tests/test_posts.py b/tests/test_posts.py index 42183dc..87a025a 100644 --- a/tests/test_posts.py +++ b/tests/test_posts.py @@ -183,7 +183,8 @@ def test_post_get_map_annotation(conn, project_structure, users_groups): im_id = image_info[0][1] # This test both ezomero.post_map_annotation and ezomero.get_map_annotation kv = {"key1": "value1", - "key2": "value2"} + "key2": "value2", + "key3": ["value3", 123]} ns = "jax.org/omeroutils/tests/v0" # test sanitized input on post @@ -197,6 +198,7 @@ def test_post_get_map_annotation(conn, project_structure, users_groups): map_ann_id = ezomero.post_map_annotation(conn, "Image", im_id, kv, ns) kv_pairs = ezomero.get_map_annotation(conn, map_ann_id) assert kv_pairs["key2"] == "value2" + assert sorted(kv_pairs["key3"]) == sorted(["value3", "123"]) # Test posting to non-existing object im_id2 = 999999999 diff --git a/tests/test_puts.py b/tests/test_puts.py index 6b08564..442e5fe 100644 --- a/tests/test_puts.py +++ b/tests/test_puts.py @@ -19,11 +19,11 @@ def test_put_map_annotation(conn, project_structure, users_groups): image_info = project_structure[2] im_id = image_info[0][1] map_ann_id = ezomero.post_map_annotation(conn, "Image", im_id, kv, ns) - kv = {"key1": "changed1", + kv = {"key1": ["changed1", "changed2"], "key2": "value2"} ezomero.put_map_annotation(conn, map_ann_id, kv) kv_pairs = ezomero.get_map_annotation(conn, map_ann_id) - assert kv_pairs['key1'] == kv['key1'] + assert sorted(kv_pairs['key1']) == sorted(kv['key1']) # test cross-group kv = {"key1": "value1",