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

Allow arbitrary defined annotation properties as qualifier tags in OBO format #1099

Closed
wants to merge 5 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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions contract/src/test/java/org/obolibrary/oboformat/TagIRIsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.obolibrary.oboformat;

import org.junit.jupiter.api.Test;
import org.semanticweb.owlapi.api.test.baseclasses.TestBase;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.vocab.OWL2Datatype;

import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertTrue;

public class TagIRIsTest extends TestBase {

@Test
public void testTagIRIMapping() {
OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
OWLDataFactory factory = manager.getOWLDataFactory();
OWLAnnotationProperty definition = factory.getOWLAnnotationProperty(IRI.create("http://purl.obolibrary.org/obo/IAO_0000115"));
OWLAnnotationProperty oioCreatedBy = factory.getOWLAnnotationProperty(IRI.create("http://www.geneontology.org/formats/oboInOwl#created_by"));
OWLAnnotationProperty oioInventedBy = factory.getOWLAnnotationProperty(IRI.create("http://www.geneontology.org/formats/oboInOwl#invented_by"));
OWLAnnotationProperty source = factory.getOWLAnnotationProperty(IRI.create("http://purl.obolibrary.org/obo/MYONT_20"));
OWLOntology ont = loadOntology("obo/tag_iris.obo", manager);
Set<OWLAxiom> axioms = ont.getAxioms();
OWLClass term1 = factory.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/MYONT_1"));
OWLClass term2 = factory.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/MYONT_2"));
OWLClass term3 = factory.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/MYONT_3"));
OWLClass term4 = factory.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/MYONT_4"));
assertTrue(axioms.contains(
factory.getOWLAnnotationAssertionAxiom(definition, term1.getIRI(), factory.getOWLLiteral("Definition of term one.", OWL2Datatype.XSD_STRING),
Stream.of(
factory.getOWLAnnotation(factory.getRDFSComment(), factory.getOWLLiteral("Here is a sub-annotation.", OWL2Datatype.XSD_STRING)),
factory.getOWLAnnotation(factory.getRDFSSeeAlso(), factory.getOWLLiteral("A nested see also value.", OWL2Datatype.XSD_STRING)))
.collect(Collectors.toSet())
)));
assertTrue(axioms.contains(
factory.getOWLAnnotationAssertionAxiom(factory.getRDFSSeeAlso(), term1.getIRI(), factory.getOWLLiteral("See also value.", OWL2Datatype.XSD_STRING))));
assertTrue(axioms.contains(
factory.getOWLAnnotationAssertionAxiom(definition, term2.getIRI(), factory.getOWLLiteral("Definition of term two.", OWL2Datatype.XSD_STRING),
Collections.singleton(factory.getOWLAnnotation(source, factory.getOWLLiteral("A nested annotation value.", OWL2Datatype.XSD_STRING))))));
assertTrue(axioms.contains(
factory.getOWLAnnotationAssertionAxiom(definition, term3.getIRI(), factory.getOWLLiteral("Definition of term three.", OWL2Datatype.XSD_STRING),
Collections.singleton(factory.getOWLAnnotation(source, factory.getOWLLiteral("A definition source value.", OWL2Datatype.XSD_STRING))))));
assertTrue(axioms.contains(
factory.getOWLAnnotationAssertionAxiom(oioCreatedBy, term3.getIRI(), factory.getOWLLiteral("goc:bro", OWL2Datatype.XSD_STRING))), "created_by is built in and should not be overridden by a typedef");
assertTrue(axioms.contains(
factory.getOWLAnnotationAssertionAxiom(definition, term4.getIRI(), factory.getOWLLiteral("Definition of term four.", OWL2Datatype.XSD_STRING),
Collections.singleton(factory.getOWLAnnotation(oioInventedBy, factory.getOWLLiteral("An inventor value.", OWL2Datatype.XSD_STRING))))), "An undeclared tag should have oio namespace");

}
}
56 changes: 56 additions & 0 deletions contract/src/test/resources/obo/tag_iris.obo
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
format-version: 1.2
ontology: myont

[Term]
id: MYONT:1
name: term one
def: "Definition of term one." [] {comment="Here is a sub-annotation.", seeAlso="A nested see also value."}
property_value: seeAlso "See also value." xsd:string

[Term]
id: MYONT:2
name: term two
def: "Definition of term two." [] {MYONT:20="A nested annotation value."}
property_value: MYONT:21 "A top level annotation value." xsd:string

[Term]
id: MYONT:3
name: term three
def: "Definition of term three." [] {source="A definition source value."}
intersection_of: MYONT:2 ! term two
intersection_of: results_in_transport_across GO:0005739 ! mitochondrion
created_by: goc:bro

[Term]
id: MYONT:4
name: term four
def: "Definition of term four." [] {invented_by="An inventor value."}

[Typedef]
id: source
name: source
xref: MYONT:20
is_metadata_tag: true

[Typedef]
id: MYONT:21
name: source2
is_metadata_tag: true

[Typedef]
id: seeAlso
name: see also
xref: http://www.w3.org/2000/01/rdf-schema#seeAlso
is_metadata_tag: true

[Typedef]
id: results_in_transport_across
name: results in transport across
namespace: external
xref: RO:0002342

[Typedef]
id: created_by
name: created by
namespace: external
xref: http://purl.org/dc/terms/creator
37 changes: 31 additions & 6 deletions oboformat/src/main/java/org/obolibrary/obo2owl/OWLAPIObo2Owl.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.obolibrary.obo2owl;

import static org.obolibrary.obo2owl.Obo2OWLConstants.DEFAULT_IRI_PREFIX;
import static org.obolibrary.obo2owl.Obo2OWLConstants.OIOVOCAB_IRI_PREFIX;
import static org.semanticweb.owlapi.util.OWLAPIPreconditions.verifyNotNull;

import java.io.File;
Expand Down Expand Up @@ -1518,6 +1519,15 @@ public static IRI trTagToIRI(String tag) {
return iri;
}

@Nonnull
private IRI trTagToIRIIncludingTypedefs(String tag) {
IRI iri = ANNOTATIONPROPERTYMAP.get(tag);
if (iri == null) {
iri = oboIdToIRI(tag, true);
}
return iri;
}

/**
* Translate tag to annotation prop.
*
Expand All @@ -1526,7 +1536,7 @@ public static IRI trTagToIRI(String tag) {
*/
@Nonnull
protected OWLAnnotationProperty trTagToAnnotationProp(@Nonnull String tag) {
IRI iri = trTagToIRI(tag);
IRI iri = trTagToIRIIncludingTypedefs(tag);
OWLAnnotationProperty ap = fac.getOWLAnnotationProperty(iri);
if (!apToDeclare.contains(ap)) {
apToDeclare.add(ap);
Expand Down Expand Up @@ -1624,22 +1634,31 @@ protected OWLAnnotationValue trLiteral(@Nonnull Object inputValue) {
*/
@Nonnull
public IRI oboIdToIRI(@Nonnull String id) {
return oboIdToIRI(id, false);
}

private IRI oboIdToIRI(@Nonnull String id, boolean oboInOwlDefault) {
IRI iri = idToIRICache.get(id);
if (iri == null) {
iri = oboIdToIRI_load(id);
iri = oboIdToIRI_load(id, oboInOwlDefault);
idToIRICache.put(id, iri);
}
return iri;
}

@Nonnull
public IRI oboIdToIRI_load(@Nonnull String id) {
return oboIdToIRI_load(id, false);
}

/**
* Obo id to iri.
*
* @param id the id
* @return the iri
*/
@Nonnull
public IRI oboIdToIRI_load(@Nonnull String id) {
public IRI oboIdToIRI_load(@Nonnull String id, boolean oboInOwlDefault) {
if (id.contains(" ")) {
LOG.error("id contains space: \"{}\"", id);
throw new OWLParserException("spaces not allowed: '" + id + '\'');
Expand Down Expand Up @@ -1704,10 +1723,16 @@ public IRI oboIdToIRI_load(@Nonnull String id) {
// if(id.contains("_"))
// db += "_";
localId = idParts[0];// Unprefixed-ID

}
String uriPrefix = DEFAULT_IRI_PREFIX + db;
if (idSpaceMap.containsKey(db)) {
uriPrefix = idSpaceMap.get(db);
String uriPrefix;
if (oboInOwlDefault) {
uriPrefix = OIOVOCAB_IRI_PREFIX;
} else {
uriPrefix = DEFAULT_IRI_PREFIX + db;
if (idSpaceMap.containsKey(db)) {
uriPrefix = idSpaceMap.get(db);
}
}
String safeId;
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1869,6 +1869,8 @@ public static String owlObjectToTag(OWLObject obj) {
String prefix = Obo2OWLConstants.OIOVOCAB_IRI_PREFIX;
if (iri.startsWith(prefix)) {
tag = iri.substring(prefix.length());
} else {
tag = getIdentifier(iriObj);
}
}
return tag;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ public enum Obo2OWLVocabulary implements HasIRI {
/**IRI_IAO_0100001*/ IRI_IAO_0100001(DEFAULT_IRI_PREFIX, "IAO_0100001", "term replaced by", OboFormatTag.TAG_REPLACED_BY.getTag()),
/**IRI_OIO_shorthand*/ IRI_OIO_shorthand(OIOVOCAB_IRI_PREFIX, "shorthand", "shorthand", "shorthand"),
/**IRI_OIO_consider*/ IRI_OIO_consider(OIOVOCAB_IRI_PREFIX, "consider", "consider", OboFormatTag.TAG_CONSIDER.getTag()),
/**IRI_OIO_id*/ IRI_OIO_id(OIOVOCAB_IRI_PREFIX, "id", "id", OboFormatTag.TAG_ID.getTag()),
/**IRI_OIO_created_by*/ IRI_OIO_created_by(OIOVOCAB_IRI_PREFIX, "created_by", "created by", OboFormatTag.TAG_CREATED_BY.getTag()),
/**IRI_OIO_creation_date*/ IRI_OIO_creation_date(OIOVOCAB_IRI_PREFIX, "creation_date", "creation date", OboFormatTag.TAG_CREATION_DATE.getTag()),
/**IRI_OIO_hasOBOFormatVersion*/ IRI_OIO_hasOBOFormatVersion(OIOVOCAB_IRI_PREFIX, "hasOBOFormatVersion", "has_obo_format_version", OboFormatTag.TAG_FORMAT_VERSION.getTag()),
/**IRI_OIO_treatXrefsAsIsA*/ IRI_OIO_treatXrefsAsIsA(OIOVOCAB_IRI_PREFIX, "treat-xrefs-as-is_a", "treat-xrefs-as-is_a", OboFormatTag.TAG_TREAT_XREFS_AS_IS_A.getTag()),
/**IRI_OIO_treatXrefsAsHasSubClass*/ IRI_OIO_treatXrefsAsHasSubClass(OIOVOCAB_IRI_PREFIX, "treat-xrefs-as-has-subclass", "treat-xrefs-as-has-subclass", OboFormatTag.TAG_TREAT_XREFS_AS_HAS_SUBCLASS.getTag()),
Expand Down