BatchSize now 10
[jalview.git] / src / jalview / io / DasSequenceFeatureFetcher.java
index a420afa..ad2e37b 100755 (executable)
@@ -1,6 +1,6 @@
 /*\r
 * Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
+* Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
 *\r
 * This program is free software; you can redistribute it and/or\r
 * modify it under the terms of the GNU General Public License\r
@@ -27,7 +27,6 @@ import java.util.*;
 import java.net.URL;\r
 \r
 import org.biojava.dasobert.das.FeatureThread;\r
-import org.biojava.dasobert.dasregistry.Das1Source;\r
 import org.biojava.dasobert.eventmodel.FeatureEvent;\r
 import org.biojava.dasobert.eventmodel.FeatureListener;\r
 import org.biojava.dasobert.dasregistry.DasSource;\r
@@ -40,7 +39,9 @@ import org.biojava.dasobert.das2.DasSourceConverter;
 \r
 \r
 import jalview.bin.Cache;\r
+import org.biojava.dasobert.dasregistry.DasCoordinateSystem;\r
 \r
+import javax.swing.*;\r
 \r
 /**\r
  * DOCUMENT ME!\r
@@ -50,26 +51,108 @@ import jalview.bin.Cache;
  */\r
 public class DasSequenceFeatureFetcher implements Runnable\r
 {\r
-  final AlignmentI dataset;\r
-  final AlignmentPanel ap;\r
+  SequenceI [] sequences;\r
+  AlignFrame af;\r
   StringBuffer sbuffer = new StringBuffer();\r
+  Vector selectedSources;\r
 \r
+  long startTime;\r
+  int threadsRunning = 0;\r
+  boolean allBatchesComplete = false;\r
 \r
 \r
   /**\r
    * Creates a new SequenceFeatureFetcher object.\r
+   * Uses default\r
    *\r
    * @param align DOCUMENT ME!\r
    * @param ap DOCUMENT ME!\r
    */\r
-  public DasSequenceFeatureFetcher(AlignmentI align, AlignmentPanel ap)\r
+  public DasSequenceFeatureFetcher(SequenceI [] sequences,\r
+                                   final AlignFrame af,\r
+                                   Vector selectedSources)\r
   {\r
-    this.dataset = align.getDataset();\r
-    this.ap = ap;\r
+    this.selectedSources = selectedSources;\r
+    this.sequences = sequences;\r
+    this.af = af;\r
+\r
+    int uniprotCount = 0;\r
+    for (int i = 0; i < selectedSources.size(); i++)\r
+    {\r
+      DasSource source = (DasSource) selectedSources.elementAt(i);\r
+      DasCoordinateSystem[] coords = source.getCoordinateSystem();\r
+      for (int c = 0; c < coords.length; c++)\r
+      {\r
+        if (coords[c].getName().indexOf("UniProt")>-1)\r
+        {\r
+          uniprotCount++;\r
+          break;\r
+        }\r
+      }\r
+    }\r
+\r
+    int refCount = 0;\r
+    for(int i=0; i<sequences.length; i++)\r
+    {\r
+      DBRefEntry [] dbref = sequences[i].getDBRef();\r
+      if(dbref!=null)\r
+      {\r
+        for(int j=0; j<dbref.length; j++)\r
+        {\r
+          if(dbref[j].getSource()\r
+             .equals(jalview.datamodel.DBRefSource.UNIPROT))\r
+          {\r
+            refCount++;\r
+            break;\r
+          }\r
+        }\r
+      }\r
+    }\r
 \r
+    if(refCount<sequences.length && uniprotCount>0)\r
+    {\r
+\r
+     int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,\r
+          "Do you want Jalview to find\n"\r
+         +"Uniprot Accession ids for given sequence names?",\r
+         "Find Uniprot Accession Ids",\r
+         JOptionPane.YES_NO_OPTION,\r
+         JOptionPane.QUESTION_MESSAGE);\r
+\r
+     if(reply == JOptionPane.YES_OPTION)\r
+     {\r
+       Thread thread = new Thread(new FetchDBRefs());\r
+       thread.start();\r
+     }\r
+     else\r
+      startFetching();\r
+    }\r
+    else\r
+      startFetching();\r
+\r
+  /* System.out.println("User selection is "   +\r
+                       ( ( (float) uniprotCount / (float) selectedSources.size()) * 100)\r
+                      + " % Uniprot,  and "+refCount+" / " +sequences.length+" have uniprot accession");\r
+*/\r
+  }\r
+\r
+  void startFetching()\r
+  {\r
     Thread thread = new Thread(this);\r
     thread.start();\r
   }\r
+\r
+  class FetchDBRefs implements Runnable\r
+  {\r
+    public void run()\r
+    {\r
+      new DBRefFetcher(\r
+             af.getViewport().getAlignment(), af).fetchDBRefs(true);\r
+      startFetching();\r
+    }\r
+  }\r
+\r
+\r
   /**\r
    * creates a jalview sequence feature from a das feature document\r
    * @param dasfeature\r
@@ -123,11 +206,12 @@ public class DasSequenceFeatureFetcher implements Runnable
                                //  null\r
                        // );\r
 \r
-                     // System.out.println(nickname+" "+f.getType()+" "+f.begin+" "+f.end);\r
          return f;\r
          }\r
          catch (Exception e) {\r
+            System.out.println("ERRR "+e);\r
             e.printStackTrace();\r
+            System.out.println("############");\r
                  Cache.log.debug("Failed to parse "+dasfeature.toString(), e);\r
                  return null;\r
          }\r
@@ -138,10 +222,11 @@ public class DasSequenceFeatureFetcher implements Runnable
    * @param SourceUrl\r
    * @param id\r
    */\r
-  protected void createFeatureFetcher(final Sequence seq,\r
+  protected void createFeatureFetcher(final SequenceI seq,\r
                                       final String sourceUrl,\r
                                       String id,\r
-                                      String nickname)  {\r
+                                      String nickname)\r
+  {\r
          //////////////\r
          /// fetch DAS features\r
           final Das1Source source = new Das1Source();\r
@@ -151,16 +236,34 @@ public class DasSequenceFeatureFetcher implements Runnable
 \r
           Cache.log.debug("new Das Feature Fetcher for " + id + " querying " +\r
                           sourceUrl);\r
+\r
           if (id != null && id.length() > 0)\r
           {\r
+            setThreadsRunning(+1);\r
+\r
+          //  int start=seq.getStart(), end = seq.getEnd();\r
+          /*  if(af.getViewport().getSelectionGroup()!=null)\r
+            {\r
+              SequenceI tmp = af.getViewport().getAlignment().findName(seq.getName());\r
+              start = tmp.findPosition(\r
+              af.getViewport().getSelectionGroup().getStartRes()\r
+                  );\r
+\r
+              end = tmp.findPosition(\r
+                 af.getViewport().getSelectionGroup().getEndRes()\r
+                 );\r
+            }*/\r
+\r
             FeatureThread fetcher = new FeatureThread(id\r
-               +  ":" + seq.getStart() + "," +seq.getEnd()\r
-                 , source);\r
+                                                   //  +  ":" + start + "," + end,\r
+                                                      , source);\r
+\r
 \r
             fetcher.addFeatureListener(new FeatureListener()\r
             {\r
               public void comeBackLater(FeatureEvent e)\r
               {\r
+                setThreadsRunning(-1);\r
                 Cache.log.debug("das source " + e.getDasSource().getNickname() +\r
                                 " asked us to come back in " + e.getComeBackLater() +\r
                                 " secs.");\r
@@ -168,6 +271,7 @@ public class DasSequenceFeatureFetcher implements Runnable
 \r
               public void newFeatures(FeatureEvent e)\r
               {\r
+                setThreadsRunning(-1);\r
                 Das1Source ds = e.getDasSource();\r
 \r
                 Map[] features = e.getFeatures();\r
@@ -185,58 +289,91 @@ public class DasSequenceFeatureFetcher implements Runnable
                       seq.addSequenceFeature(f);\r
                   }\r
                 }\r
-              }\r
+                else\r
+                {\r
+                  System.out.println("No features found for sequence " +seq.getName()\r
+                                     +" from: "+ e.getDasSource().getNickname());\r
+                }\r
 \r
+              }\r
             }\r
 \r
             );\r
 \r
             //NOTE alignPanel listener will be called after the previous\r
             //anonymous listener!!!\r
-            fetcher.addFeatureListener(ap);\r
+            fetcher.addFeatureListener(af);\r
 \r
             fetcher.start();\r
          }\r
   }\r
+\r
+  synchronized void setThreadsRunning(int i)\r
+  {\r
+    threadsRunning += i;\r
+    if(threadsRunning<1 && allBatchesComplete)\r
+    {\r
+      af.setProgressBar("DAS Feature Fetching Complete", startTime);\r
+\r
+      if(af.featureSettings!=null)\r
+        af.featureSettings.setTableData();\r
+    }\r
+  }\r
+\r
   /**\r
    * Spawns a number of dasobert Fetcher threads to add features to sequences in the dataset\r
    */\r
   public void run()\r
   {\r
+    startTime = System.currentTimeMillis();\r
+    af.setProgressBar("Fetching DAS Sequence Features", startTime);\r
+\r
     DasSource [] sources = new jalview.gui.DasSourceBrowser().getDASSource();\r
 \r
-    String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE", "uniprot");\r
-    StringTokenizer st = new StringTokenizer(active, "\t");\r
-    Vector selectedSources = new Vector();\r
-    String token;\r
-    while (st.hasMoreTokens())\r
+    if(selectedSources==null || selectedSources.size()==0)\r
     {\r
-      token = st.nextToken();\r
-      for(int i=0; i<sources.length; i++)\r
+      String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE", "uniprot");\r
+      StringTokenizer st = new StringTokenizer(active, "\t");\r
+      Vector selectedSources = new Vector();\r
+      String token;\r
+      while (st.hasMoreTokens())\r
       {\r
-        if(sources[i].getNickname().equals(token))\r
+        token = st.nextToken();\r
+        for (int i = 0; i < sources.length; i++)\r
         {\r
-          selectedSources.addElement(sources[i]);\r
-          break;\r
+          if (sources[i].getNickname().equals(token))\r
+          {\r
+            selectedSources.addElement(sources[i]);\r
+            break;\r
+          }\r
         }\r
       }\r
     }\r
 \r
-\r
     if(selectedSources == null || selectedSources.size()==0)\r
     {\r
       System.out.println("No DAS Sources active");\r
+      af.setProgressBar("No DAS Sources Active", startTime);\r
       return;\r
     }\r
 \r
     try\r
     {\r
+      //We must limit the feature fetching to 20 to prevent\r
+      //Servers being overloaded with too many requests\r
+      int batchCount = 0;\r
+      int batchMaxSize = 10;\r
       int seqIndex = 0;\r
-      Vector sequences = dataset.getSequences();\r
-      while (seqIndex < sequences.size())\r
+      while (seqIndex < sequences.length)\r
       {\r
-          Sequence sequence = (Sequence) sequences.get(seqIndex);\r
-          Vector uprefs = jalview.util.DBRefUtils.selectRefs(sequence.getDBRef(),\r
+          batchCount ++;\r
+          if(batchCount>=batchMaxSize)\r
+          {\r
+            waitTillBatchComplete();\r
+            batchCount = 0;\r
+          }\r
+\r
+          DBRefEntry [] uprefs = jalview.util.DBRefUtils.selectRefs(sequences[seqIndex].getDBRef(),\r
               new String[]  {\r
               jalview.datamodel.DBRefSource.PDB,\r
               jalview.datamodel.DBRefSource.UNIPROT});\r
@@ -248,20 +385,22 @@ public class DasSequenceFeatureFetcher implements Runnable
             if (uprefs != null)\r
             {\r
               // we know the id for this entry, so don't note its ID in the unknownSequences list\r
-              for (int j = 0, k = uprefs.size(); j < k; j++)\r
+              for (int j = 0;  j < uprefs.length; j++)\r
               {\r
+\r
                 // Will have to pass any mapping information to the fetcher - the start/end for the DBRefEntry may not be the same as the sequence's start/end\r
-                org.biojava.dasobert.dasregistry.DasCoordinateSystem cs[] = dasSource.getCoordinateSystem();\r
-                for (int l=0; l<cs.length; l++) {\r
-                  if (jalview.util.DBRefUtils.isDasCoordinateSystem(cs[l].getName(), (DBRefEntry)\r
-                      uprefs.get(j)))\r
+                DasCoordinateSystem cs[] = dasSource.getCoordinateSystem();\r
+                for (int l=0; l<cs.length; l++)\r
+                {\r
+                  if (jalview.util.DBRefUtils.isDasCoordinateSystem(cs[l].getName(), uprefs[j]))\r
                   {\r
                     Cache.log.debug("Launched fetcher for coordinate system " +\r
                                     cs[l].getName());\r
-                    createFeatureFetcher(sequence,\r
+\r
+\r
+                    createFeatureFetcher(sequences[seqIndex],\r
                                          dasSource.getUrl(),\r
-                                         ( (DBRefEntry) uprefs.get(j)).\r
-                                         getAccessionId(),\r
+                                          uprefs[j].getAccessionId(),\r
                                          dasSource.getNickname());\r
                   }\r
                 }\r
@@ -271,19 +410,19 @@ public class DasSequenceFeatureFetcher implements Runnable
             {\r
               String id = null;\r
               // try and use the name as the sequence id\r
-              if (sequence.getName().indexOf("|") > -1)\r
+              if (sequences[seqIndex].getName().indexOf("|") > -1)\r
               {\r
-                id = sequence.getName().substring(\r
-                    sequence.getName().lastIndexOf("|") + 1);\r
+                id = sequences[seqIndex].getName().substring(\r
+                    sequences[seqIndex].getName().lastIndexOf("|") + 1);\r
               }\r
               else\r
               {\r
-                id = sequence.getName();\r
+                id = sequences[seqIndex].getName();\r
               }\r
               if (id != null)\r
               {\r
                 // Should try to call a general feature fetcher that queries many sources with name to discover applicable ID references\r
-                createFeatureFetcher(sequence,\r
+                createFeatureFetcher(sequences[seqIndex],\r
                                      dasSource.getUrl(),\r
                                      id,\r
                                      dasSource.getNickname());\r
@@ -298,6 +437,22 @@ public class DasSequenceFeatureFetcher implements Runnable
     {\r
       ex.printStackTrace();\r
     }\r
+    allBatchesComplete = true;\r
+  }\r
+\r
+  void waitTillBatchComplete()\r
+  {\r
+    while( threadsRunning > 0 )\r
+    {\r
+      try{\r
+        Thread.sleep(500);\r
+\r
+      }catch(Exception ex)\r
+      {\r
+        ex.printStackTrace();\r
+      }\r
+    }\r
+\r
   }\r
 \r
 \r
@@ -305,10 +460,9 @@ public class DasSequenceFeatureFetcher implements Runnable
   {\r
     DasSourceReaderImpl reader = new DasSourceReaderImpl();\r
 \r
-    String registryURL = //jalview.bin.Cache.getDefault("DAS_REGISTRY_URL",\r
-       // "http://servlet.sanger.ac.uk/dasregistry/services/das_registry"\r
-        "http://www.spice-3d.org/dasregistry/das1/sources";\r
-     //  );\r
+    String registryURL =jalview.bin.Cache.getDefault("DAS_REGISTRY_URL",\r
+        "http://das.sanger.ac.uk/registry/das1/sources/"\r
+      );\r
 \r
     try\r
     {\r