Formatting
[jalview.git] / src / jalview / io / WSWUBlastClient.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2007 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 java.util.*;\r
22 \r
23 import javax.swing.*;\r
24 \r
25 import jalview.analysis.*;\r
26 import jalview.datamodel.*;\r
27 import jalview.gui.*;\r
28 import uk.ac.ebi.www.*;\r
29 \r
30 /**\r
31  * DOCUMENT ME!\r
32  *\r
33  * @author $author$\r
34  * @version $Revision$\r
35  */\r
36 public class WSWUBlastClient\r
37 {\r
38   AlignmentPanel ap;\r
39   AlignmentI al;\r
40   CutAndPasteTransfer output = new CutAndPasteTransfer();\r
41   int jobsRunning = 0;\r
42 \r
43   Vector suggestedIds = new Vector();\r
44   /**\r
45    * Creates a new WSWUBlastClient object.\r
46    *\r
47    * @param al DOCUMENT ME!\r
48    * @param ids DOCUMENT ME!\r
49    */\r
50   public WSWUBlastClient(AlignmentPanel ap, AlignmentI al, ArrayList ids)\r
51   {\r
52     this.ap = ap;\r
53     this.al = al;\r
54     output.setText(\r
55         "To display sequence features an exact Uniprot id with 100% sequence identity match must be entered."\r
56         + "\nIn order to display these features, try changing the names of your sequences to the ids suggested below."\r
57         + "\n\nRunning WSWUBlast at EBI."\r
58         + "\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
59         +\r
60         "\nSOAP-based services provided by the European Bioinformatics Institute."\r
61         + "\nNucleic Acids Res. 33(1):W25-W28 (2005));");\r
62 \r
63     Desktop.addInternalFrame(output,\r
64                              "BLASTing for unidentified sequences ", 800, 300);\r
65 \r
66     for (int i = 0; i < ids.size(); i++)\r
67     {\r
68       Sequence sequence = (Sequence) ids.get(i);\r
69       System.out.println(sequence.getName());\r
70 \r
71       BlastThread thread = new BlastThread(sequence);\r
72       thread.start();\r
73       jobsRunning++;\r
74     }\r
75 \r
76     ImageTwirler thread = new ImageTwirler();\r
77     thread.start();\r
78   }\r
79 \r
80   /**\r
81    * DOCUMENT ME!\r
82    *\r
83    * @param id1 DOCUMENT ME!\r
84    * @param res DOCUMENT ME!\r
85    */\r
86   void parseResult(Sequence seq, String res)\r
87   {\r
88     StringTokenizer st = new StringTokenizer(res, "\n");\r
89     String data;\r
90     String id2;\r
91     int maxFound = 90;\r
92     StringBuffer buffer = new StringBuffer("\n\n" + seq.getName() + " :");\r
93 \r
94     while (st.hasMoreTokens())\r
95     {\r
96       data = st.nextToken();\r
97 \r
98       if (data.indexOf(">UNIPROT") > -1)\r
99       {\r
100         int index = data.indexOf(">UNIPROT") + 9;\r
101         id2 = data.substring(index, data.indexOf(" ", index));\r
102 \r
103         boolean identitiesFound = false;\r
104         while (!identitiesFound)\r
105         {\r
106           data = st.nextToken();\r
107 \r
108           if (data.indexOf("Identities") > -1)\r
109           {\r
110             identitiesFound = true;\r
111 \r
112             int value = Integer.parseInt(data.substring(data.indexOf(\r
113                 "(") + 1,\r
114                 data.indexOf("%")));\r
115 \r
116             if (value >= maxFound)\r
117             {\r
118               maxFound = value;\r
119               buffer.append(" " + id2 + " " + value + "%; ");\r
120               suggestedIds.addElement(new Object[]\r
121                                       {seq, id2});\r
122             }\r
123           }\r
124         }\r
125       }\r
126     }\r
127 \r
128     output.appendText(buffer.toString());\r
129   }\r
130 \r
131   void updateIds()\r
132   {\r
133     // This must be outside the run() body as java 1.5\r
134     // will not return any value from the OptionPane to the expired thread.\r
135     int reply = JOptionPane.showConfirmDialog(\r
136         Desktop.desktop, "Automatically update suggested ids?",\r
137         "Auto replace sequence ids", JOptionPane.YES_NO_OPTION);\r
138 \r
139     if (reply == JOptionPane.YES_OPTION)\r
140     {\r
141       Enumeration keys = suggestedIds.elements();\r
142       while (keys.hasMoreElements())\r
143       {\r
144         Object[] object = (Object[]) keys.nextElement();\r
145 \r
146         Sequence oldseq = (Sequence) object[0];\r
147 \r
148         oldseq.setName(object[1].toString());\r
149 \r
150         // Oldseq is actually in the dataset, we must find the\r
151         // Visible seq and change its name also.\r
152         for (int i = 0; i < al.getHeight(); i++)\r
153         {\r
154           if (al.getSequenceAt(i).getDatasetSequence() == oldseq)\r
155           {\r
156             al.getSequenceAt(i).setName(oldseq.getName());\r
157             break;\r
158           }\r
159         }\r
160 \r
161         DBRefEntry[] entries = oldseq.getDBRef();\r
162         if (entries != null)\r
163         {\r
164           oldseq.addDBRef(new jalview.datamodel.\r
165                           DBRefEntry(jalview.datamodel.DBRefSource.UNIPROT,\r
166                                      "0",\r
167                                      entries[0].getAccessionId()));\r
168         }\r
169       }\r
170     }\r
171     ap.repaint();\r
172 \r
173   }\r
174 \r
175   class ImageTwirler\r
176       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\r
223       extends Thread\r
224   {\r
225     Sequence sequence;\r
226     String jobid;\r
227     boolean jobComplete = false;\r
228 \r
229     BlastThread(Sequence sequence)\r
230     {\r
231       System.out.println("blasting for: " + sequence.getName());\r
232       this.sequence = sequence;\r
233     }\r
234 \r
235     public void run()\r
236     {\r
237       StartJob();\r
238 \r
239       while (!jobComplete)\r
240       {\r
241         try\r
242         {\r
243           WSWUBlastService service = new WSWUBlastServiceLocator();\r
244           WSWUBlast wublast = service.getWSWUBlast();\r
245           WSFile[] results = wublast.getResults(jobid);\r
246 \r
247           if (results != null)\r
248           {\r
249             String result = new String(wublast.poll(jobid, "tooloutput"));\r
250             parseResult(sequence, result);\r
251             jobComplete = true;\r
252             jobsRunning--;\r
253           }\r
254           else\r
255           {\r
256             Thread.sleep(10000);\r
257             System.out.println("WSWuBlastClient: I'm alive " +\r
258                                sequence.getName() + " " + jobid); // log.debug\r
259           }\r
260         }\r
261         catch (Exception ex)\r
262         {\r
263         }\r
264       }\r
265     }\r
266 \r
267     void StartJob()\r
268     {\r
269       InputParams params = new InputParams();\r
270 \r
271       params.setProgram("blastp");\r
272       params.setDatabase("uniprot");\r
273       params.setMatrix("pam10");\r
274 \r
275       params.setNumal(5);\r
276       params.setSensitivity("low");\r
277       params.setSort("totalscore");\r
278       params.setOutformat("txt");\r
279       params.setAsync(true);\r
280 \r
281       try\r
282       {\r
283         Data inputs[] = new Data[1];\r
284         Data input = new Data();\r
285         input.setType("sequence");\r
286         input.setContent(AlignSeq.extractGaps("-. ",\r
287                                               sequence.getSequenceAsString()));\r
288         inputs[0] = input;\r
289 \r
290         WSWUBlastService service = new WSWUBlastServiceLocator();\r
291         WSWUBlast wublast = service.getWSWUBlast();\r
292         jobid = wublast.runWUBlast(params, inputs);\r
293       }\r
294       catch (Exception exp)\r
295       {\r
296         jobComplete = true;\r
297         jobsRunning--;\r
298         System.err.println("WSWUBlastClient error:\n" + exp.toString());\r
299         exp.printStackTrace();\r
300       }\r
301     }\r
302   }\r
303 }\r