2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.workers;
23 import jalview.analysis.AAFrequency;
24 import jalview.api.AlignCalcWorkerI;
25 import jalview.api.AlignViewportI;
26 import jalview.api.AlignmentViewPanel;
27 import jalview.datamodel.AlignmentAnnotation;
28 import jalview.datamodel.AlignmentI;
29 import jalview.datamodel.Annotation;
30 import jalview.datamodel.SequenceI;
31 import jalview.schemes.ColourSchemeI;
33 import java.util.Hashtable;
35 public class ConsensusThread extends AlignCalcWorker implements
39 protected Hashtable<String, Object>[] hconsensus;
40 protected SequenceI[] aseqs;
43 public AlignCalcWorkerI getNewWorker() {
44 return new ConsensusThread(alignViewport, ap);
47 public ConsensusThread(AlignViewportI alignViewport,
48 AlignmentViewPanel alignPanel)
50 super(alignViewport, alignPanel);
55 * The basic idea is that the state starts INIT, and then you can advance it as you
56 * wish to one or more LOOP states, and then to DONE.
58 * The entire operation is within a while loop so that Java need not exit.
60 * You can test for JavaScript using the field isJS.
62 * JSThread simply executes sleepAndReturn() at the end of these loops, returning
63 * TRUE if it is necessary to exit the thread (because this is JavaScript). In the
64 * case of Java, we are simply executing sleep(n), so we embed all this in
69 protected void run1(int state) {
70 while (!interrupted()) {
71 if (alignViewport.isClosed())
79 if (calcMan.isPending(this))
81 calcMan.notifyStart(this);
82 AlignmentAnnotation consensus = getConsensusAnnotation();
83 if (consensus == null || calcMan.isPending(this)) {
84 calcMan.workerComplete(this);
90 while (!calcMan.notifyWorking(this)) {
92 ap.paintAlignment(false);
95 if (sleepAndReturn(200, state))
97 } catch (InterruptedException e) {
102 if (alignViewport.isClosed()) {
107 alignment = alignViewport.getAlignment();
109 if (alignment == null || (aWidth = alignment.getWidth()) < 0) {
112 eraseConsensus(aWidth);
113 state = (initializeCalc() ? LOOP_CALCULATE : DONE);
117 iLast = Math.min(iLast + nPer, aWidth);
118 if (iLast == iFirst) {
122 if (sleepAndReturn(0, state))
132 } catch (OutOfMemoryError error) {
133 calcMan.workerCannotRun(this);
134 ap.raiseOOMWarning("calculating consensus", error);
135 } catch (Throwable e) {
136 System.out.println("Error in ConsensusThread: " + e);
138 calcMan.workerComplete(this);
143 @SuppressWarnings("unchecked")
144 protected boolean initializeCalc() {
146 hconsensus = new Hashtable[aWidth];
147 aseqs = getSequences();
151 protected void computeConsensus() {
152 started = System.currentTimeMillis();
153 AAFrequency.calculate(aseqs, iFirst, iLast, hconsensus, true);
154 if (System.currentTimeMillis() - started < MS_MAX)
158 protected void finalizeCalc() {
159 // BH: I was not sure about the exact placement of each of these steps
160 alignViewport.setSequenceConsensusHash(hconsensus);
163 protected void updateAlignment() {
164 setColourSchemeConsensus(hconsensus);
165 updateResultAnnotation(true);
170 * Clear out any existing consensus annotations
173 * the width (number of columns) of the annotated alignment
175 protected void eraseConsensus(int aWidth)
177 AlignmentAnnotation consensus = getConsensusAnnotation();
178 consensus.annotations = new Annotation[aWidth];
184 protected SequenceI[] getSequences()
186 return alignViewport.getAlignment().getSequencesArray();
192 protected void setColourSchemeConsensus(Hashtable[] hconsensus)
194 ColourSchemeI globalColourScheme = alignViewport
195 .getGlobalColourScheme();
196 if (globalColourScheme != null)
198 globalColourScheme.setConsensus(hconsensus);
203 * Get the Consensus annotation for the alignment
207 protected AlignmentAnnotation getConsensusAnnotation()
209 return alignViewport.getAlignmentConsensusAnnotation();
213 * update the consensus annotation from the sequence profile data using
214 * current visualization settings.
217 public void updateAnnotation()
219 updateResultAnnotation(false);
222 public void updateResultAnnotation(boolean immediate)
224 AlignmentAnnotation consensus = getConsensusAnnotation();
225 Hashtable[] hconsensus = getViewportConsensus();
226 if (immediate || !calcMan.isWorking(this) && consensus != null
227 && hconsensus != null)
229 deriveConsensus(consensus, hconsensus);
234 * Convert the computed consensus data into the desired annotation for
237 * @param consensusAnnotation
238 * the annotation to be populated
239 * @param consensusData
240 * the computed consensus data
242 protected void deriveConsensus(AlignmentAnnotation consensusAnnotation,
243 Hashtable[] consensusData)
245 long nseq = getSequences().length;
246 AAFrequency.completeConsensus(consensusAnnotation, consensusData, 0,
247 consensusData.length, alignViewport.isIgnoreGapsConsensus(),
248 alignViewport.isShowSequenceLogo(), nseq);
252 * Get the consensus data stored on the viewport.
256 protected Hashtable[] getViewportConsensus()
258 return alignViewport.getSequenceConsensusHash();