--- /dev/null
+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<SequenceAnnotation>
+ 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<SequenceI> seqs, WsParamSetI preset,
+ List<ArgumentI> arguments) throws Throwable
+ {
+ String rslt = null;
+ scoremanager = null;
+ List<FastaSequence> 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<AlignmentAnnotation> getAnnotationResult(JobId job,
+ List<SequenceI> seqs, Map<String, FeatureColourI> featureColours,
+ Map<String, FeatureMatcherSetI> 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<AlignmentAnnotation> 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<AlignmentAnnotation> annotationFromScoreManager(
+ AlignmentI seqs, Map<String, FeatureColourI> featureColours,
+ Map<String, FeatureMatcherSetI> 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<AlignmentAnnotation> 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<AlignmentAnnotation> 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<Float> 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();
+ }
+
+}