8e4532c836e0337318d85435c0ecba49a174a2cf
[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 \r
33 \r
34 /**\r
35  * DOCUMENT ME!\r
36  *\r
37  * @author $author$\r
38  * @version $Revision$\r
39  */\r
40 public class WSWUBlastClient\r
41 {\r
42     AlignmentPanel ap;\r
43     AlignmentI al;\r
44     CutAndPasteTransfer output = new CutAndPasteTransfer();\r
45     int jobsRunning = 0;\r
46 \r
47     Hashtable suggestedIds = new Hashtable();\r
48     /**\r
49      * Creates a new WSWUBlastClient object.\r
50      *\r
51      * @param al DOCUMENT ME!\r
52      * @param ids DOCUMENT ME!\r
53      */\r
54     public WSWUBlastClient(AlignmentPanel ap, AlignmentI al, ArrayList ids)\r
55     {\r
56         this.ap = ap;\r
57         this.al = al;\r
58         output.setText(\r
59             "To display sequence features an exact Uniprot id with 100% sequence identity match must be entered." +\r
60             "\nIn order to display these features, try changing the names of your sequences to the ids suggested below.");\r
61         Desktop.addInternalFrame(output,\r
62             "BLASTing for unidentified sequences ", 800, 300);\r
63 \r
64         for (int i = 0; i < ids.size(); i++)\r
65         {\r
66             SequenceI sequence = al.findName(ids.get(i).toString());\r
67             StringBuffer nonGapped = new StringBuffer();\r
68 \r
69 \r
70             for (int n = 0; n < sequence.getSequence().length(); n++)\r
71             {\r
72                 if (!jalview.util.Comparison.isGap(sequence.getCharAt(n)))\r
73                 {\r
74                     nonGapped.append(sequence.getCharAt(n));\r
75                 }\r
76             }\r
77 \r
78             BlastThread thread = new BlastThread(ids.get(i).toString(),\r
79                     nonGapped.toString());\r
80             thread.start();\r
81             jobsRunning++;\r
82         }\r
83 \r
84         ImageTwirler thread = new ImageTwirler();\r
85         thread.start();\r
86     }\r
87 \r
88 \r
89     /**\r
90      * DOCUMENT ME!\r
91      *\r
92      * @param id1 DOCUMENT ME!\r
93      * @param res DOCUMENT ME!\r
94      */\r
95     void parseResult(String id1, String res)\r
96     {\r
97         StringTokenizer st = new StringTokenizer(res, "\n");\r
98         String data;\r
99         String id2;\r
100         int maxFound = 90;\r
101         StringBuffer buffer = new StringBuffer("\n\n" + id1 + " :");\r
102 \r
103         while (st.hasMoreTokens())\r
104         {\r
105             data = st.nextToken();\r
106 \r
107             if (data.indexOf(">UNIPROT") > -1)\r
108             {\r
109                 int index = data.indexOf(">UNIPROT") + 9;\r
110                 id2 = data.substring(index, data.indexOf(" ", index));\r
111 \r
112                 boolean identitiesFound = false;\r
113                 while (!identitiesFound)\r
114                 {\r
115                     data = st.nextToken();\r
116 \r
117                     if (data.indexOf("Identities") > -1)\r
118                     {\r
119                        identitiesFound = true;\r
120 \r
121                        int value = Integer.parseInt(data.substring(data.indexOf(\r
122                            "(") + 1,\r
123                                                                    data.indexOf("%")));\r
124 \r
125                         if (value >= maxFound)\r
126                         {\r
127                             maxFound = value;\r
128                             buffer.append(" " + id2 + " " + value + "%; ");\r
129                             suggestedIds.put(id1, id2);\r
130                         }\r
131                     }\r
132                 }\r
133             }\r
134         }\r
135 \r
136         output.appendText(buffer.toString());\r
137     }\r
138 \r
139     void updateIds()\r
140     {\r
141       int reply = JOptionPane.showConfirmDialog(\r
142           Desktop.desktop, "Automatically update suggested ids?",\r
143           "Auto replace sequence ids", JOptionPane.YES_NO_OPTION);\r
144 \r
145       if (reply == JOptionPane.YES_OPTION)\r
146       {\r
147         Enumeration keys = suggestedIds.keys();\r
148         while(keys.hasMoreElements())\r
149         {\r
150           String oldid = keys.nextElement().toString();\r
151           SequenceI sequence = al.findName(oldid);\r
152           sequence.setName( suggestedIds.get(oldid).toString() );\r
153 \r
154           sequence = sequence.getDatasetSequence();\r
155           if(sequence!=null)\r
156           {\r
157 \r
158             sequence.setName(suggestedIds.get(oldid).toString());\r
159 \r
160             Vector entries = sequence.getDBRef();\r
161             if(entries!=null)\r
162             {\r
163               DBRefEntry entry = (DBRefEntry) entries.elementAt(0);\r
164               sequence.addDBRef(new jalview.datamodel.DBRefEntry("UNIPROT",\r
165                   "0",\r
166                   entry.getAccessionId()));\r
167             }\r
168           }\r
169           System.out.println("replace "+oldid+" with "+suggestedIds.get(oldid));\r
170         }\r
171       }\r
172       ap.repaint();\r
173 \r
174     }\r
175 \r
176     class ImageTwirler extends Thread\r
177     {\r
178         ImageIcon[] imageIcon;\r
179         int imageIndex = 0;\r
180 \r
181         public ImageTwirler()\r
182         {\r
183             imageIcon = new ImageIcon[9];\r
184 \r
185             for (int i = 0; i < 9; i++)\r
186             {\r
187                 java.net.URL url = getClass().getResource("/images/dna" +\r
188                         (i + 1) + ".gif");\r
189 \r
190                 if (url != null)\r
191                 {\r
192                     imageIcon[i] = new ImageIcon(url);\r
193                 }\r
194             }\r
195         }\r
196 \r
197         public void run()\r
198         {\r
199             while (jobsRunning > 0)\r
200             {\r
201                 try\r
202                 {\r
203                     Thread.sleep(100);\r
204                     imageIndex++;\r
205                     imageIndex %= 9;\r
206                     output.setFrameIcon(imageIcon[imageIndex]);\r
207                     output.setTitle("BLASTing for unidentified sequences - " +\r
208                         jobsRunning + " jobs running.");\r
209                 }\r
210                 catch (Exception ex)\r
211                 {\r
212                 }\r
213             }\r
214 \r
215             if (jobsRunning == 0)\r
216             {\r
217               updateIds();\r
218             }\r
219         }\r
220     }\r
221 \r
222     class BlastThread extends Thread\r
223     {\r
224         String sequence;\r
225         String seqid;\r
226         String jobid;\r
227         boolean jobComplete = false;\r
228 \r
229         BlastThread(String id, String sequence)\r
230         {\r
231           System.out.println("blasting for: "+id);\r
232             this.sequence = sequence;\r
233             seqid = id;\r
234         }\r
235 \r
236         public void run()\r
237         {\r
238             StartJob();\r
239 \r
240             while (!jobComplete)\r
241             {\r
242                 try\r
243                 {\r
244                     Call call = (Call) new Service().createCall();\r
245                     call.setTargetEndpointAddress(new java.net.URL(\r
246                             "http://www.ebi.ac.uk/cgi-bin/webservices/WSWUBlast"));\r
247                     call.setOperationName(new QName("WSWUBlast", "polljob"));\r
248 \r
249                     Object object = (String) call.invoke(new Object[]\r
250                             {\r
251                                 jobid, "xml"\r
252                             });\r
253 \r
254                     if(object instanceof String)\r
255                     {\r
256                       parseResult(seqid, (String)object);\r
257                       jobComplete = true;\r
258                       jobsRunning--;\r
259                     }\r
260 \r
261                     Thread.sleep(5000);\r
262 \r
263                     System.out.println("WSWuBlastClient: I'm alive "+seqid+" "+jobid); // log.debug\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             HashMap params = new HashMap();\r
274             params.put("database", "uniprot");\r
275             params.put("sensitivity", "low");\r
276             params.put("sort", "totalscore");\r
277             params.put("matrix", "pam10");\r
278             params.put("program", "blastp");\r
279             params.put("alignments", "5");\r
280             params.put("type", "xml");\r
281             params.put("async", "true");\r
282 \r
283             byte[] seqbytes = sequence.getBytes();\r
284 \r
285             try\r
286             {\r
287                 Call call = (Call) new Service().createCall();\r
288                 call.setTargetEndpointAddress(new java.net.URL(\r
289                         "http://www.ebi.ac.uk/cgi-bin/webservices/WSWUBlast"));\r
290                 call.setOperationName(new QName("WSWUBlast", "doWUBlast"));\r
291 \r
292                 Object object = call.invoke(new Object[]\r
293                         {\r
294                             params, seqbytes\r
295                         });\r
296 \r
297                 if(object instanceof byte[])\r
298                   jobid = new String( (byte[])object);\r
299 \r
300                 else\r
301                 {\r
302                   jobComplete = true;\r
303                   jobsRunning--;\r
304                   parseResult(seqid, (String)object);\r
305                 }\r
306 \r
307             }\r
308             catch (Exception exp)\r
309             {\r
310                 System.err.println("WSWUBlastClient error:\n" + exp.toString());\r
311                 exp.printStackTrace();\r
312             }\r
313         }\r
314     }\r
315 }\r