Merge branch 'develop' into features/JAL-3010ontologyFeatureSettings
[jalview.git] / src / jalview / io / gff / SequenceOntologyLite.java
index 7d354e0..2cbec36 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.io.gff;
 
+import jalview.datamodel.ontology.OntologyBase;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -38,7 +40,8 @@ import java.util.Map;
  * @author gmcarstairs
  *
  */
-public class SequenceOntologyLite implements SequenceOntologyI
+public class SequenceOntologyLite extends OntologyBase
+        implements SequenceOntologyI
 {
   /*
    * initial selection of types of interest when processing Ensembl features
@@ -81,8 +84,11 @@ public class SequenceOntologyLite implements SequenceOntologyI
     { "sequence_variant", "sequence_variant" },
     { "structural_variant", "sequence_variant" },
     { "feature_variant", "sequence_variant" },
+    { "upstream_gene_variant", "sequence_variant" },
     { "gene_variant", "sequence_variant" },
     { "transcript_variant", "sequence_variant" },
+    { "non_coding_transcript_variant", "sequence_variant" },
+    { "non_coding_transcript_exon_variant", "sequence_variant" },
     // NB Ensembl uses NMD_transcript_variant as if a 'transcript'
     // but we model it here correctly as per the SO
     { "NMD_transcript_variant", "sequence_variant" },
@@ -248,4 +254,70 @@ public class SequenceOntologyLite implements SequenceOntologyI
       return termsNotFound;
     }
   }
+
+  @Override
+  public List<String> getRootParents(final String term)
+  {
+    /*
+     * check in cache first
+     */
+    if (rootParents.containsKey(term))
+    {
+      return rootParents.get(term);
+    }
+
+    List<String> top = new ArrayList<>();
+    List<String> query = new ArrayList<>();
+    query.add(term);
+
+    while (!query.isEmpty())
+    {
+      List<String> nextQuery = new ArrayList<>();
+      for (String q : query)
+      {
+        List<String> theParents = parents.get(q);
+        if (theParents != null)
+        {
+          if (theParents.size() == 1 && theParents.get(0).equals(q))
+          {
+            /*
+             * top-level term
+             */
+            if (!top.contains(q))
+            {
+              top.add(q);
+            }
+          }
+          else
+          {
+            for (String p : theParents)
+            {
+              if (!p.equals(q))
+              {
+                nextQuery.add(p);
+              }
+            }
+          }
+        }
+      }
+      query = nextQuery;
+    }
+
+    rootParents.put(term, top);
+
+    return top.isEmpty() ? null : top;
+  }
+
+  @Override
+  public List<String> getParents(String term)
+  {
+    List<String> result = parents.get(term);
+    return result == null ? new ArrayList<>() : result;
+  }
+
+  @Override
+  public boolean isValidTerm(String term)
+  {
+    return parents.containsKey(term);
+  }
 }