Skip to content

Commit 1f4764d

Browse files
gouttegdignazio1977
authored andcommitted
Fix forced use of oboInOwl namespace when translating OBO IDs.
This commit rewrites part of the OWLAPIObo2Owl#oboIdToIRI_load() method so that the oboInOwlDefault parameter is only used when translating unprefixed IDs (where it instructs to create an IRI in the oboInOwl namespace instead of the ontology's default namespace). When translating a prefixed ID, the IRI to construct should always use the URL prefix dictated by the prefix. closes #1112 2nd commit message: Ensure longest namespace match is used. Disallow prefixes that are substrings of OBO namespace. 3rd commit message: If a prefix is declared in idspaces, don't use # separator for "non-canonical" ids. 4th commit message: Drop conflicting id annotations rather than stuff into owl-axioms header. 5th commit message: Corrected key comparison in OBOFormatPrefixManager. Exclude OBO IRIs from idspaces. 7th commit message: Don't inject default semweb prefixes into OBO document format. 8th commit message: Test prefixes aren't injected.
1 parent f3ed3a2 commit 1f4764d

File tree

9 files changed

+634
-74
lines changed

9 files changed

+634
-74
lines changed

api/src/main/java/org/semanticweb/owlapi/formats/OBODocumentFormat.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,12 @@
1414

1515
import javax.annotation.Nonnull;
1616

17-
import org.semanticweb.owlapi.model.OWLDocumentFormatImpl;
18-
1917
/**
2018
* @author Matthew Horridge, The University Of Manchester, Bio-Health
2119
* Informatics Group
2220
* @since 2.0.0
2321
*/
24-
public class OBODocumentFormat extends OWLDocumentFormatImpl {
22+
public class OBODocumentFormat extends PrefixDocumentFormatImpl {
2523

2624
/**
2725
* Key for validation parameter. Currently supports Boolean.TRUE and
@@ -30,6 +28,11 @@ public class OBODocumentFormat extends OWLDocumentFormatImpl {
3028
public static final String VALIDATION = "obo.validation";
3129
private static final long serialVersionUID = 40000L;
3230

31+
public OBODocumentFormat() {
32+
super();
33+
this.clear();
34+
}
35+
3336
@Nonnull
3437
@Override
3538
public String getKey() {
@@ -38,12 +41,11 @@ public String getKey() {
3841

3942
@Override
4043
public boolean isPrefixOWLOntologyFormat() {
41-
return false;
44+
return true;
4245
}
4346

4447
@Override
4548
public PrefixDocumentFormat asPrefixOWLOntologyFormat() {
46-
throw new UnsupportedOperationException(getClass().getName()
47-
+ " is not a PrefixDocumentFormat");
49+
return this;
4850
}
4951
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package org.obolibrary.oboformat;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.semanticweb.owlapi.api.test.baseclasses.TestBase;
5+
import org.semanticweb.owlapi.apibinding.OWLManager;
6+
import org.semanticweb.owlapi.formats.OBODocumentFormat;
7+
import org.semanticweb.owlapi.model.*;
8+
import org.semanticweb.owlapi.search.EntitySearcher;
9+
10+
import java.io.ByteArrayOutputStream;
11+
import java.io.IOException;
12+
import java.nio.charset.StandardCharsets;
13+
import java.util.Map;
14+
15+
import static org.junit.jupiter.api.Assertions.*;
16+
17+
public class PrefixesTest extends TestBase {
18+
19+
@Test
20+
void testPrefixesRoundtrip() throws OWLOntologyStorageException, IOException {
21+
OWLDataFactory factory = OWLManager.getOWLDataFactory();
22+
OWLAnnotationProperty termReplacedBy = factory.getOWLAnnotationProperty(IRI.create("http://purl.obolibrary.org/obo/IAO_0100001"));
23+
OWLAnnotationProperty consider = factory.getOWLAnnotationProperty(IRI.create("http://www.geneontology.org/formats/oboInOwl#consider"));
24+
OWLOntology oboOnt = loadOntology("obo/test_prefixes.obo", OWLManager.createOWLOntologyManager());
25+
assertTrue(oboOnt.containsClassInSignature(IRI.create("http://purl.obolibrary.org/obo/FOO_1234")));
26+
assertTrue(oboOnt.containsClassInSignature(IRI.create("http://somewhere.org/MyClass")));
27+
assertFalse(oboOnt.containsClassInSignature(IRI.create("https://example.org/myns/#ABC_123")));
28+
Map<String, String> prefixMap = oboOnt.getOWLOntologyManager().getOntologyFormat(oboOnt).asPrefixOWLOntologyFormat().getPrefixName2PrefixMap();
29+
assertEquals("http://somewhere.org/", prefixMap.get("sw:"));
30+
ByteArrayOutputStream stream = new ByteArrayOutputStream();
31+
oboOnt.getOWLOntologyManager().saveOntology(oboOnt, stream);
32+
stream.close();
33+
String roundtripOBO = new String(stream.toByteArray(), StandardCharsets.UTF_8);
34+
assertTrue(roundtripOBO.contains("idspace: sw http://somewhere.org/"));
35+
assertTrue(roundtripOBO.contains("[Term]\nid: FOO:1234\nis_a: sw:MyClass"));
36+
37+
OWLOntology replacementsOnt = loadOntology("obo/iris_for_obsoletes_replacements.obo", OWLManager.createOWLOntologyManager());
38+
assertTrue(EntitySearcher.getAnnotationAssertionAxioms(factory.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/GO_0000108")), replacementsOnt).stream()
39+
.filter(ax -> ax.getProperty().equals(termReplacedBy))
40+
.anyMatch(ax -> ax.getValue().asIRI().get().equals(IRI.create("http://purl.obolibrary.org/obo/GO_0000109"))),
41+
"Values for replaced_by should be IRIs rather than strings");
42+
assertTrue(EntitySearcher.getAnnotationAssertionAxioms(factory.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/GO_0000114")), replacementsOnt).stream()
43+
.filter(ax -> ax.getProperty().equals(consider))
44+
.anyMatch(ax -> ax.getValue().asIRI().get().equals(IRI.create("http://purl.obolibrary.org/obo/GO_0000083"))),
45+
"Values for consider should be IRIs rather than strings");
46+
assertTrue(EntitySearcher.getAnnotationAssertionAxioms(factory.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/GO_0010553")), replacementsOnt).stream()
47+
.filter(ax -> ax.getProperty().equals(termReplacedBy))
48+
.anyMatch(ax -> ax.getValue().asIRI().get().equals(IRI.create("http://purl.obolibrary.org/obo/GO_0000122"))),
49+
"Values for replaced_by on alt_ids should be IRIs");
50+
ByteArrayOutputStream stream2 = new ByteArrayOutputStream();
51+
replacementsOnt.getOWLOntologyManager().saveOntology(replacementsOnt, stream2);
52+
stream2.close();
53+
String roundtripReplacementsOnt = new String(stream2.toByteArray(), StandardCharsets.UTF_8);
54+
assertFalse(roundtripReplacementsOnt.contains("idspace:"));
55+
assertTrue(roundtripReplacementsOnt.contains("replaced_by: GO:0000109"));
56+
}
57+
58+
@Test
59+
void testHandlingOfDeclaredOBOPrefix() throws OWLOntologyStorageException, IOException, OWLOntologyCreationException {
60+
OWLOntology oboOnt = loadOntology("obo/test_obo_prefix.obo", OWLManager.createOWLOntologyManager());
61+
ByteArrayOutputStream stream = new ByteArrayOutputStream();
62+
oboOnt.getOWLOntologyManager().saveOntology(oboOnt, stream);
63+
stream.close();
64+
String roundtripOBO = new String(stream.toByteArray(), StandardCharsets.UTF_8);
65+
assertFalse(roundtripOBO.contains("obo:"));
66+
assertFalse(roundtripOBO.contains("obo "));
67+
assertFalse(roundtripOBO.contains("ex:MMyClass"), "The longest available namespace match should be used");
68+
assertFalse(roundtripOBO.contains("owl-axioms:"));
69+
}
70+
71+
@Test
72+
void testOBOFormatShouldNotInjectPrefixesInConstructedDocFormat() throws OWLOntologyStorageException, IOException {
73+
OWLOntology oboOnt = loadOntology("obo/test_obo_prefix.obo", OWLManager.createOWLOntologyManager());
74+
OWLOntologyManager manager = oboOnt.getOWLOntologyManager();
75+
ByteArrayOutputStream stream = new ByteArrayOutputStream();
76+
OWLDocumentFormat format = new OBODocumentFormat();
77+
String defaultNamespace = format.asPrefixOWLOntologyFormat().getDefaultPrefix();
78+
format.asPrefixOWLOntologyFormat().copyPrefixesFrom(manager.getOntologyFormat(oboOnt).asPrefixOWLOntologyFormat());
79+
format.asPrefixOWLOntologyFormat().setDefaultPrefix(defaultNamespace);
80+
manager.saveOntology(oboOnt, format, stream);
81+
stream.close();
82+
String roundtripOBO = new String(stream.toByteArray(), StandardCharsets.UTF_8);
83+
assertFalse(roundtripOBO.contains("idspace: rdf"));
84+
}
85+
86+
@Test
87+
void testOBOFormatShouldNotInjectPrefixesInLoadedDocFormat() throws OWLOntologyStorageException, IOException {
88+
OWLOntology oboOnt = loadOntology("obo/test_obo_prefix.obo", OWLManager.createOWLOntologyManager());
89+
OWLOntologyManager manager = oboOnt.getOWLOntologyManager();
90+
ByteArrayOutputStream stream = new ByteArrayOutputStream();
91+
OWLDocumentFormat format = manager.getOntologyFormat(oboOnt);
92+
format.asPrefixOWLOntologyFormat().copyPrefixesFrom(manager.getOntologyFormat(oboOnt).asPrefixOWLOntologyFormat());
93+
manager.saveOntology(oboOnt, format, stream);
94+
stream.close();
95+
String roundtripOBO = new String(stream.toByteArray(), StandardCharsets.UTF_8);
96+
assertFalse(roundtripOBO.contains("idspace: rdf"));
97+
}
98+
99+
@Test
100+
void testOBOFormatShouldPreventOBOPrefixes() throws OWLOntologyStorageException, IOException {
101+
OWLOntology oboOnt = loadOntology("obo/test_obo_prefix.obo", OWLManager.createOWLOntologyManager());
102+
OWLOntologyManager manager = oboOnt.getOWLOntologyManager();
103+
ByteArrayOutputStream stream = new ByteArrayOutputStream();
104+
OWLDocumentFormat format = manager.getOntologyFormat(oboOnt);
105+
format.asPrefixOWLOntologyFormat().setPrefix("GO", "http://purl.obolibrary.org/obo/GX_");
106+
manager.saveOntology(oboOnt, format, stream);
107+
stream.close();
108+
String roundtripOBO = new String(stream.toByteArray(), StandardCharsets.UTF_8);
109+
assertFalse(roundtripOBO.contains("idspace: GO"));
110+
}
111+
112+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
format-version: 1.2
2+
subsetdef: chebi_ph7_3 "Rhea list of ChEBI terms representing the major species at pH 7.3."
3+
subsetdef: gocheck_do_not_annotate "Term not to be used for direct annotation"
4+
subsetdef: gocheck_do_not_manually_annotate "Term not to be used for direct manual annotation"
5+
subsetdef: goslim_agr "AGR slim"
6+
subsetdef: goslim_aspergillus "Aspergillus GO slim"
7+
subsetdef: goslim_candida "Candida GO slim"
8+
subsetdef: goslim_chembl "ChEMBL protein targets summary"
9+
subsetdef: goslim_drosophila "Drosophila GO slim"
10+
subsetdef: goslim_flybase_ribbon "FlyBase Drosophila GO ribbon slim"
11+
subsetdef: goslim_generic "Generic GO slim"
12+
subsetdef: goslim_metagenomics "Metagenomics GO slim"
13+
subsetdef: goslim_mouse "Mouse GO slim"
14+
subsetdef: goslim_pir "PIR GO slim"
15+
subsetdef: goslim_plant "Plant GO slim"
16+
subsetdef: goslim_pombe "Fission yeast GO slim"
17+
subsetdef: goslim_synapse "synapse GO slim"
18+
subsetdef: goslim_yeast "Yeast GO slim"
19+
subsetdef: prokaryote_subset "GO subset for prokaryotes"
20+
synonymtypedef: syngo_official_label "label approved by the SynGO project"
21+
synonymtypedef: systematic_synonym "Systematic synonym" EXACT
22+
default-namespace: gene_ontology
23+
ontology: go
24+
property_value: has_ontology_root_term GO:0003674
25+
property_value: has_ontology_root_term GO:0005575
26+
property_value: has_ontology_root_term GO:0008150
27+
property_value: http://purl.org/dc/elements/1.1/description "The Gene Ontology (GO) provides a framework and set of concepts for describing the functions of gene products from all organisms." xsd:string
28+
property_value: http://purl.org/dc/elements/1.1/title "Gene Ontology" xsd:string
29+
property_value: http://purl.org/dc/terms/license http://creativecommons.org/licenses/by/4.0/
30+
31+
[Term]
32+
id: GO:0000108
33+
name: obsolete repairosome
34+
namespace: cellular_component
35+
def: "OBSOLETE. A stable complex of proteins that carry out the DNA damage recognition and incision reactions characteristic of nucleotide excision repair (NER), such as DNA damage recognition, DNA helix unwinding, and endonucleolytic cleavage at sites flanking damaged DNA; includes TFIIH subunits and additional polypeptides; may form in the absence of DNA damage." [PMID:10681587, PMID:9852079]
36+
comment: This term was made obsolete because 'repairosome' has fallen out of use in the literature, and the large complex described in the definition has not been confirmed to exist. The term has also confused annotators.
37+
synonym: "repairosome" EXACT []
38+
is_obsolete: true
39+
replaced_by: GO:0000109
40+
41+
[Term]
42+
id: GO:0000109
43+
name: nucleotide-excision repair complex
44+
namespace: cellular_component
45+
def: "Any complex formed of proteins that act in nucleotide-excision repair." [PMID:10915862]
46+
comment: Note that process information is included in the term and definition for the purpose of describing and distinguishing the complex.
47+
subset: goslim_pir
48+
synonym: "UvrB-UvrC complex" NARROW [PMID:12145219]
49+
synonym: "UvrBC complex" NARROW [GOC:bhm, PMID:12145219]
50+
is_a: GO:0032991 ! protein-containing complex
51+
intersection_of: GO:0032991 ! protein-containing complex
52+
intersection_of: capable_of_part_of GO:0006289 ! nucleotide-excision repair
53+
relationship: part_of GO:0005634 ! nucleus
54+
55+
[Term]
56+
id: GO:0000114
57+
name: obsolete regulation of transcription involved in G1 phase of mitotic cell cycle
58+
namespace: biological_process
59+
def: "OBSOLETE. Any process that regulates transcription such that the target genes are transcribed as part of the G1 phase of the mitotic cell cycle." [GOC:dph, GOC:mah, GOC:tb]
60+
comment: This term was made obsolete because it is unclear exactly what it means. It could mean either 'regulation of transcription during phase X' or 'regulation of transition between phase X and phase Y'.
61+
synonym: "G1-specific transcription in mitotic cell cycle" RELATED []
62+
synonym: "regulation of transcription from RNA polymerase II promoter during G1 phase of cell cycle" EXACT []
63+
synonym: "regulation of transcription involved in G1 phase of mitotic cell cycle" EXACT []
64+
is_obsolete: true
65+
consider: GO:0000083
66+
consider: GO:0006357
67+
68+
[Term]
69+
id: GO:0000122
70+
name: negative regulation of transcription by RNA polymerase II
71+
namespace: biological_process
72+
alt_id: GO:0010553
73+
alt_id: GO:0045816
74+
def: "Any process that stops, prevents, or reduces the frequency, rate or extent of transcription mediated by RNA polymerase II." [GOC:go_curators, GOC:txnOH]
75+
synonym: "down regulation of global transcription from RNA polymerase II promoter" RELATED []
76+
synonym: "down regulation of transcription from RNA polymerase II promoter" EXACT []
77+
synonym: "down-regulation of global transcription from RNA polymerase II promoter" RELATED []
78+
synonym: "down-regulation of transcription from RNA polymerase II promoter" EXACT []
79+
synonym: "downregulation of global transcription from RNA polymerase II promoter" RELATED []
80+
synonym: "downregulation of transcription from RNA polymerase II promoter" EXACT []
81+
synonym: "inhibition of global transcription from RNA polymerase II promoter" RELATED []
82+
synonym: "inhibition of transcription from RNA polymerase II promoter" EXACT []
83+
synonym: "negative regulation of gene-specific transcription from RNA polymerase II promoter" RELATED []
84+
synonym: "negative regulation of global transcription from Pol II promoter" RELATED []
85+
synonym: "negative regulation of transcription from Pol II promoter" EXACT []
86+
synonym: "negative regulation of transcription from RNA polymerase II promoter" EXACT []
87+
synonym: "negative regulation of transcription from RNA polymerase II promoter, global" RELATED []
88+
intersection_of: GO:0065007 ! biological regulation
89+
intersection_of: negatively_regulates GO:0006366 ! transcription by RNA polymerase II
90+
91+
[Typedef]
92+
id: capable_of_part_of
93+
name: capable of part of
94+
namespace: external
95+
xref: RO:0002216
96+
97+
[Typedef]
98+
id: negatively_regulates
99+
name: negatively regulates
100+
namespace: external
101+
xref: RO:0002212
102+
is_a: regulates ! regulates
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
format-version: 1.2
2+
idspace: ex http://example.org/
3+
idspace: ex1 http://example.org/M
4+
idspace: obo http://purl.obolibrary.org/obo/
5+
ontology: foo
6+
7+
[Term]
8+
id: FOO:1234
9+
name: the 1234 class
10+
def: "A very important concept."
11+
is_a: ex:MyClass
12+
13+
[Term]
14+
id: ex:MyClass
15+
name: my ex class
16+
17+
[Term]
18+
id: ex1:MyClass
19+
name: my ex1 class
20+
relationship: capable_of_part_of FOO:1234
21+
22+
[Typedef]
23+
id: capable_of_part_of
24+
name: capable of part of
25+
xref: RO:0002216
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
format-version: 1.2
2+
idspace: owl http://www.w3.org/2002/07/owl#
3+
idspace: rdf http://www.w3.org/1999/02/22-rdf-syntax-ns#
4+
idspace: rdfs http://www.w3.org/2000/01/rdf-schema#
5+
idspace: sw http://somewhere.org/
6+
idspace: xml http://www.w3.org/XML/1998/namespace
7+
idspace: xsd http://www.w3.org/2001/XMLSchema#
8+
ontology: foo
9+
10+
[Term]
11+
id: FOO:1234
12+
is_a: sw:MyClass

0 commit comments

Comments
 (0)