Skip to content

Commit

Permalink
Merge pull request #404 from geneontology/issue-396
Browse files Browse the repository at this point in the history
Don't create root MF annotation when root BP annotation is present
  • Loading branch information
balhoff committed Aug 7, 2021
2 parents 34a131e + 541e141 commit 01cf67b
Show file tree
Hide file tree
Showing 3 changed files with 353 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public String exportGPAD(WorkingMemory wm, IRI modelIRI) throws InconsistentOnto
Set<GPADData> annotations = getGPAD(wm, modelIRI);
return new GPADRenderer(curieHandler, relationShorthandIndex).renderAll(annotations);
}

/* This is a bit convoluted in order to minimize redundant queries, for performance reasons. */
public Set<GPADData> getGPAD(WorkingMemory wm, IRI modelIRI) throws InconsistentOntologyException {
Model model = ModelFactory.createDefaultModel();
Expand All @@ -123,25 +123,25 @@ public Set<GPADData> getGPAD(WorkingMemory wm, IRI modelIRI) throws Inconsistent
//String modelID = model.listResourcesWithProperty(RDF.type, OWL.Ontology).mapWith(r -> curieHandler.getCuri(IRI.create(r.getURI()))).next();
String modelID = curieHandler.getCuri(modelIRI);
ResultSet results = qe.execSelect();
Set<BasicGPADData> basicAnnotations = new HashSet<>();
Set<BasicGPADData> basicAnnotations = new HashSet<>();
while (results.hasNext()) {
QuerySolution qs = results.next();
BasicGPADData basicGPADData = new BasicGPADData(qs.getResource("pr").asNode(), IRI.create(qs.getResource("pr_type").getURI()), IRI.create(qs.getResource("rel").getURI()), qs.getResource("target").asNode(), IRI.create(qs.getResource("target_type").getURI()));
BasicGPADData basicGPADData = new BasicGPADData(qs.getResource("pr").asNode(), IRI.create(qs.getResource("pr_type").getURI()), IRI.create(qs.getResource("rel").getURI()), qs.getResource("target").asNode(), IRI.create(qs.getResource("target_type").getURI()));

/* See whether the query answer contains not-null blank nodes, which are only set if the matching subgraph
* contains the property ComplementOf. If we see such cases, we set the operator field as NOT so that NOT value
* can be printed in GPAD. */
/* See whether the query answer contains not-null blank nodes, which are only set if the matching subgraph
* contains the property ComplementOf. If we see such cases, we set the operator field as NOT so that NOT value
* can be printed in GPAD. */
if (qs.getResource("blank_comp") != null) basicGPADData.setOperator(GPADOperatorStatus.NOT);
basicAnnotations.add(basicGPADData);
}
qe.close();

/* The bindings of ?pr_type, ?rel, ?target_type are candidate mappings or values for the final GPAD records
/* The bindings of ?pr_type, ?rel, ?target_type are candidate mappings or values for the final GPAD records
* (i.e. not every mapping is used for building the final records of GPAD file; many of them are filtered out later).
* The mappings are
* ?pr_type: DB Object ID (2nd in GPAD), ?rel: Qualifier(3rd), ?target_type: GO ID(4th)
* The mappings are
* ?pr_type: DB Object ID (2nd in GPAD), ?rel: Qualifier(3rd), ?target_type: GO ID(4th)
* The rest of fields in GPAD are then constructed by joining the candidate mappings with mappings describing evidences and so on.
* If the output of this exporter (i.e. GPAD files) does not contain the values you expect,
* If the output of this exporter (i.e. GPAD files) does not contain the values you expect,
* dump the above "QuerySolution qs" variable and see whether they are included in the dump. */
Set<AnnotationExtension> possibleExtensions = possibleExtensions(basicAnnotations, model);
Set<Triple> statementsToExplain = new HashSet<>();
Expand All @@ -165,7 +165,7 @@ public Set<GPADData> getGPAD(WorkingMemory wm, IRI modelIRI) throws Inconsistent
for (AnnotationExtension extension : possibleExtensions) {
if (extension.getTriple().getSubject().equals(annotation.getOntologyClassNode()) && !(extension.getTriple().getObject().equals(annotation.getObjectNode()))) {
for (Explanation expl : allExplanations.get(extension.getTriple())) {
boolean allFactsOfExplanationHaveRefMatchingAnnotation = toJava(expl.facts()).stream().map(fact -> allEvidences.getOrDefault(Bridge.jenaFromTriple(fact), Collections.emptySet())).allMatch(evidenceSet ->
boolean allFactsOfExplanationHaveRefMatchingAnnotation = toJava(expl.facts()).stream().map(fact -> allEvidences.getOrDefault(Bridge.jenaFromTriple(fact), Collections.emptySet())).allMatch(evidenceSet ->
evidenceSet.stream().anyMatch(ev -> ev.getReference().equals(reference)));
if (allFactsOfExplanationHaveRefMatchingAnnotation) {
goodExtensions.add(new DefaultConjunctiveExpression(IRI.create(extension.getTriple().getPredicate().getURI()), extension.getValueType()));
Expand Down Expand Up @@ -196,7 +196,15 @@ public Set<GPADData> getGPAD(WorkingMemory wm, IRI modelIRI) throws Inconsistent
}
}
}
return annotations;
Set<IRI> gpsWithRootBPAnnotation = annotations.stream()
.filter(a -> a.getOntologyClass().toString().equals(BP))
.map(GPADData::getObject)
.collect(Collectors.toSet());
// Don't output root MF annotations if there is also a root BP annotation
Set<GPADData> filteredAnnotations = annotations.stream()
.filter(a -> !(a.getOntologyClass().toString().equals(MF) && gpsWithRootBPAnnotation.contains(a.getObject())))
.collect(Collectors.toSet());
return filteredAnnotations;
}

private Map<String, String> getModelAnnotations(Model model) {
Expand All @@ -219,17 +227,17 @@ private Map<String, String> getModelAnnotations(Model model) {
}

/**
* Given a set of triples extracted/generated from the result/answer of query gpad-basic.rq, we find matching evidence subgraphs.
* Given a set of triples extracted/generated from the result/answer of query gpad-basic.rq, we find matching evidence subgraphs.
* In other words, if there are no matching evidence (i.e. no bindings for evidence_type), we discard (basic) GPAD instance.
*
* The parameter "facts" consists of triples <?subject, ?predicate, ?object> constructed from a binding of ?pr, ?rel, ?target in gpad_basic.rq.
*
* The parameter "facts" consists of triples <?subject, ?predicate, ?object> constructed from a binding of ?pr, ?rel, ?target in gpad_basic.rq.
* (The codes that constructing these triples are executed right before this method is called).
*
*
* These triples are then decomposed into values used as the parameters/bindings for objects of the following patterns.
* ?axiom owl:annotatedSource ?subject (i.e. ?pr in gpad_basic.rq)
* ?axiom owl:annotatedProperty ?predicate (i.e., ?rel in gpad_basic.rq, which denotes qualifier in GPAD)
* ?axiom owl:annotatedSource ?subject (i.e. ?pr in gpad_basic.rq)
* ?axiom owl:annotatedProperty ?predicate (i.e., ?rel in gpad_basic.rq, which denotes qualifier in GPAD)
* ?axiom owl:annotatedTarget ?object (i.e., ?target in gpad_basic.rq)
*
*
* If we find the bindings of ?axioms and the values of these bindings have some rdf:type triples, we proceed. (If not, we discard).
* The bindings of the query gpad-relation-evidence-multiple.rq are then used for filling up fields in GPAD records/tuples.
*/
Expand Down Expand Up @@ -339,11 +347,11 @@ private boolean isConsistent(Model model) {
ResultSet result = qe.execSelect();
while (result.hasNext()) {
QuerySolution qs = result.next();
Resource bad = qs.getResource("s");
Resource bad = qs.getResource("s");
LOG.info("owl nothing instance: "+bad.getURI());
}
}

return !inconsistent;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,17 @@ public void testGPADOutputWithNegation() throws Exception {
}
}
}

@Test
public void testFilterRootMFWhenRootBP() throws Exception {
Model model = ModelFactory.createDefaultModel();
model.read(this.getClass().getResourceAsStream("/test_root_mf_filter.ttl"), "", "ttl");
Set<Triple> triples = model.listStatements().toList().stream().map(s -> Bridge.tripleFromJena(s.asTriple())).collect(Collectors.toSet());
WorkingMemory mem = arachne.processTriples(JavaConverters.asScalaSetConverter(triples).asScala());
Set<GPADData> annotations = exporter.getGPAD(mem, IRI.create("http://test.org"));
IRI gene = IRI.create("http://identifiers.org/mgi/MGI:2153470");
IRI rootMF = IRI.create("http://purl.obolibrary.org/obo/GO_0003674");
Assert.assertTrue(annotations.stream().noneMatch(a -> a.getObject().equals(gene) && a.getOntologyClass().equals(rootMF)));
}

}
Loading

0 comments on commit 01cf67b

Please sign in to comment.