robot
robot copied to clipboard
Feature request: Add a parameter that enables merging multiple instances of the same axiom with different sets of axiom annotations
Derived from #1098
When terms are defined in two different inputs, the act of merging may lead to duplicate annotations. It would be nice to have a quick way of removing such duplicates when is clear that the annotation is indeed the same.
EDIT BY @matentzn
- [ ] Fold in docs from https://github.com/ontodev/robot/pull/1103 when fixing this
Sorry, I don't understand. It would be good to have some concrete examples.
- An OWL annotation such as
OBI:0000070 rdfs:label "assay".is an RDF triple where the predicate is an OWL Annotation Property. You should never see duplicates of these -- OWLAPI or any RDF library will merge them. - An OWL axiom annotation using reification
<OBI:0000070 rdfs:label "assay"> rdfs:comment "Comment".This is trickier, but I would not expect to see duplicates of these either. - From the context of #1098, the problem seems to be "duplicates" from --annotate-derived-from or --annotate-defined-by, but are they really duplicates or just more information than you want?
Test ontology:
Prefix(:=<http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12/>)
Prefix(owl:=<http://www.w3.org/2002/07/owl#>)
Prefix(rdf:=<http://www.w3.org/1999/02/22-rdf-syntax-ns#>)
Prefix(xml:=<http://www.w3.org/XML/1998/namespace>)
Prefix(xsd:=<http://www.w3.org/2001/XMLSchema#>)
Prefix(rdfs:=<http://www.w3.org/2000/01/rdf-schema#>)
Ontology(<http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12>
Declaration(Class(<http://purl.obolibrary.org/obo/TMP_A>))
Declaration(Class(<http://purl.obolibrary.org/obo/TMP_B>))
############################
# Classes
############################
# Class: <http://purl.obolibrary.org/obo/TMP_A> (B)
AnnotationAssertion(rdfs:label <http://purl.obolibrary.org/obo/TMP_A> "B"@en)
SubClassOf(Annotation(rdfs:comment "A") Annotation(owl:versionInfo "old") <http://purl.obolibrary.org/obo/TMP_A> <http://purl.obolibrary.org/obo/TMP_B>)
SubClassOf(Annotation(rdfs:comment "B") Annotation(owl:versionInfo "new") <http://purl.obolibrary.org/obo/TMP_A> <http://purl.obolibrary.org/obo/TMP_B>)
# Class: <http://purl.obolibrary.org/obo/TMP_B> (A)
AnnotationAssertion(rdfs:label <http://purl.obolibrary.org/obo/TMP_B> "A"@en)
)
Command:
robot merge -i axiom-annotations-merged.ofn --annotate-derived-from true -o test.ofn
Output:
codePrefix(:=<http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12#>)
Prefix(owl:=<http://www.w3.org/2002/07/owl#>)
Prefix(rdf:=<http://www.w3.org/1999/02/22-rdf-syntax-ns#>)
Prefix(xml:=<http://www.w3.org/XML/1998/namespace>)
Prefix(xsd:=<http://www.w3.org/2001/XMLSchema#>)
Prefix(rdfs:=<http://www.w3.org/2000/01/rdf-schema#>)
Ontology(<http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12>
Declaration(Annotation(<http://www.w3.org/ns/prov#wasDerivedFrom> <http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12>) Class(<http://purl.obolibrary.org/obo/TMP_A>))
Declaration(Annotation(<http://www.w3.org/ns/prov#wasDerivedFrom> <http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12>) Class(<http://purl.obolibrary.org/obo/TMP_B>))
Declaration(AnnotationProperty(<http://www.w3.org/ns/prov#wasDerivedFrom>))
############################
# Classes
############################
# Class: <http://purl.obolibrary.org/obo/TMP_A> (B)
AnnotationAssertion(Annotation(<http://www.w3.org/ns/prov#wasDerivedFrom> <http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12>) rdfs:label <http://purl.obolibrary.org/obo/TMP_A> "B"@en)
SubClassOf(Annotation(rdfs:comment "A") Annotation(owl:versionInfo "old") Annotation(<http://www.w3.org/ns/prov#wasDerivedFrom> <http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12>) <http://purl.obolibrary.org/obo/TMP_A> <http://purl.obolibrary.org/obo/TMP_B>)
SubClassOf(Annotation(rdfs:comment "B") Annotation(owl:versionInfo "new") Annotation(<http://www.w3.org/ns/prov#wasDerivedFrom> <http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12>) <http://purl.obolibrary.org/obo/TMP_A> <http://purl.obolibrary.org/obo/TMP_B>)
# Class: <http://purl.obolibrary.org/obo/TMP_B> (A)
AnnotationAssertion(Annotation(<http://www.w3.org/ns/prov#wasDerivedFrom> <http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12>) rdfs:label <http://purl.obolibrary.org/obo/TMP_B> "A"@en)
)
It would be somehow better if we could do instead with a nice parameter output:
codePrefix(:=<http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12#>)
Prefix(owl:=<http://www.w3.org/2002/07/owl#>)
Prefix(rdf:=<http://www.w3.org/1999/02/22-rdf-syntax-ns#>)
Prefix(xml:=<http://www.w3.org/XML/1998/namespace>)
Prefix(xsd:=<http://www.w3.org/2001/XMLSchema#>)
Prefix(rdfs:=<http://www.w3.org/2000/01/rdf-schema#>)
Ontology(<http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12>
Declaration(Annotation(<http://www.w3.org/ns/prov#wasDerivedFrom> <http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12>) Class(<http://purl.obolibrary.org/obo/TMP_A>))
Declaration(Annotation(<http://www.w3.org/ns/prov#wasDerivedFrom> <http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12>) Class(<http://purl.obolibrary.org/obo/TMP_B>))
Declaration(AnnotationProperty(<http://www.w3.org/ns/prov#wasDerivedFrom>))
############################
# Classes
############################
# Class: <http://purl.obolibrary.org/obo/TMP_A> (B)
AnnotationAssertion(Annotation(<http://www.w3.org/ns/prov#wasDerivedFrom> <http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12>) rdfs:label <http://purl.obolibrary.org/obo/TMP_A> "B"@en)
SubClassOf(Annotation(rdfs:comment "A") Annotation(owl:versionInfo "old") Annotation(rdfs:comment "B") Annotation(owl:versionInfo "new") Annotation(<http://www.w3.org/ns/prov#wasDerivedFrom> <http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12>) <http://purl.obolibrary.org/obo/TMP_A> <http://purl.obolibrary.org/obo/TMP_B>)
# Class: <http://purl.obolibrary.org/obo/TMP_B> (A)
AnnotationAssertion(Annotation(<http://www.w3.org/ns/prov#wasDerivedFrom> <http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12>) rdfs:label <http://purl.obolibrary.org/obo/TMP_B> "A"@en)
)
Is this just an artifact of the Manchester syntax renderer? Does it also happen in RDF/XML format?
I think this is part of the owl api object model, I.E will be reflected by all renderes. I know it does for OBO, OFN and RDF XML.
Does robot repair --merge-annotation-axioms true address this issue?
It's currently undocumented, so I didn't realize it was in the code already: https://github.com/ontodev/robot/blob/master/robot-core/src/main/java/org/obolibrary/robot/RepairOperation.java#L123
robot merge -i test.owl repair --merge-axiom-annotations true -o teste.owl
Unfortunately does not work, for two reasons:
- It is tied in with
repair, which I may or may not want to run. I just want to merge axiom annotations - In the test ontology provided in this issue here, it drops the axiom annotations for new reason I can understand
Resulting ontology of the above command, and the test in the third comment of this issue
<?xml version="1.0"?>
<rdf:RDF xmlns="http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12#"
xml:base="http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<owl:Ontology rdf:about="http://www.semanticweb.org/matentzn/ontologies/2023/1/untitled-ontology-12"/>
<!--
///////////////////////////////////////////////////////////////////////////////////////
//
// Classes
//
///////////////////////////////////////////////////////////////////////////////////////
-->
<!-- http://purl.obolibrary.org/obo/TMP_A -->
<owl:Class rdf:about="http://purl.obolibrary.org/obo/TMP_A">
<rdfs:label xml:lang="en">B</rdfs:label>
</owl:Class>
<!-- http://purl.obolibrary.org/obo/TMP_B -->
<owl:Class rdf:about="http://purl.obolibrary.org/obo/TMP_B">
<rdfs:label xml:lang="en">A</rdfs:label>
</owl:Class>
</rdf:RDF>