X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fws%2Fjws1%2FJPredThread.java;h=a39945edefa78f84f36baa4aab500a23d69c1e37;hb=cb8e52fbbc5f725e3f7f48c672cdddb0690bd978;hp=a0036fe2a164b2af437833c848ecad5b2ec5c15b;hpb=add30afdc46a14e61ccf55881fa91b9ca9abfe80;p=jalview.git diff --git a/src/jalview/ws/jws1/JPredThread.java b/src/jalview/ws/jws1/JPredThread.java index a0036fe..a39945e 100644 --- a/src/jalview/ws/jws1/JPredThread.java +++ b/src/jalview/ws/jws1/JPredThread.java @@ -1,33 +1,53 @@ /* - * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5) - * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - * + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * * Jalview is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along with Jalview. If not, see . + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.ws.jws1; -import java.util.*; - -import jalview.analysis.*; -import jalview.bin.*; -import jalview.datamodel.*; -import jalview.gui.*; -import jalview.io.*; -import jalview.util.*; +import jalview.analysis.AlignSeq; +import jalview.analysis.SeqsetUtils; +import jalview.bin.Console; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.AlignmentView; +import jalview.datamodel.HiddenColumns; +import jalview.datamodel.SequenceI; +import jalview.gui.AlignFrame; +import jalview.gui.Desktop; +import jalview.gui.WebserviceInfo; +import jalview.io.DataSourceType; +import jalview.io.FileFormatI; +import jalview.io.FormatAdapter; +import jalview.io.IdentifyFile; +import jalview.io.JPredFile; +import jalview.io.JnetAnnotationMaker; +import jalview.io.PileUpfile; +import jalview.util.Comparison; +import jalview.util.MessageManager; import jalview.ws.AWsJob; import jalview.ws.JobStateSummary; import jalview.ws.WSClientI; + +import java.util.Hashtable; +import java.util.List; + import vamsas.objects.simple.JpredResult; class JPredThread extends JWS1Thread implements WSClientI @@ -58,6 +78,7 @@ class JPredThread extends JWS1Thread implements WSClientI * @return true if getResultSet will return a valid alignment and prediction * result. */ + @Override public boolean hasResults() { if (subjobComplete && result != null && result.isFinished() @@ -69,6 +90,7 @@ class JPredThread extends JWS1Thread implements WSClientI return false; } + @Override public boolean hasValidInput() { if (sequence != null) @@ -91,67 +113,74 @@ class JPredThread extends JWS1Thread implements WSClientI { return null; } - Alignment al = null; - ColumnSelection alcsel = null; + AlignmentI al = null; + HiddenColumns alhidden = null; int FirstSeq = -1; // the position of the query sequence in Alignment al JpredResult result = (JpredResult) this.result; - jalview.bin.Cache.log.debug("Parsing output from JNet job."); + Console.debug("Parsing output from JNet job."); // JPredFile prediction = new JPredFile("C:/JalviewX/files/jpred.txt", // "File"); - jalview.io.JPredFile prediction = new jalview.io.JPredFile(result - .getPredfile(), "Paste"); + JPredFile prediction = new JPredFile(result.getPredfile(), + DataSourceType.PASTE); SequenceI[] preds = prediction.getSeqsAsArray(); - jalview.bin.Cache.log.debug("Got prediction profile."); + Console.debug("Got prediction profile."); if ((this.msa != null) && (result.getAligfile() != null)) { - jalview.bin.Cache.log.debug("Getting associated alignment."); + Console.debug("Getting associated alignment."); // we ignore the returned alignment if we only predicted on a single // sequence - String format = new jalview.io.IdentifyFile().Identify(result - .getAligfile(), "Paste"); + FileFormatI format = new IdentifyFile() + .identify(result.getAligfile(), DataSourceType.PASTE); - if (jalview.io.FormatAdapter.isValidFormat(format)) + if (format != null) { SequenceI sqs[]; if (predMap != null) { Object[] alandcolsel = input - .getAlignmentAndColumnSelection(getGapChar()); + .getAlignmentAndHiddenColumns(getGapChar()); sqs = (SequenceI[]) alandcolsel[0]; al = new Alignment(sqs); - alcsel = (ColumnSelection) alandcolsel[1]; + alhidden = (HiddenColumns) alandcolsel[1]; } else { al = new FormatAdapter().readFile(result.getAligfile(), - "Paste", format); + DataSourceType.PASTE, format); sqs = new SequenceI[al.getHeight()]; for (int i = 0, j = al.getHeight(); i < j; i++) { sqs[i] = al.getSequenceAt(i); } - if (!jalview.analysis.SeqsetUtils.deuniquify( - (Hashtable) SequenceInfo, sqs)) + if (!SeqsetUtils.deuniquify(SequenceInfo, sqs)) { - throw (new Exception( - "Couldn't recover sequence properties for alignment.")); + throw (new Exception(MessageManager.getString( + "exception.couldnt_recover_sequence_properties_for_alignment"))); } } FirstSeq = 0; - al.setDataset(null); + if (currentView.getDataset() != null) + { + al.setDataset(currentView.getDataset()); - jalview.io.JnetAnnotationMaker.add_annotation(prediction, al, - FirstSeq, false, predMap); + } + else + { + al.setDataset(null); + } + JnetAnnotationMaker.add_annotation(prediction, al, FirstSeq, + false, predMap); } else { - throw (new Exception("Unknown format " + format - + " for file : \n" + result.getAligfile())); + throw (new Exception(MessageManager.formatMessage( + "exception.unknown_format_for_file", new String[] + { "", result.getAligfile() }))); } } else @@ -161,18 +190,19 @@ class JPredThread extends JWS1Thread implements WSClientI if (predMap != null) { char gc = getGapChar(); - SequenceI[] sqs = (SequenceI[]) ((java.lang.Object[]) input - .getAlignmentAndColumnSelection(gc))[0]; + SequenceI[] sqs = (SequenceI[]) input + .getAlignmentAndHiddenColumns(gc)[0]; if (this.msaIndex >= sqs.length) { - throw new Error( - "Implementation Error! Invalid msaIndex for JPredJob on parent MSA input object!"); + throw new Error(MessageManager.getString( + "error.implementation_error_invalid_msa_index_for_job")); } // /// // Uses RemoveGapsCommand // /// - new jalview.commands.RemoveGapsCommand("Remove Gaps", + new jalview.commands.RemoveGapsCommand( + MessageManager.getString("label.remove_gaps"), new SequenceI[] { sqs[msaIndex] }, currentView); @@ -180,15 +210,23 @@ class JPredThread extends JWS1Thread implements WSClientI profileseq.setSequence(sqs[msaIndex].getSequenceAsString()); } - if (!jalview.analysis.SeqsetUtils.SeqCharacterUnhash(al - .getSequenceAt(FirstSeq), SequenceInfo)) + if (!jalview.analysis.SeqsetUtils.SeqCharacterUnhash( + al.getSequenceAt(FirstSeq), SequenceInfo)) { - throw (new Exception( - "Couldn't recover sequence properties for JNet Query sequence!")); + throw (new Exception(MessageManager.getString( + "exception.couldnt_recover_sequence_props_for_jnet_query"))); } else { - al.setDataset(null); + if (currentView.getDataset() != null) + { + al.setDataset(currentView.getDataset()); + + } + else + { + al.setDataset(null); + } jalview.io.JnetAnnotationMaker.add_annotation(prediction, al, FirstSeq, true, predMap); SequenceI profileseq = al.getSequenceAt(0); // this includes any gaps. @@ -197,12 +235,53 @@ class JPredThread extends JWS1Thread implements WSClientI { // Adjust input view for gaps // propagate insertions into profile - alcsel = propagateInsertions(profileseq, al, input); + alhidden = al.propagateInsertions(profileseq, input); } } } - return new Object[] - { al, alcsel }; // , FirstSeq, noMsa}; + // transfer to dataset + for (AlignmentAnnotation alant : al.getAlignmentAnnotation()) + { + if (alant.sequenceRef != null) + { + replaceAnnotationOnAlignmentWith(alant, alant.label, + "jalview.jws1.Jpred" + (this.msa == null ? "" : "MSA"), + alant.sequenceRef); + } + } + return new Object[] { al, alhidden }; // , FirstSeq, noMsa}; + } + + /** + * copied from JabawsCalcWorker + * + * @param newAnnot + * @param typeName + * @param calcId + * @param aSeq + */ + protected void replaceAnnotationOnAlignmentWith( + AlignmentAnnotation newAnnot, String typeName, String calcId, + SequenceI aSeq) + { + SequenceI dsseq = aSeq.getDatasetSequence(); + while (dsseq.getDatasetSequence() != null) + { + dsseq = dsseq.getDatasetSequence(); + } + // look for same annotation on dataset and lift this one over + List dsan = dsseq.getAlignmentAnnotations(calcId, + typeName); + if (dsan != null && dsan.size() > 0) + { + for (AlignmentAnnotation dssan : dsan) + { + dsseq.removeAlignmentAnnotation(dssan); + } + } + AlignmentAnnotation dssan = new AlignmentAnnotation(newAnnot); + dsseq.addAlignmentAnnotation(dssan); + dssan.adjustForAlignment(); } /** @@ -213,7 +292,7 @@ class JPredThread extends JWS1Thread implements WSClientI * @param al * @param profileseq */ - private void alignToProfileSeq(Alignment al, SequenceI profileseq) + private void alignToProfileSeq(AlignmentI al, SequenceI profileseq) { char gc = al.getGapCharacter(); int[] gapMap = profileseq.gapMap(); @@ -237,17 +316,15 @@ class JPredThread extends JWS1Thread implements WSClientI sq = sq + sb; while ((diff = gapMap[r] - sq.length()) > 0) { - sq = sq - + ((diff >= sb.length()) ? sb.toString() : sb - .substring(0, diff)); + sq = sq + ((diff >= sb.length()) ? sb.toString() + : sb.substring(0, diff)); } al.getSequenceAt(s).setSequence(sq); } else { - al.getSequenceAt(s).setSequence( - sq.substring(0, gapMap[r]) + sb.toString() - + sq.substring(gapMap[r])); + al.getSequenceAt(s).setSequence(sq.substring(0, gapMap[r]) + + sb.toString() + sq.substring(gapMap[r])); } } } @@ -255,105 +332,12 @@ class JPredThread extends JWS1Thread implements WSClientI } } - /** - * Add gaps into the sequences aligned to profileseq under the given - * AlignmentView - * - * @param profileseq - * @param al - * @param input - */ - private ColumnSelection propagateInsertions(SequenceI profileseq, - Alignment al, AlignmentView input) - { - char gc = al.getGapCharacter(); - Object[] alandcolsel = input.getAlignmentAndColumnSelection(gc); - ColumnSelection nview = (ColumnSelection) alandcolsel[1]; - SequenceI origseq; - nview.pruneDeletions(ShiftList - .parseMap((origseq = ((SequenceI[]) alandcolsel[0])[0]) - .gapMap())); // recover original prediction sequence's - // mapping to view. - int[] viscontigs = nview.getVisibleContigs(0, profileseq.getLength()); - int spos = 0; - int offset = 0; - // input.pruneDeletions(ShiftList.parseMap(((SequenceI[]) - // alandcolsel[0])[0].gapMap())) - // add profile to visible contigs - for (int v = 0; v < viscontigs.length; v += 2) - { - if (viscontigs[v] > spos) - { - StringBuffer sb = new StringBuffer(); - for (int s = 0, ns = viscontigs[v] - spos; s < ns; s++) - { - sb.append(gc); - } - for (int s = 0, ns = al.getHeight(); s < ns; s++) - { - SequenceI sqobj = al.getSequenceAt(s); - if (sqobj != profileseq) - { - String sq = al.getSequenceAt(s).getSequenceAsString(); - if (sq.length() <= spos + offset) - { - // pad sequence - int diff = spos + offset - sq.length() - 1; - if (diff > 0) - { - // pad gaps - sq = sq + sb; - while ((diff = spos + offset - sq.length() - 1) > 0) - { - sq = sq - + ((diff >= sb.length()) ? sb.toString() : sb - .substring(0, diff)); - } - } - sq += sb.toString(); - } - else - { - al.getSequenceAt(s).setSequence( - sq.substring(0, spos + offset) + sb.toString() - + sq.substring(spos + offset)); - } - } - } - // offset+=sb.length(); - } - spos = viscontigs[v + 1] + 1; - } - if ((offset + spos) < profileseq.getLength()) - { - StringBuffer sb = new StringBuffer(); - for (int s = 0, ns = profileseq.getLength() - spos - offset; s < ns; s++) - { - sb.append(gc); - } - for (int s = 1, ns = al.getHeight(); s < ns; s++) - { - String sq = al.getSequenceAt(s).getSequenceAsString(); - // pad sequence - int diff = origseq.getLength() - sq.length(); - while (diff > 0) - { - sq = sq - + ((diff >= sb.length()) ? sb.toString() : sb - .substring(0, diff)); - diff = origseq.getLength() - sq.length(); - } - } - } - return nview; - } - public JPredJob(Hashtable SequenceInfo, SequenceI seq, int[] delMap) { super(); this.predMap = delMap; - String sq = AlignSeq.extractGaps(Comparison.GapChars, seq - .getSequenceAsString()); + String sq = AlignSeq.extractGaps(Comparison.GapChars, + seq.getSequenceAsString()); if (sq.length() >= 20) { this.SequenceInfo = SequenceInfo; @@ -361,6 +345,10 @@ class JPredThread extends JWS1Thread implements WSClientI sequence.setId(seq.getName()); sequence.setSeq(sq); } + else + { + errorMessage = "Sequence is too short to predict with JPred - need at least 20 amino acids."; + } } public JPredJob(Hashtable SequenceInfo, SequenceI[] msf, int[] delMap) @@ -371,11 +359,18 @@ class JPredThread extends JWS1Thread implements WSClientI if (msf.length > 1) { msa = new vamsas.objects.simple.Msfalignment(); - jalview.io.PileUpfile pileup = new jalview.io.PileUpfile(); - msa.setMsf(pileup.print(msf)); + PileUpfile pileup = new PileUpfile(); + msa.setMsf(pileup.print(msf, true)); } } } + + String errorMessage = ""; + + public String getValidationMessages() + { + return errorMessage + "\n"; + } } ext.vamsas.Jpred server; @@ -401,10 +396,13 @@ class JPredThread extends JWS1Thread implements WSClientI if (job.hasValidInput()) { OutputHeader = wsInfo.getProgressText(); - jobs = new WSJob[] - { job }; + jobs = new WSJob[] { job }; job.setJobnum(0); } + else + { + wsInfo.appendProgressText(job.getValidationMessages()); + } } JPredThread(WebserviceInfo wsinfo, String altitle, @@ -416,20 +414,24 @@ class JPredThread extends JWS1Thread implements WSClientI JPredJob job = new JPredJob(SequenceInfo, msf, delMap); if (job.hasValidInput()) { - jobs = new WSJob[] - { job }; + jobs = new WSJob[] { job }; OutputHeader = wsInfo.getProgressText(); job.setJobnum(0); } + else + { + wsInfo.appendProgressText(job.getValidationMessages()); + } } + @Override public void StartJob(AWsJob j) { if (!(j instanceof JPredJob)) { - throw new Error( - "Implementation error - StartJob(JpredJob) called on " - + j.getClass()); + throw new Error(MessageManager.formatMessage( + "error.implementation_error_startjob_called", new String[] + { j.getClass().toString() })); } try { @@ -448,21 +450,24 @@ class JPredThread extends JWS1Thread implements WSClientI { if (job.getJobId().startsWith("Broken")) { - job.result = (vamsas.objects.simple.Result) new JpredResult(); + job.result = new JpredResult(); job.result.setInvalid(true); - job.result.setStatus("Submission " + job.getJobId()); + job.result.setStatus(MessageManager + .formatMessage("label.submission_params", new String[] + { job.getJobId().toString() })); throw new Exception(job.getJobId()); } else { job.setSubmitted(true); job.setSubjobComplete(false); - Cache.log.info(WsUrl + " Job Id '" + job.getJobId() + "'"); + Console.info(WsUrl + " Job Id '" + job.getJobId() + "'"); } } else { - throw new Exception("Server timed out - try again later\n"); + throw new Exception(MessageManager + .getString("exception.server_timeout_try_later")); } } catch (Exception e) { @@ -470,30 +475,27 @@ class JPredThread extends JWS1Thread implements WSClientI wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR); if (e.getMessage().indexOf("Exception") > -1) { - wsInfo - .setStatus(j.getJobnum(), - WebserviceInfo.STATE_STOPPED_SERVERERROR); - wsInfo - .setProgressText( - j.getJobnum(), - "Failed to submit the prediction. (Just close the window)\n" - + "It is most likely that there is a problem with the server.\n"); - System.err - .println("JPredWS Client: Failed to submit the prediction. Quite possibly because of a server error - see below)\n" + wsInfo.setStatus(j.getJobnum(), + WebserviceInfo.STATE_STOPPED_SERVERERROR); + wsInfo.setProgressText(j.getJobnum(), + "Failed to submit the prediction. (Just close the window)\n" + + "It is most likely that there is a problem with the server.\n"); + System.err.println( + "JPredWS Client: Failed to submit the prediction. Quite possibly because of a server error - see below)\n" + e.getMessage() + "\n"); - jalview.bin.Cache.log.warn("Server Exception", e); + Console.warn("Server Exception", e); } else { wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_ERROR); // JBPNote - this could be a popup informing the user of the problem. wsInfo.appendProgressText(j.getJobnum(), - "Failed to submit the prediction:\n" + e.getMessage() - + wsInfo.getProgressText()); + MessageManager.formatMessage( + "info.failed_to_submit_prediction", new String[] + { e.getMessage(), wsInfo.getProgressText() })); - jalview.bin.Cache.log.debug("Failed Submission of job " + j.getJobnum(), - e); + Console.debug("Failed Submission of job " + j.getJobnum(), e); } j.setAllowedServerExceptions(-1); @@ -501,6 +503,7 @@ class JPredThread extends JWS1Thread implements WSClientI } } + @Override public void parseResult() { int results = 0; // number of result sets received @@ -519,8 +522,9 @@ class JPredThread extends JWS1Thread implements WSClientI } catch (Exception ex) { - Cache.log.error("Unexpected exception when processing results for " - + altitle, ex); + Console.error( + "Unexpected exception when processing results for " + altitle, + ex); wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR); } if (results > 0) @@ -528,6 +532,7 @@ class JPredThread extends JWS1Thread implements WSClientI wsInfo.showResultsNewFrame .addActionListener(new java.awt.event.ActionListener() { + @Override public void actionPerformed(java.awt.event.ActionEvent evt) { displayResults(true); @@ -536,6 +541,7 @@ class JPredThread extends JWS1Thread implements WSClientI wsInfo.mergeResults .addActionListener(new java.awt.event.ActionListener() { + @Override public void actionPerformed(java.awt.event.ActionEvent evt) { displayResults(false); @@ -545,6 +551,8 @@ class JPredThread extends JWS1Thread implements WSClientI } else { + wsInfo.setStatus(wsInfo.STATE_STOPPED_ERROR); + wsInfo.appendInfoText("No jobs ran."); wsInfo.setFinishedNoResults(); } } @@ -568,9 +576,9 @@ class JPredThread extends JWS1Thread implements WSClientI msa = (j.msa != null) ? true : msa; try { - jalview.bin.Cache.log.debug("Parsing output of job " + jn); + Console.debug("Parsing output of job " + jn); jobres = j.getResultSet(); - jalview.bin.Cache.log.debug("Finished parsing output."); + Console.debug("Finished parsing output."); if (jobs.length == 1) { res = jobres; @@ -578,17 +586,20 @@ class JPredThread extends JWS1Thread implements WSClientI else { // do merge with other job results - throw new Error( - "Multiple JNet subjob merging not yet implemented."); + throw new Error(MessageManager.getString( + "error.multiple_jnet_subjob_merge_not_implemented")); } } catch (Exception e) { - jalview.bin.Cache.log.error( - "JNet Client: JPred Annotation Parse Error", e); - wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_ERROR); - wsInfo.appendProgressText(j.getJobnum(), OutputHeader + "\n" - + j.result.getStatus() - + "\nInvalid JNet job result data!\n" + e.getMessage()); + Console.error("JNet Client: JPred Annotation Parse Error", e); + wsInfo.setStatus(j.getJobnum(), + WebserviceInfo.STATE_STOPPED_ERROR); + wsInfo.appendProgressText(j.getJobnum(), + MessageManager.formatMessage( + "info.invalid_jnet_job_result_data", + new String[] + { OutputHeader.toString(), j.result.getStatus(), + e.getMessage() })); j.result.setBroken(true); } } @@ -599,12 +610,14 @@ class JPredThread extends JWS1Thread implements WSClientI if (newWindow) { AlignFrame af; + ((AlignmentI) res[0]) + .setSeqrep(((AlignmentI) res[0]).getSequenceAt(0)); if (input == null) { if (res[1] != null) { af = new AlignFrame((Alignment) res[0], - (ColumnSelection) res[1], AlignFrame.DEFAULT_WIDTH, + (HiddenColumns) res[1], AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); } else @@ -629,36 +642,39 @@ class JPredThread extends JWS1Thread implements WSClientI * alandcolsel[0])[0].gapMap())); } */ - af = new AlignFrame((Alignment) res[0], - (ColumnSelection) res[1], AlignFrame.DEFAULT_WIDTH, - AlignFrame.DEFAULT_HEIGHT); + af = new AlignFrame((Alignment) res[0], (HiddenColumns) res[1], + AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); } Desktop.addInternalFrame(af, altitle, AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); } else { - Cache.log.info("Append results onto existing alignment."); + Console.info("Append results onto existing alignment."); } } } } + @Override public void pollJob(AWsJob job) throws Exception { - ((JPredJob)job).result = server.getresult(job.getJobId()); + ((JPredJob) job).result = server.getresult(job.getJobId()); } + @Override public boolean isCancellable() { return false; } + @Override public void cancelJob() { - throw new Error("Implementation error!"); + throw new Error(MessageManager.getString("error.implementation_error")); } + @Override public boolean canMergeResults() { return false;