Clover icon

Coverage Report

  1. Project Clover database Tue Mar 10 2026 14:58:44 GMT
  2. Package jalview.analysis

File ConservationTest.java

 

Code metrics

0
182
6
1
344
225
6
0.03
30.33
6
1

Classes

Class Line # Actions
ConservationTest 38 182 6
0.00%
 

Contributing tests

No tests hitting this source file were found.

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 static org.testng.Assert.assertEquals;
24    import static org.testng.Assert.assertTrue;
25   
26    import jalview.datamodel.Sequence;
27    import jalview.datamodel.SequenceI;
28    import jalview.gui.JvOptionPane;
29   
30    import java.util.ArrayList;
31    import java.util.HashMap;
32    import java.util.List;
33    import java.util.Map;
34   
35    import org.testng.annotations.BeforeClass;
36    import org.testng.annotations.Test;
37   
 
38    public class ConservationTest
39    {
40   
 
41  0 toggle @BeforeClass(alwaysRun = true)
42    public void setUpJvOptionPane()
43    {
44  0 JvOptionPane.setInteractiveMode(false);
45  0 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
46    }
47   
 
48  0 toggle @Test(groups = "Functional")
49    public void testRecordConservation()
50    {
51  0 Map<String, Integer> resultMap = new HashMap<String, Integer>();
52   
53    // V is hydrophobic, aliphatic, small
54  0 Conservation.recordConservation(resultMap, "V");
55  0 assertEquals(resultMap.get("hydrophobic").intValue(), 1);
56  0 assertEquals(resultMap.get("aliphatic").intValue(), 1);
57  0 assertEquals(resultMap.get("small").intValue(), 1);
58  0 assertEquals(resultMap.get("tiny").intValue(), 0);
59  0 assertEquals(resultMap.get("polar").intValue(), 0);
60  0 assertEquals(resultMap.get("charged").intValue(), 0);
61   
62    // now add S: not hydrophobic, small, tiny, polar, not aliphatic
63  0 Conservation.recordConservation(resultMap, "s");
64  0 assertEquals(resultMap.get("hydrophobic").intValue(), -1);
65  0 assertEquals(resultMap.get("aliphatic").intValue(), -1);
66  0 assertEquals(resultMap.get("small").intValue(), 1);
67  0 assertEquals(resultMap.get("tiny").intValue(), -1);
68  0 assertEquals(resultMap.get("polar").intValue(), -1);
69  0 assertEquals(resultMap.get("charged").intValue(), 0);
70    }
71   
 
72  0 toggle @Test(groups = "Functional")
73    public void testCountConservationAndGaps()
74    {
75  0 List<SequenceI> seqs = new ArrayList<SequenceI>();
76  0 seqs.add(new Sequence("seq1", "VGnY")); // not case sensitive
77  0 seqs.add(new Sequence("seq2", "-G-y"));
78  0 seqs.add(new Sequence("seq3", "VG-Y"));
79  0 seqs.add(new Sequence("seq4", "VGNW"));
80   
81  0 Conservation cons = new Conservation("", seqs, 0, 50);
82  0 int[] counts = cons.countConservationAndGaps(0);
83  0 assertEquals(counts[0], 1); // conserved
84  0 assertEquals(counts[1], 1); // gap count
85  0 counts = cons.countConservationAndGaps(1);
86  0 assertEquals(counts[0], 1);
87  0 assertEquals(counts[1], 0);
88  0 counts = cons.countConservationAndGaps(2);
89  0 assertEquals(counts[0], 1);
90  0 assertEquals(counts[1], 2);
91  0 counts = cons.countConservationAndGaps(3);
92  0 assertEquals(counts[0], 0); // not conserved
93  0 assertEquals(counts[1], 0);
94    }
95   
 
96  0 toggle @Test(groups = "Functional")
97    public void testCalculate_noThreshold()
98    {
99  0 List<SequenceI> seqs = new ArrayList<SequenceI>();
100  0 seqs.add(new Sequence("seq1", "VGIV-N"));
101  0 seqs.add(new Sequence("seq2", "V-iL-N")); // not case sensitive
102  0 seqs.add(new Sequence("seq3", "V-IW-N"));
103  0 seqs.add(new Sequence("seq4", "VGLH-L"));
104   
105  0 Conservation cons = new Conservation("", 0, seqs, 0, 5);
106  0 cons.calculate();
107   
108    /*
109    * column 0: all V (hydrophobic/aliphatic/small)
110    */
111  0 Map<String, Integer> colCons = cons.total[0];
112  0 assertEquals(colCons.get("hydrophobic").intValue(), 1);
113  0 assertEquals(colCons.get("aliphatic").intValue(), 1);
114  0 assertEquals(colCons.get("small").intValue(), 1);
115  0 assertEquals(colCons.get("tiny").intValue(), 0);
116  0 assertEquals(colCons.get("proline").intValue(), 0);
117  0 assertEquals(colCons.get("charged").intValue(), 0);
118  0 assertEquals(colCons.get("negative").intValue(), 0);
119  0 assertEquals(colCons.get("polar").intValue(), 0);
120  0 assertEquals(colCons.get("positive").intValue(), 0);
121  0 assertEquals(colCons.get("aromatic").intValue(), 0);
122   
123    /*
124    * column 1: all G (hydrophobic/small/tiny)
125    * gaps take default value of property present
126    */
127  0 colCons = cons.total[1];
128  0 assertEquals(colCons.get("hydrophobic").intValue(), 1);
129  0 assertEquals(colCons.get("aliphatic").intValue(), -1);
130  0 assertEquals(colCons.get("small").intValue(), 1);
131  0 assertEquals(colCons.get("tiny").intValue(), 1);
132  0 assertEquals(colCons.get("proline").intValue(), -1);
133  0 assertEquals(colCons.get("charged").intValue(), -1);
134  0 assertEquals(colCons.get("negative").intValue(), -1);
135  0 assertEquals(colCons.get("polar").intValue(), -1);
136  0 assertEquals(colCons.get("positive").intValue(), -1);
137  0 assertEquals(colCons.get("aromatic").intValue(), -1);
138   
139    /*
140    * column 2: I/L (aliphatic/hydrophobic), all others negatively conserved
141    */
142  0 colCons = cons.total[2];
143  0 assertEquals(colCons.get("hydrophobic").intValue(), 1);
144  0 assertEquals(colCons.get("aliphatic").intValue(), 1);
145  0 assertEquals(colCons.get("small").intValue(), 0);
146  0 assertEquals(colCons.get("tiny").intValue(), 0);
147  0 assertEquals(colCons.get("proline").intValue(), 0);
148  0 assertEquals(colCons.get("charged").intValue(), 0);
149  0 assertEquals(colCons.get("negative").intValue(), 0);
150  0 assertEquals(colCons.get("polar").intValue(), 0);
151  0 assertEquals(colCons.get("positive").intValue(), 0);
152  0 assertEquals(colCons.get("aromatic").intValue(), 0);
153   
154    /*
155    * column 3: VLWH all hydrophobic, none is tiny, negative or proline
156    */
157  0 colCons = cons.total[3];
158  0 assertEquals(colCons.get("hydrophobic").intValue(), 1);
159  0 assertEquals(colCons.get("aliphatic").intValue(), -1);
160  0 assertEquals(colCons.get("small").intValue(), -1);
161  0 assertEquals(colCons.get("tiny").intValue(), 0);
162  0 assertEquals(colCons.get("proline").intValue(), 0);
163  0 assertEquals(colCons.get("charged").intValue(), -1);
164  0 assertEquals(colCons.get("negative").intValue(), 0);
165  0 assertEquals(colCons.get("polar").intValue(), -1);
166  0 assertEquals(colCons.get("positive").intValue(), -1);
167  0 assertEquals(colCons.get("aromatic").intValue(), -1);
168   
169    /*
170    * column 4: all gaps - counted as having all properties
171    */
172  0 colCons = cons.total[4];
173  0 assertEquals(colCons.get("hydrophobic").intValue(), 1);
174  0 assertEquals(colCons.get("aliphatic").intValue(), 1);
175  0 assertEquals(colCons.get("small").intValue(), 1);
176  0 assertEquals(colCons.get("tiny").intValue(), 1);
177  0 assertEquals(colCons.get("proline").intValue(), 1);
178  0 assertEquals(colCons.get("charged").intValue(), 1);
179  0 assertEquals(colCons.get("negative").intValue(), 1);
180  0 assertEquals(colCons.get("polar").intValue(), 1);
181  0 assertEquals(colCons.get("positive").intValue(), 1);
182  0 assertEquals(colCons.get("aromatic").intValue(), 1);
183   
184    /*
185    * column 5: N (small polar) and L (aliphatic hydrophobic)
186    * have nothing in common!
187    */
188  0 colCons = cons.total[5];
189  0 assertEquals(colCons.get("hydrophobic").intValue(), -1);
190  0 assertEquals(colCons.get("aliphatic").intValue(), -1);
191  0 assertEquals(colCons.get("small").intValue(), -1);
192  0 assertEquals(colCons.get("tiny").intValue(), 0);
193  0 assertEquals(colCons.get("proline").intValue(), 0);
194  0 assertEquals(colCons.get("charged").intValue(), 0);
195  0 assertEquals(colCons.get("negative").intValue(), 0);
196  0 assertEquals(colCons.get("polar").intValue(), -1);
197  0 assertEquals(colCons.get("positive").intValue(), 0);
198  0 assertEquals(colCons.get("aromatic").intValue(), 0);
199    }
200   
201    /**
202    * Test for the case whether the number of non-gapped sequences in a column
203    * has to be above a threshold
204    */
 
205  0 toggle @Test(groups = "Functional")
206    public void testCalculate_threshold()
207    {
208  0 List<SequenceI> seqs = new ArrayList<SequenceI>();
209  0 seqs.add(new Sequence("seq1", "VGIV-"));
210  0 seqs.add(new Sequence("seq2", "V-iL-")); // not case sensitive
211  0 seqs.add(new Sequence("seq3", "V-IW-"));
212  0 seqs.add(new Sequence("seq4", "VGLH-"));
213  0 seqs.add(new Sequence("seq5", "VGLH-"));
214   
215    /*
216    * threshold 50% means a residue has to occur 3 or more times
217    * in a column to be counted for conservation
218    */
219    // TODO: ConservationThread uses a value of 3
220    // calculateConservation states it is the minimum number of sequences
221    // but it is treated as percentage threshold in calculate() ?
222  0 Conservation cons = new Conservation("", 50, seqs, 0, 4);
223  0 cons.calculate();
224   
225    /*
226    * column 0: all V (hydrophobic/aliphatic/small)
227    */
228  0 Map<String, Integer> colCons = cons.total[0];
229  0 assertEquals(colCons.get("hydrophobic").intValue(), 1);
230  0 assertEquals(colCons.get("aliphatic").intValue(), 1);
231  0 assertEquals(colCons.get("small").intValue(), 1);
232  0 assertEquals(colCons.get("tiny").intValue(), 0);
233  0 assertEquals(colCons.get("proline").intValue(), 0);
234  0 assertEquals(colCons.get("charged").intValue(), 0);
235  0 assertEquals(colCons.get("negative").intValue(), 0);
236  0 assertEquals(colCons.get("polar").intValue(), 0);
237  0 assertEquals(colCons.get("positive").intValue(), 0);
238  0 assertEquals(colCons.get("aromatic").intValue(), 0);
239   
240    /*
241    * column 1: all G (hydrophobic/small/tiny)
242    * gaps are ignored as not above threshold
243    */
244  0 colCons = cons.total[1];
245  0 assertEquals(colCons.get("hydrophobic").intValue(), 1);
246  0 assertEquals(colCons.get("aliphatic").intValue(), 0);
247  0 assertEquals(colCons.get("small").intValue(), 1);
248  0 assertEquals(colCons.get("tiny").intValue(), 1);
249  0 assertEquals(colCons.get("proline").intValue(), 0);
250  0 assertEquals(colCons.get("charged").intValue(), 0);
251  0 assertEquals(colCons.get("negative").intValue(), 0);
252  0 assertEquals(colCons.get("polar").intValue(), 0);
253  0 assertEquals(colCons.get("positive").intValue(), 0);
254  0 assertEquals(colCons.get("aromatic").intValue(), 0);
255   
256    /*
257    * column 2: I/L (aliphatic/hydrophobic), all others negatively conserved
258    */
259  0 colCons = cons.total[2];
260  0 assertEquals(colCons.get("hydrophobic").intValue(), 1);
261  0 assertEquals(colCons.get("aliphatic").intValue(), 1);
262  0 assertEquals(colCons.get("small").intValue(), 0);
263  0 assertEquals(colCons.get("tiny").intValue(), 0);
264  0 assertEquals(colCons.get("proline").intValue(), 0);
265  0 assertEquals(colCons.get("charged").intValue(), 0);
266  0 assertEquals(colCons.get("negative").intValue(), 0);
267  0 assertEquals(colCons.get("polar").intValue(), 0);
268  0 assertEquals(colCons.get("positive").intValue(), 0);
269  0 assertEquals(colCons.get("aromatic").intValue(), 0);
270   
271    /*
272    * column 3: nothing above threshold
273    */
274  0 colCons = cons.total[3];
275  0 assertTrue(colCons.isEmpty());
276   
277    /*
278    * column 4: all gaps - counted as having all properties
279    */
280  0 colCons = cons.total[4];
281  0 assertEquals(colCons.get("hydrophobic").intValue(), 1);
282  0 assertEquals(colCons.get("aliphatic").intValue(), 1);
283  0 assertEquals(colCons.get("small").intValue(), 1);
284  0 assertEquals(colCons.get("tiny").intValue(), 1);
285  0 assertEquals(colCons.get("proline").intValue(), 1);
286  0 assertEquals(colCons.get("charged").intValue(), 1);
287  0 assertEquals(colCons.get("negative").intValue(), 1);
288  0 assertEquals(colCons.get("polar").intValue(), 1);
289  0 assertEquals(colCons.get("positive").intValue(), 1);
290  0 assertEquals(colCons.get("aromatic").intValue(), 1);
291    }
292   
293    /**
294    * Test the method that derives the conservation 'sequence' and the mouseover
295    * tooltips from the computed conservation
296    */
 
297  0 toggle @Test(groups = "Functional")
298    public void testVerdict()
299    {
300  0 List<SequenceI> seqs = new ArrayList<SequenceI>();
301  0 seqs.add(new Sequence("seq1", "VGIVV-H"));
302  0 seqs.add(new Sequence("seq2", "VGILL-H"));
303  0 seqs.add(new Sequence("seq3", "VGIW--R"));
304  0 seqs.add(new Sequence("seq4", "VGLHH--"));
305  0 seqs.add(new Sequence("seq5", "VGLHH-R"));
306  0 seqs.add(new Sequence("seq6", "VGLHH--"));
307  0 seqs.add(new Sequence("seq7", "VGLHH-R"));
308  0 seqs.add(new Sequence("seq8", "VGLHH-R"));
309   
310    // calculate with no threshold
311  0 Conservation cons = new Conservation("", 0, seqs, 0, 6);
312  0 cons.calculate();
313    // positive and negative conservation where <25% gaps in columns
314  0 cons.verdict(false, 25);
315   
316    /*
317    * verify conservation 'sequence'
318    * cols 0 fully conserved and above threshold (*)
319    * col 2 properties fully conserved (+)
320    * col 3 VLWH 1 positively and 3 negatively conserved properties
321    * col 4 has 1 positively conserved property, but because gap contributes a
322    * 'positive' for all properties, no negative conservation is counted
323    * col 5 is all gaps
324    * col 6 has 25% gaps so fails threshold test
325    */
326  0 assertEquals(cons.getConsSequence().getSequenceAsString(), "**+41--");
327   
328    /*
329    * verify tooltips; conserved properties are sorted alphabetically within
330    * positive followed by negative
331    */
332  0 assertEquals(cons.getTooltip(0),
333    "aliphatic hydrophobic small !aromatic !charged !negative !polar !positive !proline !tiny");
334  0 assertEquals(cons.getTooltip(1),
335    "hydrophobic small tiny !aliphatic !aromatic !charged !negative !polar !positive !proline");
336  0 assertEquals(cons.getTooltip(2),
337    "aliphatic hydrophobic !aromatic !charged !negative !polar !positive !proline !small !tiny");
338  0 assertEquals(cons.getTooltip(3),
339    "hydrophobic !negative !proline !tiny");
340  0 assertEquals(cons.getTooltip(4), "hydrophobic");
341  0 assertEquals(cons.getTooltip(5), "");
342  0 assertEquals(cons.getTooltip(6), "");
343    }
344    }