main method for running from command line and better binary file/archive detection
[jalview.git] / src / jalview / io / WSWUBlastClient.java
index 33d6d92..1d42620 100755 (executable)
@@ -1,37 +1,31 @@
 /*\r
-* Jalview - A Sequence Alignment Editor and Viewer\r
-* Copyright (C) 2005 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) 2007 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
-\r
-import jalview.gui.*;\r
-\r
-import org.apache.axis.client.*;\r
-\r
-import java.awt.*;\r
-\r
 import java.util.*;\r
 \r
 import javax.swing.*;\r
 \r
-import javax.xml.namespace.QName;\r
-\r
+import jalview.analysis.*;\r
+import jalview.datamodel.*;\r
+import jalview.gui.*;\r
+import uk.ac.ebi.www.*;\r
 \r
 /**\r
  * DOCUMENT ME!\r
@@ -41,217 +35,269 @@ import javax.xml.namespace.QName;
  */\r
 public class WSWUBlastClient\r
 {\r
-    CutAndPasteTransfer output = new CutAndPasteTransfer();\r
-    int jobsRunning = 0;\r
-\r
-    /**\r
-     * Creates a new WSWUBlastClient object.\r
-     *\r
-     * @param al DOCUMENT ME!\r
-     * @param ids DOCUMENT ME!\r
-     */\r
-    public WSWUBlastClient(AlignmentI al, ArrayList ids)\r
+  AlignmentPanel ap;\r
+  AlignmentI al;\r
+  CutAndPasteTransfer output = new CutAndPasteTransfer();\r
+  int jobsRunning = 0;\r
+\r
+  Vector suggestedIds = new Vector();\r
+  /**\r
+   * Creates a new WSWUBlastClient object.\r
+   *\r
+   * @param al DOCUMENT ME!\r
+   * @param ids DOCUMENT ME!\r
+   */\r
+  public WSWUBlastClient(AlignmentPanel ap, AlignmentI al, ArrayList ids)\r
+  {\r
+    this.ap = ap;\r
+    this.al = al;\r
+    output.setText(\r
+        "To display sequence features an exact Uniprot id with 100% sequence identity match must be entered."\r
+        + "\nIn order to display these features, try changing the names of your sequences to the ids suggested below."\r
+        + "\n\nRunning WSWUBlast at EBI."\r
+        + "\nPlease quote Pillai S., Silventoinen V., Kallio K., Senger M., Sobhany S., Tate J., Velankar S., Golovin A., Henrick K., Rice P., Stoehr P., Lopez R."\r
+        +\r
+        "\nSOAP-based services provided by the European Bioinformatics Institute."\r
+        + "\nNucleic Acids Res. 33(1):W25-W28 (2005));");\r
+\r
+    Desktop.addInternalFrame(output,\r
+                             "BLASTing for unidentified sequences ", 800, 300);\r
+\r
+    for (int i = 0; i < ids.size(); i++)\r
     {\r
-        output.setText(\r
-            "To display sequence features an exact Uniprot id with 100% sequence identity match must be entered." +\r
-            "\nIn order to display these features, try changing the names of your sequences to the ids suggested below.");\r
-        Desktop.addInternalFrame(output,\r
-            "BLASTing for unidentified sequences ", 800, 300);\r
-\r
-        for (int i = 0; i < ids.size(); i++)\r
-        {\r
-            SequenceI sequence = al.findName(ids.get(i).toString());\r
-            StringBuffer nonGapped = new StringBuffer();\r
+      Sequence sequence = (Sequence) ids.get(i);\r
+      System.out.println(sequence.getName());\r
 \r
-            for (int n = 0; n < sequence.getSequence().length(); n++)\r
-            {\r
-                if (!jalview.util.Comparison.isGap(sequence.getCharAt(n)))\r
-                {\r
-                    nonGapped.append(sequence.getCharAt(n));\r
-                }\r
-            }\r
-\r
-            BlastThread thread = new BlastThread(ids.get(i).toString(),\r
-                    nonGapped.toString());\r
-            thread.start();\r
-            jobsRunning++;\r
-        }\r
-\r
-        ImageTwirler thread = new ImageTwirler();\r
-        thread.start();\r
+      BlastThread thread = new BlastThread(sequence);\r
+      thread.start();\r
+      jobsRunning++;\r
     }\r
 \r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param id1 DOCUMENT ME!\r
-     * @param res DOCUMENT ME!\r
-     */\r
-    void parseResult(String id1, String res)\r
+    ImageTwirler thread = new ImageTwirler();\r
+    thread.start();\r
+  }\r
+\r
+  /**\r
+   * DOCUMENT ME!\r
+   *\r
+   * @param id1 DOCUMENT ME!\r
+   * @param res DOCUMENT ME!\r
+   */\r
+  void parseResult(Sequence seq, String res)\r
+  {\r
+    StringTokenizer st = new StringTokenizer(res, "\n");\r
+    String data;\r
+    String id2;\r
+    int maxFound = 90;\r
+    StringBuffer buffer = new StringBuffer("\n\n" + seq.getName() + " :");\r
+\r
+    while (st.hasMoreTokens())\r
     {\r
-        StringTokenizer st = new StringTokenizer(res, "\n");\r
-        String data;\r
-        String id2;\r
-        int maxFound = 90;\r
-        StringBuffer buffer = new StringBuffer("\n\n" + id1 + " :");\r
+      data = st.nextToken();\r
+\r
+      if (data.indexOf(">UNIPROT") > -1)\r
+      {\r
+        int index = data.indexOf(">UNIPROT") + 9;\r
+        id2 = data.substring(index, data.indexOf(" ", index));\r
 \r
-        while (st.hasMoreTokens())\r
+        boolean identitiesFound = false;\r
+        while (!identitiesFound)\r
         {\r
-            data = st.nextToken();\r
+          data = st.nextToken();\r
+\r
+          if (data.indexOf("Identities") > -1)\r
+          {\r
+            identitiesFound = true;\r
+\r
+            int value = Integer.parseInt(data.substring(data.indexOf(\r
+                "(") + 1,\r
+                data.indexOf("%")));\r
 \r
-            if (data.indexOf("database=\"uniprot\" id=") > -1)\r
+            if (value >= maxFound)\r
             {\r
-                int index = data.indexOf("database=\"uniprot\" id=") + 23;\r
-                id2 = data.substring(index, data.indexOf("\"", index));\r
-\r
-                while (data.indexOf("</alignment>") == -1)\r
-                {\r
-                    data = st.nextToken();\r
-\r
-                    if (data.indexOf("<identity>") > -1)\r
-                    {\r
-                        int value = Integer.parseInt(data.substring(data.indexOf(\r
-                                        "<identity>") + 10,\r
-                                    data.indexOf("</identity>")));\r
-\r
-                        if (value >= maxFound)\r
-                        {\r
-                            maxFound = value;\r
-                            buffer.append(" " + id2 + " " + value + "%; ");\r
-                        }\r
-                    }\r
-                }\r
+              maxFound = value;\r
+              buffer.append(" " + id2 + " " + value + "%; ");\r
+              suggestedIds.addElement(new Object[]\r
+                                      {seq, id2});\r
             }\r
+          }\r
         }\r
-\r
-        output.setText(output.getText() + buffer.toString());\r
+      }\r
     }\r
 \r
-    class ImageTwirler extends Thread\r
+    output.appendText(buffer.toString());\r
+  }\r
+\r
+  void updateIds()\r
+  {\r
+    // This must be outside the run() body as java 1.5\r
+    // will not return any value from the OptionPane to the expired thread.\r
+    int reply = JOptionPane.showConfirmDialog(\r
+        Desktop.desktop, "Automatically update suggested ids?",\r
+        "Auto replace sequence ids", JOptionPane.YES_NO_OPTION);\r
+\r
+    if (reply == JOptionPane.YES_OPTION)\r
     {\r
-        ImageIcon[] imageIcon;\r
-        int imageIndex = 0;\r
+      Enumeration keys = suggestedIds.elements();\r
+      while (keys.hasMoreElements())\r
+      {\r
+        Object[] object = (Object[]) keys.nextElement();\r
 \r
-        public ImageTwirler()\r
-        {\r
-            imageIcon = new ImageIcon[9];\r
+        Sequence oldseq = (Sequence) object[0];\r
 \r
-            for (int i = 0; i < 9; i++)\r
-            {\r
-                java.net.URL url = getClass().getResource("/images/dna" +\r
-                        (i + 1) + ".gif");\r
+        oldseq.setName(object[1].toString());\r
 \r
-                if (url != null)\r
-                {\r
-                    imageIcon[i] = new ImageIcon(url);\r
-                }\r
-            }\r
+        // Oldseq is actually in the dataset, we must find the\r
+        // Visible seq and change its name also.\r
+        for (int i = 0; i < al.getHeight(); i++)\r
+        {\r
+          if (al.getSequenceAt(i).getDatasetSequence() == oldseq)\r
+          {\r
+            al.getSequenceAt(i).setName(oldseq.getName());\r
+            break;\r
+          }\r
         }\r
 \r
-        public void run()\r
+        DBRefEntry[] entries = oldseq.getDBRef();\r
+        if (entries != null)\r
         {\r
-            while (jobsRunning > 0)\r
-            {\r
-                try\r
-                {\r
-                    Thread.sleep(100);\r
-                    imageIndex++;\r
-                    imageIndex %= 9;\r
-                    output.setFrameIcon(imageIcon[imageIndex]);\r
-                    output.setTitle("BLASTing for unidentified sequences - " +\r
-                        jobsRunning + " jobs running.");\r
-                }\r
-                catch (Exception ex)\r
-                {\r
-                }\r
-            }\r
+          oldseq.addDBRef(new jalview.datamodel.\r
+                          DBRefEntry(jalview.datamodel.DBRefSource.UNIPROT,\r
+                                     "0",\r
+                                     entries[0].getAccessionId()));\r
         }\r
+      }\r
     }\r
+    ap.paintAlignment(true);\r
+\r
+  }\r
+\r
+  class ImageTwirler\r
+      extends Thread\r
+  {\r
+    ImageIcon[] imageIcon;\r
+    int imageIndex = 0;\r
 \r
-    class BlastThread extends Thread\r
+    public ImageTwirler()\r
     {\r
-        String sequence;\r
-        String seqid;\r
-        String jobid;\r
-        boolean jobComplete = false;\r
+      imageIcon = new ImageIcon[9];\r
 \r
-        BlastThread(String id, String sequence)\r
+      for (int i = 0; i < 9; i++)\r
+      {\r
+        java.net.URL url = getClass().getResource("/images/dna" +\r
+                                                  (i + 1) + ".gif");\r
+\r
+        if (url != null)\r
         {\r
-            this.sequence = sequence;\r
-            seqid = id;\r
+          imageIcon[i] = new ImageIcon(url);\r
         }\r
+      }\r
+    }\r
 \r
-        public void run()\r
+    public void run()\r
+    {\r
+      while (jobsRunning > 0)\r
+      {\r
+        try\r
+        {\r
+          Thread.sleep(100);\r
+          imageIndex++;\r
+          imageIndex %= 9;\r
+          output.setFrameIcon(imageIcon[imageIndex]);\r
+          output.setTitle("BLASTing for unidentified sequences - " +\r
+                          jobsRunning + " jobs running.");\r
+        }\r
+        catch (Exception ex)\r
         {\r
-            StartJob();\r
-\r
-            while (!jobComplete)\r
-            {\r
-                try\r
-                {\r
-                    Call call = (Call) new Service().createCall();\r
-                    call.setTargetEndpointAddress(new java.net.URL(\r
-                            "http://www.ebi.ac.uk/cgi-bin/webservices/WSWUBlast"));\r
-                    call.setOperationName(new QName("WSWUBlast", "polljob"));\r
-\r
-                    String result = (String) call.invoke(new Object[]\r
-                            {\r
-                                jobid, "xml"\r
-                            });\r
-\r
-                    if ((result.indexOf("JOB PENDING") == -1) &&\r
-                            (result.indexOf("JOB RUNNING") == -1))\r
-                    {\r
-                        parseResult(seqid, result);\r
-                        jobComplete = true;\r
-                        jobsRunning--;\r
-                    }\r
-\r
-                    Thread.sleep(5000);\r
-\r
-                    // System.out.println("WSWuBlastClient: I'm alive "+seqid+" "+jobid); // log.debug\r
-                }\r
-                catch (Exception ex)\r
-                {\r
-                }\r
-            }\r
         }\r
+      }\r
+\r
+      if (jobsRunning == 0)\r
+      {\r
+        updateIds();\r
+      }\r
+    }\r
+  }\r
+\r
+  class BlastThread\r
+      extends Thread\r
+  {\r
+    Sequence sequence;\r
+    String jobid;\r
+    boolean jobComplete = false;\r
 \r
-        void StartJob()\r
+    BlastThread(Sequence sequence)\r
+    {\r
+      System.out.println("blasting for: " + sequence.getName());\r
+      this.sequence = sequence;\r
+    }\r
+\r
+    public void run()\r
+    {\r
+      StartJob();\r
+\r
+      while (!jobComplete)\r
+      {\r
+        try\r
+        {\r
+          WSWUBlastService service = new WSWUBlastServiceLocator();\r
+          WSWUBlast wublast = service.getWSWUBlast();\r
+          WSFile[] results = wublast.getResults(jobid);\r
+\r
+          if (results != null)\r
+          {\r
+            String result = new String(wublast.poll(jobid, "tooloutput"));\r
+            parseResult(sequence, result);\r
+            jobComplete = true;\r
+            jobsRunning--;\r
+          }\r
+          else\r
+          {\r
+            Thread.sleep(10000);\r
+            System.out.println("WSWuBlastClient: I'm alive " +\r
+                               sequence.getName() + " " + jobid); // log.debug\r
+          }\r
+        }\r
+        catch (Exception ex)\r
         {\r
-            HashMap params = new HashMap();\r
-            params.put("database", "uniprot");\r
-            params.put("sensitivity", "low");\r
-            params.put("sort", "totalscore");\r
-            params.put("matrix", "pam10");\r
-            params.put("program", "blastp");\r
-            params.put("alignments", "5");\r
-            params.put("outformat", "xml");\r
-            params.put("searchtype", "1");\r
-\r
-            byte[] seqbytes = sequence.getBytes();\r
-\r
-            try\r
-            {\r
-                Call call = (Call) new Service().createCall();\r
-                call.setTargetEndpointAddress(new java.net.URL(\r
-                        "http://www.ebi.ac.uk/cgi-bin/webservices/WSWUBlast"));\r
-                call.setOperationName(new QName("WSWUBlast", "doWUBlast"));\r
-\r
-                String result = (String) call.invoke(new Object[]\r
-                        {\r
-                            params, seqbytes\r
-                        });\r
-                jobid = result;\r
-                System.out.println(\r
-                    "http://www.ebi.ac.uk/cgi-bin/webservices/WSWUBlast JobId '" +\r
-                    jobid + "'");\r
-            }\r
-            catch (Exception exp)\r
-            {\r
-                System.err.println("WSWUBlastClient error:\n" + exp.toString());\r
-                exp.printStackTrace();\r
-            }\r
         }\r
+      }\r
+    }\r
+\r
+    void StartJob()\r
+    {\r
+      InputParams params = new InputParams();\r
+\r
+      params.setProgram("blastp");\r
+      params.setDatabase("uniprot");\r
+      params.setMatrix("pam10");\r
+\r
+      params.setNumal(5);\r
+      params.setSensitivity("low");\r
+      params.setSort("totalscore");\r
+      params.setOutformat("txt");\r
+      params.setAsync(true);\r
+\r
+      try\r
+      {\r
+        Data inputs[] = new Data[1];\r
+        Data input = new Data();\r
+        input.setType("sequence");\r
+        input.setContent(AlignSeq.extractGaps("-. ",\r
+                                              sequence.getSequenceAsString()));\r
+        inputs[0] = input;\r
+\r
+        WSWUBlastService service = new WSWUBlastServiceLocator();\r
+        WSWUBlast wublast = service.getWSWUBlast();\r
+        jobid = wublast.runWUBlast(params, inputs);\r
+      }\r
+      catch (Exception exp)\r
+      {\r
+        jobComplete = true;\r
+        jobsRunning--;\r
+        System.err.println("WSWUBlastClient error:\n" + exp.toString());\r
+        exp.printStackTrace();\r
+      }\r
     }\r
+  }\r
 }\r