From ebec7bf5754da64c85a0b1f26511a503247f158f Mon Sep 17 00:00:00 2001 From: jprocter Date: Thu, 3 Nov 2011 17:45:15 +0000 Subject: [PATCH] (JAL-812,JAL-811) - generic test for 'calculation involving annotation' in progress and generic way of (re)starting alignment dependent calculations. --- src/jalview/api/AlignCalcManagerI.java | 50 ++++++++++++ src/jalview/viewmodel/AlignmentViewport.java | 41 ++++------ src/jalview/workers/AlignCalcManager.java | 106 +++++++++++++++++++++++-- src/jalview/workers/ConservationThread.java | 38 ++++++--- src/jalview/workers/StrucConsensusThread.java | 10 +-- 5 files changed, 201 insertions(+), 44 deletions(-) diff --git a/src/jalview/api/AlignCalcManagerI.java b/src/jalview/api/AlignCalcManagerI.java index e310696..e9b625b 100644 --- a/src/jalview/api/AlignCalcManagerI.java +++ b/src/jalview/api/AlignCalcManagerI.java @@ -1,5 +1,9 @@ package jalview.api; +import java.util.List; + +import jalview.datamodel.AlignmentAnnotation; + public interface AlignCalcManagerI { @@ -37,6 +41,11 @@ public interface AlignCalcManagerI void workerCannotRun(AlignCalcWorkerI worker); /** + * indicate that a worker like this may be run on the platform. + * @param worker of class to be removed from the execution blacklist + */ + void workerMayRun(AlignCalcWorkerI worker); + /** * launch a new worker * @param worker */ @@ -55,4 +64,45 @@ public interface AlignCalcManagerI */ boolean isWorking(); + + /** + * register a restartable worker + * @param worker + */ + void registerWorker(AlignCalcWorkerI worker); + + /** + * restart any registered workers + */ + void restartWorkers(); + + /** + * + * @param alignmentAnnotation + * @return true if a currently registered and working worker indicates its involvement with the given alignmentAnnotation + */ + boolean workingInvolvedWith(AlignmentAnnotation alignmentAnnotation); + + /** + * kick any known instances of the given worker class to update their annotation + * @param workerClass + */ + void updateAnnotationFor(Class workerClass); + + /** + * return any registered workers of the given class + * @param workerClass + * @return null or one or more workers of the given class + */ + List getRegisteredWorkersOfClass( + Class workerClass); + + /** + * start any workers of the given class + * @param workerClass + * @return false if no workers of given class were registered + * (note - blacklisted classes cannot be restarted, so this method will return true for blacklisted workers) + */ + boolean startRegisteredWorkersOfClass(Class workerClass); + } diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index 3cac289..703e9a7 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -165,13 +165,6 @@ public abstract class AlignmentViewport implements AlignViewportI protected AlignCalcManagerI calculator=new AlignCalcManager(); - jalview.workers.ConsensusThread consensusThread; - - StrucConsensusThread strucConsensusThread; - - - private ConservationThread conservationThread; - /** * trigger update of conservation annotation */ @@ -183,8 +176,10 @@ public abstract class AlignmentViewport implements AlignViewportI { return; } - - calculator.startWorker(conservationThread=new jalview.workers.ConservationThread(this, ap)); + if (!calculator.startRegisteredWorkersOfClass(jalview.workers.ConservationThread.class)) + { + calculator.registerWorker(new jalview.workers.ConservationThread(this, ap)); + } } /** @@ -197,7 +192,10 @@ public abstract class AlignmentViewport implements AlignViewportI { return; } - calculator.startWorker(consensusThread = new ConsensusThread(this, ap)); + if (!calculator.startRegisteredWorkersOfClass(ConsensusThread.class)) + { + calculator.registerWorker(new ConsensusThread(this, ap)); + } } // --------START Structure Conservation @@ -213,7 +211,10 @@ public abstract class AlignmentViewport implements AlignViewportI { return; } - calculator.startWorker(strucConsensusThread = new StrucConsensusThread(this,ap)); + if (!calculator.startRegisteredWorkersOfClass(StrucConsensusThread.class)) + { + calculator.registerWorker(new StrucConsensusThread(this,ap)); + } } public boolean isCalcInProgress() @@ -226,11 +227,9 @@ public abstract class AlignmentViewport implements AlignViewportI { if (!alignmentAnnotation.autoCalculated) return false; - if ((calculator.isWorking(consensusThread) && consensus==alignmentAnnotation) - || (calculator.isWorking(conservationThread) && (conservation==alignmentAnnotation || quality==alignmentAnnotation)) - || (calculator.isWorking(strucConsensusThread) && strucConsensus==alignmentAnnotation) - ) + if (calculator.workingInvolvedWith(alignmentAnnotation)) { +// System.err.println("grey out ("+alignmentAnnotation.label+")"); return true; } return false; @@ -290,14 +289,8 @@ public abstract class AlignmentViewport implements AlignViewportI // TODO: decouple settings setting from calculation when refactoring // annotation update method from alignframe to viewport this.showSequenceLogo = showSequenceLogo; - if (consensusThread != null) - { - consensusThread.updateAnnotation(); - } - if (strucConsensusThread != null) - { - strucConsensusThread.updateAnnotation(); - } + calculator.updateAnnotationFor(ConsensusThread.class); + calculator.updateAnnotationFor(StrucConsensusThread.class); } this.showSequenceLogo = showSequenceLogo; } @@ -1052,7 +1045,7 @@ public abstract class AlignmentViewport implements AlignViewportI } resetAllColourSchemes(); - + calculator.restartWorkers(); // alignment.adjustSequenceAnnotations(); } diff --git a/src/jalview/workers/AlignCalcManager.java b/src/jalview/workers/AlignCalcManager.java index ef627fa..59f8444 100644 --- a/src/jalview/workers/AlignCalcManager.java +++ b/src/jalview/workers/AlignCalcManager.java @@ -1,15 +1,19 @@ package jalview.workers; import java.util.ArrayList; +import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Map; import jalview.api.AlignCalcManagerI; import jalview.api.AlignCalcWorkerI; +import jalview.datamodel.AlignmentAnnotation; public class AlignCalcManager implements AlignCalcManagerI { + private volatile List restartable = new ArrayList(); + private List blackList = new ArrayList(); /** @@ -31,11 +35,11 @@ public class AlignCalcManager implements AlignCalcManagerI updating.put(worker.getClass(), upd = new ArrayList()); } - // upd.add(worker); + upd.add(worker); } @Override - public synchronized boolean alreadyDoing(AlignCalcWorkerI worker) + public synchronized boolean alreadyDoing(AlignCalcWorkerI worker) { return inProgress.containsKey(worker.getClass()); } @@ -62,6 +66,7 @@ public class AlignCalcManager implements AlignCalcManagerI return true; } + private HashSet canUpdate=new HashSet(); @Override public synchronized void workerComplete(AlignCalcWorkerI worker) { @@ -70,6 +75,7 @@ public class AlignCalcManager implements AlignCalcManagerI if (upd != null) { upd.remove(worker); + canUpdate.add(worker); } } @@ -94,13 +100,101 @@ public class AlignCalcManager implements AlignCalcManagerI @Override public synchronized boolean isWorking(AlignCalcWorkerI worker) { -// System.err.println("isWorking : worker "+(worker!=null ? worker.getClass():"null")+ " "+hashCode()); - return worker!=null && inProgress.get(worker.getClass()) == worker; + // System.err.println("isWorking : worker "+(worker!=null ? + // worker.getClass():"null")+ " "+hashCode()); + return worker != null && inProgress.get(worker.getClass()) == worker; } + @Override public boolean isWorking() { -// System.err.println("isWorking "+hashCode()); - return inProgress.size()>0; + // System.err.println("isWorking "+hashCode()); + return inProgress.size() > 0; + } + + @Override + public void registerWorker(AlignCalcWorkerI worker) + { + if (!restartable.contains(worker)) + { + restartable.add(worker); + } + startWorker(worker); + } + + @Override + public void restartWorkers() + { + for (AlignCalcWorkerI worker : restartable) + { + startWorker(worker); + } + } + + @Override + public boolean workingInvolvedWith(AlignmentAnnotation alignmentAnnotation) + { + if (isWorking()) + { + for (List workers: updating.values()) + { + for (AlignCalcWorkerI worker:workers) + if (worker.involves(alignmentAnnotation)) + { + return true; + } + } + } + return false; + } + + @Override + public void updateAnnotationFor(Class workerClass) + { + for (AlignCalcWorkerI worker:canUpdate.toArray(new AlignCalcWorkerI[1])) + { + if (workerClass.equals(worker.getClass())) + { + worker.updateAnnotation(); + } + } + } + + @Override + public List getRegisteredWorkersOfClass( + Class workerClass) + { + List workingClass=new ArrayList(); + for (AlignCalcWorkerI worker:canUpdate.toArray(new AlignCalcWorkerI[0])) + { + if (workerClass.equals(worker.getClass())) + { + workingClass.add(worker); + } + } + return (workingClass.size()==0) ? null : workingClass; + } + + @Override + public boolean startRegisteredWorkersOfClass(Class workerClass) + { + List workers=getRegisteredWorkersOfClass(workerClass); + if (workers==null) + { + return false; + } + for (AlignCalcWorkerI worker: workers) { + startWorker(worker); + } + return true; + } + + @Override + public void workerMayRun(AlignCalcWorkerI worker) + { + if (blackList.contains(worker.getClass())) + { + blackList.remove(worker.getClass()); + } } } diff --git a/src/jalview/workers/ConservationThread.java b/src/jalview/workers/ConservationThread.java index bd025a5..7d5c661 100644 --- a/src/jalview/workers/ConservationThread.java +++ b/src/jalview/workers/ConservationThread.java @@ -17,6 +17,9 @@ */ package jalview.workers; +import java.util.ArrayList; +import java.util.List; + import jalview.analysis.Conservation; import jalview.api.AlignCalcWorkerI; import jalview.api.AlignmentViewPanel; @@ -34,7 +37,10 @@ public class ConservationThread extends AlignCalcWorker implements AlignCalcWork super(alignViewport, alignPanel); ConsPercGaps = alignViewport.getConsPercGaps(); } - + + private Conservation cons; + AlignmentAnnotation conservation,quality; + int alWidth; public void run() { try @@ -58,13 +64,15 @@ public class ConservationThread extends AlignCalcWorker implements AlignCalcWork if (alignViewport.isClosed()) { abortAndDestroy(); } - + ListourAnnot = new ArrayList(); AlignmentI alignment=alignViewport.getAlignment(); - AlignmentAnnotation conservation=alignViewport.getAlignmentConservationAnnotation(); - AlignmentAnnotation quality=alignViewport.getAlignmentQualityAnnot(); + conservation=alignViewport.getAlignmentConservationAnnotation(); + quality=alignViewport.getAlignmentQualityAnnot(); + ourAnnot.add(conservation); + ourAnnot.add(quality); + ourAnnots = ourAnnot; + // AlignViewport.UPDATING_CONSERVATION = true; - - int alWidth; if (alignment==null || (alWidth=alignment.getWidth())< 0) { @@ -75,11 +83,10 @@ public class ConservationThread extends AlignCalcWorker implements AlignCalcWork return; } - Conservation cons = Conservation.calculateConservation("All", + cons = Conservation.calculateConservation("All", jalview.schemes.ResidueProperties.propHash, 3, alignment.getSequences(), 0, alWidth - 1, false, ConsPercGaps, quality!=null); - cons.completeAnnotations(conservation, - quality, 0, alWidth); + updateResultAnnotation(true); } catch (OutOfMemoryError error) { ap.raiseOOMWarning("calculating conservation", error); @@ -96,4 +103,17 @@ public class ConservationThread extends AlignCalcWorker implements AlignCalcWork } } + + private void updateResultAnnotation(boolean b) + { + if (b || !calcMan.isWorking(this) && cons!=null && conservation!=null && quality!=null) + cons.completeAnnotations(conservation, + quality, 0, alWidth); + } + @Override + public void updateAnnotation() + { + updateResultAnnotation(false); + + } } diff --git a/src/jalview/workers/StrucConsensusThread.java b/src/jalview/workers/StrucConsensusThread.java index 76b87a6..69236d8 100644 --- a/src/jalview/workers/StrucConsensusThread.java +++ b/src/jalview/workers/StrucConsensusThread.java @@ -18,6 +18,9 @@ public class StrucConsensusThread extends AlignCalcWorker implements AlignCalcWo { super(alignViewport, alignPanel); } + AlignmentAnnotation strucConsensus; + Hashtable[] hStrucConsensus; + public void run() { try @@ -51,8 +54,8 @@ public class StrucConsensusThread extends AlignCalcWorker implements AlignCalcWo calcMan.workerComplete(this); return; } - AlignmentAnnotation strucConsensus=alignViewport.getAlignmentStrucConsensusAnnotation(); - Hashtable[] hStrucConsensus=alignViewport.getRnaStructureConsensusHash(); + strucConsensus=alignViewport.getAlignmentStrucConsensusAnnotation(); + hStrucConsensus=alignViewport.getRnaStructureConsensusHash(); strucConsensus.annotations = null; strucConsensus.annotations = new Annotation[aWidth]; @@ -115,9 +118,6 @@ public class StrucConsensusThread extends AlignCalcWorker implements AlignCalcWo public void updateResultAnnotation(boolean immediate) { - AlignmentAnnotation strucConsensus = alignViewport - .getAlignmentStrucConsensusAnnotation(); - Hashtable[] hStrucConsensus = alignViewport.getRnaStructureConsensusHash(); if (immediate || !calcMan.isWorking(this) && strucConsensus!=null && hStrucConsensus!=null) { StructureFrequency.completeConsensus(strucConsensus, -- 1.7.10.2