X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fws%2Fjws2%2FSeqAnnotationServiceCalcWorker.java;h=661bdf7228c31a05929d3fcffe1b06f694a01e6b;hb=4ad3af6fae856880fea0a982e6f0dc65f3109567;hp=e92a33869f2e1e6ea1eae8d3120140bf962db175;hpb=f23b980dfbe309bdeb10514dad28c357b06768a4;p=jalview.git diff --git a/src/jalview/ws/jws2/SeqAnnotationServiceCalcWorker.java b/src/jalview/ws/jws2/SeqAnnotationServiceCalcWorker.java index e92a338..661bdf7 100644 --- a/src/jalview/ws/jws2/SeqAnnotationServiceCalcWorker.java +++ b/src/jalview/ws/jws2/SeqAnnotationServiceCalcWorker.java @@ -21,29 +21,40 @@ package jalview.ws.jws2; import jalview.analysis.AlignSeq; +import jalview.analysis.AlignmentAnnotationUtils; import jalview.analysis.SeqsetUtils; import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; +import jalview.api.FeatureColourI; import jalview.bin.Cache; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.AnnotatedCollectionI; +import jalview.datamodel.Annotation; +import jalview.datamodel.ContiguousI; +import jalview.datamodel.Mapping; import jalview.datamodel.SequenceI; +import jalview.datamodel.features.FeatureMatcherSetI; import jalview.gui.AlignFrame; import jalview.gui.Desktop; import jalview.gui.IProgressIndicator; import jalview.gui.IProgressIndicatorHandler; import jalview.gui.JvOptionPane; +import jalview.gui.WebserviceInfo; +import jalview.schemes.FeatureSettingsAdapter; import jalview.schemes.ResidueProperties; +import jalview.util.MapList; import jalview.util.MessageManager; import jalview.workers.AlignCalcWorker; +import jalview.ws.JobStateSummary; import jalview.ws.api.CancellableI; +import jalview.ws.api.JalviewServiceEndpointProviderI; import jalview.ws.api.JobId; import jalview.ws.api.SequenceAnnotationServiceI; +import jalview.ws.api.ServiceWithParameters; import jalview.ws.api.WSAnnotationCalcManagerI; import jalview.ws.gui.AnnotationWsJob; import jalview.ws.jws2.dm.AAConSettings; -import jalview.ws.jws2.jabaws2.Jws2Instance; import jalview.ws.params.ArgumentI; import jalview.ws.params.WsParamSetI; @@ -56,7 +67,7 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker implements WSAnnotationCalcManagerI { - protected Jws2Instance service; + protected ServiceWithParameters service; protected WsParamSetI preset; @@ -157,7 +168,8 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker super(alignViewport, alignPanel); } - public SeqAnnotationServiceCalcWorker(Jws2Instance service, AlignFrame alignFrame, + public SeqAnnotationServiceCalcWorker(ServiceWithParameters service, + AlignFrame alignFrame, WsParamSetI preset, List paramset) { this(alignFrame.getCurrentView(), alignFrame.alignPanel); @@ -169,7 +181,7 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker this.service = service; try { - annotService = (jalview.ws.api.SequenceAnnotationServiceI) service + annotService = (jalview.ws.api.SequenceAnnotationServiceI) ((JalviewServiceEndpointProviderI) service) .getEndpoint(); } catch (ClassCastException cce) { @@ -189,6 +201,7 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker bySequence = !service.isAlignmentAnalysis(); filterNonStandardResidues = service.isFilterSymbols(); min_valid_seqs = service.getMinimumInputSequences(); + submitGaps = service.isAlignmentAnalysis(); if (service.isInteractiveUpdate()) { @@ -216,8 +229,13 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker @Override public void run() { + if (checkDone()) + { + return; + } if (!hasService()) { + calcMan.workerComplete(this); return; } @@ -227,12 +245,10 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker final boolean cancellable = CancellableI.class .isAssignableFrom(annotService.getClass()); StringBuffer msg = new StringBuffer(); + JobStateSummary job = new JobStateSummary(); + WebserviceInfo info = new WebserviceInfo("foo", "bar", false); try { - if (checkDone()) - { - return; - } List seqs = getInputSequences( alignViewport.getAlignment(), bySequence ? alignViewport.getSelectionGroup() : null); @@ -245,8 +261,6 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker return; } - AlignmentAnnotation[] aa = alignViewport.getAlignment() - .getAlignmentAnnotation(); if (guiProgress != null) { guiProgress.setProgressBar(service.getActionText(), @@ -262,7 +276,9 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker return; } // TODO: handle job submission error reporting here. - + Cache.log.debug("Service " + service.getUri() + "\nSubmitted job ID: " + + rslt); + ; // /// // otherwise, construct WsJob and any UI handlers running = new AnnotationWsJob(); @@ -270,7 +286,7 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker running.setSeqNames(seqNames); running.setStartPos(start); running.setSeqs(seqs); - + job.updateJobPanelState(info, "", running); if (guiProgress != null) { guiProgress.registerHandler(progressId, @@ -296,15 +312,16 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker // and poll for updates until job finishes, fails or becomes stale boolean finished = false; - long rpos = 0; do { Cache.log.debug("Updating status for annotation service."); annotService.updateStatus(running); - - if (running.isFinished()) + job.updateJobPanelState(info, "", running); + if (running.isSubjobComplete()) { - Cache.log.debug("Analysis service job reported finished."); + Cache.log.debug( + "Finished polling analysis service job: status reported is " + + running.getState()); finished = true; } else @@ -324,11 +341,11 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker if (cancellable && ((CancellableI) annotService).cancel(running)) { - System.err.println("Cancelled AACon job: " + rslt); + System.err.println("Cancelled job: " + rslt); } else { - System.err.println("FAILED TO CANCEL AACon job: " + rslt); + System.err.println("FAILED TO CANCEL job: " + rslt); } } catch (Exception x) @@ -368,6 +385,7 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker } } while (!finished); + Cache.log.debug("Job poll loop exited. Job is " + running.getState()); // TODO: need to poll/retry if (serverErrorsLeft > 0) { @@ -378,43 +396,85 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker { } } - // configure job with the associated view's feature renderer, if one - // exists. - // TODO: here one would also grab the 'master feature renderer' in order - // to enable/disable - // features automatically according to user preferences - running.setFeatureRenderer( - ((jalview.gui.AlignmentPanel) ap).cloneFeatureRenderer()); - Cache.log.debug("retrieving job results."); - List returnedAnnot = annotService - .getAlignmentAnnotation(running, this); - Cache.log.debug("Obtained " + (returnedAnnot == null ? "no rows" - : ("" + returnedAnnot.size()))); - running.setAnnotation(returnedAnnot); - - if (running.hasResults()) + if (running.isFinished()) { - jalview.bin.Cache.log.debug("Updating result annotation from Job " - + rslt + " at " + service.getUri()); - updateResultAnnotation(true); - if (running.isTransferSequenceFeatures()) + // expect there to be results to collect + // configure job with the associated view's feature renderer, if one + // exists. + // TODO: here one would also grab the 'master feature renderer' in order + // to enable/disable + // features automatically according to user preferences + running.setFeatureRenderer( + ((jalview.gui.AlignmentPanel) ap).cloneFeatureRenderer()); + Cache.log.debug("retrieving job results."); + final Map featureColours = new HashMap<>(); + final Map featureFilters = new HashMap<>(); + List returnedAnnot = annotService + .getAnnotationResult(running.getJobHandle(), seqs, + featureColours, featureFilters); + + Cache.log.debug("Obtained " + (returnedAnnot == null ? "no rows" + : ("" + returnedAnnot.size()))); + Cache.log.debug("There were " + featureColours.size() + + " feature colours and " + featureFilters.size() + + " filters defined."); + + // TODO + // copy over each annotation row reurned and also defined on each + // sequence, excluding regions not annotated due to gapMap/column + // visibility + + running.setAnnotation(returnedAnnot); + + if (running.hasResults()) { - jalview.bin.Cache.log.debug( - "Updating feature display settings and transferring features from Job " - + rslt + " at " + service.getUri()); - ((jalview.gui.AlignmentPanel) ap) - .updateFeatureRendererFrom(running.getFeatureRenderer()); - // TODO: JAL-1150 - create sequence feature settings API for defining - // styles and enabling/disabling feature overlay on alignment panel - - if (alignFrame.alignPanel == ap) + jalview.bin.Cache.log.debug("Updating result annotation from Job " + + rslt + " at " + service.getUri()); + updateResultAnnotation(true); + if (running.isTransferSequenceFeatures()) { - // only do this if the alignFrame is currently showing this view. - Desktop.getAlignFrameFor(alignViewport) - .setShowSeqFeatures(true); + // TODO + // look at each sequence and lift over any features, excluding + // regions + // not annotated due to gapMap/column visibility + + jalview.bin.Cache.log.debug( + "Updating feature display settings and transferring features from Job " + + rslt + " at " + service.getUri()); + // TODO: consider merge rather than apply here + alignViewport.applyFeaturesStyle(new FeatureSettingsAdapter() + { + @Override + public FeatureColourI getFeatureColour(String type) + { + return featureColours.get(type); + } + + @Override + public FeatureMatcherSetI getFeatureFilters(String type) + { + return featureFilters.get(type); + } + + @Override + public boolean isFeatureDisplayed(String type) + { + return featureColours.containsKey(type); + } + + }); + // TODO: JAL-1150 - create sequence feature settings API for + // defining + // styles and enabling/disabling feature overlay on alignment panel + + if (alignFrame.alignPanel == ap) + { + alignViewport.setShowSequenceFeatures(true); + alignFrame.setMenusForViewport(); + } } + ap.adjustAnnotationHeight(); } - ap.adjustAnnotationHeight(); } Cache.log.debug("Annotation Service Worker thread finished."); } @@ -451,7 +511,6 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker calcMan.workerComplete(this); if (ap != null) { - calcMan.workerComplete(this); if (guiProgress != null && progressId != -1) { guiProgress.setProgressBar("", progressId); @@ -678,8 +737,137 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker if ((immediate || !calcMan.isWorking(this)) && running != null && running.hasResults()) { - List ourAnnot = running.getAnnotation(); - updateOurAnnots(ourAnnot); + List ourAnnot = running.getAnnotation(), + newAnnots = new ArrayList<>(); + // + // update graphGroup for all annotation + // + /** + * find a graphGroup greater than any existing ones this could be a method + * provided by alignment Alignment.getNewGraphGroup() - returns next + * unused graph group + */ + int graphGroup = 1; + if (alignViewport.getAlignment().getAlignmentAnnotation() != null) + { + for (AlignmentAnnotation ala : alignViewport.getAlignment() + .getAlignmentAnnotation()) + { + if (ala.graphGroup > graphGroup) + { + graphGroup = ala.graphGroup; + } + } + } + /** + * update graphGroup in the annotation rows returned from service + */ + // TODO: look at sequence annotation rows and update graph groups in the + // case of reference annotation. + for (AlignmentAnnotation ala : ourAnnot) + { + if (ala.graphGroup > 0) + { + ala.graphGroup += graphGroup; + } + SequenceI aseq = null; + + /** + * transfer sequence refs and adjust gapmap + */ + if (ala.sequenceRef != null) + { + SequenceI seq = running.getSeqNames() + .get(ala.sequenceRef.getName()); + aseq = seq; + while (seq.getDatasetSequence() != null) + { + seq = seq.getDatasetSequence(); + } + } + Annotation[] resAnnot = ala.annotations, + gappedAnnot = new Annotation[Math.max( + alignViewport.getAlignment().getWidth(), + gapMap.length)]; + for (int p = 0, ap = start; ap < gappedAnnot.length; ap++) + { + if (gapMap != null && gapMap.length > ap && !gapMap[ap]) + { + gappedAnnot[ap] = new Annotation("", "", ' ', Float.NaN); + } + else if (p < resAnnot.length) + { + gappedAnnot[ap] = resAnnot[p++]; + } + } + ala.sequenceRef = aseq; + ala.annotations = gappedAnnot; + AlignmentAnnotation newAnnot = getAlignViewport().getAlignment() + .updateFromOrCopyAnnotation(ala); + if (aseq != null) + { + + aseq.addAlignmentAnnotation(newAnnot); + newAnnot.adjustForAlignment(); + + AlignmentAnnotationUtils.replaceAnnotationOnAlignmentWith( + newAnnot, newAnnot.label, newAnnot.getCalcId()); + } + newAnnots.add(newAnnot); + + } + for (SequenceI sq : running.getSeqs()) + { + if (!sq.getFeatures().hasFeatures() + && (sq.getDBRefs() == null || sq.getDBRefs().length == 0)) + { + continue; + } + running.setTransferSequenceFeatures(true); + SequenceI seq = running.getSeqNames().get(sq.getName()); + SequenceI dseq; + ContiguousI seqRange = seq.findPositions(start, end); + + while ((dseq = seq).getDatasetSequence() != null) + { + seq = seq.getDatasetSequence(); + } + List sourceRange = new ArrayList(); + if (gapMap != null && gapMap.length >= end) + { + int lastcol = start, col = start; + do + { + if (col == end || !gapMap[col]) + { + if (lastcol <= (col - 1)) + { + seqRange = seq.findPositions(lastcol, col); + sourceRange.add(seqRange); + } + lastcol = col + 1; + } + } while (++col <= end); + } + else + { + sourceRange.add(seq.findPositions(start, end)); + } + int i = 0; + int source_startend[] = new int[sourceRange.size() * 2]; + + for (ContiguousI range : sourceRange) + { + source_startend[i++] = range.getBegin(); + source_startend[i++] = range.getEnd(); + } + Mapping mp = new Mapping( + new MapList(source_startend, new int[] + { seq.getStart(), seq.getEnd() }, 1, 1)); + dseq.transferAnnotation(sq, mp); + + } + updateOurAnnots(newAnnots); } } @@ -739,15 +927,17 @@ public class SeqAnnotationServiceCalcWorker extends AlignCalcWorker } } our.clear(); - // validate rows and update Alignmment state - for (AlignmentAnnotation an : ourAnnots) - { - alignViewport.getAlignment().validateAnnotation(an); - } - // TODO: may need a menu refresh after this - // af.setMenusForViewport(); - ap.adjustAnnotationHeight(); } + + // validate rows and update Alignmment state + for (AlignmentAnnotation an : ourAnnots) + { + alignViewport.getAlignment().validateAnnotation(an); + } + // TODO: may need a menu refresh after this + // af.setMenusForViewport(); + ap.adjustAnnotationHeight(); + } public SequenceAnnotationServiceI getService()