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