Open pnrobinson opened 7 years ago
I think that getNonObsoleteTermIds(); is showing the expected behavior and that getMap is showing terms from the original ontology. This is unexpected behavior!
Not sure what you mean by the function crashes.
Here is a running example, is this doing what you were trying to do? It is not crashing
HpoOboParser hpoOboParser = new HpoOboParser(new File(hpopath));
ImmutableOntology<HpoTerm, HpoTermRelation> phenoSubOntology = hpoOboParser.parse().getPhenotypicAbnormalitySubOntology();
Map<TermId, HpoTerm> termmap = phenoSubOntology.getTermMap();
// test 1
TermPrefix pref = new ImmutableTermPrefix("HP");
TermId autosomalDominantId = new ImmutableTermId(pref, "0000006");
System.out.println(termmap.get(autosomalDominantId));
// test 2
ArrayList<TermId> termids = new ArrayList<>();
termids.add(autosomalDominantId);
TermId anotherTermId = new ImmutableTermId(pref, "0000123");
termids.add(anotherTermId);
Set<TermId> ancestors = phenoSubOntology.getAllAncestorTermIds(termids);
System.out.println(ancestors);
@holtgrewe I find it irritating that the the map produced by getTermMap (test 1) contains Terms that are not in the sub-ontology selected in the step before.
@drseb The fact that "the map produced by getTermMap (test 1) contains Terms that are not in the sub-ontology selected in the step before" was indeed the problem that was leading to a difficult to debug crash (run time error). I am not sure if the test class crashes. I think that the problem is that a shallow copy is being done (i.e., the term map is copy the reference to the term map from the bigger ontology). It would be better to do a deep copy of the term map when we create a subontology.
@drseb @holtgrewe I think I fixed the bug. The function subOntology in the class com.github.phenomics.ontolib.ontology.data.ImmutableOntology was passing the original termMap object, which contains all of the terms of the original ontology -- it should contain only the terms of the new subontology.
This is the revised function
@Override
public Ontology<T, R> subOntology(TermId subOntologyRoot) {
final Set<TermId> childTermIds = OntologyTerms.childrenOf(subOntologyRoot, this);
final ImmutableDirectedGraph<TermId, ImmutableEdge<TermId>> subGraph =
(ImmutableDirectedGraph<TermId, ImmutableEdge<TermId>>) graph.subGraph(childTermIds);
Set<TermId> intersectingTerms = Sets.intersection(nonObsoleteTermIds,childTermIds);
final ImmutableMap.Builder<TermId,T> lb = ImmutableMap.builder();
for (final TermId tid : intersectingTerms) {
lb.put(tid,termMap.get(tid));
}
return new ImmutableOntology<T, R>(metaInfo, subGraph, subOntologyRoot,
intersectingTerms,
Sets.intersection(obsoleteTermIds, childTermIds), lb.build(), relationMap);
}
This is a new test for com.github.phenomics.ontolib.ontology.data.ImmutableOntologyTest
/**
* The subontology defined by Term with id4 should consist of only the terms id4 and id1.
* The termmap should thus contain only two terms. The subontology does not contain the original root of the ontology, id5.
*/
@Test
public void testSubontologyCreation() {
ImmutableOntology<TestTerm, TestTermRelation> subontology=(ImmutableOntology<TestTerm, TestTermRelation>)ontology.subOntology(id4);
Assert.assertTrue(subontology.getTermMap().containsKey(id4));
Assert.assertTrue(subontology.getTermMap().containsKey(id1));
Assert.assertTrue(ontology.getTermMap().size()==5);
Assert.assertTrue(subontology.getTermMap().size()==2);
Assert.assertFalse(subontology.getTermMap().containsKey(id5));
}
I have not yet addressed whether the relationMap needs to be treated in this way also. All other unit tests still pass.
The function getPhenotypicAbnormalitySubOntology() should be returning an ontology that just has terms from this subontology. And yet it apparently returns the inheritance terms. On the other hand, the function Set ancestors = ontology.getAllAncestorTermIds(myset); crashes if myset contains the Term HP:0000006, Autosomal doimant inheritance.
I am not sure I understand this issue, but here is some code that can be used to reproduce the problem I am seeing. If you use the code, then path and hpopath need to be modified accordingly.