2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
21 package jalview.datamodel;
23 import static org.testng.Assert.assertEquals;
24 import static org.testng.Assert.assertFalse;
25 import static org.testng.Assert.assertTrue;
27 import jalview.datamodel.ResidueCount.SymbolCounts;
29 import org.junit.Assert;
30 import org.testng.annotations.Test;
32 public class ResidueCountTest
35 * Test a mix of add and put for nucleotide counting
37 @Test(groups = "Functional")
38 public void test_countNucleotide()
40 ResidueCount rc = new ResidueCount(true);
41 assertEquals(rc.getCount('A'), 0);
42 assertEquals(rc.getGapCount(), 0);
44 assertEquals(rc.add('A'), 1);
45 assertEquals(rc.add('a'), 2);
48 assertEquals(rc.add('G'), 4);
50 assertEquals(rc.add('c'), 1);
52 assertEquals(rc.add('N'), 1);
54 assertEquals(rc.getCount('a'), 2);
55 assertEquals(rc.getCount('A'), 2);
56 assertEquals(rc.getCount('G'), 4);
57 assertEquals(rc.getCount('c'), 4);
58 assertEquals(rc.getCount('T'), 0); // never seen
59 assertEquals(rc.getCount('N'), 1);
60 assertEquals(rc.getCount('?'), 0);
61 assertEquals(rc.getCount('-'), 0);
63 assertFalse(rc.isCountingInts());
64 assertFalse(rc.isUsingOtherData());
68 * Test adding to gap count (either using addGap or add)
70 @Test(groups = "Functional")
71 public void testAddGap()
73 ResidueCount rc = new ResidueCount(true);
79 assertEquals(rc.getGapCount(), 4);
80 assertEquals(rc.getCount(' '), 4);
81 assertEquals(rc.getCount('-'), 4);
82 assertEquals(rc.getCount('.'), 4);
83 assertFalse(rc.isUsingOtherData());
84 assertFalse(rc.isCountingInts());
87 @Test(groups = "Functional")
88 public void testOverflow()
93 ResidueCount rc = new ResidueCount(true);
95 rc.put('A', Short.MAX_VALUE - 1);
96 assertFalse(rc.isCountingInts());
98 assertFalse(rc.isCountingInts());
100 assertTrue(rc.isCountingInts());
101 assertEquals(rc.getCount('a'), Short.MAX_VALUE + 1);
103 assertTrue(rc.isCountingInts());
104 assertEquals(rc.getCount('a'), Short.MAX_VALUE + 2);
105 assertEquals(rc.getGapCount(), 1);
107 assertEquals(rc.getGapCount(), 2);
112 rc = new ResidueCount(true);
113 rc.put('G', Short.MAX_VALUE + 1);
114 assertTrue(rc.isCountingInts());
115 assertEquals(rc.getCount('g'), Short.MAX_VALUE + 1);
117 assertTrue(rc.isCountingInts());
118 assertEquals(rc.getCount('g'), 1);
123 rc = new ResidueCount(true);
124 rc.put('G', Short.MIN_VALUE - 1);
125 assertTrue(rc.isCountingInts());
126 assertEquals(rc.getCount('g'), Short.MIN_VALUE - 1);
130 * Test a mix of add and put for peptide counting
132 @Test(groups = "Functional")
133 public void test_countPeptide()
135 ResidueCount rc = new ResidueCount(false);
145 assertEquals(rc.getCount('q'), 5);
146 assertEquals(rc.getCount('X'), 2);
147 assertEquals(rc.getCount('W'), 7);
148 assertEquals(rc.getCount('m'), 13);
149 assertEquals(rc.getCount('G'), 0);
150 assertEquals(rc.getCount('-'), 0);
152 assertFalse(rc.isCountingInts());
153 assertFalse(rc.isUsingOtherData());
156 @Test(groups = "Functional")
157 public void test_unexpectedPeptide()
159 ResidueCount rc = new ResidueCount(false);
160 // expected characters (upper or lower case):
161 String aas = "ACDEFGHIKLMNPQRSTVWXY";
162 String lower = aas.toLowerCase();
163 for (int i = 0; i < aas.length(); i++)
165 rc.put(aas.charAt(i), i);
166 rc.add(lower.charAt(i));
168 for (int i = 0; i < aas.length(); i++)
170 assertEquals(rc.getCount(aas.charAt(i)), i + 1);
172 assertFalse(rc.isUsingOtherData());
175 assertTrue(rc.isUsingOtherData());
176 assertEquals(rc.getCount('J'), 4);
178 assertEquals(rc.getCount('J'), 5);
181 @Test(groups = "Functional")
182 public void test_unexpectedNucleotide()
184 ResidueCount rc = new ResidueCount(true);
185 // expected characters (upper or lower case):
186 String nucs = "ACGTUN";
187 String lower = nucs.toLowerCase();
188 for (int i = 0; i < nucs.length(); i++)
190 rc.put(nucs.charAt(i), i);
191 rc.add(lower.charAt(i));
193 for (int i = 0; i < nucs.length(); i++)
195 assertEquals(rc.getCount(nucs.charAt(i)), i + 1);
197 assertFalse(rc.isUsingOtherData());
200 assertTrue(rc.isUsingOtherData());
203 @Test(groups = "Functional")
204 public void testGetModalCount()
206 ResidueCount rc = new ResidueCount(true);
210 assertEquals(rc.getModalCount(), 2);
212 // modal count is in the 'short overflow' counts
213 rc = new ResidueCount();
215 rc.put('g', Short.MAX_VALUE);
217 assertEquals(rc.getModalCount(), Short.MAX_VALUE + 1);
219 // modal count is in the 'other data' counts
220 rc = new ResidueCount(false);
224 assertEquals(rc.getModalCount(), 2);
226 // verify modal count excludes gap
227 rc = new ResidueCount();
234 assertEquals(rc.getModalCount(), 2);
237 @Test(groups = "Functional")
238 public void testGetResiduesForCount()
240 ResidueCount rc = new ResidueCount(true);
244 assertEquals(rc.getResiduesForCount(2), "C");
245 assertEquals(rc.getResiduesForCount(1), "G");
246 assertEquals(rc.getResiduesForCount(3), "");
247 assertEquals(rc.getResiduesForCount(0), "");
248 assertEquals(rc.getResiduesForCount(-1), "");
250 // modal count is in the 'short overflow' counts
251 rc = new ResidueCount(true);
253 rc.put('g', Short.MAX_VALUE);
255 assertEquals(rc.getResiduesForCount(Short.MAX_VALUE + 1), "G");
256 assertEquals(rc.getResiduesForCount(1), "C");
258 // peptide modal count is in the 'short overflow' counts
259 rc = new ResidueCount(false);
261 rc.put('p', Short.MAX_VALUE);
263 assertEquals(rc.getResiduesForCount(Short.MAX_VALUE + 1), "P");
264 assertEquals(rc.getResiduesForCount(1), "C");
266 // modal count is in the 'other data' counts
267 rc = new ResidueCount();
271 assertEquals(rc.getResiduesForCount(1), "Q");
272 assertEquals(rc.getResiduesForCount(2), "{");
274 // residues share modal count
275 rc = new ResidueCount();
281 assertEquals(rc.getResiduesForCount(1), "U");
282 assertEquals(rc.getResiduesForCount(2), "CG");
284 // expected and unexpected symbols share modal count
285 rc = new ResidueCount();
295 assertEquals(rc.getResiduesForCount(1), "U");
296 assertEquals(rc.getResiduesForCount(2), "CGT[");
299 @Test(groups = "Functional")
300 public void testGetSymbolCounts_nucleotide()
302 ResidueCount rc = new ResidueCount(true);
306 rc.add('J'); // 'otherData'
309 rc.put('[', 0); // 'otherdata'
311 SymbolCounts sc = rc.getSymbolCounts();
312 Assert.assertArrayEquals(new char[] { 'C', 'G', 'N', 'J', '[' },
314 Assert.assertArrayEquals(new int[] { 1, 3, 1, 1, 0 }, sc.values);
316 // now with overflow to int counts
317 rc.put('U', Short.MAX_VALUE);
319 sc = rc.getSymbolCounts();
320 Assert.assertArrayEquals(new char[] { 'C', 'G', 'N', 'U', 'J', '[' },
322 Assert.assertArrayEquals(new int[] { 1, 3, 1, 32768, 1, 0 }, sc.values);
325 @Test(groups = "Functional")
326 public void testGetSymbolCounts_peptide()
328 ResidueCount rc = new ResidueCount(false);
332 rc.add('Z'); // 'otherData'
336 SymbolCounts sc = rc.getSymbolCounts();
337 Assert.assertArrayEquals(new char[] { 'L', 'Q', 'W', 'Z' }, sc.symbols);
338 Assert.assertArrayEquals(new int[] { 1, 1, 3, 1 }, sc.values);
340 // now with overflow to int counts
341 rc.put('W', Short.MAX_VALUE);
343 sc = rc.getSymbolCounts();
344 Assert.assertArrayEquals(new char[] { 'L', 'Q', 'W', 'Z' }, sc.symbols);
345 Assert.assertArrayEquals(new int[] { 1, 1, 32768, 1 }, sc.values);
348 @Test(groups = "Functional")
349 public void testToString()
351 ResidueCount rc = new ResidueCount();
355 assertEquals(rc.toString(), "[ C:1 Q:2 ]");
359 assertEquals(rc.toString(), "[ C:1 Q:2 {:1 ]");
361 // switch from short to int counting:
362 rc.put('G', Short.MAX_VALUE);
364 assertEquals(rc.toString(), "[ C:1 G:32768 Q:2 {:1 ]");
367 @Test(groups = "Functional")
368 public void testGetTooltip()
370 ResidueCount rc = new ResidueCount();
373 assertEquals(rc.getTooltip(20, 1), "");
376 * count 7 C, 6 K, 7 Q, 10 P, 9 W, 1 F (total 40)
378 for (int i = 0; i < 7; i++)
383 for (int i = 0; i < 10; i++)
387 for (int i = 0; i < 9; i++)
391 for (int i = 0; i < 6; i++)
398 * percentages are rounded (0.5 rounded up)
399 * 10/40 9/40 7/40 6/40 1/40
401 assertEquals(rc.getTooltip(40, 0),
402 "P 25%; W 23%; C 18%; Q 18%; K 15%; F 3%");
406 * 10/30 9/30 8/30 7/30 6/30 1/30
408 assertEquals(rc.getTooltip(30, 1),
409 "P 33.3%; W 30.0%; Q 26.7%; C 23.3%; K 20.0%; F 3.3%");
412 @Test(groups = "Functional")
413 public void testPut()
415 ResidueCount rc = new ResidueCount();
417 assertEquals(rc.getCount('Q'), 3);
419 assertEquals(rc.getGapCount(), 4);
421 assertEquals(rc.getGapCount(), 5);
423 assertEquals(rc.getGapCount(), 6);
426 assertEquals(rc.getCount('?'), 5);
429 assertEquals(rc.getCount('?'), 6);
430 assertEquals(rc.getCount('!'), 7);