Clover icon

Coverage Report

  1. Project Clover database Mon Dec 1 2025 15:35:32 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.79674879.7%
 

Contributing tests

This file is covered by 217 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  584 toggle public SecondaryStructureConsensusThread(AlignViewportI alignViewport,
43    AlignmentViewPanel alignPanel)
44    {
45  584 super(alignViewport, alignPanel);
46    }
47   
 
48  3007 toggle @Override
49    public void run()
50    {
51  3007 if (calcMan.isPending(this))
52    {
53  63 return;
54    }
55  2944 calcMan.notifyStart(this);
56    // long started = System.currentTimeMillis();
57  2944 try
58    {
59  2944 List<AlignmentAnnotation> ssConsensus = getSSConsensusAnnotation();
60  2944 if ((ssConsensus == null) || calcMan.isPending(this))
61    {
62  495 calcMan.workerComplete(this);
63  495 return;
64    }
65  2449 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  2449 if (alignViewport.isClosed())
80    {
81  0 abortAndDestroy();
82  0 return;
83    }
84  2449 AlignmentI alignment = alignViewport.getAlignment();
85   
86  2449 int aWidth = -1;
87   
88  ? if (alignment == null || (aWidth = alignment.getWidth()) < 0)
89    {
90  0 calcMan.workerComplete(this);
91  0 return;
92    }
93   
94  2449 alignViewport.setSecondaryStructureSources();
95  2449 eraseSSConsensus(aWidth);
96  2448 computeSSConsensus(alignment);
97  2448 updateResultAnnotation(true);
98   
99  2448 if (ap != null)
100    {
101  2448 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  2944 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  2449 toggle protected void eraseSSConsensus(int aWidth)
124    {
125  2449 List<AlignmentAnnotation> ssConsensuses = getSSConsensusAnnotation();
126  2449 for (AlignmentAnnotation ssConsensus : ssConsensuses)
127    {
128  2678 if (ssConsensus != null)
129    {
130  2678 ssConsensus.annotations = new Annotation[aWidth];
131    }
132    }
133    }
134   
135    /**
136    * @param alignment
137    */
 
138  2448 toggle protected void computeSSConsensus(AlignmentI alignment)
139    {
140   
141  2448 SequenceI[] aseqs = getSequences();
142  2448 int width = alignment.getWidth();
143  2448 Map<String, ProfilesI> hSSConsensusProfileMap = new HashMap<String, ProfilesI>();
144  2448 List<String> ssSources = getSecondaryStructureSources();
145  2448 for (String ssSource : ssSources)
146    {
147  2678 ProfilesI hSSConsensus = AAFrequency.calculateSS(aseqs, width, 0,
148    width, true, ssSource, null);
149  2678 hSSConsensusProfileMap.put(ssSource, hSSConsensus);
150    }
151   
152  2448 alignViewport.setSequenceSSConsensusHash(hSSConsensusProfileMap);
153  2448 setColourSchemeConsensus(hSSConsensusProfileMap);
154    }
155   
156    /**
157    * @return
158    */
 
159  5142 toggle protected SequenceI[] getSequences()
160    {
161  5142 return alignViewport.getAlignment().getSequencesArray();
162    }
163   
164    /**
165    * @param hconsensus
166    */
 
167  2448 toggle protected void setColourSchemeConsensus(
168    Map<String, ProfilesI> ssConsensusProfileMap)
169    {
170  2448 ResidueShaderI cs = alignViewport.getResidueShading();
171  2448 if (cs != null)
172    {
173  2448 cs.setSSConsensusProfileMap(ssConsensusProfileMap);
174    }
175    }
176   
177    /**
178    * Get the Consensus annotation for the alignment
179    *
180    * @return
181    */
 
182  7858 toggle protected List<AlignmentAnnotation> getSSConsensusAnnotation()
183    {
184  7858 return alignViewport
185    .getAlignmentSecondaryStructureConsensusAnnotation();
186    }
187   
 
188  2448 toggle protected List<String> getSecondaryStructureSources()
189    {
190  2448 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  17 toggle @Override
208    public void updateAnnotation()
209    {
210  17 updateResultAnnotation(false);
211    }
212   
 
213  2465 toggle public void updateResultAnnotation(boolean immediate)
214    {
215  2465 List<AlignmentAnnotation> ssConsensuses = getSSConsensusAnnotation();
216  2465 Map<String, ProfilesI> ssConsensusProfileMap = getViewportSSConsensus();
217   
218  2465 boolean singleProvider = false;
219   
220  2465 if(ssConsensusProfileMap.keySet() != null && ssConsensusProfileMap.keySet().size() == 2)
221    {
222  193 singleProvider = true; //Single provider if size is 2 (All, Provider 1)
223    }
224   
225  2465 for (AlignmentAnnotation ssConsensus : ssConsensuses)
226    {
227  2695 ProfilesI ssConsensusProfile = null;
228  2695 for (String source : ssConsensusProfileMap.keySet())
229    {
230  2989 if (ssConsensus.description.startsWith(source))
231    {
232  2695 ssConsensusProfile = ssConsensusProfileMap.get(source);
233  2695 ssConsensus.visible = source.equals(Constants.SS_ALL_PROVIDERS) && singleProvider ? false : true;
234   
235  2695 break;
236    }
237    }
238  2695 if (ssConsensusProfile == null)
239    {
240  0 continue;
241    }
242  2695 if (immediate || !calcMan.isWorking(this) && ssConsensus != null
243    && ssConsensusProfile != null)
244    {
245  2694 deriveSSConsensus(ssConsensus, ssConsensusProfile);
246   
247  2694 if (ssConsensusProfile.get(1) != null)
248    {
249  2694 ssConsensus.setNoOfSequencesIncluded(
250    ssConsensusProfile.get(1).getSeqWithSSCount());
251    }
252  2694 ssConsensus.setNoOfTracksIncluded(ssConsensusProfile.getCount());
253  2694 ssConsensus.hasData=ssConsensusProfile.getCount()>0;
254  2694 if (!ssConsensus.hasData) {
255  2262 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  2694 toggle protected void deriveSSConsensus(AlignmentAnnotation ssConsensus,
273    ProfilesI hSSConsensus)
274    {
275   
276  2694 long nseq = getSequences().length;
277  2694 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  2465 toggle protected Map<String, ProfilesI> getViewportSSConsensus()
289    {
290    // TODO convert ComplementConsensusThread to use Profile
291  2465 return alignViewport.getSequenceSSConsensusHash();
292    }
293    }