Clover icon

Coverage Report

  1. Project Clover database Mon Dec 1 2025 13:17:41 GMT
  2. Package jalview.workers

File SecondaryStructureConsensusThread.java

 

Coverage histogram

../../img/srcFileCovDistChart9.png
13% 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.878048887.8%
 

Contributing tests

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