package jalview.ws.jws2.jabaws2; import jalview.api.FeatureColourI; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.Annotation; import jalview.datamodel.SequenceI; import jalview.datamodel.features.FeatureMatcherSetI; import jalview.util.MessageManager; import jalview.ws.api.JobId; import jalview.ws.api.SequenceAnnotationServiceI; import jalview.ws.jws2.JabaParamStore; import jalview.ws.jws2.JabaPreset; import jalview.ws.params.ArgumentI; import jalview.ws.params.WsParamSetI; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import compbio.data.msa.SequenceAnnotation; import compbio.data.sequence.FastaSequence; import compbio.data.sequence.Score; import compbio.data.sequence.ScoreManager; import compbio.metadata.JobSubmissionException; import compbio.metadata.WrongParameterException; public abstract class JabawsAnnotationInstance extends JabawsServiceInstance implements SequenceAnnotationServiceI { /** * holds last results obtained when non-null. TODO: remove this as a field ? */ protected ScoreManager scoremanager = null; public JabawsAnnotationInstance(Jws2Instance handle) { super(handle); } /** * * @return the calcId for this Jabaws Service (convenience method). * * TODO: decide if this is really convenient since manager and * instance have same method ! */ public String getCalcId() { return our.getAlignAnalysisUI() == null ? null : our.getAlignAnalysisUI().getCalcId(); } @Override public JobId submitToService(List seqs, WsParamSetI preset, List arguments) throws Throwable { String rslt = null; scoremanager = null; List jabaseqs = new ArrayList(seqs.size()); for (SequenceI seq : seqs) { jabaseqs.add( new FastaSequence(seq.getName(), seq.getSequenceAsString())); } if (preset == null && arguments == null) { rslt = service.analize(jabaseqs); } if (preset != null) { if (preset instanceof JabaPreset) { // TODO: verify behaviour is really the same, since preset analyze was // never called in Jalview 2.11.x rslt = service.presetAnalize(jabaseqs, ((JabaPreset) preset).getJabaPreset()); } else { rslt = service.customAnalize(jabaseqs, JabaParamStore.getJabafromJwsArgs(preset.getArguments())); } } else if (arguments != null && arguments.size() > 0) { try { rslt = service.customAnalize(jabaseqs, JabaParamStore.getJabafromJwsArgs(arguments)); } catch (WrongParameterException x) { throw new JobSubmissionException(MessageManager.getString( "exception.jobsubmission_invalid_params_set"), x); } } if (rslt == null) { return null; } return new JobId(our.getServiceType(), our.getName(), rslt); } @Override public List getAnnotationResult(JobId job, List seqs, Map featureColours, Map featureFilters) throws Throwable { if (scoremanager == null) { // TODO: raise annotation unavailable exception ? scoremanager = service.getAnnotation(job.getJobId()); } if (scoremanager == null) { return List.of(); } /** * dummy alignment to perform annotation on */ AlignmentI newal = new Alignment(seqs.toArray(new SequenceI[0])); List ourAnnot = annotationFromScoreManager(newal, featureColours, featureFilters); return ourAnnot; } /** * service specific annotation creation method * * @param seqs * - sequences to be annotated with results * @param featureColours * - - updated with any colours imported during result processing * @param featureFilters * - updated with any filters imported during result processing * * @return */ abstract List annotationFromScoreManager( AlignmentI seqs, Map featureColours, Map featureFilters); /** * create and complete an annotation row from a JABAWS score object * * @param alignViewport * @param gapMap * @param ourAnnot * @param calcId * @param alWidth * @param scr */ protected void createAnnotationRowsForScores(AlignmentI al_result, boolean[] gapMap, List ourAnnot, String calcId, int alWidth, Score scr) { // simple annotation row AlignmentAnnotation annotation = al_result .findOrCreateAnnotation(scr.getMethod(), calcId, true, null, null); if (gapMap == null || alWidth == gapMap.length) // scr.getScores().size()) { constructAnnotationFromScore(gapMap, annotation, 0, alWidth, scr); ourAnnot.add(annotation); } } /** * create a sequence associated annotation row for JABAWS score object scr * * @param alignViewport * @param gapMap * @param ourAnnot * @param typeName * @param calcId * @param dseq * @param base * @param scr * @return */ protected AlignmentAnnotation createAnnotationRowsForScores( AlignmentI alignment, boolean[] gapMap, List ourAnnot, String typeName, String calcId, SequenceI dseq, int base, Score scr) { System.out.println("Creating annotation on dseq:" + dseq.getStart() + " base is " + base + " and length=" + dseq.getLength() + " == " + scr.getScores().size()); // AlignmentAnnotation annotation = new AlignmentAnnotation( // scr.getMethod(), typeName, new Annotation[] // {}, 0, -1, AlignmentAnnotation.LINE_GRAPH); // annotation.setCalcId(calcId); AlignmentAnnotation annotation = alignment .findOrCreateAnnotation(typeName, calcId, false, dseq, null); constructAnnotationFromScore(gapMap, annotation, 0, dseq.getLength(), scr); annotation.createSequenceMapping(dseq, base, false); annotation.adjustForAlignment(); dseq.addAlignmentAnnotation(annotation); ourAnnot.add(annotation); return annotation; } /** * create column annotation elements from Jabaws score object * * @param gapMap * @param annotation * @param base * @param alWidth * @param scr * JABAWS score object */ protected void constructAnnotationFromScore(boolean[] gapMap, AlignmentAnnotation annotation, int base, int alWidth, Score scr) { Annotation[] elm = new Annotation[alWidth]; Iterator vals = scr.getScores().iterator(); float m = 0f, x = 0f; for (int i = 0; vals.hasNext(); i++) { float val = vals.next().floatValue(); if (i == 0) { m = val; x = val; } else { if (m > val) { m = val; } ; if (x < val) { x = val; } } // if we're at a gapped column then skip to next ungapped position if (gapMap != null && gapMap.length > 0) { // if gapMap is a different length to the result then it may be out of // sync with the job. while (i < gapMap.length && !gapMap[i]) { elm[i++] = new Annotation("", "", ' ', Float.NaN); } } elm[i] = new Annotation("", "" + val, ' ', val); } annotation.annotations = elm; annotation.belowAlignment = true; if (x < 0) { x = 0; } x += (x - m) * 0.1; annotation.graphMax = x; annotation.graphMin = m; annotation.validateRangeAndDisplay(); } }