Skip to content

Commit

Permalink
Merge pull request #13 from INCATools/custom-schema
Browse files Browse the repository at this point in the history
custom schema
  • Loading branch information
cmungall authored Apr 12, 2022
2 parents fce1bc5 + 0a71aec commit df31f74
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 66 deletions.
10 changes: 8 additions & 2 deletions src/oaklib/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import click
from linkml_runtime.dumpers import yaml_dumper
from oaklib.datamodels.validation_datamodel import ValidationConfiguration
from oaklib.implementations.bioportal.bioportal_implementation import BioportalImplementation
from oaklib.implementations.ontobee.ontobee_implementation import OntobeeImplementation
from oaklib.implementations.pronto.pronto_implementation import ProntoImplementation
Expand Down Expand Up @@ -446,21 +447,26 @@ def validate(output: str, cutoff: int):
default=50,
show_default=True,
help="maximum results to report for any (type, predicate) pair")
@click.option('-s', '--schema',
help="Path to schema (if you want to override the bundled OMO schema)")
@click.argument("dbs", nargs=-1)
@output_option
def validate_multiple(dbs, output, cutoff: int):
def validate_multiple(dbs, output, schema, cutoff: int):
"""
Validate an ontology against ontology metadata
"""
writer = StreamingCsvWriter(output)
config = ValidationConfiguration()
if schema:
config.schema_path = schema
for db in dbs:
try:
path = Path(db).absolute()
print(f'PATH={path}')
resource = OntologyResource(slug=f'sqlite:///{str(path)}')
impl = SqlImplementation(resource)
counts = defaultdict(int)
for result in impl.validate():
for result in impl.validate(configuration=config):
result.source = f'sqlite:{db}'
key = (result.type, result.predicate)
n = counts[key]
Expand Down
7 changes: 4 additions & 3 deletions src/oaklib/datamodels/lexical_index.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Auto generated from lexical_index.yaml by pythongen.py version: 0.9.0
# Generation date: 2022-03-31T09:17:44
# Schema: lexican-index
# Generation date: 2022-04-11T17:33:31
# Schema: lexical-index
#
# id: https://w3id.org/linkml/lexical_index
# description: A datamodel for representing a lexical index of an ontology
# description: A datamodel for representing a lexical index of an ontology. A lexical index is keyed by optionally
# normalized terms.
# license: https://creativecommons.org/publicdomain/zero/1.0/

import dataclasses
Expand Down
88 changes: 40 additions & 48 deletions src/oaklib/datamodels/ontology_metadata.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Auto generated from ontology_metadata.yaml by pythongen.py version: 0.9.0
# Generation date: 2022-04-10T13:59:10
# Generation date: 2022-04-11T17:33:26
# Schema: Ontology-Metadata
#
# id: http://purl.obolibrary.org/obo/omo/schema
Expand Down Expand Up @@ -373,8 +373,8 @@ class HasLifeCycle(AnnotationPropertyMixin):

deprecated: Optional[Union[bool, Bool]] = None
has_obsolescence_reason: Optional[str] = None
term_replaced_by: Optional[Union[dict, "Thing"]] = None
consider: Optional[Union[str, List[str]]] = empty_list()
term_replaced_by: Optional[Union[dict, Any]] = None
consider: Optional[Union[Union[dict, Any], List[Union[dict, Any]]]] = empty_list()
has_alternative_id: Optional[Union[Union[str, URIorCURIE], List[Union[str, URIorCURIE]]]] = empty_list()
excluded_from_QC_check: Optional[Union[dict, "Thing"]] = None
excluded_subClassOf: Optional[Union[Union[str, ClassId], List[Union[str, ClassId]]]] = empty_list()
Expand All @@ -388,13 +388,6 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):
if self.has_obsolescence_reason is not None and not isinstance(self.has_obsolescence_reason, str):
self.has_obsolescence_reason = str(self.has_obsolescence_reason)

if self.term_replaced_by is not None and not isinstance(self.term_replaced_by, Thing):
self.term_replaced_by = Thing(**as_dict(self.term_replaced_by))

if not isinstance(self.consider, list):
self.consider = [self.consider] if self.consider is not None else []
self.consider = [v if isinstance(v, str) else str(v) for v in self.consider]

if not isinstance(self.has_alternative_id, list):
self.has_alternative_id = [self.has_alternative_id] if self.has_alternative_id is not None else []
self.has_alternative_id = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.has_alternative_id]
Expand Down Expand Up @@ -642,8 +635,8 @@ class Term(NamedObject):
OBO_foundry_unique_label: Optional[Union[str, List[str]]] = empty_list()
deprecated: Optional[Union[bool, Bool]] = None
has_obsolescence_reason: Optional[str] = None
term_replaced_by: Optional[Union[dict, Thing]] = None
consider: Optional[Union[str, List[str]]] = empty_list()
term_replaced_by: Optional[Union[dict, Any]] = None
consider: Optional[Union[Union[dict, Any], List[Union[dict, Any]]]] = empty_list()
has_alternative_id: Optional[Union[Union[str, URIorCURIE], List[Union[str, URIorCURIE]]]] = empty_list()
excluded_from_QC_check: Optional[Union[dict, Thing]] = None
excluded_subClassOf: Optional[Union[Union[str, ClassId], List[Union[str, ClassId]]]] = empty_list()
Expand Down Expand Up @@ -725,13 +718,6 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):
if self.has_obsolescence_reason is not None and not isinstance(self.has_obsolescence_reason, str):
self.has_obsolescence_reason = str(self.has_obsolescence_reason)

if self.term_replaced_by is not None and not isinstance(self.term_replaced_by, Thing):
self.term_replaced_by = Thing(**as_dict(self.term_replaced_by))

if not isinstance(self.consider, list):
self.consider = [self.consider] if self.consider is not None else []
self.consider = [v if isinstance(v, str) else str(v) for v in self.consider]

if not isinstance(self.has_alternative_id, list):
self.has_alternative_id = [self.has_alternative_id] if self.has_alternative_id is not None else []
self.has_alternative_id = [v if isinstance(v, URIorCURIE) else URIorCURIE(v) for v in self.has_alternative_id]
Expand Down Expand Up @@ -894,8 +880,8 @@ class Class(Term):
closeMatch: Optional[Union[Union[str, ClassId], List[Union[str, ClassId]]]] = empty_list()
subClassOf: Optional[Union[Union[str, ClassId], List[Union[str, ClassId]]]] = empty_list()
disjointWith: Optional[Union[str, List[str]]] = empty_list()
equivalentClass: Optional[Union[str, List[str]]] = empty_list()
intersectionOf: Optional[str] = None
equivalentClass: Optional[Union[Union[dict, "ClassExpression"], List[Union[dict, "ClassExpression"]]]] = empty_list()
intersectionOf: Optional[Union[dict, "ClassExpression"]] = None
cardinality: Optional[str] = None
complementOf: Optional[str] = None
oneOf: Optional[Union[dict, "ClassExpression"]] = None
Expand Down Expand Up @@ -952,10 +938,10 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):

if not isinstance(self.equivalentClass, list):
self.equivalentClass = [self.equivalentClass] if self.equivalentClass is not None else []
self.equivalentClass = [v if isinstance(v, str) else str(v) for v in self.equivalentClass]
self.equivalentClass = [v if isinstance(v, ClassExpression) else ClassExpression(**as_dict(v)) for v in self.equivalentClass]

if self.intersectionOf is not None and not isinstance(self.intersectionOf, str):
self.intersectionOf = str(self.intersectionOf)
if self.intersectionOf is not None and not isinstance(self.intersectionOf, ClassExpression):
self.intersectionOf = ClassExpression(**as_dict(self.intersectionOf))

if self.cardinality is not None and not isinstance(self.cardinality, str):
self.cardinality = str(self.cardinality)
Expand Down Expand Up @@ -1078,8 +1064,8 @@ class ObjectProperty(Property):
is_cyclic: Optional[Union[bool, Bool]] = None
is_transitive: Optional[Union[bool, Bool]] = None
shorthand: Optional[Union[str, List[str]]] = empty_list()
equivalentProperty: Optional[Union[Union[dict, Thing], List[Union[dict, Thing]]]] = empty_list()
inverseOf: Optional[str] = None
equivalentProperty: Optional[Union[Union[str, PropertyId], List[Union[str, PropertyId]]]] = empty_list()
inverseOf: Optional[Union[str, PropertyId]] = None
propertyChainAxiom: Optional[Union[str, List[str]]] = empty_list()
disjointWith: Optional[Union[str, List[str]]] = empty_list()

Expand All @@ -1104,10 +1090,10 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):

if not isinstance(self.equivalentProperty, list):
self.equivalentProperty = [self.equivalentProperty] if self.equivalentProperty is not None else []
self.equivalentProperty = [v if isinstance(v, Thing) else Thing(**as_dict(v)) for v in self.equivalentProperty]
self.equivalentProperty = [v if isinstance(v, PropertyId) else PropertyId(v) for v in self.equivalentProperty]

if self.inverseOf is not None and not isinstance(self.inverseOf, str):
self.inverseOf = str(self.inverseOf)
if self.inverseOf is not None and not isinstance(self.inverseOf, PropertyId):
self.inverseOf = PropertyId(self.inverseOf)

if not isinstance(self.propertyChainAxiom, list):
self.propertyChainAxiom = [self.propertyChainAxiom] if self.propertyChainAxiom is not None else []
Expand Down Expand Up @@ -1316,8 +1302,8 @@ class Restriction(AnonymousClassExpression):
someValuesFrom: Optional[Union[str, List[str]]] = empty_list()
allValuesFrom: Optional[str] = None
disjointWith: Optional[Union[str, List[str]]] = empty_list()
equivalentClass: Optional[Union[str, List[str]]] = empty_list()
intersectionOf: Optional[str] = None
equivalentClass: Optional[Union[Union[dict, "ClassExpression"], List[Union[dict, "ClassExpression"]]]] = empty_list()
intersectionOf: Optional[Union[dict, "ClassExpression"]] = None
subClassOf: Optional[Union[Union[dict, "ClassExpression"], List[Union[dict, "ClassExpression"]]]] = empty_list()
cardinality: Optional[str] = None
complementOf: Optional[str] = None
Expand All @@ -1342,10 +1328,10 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):

if not isinstance(self.equivalentClass, list):
self.equivalentClass = [self.equivalentClass] if self.equivalentClass is not None else []
self.equivalentClass = [v if isinstance(v, str) else str(v) for v in self.equivalentClass]
self.equivalentClass = [v if isinstance(v, ClassExpression) else ClassExpression(**as_dict(v)) for v in self.equivalentClass]

if self.intersectionOf is not None and not isinstance(self.intersectionOf, str):
self.intersectionOf = str(self.intersectionOf)
if self.intersectionOf is not None and not isinstance(self.intersectionOf, ClassExpression):
self.intersectionOf = ClassExpression(**as_dict(self.intersectionOf))

if not isinstance(self.subClassOf, list):
self.subClassOf = [self.subClassOf] if self.subClassOf is not None else []
Expand Down Expand Up @@ -1385,8 +1371,8 @@ class ClassExpression(Expression):
class_model_uri: ClassVar[URIRef] = OMOSCHEMA.ClassExpression

disjointWith: Optional[Union[str, List[str]]] = empty_list()
equivalentClass: Optional[Union[str, List[str]]] = empty_list()
intersectionOf: Optional[str] = None
equivalentClass: Optional[Union[Union[dict, "ClassExpression"], List[Union[dict, "ClassExpression"]]]] = empty_list()
intersectionOf: Optional[Union[dict, "ClassExpression"]] = None
subClassOf: Optional[Union[Union[dict, "ClassExpression"], List[Union[dict, "ClassExpression"]]]] = empty_list()
cardinality: Optional[str] = None
complementOf: Optional[str] = None
Expand All @@ -1400,10 +1386,10 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):

if not isinstance(self.equivalentClass, list):
self.equivalentClass = [self.equivalentClass] if self.equivalentClass is not None else []
self.equivalentClass = [v if isinstance(v, str) else str(v) for v in self.equivalentClass]
self.equivalentClass = [v if isinstance(v, ClassExpression) else ClassExpression(**as_dict(v)) for v in self.equivalentClass]

if self.intersectionOf is not None and not isinstance(self.intersectionOf, str):
self.intersectionOf = str(self.intersectionOf)
if self.intersectionOf is not None and not isinstance(self.intersectionOf, ClassExpression):
self.intersectionOf = ClassExpression(**as_dict(self.intersectionOf))

if not isinstance(self.subClassOf, list):
self.subClassOf = [self.subClassOf] if self.subClassOf is not None else []
Expand Down Expand Up @@ -1445,6 +1431,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):

@dataclass
class ObsoleteAspect(YAMLRoot):
"""
Auto-classifies anything that is obsolete
"""
_inherited_slots: ClassVar[List[str]] = []

class_class_uri: ClassVar[URIRef] = OMOSCHEMA.ObsoleteAspect
Expand All @@ -1462,6 +1451,9 @@ def __post_init__(self, *_: List[str], **kwargs: Dict[str, Any]):


class NotObsoleteAspect(YAMLRoot):
"""
Auto-classifies anything that is not obsolete
"""
_inherited_slots: ClassVar[List[str]] = []

class_class_uri: ClassVar[URIRef] = OMOSCHEMA.NotObsoleteAspect
Expand Down Expand Up @@ -1568,13 +1560,13 @@ class slots:
model_uri=OMOSCHEMA.deprecated, domain=None, range=Optional[Union[bool, Bool]])

slots.term_replaced_by = Slot(uri=IAO['0100001'], name="term_replaced_by", curie=IAO.curie('0100001'),
model_uri=OMOSCHEMA.term_replaced_by, domain=None, range=Optional[Union[dict, Thing]])
model_uri=OMOSCHEMA.term_replaced_by, domain=None, range=Optional[Union[dict, Any]])

slots.has_obsolescence_reason = Slot(uri=IAO['0000231'], name="has_obsolescence_reason", curie=IAO.curie('0000231'),
model_uri=OMOSCHEMA.has_obsolescence_reason, domain=None, range=Optional[str])

slots.consider = Slot(uri=OIO.consider, name="consider", curie=OIO.curie('consider'),
model_uri=OMOSCHEMA.consider, domain=None, range=Optional[Union[str, List[str]]])
model_uri=OMOSCHEMA.consider, domain=None, range=Optional[Union[Union[dict, Any], List[Union[dict, Any]]]])

slots.has_alternative_id = Slot(uri=OIO.hasAlternativeId, name="has_alternative_id", curie=OIO.curie('hasAlternativeId'),
model_uri=OMOSCHEMA.has_alternative_id, domain=None, range=Optional[Union[Union[str, URIorCURIE], List[Union[str, URIorCURIE]]]])
Expand Down Expand Up @@ -1736,25 +1728,25 @@ class slots:
model_uri=OMOSCHEMA.distinctMembers, domain=None, range=Optional[Union[dict, Thing]])

slots.equivalentClass = Slot(uri=OWL.equivalentClass, name="equivalentClass", curie=OWL.curie('equivalentClass'),
model_uri=OMOSCHEMA.equivalentClass, domain=None, range=Optional[Union[str, List[str]]])
model_uri=OMOSCHEMA.equivalentClass, domain=None, range=Optional[Union[Union[dict, ClassExpression], List[Union[dict, ClassExpression]]]])

slots.sameAs = Slot(uri=OWL.sameAs, name="sameAs", curie=OWL.curie('sameAs'),
model_uri=OMOSCHEMA.sameAs, domain=None, range=Optional[Union[str, List[str]]])
model_uri=OMOSCHEMA.sameAs, domain=None, range=Optional[Union[Union[dict, Thing], List[Union[dict, Thing]]]])

slots.equivalentProperty = Slot(uri=OWL.equivalentProperty, name="equivalentProperty", curie=OWL.curie('equivalentProperty'),
model_uri=OMOSCHEMA.equivalentProperty, domain=None, range=Optional[Union[Union[dict, Thing], List[Union[dict, Thing]]]])
model_uri=OMOSCHEMA.equivalentProperty, domain=None, range=Optional[Union[Union[str, PropertyId], List[Union[str, PropertyId]]]])

slots.hasValue = Slot(uri=OWL.hasValue, name="hasValue", curie=OWL.curie('hasValue'),
model_uri=OMOSCHEMA.hasValue, domain=None, range=Optional[str])
model_uri=OMOSCHEMA.hasValue, domain=None, range=Optional[Union[dict, Any]])

slots.intersectionOf = Slot(uri=OWL.intersectionOf, name="intersectionOf", curie=OWL.curie('intersectionOf'),
model_uri=OMOSCHEMA.intersectionOf, domain=None, range=Optional[str])
model_uri=OMOSCHEMA.intersectionOf, domain=None, range=Optional[Union[dict, ClassExpression]])

slots.inverseOf = Slot(uri=OWL.inverseOf, name="inverseOf", curie=OWL.curie('inverseOf'),
model_uri=OMOSCHEMA.inverseOf, domain=None, range=Optional[str])
model_uri=OMOSCHEMA.inverseOf, domain=None, range=Optional[Union[str, PropertyId]])

slots.maxQualifiedCardinality = Slot(uri=OWL.maxQualifiedCardinality, name="maxQualifiedCardinality", curie=OWL.curie('maxQualifiedCardinality'),
model_uri=OMOSCHEMA.maxQualifiedCardinality, domain=None, range=Optional[str])
model_uri=OMOSCHEMA.maxQualifiedCardinality, domain=None, range=Optional[int])

slots.members = Slot(uri=OWL.members, name="members", curie=OWL.curie('members'),
model_uri=OMOSCHEMA.members, domain=None, range=Optional[Union[dict, Thing]])
Expand Down
8 changes: 7 additions & 1 deletion src/oaklib/datamodels/ontology_metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,7 @@ slots:
multivalued: true
todos:
- restrict range
range: ClassExpression
sameAs:
is_a: logical_predicate
mixins:
Expand All @@ -958,31 +959,36 @@ slots:
multivalued: true
todos:
- restrict range
range: Thing
equivalentProperty:
is_a: logical_predicate
mixins:
- match_aspect
slot_uri: owl:equivalentProperty
multivalued: true
range: Thing
range: Property
hasValue:
is_a: logical_predicate
slot_uri: owl:hasValue
todos:
- restrict range
range: Any
intersectionOf:
is_a: logical_predicate
slot_uri: owl:intersectionOf
todos:
- restrict range
range: ClassExpression
inverseOf:
is_a: logical_predicate
slot_uri: owl:inverseOf
todos:
- restrict range
range: Property
maxQualifiedCardinality:
is_a: logical_predicate
slot_uri: owl:maxQualifiedCardinality
range: integer
members:
is_a: logical_predicate
slot_uri: owl:members
Expand Down
Loading

0 comments on commit df31f74

Please sign in to comment.