Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OBO Compliance suite (replay of 683) #693

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
12 changes: 9 additions & 3 deletions src/oaklib/converters/obo_graph_to_rdf_owl_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
HAS_RELATED_SYNONYM,
)
from oaklib.types import CURIE
from oaklib.utilities.format_utilities import RDFLIB_SYNTAX_ALIAS_MAP

TRIPLE = Tuple[rdflib.URIRef, rdflib.URIRef, Any]

Expand All @@ -45,7 +46,7 @@
class OboGraphToRdfOwlConverter(DataModelConverter):
"""Converts from OboGraph to OWL layered on RDF."""

def dump(self, source: GraphDocument, target: str = None, **kwargs) -> None:
def dump(self, source: GraphDocument, target: str = None, format="turtle", **kwargs) -> None:
"""
Dump an OBO Graph Document to a FHIR CodeSystem

Expand All @@ -54,10 +55,13 @@ def dump(self, source: GraphDocument, target: str = None, **kwargs) -> None:
:return:
"""
g = self.convert(source)
# TODO: simplify this, see https://github.com/INCATools/ontology-access-kit/issues/687
if format in RDFLIB_SYNTAX_ALIAS_MAP:
format = RDFLIB_SYNTAX_ALIAS_MAP[format]
if target is None:
print(g.serialize(format="turtle"))
print(g.serialize(format=format))
else:
g.serialize(format="turtle", destination=target)
g.serialize(format=format, destination=target)

def convert(
self, source: Union[Graph, GraphDocument], target: rdflib.Graph = None, **kwargs
Expand Down Expand Up @@ -157,6 +161,8 @@ def _add_reified(
target.add((pred, RDF.type, OWL.AnnotationProperty))

def _uri_ref(self, curie: CURIE) -> rdflib.URIRef:
if ":" not in curie:
curie = f"obo:{curie}"
if self.curie_converter is None:
self.curie_converter = BasicOntologyInterface().converter
uri = self.curie_converter.expand(curie, passthrough=True)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ def dump(self, path: Union[str, TextIO] = None, syntax: str = "obo", **kwargs):
else:
self.obo_document.dump(path)
else:
super().dump(path, syntax)
super().dump(path, syntax=syntax)

def save(
self,
Expand Down Expand Up @@ -706,6 +706,8 @@ def node(self, curie: CURIE, strict=False, include_metadata=False) -> obograph.N
meta.definition = obograph.DefinitionPropertyValue(val=defn)
for _, syn in self.synonym_property_values([curie]):
meta.synonyms.append(syn)
for _, subset in self.terms_subsets([curie]):
meta.subsets.append(subset)
return obograph.Node(id=curie, lbl=self.label(curie), type=typ, meta=meta)

def as_obograph(self, expand_curies=False) -> Graph:
Expand Down
4 changes: 2 additions & 2 deletions src/oaklib/implementations/simpleobo/simple_obo_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ def intersection_of_tuples(self) -> List[Tuple[CURIE, Optional[CURIE]]]:
pairs = []
for v in self._values(TAG_INTERSECTION_OF):
toks = [x for x in v.split(" ") if x]
if toks[1].startswith("!"):
if len(toks) == 1 or toks[1].startswith("!"):
pairs.append((toks[0], None))
else:
pairs.append((toks[0], toks[1]))
Expand All @@ -382,7 +382,7 @@ def property_value_tuples(self) -> List[Tuple[CURIE, Optional[CURIE]]]:
pairs = []
for v in self._values(TAG_PROPERTY_VALUE):
toks = [x for x in v.split(" ") if x]
if toks[1].startswith("!"):
if len(toks) == 1 or toks[1].startswith("!"):
pairs.append((toks[0], None))
else:
pairs.append((toks[0], toks[1]))
Expand Down
11 changes: 9 additions & 2 deletions src/oaklib/implementations/sqldb/sql_implementation.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@
from oaklib.utilities.axioms.logical_definition_utilities import (
logical_definition_matches,
)
from oaklib.utilities.format_utilities import (
OBOGRAPHS_SYNTAX_ALIAS_MAP,
RDFLIB_SYNTAX_ALIAS_MAP,
)
from oaklib.utilities.graph.relationship_walker import walk_down, walk_up
from oaklib.utilities.identifier_utils import (
string_as_base64_curie,
Expand Down Expand Up @@ -1180,11 +1184,14 @@ def dump(self, path: str = None, syntax: str = None, **kwargs):
"""
if syntax is None:
syntax = "ttl"
if syntax == "ttl":
if syntax in ["ttl", "rdfxml", "owl"]:
if syntax in RDFLIB_SYNTAX_ALIAS_MAP:
syntax = RDFLIB_SYNTAX_ALIAS_MAP[syntax]
g = self.as_rdflib_graph()
logging.info(f"Dumping to {path}")
g.serialize(path, format=syntax)
elif syntax == "json":
elif syntax in OBOGRAPHS_SYNTAX_ALIAS_MAP.keys():
syntax = OBOGRAPHS_SYNTAX_ALIAS_MAP[syntax]
g = self.as_obograph(expand_curies=True)
gd = obograph.GraphDocument(graphs=[g])
json_dumper.dump(gd, path)
Expand Down
7 changes: 5 additions & 2 deletions src/oaklib/interfaces/dumper_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"rdfxml": (OboGraphToRdfOwlConverter, {"format": "xml"}),
"cx": OboGraphToCXConverter,
"obojson": None,
"json": None,
}

FORMAT_SYNONYMS = {
Expand Down Expand Up @@ -61,15 +62,15 @@ def dump(
raise ValueError(f"Cannot handle interface: {self}")
og = self.as_obograph()
ogdoc = GraphDocument(graphs=[og])
if syntax == "obojson":
converter_class = OBOGRAPH_CONVERTERS.get(syntax, None)
if converter_class is None:
json_str = json_dumper.dumps(ogdoc, inject_type=False)
if path:
with open(path, "w", encoding="utf-8") as f:
f.write(json_str)
else:
print(json_str)
else:
converter_class = OBOGRAPH_CONVERTERS[syntax]
if isinstance(converter_class, tuple):
converter_class, converter_kwargs = converter_class
kwargs.update(converter_kwargs)
Expand All @@ -78,4 +79,6 @@ def dump(
logging.info(f"Using {converter}, kwargs={kwargs}")
converter.curie_converter = self.converter
kwargs = {k: v for k, v in kwargs.items() if v is not None}
if "format" not in kwargs:
kwargs["format"] = syntax
converter.dump(ogdoc, target=path, **kwargs)
68 changes: 68 additions & 0 deletions src/oaklib/utilities/format_utilities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""
Utilities for working with formats

See https://github.com/INCATools/ontology-access-kit/issues/687
"""

from enum import Enum


class OntologyModel(str, Enum):
"""
Enumerated types for ontology models.

A model is an abstract representation of an ontology that is potentially
serializable in multiple syntaxes.
"""

OWL = "owl"
"""W3C OWL2 Ontology Model"""

SKOS = "skos"
"""W3C SKOS Ontology Model"""

SDO_RDFS = "sdo_rdfs"
"""Schema.org RDFS Ontology Model"""

OBOFORMAT = "oboformat"
"""OBO Format Ontology Model. Always serialized as obo format"""

OBOGRAPHS = "obographs"
"""OBO Graphs Ontology Model"""


MODEL_ALLOWED_SYNTAXES = {
OntologyModel.OWL: [
"ttl",
"rdfxml",
"n3",
"nt",
"pretty-xml",
"trix",
"trig",
"ofn",
"owx",
"omn",
"obo",
],
OntologyModel.SKOS: ["ttl", "rdfxml", "n3", "nt", "pretty-xml", "trix", "trig"],
OntologyModel.OBOFORMAT: ["obo"],
OntologyModel.OBOGRAPHS: ["json", "yaml"],
}


OBOGRAPHS_SYNTAX_ALIAS_MAP = {
"json": "json",
"obojson": "json",
"yaml": "yaml",
"obograph": "json",
"obographjson": "json",
"obographyaml": "yaml",
}


RDFLIB_SYNTAX_ALIAS_MAP = {
"owl": "turtle",
"ttl": "turtle",
"rdfxml": "xml",
}
Loading
Loading