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