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