Clover icon

Coverage Report

  1. Project Clover database Fri Nov 1 2024 11:46:37 GMT
  2. Package jalview.analysis

File AlignmentAnnotationUtils.java

 

Coverage histogram

../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

36
52
3
1
242
140
27
0.52
17.33
3
9

Classes

Class Line # Actions
AlignmentAnnotationUtils 35 52 27
0.9560439695.6%
 

Contributing tests

This file is covered by 13 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.analysis;
22   
23    import jalview.datamodel.AlignmentAnnotation;
24    import jalview.datamodel.SequenceI;
25    import jalview.renderer.AnnotationRenderer;
26   
27    import java.util.ArrayList;
28    import java.util.Arrays;
29    import java.util.BitSet;
30    import java.util.Collections;
31    import java.util.HashMap;
32    import java.util.List;
33    import java.util.Map;
34   
 
35    public class AlignmentAnnotationUtils
36    {
37   
38    /**
39    * Helper method to populate lists of annotation types for the Show/Hide
40    * Annotations menus. If sequenceGroup is not null, this is restricted to
41    * annotations which are associated with sequences in the selection group.
42    * <p/>
43    * If an annotation row is currently visible, its type (label) is added (once
44    * only per type), to the shownTypes list. If it is currently hidden, it is
45    * added to the hiddenTypesList.
46    * <p/>
47    * For rows that belong to a line graph group, so are always rendered
48    * together:
49    * <ul>
50    * <li>Treat all rows in the group as visible, if at least one of them is</li>
51    * <li>Build a list of all the annotation types that belong to the group</li>
52    * </ul>
53    *
54    * @param shownTypes
55    * a map, keyed by calcId (annotation source), whose entries are the
56    * lists of annotation types found for the calcId; each annotation
57    * type in turn may be a list (in the case of grouped annotations)
58    * @param hiddenTypes
59    * a map, similar to shownTypes, but for hidden annotation types
60    * @param annotations
61    * the annotations on the alignment to scan
62    * @param forSequences
63    * the sequences to restrict search to
64    */
 
65  47 toggle public static void getShownHiddenTypes(
66    Map<String, List<List<String>>> shownTypes,
67    Map<String, List<List<String>>> hiddenTypes,
68    List<AlignmentAnnotation> annotations,
69    List<SequenceI> forSequences)
70    {
71  47 BitSet visibleGraphGroups = AlignmentAnnotationUtils
72    .getVisibleLineGraphGroups(annotations);
73   
74    /*
75    * Build a lookup, by calcId (annotation source), of all annotation types in
76    * each graph group.
77    */
78  47 Map<String, Map<Integer, List<String>>> groupLabels = new HashMap<String, Map<Integer, List<String>>>();
79   
80    // trackers for which calcId!label combinations we have dealt with
81  47 List<String> addedToShown = new ArrayList<String>();
82  47 List<String> addedToHidden = new ArrayList<String>();
83   
84  47 for (AlignmentAnnotation aa : annotations)
85    {
86    /*
87    * Ignore non-positional annotations, can't render these against an
88    * alignment
89    */
90  224 if (aa.annotations == null)
91    {
92  0 continue;
93    }
94  224 if (forSequences != null && (aa.sequenceRef != null
95    && forSequences.contains(aa.sequenceRef)))
96    {
97  22 String calcId = aa.getCalcId();
98   
99    /*
100    * Build a 'composite label' for types in line graph groups.
101    */
102  22 final List<String> labelAsList = new ArrayList<String>();
103  22 final String displayLabel = aa.label;
104  22 labelAsList.add(displayLabel);
105  22 if (aa.graph == AlignmentAnnotation.LINE_GRAPH
106    && aa.graphGroup > -1)
107    {
108  8 if (!groupLabels.containsKey(calcId))
109    {
110  2 groupLabels.put(calcId, new HashMap<Integer, List<String>>());
111    }
112  8 Map<Integer, List<String>> groupLabelsForCalcId = groupLabels
113    .get(calcId);
114  8 if (groupLabelsForCalcId.containsKey(aa.graphGroup))
115    {
116  4 if (!groupLabelsForCalcId.get(aa.graphGroup)
117    .contains(displayLabel))
118    {
119  4 groupLabelsForCalcId.get(aa.graphGroup).add(displayLabel);
120    }
121    }
122    else
123    {
124  4 groupLabelsForCalcId.put(aa.graphGroup, labelAsList);
125    }
126    }
127    else
128    /*
129    * 'Simple case' - not a grouped annotation type - list of one label
130    * only
131    */
132    {
133  14 String rememberAs = calcId + "!" + displayLabel;
134  14 if (aa.isForDisplay() && !addedToShown.contains(rememberAs)) // exclude noData annotations
135    {
136  6 if (!shownTypes.containsKey(calcId))
137    {
138  4 shownTypes.put(calcId, new ArrayList<List<String>>());
139    }
140  6 shownTypes.get(calcId).add(labelAsList);
141  6 addedToShown.add(rememberAs);
142    }
143    else
144    {
145  8 if (!aa.visible && !addedToHidden.contains(rememberAs))
146    {
147  8 if (!hiddenTypes.containsKey(calcId))
148    {
149  7 hiddenTypes.put(calcId, new ArrayList<List<String>>());
150    }
151  8 hiddenTypes.get(calcId).add(labelAsList);
152  8 addedToHidden.add(rememberAs);
153    }
154    }
155    }
156    }
157    }
158    /*
159    * Finally add the 'composite group labels' to the appropriate lists,
160    * depending on whether the group is identified as visible or hidden. Don't
161    * add the same label more than once (there may be many graph groups that
162    * generate it).
163    */
164  47 for (String calcId : groupLabels.keySet())
165    {
166  2 for (int group : groupLabels.get(calcId).keySet())
167    {
168  4 final List<String> groupLabel = groupLabels.get(calcId).get(group);
169    // don't want to duplicate 'same types in different order'
170  4 Collections.sort(groupLabel);
171  4 if (visibleGraphGroups.get(group))
172    {
173  2 if (!shownTypes.containsKey(calcId))
174    {
175  1 shownTypes.put(calcId, new ArrayList<List<String>>());
176    }
177  2 if (!shownTypes.get(calcId).contains(groupLabel))
178    {
179  1 shownTypes.get(calcId).add(groupLabel);
180    }
181    }
182    else
183    {
184  2 if (!hiddenTypes.containsKey(calcId))
185    {
186  1 hiddenTypes.put(calcId, new ArrayList<List<String>>());
187    }
188  2 if (!hiddenTypes.get(calcId).contains(groupLabel))
189    {
190  1 hiddenTypes.get(calcId).add(groupLabel);
191    }
192    }
193    }
194    }
195    }
196   
197    /**
198    * Returns a BitSet (possibly empty) of those graphGroups for line graph
199    * annotations, which have at least one member annotation row marked visible.
200    * <p/>
201    * Only one row in each visible group is marked visible, but when it is drawn,
202    * so are all the other rows in the same group.
203    * <p/>
204    * This lookup set allows us to check whether rows apparently marked not
205    * visible are in fact shown.
206    *
207    * @see AnnotationRenderer#drawComponent
208    * @param annotations
209    * @return
210    */
 
211  48 toggle public static BitSet getVisibleLineGraphGroups(
212    List<AlignmentAnnotation> annotations)
213    {
214  48 BitSet result = new BitSet();
215  48 for (AlignmentAnnotation ann : annotations)
216    {
217  236 if (ann.graph == AlignmentAnnotation.LINE_GRAPH && ann.visible)
218    {
219  6 int gg = ann.graphGroup;
220  6 if (gg > -1)
221    {
222  5 result.set(gg);
223    }
224    }
225    }
226  48 return result;
227    }
228   
229    /**
230    * Converts an array of AlignmentAnnotation into a List of
231    * AlignmentAnnotation. A null array is converted to an empty list.
232    *
233    * @param anns
234    * @return
235    */
 
236  51 toggle public static List<AlignmentAnnotation> asList(AlignmentAnnotation[] anns)
237    {
238    // TODO use AlignmentAnnotationI instead when it exists
239  51 return (anns == null ? Collections.<AlignmentAnnotation> emptyList()
240    : Arrays.asList(anns));
241    }
242    }