Clover icon

Coverage Report

  1. Project Clover database Tue Nov 18 2025 10:51:49 GMT
  2. Package jalview.workers

File SecondaryStructureConsensusThread.java

 

Coverage histogram

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

Code metrics

30
79
14
1
302
202
36
0.46
5.64
14
2.57

Classes

Class Line # Actions
SecondaryStructureConsensusThread 41 79 36
0.8373983583.7%
 

Contributing tests

This file is covered by 211 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 java.util.Collections;
24    import java.util.HashMap;
25    import java.util.List;
26    import java.util.Map;
27   
28    import jalview.analysis.AAFrequency;
29    import jalview.analysis.AlignmentUtils;
30    import jalview.api.AlignViewportI;
31    import jalview.api.AlignmentViewPanel;
32    import jalview.datamodel.AlignmentAnnotation;
33    import jalview.datamodel.AlignmentI;
34    import jalview.datamodel.Annotation;
35    import jalview.datamodel.ProfilesI;
36    import jalview.datamodel.SequenceI;
37    import jalview.renderer.ResidueShaderI;
38    import jalview.util.Constants;
39    import jalview.util.MessageManager;
40   
 
41    public class SecondaryStructureConsensusThread extends AlignCalcWorker
42    {
 
43  546 toggle public SecondaryStructureConsensusThread(AlignViewportI alignViewport,
44    AlignmentViewPanel alignPanel)
45    {
46  546 super(alignViewport, alignPanel);
47    }
48   
 
49  1588 toggle @Override
50    public void run()
51    {
52  1588 if (calcMan.isPending(this))
53    {
54  63 return;
55    }
56  1525 calcMan.notifyStart(this);
57    // long started = System.currentTimeMillis();
58  1525 try
59    {
60  1525 List<AlignmentAnnotation> ssConsensus = getSSConsensusAnnotation();
61  1525 if ((ssConsensus == null) || calcMan.isPending(this))
62    {
63  127 calcMan.workerComplete(this);
64  127 return;
65    }
66  1399 while (!calcMan.notifyWorking(this))
67    {
68  1 try
69    {
70  1 if (ap != null)
71    {
72  1 ap.paintAlignment(false, false);
73    }
74  1 Thread.sleep(200);
75    } catch (Exception ex)
76    {
77  0 ex.printStackTrace();
78    }
79    }
80  1398 if (alignViewport.isClosed())
81    {
82  0 abortAndDestroy();
83  0 return;
84    }
85  1398 AlignmentI alignment = alignViewport.getAlignment();
86   
87  1398 int aWidth = -1;
88   
89  ? if (alignment == null || (aWidth = alignment.getWidth()) < 0)
90    {
91  0 calcMan.workerComplete(this);
92  0 return;
93    }
94   
95  1398 setSecondaryStructureSources();
96  1398 eraseSSConsensus(aWidth);
97  1397 computeSSConsensus(alignment);
98  1397 updateResultAnnotation(true);
99   
100  1394 if (ap != null)
101    {
102  1394 ap.paintAlignment(true, true);
103    }
104    } catch (OutOfMemoryError error)
105    {
106  0 calcMan.disableWorker(this);
107  0 ap.raiseOOMWarning("calculating consensus", error);
108    } finally
109    {
110    /*
111    * e.g. ArrayIndexOutOfBoundsException can happen due to a race condition
112    * - alignment was edited at same time as calculation was running
113    */
114  1525 calcMan.workerComplete(this);
115    }
116    }
117   
118    /**
119    * Clear out any existing consensus annotations
120    *
121    * @param aWidth
122    * the width (number of columns) of the annotated alignment
123    */
 
124  1398 toggle protected void eraseSSConsensus(int aWidth)
125    {
126  1398 List<AlignmentAnnotation> ssConsensuses = getSSConsensusAnnotation();
127  1398 for (AlignmentAnnotation ssConsensus : ssConsensuses)
128    {
129  1403 if (ssConsensus != null)
130    {
131  1403 ssConsensus.annotations = new Annotation[aWidth];
132    }
133    }
134    }
135   
136    /**
137    * @param alignment
138    */
 
139  1397 toggle protected void computeSSConsensus(AlignmentI alignment)
140    {
141   
142  1397 SequenceI[] aseqs = getSequences();
143  1397 int width = alignment.getWidth();
144  1397 Map<String, ProfilesI> hSSConsensusProfileMap = new HashMap<String, ProfilesI>();
145  1397 List<String> ssSources = getSecondaryStructureSources();
146  1397 for (String ssSource : ssSources)
147    {
148  1524 ProfilesI hSSConsensus = AAFrequency.calculateSS(aseqs, width, 0,
149    width, true, ssSource, null);
150  1524 hSSConsensusProfileMap.put(ssSource, hSSConsensus);
151    }
152   
153  1397 alignViewport.setSequenceSSConsensusHash(hSSConsensusProfileMap);
154  1397 setColourSchemeConsensus(hSSConsensusProfileMap);
155    }
156   
157    /**
158    * @return
159    */
 
160  2819 toggle protected SequenceI[] getSequences()
161    {
162  2819 return alignViewport.getAlignment().getSequencesArray();
163    }
164   
165    /**
166    * @param hconsensus
167    */
 
168  1397 toggle protected void setColourSchemeConsensus(
169    Map<String, ProfilesI> ssConsensusProfileMap)
170    {
171  1397 ResidueShaderI cs = alignViewport.getResidueShading();
172  1397 if (cs != null)
173    {
174  1395 cs.setSSConsensusProfileMap(ssConsensusProfileMap);
175    }
176    }
177   
178    /**
179    * Get the Consensus annotation for the alignment
180    *
181    * @return
182    */
 
183  4336 toggle protected List<AlignmentAnnotation> getSSConsensusAnnotation()
184    {
185  4336 return alignViewport
186    .getAlignmentSecondaryStructureConsensusAnnotation();
187    }
188   
189    /**
190    * Get the Consensus annotation for the alignment
191    *
192    * @return
193    */
 
194  1398 toggle protected void setSecondaryStructureSources()
195    {
196  1398 List<String> sources = null;
197  1398 AlignmentAnnotation[] aa = alignViewport.getAlignment()
198    .getAlignmentAnnotation();
199  1398 if (aa != null)
200    {
201  1398 sources = AlignmentUtils.extractSSSourceInAlignmentAnnotation(aa);
202  1398 if (sources != null)
203    {
204  1398 sources.add(0, Constants.SS_ALL_PROVIDERS);
205  1398 alignViewport.setSecondaryStructureSources(sources);
206    }
207    }
208    }
209   
 
210  1397 toggle protected List<String> getSecondaryStructureSources()
211    {
212  1397 return alignViewport.getSecondaryStructureSources();
213    }
214   
215    /**
216    * Get the Gap annotation for the alignment
217    *
218    * @return
219    */
 
220  0 toggle protected AlignmentAnnotation getGapAnnotation()
221    {
222  0 return alignViewport.getAlignmentGapAnnotation();
223    }
224   
225    /**
226    * update the consensus annotation from the sequence profile data using
227    * current visualization settings.
228    */
 
229  16 toggle @Override
230    public void updateAnnotation()
231    {
232  16 updateResultAnnotation(false);
233    }
234   
 
235  1413 toggle public void updateResultAnnotation(boolean immediate)
236    {
237  1413 List<AlignmentAnnotation> ssConsensuses = getSSConsensusAnnotation();
238  1413 Map<String, ProfilesI> ssConsensusProfileMap = getViewportSSConsensus();
239  1413 for (AlignmentAnnotation ssConsensus : ssConsensuses)
240    {
241  1424 ProfilesI ssConsensusProfile = null;
242  1424 for (String source : ssConsensusProfileMap.keySet())
243    {
244  1593 if (ssConsensus.description.startsWith(source))
245    {
246  1424 ssConsensusProfile = ssConsensusProfileMap.get(source);
247  1424 break;
248    }
249    }
250  1424 if (ssConsensusProfile == null)
251    {
252  0 continue;
253    }
254  1424 if (immediate || !calcMan.isWorking(this) && ssConsensus != null
255    && ssConsensusProfile != null)
256    {
257  1422 deriveSSConsensus(ssConsensus, ssConsensusProfile);
258   
259  1422 if (ssConsensusProfile.get(1) != null)
260    {
261  1422 ssConsensus.setNoOfSequencesIncluded(
262    ssConsensusProfile.get(1).getSeqWithSSCount());
263    }
264  1422 ssConsensus.setNoOfTracksIncluded(ssConsensusProfile.getCount());
265  1422 ssConsensus.hasData=ssConsensusProfile.getCount()>0;
266    }
267   
268   
269    }
270    }
271   
272    /**
273    * Convert the computed consensus data into the desired annotation for
274    * display.
275    *
276    * @param consensusAnnotation
277    * the annotation to be populated
278    * @param hconsensus
279    * the computed consensus data
280    */
 
281  1422 toggle protected void deriveSSConsensus(AlignmentAnnotation ssConsensus,
282    ProfilesI hSSConsensus)
283    {
284   
285  1422 long nseq = getSequences().length;
286  1422 AAFrequency.completeSSConsensus(ssConsensus, hSSConsensus,
287    hSSConsensus.getStartColumn(), hSSConsensus.getEndColumn() + 1,
288    alignViewport.isIgnoreGapsConsensus(),
289    alignViewport.isShowSequenceLogo(), nseq);
290    }
291   
292    /**
293    * Get the consensus data stored on the viewport.
294    *
295    * @return
296    */
 
297  1413 toggle protected Map<String, ProfilesI> getViewportSSConsensus()
298    {
299    // TODO convert ComplementConsensusThread to use Profile
300  1413 return alignViewport.getSequenceSSConsensusHash();
301    }
302    }