732c072bed2c570b0546a88966d57219edfa0f25
[jalview.git] / src / jalview / io / WSWUBlastClient.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.0b1)
3  * Copyright (C) 2014 The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
10  *  
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  * The Jalview Authors are detailed in the 'AUTHORS' file.
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 jalview.util.MessageManager;
29 import uk.ac.ebi.www.*;
30
31 /**
32  * DOCUMENT ME!
33  * 
34  * @author $author$
35  * @version $Revision$
36  */
37 public class WSWUBlastClient
38 {
39   AlignmentPanel ap;
40
41   AlignmentI al;
42
43   CutAndPasteTransfer output = new CutAndPasteTransfer();
44
45   int jobsRunning = 0;
46
47   Vector suggestedIds = new Vector();
48
49   /**
50    * Creates a new WSWUBlastClient object.
51    * 
52    * @param al
53    *          DOCUMENT ME!
54    * @param ids
55    *          DOCUMENT ME!
56    */
57   public WSWUBlastClient(AlignmentPanel ap, AlignmentI al, ArrayList ids)
58   {
59     this.ap = ap;
60     this.al = al;
61     output.setText(MessageManager.getString("label.wswublast_client_credits"));
62
63     Desktop.addInternalFrame(output,
64             MessageManager.getString("label.blasting_for_unidentified_sequence"), 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
84    *          DOCUMENT ME!
85    * @param res
86    *          DOCUMENT ME!
87    */
88   void parseResult(Sequence seq, String res)
89   {
90     StringTokenizer st = new StringTokenizer(res, "\n");
91     String data;
92     String id2;
93     int maxFound = 90;
94     StringBuffer buffer = new StringBuffer("\n\n" + seq.getName() + " :");
95
96     while (st.hasMoreTokens())
97     {
98       data = st.nextToken();
99
100       if (data.indexOf(">UNIPROT") > -1)
101       {
102         int index = data.indexOf(">UNIPROT") + 9;
103         id2 = data.substring(index, data.indexOf(" ", index));
104
105         boolean identitiesFound = false;
106         while (!identitiesFound)
107         {
108           data = st.nextToken();
109
110           if (data.indexOf("Identities") > -1)
111           {
112             identitiesFound = true;
113
114             int value = Integer.parseInt(data.substring(
115                     data.indexOf("(") + 1, data.indexOf("%")));
116
117             if (value >= maxFound)
118             {
119               maxFound = value;
120               buffer.append(" " + id2 + " " + value + "%; ");
121               suggestedIds.addElement(new Object[]
122               { seq, id2 });
123             }
124           }
125         }
126       }
127     }
128
129     output.appendText(buffer.toString());
130   }
131
132   void updateIds()
133   {
134     // This must be outside the run() body as java 1.5
135     // will not return any value from the OptionPane to the expired thread.
136     int reply = JOptionPane.showConfirmDialog(Desktop.desktop,
137             "Automatically update suggested ids?",
138             "Auto replace sequence ids", JOptionPane.YES_NO_OPTION);
139
140     if (reply == JOptionPane.YES_OPTION)
141     {
142       Enumeration keys = suggestedIds.elements();
143       while (keys.hasMoreElements())
144       {
145         Object[] object = (Object[]) keys.nextElement();
146
147         Sequence oldseq = (Sequence) object[0];
148
149         oldseq.setName(object[1].toString());
150
151         // Oldseq is actually in the dataset, we must find the
152         // Visible seq and change its name also.
153         for (int i = 0; i < al.getHeight(); i++)
154         {
155           if (al.getSequenceAt(i).getDatasetSequence() == oldseq)
156           {
157             al.getSequenceAt(i).setName(oldseq.getName());
158             break;
159           }
160         }
161
162         DBRefEntry[] entries = oldseq.getDBRef();
163         if (entries != null)
164         {
165           oldseq.addDBRef(new jalview.datamodel.DBRefEntry(
166                   jalview.datamodel.DBRefSource.UNIPROT, "0", entries[0]
167                           .getAccessionId()));
168         }
169       }
170     }
171     ap.paintAlignment(true);
172
173   }
174
175   class ImageTwirler extends Thread
176   {
177     ImageIcon[] imageIcon;
178
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(
188                 "/images/dna" + (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         } catch (Exception ex)
210         {
211         }
212       }
213
214       if (jobsRunning == 0)
215       {
216         updateIds();
217       }
218     }
219   }
220
221   class BlastThread extends Thread
222   {
223     Sequence sequence;
224
225     String jobid;
226
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         } catch (Exception ex)
261         {
262         }
263       }
264     }
265
266     void StartJob()
267     {
268       InputParams params = new InputParams();
269
270       params.setProgram("blastp");
271       params.setDatabase("uniprot");
272       params.setMatrix("pam10");
273
274       params.setNumal(5);
275       params.setSensitivity("low");
276       params.setSort("totalscore");
277       params.setOutformat("txt");
278       params.setAsync(true);
279
280       try
281       {
282         Data inputs[] = new Data[1];
283         Data input = new Data();
284         input.setType("sequence");
285         input.setContent(AlignSeq.extractGaps("-. ",
286                 sequence.getSequenceAsString()));
287         inputs[0] = input;
288
289         WSWUBlastService service = new WSWUBlastServiceLocator();
290         WSWUBlast wublast = service.getWSWUBlast();
291         jobid = wublast.runWUBlast(params, inputs);
292       } catch (Exception exp)
293       {
294         jobComplete = true;
295         jobsRunning--;
296         System.err.println("WSWUBlastClient error:\n" + exp.toString());
297         exp.printStackTrace();
298       }
299     }
300   }
301 }