diff --git a/src/oaklib/implementations/pronto/pronto_implementation.py b/src/oaklib/implementations/pronto/pronto_implementation.py index 4ed08d72e..617d45ba3 100644 --- a/src/oaklib/implementations/pronto/pronto_implementation.py +++ b/src/oaklib/implementations/pronto/pronto_implementation.py @@ -40,7 +40,6 @@ OWL_VERSION_INFO, SCOPE_TO_SYNONYM_PRED_MAP, SEMAPV, - SKOS_CLOSE_MATCH, SKOS_MATCH_PREDICATES, TERM_REPLACED_BY, TERMS_MERGED, @@ -549,6 +548,12 @@ def simple_mappings_by_curie(self, curie: CURIE) -> Iterable[Tuple[PRED_CURIE, C yield pred, v elif isinstance(s, ResourcePropertyValue): yield pred, s.resource + if isinstance(t, Term): + for rel_type, parents in t.relationships.items(): + pred = self._get_pronto_relationship_type_curie(rel_type) + if pred in SKOS_MATCH_PREDICATES: + for parent in parents: + yield pred, parent.id def entity_metadata_map(self, curie: CURIE) -> METADATA_MAP: t = self._entity(curie) @@ -662,7 +667,7 @@ def sssom_mappings( if x.id in curies: m = sssom.Mapping( subject_id=e, - predicate_id=SKOS_CLOSE_MATCH, + predicate_id=HAS_DBXREF, object_id=x.id, mapping_justification=sssom.EntityReference( SEMAPV.UnspecifiedMatching.value diff --git a/src/oaklib/implementations/simpleobo/simple_obo_implementation.py b/src/oaklib/implementations/simpleobo/simple_obo_implementation.py index 572d6538e..f645ace3e 100644 --- a/src/oaklib/implementations/simpleobo/simple_obo_implementation.py +++ b/src/oaklib/implementations/simpleobo/simple_obo_implementation.py @@ -59,7 +59,7 @@ RDFS_RANGE, SCOPE_TO_SYNONYM_PRED_MAP, SEMAPV, - SKOS_CLOSE_MATCH, + SKOS_MATCH_PREDICATES, SUBPROPERTY_OF, TERM_REPLACED_BY, TERMS_MERGED, @@ -697,12 +697,38 @@ def get_sssom_mappings_by_curie(self, curie: Union[str, CURIE]) -> Iterator[ssso for x in s.simple_values(TAG_XREF): m = sssom.Mapping( subject_id=curie, - predicate_id=SKOS_CLOSE_MATCH, + predicate_id=HAS_DBXREF, object_id=x, mapping_justification=sssom.EntityReference(SEMAPV.UnspecifiedMatching.value), ) inject_mapping_sources(m) yield m + for x in s.property_values(): + p = self.map_shorthand_to_curie(x[0]) + if p in SKOS_MATCH_PREDICATES: + m = sssom.Mapping( + subject_id=curie, + predicate_id=p, + object_id=x[1], + mapping_justification=sssom.EntityReference( + SEMAPV.UnspecifiedMatching.value + ), + ) + inject_mapping_sources(m) + yield m + for p, v in s.pair_values(TAG_RELATIONSHIP): + p = self.map_shorthand_to_curie(p) + if p in SKOS_MATCH_PREDICATES: + m = sssom.Mapping( + subject_id=curie, + predicate_id=p, + object_id=v, + mapping_justification=sssom.EntityReference( + SEMAPV.UnspecifiedMatching.value + ), + ) + inject_mapping_sources(m) + yield m # TODO: use a cache to avoid re-calculating for _, stanza in self.obo_document.stanzas.items(): if len(stanza.simple_values(TAG_XREF)) > 0: @@ -710,7 +736,7 @@ def get_sssom_mappings_by_curie(self, curie: Union[str, CURIE]) -> Iterator[ssso if x == curie: m = sssom.Mapping( subject_id=stanza.id, - predicate_id=SKOS_CLOSE_MATCH, + predicate_id=HAS_DBXREF, object_id=curie, mapping_justification=SEMAPV.UnspecifiedMatching.value, ) diff --git a/tests/input/mapping-predicates-test.obo b/tests/input/mapping-predicates-test.obo new file mode 100644 index 000000000..37f4f109d --- /dev/null +++ b/tests/input/mapping-predicates-test.obo @@ -0,0 +1,30 @@ +format-version: 1.2 +ontology: test.obo +idspace: dc http://purl.org/dc/elements/1.1/ +idspace: oboInOwl http://www.geneontology.org/formats/oboInOwl# +idspace: owl http://www.w3.org/2002/07/owl# +idspace: rdf http://www.w3.org/1999/02/22-rdf-syntax-ns# +idspace: rdfs http://www.w3.org/2000/01/rdf-schema# +idspace: terms http://purl.org/dc/terms/ +idspace: xml http://www.w3.org/XML/1998/namespace +idspace: xsd http://www.w3.org/2001/XMLSchema# +idspace: X http://purl.obolibrary.org/obo/X_ + +[Term] +id: X:0000001 +name: Person +property_value: skos:exactMatch schema:Person +relationship: skos:closeMatch prov:Agent +xref: Y:1 + +[Typedef] +id: skos:exactMatch +is_metadata_tag: true +is_class_level: true + + +[Typedef] +id: skos:closeMatch +is_metadata_tag: true +is_class_level: true + diff --git a/tests/test_implementations/__init__.py b/tests/test_implementations/__init__.py index 9642b4da6..5ea67f33c 100644 --- a/tests/test_implementations/__init__.py +++ b/tests/test_implementations/__init__.py @@ -458,6 +458,19 @@ def test_multilingual(self, oi: BasicOntologyInterface): f"Definition for {lang} did not match", ) + def test_skos_mappings(self, oi: MappingProviderInterface): + for curies in [None, ["X:0000001"]]: + mappings = [ + (m.subject_id, m.predicate_id, m.object_id) for m in oi.sssom_mappings(curies) + ] + print(mappings) + expected = [ + ("X:0000001", "oio:hasDbXref", "Y:1"), + ("X:0000001", "skos:exactMatch", "schema:Person"), + ("X:0000001", "skos:closeMatch", "prov:Agent"), + ] + self.test.assertCountEqual(expected, mappings) + def test_sssom_mappings(self, oi: MappingProviderInterface): """ Tests conformance of MappingProviderInterface. diff --git a/tests/test_implementations/test_pronto.py b/tests/test_implementations/test_pronto.py index 694762cd2..ba254c994 100644 --- a/tests/test_implementations/test_pronto.py +++ b/tests/test_implementations/test_pronto.py @@ -44,6 +44,7 @@ TEST_SIMPLE_ONT = INPUT_DIR / "go-nucleus-simple.obo" TEST_ONT_COPY = OUTPUT_DIR / "go-nucleus.copy.obo" TEST_SUBGRAPH_OUT = OUTPUT_DIR / "vacuole.obo" +TEST_SKOS_MAPPINGS_ONT = INPUT_DIR / "mapping-predicates-test.obo" class TestProntoImplementation(unittest.TestCase): @@ -193,6 +194,16 @@ def test_obsolete_entities(self): oi = ProntoImplementation(resource) self.compliance_tester.test_obsolete_entities(oi) + @unittest.skip("Pronto does not handling dangling references") + def test_skos_mappings(self): + """ + Tests mappings as SKOS properties. + + :return: + """ + adapter = get_adapter(f"pronto:{TEST_SKOS_MAPPINGS_ONT}") + self.compliance_tester.test_skos_mappings(adapter) + def test_sssom_mappings(self): self.compliance_tester.test_sssom_mappings(self.oi) diff --git a/tests/test_implementations/test_simple_obo.py b/tests/test_implementations/test_simple_obo.py index f99b191c9..c9aee221f 100644 --- a/tests/test_implementations/test_simple_obo.py +++ b/tests/test_implementations/test_simple_obo.py @@ -3,6 +3,7 @@ from copy import deepcopy from kgcl_schema.datamodel import kgcl +from oaklib import get_adapter from oaklib.datamodels import obograph from oaklib.datamodels.search import SearchConfiguration from oaklib.datamodels.search_datamodel import SearchProperty, SearchTermSyntax @@ -59,6 +60,7 @@ TEST_SIMPLE_ONT = INPUT_DIR / "go-nucleus-simple.obo" TEST_ONT_COPY = OUTPUT_DIR / "go-nucleus.copy.obo" TEST_SUBGRAPH_OUT = OUTPUT_DIR / "vacuole.obo" +TEST_SKOS_MAPPINGS_ONT = INPUT_DIR / "mapping-predicates-test.obo" class TestSimpleOboImplementation(unittest.TestCase): @@ -236,6 +238,15 @@ def test_synonyms_extra(self): def test_sssom_mappings(self): self.compliance_tester.test_sssom_mappings(self.oi) + def test_skos_mappings(self): + """ + Tests mappings as SKOS properties. + + :return: + """ + adapter = get_adapter(f"simpleobo:{TEST_SKOS_MAPPINGS_ONT}") + self.compliance_tester.test_skos_mappings(adapter) + def test_definitions(self): self.compliance_tester.test_definitions(self.oi, include_metadata=True)