Wait for response from server before next sequence
authoramwaterhouse <Andrew Waterhouse>
Wed, 18 Oct 2006 13:10:10 +0000 (13:10 +0000)
committeramwaterhouse <Andrew Waterhouse>
Wed, 18 Oct 2006 13:10:10 +0000 (13:10 +0000)
src/jalview/io/DasSequenceFeatureFetcher.java

index ad2e37b..305160e 100755 (executable)
@@ -1,21 +1,21 @@
 /*\r
-* Jalview - A Sequence Alignment Editor and Viewer\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
-* as published by the Free Software Foundation; either version 2\r
-* of the License, or (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-* GNU General Public License for more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program; if not, write to the Free Software\r
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
-*/\r
+ * Jalview - A Sequence Alignment Editor and Viewer\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
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
+ */\r
 package jalview.io;\r
 \r
 import jalview.datamodel.*;\r
@@ -37,7 +37,6 @@ import org.biojava.dasobert.dasregistry.DasSource;
 import org.biojava.dasobert.das2.Das2Source;\r
 import org.biojava.dasobert.das2.DasSourceConverter;\r
 \r
-\r
 import jalview.bin.Cache;\r
 import org.biojava.dasobert.dasregistry.DasCoordinateSystem;\r
 \r
@@ -49,17 +48,14 @@ import javax.swing.*;
  * @author $author$\r
  * @version $Revision$\r
  */\r
-public class DasSequenceFeatureFetcher implements Runnable\r
+public class DasSequenceFeatureFetcher\r
 {\r
-  SequenceI [] sequences;\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
@@ -68,7 +64,7 @@ public class DasSequenceFeatureFetcher implements Runnable
    * @param align DOCUMENT ME!\r
    * @param ap DOCUMENT ME!\r
    */\r
-  public DasSequenceFeatureFetcher(SequenceI [] sequences,\r
+  public DasSequenceFeatureFetcher(SequenceI[] sequences,\r
                                    final AlignFrame af,\r
                                    Vector selectedSources)\r
   {\r
@@ -83,7 +79,7 @@ public class DasSequenceFeatureFetcher implements Runnable
       DasCoordinateSystem[] coords = source.getCoordinateSystem();\r
       for (int c = 0; c < coords.length; c++)\r
       {\r
-        if (coords[c].getName().indexOf("UniProt")>-1)\r
+        if (coords[c].getName().indexOf("UniProt") > -1)\r
         {\r
           uniprotCount++;\r
           break;\r
@@ -92,15 +88,15 @@ public class DasSequenceFeatureFetcher implements Runnable
     }\r
 \r
     int refCount = 0;\r
-    for(int i=0; i<sequences.length; i++)\r
+    for (int i = 0; i < sequences.length; i++)\r
     {\r
-      DBRefEntry [] dbref = sequences[i].getDBRef();\r
-      if(dbref!=null)\r
+      DBRefEntry[] dbref = sequences[i].getDBRef();\r
+      if (dbref != null)\r
       {\r
-        for(int j=0; j<dbref.length; j++)\r
+        for (int j = 0; j < dbref.length; j++)\r
         {\r
-          if(dbref[j].getSource()\r
-             .equals(jalview.datamodel.DBRefSource.UNIPROT))\r
+          if (dbref[j].getSource()\r
+              .equals(jalview.datamodel.DBRefSource.UNIPROT))\r
           {\r
             refCount++;\r
             break;\r
@@ -109,360 +105,345 @@ public class DasSequenceFeatureFetcher implements Runnable
       }\r
     }\r
 \r
-    if(refCount<sequences.length && uniprotCount>0)\r
+    if (refCount < sequences.length && uniprotCount > 0)\r
     {\r
 \r
-     int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,\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
+          + "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
+      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
 \r
-  class FetchDBRefs implements Runnable\r
+  class FetchDBRefs\r
+      implements Runnable\r
   {\r
     public void run()\r
     {\r
       new DBRefFetcher(\r
-             af.getViewport().getAlignment(), af).fetchDBRefs(true);\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
-   * @return sequence feature object created using dasfeature information\r
-   */\r
-  SequenceFeature newSequenceFeature(Map dasfeature, String nickname)\r
-  {\r
-         try {\r
-               /**\r
-          * Different qNames for a DAS Feature - are string keys to the HashMaps in features\r
-          * "METHOD") ||\r
-          qName.equals("TYPE") ||\r
-          qName.equals("START") ||\r
-          qName.equals("END") ||\r
-          qName.equals("NOTE") ||\r
-          qName.equals("LINK") ||\r
-          qName.equals("SCORE")\r
-          */\r
-                 String desc = new String();\r
-                 if (dasfeature.containsKey("NOTE"))\r
-                               desc+=(String) dasfeature.get("NOTE");\r
-\r
-\r
-                  int start = 0, end = 0;\r
-                  float score = 0f;\r
-\r
-                  try{ start = Integer.parseInt( dasfeature.get("START").toString()); }\r
-                  catch( Exception ex){}\r
-                  try{ end = Integer.parseInt( dasfeature.get("END").toString()); }\r
-                  catch (Exception ex){}\r
-                  try{ score = Integer.parseInt( dasfeature.get("SCORE").toString()); }\r
-                  catch (Exception ex){}\r
-\r
-\r
-                 SequenceFeature f = new SequenceFeature(\r
-                                 (String) dasfeature.get("TYPE"),\r
-                                 desc,\r
-                                 start,\r
-                                 end,\r
-                                  score,\r
-                                 nickname);\r
-\r
-                  if (dasfeature.containsKey("LINK"))\r
-                 {\r
-                      f.addLink(f.getType()+" "+f.begin+"_"+f.end\r
-                                +"|"+ dasfeature.get("LINK"));\r
-                 }\r
-                  // (String) dasfeature.get("ID"),\r
-                  ////  (String) dasfeature.get("METHOD"),\r
-                               //  (String) dasfeature.get("SCORE"),\r
-                               //  null\r
-                       // );\r
-\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
-  }\r
-  /**\r
-   * fetch and add das features to a sequence using the given source URL and Id to create a feature request\r
-   * @param seq\r
-   * @param SourceUrl\r
-   * @param id\r
-   */\r
-  protected void createFeatureFetcher(final SequenceI seq,\r
-                                      final String sourceUrl,\r
-                                      String id,\r
-                                      String nickname)\r
-  {\r
-         //////////////\r
-         /// fetch DAS features\r
-          final Das1Source source = new Das1Source();\r
-          source.setUrl(sourceUrl);\r
-          source.setNickname(nickname);\r
+   /**\r
+    * Spawns a number of dasobert Fetcher threads to add features to sequences in the dataset\r
+    */\r
+   void startFetching()\r
+   {\r
+     startTime = System.currentTimeMillis();\r
+     af.setProgressBar("Fetching DAS Sequence Features", startTime);\r
 \r
+     DasSource[] sources = new jalview.gui.DasSourceBrowser().getDASSource();\r
 \r
-          Cache.log.debug("new Das Feature Fetcher for " + id + " querying " +\r
-                          sourceUrl);\r
+     if (selectedSources == null || selectedSources.size() == 0)\r
+     {\r
+       String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE",\r
+           "uniprot");\r
+       StringTokenizer st = new StringTokenizer(active, "\t");\r
+       Vector selectedSources = new Vector();\r
+       String token;\r
+       while (st.hasMoreTokens())\r
+       {\r
+         token = st.nextToken();\r
+         for (int i = 0; i < sources.length; i++)\r
+         {\r
+           if (sources[i].getNickname().equals(token))\r
+           {\r
+             selectedSources.addElement(sources[i]);\r
+             break;\r
+           }\r
+         }\r
+       }\r
+     }\r
 \r
-          if (id != null && id.length() > 0)\r
-          {\r
-            setThreadsRunning(+1);\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
-          //  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
+       sourcesRemaining = selectedSources.size();\r
+       //Now sending requests one at a time to each server\r
+       for (int sourceIndex = 0; sourceIndex < selectedSources.size();\r
+            sourceIndex++)\r
+       {\r
+         DasSource dasSource = (DasSource) selectedSources.elementAt(\r
+             sourceIndex);\r
+\r
+         nextSequence(dasSource, sequences[0]);\r
+       }\r
+   }\r
+\r
+   int sourcesRemaining=0;\r
+   void responseComplete(DasSource dasSource, SequenceI seq)\r
+   {\r
+     if (seq != null)\r
+     {\r
+       for (int seqIndex = 0; seqIndex < sequences.length-1; seqIndex++)\r
+       {\r
+         if (sequences[seqIndex] == seq)\r
+         {\r
+           nextSequence(dasSource, sequences[++seqIndex]);\r
+           return;\r
+         }\r
+       }\r
+     }\r
 \r
-              end = tmp.findPosition(\r
-                 af.getViewport().getSelectionGroup().getEndRes()\r
-                 );\r
-            }*/\r
+     sourcesRemaining --;\r
 \r
-            FeatureThread fetcher = new FeatureThread(id\r
-                                                   //  +  ":" + start + "," + end,\r
-                                                      , source);\r
+     if(sourcesRemaining==0)\r
+     {\r
+       af.setProgressBar("DAS Feature Fetching Complete", startTime);\r
 \r
+       if(af.featureSettings!=null)\r
+         af.featureSettings.setTableData();\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
-              }\r
+   }\r
 \r
-              public void newFeatures(FeatureEvent e)\r
-              {\r
-                setThreadsRunning(-1);\r
-                Das1Source ds = e.getDasSource();\r
-\r
-                Map[] features = e.getFeatures();\r
-                // add features to sequence\r
-                Cache.log.debug("das source " + ds.getUrl() + " returned " +\r
-                                features.length + " features");\r
-\r
-                if (features.length > 0)\r
-                {\r
-                  for (int i = 0; i < features.length; i++)\r
-                  {\r
-                      SequenceFeature f = newSequenceFeature(features[i],\r
-                        source.getNickname());\r
-\r
-                      seq.addSequenceFeature(f);\r
-                  }\r
-                }\r
-                else\r
-                {\r
-                  System.out.println("No features found for sequence " +seq.getName()\r
-                                     +" from: "+ e.getDasSource().getNickname());\r
-                }\r
+   void featuresAdded(SequenceI seq)\r
+   {\r
+     af.getFeatureRenderer().featuresAdded();\r
 \r
-              }\r
-            }\r
+     int start = af.getViewport().getStartSeq();\r
+     int end = af.getViewport().getEndSeq();\r
+     int index;\r
+     for(index=start; index<end; index++)\r
+      if(seq == af.getViewport().getAlignment().getSequenceAt(index).getDatasetSequence())\r
+       {\r
+         af.alignPanel.repaint();\r
+         break;\r
+       }\r
+   }\r
 \r
-            );\r
 \r
-            //NOTE alignPanel listener will be called after the previous\r
-            //anonymous listener!!!\r
-            fetcher.addFeatureListener(af);\r
+  void nextSequence(DasSource dasSource, SequenceI seq)\r
+  {\r
+      DBRefEntry[] uprefs = jalview.util.DBRefUtils.selectRefs(seq.getDBRef(),\r
+          new String[]\r
+          {\r
+        //  jalview.datamodel.DBRefSource.PDB,\r
+          jalview.datamodel.DBRefSource.UNIPROT\r
+      });\r
 \r
-            fetcher.start();\r
-         }\r
-  }\r
+        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; j < uprefs.length; j++)\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
+            // 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
+            DasCoordinateSystem cs[] = dasSource.getCoordinateSystem();\r
+           // if(cs.length>0)\r
+             // System.out.println("err "+\r
+            for (int l = 0; l < cs.length; l++)\r
+            {\r
+              if (jalview.util.DBRefUtils.isDasCoordinateSystem(cs[l].\r
+                  getName(), uprefs[0]))\r
+              {\r
 \r
-      if(af.featureSettings!=null)\r
-        af.featureSettings.setTableData();\r
-    }\r
-  }\r
+                Cache.log.debug("Launched fetcher for coordinate system " +\r
+                                   cs[l].getName());\r
+\r
+                createFeatureFetcher(seq,\r
+                                     dasSource,\r
+                                     uprefs[0].getAccessionId());\r
+              }\r
+            }\r
+          }\r
+        }\r
+        else\r
+        {\r
+          String id = null;\r
+          // try and use the name as the sequence id\r
+          if (seq.getName().indexOf("|") > -1)\r
+          {\r
+            id = seq.getName().substring(\r
+                seq.getName().lastIndexOf("|") + 1);\r
+          }\r
+          else\r
+          {\r
+            id = seq.getName();\r
+          }\r
+          if (id != null)\r
+          {\r
+            // Should try to call a general feature fetcher that\r
+            // queries many sources with name to discover applicable ID references\r
+            createFeatureFetcher(seq,\r
+                                 dasSource,\r
+                                 id);\r
+          }\r
+        }\r
+\r
+   }\r
 \r
   /**\r
-   * Spawns a number of dasobert Fetcher threads to add features to sequences in the dataset\r
+   * fetch and add das features to a sequence using the given source URL and Id to create a feature request\r
+   * @param seq\r
+   * @param SourceUrl\r
+   * @param id\r
    */\r
-  public void run()\r
+  protected void createFeatureFetcher(final SequenceI seq,\r
+                                      final DasSource dasSource,\r
+                                      String id)\r
   {\r
-    startTime = System.currentTimeMillis();\r
-    af.setProgressBar("Fetching DAS Sequence Features", startTime);\r
+    //////////////\r
+    /// fetch DAS features\r
+    final Das1Source source = new Das1Source();\r
+    source.setUrl(dasSource.getUrl());\r
+    source.setNickname(dasSource.getNickname());\r
 \r
-    DasSource [] sources = new jalview.gui.DasSourceBrowser().getDASSource();\r
+    Cache.log.debug("new Das Feature Fetcher for " + id + " querying " +\r
+                    dasSource.getUrl());\r
 \r
-    if(selectedSources==null || selectedSources.size()==0)\r
+    if (id != null && id.length() > 0)\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
+      FeatureThread fetcher = new FeatureThread(id\r
+                                                //  +  ":" + start + "," + end,\r
+                                                , source);\r
+\r
+      fetcher.addFeatureListener(new FeatureListener()\r
       {\r
-        token = st.nextToken();\r
-        for (int i = 0; i < sources.length; i++)\r
+        public void comeBackLater(FeatureEvent e)\r
         {\r
-          if (sources[i].getNickname().equals(token))\r
-          {\r
-            selectedSources.addElement(sources[i]);\r
-            break;\r
-          }\r
+          responseComplete(dasSource, seq);\r
+          Cache.log.debug("das source " + e.getDasSource().getNickname() +\r
+                          " asked us to come back in " + e.getComeBackLater() +\r
+                          " secs.");\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
+        public void newFeatures(FeatureEvent e)\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
-      while (seqIndex < sequences.length)\r
-      {\r
-          batchCount ++;\r
-          if(batchCount>=batchMaxSize)\r
-          {\r
-            waitTillBatchComplete();\r
-            batchCount = 0;\r
-          }\r
+          Das1Source ds = e.getDasSource();\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
+          Map[] features = e.getFeatures();\r
+          // add features to sequence\r
+          Cache.log.debug("das source " + ds.getUrl() + " returned " +\r
+                          features.length + " features");\r
 \r
-          for(int sourceIndex=0; sourceIndex<selectedSources.size(); sourceIndex++)\r
+          if (features.length > 0)\r
           {\r
-            DasSource dasSource = (DasSource)selectedSources.elementAt(sourceIndex);\r
-\r
-            if (uprefs != null)\r
+            for (int i = 0; i < features.length; i++)\r
             {\r
-              // we know the id for this entry, so don't note its ID in the unknownSequences list\r
-              for (int j = 0;  j < uprefs.length; j++)\r
-              {\r
+              SequenceFeature f = newSequenceFeature(features[i],\r
+                  source.getNickname());\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
-                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
-\r
-\r
-                    createFeatureFetcher(sequences[seqIndex],\r
-                                         dasSource.getUrl(),\r
-                                          uprefs[j].getAccessionId(),\r
-                                         dasSource.getNickname());\r
-                  }\r
-                }\r
-              }\r
-            }\r
-            else\r
-            {\r
-              String id = null;\r
-              // try and use the name as the sequence id\r
-              if (sequences[seqIndex].getName().indexOf("|") > -1)\r
-              {\r
-                id = sequences[seqIndex].getName().substring(\r
-                    sequences[seqIndex].getName().lastIndexOf("|") + 1);\r
-              }\r
-              else\r
-              {\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(sequences[seqIndex],\r
-                                     dasSource.getUrl(),\r
-                                     id,\r
-                                     dasSource.getNickname());\r
-              }\r
+              seq.addSequenceFeature(f);\r
             }\r
+\r
+            featuresAdded(seq);\r
+          }\r
+          else\r
+          {\r
+          //  System.out.println("No features found for " + seq.getName()\r
+          //                     + " from: " + e.getDasSource().getNickname());\r
           }\r
+          responseComplete(dasSource, seq);\r
 \r
-          seqIndex++;\r
-    }\r
-    }\r
-    catch (Exception ex)\r
-    {\r
-      ex.printStackTrace();\r
+        }\r
+      }\r
+\r
+      );\r
+\r
+      fetcher.start();\r
     }\r
-    allBatchesComplete = true;\r
   }\r
 \r
-  void waitTillBatchComplete()\r
+  /**\r
+   * creates a jalview sequence feature from a das feature document\r
+   * @param dasfeature\r
+   * @return sequence feature object created using dasfeature information\r
+   */\r
+  SequenceFeature newSequenceFeature(Map dasfeature, String nickname)\r
   {\r
-    while( threadsRunning > 0 )\r
+    try\r
     {\r
-      try{\r
-        Thread.sleep(500);\r
-\r
-      }catch(Exception ex)\r
+      /**\r
+       * Different qNames for a DAS Feature - are string keys to the HashMaps in features\r
+       * "METHOD") ||\r
+                  qName.equals("TYPE") ||\r
+                  qName.equals("START") ||\r
+                  qName.equals("END") ||\r
+                  qName.equals("NOTE") ||\r
+                  qName.equals("LINK") ||\r
+                  qName.equals("SCORE")\r
+       */\r
+      String desc = new String();\r
+      if (dasfeature.containsKey("NOTE"))\r
+        desc += (String) dasfeature.get("NOTE");\r
+\r
+      int start = 0, end = 0;\r
+      float score = 0f;\r
+\r
+      try\r
       {\r
-        ex.printStackTrace();\r
+        start = Integer.parseInt(dasfeature.get("START").toString());\r
+      }\r
+      catch (Exception ex)\r
+      {}\r
+      try\r
+      {\r
+        end = Integer.parseInt(dasfeature.get("END").toString());\r
+      }\r
+      catch (Exception ex)\r
+      {}\r
+      try\r
+      {\r
+        score = Integer.parseInt(dasfeature.get("SCORE").toString());\r
+      }\r
+      catch (Exception ex)\r
+      {}\r
+\r
+      SequenceFeature f = new SequenceFeature(\r
+          (String) dasfeature.get("TYPE"),\r
+          desc,\r
+          start,\r
+          end,\r
+          score,\r
+          nickname);\r
+\r
+      if (dasfeature.containsKey("LINK"))\r
+      {\r
+        f.addLink(f.getType() + " " + f.begin + "_" + f.end\r
+                  + "|" + dasfeature.get("LINK"));\r
       }\r
-    }\r
 \r
+      return f;\r
+    }\r
+    catch (Exception e)\r
+    {\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
   }\r
 \r
-\r
   public static DasSource[] getDASSources()\r
   {\r
     DasSourceReaderImpl reader = new DasSourceReaderImpl();\r
 \r
-    String registryURL =jalview.bin.Cache.getDefault("DAS_REGISTRY_URL",\r
+    String registryURL = jalview.bin.Cache.getDefault("DAS_REGISTRY_URL",\r
         "http://das.sanger.ac.uk/registry/das1/sources/"\r
-      );\r
+        );\r
 \r
     try\r
     {\r
@@ -497,8 +478,7 @@ public class DasSequenceFeatureFetcher implements Runnable
       ex.printStackTrace();\r
       return null;\r
     }\r
-\r
   }\r
-}\r
 \r
+}\r
 \r