package jalview.ws.jws1; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentView; import jalview.datamodel.ColumnSelection; import jalview.datamodel.SequenceI; import jalview.io.FileParse; import jalview.io.FormatAdapter; import jalview.util.MessageManager; import java.util.Hashtable; import java.util.List; /** * extraction of processing routines to allow mocking * * @author jprocter * */ public class JPredWSUtils { /** * Process data extracted from service result set to generate a JPred result * view. * * @param currentView * * @param input * - original input alignment * @param gapChar * - character to use for reconstructing alignment used for * prediction * @param SequenceInfo * - from SeqHash * @param msaPred * - true if a prediction based on existing MSA * @param predMap * - position * @param result_PredFile * @param result_Aligfile * @param full_alignment * @return { Alignment, ColumnSelection } * @throws Exception */ public static Object[] processJnetResult(AlignmentI currentView, AlignmentView input, char gapChar, Hashtable SequenceInfo, boolean msaPred, int[] predMap, String result_PredFile, String result_Aligfile, FileParse full_alignment) throws Exception { AlignmentI al = null; ColumnSelection alcsel = null; // the position of the query sequence in Alignment al int FirstSeq = -1; // the position of the original sequence in the array of // Sequences in the input object that this job holds a // prediction for int msaIndex = 0; // JPredFile prediction = new JPredFile("C:/JalviewX/files/jpred.txt", // "File"); jalview.io.JPredFile prediction = new jalview.io.JPredFile( result_PredFile, "Paste"); SequenceI[] preds = prediction.getSeqsAsArray(); jalview.bin.Cache.log.debug("Got prediction profile."); if (msaPred && (result_Aligfile != null)) { jalview.bin.Cache.log.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_Aligfile, "Paste"); if (jalview.io.FormatAdapter.isValidFormat(format)) { SequenceI sqs[]; if (predMap != null) { Object[] alandcolsel = input .getAlignmentAndColumnSelection(gapChar); sqs = (SequenceI[]) alandcolsel[0]; al = new Alignment(sqs); alcsel = (ColumnSelection) alandcolsel[1]; } else { al = new FormatAdapter().readFile(result_Aligfile, "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(SequenceInfo, sqs)) { throw (new Exception( MessageManager .getString("exception.couldnt_recover_sequence_properties_for_alignment"))); } } FirstSeq = 0; if (currentView.getDataset() != null) { al.setDataset(currentView.getDataset()); } else { al.setDataset(null); } jalview.io.JnetAnnotationMaker.add_annotation(prediction, al, FirstSeq, false, predMap); } else { throw (new Exception(MessageManager.formatMessage( "exception.unknown_format_for_file", new String[] { format, result_Aligfile }))); } } else { AlignmentI fullAlignment = null; try { // read full alignment if present. if (full_alignment != null) { fullAlignment = new FormatAdapter().readFromFile(full_alignment, "FASTA"); } } catch (Exception q) { } finally { if (fullAlignment != null) { al = fullAlignment; FirstSeq = 0; } else { al = new Alignment(preds); FirstSeq = prediction.getQuerySeqPosition(); } } if (predMap != null) { // map the prediction onto the query sequence, excluding positions // corresponding to hidden regions in the original input. char gc = gapChar; SequenceI[] sqs = (SequenceI[]) input .getAlignmentAndColumnSelection(gc)[0]; if (msaIndex >= sqs.length) { throw new Error( MessageManager .getString("error.implementation_error_invalid_msa_index_for_job")); } if (fullAlignment == null) { // // // Uses RemoveGapsCommand // // new jalview.commands.RemoveGapsCommand( MessageManager.getString("label.remove_gaps"), new SequenceI[] { sqs[msaIndex] }, currentView); SequenceI profileseq = al.getSequenceAt(FirstSeq); profileseq.setSequence(sqs[msaIndex].getSequenceAsString()); } } if (!jalview.analysis.SeqsetUtils.SeqCharacterUnhash( al.getSequenceAt(FirstSeq), SequenceInfo)) { throw (new Exception( MessageManager .getString("exception.couldnt_recover_sequence_props_for_jnet_query"))); } else { 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. if (fullAlignment == null) { alignToProfileSeq(al, profileseq); } if (fullAlignment == null && predMap != null) { // Adjust input view for gaps // propagate insertions into profile alcsel = ColumnSelection.propagateInsertions(profileseq, al, input); } } } // transfer to dataset for (AlignmentAnnotation alant : al.getAlignmentAnnotation()) { if (alant.sequenceRef != null) { replaceAnnotationOnAlignmentWith(alant, alant.label, "jalview.jws1.Jpred" + (msaPred ? "MSA" : ""), alant.sequenceRef); } } return new Object[] { al, alcsel }; // , FirstSeq, noMsa}; } /** * copied from JabawsCalcWorker * * @param newAnnot * @param typeName * @param calcId * @param aSeq */ public static 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(); } /** * Given an alignment where all other sequences except profileseq are aligned * to the ungapped profileseq, insert gaps in the other sequences to realign * them with the residues in profileseq * * @param al * @param profileseq */ public static void alignToProfileSeq(AlignmentI al, SequenceI profileseq) { char gc = al.getGapCharacter(); int[] gapMap = profileseq.gapMap(); // insert gaps into profile for (int lp = 0, r = 0; r < gapMap.length; r++) { if (gapMap[r] - lp > 1) { StringBuffer sb = new StringBuffer(); for (int s = 0, ns = gapMap[r] - lp; s < ns; s++) { sb.append(gc); } for (int s = 1, ns = al.getHeight(); s < ns; s++) { String sq = al.getSequenceAt(s).getSequenceAsString(); int diff = gapMap[r] - sq.length(); if (diff > 0) { // pad gaps sq = sq + sb; while ((diff = gapMap[r] - sq.length()) > 0) { 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])); } } } lp = gapMap[r]; } } }