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 java.util.Locale;
25 import static org.testng.Assert.assertEquals;
26 import static org.testng.Assert.assertFalse;
27 import static org.testng.Assert.assertTrue;
29 import jalview.datamodel.ResidueCount.SymbolCounts;
30 import jalview.gui.JvOptionPane;
32 import java.util.Arrays;
34 import org.junit.Assert;
35 import org.testng.annotations.BeforeClass;
36 import org.testng.annotations.Test;
38 public class ResidueCountTest
41 @BeforeClass(alwaysRun = true)
42 public void setUpJvOptionPane()
44 JvOptionPane.setInteractiveMode(false);
45 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
49 * Test a mix of add and put for nucleotide counting
51 @Test(groups = "Functional")
52 public void test_countNucleotide()
54 ResidueCount rc = new ResidueCount(true);
55 assertEquals(rc.getCount('A'), 0);
56 assertEquals(rc.getGapCount(), 0);
58 assertEquals(rc.add('A'), 1);
59 assertEquals(rc.add('a'), 2);
62 assertEquals(rc.add('G'), 4);
64 assertEquals(rc.add('c'), 1);
66 assertEquals(rc.add('N'), 1);
68 assertEquals(rc.getCount('a'), 2);
69 assertEquals(rc.getCount('A'), 2);
70 assertEquals(rc.getCount('G'), 4);
71 assertEquals(rc.getCount('c'), 4);
72 assertEquals(rc.getCount('T'), 0); // never seen
73 assertEquals(rc.getCount('N'), 1);
74 assertEquals(rc.getCount('?'), 0);
75 assertEquals(rc.getCount('-'), 0);
76 assertEquals(rc.getTotalResidueCount(), 11);
78 assertFalse(rc.isCountingInts());
79 assertFalse(rc.isUsingOtherData());
83 * Test adding to gap count (either using addGap or add)
85 @Test(groups = "Functional")
86 public void testAddGap()
88 ResidueCount rc = new ResidueCount(true);
94 assertEquals(rc.getGapCount(), 4);
95 assertEquals(rc.getCount(' '), 4);
96 assertEquals(rc.getCount('-'), 4);
97 assertEquals(rc.getCount('.'), 4);
98 assertEquals(rc.getTotalResidueCount(), 0);
99 assertFalse(rc.isUsingOtherData());
100 assertFalse(rc.isCountingInts());
102 rc.set(ResidueCount.GAP_COUNT, Short.MAX_VALUE - 2);
103 assertEquals(rc.getGapCount(), Short.MAX_VALUE - 2);
104 assertFalse(rc.isCountingInts());
106 assertEquals(rc.getGapCount(), Short.MAX_VALUE - 1);
107 assertFalse(rc.isCountingInts());
109 assertEquals(rc.getGapCount(), Short.MAX_VALUE);
111 assertTrue(rc.isCountingInts());
112 assertEquals(rc.getGapCount(), Short.MAX_VALUE + 1);
115 @Test(groups = "Functional")
116 public void testOverflow()
121 ResidueCount rc = new ResidueCount(true);
123 rc.put('A', Short.MAX_VALUE - 1);
124 assertFalse(rc.isCountingInts());
126 assertFalse(rc.isCountingInts());
128 assertTrue(rc.isCountingInts());
129 assertEquals(rc.getCount('a'), Short.MAX_VALUE + 1);
131 assertTrue(rc.isCountingInts());
132 assertEquals(rc.getCount('a'), Short.MAX_VALUE + 2);
133 assertEquals(rc.getGapCount(), 1);
135 assertEquals(rc.getGapCount(), 2);
140 rc = new ResidueCount(true);
141 rc.put('G', Short.MAX_VALUE + 1);
142 assertTrue(rc.isCountingInts());
143 assertEquals(rc.getCount('g'), Short.MAX_VALUE + 1);
145 assertTrue(rc.isCountingInts());
146 assertEquals(rc.getCount('g'), 1);
151 rc = new ResidueCount(true);
152 rc.put('G', Short.MIN_VALUE - 1);
153 assertTrue(rc.isCountingInts());
154 assertEquals(rc.getCount('g'), Short.MIN_VALUE - 1);
158 * Test a mix of add and put for peptide counting
160 @Test(groups = "Functional")
161 public void test_countPeptide()
163 ResidueCount rc = new ResidueCount(false);
173 assertEquals(rc.getCount('q'), 5);
174 assertEquals(rc.getCount('X'), 2);
175 assertEquals(rc.getCount('W'), 7);
176 assertEquals(rc.getCount('m'), 13);
177 assertEquals(rc.getCount('G'), 0);
178 assertEquals(rc.getCount('-'), 0);
179 assertEquals(rc.getTotalResidueCount(), 27);
181 assertFalse(rc.isCountingInts());
182 assertFalse(rc.isUsingOtherData());
185 @Test(groups = "Functional")
186 public void test_unexpectedPeptide()
188 ResidueCount rc = new ResidueCount(false);
189 // expected characters (upper or lower case):
190 String aas = "ACDEFGHIKLMNPQRSTVWXY";
191 String lower = aas.toLowerCase(Locale.ROOT);
192 for (int i = 0; i < aas.length(); i++)
194 rc.put(aas.charAt(i), i);
195 rc.add(lower.charAt(i));
197 for (int i = 0; i < aas.length(); i++)
199 assertEquals(rc.getCount(aas.charAt(i)), i + 1);
201 assertFalse(rc.isUsingOtherData());
204 assertTrue(rc.isUsingOtherData());
205 assertEquals(rc.getCount('J'), 4);
207 assertEquals(rc.getCount('J'), 5);
210 @Test(groups = "Functional")
211 public void test_unexpectedNucleotide()
213 ResidueCount rc = new ResidueCount(true);
214 // expected characters (upper or lower case):
215 String nucs = "ACGTUN";
216 String lower = nucs.toLowerCase(Locale.ROOT);
217 for (int i = 0; i < nucs.length(); i++)
219 rc.put(nucs.charAt(i), i);
220 rc.add(lower.charAt(i));
222 for (int i = 0; i < nucs.length(); i++)
224 assertEquals(rc.getCount(nucs.charAt(i)), i + 1);
226 assertFalse(rc.isUsingOtherData());
229 assertTrue(rc.isUsingOtherData());
232 @Test(groups = "Functional")
233 public void testGetModalCount()
235 ResidueCount rc = new ResidueCount(true);
239 assertEquals(rc.getModalCount(), 2);
241 // modal count is in the 'short overflow' counts
242 rc = new ResidueCount();
244 rc.put('g', Short.MAX_VALUE);
246 assertEquals(rc.getModalCount(), Short.MAX_VALUE + 1);
248 // modal count is in the 'other data' counts
249 rc = new ResidueCount(false);
253 assertEquals(rc.getModalCount(), 2);
255 // verify modal count excludes gap
256 rc = new ResidueCount();
263 assertEquals(rc.getModalCount(), 2);
266 @Test(groups = "Functional")
267 public void testGetResiduesForCount()
269 ResidueCount rc = new ResidueCount(true);
273 assertEquals(rc.getResiduesForCount(2), "C");
274 assertEquals(rc.getResiduesForCount(1), "G");
275 assertEquals(rc.getResiduesForCount(3), "");
276 assertEquals(rc.getResiduesForCount(0), "");
277 assertEquals(rc.getResiduesForCount(-1), "");
279 // modal count is in the 'short overflow' counts
280 rc = new ResidueCount(true);
282 rc.put('g', Short.MAX_VALUE);
284 assertEquals(rc.getResiduesForCount(Short.MAX_VALUE + 1), "G");
285 assertEquals(rc.getResiduesForCount(1), "C");
287 // peptide modal count is in the 'short overflow' counts
288 rc = new ResidueCount(false);
290 rc.put('p', Short.MAX_VALUE);
292 assertEquals(rc.getResiduesForCount(Short.MAX_VALUE + 1), "P");
293 assertEquals(rc.getResiduesForCount(1), "C");
295 // modal count is in the 'other data' counts
296 rc = new ResidueCount();
300 assertEquals(rc.getResiduesForCount(1), "Q");
301 assertEquals(rc.getResiduesForCount(2), "{");
303 // residues share modal count
304 rc = new ResidueCount();
310 assertEquals(rc.getResiduesForCount(1), "U");
311 assertEquals(rc.getResiduesForCount(2), "CG");
313 // expected and unexpected symbols share modal count
314 rc = new ResidueCount();
324 assertEquals(rc.getResiduesForCount(1), "U");
325 assertEquals(rc.getResiduesForCount(2), "CGT[");
328 @Test(groups = "Functional")
329 public void testGetSymbolCounts_nucleotide()
331 ResidueCount rc = new ResidueCount(true);
335 rc.add('J'); // 'otherData'
338 rc.put('[', 0); // 'otherdata'
340 SymbolCounts sc = rc.getSymbolCounts();
341 Assert.assertArrayEquals(new char[] { 'C', 'G', 'N', 'J', '[' },
343 Assert.assertArrayEquals(new int[] { 1, 3, 1, 1, 0 }, sc.values);
345 // now with overflow to int counts
346 rc.put('U', Short.MAX_VALUE);
348 sc = rc.getSymbolCounts();
349 Assert.assertArrayEquals(new char[] { 'C', 'G', 'N', 'U', 'J', '[' },
351 Assert.assertArrayEquals(new int[] { 1, 3, 1, 32768, 1, 0 }, sc.values);
354 @Test(groups = "Functional")
355 public void testGetSymbolCounts_peptide()
357 ResidueCount rc = new ResidueCount(false);
361 rc.add('Z'); // 'otherData'
365 SymbolCounts sc = rc.getSymbolCounts();
366 Assert.assertArrayEquals(new char[] { 'L', 'Q', 'W', 'Z' }, sc.symbols);
367 Assert.assertArrayEquals(new int[] { 1, 1, 3, 1 }, sc.values);
369 // now with overflow to int counts
370 rc.put('W', Short.MAX_VALUE);
372 sc = rc.getSymbolCounts();
373 Assert.assertArrayEquals(new char[] { 'L', 'Q', 'W', 'Z' }, sc.symbols);
374 Assert.assertArrayEquals(new int[] { 1, 1, 32768, 1 }, sc.values);
377 @Test(groups = "Functional")
378 public void testToString()
380 ResidueCount rc = new ResidueCount();
384 assertEquals(rc.toString(), "[ C:1 Q:2 ]");
388 assertEquals(rc.toString(), "[ C:1 Q:2 {:1 ]");
390 // switch from short to int counting:
391 rc.put('G', Short.MAX_VALUE);
393 assertEquals(rc.toString(), "[ C:1 G:32768 Q:2 {:1 ]");
396 @Test(groups = "Functional")
397 public void testGetTooltip()
399 ResidueCount rc = new ResidueCount();
402 assertEquals(rc.getTooltip(20, 1), "");
405 * count 7 C, 6 K, 7 Q, 10 P, 9 W, 1 F (total 40)
407 for (int i = 0; i < 7; i++)
412 for (int i = 0; i < 10; i++)
416 for (int i = 0; i < 9; i++)
420 for (int i = 0; i < 6; i++)
427 * percentages are rounded (0.5 rounded up)
428 * 10/40 9/40 7/40 6/40 1/40
430 assertEquals(rc.getTooltip(40, 0),
431 "P 25%; W 23%; C 18%; Q 18%; K 15%; F 3%");
435 * 10/30 9/30 8/30 7/30 6/30 1/30
437 assertEquals(rc.getTooltip(30, 1),
438 "P 33.3%; W 30.0%; Q 26.7%; C 23.3%; K 20.0%; F 3.3%");
441 @Test(groups = "Functional")
442 public void testPut()
444 ResidueCount rc = new ResidueCount();
446 assertEquals(rc.getCount('Q'), 3);
448 assertEquals(rc.getGapCount(), 4);
450 assertEquals(rc.getGapCount(), 5);
452 assertEquals(rc.getGapCount(), 6);
455 assertEquals(rc.getCount('?'), 5);
458 assertEquals(rc.getCount('?'), 6);
459 assertEquals(rc.getCount('!'), 7);
462 @Test(groups = "Functional")
463 public void testConstructor_forSequences()
465 SequenceI seq1 = new Sequence("seq1", "abcde--. FCD");
466 SequenceI seq2 = new Sequence("seq2", "ab.kKqBd-.");
467 ResidueCount rc = new ResidueCount(Arrays.asList(seq1, seq2));
469 assertEquals(rc.getGapCount(), 7);
470 assertEquals(rc.getTotalResidueCount(), 15); // excludes gaps
471 assertEquals(rc.getCount('a'), 2);
472 assertEquals(rc.getCount('A'), 2);
473 assertEquals(rc.getCount('B'), 3);
474 assertEquals(rc.getCount('c'), 2);
475 assertEquals(rc.getCount('D'), 3);
476 assertEquals(rc.getCount('f'), 1);
477 assertEquals(rc.getCount('K'), 2);
478 assertEquals(rc.getCount('Q'), 1);