Skip to content

Commit

Permalink
Merge pull request #36 from linkml/fix-uriref-in-tr-expression
Browse files Browse the repository at this point in the history
Adding test for tr function in templates
  • Loading branch information
cmungall authored Apr 4, 2023
2 parents cd19641 + 5646fd1 commit f5dbb74
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 75 deletions.
13 changes: 10 additions & 3 deletions linkml_owl/dumpers/owl_dumper.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
SubObjectPropertyOf, TransitiveObjectProperty, SymmetricObjectProperty, AsymmetricObjectProperty, \
ReflexiveObjectProperty, IrreflexiveObjectProperty, Annotation, ObjectMinCardinality, ObjectHasValue, \
NamedIndividual, DataSomeValuesFrom, DataHasValue, DataAllValuesFrom, AnnotationProperty, DataProperty, Datatype, \
DisjointClasses
DisjointClasses, DisjointUnion

from linkml_runtime.dumpers.dumper_root import Dumper
from linkml_runtime.utils.yamlutils import YAMLRoot
Expand Down Expand Up @@ -194,7 +194,7 @@ def transform(self, element: YAMLRoot, schema: SchemaDefinition, is_element_an_o
"""
Recursively transform a LinkML element
Each field is introspected, and translated to an OWL axiom.
Each field is introspected, and translated to an OWL axiom or expression.
The field value is recursively transformed
:param element:
Expand Down Expand Up @@ -461,6 +461,7 @@ def transform(self, element: YAMLRoot, schema: SchemaDefinition, is_element_an_o
for op_key, operands in eai.operand_list_index.items():
_, interp, operator = op_key
logging.debug(f'EntityAxiomIndex {subj}: {interp} => {operator} over {operands}')
# pre-process operands
if len(operands) == 0:
raise ValueError(f'Too few operands: {operands} for {operator} in {subj}')
if len(operands) == 1:
Expand All @@ -476,12 +477,15 @@ def transform(self, element: YAMLRoot, schema: SchemaDefinition, is_element_an_o
expr = ObjectIntersectionOf(*operands)
else:
raise ValueError(f'Cannot handle operator: {operator}')
# interpret as axiom
if interp == EquivalentClasses.__name__:
axiom = EquivalentClasses(subj, expr)
elif interp == SubClassOf.__name__:
axiom = SubClassOf(subj, expr)
elif interp == DisjointClasses.__name__:
axiom = DisjointClasses(subj, expr)
elif interp == DisjointUnion.__name__:
axiom = DisjointUnion(operands[0], operands[1:])
else:
raise ValueError(f'Not handled: {interp}')
logging.debug(f'Adding axiom: {axiom}')
Expand Down Expand Up @@ -698,7 +702,10 @@ def tr(e: YAMLRoot):
def _tr(x):
fw = FunctionalWriter()
expr = self.transform(x, schema)
return expr.to_functional(fw)
if isinstance(expr, URIRef):
return str(expr)
else:
return expr.to_functional(fw)
d["tr"] = _tr
owl_str = jt.render(**d)
axioms = self.parse_axioms_string(owl_str).ontology.axioms
Expand Down
68 changes: 59 additions & 9 deletions tests/inputs/owl_dumper_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ slots:
range: NamedThing
multivalued: true
description: named class this is subclass of
subclass_of_anon:
slot_uri: rdfs:subclass_of
range: AnonPartOf
multivalued: true
inlined: true
inlined_as_list: true
operands:
range: NamedThing
multivalued: true
Expand Down Expand Up @@ -197,10 +203,10 @@ classes:
is_a: NamedThing
description: test metaclass illustrating classes with parents that are class expressions
slots:
- subclass_of
- subclass_of_anon
slot_usage:
subclass_of:
range: AnonPartOf
subclass_of_anon:
required: true
annotations:
owl: SubClassOf
DirectEquivalent:
Expand Down Expand Up @@ -246,7 +252,7 @@ classes:
operands:
required: true
annotations:
owl: DisjointUnionOf
owl: DisjointUnion
EquivIntersection:
is_a: NamedThing
description: test metaclass illustrating classes defined by a simple intersection of classes
Expand Down Expand Up @@ -323,7 +329,7 @@ classes:
annotations:
owl: EquivalentClasses, IntersectionOf
part_of:
required: true
required: false
description: the part-of differentiae
annotations:
owl: EquivalentClasses, IntersectionOf, ObjectSomeValuesFrom
Expand Down Expand Up @@ -458,20 +464,22 @@ classes:
range: NamedThing
multivalued: false
annotations:
owl: SomeValuesFrom
owl: SomeValuesFrom, ObjectProperty
count:
range: integer
minimum_value: 1
annotations:
owl: HasValue
owl: HasValue, DataProperty
state:
range: ActivationStateEnum
annotations:
owl: SomeValuesFrom
owl: SomeValuesFrom, ObjectProperty

CollectionOfPartsWithCounts:
is_a: NamedThing
description: test metaclass that illustrates a complex nested multi-part structure, where a whole is defined by a collection of repeared parts in specified states
description: >-
test metaclass that illustrates a complex nested multi-part structure,
where a whole is defined by a collection of repeated parts in specified states.
slots:
- has_part
slot_usage:
Expand All @@ -494,6 +502,48 @@ classes:
)
{% endfor %}
CollectionOfPartsWithCounts2:
is_a: NamedThing
description: >-
as CollectionOfPartsWithCounts but using tr function
slots:
- has_part
slot_usage:
has_part:
range: PartWithCounts2
inlined: true
annotations:
owl.template: |-
{% for p in has_part %}
SubClassOf( {{id}}
ObjectSomeValuesFrom( BFO:0000051
{{ tr(p) }}
)
)
{% endfor %}
PartWithCounts2:
is_a: Anonymous
description: test metaclass that generates anonymous classes used as part of a more complex class
attributes:
unit:
range: NamedThing
multivalued: false
annotations:
owl: ObjectSomeValuesFrom, ObjectProperty
count:
range: integer
minimum_value: 1
annotations:
owl: DataHasValue, DataProperty
state:
range: ActivationStateEnum
annotations:
owl: ObjectSomeValuesFrom, ObjectProperty
annotations:
owl: IntersectionOf

GCIPropagationMetapattern:
mixin: true
description: mixin for patterns that require GCI inference
Expand Down
108 changes: 54 additions & 54 deletions tests/output/chromo.schema.owl.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
chromoschema:GenomeBuild,
chromoschema:OrganismTaxon ;
dcterms:license "https://creativecommons.org/publicdomain/zero/1.0/" ;
linkml:generation_date "2023-03-21T13:21:57" ;
linkml:generation_date "2023-04-03T17:22:51" ;
linkml:metamodel_version "1.7.0" ;
linkml:source_file "chromo.yaml" ;
linkml:source_file_date "2022-01-12T21:11:50" ;
Expand All @@ -44,14 +44,14 @@ chromoschema:ChromosomePartCollection a owl:Class,
linkml:ClassDefinition ;
rdfs:label "ChromosomePartCollection" ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom chromoschema:OrganismTaxon ;
owl:onProperty dcterms:hasPart ],
[ a owl:Restriction ;
owl:allValuesFrom chromoschema:ChromosomePart ;
owl:onProperty dcterms:hasPart ],
[ a owl:Restriction ;
owl:allValuesFrom chromoschema:Genome ;
owl:onProperty dcterms:hasPart ],
[ a owl:Restriction ;
owl:allValuesFrom chromoschema:OrganismTaxon ;
owl:onProperty dcterms:hasPart ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass linkml:String ;
Expand Down Expand Up @@ -206,24 +206,24 @@ chromoschema:Genome a owl:Class,
linkml:ClassDefinition ;
rdfs:label "Genome" ;
rdfs:subClassOf [ a owl:Restriction ;
owl:allValuesFrom chromoschema:GenomeBuild ;
owl:onProperty chromoschema:previous_builds ],
[ a owl:Restriction ;
owl:onClass linkml:String ;
owl:onProperty chromoschema:id ;
owl:qualifiedCardinality 1 ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:GenomeBuild ;
owl:onProperty biolink:genome_build ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:TaxonIdentifier ;
owl:onProperty RO:0002162 ],
[ a owl:Restriction ;
owl:allValuesFrom chromoschema:GenomeBuild ;
owl:onProperty chromoschema:previous_builds ],
[ a owl:Restriction ;
owl:onClass chromoschema:LabelType ;
owl:onProperty rdfs:label ;
owl:qualifiedCardinality 1 ],
[ a owl:Restriction ;
owl:onClass linkml:String ;
owl:onProperty chromoschema:id ;
owl:qualifiedCardinality 1 ] ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:TaxonIdentifier ;
owl:onProperty RO:0002162 ] ;
skos:definition """Represents a sequenced genome, one per species.
Each genome can be associated with one or more builds""" .

Expand All @@ -233,15 +233,15 @@ chromoschema:OrganismTaxon a owl:Class,
rdfs:subClassOf [ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:LabelType ;
owl:onProperty rdfs:label ],
owl:onProperty OIO:hasExactSynonym ],
[ a owl:Restriction ;
owl:onClass linkml:String ;
owl:onProperty chromoschema:id ;
owl:qualifiedCardinality 1 ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:LabelType ;
owl:onProperty OIO:hasExactSynonym ] ;
owl:onProperty rdfs:label ] ;
skos:definition "Represents a species, e.g. Homo sapiens" ;
skos:exactMatch biolink:OrganismTaxon .

Expand Down Expand Up @@ -323,69 +323,69 @@ chromoschema:ChromosomePart a owl:Class,
linkml:ClassDefinition ;
rdfs:label "ChromosomePart" ;
rdfs:subClassOf [ a owl:Restriction ;
owl:onClass linkml:String ;
owl:onProperty chromoschema:id ;
owl:qualifiedCardinality 1 ],
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:BandDescriptor ;
owl:onProperty chromoschema:band_descriptor ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:LocationType ;
owl:onClass chromoschema:ChromosomePart ;
owl:onProperty BFO:0000050 ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:LabelType ;
owl:onProperty rdfs:label ],
owl:allValuesFrom linkml:String ;
owl:onProperty OIO:hasExactSynonym ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:ChromosomeNameType ;
owl:onProperty chromoschema:chromosome_name ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:BandDescriptor ;
owl:onProperty chromoschema:band_descriptor ],
[ a owl:Restriction ;
owl:allValuesFrom linkml:Uriorcurie ;
owl:onProperty skos:exactMatch ],
owl:onClass chromoschema:TaxonIdentifier ;
owl:onProperty RO:0002162 ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass linkml:Integer ;
owl:onProperty gff:start ],
[ a owl:Restriction ;
owl:allValuesFrom linkml:String ;
owl:onProperty OIO:hasExactSynonym ],
owl:onClass chromoschema:SexChromosomeType ;
owl:onProperty chromoschema:sex_chromosome_type ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:EntityType ;
owl:onProperty rdf:type ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass linkml:Integer ;
owl:onProperty gff:end ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:LabelType ;
owl:onProperty rdfs:label ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:GenomeBuild ;
owl:onProperty biolink:genome_build ],
[ a owl:Restriction ;
owl:allValuesFrom linkml:String ;
owl:onProperty OIO:hasBroadSynonym ],
owl:allValuesFrom chromoschema:ChromosomePart ;
owl:onProperty BFO:0000051 ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:ChromosomePart ;
owl:onProperty BFO:0000050 ],
owl:onClass chromoschema:AutosomeVsSexChromosome ;
owl:onProperty chromoschema:somal_type ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:SexChromosomeType ;
owl:onProperty chromoschema:sex_chromosome_type ],
owl:allValuesFrom linkml:String ;
owl:onProperty OIO:hasBroadSynonym ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:TaxonIdentifier ;
owl:onProperty RO:0002162 ],
[ a owl:Restriction ;
owl:allValuesFrom chromoschema:ChromosomePart ;
owl:onProperty BFO:0000051 ],
owl:onClass chromoschema:LocationType ;
owl:onProperty BFO:0000050 ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass linkml:Integer ;
owl:onProperty gff:end ],
owl:onProperty gff:start ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:AutosomeVsSexChromosome ;
owl:onProperty chromoschema:somal_type ] ;
owl:onClass linkml:String ;
owl:onProperty chromoschema:id ;
owl:qualifiedCardinality 1 ],
[ a owl:Restriction ;
owl:allValuesFrom linkml:Uriorcurie ;
owl:onProperty skos:exactMatch ] ;
skos:definition "A Chromosome or a part of a chromosome (includes whole chromosomes, arms, and bands)" ;
skos:note """OWL Notes: when translated to OWL, instances of this class will be treated as
OWL classes, with the superclass determined by the type field""",
Expand All @@ -401,13 +401,13 @@ chromoschema:GenomeBuild a owl:Class,
linkml:ClassDefinition ;
rdfs:label "GenomeBuild" ;
rdfs:subClassOf [ a owl:Restriction ;
owl:onClass linkml:String ;
owl:onProperty chromoschema:id ;
owl:qualifiedCardinality 1 ],
[ a owl:Restriction ;
owl:maxQualifiedCardinality 1 ;
owl:onClass chromoschema:LabelType ;
owl:onProperty rdfs:label ] ;
owl:onProperty rdfs:label ],
[ a owl:Restriction ;
owl:onClass linkml:String ;
owl:onProperty chromoschema:id ;
owl:qualifiedCardinality 1 ] ;
skos:closeMatch edam:operation_0525 ;
skos:definition "Represents a specific build of a sequenced genome" .

Expand Down
Loading

0 comments on commit f5dbb74

Please sign in to comment.