Clover icon

Coverage Report

  1. Project Clover database Thu Nov 27 2025 17:07:57 GMT
  2. Package jalview.workers

File SecondaryStructureConsensusThread.java

 

Coverage histogram

../../img/srcFileCovDistChart8.png
21% of files have more coverage

Code metrics

32
78
13
1
293
195
38
0.49
6
13
2.92

Classes

Class Line # Actions
SecondaryStructureConsensusThread 40 78 38
0.8048780680.5%
 

Contributing tests

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