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