package jalview.ws2.actions.hmmer; import static jalview.util.Comparison.GapChars; import java.io.IOException; import java.util.List; import jalview.analysis.AlignSeq; import jalview.bin.Console; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentView; import jalview.datamodel.Annotation; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceI; import jalview.util.Comparison; 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.AlignmentWebServiceClientI; class PhmmerTask extends BaseTask { private final AlignmentWebServiceClientI client; private final AlignmentView view; PhmmerTask(AlignmentWebServiceClientI client, List args, Credentials credentials, AlignmentView view) { super(client, args, credentials); this.client = client; this.view = view; } @Override protected List prepareJobs() throws ServiceInputInvalidException { Console.info("Preparing sequence for phmmer job"); var sequence = view.getVisibleAlignment('-').getSequenceAt(0); var seq = new Sequence(sequence.getName(), AlignSeq.extractGaps(GapChars, sequence.getSequenceAsString())); var job = new BaseJob(List.of(seq)) { @Override public boolean isInputValid() { return true; } }; job.setStatus(JobStatus.READY); return List.of(job); } @Override protected AlignmentI collectResult(List jobs) throws IOException { var job = jobs.get(0); var status = job.getStatus(); Console.info(String.format("phmmer finished job \"%s\" with status %s", job.getServerJob().getJobId(), status)); if (status != JobStatus.COMPLETED) return null; var outputAlignment = client.getAlignment(job.getServerJob()); var querySeq = job.getInputSequences().get(0).deriveSequence(); { AlignmentAnnotation refpos = null; for (var annot : outputAlignment.getAlignmentAnnotation()) { if (annot.sequenceRef == null && annot.label.equals("Reference Positions")) { refpos = annot; break; } } if (refpos != null) { querySeq = alignQeuryToReferencePositions(querySeq, refpos); } } outputAlignment.insertSequenceAt(0, querySeq); return outputAlignment; } private SequenceI alignQeuryToReferencePositions(SequenceI query, AlignmentAnnotation refpos) { var sequenceBuilder = new StringBuilder(); var index = 0; for (Annotation a : refpos.annotations) { // TODO: we assume that the number of "x" annotations is equal to the number // of residues. may need a safeguard against invalid input if (a != null && a.displayCharacter.equals("x")) { char c; do c = query.getCharAt(index++); while (Comparison.isGap(c)); sequenceBuilder.append(c); } else { sequenceBuilder.append(Comparison.GAP_DASH); } } query.setSequence(sequenceBuilder.toString()); return query; } }