diff --git a/sfftkrw/conf.py b/sfftkrw/conf.py index 209ed76..626a94a 100644 --- a/sfftkrw/conf.py +++ b/sfftkrw/conf.py @@ -1,2 +1,2 @@ -SFFTKRW_VERSION = 'v0.6.1.dev0' +SFFTKRW_VERSION = 'v0.6.2.dev0' SFFTKRW_ENTRY_POINT = 'sff' diff --git a/sfftkrw/schema/adapter_v0_8_0_dev1.py b/sfftkrw/schema/adapter_v0_8_0_dev1.py index 6ce12a4..f1c7e14 100644 --- a/sfftkrw/schema/adapter_v0_8_0_dev1.py +++ b/sfftkrw/schema/adapter_v0_8_0_dev1.py @@ -2523,3 +2523,50 @@ def from_file(cls, fn, args=None): def to_file(self, *args, **kwargs): """Alias for :py:meth:`.export` method. Passes all args and kwargs onto :py:meth:`.export`""" return super(SFFSegmentation, self).export(*args, **kwargs) + + def merge_annotation(self, other_seg): + """Merge the annotation from another sff_seg to this one + + :param other_seg: segmentation to get annotations from + :type other_seg: :py:class:`sfftkrw.SFFSegmentation` + """ + _assert_or_raise(other_seg, SFFSegmentation) + # global data + # self.name = other_seg.name + # self.software_list = other_seg.software_list + self.global_external_references = other_seg.global_external_references + # self.details = other_seg.details + # loop through segments + for segment in self.segments: + other_segment = other_seg.segments.get_by_id(segment.id) + segment.biological_annotation = other_segment.biological_annotation + + def copy_annotation(self, from_id, to_id): + """Copy annotation across segments + + :param int/list from_id: segment ID to get notes from; use -1 for for global notes + :param int/list to_id: segment ID to copy notes to; use -1 for global notes + """ + if from_id == -1: + _from = self.global_external_references + else: + _from = self.segments.get_by_id(from_id).biological_annotation.external_references + if to_id == -1: + to = self.global_external_references + else: + to = self.segments.get_by_id(to_id).biological_annotation.external_references + # the id for global notes + for extref in _from: + to.append(extref) + + def clear_annotation(self, from_id): + """Clear all annotations from the segment with ID specified + + :param from_id: segment ID + :return: + """ + if from_id == -1: + self.global_external_references.clear() # = SFFGlobalExternalReferenceList() + else: + segment = self.segments.get_by_id(from_id) + segment.biological_annotation.external_references.clear() # = SFFExternalReferenceList() diff --git a/sfftkrw/unittests/test_adapter_v0_8_0_dev1.py b/sfftkrw/unittests/test_adapter_v0_8_0_dev1.py index 35bf465..1bcbe46 100644 --- a/sfftkrw/unittests/test_adapter_v0_8_0_dev1.py +++ b/sfftkrw/unittests/test_adapter_v0_8_0_dev1.py @@ -5238,3 +5238,66 @@ def test_export_json(self): with open(temp_file.name) as f: J = json.load(f) self.assertEqual(J[u'primary_descriptor'], u"three_d_volume") + + def test_merge_annotation(self): + """Test that we can merge annotation from one to another""" + seg1_fn = os.path.join(TEST_DATA_PATH, u'sff', u'v0.8', u'annotated_emd_1014.json') + seg2_fn = os.path.join(TEST_DATA_PATH, u'sff', u'v0.8', u'emd_1014.json') + seg1 = adapter.SFFSegmentation.from_file(seg1_fn) + seg2 = adapter.SFFSegmentation.from_file(seg2_fn) + # perform the notes merge + seg1.merge_annotation(seg2) + self.assertEqual(seg1.global_external_references, seg2.global_external_references) + for segment in seg1.segment_list: + other_segment = seg2.segment_list.get_by_id(segment.id) + self.assertEqual(segment.biological_annotation.external_references, other_segment.biological_annotation.external_references) + + def test_copy_annotation(self): + """Test that we can copy annotations: global and local""" + seg_fn = os.path.join(TEST_DATA_PATH, u'sff', u'v0.8', u'emd_1014.json') + seg = adapter.SFFSegmentation.from_file(seg_fn) + segment_ids = list(seg.segment_list.get_ids()) + from_segment_id = random.choice(segment_ids) + from_segment = seg.segment_list.get_by_id(from_segment_id) + segment_ids.remove(from_segment_id) + try: + to_segment_ids = random.choices(segment_ids, k=len(segment_ids)//2) + except AttributeError: + to_segment_ids = list(set([random.choice(segment_ids) for _ in _xrange(len(segment_ids)//2)])) + # clear annotations; check no annotations left + for segment_id in to_segment_ids: + segment = seg.segment_list.get_by_id(segment_id) + segment.biological_annotation.external_references.clear() + self.assertEqual(len(segment.biological_annotation.external_references), 0) + # copy annotations + # noinspection PyStatementEffect + (seg.copy_annotation(from_segment_id, to_id) for to_id in to_segment_ids) + # now ensure they are similar to the one copied from + for segment_id in to_segment_ids: + segment = seg.segment_list.get_by_id(segment_id) + self.assertEqual(segment.biological_annotation.external_references, from_segment.biological_annotation.external_references) + # for global + seg.global_external_references.clear() + self.assertEqual(len(seg.global_external_references), 0) + seg.copy_annotation(from_segment_id, -1) # -1 for global + self.assertEqual(len(from_segment.biological_annotation.external_references), len(seg.global_external_references)) + for i, er in enumerate(from_segment.biological_annotation.external_references): + self.assertEqual(er, seg.global_external_references[i]) + + def test_clear_annotation(self): + """Test that we can clear annotations""" + seg_fn = os.path.join(TEST_DATA_PATH, u'sff', u'v0.8', u'emd_1014.json') + seg = adapter.SFFSegmentation.from_file(seg_fn) + # global + self.assertTrue(len(seg.global_external_references) > 0) + seg.clear_annotation(-1) + self.assertEqual(len(seg.global_external_references), 0) + # local + segment_ids = list(seg.segment_list.get_ids()) + from_segment_id = random.choice(segment_ids) + from_segment = seg.segment_list.get_by_id(from_segment_id) + self.assertTrue(len(from_segment.biological_annotation.external_references) > 0) + seg.clear_annotation(from_segment_id) + self.assertEqual(len(from_segment.biological_annotation.external_references), 0) + +