8fff195e84c72f7038543e4035e96aa1330e0e71
[jalview.git] / src / jalview / ws / jws1 / JPredClient.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
3  * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
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  */
18 package jalview.ws.jws1;
19
20 import java.awt.event.ActionEvent;
21 import java.awt.event.ActionListener;
22 import java.util.*;
23
24 import javax.swing.*;
25
26 import ext.vamsas.*;
27 import jalview.analysis.*;
28 import jalview.bin.*;
29 import jalview.datamodel.*;
30 import jalview.gui.*;
31
32 public class JPredClient extends WS1Client
33 {
34   /**
35    * crate a new GUI JPred Job
36    * 
37    * @param sh
38    *          ServiceHandle
39    * @param title
40    *          String
41    * @param msa
42    *          boolean - true - submit alignment as a sequence profile
43    * @param alview
44    *          AlignmentView
45    * @param viewonly
46    *          TODO
47    */
48   public JPredClient(ext.vamsas.ServiceHandle sh, String title,
49           boolean msa, AlignmentView alview, AlignFrame parentFrame,
50           boolean viewonly)
51   {
52     super();
53     wsInfo = setWebService(sh);
54     startJPredClient(title, msa, alview, parentFrame, viewonly);
55
56   }
57
58   /**
59    * startJPredClient TODO: refine submission to cope with local prediction of
60    * visible regions or multiple single sequence jobs TODO: sequence
61    * representative support - could submit alignment of representatives as msa.
62    * TODO: msa hidden region prediction - submit each chunk for prediction.
63    * concatenate results of each. TODO: single seq prediction - submit each
64    * contig of each sequence for prediction (but must cope with flanking regions
65    * and short seqs)
66    * 
67    * @param title
68    *          String
69    * @param msa
70    *          boolean
71    * @param alview
72    *          AlignmentView
73    * @param viewonly
74    *          if true then the prediction will be made just on the concatenated
75    *          visible regions
76    */
77   private void startJPredClient(String title, boolean msa,
78           jalview.datamodel.AlignmentView alview, AlignFrame parentFrame,
79           boolean viewonly)
80   {
81     AlignmentView input = alview;
82     if (wsInfo == null)
83     {
84       wsInfo = setWebService();
85     }
86     Jpred server = locateWebService();
87     if (server == null)
88     {
89       Cache.log.warn("Couldn't find a Jpred webservice to invoke!");
90       return;
91     }
92     SeqCigar[] msf = null;
93     SequenceI seq = null;
94     int[] delMap = null;
95     // original JNetClient behaviour - submit full length of sequence or profile
96     // and mask result.
97     msf = input.getSequences();
98     seq = msf[0].getSeq('-');
99
100     if (viewonly)
101     {
102       int[] viscontigs = alview.getVisibleContigs();
103       int spos = 0;
104       int i = 0;
105       if (viscontigs != null)
106       {
107         // Construct the delMap - mapping from the positions within the input to
108         // Jnet to the contigs in the original sequence
109
110         delMap = new int[seq.getEnd() - seq.getStart() + 1];
111         int gapMap[] = seq.gapMap();
112         for (int contig = 0; contig < viscontigs.length; contig += 2)
113         {
114
115           while (spos < gapMap.length && gapMap[spos] < viscontigs[contig])
116           {
117             spos++;
118           }
119           while (spos < gapMap.length
120                   && gapMap[spos] <= viscontigs[contig + 1])
121           {
122             delMap[i++] = spos++;
123           }
124         }
125         int tmap[] = new int[i];
126         System.arraycopy(delMap, 0, tmap, 0, i);
127         delMap = tmap;
128       }
129     }
130     if (msa && msf.length > 1)
131     {
132
133       String altitle = getPredictionName(WebServiceName) + " on "
134               + (viewonly ? "visible " : "") + seq.getName()
135               + " using alignment from " + title;
136
137       SequenceI aln[] = new SequenceI[msf.length];
138       for (int i = 0, j = msf.length; i < j; i++)
139       {
140         aln[i] = msf[i].getSeq('-');
141       }
142
143       Hashtable SequenceInfo = jalview.analysis.SeqsetUtils.uniquify(aln,
144               true);
145       if (viewonly)
146       {
147         // Remove hidden regions from sequence objects.
148         String seqs[] = alview.getSequenceStrings('-');
149         for (int i = 0, j = msf.length; i < j; i++)
150         {
151           aln[i].setSequence(seqs[i]);
152         }
153         seq.setSequence(seqs[0]);
154       }
155       wsInfo.setProgressText("Job details for "
156               + (viewonly ? "visible " : "") + "MSA based prediction ("
157               + title + ") on sequence :\n>" + seq.getName() + "\n"
158               + AlignSeq.extractGaps("-. ", seq.getSequenceAsString())
159               + "\n");
160       JPredThread jthread = new JPredThread(wsInfo, altitle, server,
161               SequenceInfo, aln, delMap, alview, parentFrame, WsURL);
162       wsInfo.setthisService(jthread);
163       jthread.start();
164     }
165     else
166     {
167       if (!msa && msf.length > 1)
168       {
169         throw new Error(
170                 "Implementation Error! Multiple single sequence prediction jobs are not yet supported.");
171       }
172
173       String altitle = getPredictionName(WebServiceName) + " for "
174               + (viewonly ? "visible " : "") + "sequence " + seq.getName()
175               + " from " + title;
176       String seqname = seq.getName();
177       Hashtable SequenceInfo = jalview.analysis.SeqsetUtils
178               .SeqCharacterHash(seq);
179       if (viewonly)
180       {
181         // Remove hidden regions from input sequence
182         String seqs[] = alview.getSequenceStrings('-');
183         seq.setSequence(seqs[0]);
184       }
185       wsInfo.setProgressText("Job details for prediction on "
186               + (viewonly ? "visible " : "") + "sequence :\n>" + seqname
187               + "\n"
188               + AlignSeq.extractGaps("-. ", seq.getSequenceAsString())
189               + "\n");
190       JPredThread jthread = new JPredThread(wsInfo, altitle, server, WsURL,
191               SequenceInfo, seq, delMap, alview, parentFrame);
192       wsInfo.setthisService(jthread);
193       jthread.start();
194     }
195   }
196
197   private String getPredictionName(String webServiceName)
198   {
199     if (webServiceName.toLowerCase().indexOf(
200             "secondary structure prediction") > -1)
201     {
202       return webServiceName;
203     }
204     else
205     {
206       return webServiceName + "secondary structure prediction";
207     }
208   }
209
210   public JPredClient(ext.vamsas.ServiceHandle sh, String title,
211           SequenceI seq, AlignFrame parentFrame)
212   {
213     super();
214     wsInfo = setWebService(sh);
215     startJPredClient(title, seq, parentFrame);
216   }
217
218   public JPredClient(ext.vamsas.ServiceHandle sh, String title,
219           SequenceI[] msa, AlignFrame parentFrame)
220   {
221     wsInfo = setWebService(sh);
222     startJPredClient(title, msa, parentFrame);
223   }
224
225   public JPredClient(String title, SequenceI[] msf)
226   {
227     startJPredClient(title, msf, null);
228   }
229
230   public JPredClient(String title, SequenceI seq)
231   {
232     startJPredClient(title, seq, null);
233   }
234
235   public JPredClient()
236   {
237
238     super();
239     // add a class reference to the list
240   }
241
242   private void startJPredClient(String title, SequenceI[] msf,
243           AlignFrame parentFrame)
244   {
245     if (wsInfo == null)
246     {
247       wsInfo = setWebService();
248     }
249
250     SequenceI seq = msf[0];
251
252     String altitle = "JNet prediction on " + seq.getName()
253             + " using alignment from " + title;
254
255     wsInfo.setProgressText("Job details for MSA based prediction (" + title
256             + ") on sequence :\n>" + seq.getName() + "\n"
257             + AlignSeq.extractGaps("-. ", seq.getSequenceAsString()) + "\n");
258     SequenceI aln[] = new SequenceI[msf.length];
259     for (int i = 0, j = msf.length; i < j; i++)
260     {
261       aln[i] = new jalview.datamodel.Sequence(msf[i]);
262     }
263
264     Hashtable SequenceInfo = jalview.analysis.SeqsetUtils.uniquify(aln,
265             true);
266
267     Jpred server = locateWebService();
268     if (server == null)
269     {
270       return;
271     }
272
273     JPredThread jthread = new JPredThread(wsInfo, altitle, server,
274             SequenceInfo, aln, null, null, parentFrame, WsURL);
275     wsInfo.setthisService(jthread);
276     jthread.start();
277   }
278
279   public void startJPredClient(String title, SequenceI seq,
280           AlignFrame parentFrame)
281   {
282     if (wsInfo == null)
283     {
284       wsInfo = setWebService();
285     }
286     wsInfo.setProgressText("Job details for prediction on sequence :\n>"
287             + seq.getName() + "\n"
288             + AlignSeq.extractGaps("-. ", seq.getSequenceAsString()) + "\n");
289     String altitle = "JNet prediction for sequence " + seq.getName()
290             + " from " + title;
291
292     Hashtable SequenceInfo = jalview.analysis.SeqsetUtils
293             .SeqCharacterHash(seq);
294
295     Jpred server = locateWebService();
296     if (server == null)
297     {
298       return;
299     }
300
301     JPredThread jthread = new JPredThread(wsInfo, altitle, server, WsURL,
302             SequenceInfo, seq, null, null, parentFrame);
303     wsInfo.setthisService(jthread);
304     jthread.start();
305   }
306
307   private WebserviceInfo setWebService()
308   {
309     WebServiceName = "JNetWS";
310     WebServiceJobTitle = "JNet secondary structure prediction";
311     WebServiceReference = "\"Cuff J. A and Barton G.J (2000) Application of "
312             + "multiple sequence alignment profiles to improve protein secondary structure prediction, "
313             + "Proteins 40:502-511\".";
314     WsURL = "http://www.compbio.dundee.ac.uk/JalviewWS/services/jpred";
315
316     WebserviceInfo wsInfo = new WebserviceInfo(WebServiceJobTitle,
317             WebServiceReference);
318
319     return wsInfo;
320   }
321
322   private ext.vamsas.Jpred locateWebService()
323   {
324     ext.vamsas.JpredServiceLocator loc = new JpredServiceLocator(); // Default
325     ext.vamsas.Jpred server = null;
326     try
327     {
328       server = loc.getjpred(new java.net.URL(WsURL)); // JBPNote will be set
329       // from properties
330       ((JpredSoapBindingStub) server).setTimeout(60000); // one minute stub
331       // ((JpredSoapBindingStub)this.server)._setProperty(org.apache.axis.encoding.C,
332       // Boolean.TRUE);
333
334     } catch (Exception ex)
335     {
336       JOptionPane.showMessageDialog(Desktop.desktop,
337               "The Secondary Structure Prediction Service named "
338                       + WebServiceName + " at " + WsURL
339                       + " couldn't be located.", "Internal Jalview Error",
340               JOptionPane.WARNING_MESSAGE);
341       wsInfo.setProgressText("Serious! " + WebServiceName
342               + " Service location failed\nfor URL :" + WsURL + "\n"
343               + ex.getMessage());
344       wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);
345
346     }
347
348     return server;
349   }
350
351   public void attachWSMenuEntry(JMenu wsmenu, final ServiceHandle sh,
352           final AlignFrame af)
353   {
354     final JMenuItem method = new JMenuItem(sh.getName());
355     method.setToolTipText(sh.getEndpointURL());
356     method.addActionListener(new ActionListener()
357     {
358       public void actionPerformed(ActionEvent e)
359       {
360         AlignmentView msa = af.gatherSeqOrMsaForSecStrPrediction();
361         if (msa.getSequences().length == 1)
362         {
363           // Single Sequence prediction
364           new jalview.ws.jws1.JPredClient(sh, af.getTitle(), false, msa,
365                   af, true);
366         }
367         else
368         {
369           if (msa.getSequences().length > 1)
370           {
371             // Sequence profile based prediction
372             new jalview.ws.jws1.JPredClient(sh, af.getTitle(), true, msa,
373                     af, true);
374           }
375         }
376       }
377     });
378     wsmenu.add(method);
379   }
380 }