Clover icon

Coverage Report

  1. Project Clover database Fri Nov 28 2025 17:48:58 GMT
  2. Package jalview.workers

File ConsensusThread.java

 

Coverage histogram

../../img/srcFileCovDistChart9.png
13% of files have more coverage

Code metrics

24
64
13
1
265
162
33
0.52
4.92
13
2.54

Classes

Class Line # Actions
ConsensusThread 33 64 33
0.871287187.1%
 

Contributing tests

This file is covered by 206 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
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.
11    *
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.
16    *
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.
20    */
21    package jalview.workers;
22   
23    import jalview.analysis.AAFrequency;
24    import jalview.api.AlignViewportI;
25    import jalview.api.AlignmentViewPanel;
26    import jalview.datamodel.AlignmentAnnotation;
27    import jalview.datamodel.AlignmentI;
28    import jalview.datamodel.Annotation;
29    import jalview.datamodel.ProfilesI;
30    import jalview.datamodel.SequenceI;
31    import jalview.renderer.ResidueShaderI;
32   
 
33    public class ConsensusThread extends AlignCalcWorker
34    {
 
35  521 toggle public ConsensusThread(AlignViewportI alignViewport,
36    AlignmentViewPanel alignPanel)
37    {
38  521 super(alignViewport, alignPanel);
39    }
40   
 
41  1525 toggle @Override
42    public void run()
43    {
44  1525 if (calcMan.isPending(this))
45    {
46  27 return;
47    }
48  1498 calcMan.notifyStart(this);
49    // long started = System.currentTimeMillis();
50  1498 try
51    {
52  1498 AlignmentAnnotation consensus = getConsensusAnnotation();
53  1498 AlignmentAnnotation gap = getGapAnnotation();
54  1498 if ((consensus == null && gap == null) || calcMan.isPending(this))
55    {
56  122 calcMan.workerComplete(this);
57  122 return;
58    }
59  1378 while (!calcMan.notifyWorking(this))
60    {
61    // jalview.bin.Console.errPrintln("Thread
62    // (Consensus"+Thread.currentThread().getName()+") Waiting around.");
63  2 try
64    {
65  2 if (ap != null)
66    {
67  2 ap.paintAlignment(false, false);
68    }
69  2 Thread.sleep(200);
70    } catch (Exception ex)
71    {
72  0 ex.printStackTrace();
73    }
74    }
75  1376 if (alignViewport.isClosed())
76    {
77  0 abortAndDestroy();
78  0 return;
79    }
80  1376 AlignmentI alignment = alignViewport.getAlignment();
81   
82  1376 int aWidth = -1;
83   
84  ? if (alignment == null || (aWidth = alignment.getWidth()) < 0)
85    {
86  0 calcMan.workerComplete(this);
87  0 return;
88    }
89   
90  1376 eraseConsensus(aWidth);
91  1376 computeConsensus(alignment);
92  1375 updateResultAnnotation(true);
93   
94  1372 if (ap != null)
95    {
96  1372 ap.paintAlignment(true, true);
97    }
98    } catch (OutOfMemoryError error)
99    {
100  0 calcMan.disableWorker(this);
101  0 ap.raiseOOMWarning("calculating consensus", error);
102    } finally
103    {
104    /*
105    * e.g. ArrayIndexOutOfBoundsException can happen due to a race condition
106    * - alignment was edited at same time as calculation was running
107    */
108  1498 calcMan.workerComplete(this);
109    }
110    }
111   
112    /**
113    * Clear out any existing consensus annotations
114    *
115    * @param aWidth
116    * the width (number of columns) of the annotated alignment
117    */
 
118  1376 toggle protected void eraseConsensus(int aWidth)
119    {
120  1376 AlignmentAnnotation consensus = getConsensusAnnotation();
121  1376 if (consensus != null)
122    {
123  1376 consensus.annotations = new Annotation[aWidth];
124    }
125  1376 AlignmentAnnotation gap = getGapAnnotation();
126  1376 if (gap != null)
127    {
128  1365 gap.annotations = new Annotation[aWidth];
129    }
130    }
131   
132    /**
133    * @param alignment
134    */
 
135  1371 toggle protected void computeConsensus(AlignmentI alignment)
136    {
137   
138  1371 SequenceI[] aseqs = getSequences();
139  1370 int width = alignment.getWidth();
140  1370 ProfilesI hconsensus = AAFrequency.calculate(aseqs, width, 0, width,
141    true);
142   
143  1370 alignViewport.setSequenceConsensusHash(hconsensus);
144  1370 setColourSchemeConsensus(hconsensus);
145    }
146   
147    /**
148    * @return
149    */
 
150  4139 toggle protected SequenceI[] getSequences()
151    {
152  4139 return alignViewport.getAlignment().getSequencesArray();
153    }
154   
155    /**
156    * @param hconsensus
157    */
 
158  1370 toggle protected void setColourSchemeConsensus(ProfilesI hconsensus)
159    {
160  1370 ResidueShaderI cs = alignViewport.getResidueShading();
161  1370 if (cs != null)
162    {
163  1368 cs.setConsensus(hconsensus);
164    }
165    }
166   
167    /**
168    * Get the Consensus annotation for the alignment
169    *
170    * @return
171    */
 
172  4255 toggle protected AlignmentAnnotation getConsensusAnnotation()
173    {
174  4255 return alignViewport.getAlignmentConsensusAnnotation();
175    }
176   
177    /**
178    * Get the Gap annotation for the alignment
179    *
180    * @return
181    */
 
182  4260 toggle protected AlignmentAnnotation getGapAnnotation()
183    {
184  4260 return alignViewport.getAlignmentGapAnnotation();
185    }
186   
187    /**
188    * update the consensus annotation from the sequence profile data using
189    * current visualization settings.
190    */
 
191  21 toggle @Override
192    public void updateAnnotation()
193    {
194  21 updateResultAnnotation(false);
195    }
196   
 
197  1391 toggle public void updateResultAnnotation(boolean immediate)
198    {
199  1391 AlignmentAnnotation consensus = getConsensusAnnotation();
200  1391 ProfilesI hconsensus = (ProfilesI) getViewportConsensus();
201  1391 if (immediate || !calcMan.isWorking(this) && consensus != null
202    && hconsensus != null)
203    {
204  1388 deriveConsensus(consensus, hconsensus);
205  1386 AlignmentAnnotation gap = getGapAnnotation();
206  1386 if (gap != null)
207    {
208  1375 deriveGap(gap, hconsensus);
209    }
210    }
211    }
212   
213    /**
214    * Convert the computed consensus data into the desired annotation for
215    * display.
216    *
217    * @param consensusAnnotation
218    * the annotation to be populated
219    * @param hconsensus
220    * the computed consensus data
221    */
 
222  1388 toggle protected void deriveConsensus(AlignmentAnnotation consensusAnnotation,
223    ProfilesI hconsensus)
224    {
225   
226  1388 long nseq = getSequences().length;
227  1386 consensusAnnotation.setNoOfSequencesIncluded(nseq);
228  1386 AAFrequency.completeConsensus(consensusAnnotation, hconsensus,
229    hconsensus.getStartColumn(), hconsensus.getEndColumn() + 1,
230    alignViewport.isIgnoreGapsConsensus(),
231    alignViewport.isShowSequenceLogo(), nseq);
232    // TODO: JAL-4425 - from JAL-4392 - uncommenting this line will mean consensus annotation is hidden if only one sequence is shown.
233    // consensusAnnotation.hasData=hconsensus.getCount()>1;
234   
235    }
236   
237    /**
238    * Convert the computed consensus data into a gap annotation row for display.
239    *
240    * @param gapAnnotation
241    * the annotation to be populated
242    * @param hconsensus
243    * the computed consensus data
244    */
 
245  1375 toggle protected void deriveGap(AlignmentAnnotation gapAnnotation,
246    ProfilesI hconsensus)
247    {
248  1375 long nseq = getSequences().length;
249  1375 gapAnnotation.setNoOfSequencesIncluded(nseq);
250  1375 AAFrequency.completeGapAnnot(gapAnnotation, hconsensus,
251    hconsensus.getStartColumn(), hconsensus.getEndColumn() + 1,
252    nseq);
253    }
254   
255    /**
256    * Get the consensus data stored on the viewport.
257    *
258    * @return
259    */
 
260  1391 toggle protected Object getViewportConsensus()
261    {
262    // TODO convert ComplementConsensusThread to use Profile
263  1391 return alignViewport.getSequenceConsensusHash();
264    }
265    }