after merge
[jalview.git] / src / jalview / io / WSWUBlastClient.java
1 /*\r
2 * Jalview - A Sequence Alignment Editor and Viewer\r
3 * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4 *\r
5 * This program is free software; you can redistribute it and/or\r
6 * modify it under the terms of the GNU General Public License\r
7 * as published by the Free Software Foundation; either version 2\r
8 * of the License, or (at your option) any later version.\r
9 *\r
10 * This program is distributed in the hope that it will be useful,\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 * GNU General Public License for more details.\r
14 *\r
15 * You should have received a copy of the GNU General Public License\r
16 * along with this program; if not, write to the Free Software\r
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18 */\r
19 package jalview.io;\r
20 \r
21 import jalview.datamodel.*;\r
22 \r
23 import jalview.gui.*;\r
24 \r
25 import org.apache.axis.client.*;\r
26 \r
27 import java.util.*;\r
28 \r
29 import javax.swing.*;\r
30 \r
31 import javax.xml.namespace.QName;\r
32 import jalview.analysis.AlignSeq;\r
33 \r
34 import uk.ac.ebi.www.*;\r
35 \r
36 /**\r
37  * DOCUMENT ME!\r
38  *\r
39  * @author $author$\r
40  * @version $Revision$\r
41  */\r
42 public class WSWUBlastClient\r
43 {\r
44     AlignmentPanel ap;\r
45     AlignmentI al;\r
46     CutAndPasteTransfer output = new CutAndPasteTransfer();\r
47     int jobsRunning = 0;\r
48 \r
49     Vector suggestedIds = new Vector();\r
50     /**\r
51      * Creates a new WSWUBlastClient object.\r
52      *\r
53      * @param al DOCUMENT ME!\r
54      * @param ids DOCUMENT ME!\r
55      */\r
56     public WSWUBlastClient(AlignmentPanel ap, AlignmentI al, ArrayList ids)\r
57     {\r
58         this.ap = ap;\r
59         this.al = al;\r
60         output.setText(\r
61             "To display sequence features an exact Uniprot id with 100% sequence identity match must be entered."\r
62             +"\nIn order to display these features, try changing the names of your sequences to the ids suggested below."\r
63             +"\n\nRunning WSWUBlast at EBI."\r
64             +"\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
65             +"\nSOAP-based services provided by the European Bioinformatics Institute."\r
66             +"\nNucleic Acids Res. 33(1):W25-W28 (2005));");\r
67 \r
68         Desktop.addInternalFrame(output,\r
69             "BLASTing for unidentified sequences ", 800, 300);\r
70 \r
71         for (int i = 0; i < ids.size(); i++)\r
72         {\r
73             Sequence sequence = (Sequence)ids.get(i);\r
74             System.out.println(sequence.getName());\r
75 \r
76             BlastThread thread = new BlastThread(sequence);\r
77             thread.start();\r
78             jobsRunning++;\r
79         }\r
80 \r
81         ImageTwirler thread = new ImageTwirler();\r
82         thread.start();\r
83     }\r
84 \r
85 \r
86     /**\r
87      * DOCUMENT ME!\r
88      *\r
89      * @param id1 DOCUMENT ME!\r
90      * @param res DOCUMENT ME!\r
91      */\r
92     void parseResult(Sequence seq, String res)\r
93     {\r
94         StringTokenizer st = new StringTokenizer(res, "\n");\r
95         String data;\r
96         String id2;\r
97         int maxFound = 90;\r
98         StringBuffer buffer = new StringBuffer("\n\n" + seq.getName() + " :");\r
99 \r
100         while (st.hasMoreTokens())\r
101         {\r
102             data = st.nextToken();\r
103 \r
104             if (data.indexOf(">UNIPROT") > -1)\r
105             {\r
106                 int index = data.indexOf(">UNIPROT") + 9;\r
107                 id2 = data.substring(index, data.indexOf(" ", index));\r
108 \r
109                 boolean identitiesFound = false;\r
110                 while (!identitiesFound)\r
111                 {\r
112                     data = st.nextToken();\r
113 \r
114                     if (data.indexOf("Identities") > -1)\r
115                     {\r
116                        identitiesFound = true;\r
117 \r
118                        int value = Integer.parseInt(data.substring(data.indexOf(\r
119                            "(") + 1,\r
120                                                                    data.indexOf("%")));\r
121 \r
122                         if (value >= maxFound)\r
123                         {\r
124                             maxFound = value;\r
125                             buffer.append(" " + id2 + " " + value + "%; ");\r
126                             suggestedIds.addElement( new Object[]{seq, id2});\r
127                         }\r
128                     }\r
129                 }\r
130             }\r
131         }\r
132 \r
133         output.appendText(buffer.toString());\r
134     }\r
135 \r
136     void updateIds()\r
137     {\r
138         // This must be outside the run() body as java 1.5\r
139      // will not return any value from the OptionPane to the expired thread.\r
140       int reply = JOptionPane.showConfirmDialog(\r
141           Desktop.desktop, "Automatically update suggested ids?",\r
142           "Auto replace sequence ids", JOptionPane.YES_NO_OPTION);\r
143 \r
144       if (reply == JOptionPane.YES_OPTION)\r
145       {\r
146         Enumeration keys = suggestedIds.elements();\r
147         while(keys.hasMoreElements())\r
148         {\r
149           Object [] object = (Object[])keys.nextElement();\r
150 \r
151           Sequence oldseq = (Sequence)object[0];\r
152 \r
153           oldseq.setName( object[1].toString() );\r
154 \r
155           // Oldseq is actually in the dataset, we must find the\r
156           // Visible seq and change its name also.\r
157           for (int i = 0; i < al.getHeight(); i++)\r
158           {\r
159             if (al.getSequenceAt(i).getDatasetSequence() == oldseq)\r
160             {\r
161               al.getSequenceAt(i).setName(oldseq.getName());\r
162               break;\r
163             }\r
164           }\r
165 \r
166           Vector entries = oldseq.getDBRef();\r
167           if (entries != null)\r
168           {\r
169             DBRefEntry entry = (DBRefEntry) entries.elementAt(0);\r
170             oldseq.addDBRef(new jalview.datamodel.\r
171                                                  DBRefEntry("UNIPROT",\r
172                 "0",\r
173                 entry.getAccessionId()));\r
174           }\r
175         }\r
176       }\r
177       ap.repaint();\r
178 \r
179     }\r
180 \r
181     class ImageTwirler extends Thread\r
182     {\r
183         ImageIcon[] imageIcon;\r
184         int imageIndex = 0;\r
185 \r
186         public ImageTwirler()\r
187         {\r
188             imageIcon = new ImageIcon[9];\r
189 \r
190             for (int i = 0; i < 9; i++)\r
191             {\r
192                 java.net.URL url = getClass().getResource("/images/dna" +\r
193                         (i + 1) + ".gif");\r
194 \r
195                 if (url != null)\r
196                 {\r
197                     imageIcon[i] = new ImageIcon(url);\r
198                 }\r
199             }\r
200         }\r
201 \r
202         public void run()\r
203         {\r
204             while (jobsRunning > 0)\r
205             {\r
206                 try\r
207                 {\r
208                     Thread.sleep(100);\r
209                     imageIndex++;\r
210                     imageIndex %= 9;\r
211                     output.setFrameIcon(imageIcon[imageIndex]);\r
212                     output.setTitle("BLASTing for unidentified sequences - " +\r
213                         jobsRunning + " jobs running.");\r
214                 }\r
215                 catch (Exception ex)\r
216                 {\r
217                 }\r
218             }\r
219 \r
220             if (jobsRunning == 0)\r
221             {\r
222               updateIds();\r
223             }\r
224         }\r
225     }\r
226 \r
227     class BlastThread extends Thread\r
228     {\r
229         Sequence sequence;\r
230         String jobid;\r
231         boolean jobComplete = false;\r
232 \r
233         BlastThread(Sequence sequence)\r
234         {\r
235           System.out.println("blasting for: "+sequence.getName());\r
236           this.sequence = sequence;\r
237         }\r
238 \r
239         public void run()\r
240         {\r
241             StartJob();\r
242 \r
243             while (!jobComplete)\r
244             {\r
245                 try\r
246                 {\r
247                   WSWUBlastService service =  new WSWUBlastServiceLocator();\r
248                   WSWUBlast wublast = service.getWSWUBlast();\r
249                   WSFile[] results = wublast.getResults(jobid);\r
250 \r
251                   if(results!=null)\r
252                   {\r
253                       String result = new String(wublast.poll(jobid, "tooloutput"));\r
254                       parseResult(sequence, result);\r
255                       jobComplete = true;\r
256                       jobsRunning--;\r
257                   }\r
258                   else\r
259                   {\r
260                     Thread.sleep(10000);\r
261                     System.out.println("WSWuBlastClient: I'm alive " +\r
262                                        sequence.getName() + " " + jobid); // log.debug\r
263                   }\r
264                 }\r
265                 catch (Exception ex)\r
266                 {\r
267                 }\r
268             }\r
269         }\r
270 \r
271         void StartJob()\r
272         {\r
273           InputParams params = new InputParams();\r
274 \r
275           params.setProgram("blastp");\r
276           params.setDatabase("uniprot");\r
277           params.setMatrix("pam10");\r
278 \r
279           params.setNumal(5);\r
280           params.setSensitivity("low");\r
281           params.setSort("totalscore");\r
282           params.setOutformat("txt");\r
283           params.setAsync(true);\r
284 \r
285             try\r
286             {\r
287               Data inputs[] = new Data[1];\r
288               Data input= new Data();\r
289               input.setType("sequence");\r
290               input.setContent(AlignSeq.extractGaps("-. ",sequence.getSequence()));\r
291               inputs[0]=input;\r
292 \r
293               WSWUBlastService service = new WSWUBlastServiceLocator();\r
294               WSWUBlast wublast = service.getWSWUBlast();\r
295               jobid = wublast.runWUBlast(params, inputs);\r
296             }\r
297             catch (Exception exp)\r
298             {\r
299               jobComplete = true;\r
300               jobsRunning--;\r
301               System.err.println("WSWUBlastClient error:\n" + exp.toString());\r
302               exp.printStackTrace();\r
303             }\r
304         }\r
305     }\r
306 }\r