Clover icon

Coverage Report

  1. Project Clover database Mon Oct 6 2025 17:39:40 BST
  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 205 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  531 toggle public SecondaryStructureConsensusThread(AlignViewportI alignViewport,
44    AlignmentViewPanel alignPanel)
45    {
46  531 super(alignViewport, alignPanel);
47    }
48   
 
49  1536 toggle @Override
50    public void run()
51    {
52  1536 if (calcMan.isPending(this))
53    {
54  37 return;
55    }
56  1499 calcMan.notifyStart(this);
57    // long started = System.currentTimeMillis();
58  1499 try
59    {
60  1499 List<AlignmentAnnotation> ssConsensus = getSSConsensusAnnotation();
61  1499 if ((ssConsensus == null) || calcMan.isPending(this))
62    {
63  110 calcMan.workerComplete(this);
64  110 return;
65    }
66  1390 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  1389 if (alignViewport.isClosed())
81    {
82  0 abortAndDestroy();
83  0 return;
84    }
85  1389 AlignmentI alignment = alignViewport.getAlignment();
86   
87  1389 int aWidth = -1;
88   
89  ? if (alignment == null || (aWidth = alignment.getWidth()) < 0)
90    {
91  0 calcMan.workerComplete(this);
92  0 return;
93    }
94   
95  1389 setSecondaryStructureSources();
96  1389 eraseSSConsensus(aWidth);
97  1388 computeSSConsensus(alignment);
98  1388 updateResultAnnotation(true);
99   
100  1387 if (ap != null)
101    {
102  1387 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  1499 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  1389 toggle protected void eraseSSConsensus(int aWidth)
125    {
126  1389 List<AlignmentAnnotation> ssConsensuses = getSSConsensusAnnotation();
127  1389 for (AlignmentAnnotation ssConsensus : ssConsensuses)
128    {
129  1395 if (ssConsensus != null)
130    {
131  1395 ssConsensus.annotations = new Annotation[aWidth];
132    }
133    }
134    }
135   
136    /**
137    * @param alignment
138    */
 
139  1388 toggle protected void computeSSConsensus(AlignmentI alignment)
140    {
141   
142  1388 SequenceI[] aseqs = getSequences();
143  1388 int width = alignment.getWidth();
144  1388 Map<String, ProfilesI> hSSConsensusProfileMap = new HashMap<String, ProfilesI>();
145  1388 List<String> ssSources = getSecondaryStructureSources();
146  1388 for (String ssSource : ssSources)
147    {
148  1502 ProfilesI hSSConsensus = AAFrequency.calculateSS(aseqs, width, 0,
149    width, true, ssSource, null);
150  1502 hSSConsensusProfileMap.put(ssSource, hSSConsensus);
151    }
152   
153  1388 alignViewport.setSequenceSSConsensusHash(hSSConsensusProfileMap);
154  1388 setColourSchemeConsensus(hSSConsensusProfileMap);
155    }
156   
157    /**
158    * @return
159    */
 
160  2807 toggle protected SequenceI[] getSequences()
161    {
162  2807 return alignViewport.getAlignment().getSequencesArray();
163    }
164   
165    /**
166    * @param hconsensus
167    */
 
168  1388 toggle protected void setColourSchemeConsensus(
169    Map<String, ProfilesI> ssConsensusProfileMap)
170    {
171  1388 ResidueShaderI cs = alignViewport.getResidueShading();
172  1388 if (cs != null)
173    {
174  1387 cs.setSSConsensusProfileMap(ssConsensusProfileMap);
175    }
176    }
177   
178    /**
179    * Get the Consensus annotation for the alignment
180    *
181    * @return
182    */
 
183  4293 toggle protected List<AlignmentAnnotation> getSSConsensusAnnotation()
184    {
185  4293 return alignViewport
186    .getAlignmentSecondaryStructureConsensusAnnotation();
187    }
188   
189    /**
190    * Get the Consensus annotation for the alignment
191    *
192    * @return
193    */
 
194  1389 toggle protected void setSecondaryStructureSources()
195    {
196  1389 List<String> sources = null;
197  1389 AlignmentAnnotation[] aa = alignViewport.getAlignment()
198    .getAlignmentAnnotation();
199  1389 if (aa != null)
200    {
201  1389 sources = AlignmentUtils.extractSSSourceInAlignmentAnnotation(aa);
202  1389 if (sources != null)
203    {
204  1389 sources.add(0, Constants.SS_ALL_PROVIDERS);
205  1389 alignViewport.setSecondaryStructureSources(sources);
206    }
207    }
208    }
209   
 
210  1388 toggle protected List<String> getSecondaryStructureSources()
211    {
212  1388 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  17 toggle @Override
230    public void updateAnnotation()
231    {
232  17 updateResultAnnotation(false);
233    }
234   
 
235  1405 toggle public void updateResultAnnotation(boolean immediate)
236    {
237  1405 List<AlignmentAnnotation> ssConsensuses = getSSConsensusAnnotation();
238  1405 Map<String, ProfilesI> ssConsensusProfileMap = getViewportSSConsensus();
239  1405 for (AlignmentAnnotation ssConsensus : ssConsensuses)
240    {
241  1420 ProfilesI ssConsensusProfile = null;
242  1420 for (String source : ssConsensusProfileMap.keySet())
243    {
244  1570 if (ssConsensus.description.startsWith(source))
245    {
246  1420 ssConsensusProfile = ssConsensusProfileMap.get(source);
247  1420 break;
248    }
249    }
250  1420 if (ssConsensusProfile == null)
251    {
252  0 continue;
253    }
254  1420 if (immediate || !calcMan.isWorking(this) && ssConsensus != null
255    && ssConsensusProfile != null)
256    {
257  1419 deriveSSConsensus(ssConsensus, ssConsensusProfile);
258   
259  1419 if (ssConsensusProfile.get(1) != null)
260    {
261  1419 ssConsensus.setNoOfSequencesIncluded(
262    ssConsensusProfile.get(1).getSeqWithSSCount());
263    }
264  1419 ssConsensus.setNoOfTracksIncluded(ssConsensusProfile.getCount());
265  1419 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  1419 toggle protected void deriveSSConsensus(AlignmentAnnotation ssConsensus,
282    ProfilesI hSSConsensus)
283    {
284   
285  1419 long nseq = getSequences().length;
286  1419 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  1405 toggle protected Map<String, ProfilesI> getViewportSSConsensus()
298    {
299    // TODO convert ComplementConsensusThread to use Profile
300  1405 return alignViewport.getSequenceSSConsensusHash();
301    }
302    }