JAL-3210 Improvements to eclipse detection. New src tree and SwingJS updated from...
[jalview.git] / src / jalview / io / WSWUBlastClient.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ 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
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.io;
22
23 import jalview.analysis.AlignSeq;
24 import jalview.datamodel.AlignmentI;
25 import jalview.datamodel.DBRefEntry;
26 import jalview.datamodel.Sequence;
27 import jalview.gui.AlignmentPanel;
28 import jalview.gui.CutAndPasteTransfer;
29 import jalview.gui.Desktop;
30 import jalview.gui.JvOptionPane;
31 import jalview.util.MessageManager;
32
33 import java.util.ArrayList;
34 import java.util.Enumeration;
35 import java.util.List;
36 import java.util.StringTokenizer;
37 import java.util.Vector;
38
39 import javax.swing.ImageIcon;
40
41 import uk.ac.ebi.www.Data;
42 import uk.ac.ebi.www.InputParams;
43 import uk.ac.ebi.www.WSFile;
44 import uk.ac.ebi.www.WSWUBlast;
45 import uk.ac.ebi.www.WSWUBlastService;
46 import uk.ac.ebi.www.WSWUBlastServiceLocator;
47
48 /**
49  * DOCUMENT ME!
50  * 
51  * @author $author$
52  * @version $Revision$
53  */
54 public class WSWUBlastClient
55 {
56   AlignmentPanel ap;
57
58   AlignmentI al;
59
60   CutAndPasteTransfer output = new CutAndPasteTransfer();
61
62   int jobsRunning = 0;
63
64   Vector suggestedIds = new Vector();
65
66   /**
67    * Creates a new WSWUBlastClient object.
68    * 
69    * @param al
70    *          DOCUMENT ME!
71    * @param ids
72    *          DOCUMENT ME!
73    */
74   public WSWUBlastClient(AlignmentPanel ap, AlignmentI al, ArrayList ids)
75   {
76     this.ap = ap;
77     this.al = al;
78     output.setText(
79             MessageManager.getString("label.wswublast_client_credits"));
80
81     Desktop.addInternalFrame(output, MessageManager.getString(
82             "label.blasting_for_unidentified_sequence"), 800, 300);
83
84     for (int i = 0; i < ids.size(); i++)
85     {
86       Sequence sequence = (Sequence) ids.get(i);
87       System.out.println(sequence.getName());
88
89       BlastThread thread = new BlastThread(sequence);
90       thread.start();
91       jobsRunning++;
92     }
93
94     ImageTwirler thread = new ImageTwirler();
95     thread.start();
96   }
97
98   /**
99    * DOCUMENT ME!
100    * 
101    * @param id1
102    *          DOCUMENT ME!
103    * @param res
104    *          DOCUMENT ME!
105    */
106   void parseResult(Sequence seq, String res)
107   {
108     StringTokenizer st = new StringTokenizer(res, "\n");
109     String data;
110     String id2;
111     int maxFound = 90;
112     StringBuffer buffer = new StringBuffer("\n\n" + seq.getName() + " :");
113
114     while (st.hasMoreTokens())
115     {
116       data = st.nextToken();
117
118       if (data.indexOf(">UNIPROT") > -1)
119       {
120         int index = data.indexOf(">UNIPROT") + 9;
121         id2 = data.substring(index, data.indexOf(" ", index));
122
123         boolean identitiesFound = false;
124         while (!identitiesFound)
125         {
126           data = st.nextToken();
127
128           if (data.indexOf("Identities") > -1)
129           {
130             identitiesFound = true;
131
132             int value = Integer.parseInt(data
133                     .substring(data.indexOf("(") + 1, data.indexOf("%")));
134
135             if (value >= maxFound)
136             {
137               maxFound = value;
138               buffer.append(" " + id2 + " " + value + "%; ");
139               suggestedIds.addElement(new Object[] { seq, id2 });
140             }
141           }
142         }
143       }
144     }
145
146     output.appendText(buffer.toString());
147   }
148
149   void updateIds()
150   {
151     // This must be outside the run() body as java 1.5
152     // will not return any value from the OptionPane to the expired thread.
153     int reply = JvOptionPane.showConfirmDialog(Desktop.getDesktopPane(),
154             "Automatically update suggested ids?",
155             "Auto replace sequence ids", JvOptionPane.YES_NO_OPTION);
156
157     if (reply == JvOptionPane.YES_OPTION)
158     {
159       Enumeration keys = suggestedIds.elements();
160       while (keys.hasMoreElements())
161       {
162         Object[] object = (Object[]) keys.nextElement();
163
164         Sequence oldseq = (Sequence) object[0];
165
166         oldseq.setName(object[1].toString());
167
168         // Oldseq is actually in the dataset, we must find the
169         // Visible seq and change its name also.
170         for (int i = 0; i < al.getHeight(); i++)
171         {
172           if (al.getSequenceAt(i).getDatasetSequence() == oldseq)
173           {
174             al.getSequenceAt(i).setName(oldseq.getName());
175             break;
176           }
177         }
178
179         List<DBRefEntry> entries = oldseq.getDBRefs();
180         // BH 2019.01.25 check for 0-length was missing here
181         if (entries != null && entries.size() > 0)
182         {
183           oldseq.addDBRef(new jalview.datamodel.DBRefEntry(
184                   jalview.datamodel.DBRefSource.UNIPROT, "0",
185                   entries.get(0).getAccessionId()));
186         }
187       }
188     }
189     ap.paintAlignment(true, false);
190
191   }
192
193   class ImageTwirler extends Thread
194   {
195     ImageIcon[] imageIcon;
196
197     int imageIndex = 0;
198
199     public ImageTwirler()
200     {
201       imageIcon = new ImageIcon[9];
202
203       for (int i = 0; i < 9; i++)
204       {
205         java.net.URL url = getClass()
206                 .getResource("/images/dna" + (i + 1) + ".gif");
207
208         if (url != null)
209         {
210           imageIcon[i] = new ImageIcon(url);
211         }
212       }
213     }
214
215     @Override
216     public void run()
217     {
218       while (jobsRunning > 0)
219       {
220         try
221         {
222           Thread.sleep(100);
223           imageIndex++;
224           imageIndex %= 9;
225           output.setFrameIcon(imageIcon[imageIndex]);
226           output.setTitle(MessageManager.formatMessage(
227                   "label.blasting_for_unidentified_sequence_jobs_running",
228                   new String[]
229                   { Integer.valueOf(jobsRunning).toString() }));
230         } catch (Exception ex)
231         {
232         }
233       }
234
235       if (jobsRunning == 0)
236       {
237         updateIds();
238       }
239     }
240   }
241
242   class BlastThread extends Thread
243   {
244     Sequence sequence;
245
246     String jobid;
247
248     boolean jobComplete = false;
249
250     BlastThread(Sequence sequence)
251     {
252       System.out.println("blasting for: " + sequence.getName());
253       this.sequence = sequence;
254     }
255
256     @Override
257     public void run()
258     {
259       StartJob();
260
261       while (!jobComplete)
262       {
263         try
264         {
265           WSWUBlastService service = new WSWUBlastServiceLocator();
266           WSWUBlast wublast = service.getWSWUBlast();
267           WSFile[] results = wublast.getResults(jobid);
268
269           if (results != null)
270           {
271             String result = new String(wublast.poll(jobid, "tooloutput"));
272             parseResult(sequence, result);
273             jobComplete = true;
274             jobsRunning--;
275           }
276           else
277           {
278             Thread.sleep(10000);
279             System.out.println("WSWuBlastClient: I'm alive "
280                     + sequence.getName() + " " + jobid); // log.debug
281           }
282         } catch (Exception ex)
283         {
284         }
285       }
286     }
287
288     void StartJob()
289     {
290       InputParams params = new InputParams();
291
292       params.setProgram("blastp");
293       params.setDatabase("uniprot");
294       params.setMatrix("pam10");
295
296       params.setNumal(5);
297       params.setSensitivity("low");
298       params.setSort("totalscore");
299       params.setOutformat("txt");
300       params.setAsync(true);
301
302       try
303       {
304         Data inputs[] = new Data[1];
305         Data input = new Data();
306         input.setType("sequence");
307         input.setContent(AlignSeq.extractGaps("-. ",
308                 sequence.getSequenceAsString()));
309         inputs[0] = input;
310
311         WSWUBlastService service = new WSWUBlastServiceLocator();
312         WSWUBlast wublast = service.getWSWUBlast();
313         jobid = wublast.runWUBlast(params, inputs);
314       } catch (Exception exp)
315       {
316         jobComplete = true;
317         jobsRunning--;
318         System.err.println("WSWUBlastClient error:\n" + exp.toString());
319         exp.printStackTrace();
320       }
321     }
322   }
323 }