2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
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.
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.
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
26 import jalview.analysis.*;
28 import jalview.datamodel.*;
29 import jalview.datamodel.Alignment;
30 import jalview.datamodel.AlignmentView;
33 import jalview.util.*;
34 import jalview.ws.WSThread.*;
35 import vamsas.objects.simple.*;
37 public class JPredClient
41 * crate a new GUI JPred Job
42 * @param sh ServiceHandle
44 * @param msa boolean - true - submit alignment as a sequence profile
45 * @param alview AlignmentView
47 public JPredClient(ext.vamsas.ServiceHandle sh, String title, boolean msa, AlignmentView alview, AlignFrame parentFrame) {
49 wsInfo=setWebService(sh);
50 startJPredClient(title, msa, alview, parentFrame);
55 * TODO: refine submission to cope with local prediction of visible regions or multiple single sequence jobs
56 * TODO: sequence representative support - could submit alignment of representatives as msa.
57 * TODO: msa hidden region prediction - submit each chunk for prediction. concatenate results of each.
58 * TODO: single seq prediction - submit each contig of each sequence for prediction (but must cope with flanking regions and short seqs)
61 * @param alview AlignmentView
63 private void startJPredClient(String title, boolean msa,
64 jalview.datamodel.AlignmentView alview, AlignFrame parentFrame)
66 AlignmentView input = alview;
69 wsInfo = setWebService();
71 Jpred server = locateWebService();
74 Cache.log.warn("Couldn't find a Jpred webservice to invoke!");
78 SeqCigar[] msf = input.getSequences();
79 SequenceI seq = msf[0].getSeq('-');
80 if (msa && msf.length > 1)
83 String altitle = "JNet prediction on " + seq.getName() +
84 " using alignment from " + title;
86 wsInfo.setProgressText("Job details for MSA based prediction (" +
87 title + ") on sequence :\n>" + seq.getName() +
89 AlignSeq.extractGaps("-. ", seq.getSequence()) +
91 SequenceI aln[] = new SequenceI[msf.length];
92 for (int i = 0, j = msf.length; i < j; i++)
94 aln[i] = msf[i].getSeq('-');
97 Hashtable SequenceInfo = jalview.analysis.SeqsetUtils.uniquify(aln, true);
99 JPredThread jthread = new JPredThread(wsInfo, altitle, server,
100 SequenceInfo, aln, alview, parentFrame);
101 wsInfo.setthisService(jthread);
106 if (!msa && msf.length>1)
107 throw new Error("Implementation Error! Multiple single sequence prediction jobs are not yet supported.");
108 wsInfo.setProgressText("Job details for prediction on sequence :\n>" +
109 seq.getName() + "\n" +
110 AlignSeq.extractGaps("-. ", seq.getSequence()) +
112 String altitle = "JNet prediction for sequence " + seq.getName() +
116 Hashtable SequenceInfo = jalview.analysis.SeqsetUtils.SeqCharacterHash(
119 JPredThread jthread = new JPredThread(wsInfo, altitle, server,
120 SequenceInfo, seq, alview, parentFrame);
121 wsInfo.setthisService(jthread);
125 public JPredClient(ext.vamsas.ServiceHandle sh, String title, SequenceI seq, AlignFrame parentFrame)
128 wsInfo = setWebService(sh);
129 startJPredClient(title, seq, parentFrame);
132 public JPredClient(ext.vamsas.ServiceHandle sh, String title, SequenceI[] msa, AlignFrame parentFrame)
134 wsInfo = setWebService(sh);
135 startJPredClient(title, msa, parentFrame);
138 public JPredClient(String title, SequenceI[] msf)
140 startJPredClient(title, msf, null);
143 public JPredClient(String title, SequenceI seq)
145 startJPredClient(title, seq, null);
148 private void startJPredClient(String title, SequenceI[] msf, AlignFrame parentFrame)
152 wsInfo = setWebService();
155 SequenceI seq = msf[0];
157 String altitle = "JNet prediction on " + seq.getName() +
158 " using alignment from " + title;
160 wsInfo.setProgressText("Job details for MSA based prediction (" +
161 title + ") on sequence :\n>" + seq.getName() + "\n" +
162 AlignSeq.extractGaps("-. ", seq.getSequence()) +
164 SequenceI aln[] = new SequenceI[msf.length];
165 for (int i = 0, j = msf.length; i < j; i++)
167 aln[i] = new jalview.datamodel.Sequence(msf[i]);
170 Hashtable SequenceInfo = jalview.analysis.SeqsetUtils.uniquify(aln, true);
172 Jpred server = locateWebService();
178 JPredThread jthread = new JPredThread(wsInfo, altitle, server, SequenceInfo, aln,null, parentFrame);
179 wsInfo.setthisService(jthread);
183 public void startJPredClient(String title, SequenceI seq, AlignFrame parentFrame)
187 wsInfo = setWebService();
189 wsInfo.setProgressText("Job details for prediction on sequence :\n>" +
190 seq.getName() + "\n" +
191 AlignSeq.extractGaps("-. ", seq.getSequence()) +
193 String altitle = "JNet prediction for sequence " + seq.getName() + " from " +
196 Hashtable SequenceInfo = jalview.analysis.SeqsetUtils.SeqCharacterHash(seq);
198 Jpred server = locateWebService();
204 JPredThread jthread = new JPredThread(wsInfo, altitle, server, SequenceInfo, seq,null, parentFrame);
205 wsInfo.setthisService(jthread);
209 private WebserviceInfo setWebService()
211 WebServiceName = "JNetWS";
212 WebServiceJobTitle = "JNet secondary structure prediction";
213 WebServiceReference =
214 "\"Cuff J. A and Barton G.J (2000) Application of " +
215 "multiple sequence alignment profiles to improve protein secondary structure prediction, " +
216 "Proteins 40:502-511\".";
217 WsURL = "http://www.compbio.dundee.ac.uk/JalviewWS/services/jpred";
219 WebserviceInfo wsInfo = new WebserviceInfo(WebServiceJobTitle,
220 WebServiceReference);
225 private ext.vamsas.Jpred locateWebService()
227 ext.vamsas.JpredServiceLocator loc = new JpredServiceLocator(); // Default
228 ext.vamsas.Jpred server=null;
231 server = loc.getjpred(new java.net.URL(WsURL)); // JBPNote will be set from properties
232 ( (JpredSoapBindingStub)server).setTimeout(60000); // one minute stub
233 //((JpredSoapBindingStub)this.server)._setProperty(org.apache.axis.encoding.C, Boolean.TRUE);
238 JOptionPane.showMessageDialog(Desktop.desktop,
239 "The Secondary Structure Prediction Service named " +
240 WebServiceName + " at " + WsURL +
241 " couldn't be located.",
242 "Internal Jalview Error",
243 JOptionPane.WARNING_MESSAGE);
244 wsInfo.setProgressText("Serious! " + WebServiceName +
245 " Service location failed\nfor URL :" + WsURL +
248 wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);
260 extends WSThread.WSJob
263 vamsas.objects.simple.Sequence sequence;
264 vamsas.objects.simple.Msfalignment msa;
265 java.util.Hashtable SequenceInfo = null;
268 * @return true if getResultSet will return a valid alignment and prediction result.
270 public boolean hasResults()
272 if (subjobComplete && result != null && result.isFinished()
273 && ( (JpredResult) result).getPredfile() != null &&
274 ( (JpredResult) result).getAligfile() != null)
281 boolean hasValidInput()
283 if (sequence != null)
290 public Alignment getResultSet()
293 if (result == null || !result.isFinished())
298 int FirstSeq = -1; // the position of the query sequence in Alignment al
300 JpredResult result = (JpredResult)this.result;
302 jalview.bin.Cache.log.debug("Parsing output from JNet job.");
303 // JPredFile prediction = new JPredFile("C:/JalviewX/files/jpred.txt", "File");
304 jalview.io.JPredFile prediction = new jalview.io.JPredFile(result.
307 SequenceI[] preds = prediction.getSeqsAsArray();
308 jalview.bin.Cache.log.debug("Got prediction profile.");
310 if ( (this.msa != null) && (result.getAligfile() != null))
312 jalview.bin.Cache.log.debug("Getting associated alignment.");
313 // we ignore the returned alignment if we only predicted on a single sequence
314 String format = new jalview.io.IdentifyFile().Identify(result.
318 if (jalview.io.FormatAdapter.isValidFormat(format))
320 al = new Alignment(new FormatAdapter().readFile(result.getAligfile(),
322 SequenceI sqs[] = new SequenceI[al.getHeight()];
323 for (int i = 0, j = al.getHeight(); i < j; i++)
325 sqs[i] = al.getSequenceAt(i);
327 if (!jalview.analysis.SeqsetUtils.deuniquify( (Hashtable)
330 throw (new Exception(
331 "Couldn't recover sequence properties for alignment."));
337 jalview.io.JnetAnnotationMaker.add_annotation(prediction, al, FirstSeq,
343 throw (new Exception(
344 "Unknown format "+format+" for file : \n" +
345 result.getAligfile()));
350 al = new Alignment(preds);
351 FirstSeq = prediction.getQuerySeqPosition();
352 if (!jalview.analysis.SeqsetUtils.SeqCharacterUnhash(
353 al.getSequenceAt(FirstSeq), SequenceInfo))
355 throw (new Exception(
356 "Couldn't recover sequence properties for JNet Query sequence!"));
359 jalview.io.JnetAnnotationMaker.add_annotation(prediction, al, FirstSeq,
364 return al; // , FirstSeq, noMsa};
366 public JPredJob(Hashtable SequenceInfo, SequenceI seq)
369 String sq = AlignSeq.extractGaps(Comparison.GapChars, seq.getSequence());
370 if (sq.length() >= 20)
372 this.SequenceInfo = SequenceInfo;
373 sequence = new vamsas.objects.simple.Sequence();
374 sequence.setId(seq.getName());
379 public JPredJob(Hashtable SequenceInfo, SequenceI[] msf)
381 this(SequenceInfo, msf[0]);
382 if (sequence != null)
386 msa = new vamsas.objects.simple.Msfalignment();
387 jalview.io.PileUpfile pileup = new jalview.io.PileUpfile();
388 msa.setMsf(pileup.print(msf));
393 ext.vamsas.Jpred server;
395 JPredThread(WebserviceInfo wsinfo, String altitle, ext.vamsas.Jpred server, AlignmentView alview, AlignFrame alframe) {
396 this.altitle = altitle;
397 this.server = server;
398 this.wsInfo = wsinfo;
400 this.alignFrame = alframe;
403 // String OutputHeader;
404 // vamsas.objects.simple.JpredResult result;
406 JPredThread(WebserviceInfo wsinfo, String altitle, ext.vamsas.Jpred server, Hashtable SequenceInfo,SequenceI seq, AlignmentView alview, AlignFrame alframe)
408 this(wsinfo, altitle, server,alview, alframe);
409 JPredJob job = new JPredJob(SequenceInfo, seq);
410 if (job.hasValidInput())
412 OutputHeader = wsInfo.getProgressText();
420 JPredThread(WebserviceInfo wsinfo, String altitle, ext.vamsas.Jpred server, Hashtable SequenceInfo, SequenceI[] msf, AlignmentView alview, AlignFrame alframe)
422 this(wsinfo, altitle, server,alview, alframe);
423 JPredJob job = new JPredJob(SequenceInfo, msf);
424 if (job.hasValidInput())
429 OutputHeader = wsInfo.getProgressText();
439 while (!jobComplete && (allowedServerExceptions > 0))
443 if ( (result = server.getresult(jobId)) == null)
445 throw (new Exception(
446 "Timed out when communicating with server\nTry again later.\n"));
448 if (result.getState()==0)
449 jalview.bin.Cache.log.debug("Finished "+jobId);
450 if (result.isRunning())
452 wsInfo.setStatus(WebserviceInfo.STATE_RUNNING);
454 if (result.isQueued())
456 wsInfo.setStatus(WebserviceInfo.STATE_QUEUING);
459 wsInfo.setProgressText(OutputHeader + "\n" +
462 if (result.isFinished())
470 if (! (result.isJobFailed() || result.isServerError()))
476 catch (InterruptedException ex1)
480 // System.out.println("I'm alive "+seqid+" "+jobid);
484 wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
492 allowedServerExceptions--;
494 wsInfo.appendProgressText("\nJPredWS Server exception!\n" +
499 if (allowedServerExceptions > 0)
504 catch (InterruptedException ex1)
508 catch (OutOfMemoryError er)
511 wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
512 JOptionPane.showInternalMessageDialog(Desktop.desktop,
513 "Out of memory handling result!!"
515 "\nSee help files for increasing Java Virtual Machine memory."
517 JOptionPane.WARNING_MESSAGE);
518 System.out.println("JPredClient: "+er);
523 if (! (result.isJobFailed() || result.isServerError()))
525 wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_OK);
529 wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
533 void StartJob(WSJob j)
535 if (! (j instanceof JPredJob))
537 throw new Error("Implementation error - StartJob(JpredJob) called on " +
542 JPredJob job = (JPredJob) j;
545 job.jobId = server.predictOnMsa(job.msa);
548 if (job.sequence!=null)
550 job.jobId = server.predict(job.sequence); // debug like : job.jobId = "/jobs/www-jpred/jp_Yatat29";//
553 if (job.jobId != null)
555 if (job.jobId.startsWith("Broken"))
557 job.result = (vamsas.objects.simple.Result)new JpredResult();
558 job.result.setInvalid(true);
559 job.result.setStatus("Submission " + job.jobId);
563 job.submitted = true;
564 job.subjobComplete = false;
565 Cache.log.info(WsURL + " Job Id '" + job.jobId + "'");
570 throw new Exception("Server timed out - try again later\n");
575 if (e.getMessage().indexOf("Exception") > -1)
577 wsInfo.setStatus(j.jobnum, WebserviceInfo.STATE_STOPPED_SERVERERROR);
578 wsInfo.setProgressText(j.jobnum,
579 "Failed to submit the prediction. (Just close the window)\n"
581 "It is most likely that there is a problem with the server.\n");
583 "JPredWS Client: Failed to submit the prediction. Quite possibly because of a server error - see below)\n" +
584 e.getMessage() + "\n");
586 jalview.bin.Cache.log.warn("Server Exception", e);
590 wsInfo.setStatus(j.jobnum, WebserviceInfo.STATE_STOPPED_ERROR);
591 // JBPNote - this could be a popup informing the user of the problem.
592 wsInfo.appendProgressText(j.jobnum,
593 "Failed to submit the prediction:\n"
595 wsInfo.getProgressText());
597 jalview.bin.Cache.log.debug("Failed Submission of job " + j.jobnum, e);
600 j.allowedServerExceptions = -1;
601 j.subjobComplete = true;
605 /* private void addFloatAnnotations(Alignment al, int[] gapmap,
606 Vector values, String Symname,
607 String Visname, float min,
608 float max, int winLength)
610 Annotation[] annotations = new Annotation[al.getWidth()];
612 for (int j = 0; j < values.size(); j++)
614 float value = Float.parseFloat(values.get(j).toString());
615 annotations[gapmap[j]] = new Annotation("", value + "", ' ',
619 al.addAnnotation(new AlignmentAnnotation(Symname, Visname,
620 annotations, min, max, winLength));
625 int results = 0; // number of result sets received
626 JobStateSummary finalState = new JobStateSummary();
629 for (int j = 0; j < jobs.length; j++)
631 finalState.updateJobPanelState(wsInfo, OutputHeader, jobs[j]);
632 if (jobs[j].submitted && jobs[j].subjobComplete && jobs[j].hasResults())
641 Cache.log.error("Unexpected exception when processing results for " +
643 wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
647 wsInfo.showResultsNewFrame
648 .addActionListener(new java.awt.event.ActionListener()
650 public void actionPerformed(
651 java.awt.event.ActionEvent evt)
653 displayResults(true);
657 .addActionListener(new java.awt.event.ActionListener()
659 public void actionPerformed(
660 java.awt.event.ActionEvent evt)
662 displayResults(false);
665 wsInfo.setResultsReady();
669 wsInfo.setFinishedNoResults();
673 void displayResults(boolean newWindow)
675 // TODO: cope with multiple subjobs.
678 Alignment res = null;
680 for (int jn = 0; jn < jobs.length; jn++)
682 Alignment jobres = null;
683 JPredJob j = (JPredJob) jobs[jn];
687 // hack - we only deal with all single seuqence predictions or all profile predictions
688 msa = (j.msa!=null) ? true : msa;
691 jalview.bin.Cache.log.debug("Parsing output of job " + jn);
692 jobres = j.getResultSet();
693 jalview.bin.Cache.log.debug("Finished parsing output.");
697 // do merge with other job results
698 throw new Error("Multiple JNet subjob merging not yet implemented.");
703 jalview.bin.Cache.log.error(
704 "JNet Client: JPred Annotation Parse Error",
706 wsInfo.setStatus(j.jobnum, WebserviceInfo.STATE_STOPPED_ERROR);
707 wsInfo.appendProgressText(j.jobnum,
708 OutputHeader + "\n" +
709 j.result.getStatus() +
710 "\nInvalid JNet job result data!\n" +
712 j.result.setBroken(true);
723 af = new AlignFrame(res);
725 java.lang.Object[] alandcolsel = input.getAlignmentAndColumnSelection(alignFrame.getViewport().getGapCharacter());
727 if (((SequenceI[])alandcolsel[0])[0].getLength()!=res.getWidth()) {
729 throw new Error("Implementation Error! ColumnSelection from input alignment will not map to result alignment!");
732 ((ColumnSelection) alandcolsel[1]).pruneDeletions(ShiftList.parseMap(((SequenceI[]) alandcolsel[0])[0].gapMap()));//gapMap returns insert list, interpreted as delete list by pruneDeletions
735 af = new AlignFrame(res, (ColumnSelection) alandcolsel[1]);
737 Desktop.addInternalFrame(af, altitle,
738 AlignFrame.NEW_WINDOW_WIDTH,
739 AlignFrame.NEW_WINDOW_HEIGHT);
743 Cache.log.info("Append results onto existing alignment.");
748 void pollJob(WSJob job)
751 job.result = server.getresult(job.jobId);
753 public boolean isCancellable()
758 public void cancelJob()
760 throw new Error("Implementation error!");
763 public boolean canMergeResults()