Jalview 2.6 source licence
[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
256             .setProgressText("Job details for MSA based prediction ("
257                     + title
258                     + ") on sequence :\n>"
259                     + seq.getName()
260                     + "\n"
261                     + AlignSeq
262                             .extractGaps("-. ", seq.getSequenceAsString())
263                     + "\n");
264     SequenceI aln[] = new SequenceI[msf.length];
265     for (int i = 0, j = msf.length; i < j; i++)
266     {
267       aln[i] = new jalview.datamodel.Sequence(msf[i]);
268     }
269
270     Hashtable SequenceInfo = jalview.analysis.SeqsetUtils.uniquify(aln,
271             true);
272
273     Jpred server = locateWebService();
274     if (server == null)
275     {
276       return;
277     }
278
279     JPredThread jthread = new JPredThread(wsInfo, altitle, server,
280             SequenceInfo, aln, null, null, parentFrame, WsURL);
281     wsInfo.setthisService(jthread);
282     jthread.start();
283   }
284
285   public void startJPredClient(String title, SequenceI seq,
286           AlignFrame parentFrame)
287   {
288     if (wsInfo == null)
289     {
290       wsInfo = setWebService();
291     }
292     wsInfo
293             .setProgressText("Job details for prediction on sequence :\n>"
294                     + seq.getName()
295                     + "\n"
296                     + AlignSeq
297                             .extractGaps("-. ", seq.getSequenceAsString())
298                     + "\n");
299     String altitle = "JNet prediction for sequence " + seq.getName()
300             + " from " + title;
301
302     Hashtable SequenceInfo = jalview.analysis.SeqsetUtils
303             .SeqCharacterHash(seq);
304
305     Jpred server = locateWebService();
306     if (server == null)
307     {
308       return;
309     }
310
311     JPredThread jthread = new JPredThread(wsInfo, altitle, server, WsURL,
312             SequenceInfo, seq, null, null, parentFrame);
313     wsInfo.setthisService(jthread);
314     jthread.start();
315   }
316
317   private WebserviceInfo setWebService()
318   {
319     WebServiceName = "JNetWS";
320     WebServiceJobTitle = "JNet secondary structure prediction";
321     WebServiceReference = "\"Cuff J. A and Barton G.J (2000) Application of "
322             + "multiple sequence alignment profiles to improve protein secondary structure prediction, "
323             + "Proteins 40:502-511\".";
324     WsURL = "http://www.compbio.dundee.ac.uk/JalviewWS/services/jpred";
325
326     WebserviceInfo wsInfo = new WebserviceInfo(WebServiceJobTitle,
327             WebServiceReference);
328
329     return wsInfo;
330   }
331
332   private ext.vamsas.Jpred locateWebService()
333   {
334     ext.vamsas.JpredServiceLocator loc = new JpredServiceLocator(); // Default
335     ext.vamsas.Jpred server = null;
336     try
337     {
338       server = loc.getjpred(new java.net.URL(WsURL)); // JBPNote will be set
339       // from properties
340       ((JpredSoapBindingStub) server).setTimeout(60000); // one minute stub
341       // ((JpredSoapBindingStub)this.server)._setProperty(org.apache.axis.encoding.C,
342       // Boolean.TRUE);
343
344     } catch (Exception ex)
345     {
346       JOptionPane.showMessageDialog(Desktop.desktop,
347               "The Secondary Structure Prediction Service named "
348                       + WebServiceName + " at " + WsURL
349                       + " couldn't be located.", "Internal Jalview Error",
350               JOptionPane.WARNING_MESSAGE);
351       wsInfo.setProgressText("Serious! " + WebServiceName
352               + " Service location failed\nfor URL :" + WsURL + "\n"
353               + ex.getMessage());
354       wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);
355
356     }
357
358     return server;
359   }
360
361   public void attachWSMenuEntry(JMenu wsmenu, final ServiceHandle sh,
362           final AlignFrame af)
363   {
364     final JMenuItem method = new JMenuItem(sh.getName());
365     method.setToolTipText(sh.getEndpointURL());
366     method.addActionListener(new ActionListener()
367     {
368       public void actionPerformed(ActionEvent e)
369       {
370         AlignmentView msa = af.gatherSeqOrMsaForSecStrPrediction();
371         if (msa.getSequences().length == 1)
372         {
373           // Single Sequence prediction
374           new jalview.ws.jws1.JPredClient(sh, af.getTitle(), false, msa, af,
375                   true);
376         }
377         else
378         {
379           if (msa.getSequences().length > 1)
380           {
381             // Sequence profile based prediction
382             new jalview.ws.jws1.JPredClient(sh, af.getTitle(), true, msa, af,
383                     true);
384           }
385         }
386       }
387     });
388     wsmenu.add(method);
389   }
390 }