package jalview.ws2.actions.secstructpred; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import jalview.analysis.AlignmentAnnotationUtils; import jalview.analysis.SeqsetUtils; import jalview.analysis.SeqsetUtils.SequenceInfo; import jalview.api.AlignViewportI; 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.SeqCigar; import jalview.datamodel.SequenceI; import jalview.io.AlignFile; import jalview.io.JPredFile; import jalview.io.JnetAnnotationMaker; import jalview.ws.params.ArgumentI; import jalview.ws2.actions.BaseJob; import jalview.ws2.actions.BaseTask; import jalview.ws2.actions.ServiceInputInvalidException; import jalview.ws2.api.Credentials; import jalview.ws2.api.JobStatus; import jalview.ws2.client.api.SecStructPredWebServiceClientI; public class SecStructPredMsaTask extends BaseTask { private final SecStructPredWebServiceClientI client; private final AlignmentView alignmentView; private final AlignmentI currentView; private final char gapChar; SecStructPredMsaTask(SecStructPredWebServiceClientI client, List args, Credentials credentials, AlignViewportI viewport) { super(client, args, credentials); this.client = client; this.alignmentView = viewport.getAlignmentView(true); this.currentView = viewport.getAlignment(); this.gapChar = viewport.getGapCharacter(); } @Override protected List prepareJobs() throws ServiceInputInvalidException { SeqCigar[] msf = alignmentView.getSequences(); SequenceI referenceSeq = msf[0].getSeq('-'); int[] delMap = alignmentView .getVisibleContigMapFor(referenceSeq.gapMap()); // TODO: assume MSA for now SequenceI[] sequences = new SequenceI[msf.length]; for (int i = 0; i < msf.length; i++) sequences[i] = msf[i].getSeq('-'); var sequenceInfo = SeqsetUtils.uniquify(sequences, true); referenceSeq.setSequence(alignmentView.getASequenceString('-', 0)); for (int i = 0; i < sequences.length; i++) sequences[i].setSequence(alignmentView.getASequenceString('-', i)); var nonEmptySeqs = SeqsetUtils.getNonEmptySequenceSet(sequences); var job = new SecStructPredJob(Arrays.asList(nonEmptySeqs), referenceSeq, delMap, sequenceInfo); job.setStatus(JobStatus.READY); return List.of(job); } @Override protected AlignmentI collectResult(List jobs) throws IOException { var job = jobs.get(0); // There shouldn't be more than one job var status = job.getStatus(); Console.info( String.format("sec str pred job \"%s\" finished with status %s", job.getServerJob().getJobId(), status)); if (status != JobStatus.COMPLETED) return null; JPredFile predictionFile = client.getPredictionFile(job.getServerJob()); AlignFile alignmentFile = client.getAlignmentFile(job.getServerJob()); Object[] alnAndHiddenCols = alignmentView .getAlignmentAndHiddenColumns(gapChar); Alignment aln = new Alignment((SequenceI[]) alnAndHiddenCols[0]); aln.setDataset(currentView.getDataset()); aln.setHiddenColumns((HiddenColumns) alnAndHiddenCols[1]); try { JnetAnnotationMaker.add_annotation(predictionFile, aln, 0, false, job.getDelMap()); } catch (Exception e) { throw new IOException(e); } for (AlignmentAnnotation alnAnnot : aln.getAlignmentAnnotation()) { if (alnAnnot.sequenceRef != null) { AlignmentAnnotationUtils.replaceAnnotationOnAlignmentWith(alnAnnot, alnAnnot.label, getClass().getSimpleName()); } } aln.setSeqrep(aln.getSequenceAt(0)); return aln; } public static class SecStructPredJob extends BaseJob { private final int[] delMap; private final SequenceI refSeq; final Map seqNames; SecStructPredJob(List sequences, SequenceI refSeq, int[] delMap, Map seqNames) { super(sequences); this.refSeq = refSeq; this.delMap = delMap; this.seqNames = seqNames; } @Override public boolean isInputValid() { return true; } public int[] getDelMap() { return this.delMap; } } }