JAL-1705 get xrefs only for dna/peptide; code tidy
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 21 Jan 2016 14:34:54 +0000 (14:34 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 21 Jan 2016 14:34:54 +0000 (14:34 +0000)
src/jalview/analysis/CrossRef.java
src/jalview/ws/seqfetcher/ASequenceFetcher.java

index 95d2396..e96d9d7 100644 (file)
@@ -244,29 +244,30 @@ public class CrossRef
       }
       for (int r = 0; xrfs != null && r < xrfs.length; r++)
       {
-        if (source != null && !source.equals(xrfs[r].getSource()))
+        DBRefEntry xref = xrfs[r];
+        if (source != null && !source.equals(xref.getSource()))
         {
           continue;
         }
-        if (xrfs[r].hasMap())
+        if (xref.hasMap())
         {
-          if (xrfs[r].getMap().getTo() != null)
+          if (xref.getMap().getTo() != null)
           {
-            SequenceI rsq = new Sequence(xrfs[r].getMap().getTo());
+            SequenceI rsq = new Sequence(xref.getMap().getTo());
             rseqs.add(rsq);
-            if (xrfs[r].getMap().getMap().getFromRatio() != xrfs[r]
+            if (xref.getMap().getMap().getFromRatio() != xref
                     .getMap().getMap().getToRatio())
             {
               // get sense of map correct for adding to product alignment.
               if (dna)
               {
                 // map is from dna seq to a protein product
-                cf.addMap(dss, rsq, xrfs[r].getMap().getMap());
+                cf.addMap(dss, rsq, xref.getMap().getMap());
               }
               else
               {
                 // map should be from protein seq to its coding dna
-                cf.addMap(rsq, dss, xrfs[r].getMap().getMap().getInverse());
+                cf.addMap(rsq, dss, xref.getMap().getMap().getInverse());
               }
             }
             found = true;
@@ -278,7 +279,7 @@ public class CrossRef
           // xrefs on this sequence.
           if (dataset != null)
           {
-            found |= searchDataset(dss, xrfs[r], dataset, rseqs, cf); // ,false,!dna);
+            found |= searchDataset(dss, xref, dataset, rseqs, cf); // ,false,!dna);
             if (found)
             {
               xrfs[r] = null; // we've recovered seqs for this one.
@@ -326,9 +327,8 @@ public class CrossRef
             xrfs = t;
             try
             {
-              retrieved = sftch.getSequences(xrfs); // problem here is we don't
-              // know which of xrfs
-              // resulted in which
+              retrieved = sftch.getSequences(xrfs, !dna);
+              // problem here is we don't know which of xrfs resulted in which
               // retrieved element
             } catch (Exception e)
             {
@@ -401,7 +401,7 @@ public class CrossRef
       SequenceI[] rsqs = new SequenceI[rseqs.size()];
       rseqs.toArray(rsqs);
       ral = new Alignment(rsqs);
-      if (cf != null && cf.getProtMappings() != null)
+      if (cf != null && !cf.isEmpty())
       {
         ral.addCodonFrame(cf);
       }
index 1e3ae7a..9e438d3 100644 (file)
@@ -26,13 +26,13 @@ import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.SequenceI;
 import jalview.util.DBRefUtils;
 import jalview.util.MessageManager;
-import jalview.util.QuickSort;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Stack;
@@ -41,46 +41,72 @@ import java.util.Vector;
 public class ASequenceFetcher
 {
 
-  /**
+  /*
    * set of databases we can retrieve entries from
    */
-  protected Hashtable<String, Map<String, DbSourceProxy>> FETCHABLEDBS;
+  protected Hashtable<String, Map<String, DbSourceProxy>> fetchableDbs;
+
+  /*
+   * comparator to sort by tier (0/1/2) and name
+   */
+  private Comparator<DbSourceProxy> proxyComparator;
 
+  /**
+   * Constructor
+   */
   public ASequenceFetcher()
   {
     super();
+
+    /*
+     * comparator to sort proxies by tier and name
+     */
+    proxyComparator = new Comparator<DbSourceProxy>()
+    {
+      @Override
+      public int compare(DbSourceProxy o1, DbSourceProxy o2)
+      {
+        /*
+         * Tier 0 precedes 1 precedes 2
+         */
+        int compared = Integer.compare(o1.getTier(), o2.getTier());
+        if (compared == 0)
+        {
+          // defend against NullPointer - should never happen
+          String o1Name = o1.getDbName();
+          String o2Name = o2.getDbName();
+          if (o1Name != null && o2Name != null)
+          {
+            compared = o1Name.compareToIgnoreCase(o2Name);
+          }
+        }
+        return compared;
+      }
+    };
   }
 
   /**
-   * get list of supported Databases
+   * get array of supported Databases
    * 
    * @return database source string for each database - only the latest version
    *         of a source db is bound to each source.
    */
   public String[] getSupportedDb()
   {
-    if (FETCHABLEDBS == null)
+    if (fetchableDbs == null)
     {
       return null;
     }
-    String[] sf = new String[FETCHABLEDBS.size()];
-    Enumeration<String> e = FETCHABLEDBS.keys();
-    int i = 0;
-    while (e.hasMoreElements())
-    {
-      sf[i++] = e.nextElement();
-    }
-    ;
+    String[] sf = fetchableDbs.keySet().toArray(
+            new String[fetchableDbs.size()]);
     return sf;
   }
 
   public boolean isFetchable(String source)
   {
-    Enumeration<String> e = FETCHABLEDBS.keys();
-    while (e.hasMoreElements())
+    for (String db : fetchableDbs.keySet())
     {
-      String db = e.nextElement();
-      if (source.compareToIgnoreCase(db) == 0)
+      if (source.equalsIgnoreCase(db))
       {
         return true;
       }
@@ -90,9 +116,16 @@ public class ASequenceFetcher
     return false;
   }
 
-  public SequenceI[] getSequences(DBRefEntry[] refs)
+  /**
+   * Fetch sequences for the given cross-references
+   * 
+   * @param refs
+   * @param dna
+   *          if true, only fetch from nucleotide data sources, else peptide
+   * @return
+   */
+  public SequenceI[] getSequences(DBRefEntry[] refs, boolean dna)
   {
-    SequenceI[] ret = null;
     Vector<SequenceI> rseqs = new Vector<SequenceI>();
     Hashtable<String, List<String>> queries = new Hashtable<String, List<String>>();
     for (int r = 0; r < refs.length; r++)
@@ -120,17 +153,20 @@ public class ASequenceFetcher
                 "Don't know how to fetch from this database :" + db));
         continue;
       }
-      Iterator<DbSourceProxy> fetchers = getSourceProxy(db).iterator();
+
       Stack<String> queriesLeft = new Stack<String>();
-      // List<String> queriesFailed = new ArrayList<String>();
       queriesLeft.addAll(query);
-      while (fetchers.hasNext())
+
+      for (DbSourceProxy fetcher : getSourceProxy(db))
       {
         List<String> queriesMade = new ArrayList<String>();
         HashSet<String> queriesFound = new HashSet<String>();
         try
         {
-          DbSourceProxy fetcher = fetchers.next();
+          if (fetcher.isDnaCoding() != dna)
+          {
+            continue; // wrong sort of data
+          }
           boolean doMultiple = fetcher.getAccessionSeparator() != null;
           // No separator - no Multiple Queries
           while (!queriesLeft.isEmpty())
@@ -224,19 +260,19 @@ public class ASequenceFetcher
         }
       }
     }
+
+    SequenceI[] result = null;
     if (rseqs.size() > 0)
     {
-      ret = new SequenceI[rseqs.size()];
-      Enumeration<SequenceI> sqs = rseqs.elements();
+      result = new SequenceI[rseqs.size()];
       int si = 0;
-      while (sqs.hasMoreElements())
+      for (SequenceI s : rseqs)
       {
-        SequenceI s = sqs.nextElement();
-        ret[si++] = s;
+        result[si++] = s;
         s.updatePDBIds();
       }
     }
-    return ret;
+    return result;
   }
 
   public void reportStdError(String db, List<String> queriesMade,
@@ -260,44 +296,27 @@ public class ASequenceFetcher
   }
 
   /**
-   * Retrieve an instance of the proxy for the given source
+   * Returns a list of proxies for the given source
    * 
    * @param db
    *          database source string TODO: add version string/wildcard for
    *          retrieval of specific DB source/version combinations.
-   * @return an instance of DbSourceProxy for that db.
+   * @return a list of DbSourceProxy for the db
    */
   public List<DbSourceProxy> getSourceProxy(String db)
   {
-    List<DbSourceProxy> dbs;
-    Map<String, DbSourceProxy> dblist = FETCHABLEDBS.get(db);
+    db = DBRefUtils.getCanonicalName(db);
+    Map<String, DbSourceProxy> dblist = fetchableDbs.get(db);
     if (dblist == null)
     {
       return new ArrayList<DbSourceProxy>();
     }
-    ;
-    if (dblist.size() > 1)
-    {
-      DbSourceProxy[] l = dblist.values().toArray(new DbSourceProxy[0]);
-      int i = 0;
-      String[] nm = new String[l.length];
-      // make sure standard dbs appear first, followed by reference das sources,
-      // followed by anything else.
-      for (DbSourceProxy s : l)
-      {
-        nm[i++] = "" + s.getTier() + s.getDbName().toLowerCase();
-      }
-      QuickSort.sort(nm, l);
-      dbs = new ArrayList<DbSourceProxy>();
-      for (i = l.length - 1; i >= 0; i--)
-      {
-        dbs.add(l[i]);
-      }
-    }
-    else
-    {
-      dbs = new ArrayList<DbSourceProxy>(dblist.values());
-    }
+
+    /*
+     * sort so that primary sources precede secondary
+     */
+    List<DbSourceProxy> dbs = new ArrayList<DbSourceProxy>(dblist.values());
+    Collections.sort(dbs, proxyComparator);
     return dbs;
   }
 
@@ -341,15 +360,15 @@ public class ASequenceFetcher
   {
     if (proxy != null)
     {
-      if (FETCHABLEDBS == null)
+      if (fetchableDbs == null)
       {
-        FETCHABLEDBS = new Hashtable<String, Map<String, DbSourceProxy>>();
+        fetchableDbs = new Hashtable<String, Map<String, DbSourceProxy>>();
       }
-      Map<String, DbSourceProxy> slist = FETCHABLEDBS.get(proxy
+      Map<String, DbSourceProxy> slist = fetchableDbs.get(proxy
               .getDbSource());
       if (slist == null)
       {
-        FETCHABLEDBS.put(proxy.getDbSource(),
+        fetchableDbs.put(proxy.getDbSource(),
                 slist = new Hashtable<String, DbSourceProxy>());
       }
       slist.put(proxy.getDbName(), proxy);
@@ -372,17 +391,17 @@ public class ASequenceFetcher
                               "error.implementation_error_dbinstance_must_implement_interface",
                               new String[] { class1.toString() }));
     }
-    if (FETCHABLEDBS == null)
+    if (fetchableDbs == null)
     {
       return null;
     }
     String[] sources = null;
     Vector<String> src = new Vector<String>();
-    Enumeration<String> dbs = FETCHABLEDBS.keys();
+    Enumeration<String> dbs = fetchableDbs.keys();
     while (dbs.hasMoreElements())
     {
       String dbn = dbs.nextElement();
-      for (DbSourceProxy dbp : FETCHABLEDBS.get(dbn).values())
+      for (DbSourceProxy dbp : fetchableDbs.get(dbn).values())
       {
         if (class1.isAssignableFrom(dbp.getClass()))
         {