package jalview.util; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertTrue; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.testng.annotations.Test; public class MapListTest { @Test(groups ={ "Functional" }) public void testSomething() { MapList ml = new MapList(new int[] { 1, 5, 10, 15, 25, 20 }, new int[] { 51, 1 }, 1, 3); MapList ml1 = new MapList(new int[] { 1, 3, 17, 4 }, new int[] { 51, 1 }, 1, 3); MapList ml2 = new MapList(new int[] { 1, 60 }, new int[] { 1, 20 }, 3, 1); // test internal consistency int to[] = new int[51]; testMap(ml, 1, 60); MapList mldna = new MapList(new int[] { 2, 2, 6, 8, 12, 16 }, new int[] { 1, 3 }, 3, 1); int[] frm = mldna.locateInFrom(1, 1); testLocateFrom(mldna, 1, 1, new int[] { 2, 2, 6, 7 }); testMap(mldna, 1, 3); /* * for (int from=1; from<=51; from++) { int[] too=ml.shiftTo(from); int[] * toofrom=ml.shiftFrom(too[0]); * System.out.println("ShiftFrom("+from+")=="+too[0]+" % * "+too[1]+"\t+-+\tShiftTo("+too[0]+")=="+toofrom[0]+" % "+toofrom[1]); } */ } private static void testLocateFrom(MapList mldna, int i, int j, int[] ks) { int[] frm = mldna.locateInFrom(i, j); assertEquals("Failed test locate from " + i + " to " + j, Arrays.toString(frm), Arrays.toString(ks)); } /** * test routine. not incremental. * * @param ml * @param fromS * @param fromE */ private void testMap(MapList ml, int fromS, int fromE) { // todo convert to JUnit style tests for (int from = 1; from <= 25; from++) { int[] too = ml.shiftFrom(from); System.out.print("ShiftFrom(" + from + ")=="); if (too == null) { System.out.print("NaN\n"); } else { System.out.print(too[0] + " % " + too[1] + " (" + too[2] + ")"); System.out.print("\t+--+\t"); int[] toofrom = ml.shiftTo(too[0]); if (toofrom != null) { if (toofrom[0] != from) { System.err.println("Mapping not reflexive:" + from + " " + too[0] + "->" + toofrom[0]); } System.out.println("ShiftTo(" + too[0] + ")==" + toofrom[0] + " % " + toofrom[1] + " (" + toofrom[2] + ")"); } else { System.out.println("ShiftTo(" + too[0] + ")==" + "NaN! - not Bijective Mapping!"); } } } int mmap[][] = ml.makeFromMap(); System.out.println("FromMap : (" + mmap[0][0] + " " + mmap[0][1] + " " + mmap[0][2] + " " + mmap[0][3] + " "); for (int i = 1; i <= mmap[1].length; i++) { if (mmap[1][i - 1] == -1) { System.out.print(i + "=XXX"); } else { System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1])); } if (i % 20 == 0) { System.out.print("\n"); } else { System.out.print(","); } } // test range function System.out.print("\nTest locateInFrom\n"); { int f = mmap[0][2], t = mmap[0][3]; while (f <= t) { System.out.println("Range " + f + " to " + t); int rng[] = ml.locateInFrom(f, t); if (rng != null) { for (int i = 0; i < rng.length; i++) { System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); } } else { System.out.println("No range!"); } System.out.print("\nReversed\n"); rng = ml.locateInFrom(t, f); if (rng != null) { for (int i = 0; i < rng.length; i++) { System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); } } else { System.out.println("No range!"); } System.out.print("\n"); f++; t--; } } System.out.print("\n"); mmap = ml.makeToMap(); System.out.println("ToMap : (" + mmap[0][0] + " " + mmap[0][1] + " " + mmap[0][2] + " " + mmap[0][3] + " "); for (int i = 1; i <= mmap[1].length; i++) { if (mmap[1][i - 1] == -1) { System.out.print(i + "=XXX"); } else { System.out.print(i + "=" + (mmap[0][2] + mmap[1][i - 1])); } if (i % 20 == 0) { System.out.print("\n"); } else { System.out.print(","); } } System.out.print("\n"); // test range function System.out.print("\nTest locateInTo\n"); { int f = mmap[0][2], t = mmap[0][3]; while (f <= t) { System.out.println("Range " + f + " to " + t); int rng[] = ml.locateInTo(f, t); if (rng != null) { for (int i = 0; i < rng.length; i++) { System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); } } else { System.out.println("No range!"); } System.out.print("\nReversed\n"); rng = ml.locateInTo(t, f); if (rng != null) { for (int i = 0; i < rng.length; i++) { System.out.print(rng[i] + ((i % 2 == 0) ? "," : ";")); } } else { System.out.println("No range!"); } f++; t--; System.out.print("\n"); } } } /** * Tests for method that locates ranges in the 'from' map for given range in * the 'to' map. */ @Test(groups ={ "Functional" }) public void testLocateInFrom_noIntrons() { /* * Simple mapping with no introns */ int[] codons = new int[] { 1, 12 }; int[] protein = new int[] { 1, 4 }; MapList ml = new MapList(codons, protein, 3, 1); assertEquals("[1, 3]", Arrays.toString(ml.locateInFrom(1, 1))); assertEquals("[4, 6]", Arrays.toString(ml.locateInFrom(2, 2))); assertEquals("[7, 9]", Arrays.toString(ml.locateInFrom(3, 3))); assertEquals("[10, 12]", Arrays.toString(ml.locateInFrom(4, 4))); assertEquals("[1, 6]", Arrays.toString(ml.locateInFrom(1, 2))); assertEquals("[1, 9]", Arrays.toString(ml.locateInFrom(1, 3))); assertEquals("[1, 12]", Arrays.toString(ml.locateInFrom(1, 4))); assertEquals("[4, 9]", Arrays.toString(ml.locateInFrom(2, 3))); assertEquals("[4, 12]", Arrays.toString(ml.locateInFrom(2, 4))); assertEquals("[7, 12]", Arrays.toString(ml.locateInFrom(3, 4))); assertEquals("[10, 12]", Arrays.toString(ml.locateInFrom(4, 4))); assertNull(ml.locateInFrom(0, 0)); assertNull(ml.locateInFrom(1, 5)); assertNull(ml.locateInFrom(-1, 1)); } /** * Tests for method that locates ranges in the 'from' map for given range in * the 'to' map. */ @Test(groups ={ "Functional" }) public void testLocateInFrom_withIntrons() { /* * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [16, 17, 18] i.e. * 2-3, 5-7, 9-10, 12-12, 14-14, 16-18 */ int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; int[] protein = { 1, 4 }; MapList ml = new MapList(codons, protein, 3, 1); assertEquals("[2, 3, 5, 5]", Arrays.toString(ml.locateInFrom(1, 1))); assertEquals("[6, 7, 9, 9]", Arrays.toString(ml.locateInFrom(2, 2))); assertEquals("[10, 10, 12, 12, 14, 14]", Arrays.toString(ml.locateInFrom(3, 3))); assertEquals("[16, 18]", Arrays.toString(ml.locateInFrom(4, 4))); } /** * Tests for method that locates ranges in the 'to' map for given range in the * 'from' map. */ @Test(groups ={ "Functional" }) public void testLocateInTo_noIntrons() { /* * Simple mapping with no introns */ int[] codons = new int[] { 1, 12 }; int[] protein = new int[] { 1, 4 }; MapList ml = new MapList(codons, protein, 3, 1); assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 3))); assertEquals("[2, 2]", Arrays.toString(ml.locateInTo(4, 6))); assertEquals("[3, 3]", Arrays.toString(ml.locateInTo(7, 9))); assertEquals("[4, 4]", Arrays.toString(ml.locateInTo(10, 12))); assertEquals("[1, 2]", Arrays.toString(ml.locateInTo(1, 6))); assertEquals("[1, 3]", Arrays.toString(ml.locateInTo(1, 9))); assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(1, 12))); assertEquals("[2, 2]", Arrays.toString(ml.locateInTo(4, 6))); assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(4, 12))); /* * A part codon is treated as if a whole one. */ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 1))); assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 2))); assertEquals("[1, 2]", Arrays.toString(ml.locateInTo(1, 4))); assertEquals("[1, 3]", Arrays.toString(ml.locateInTo(2, 8))); assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(3, 11))); assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(5, 11))); assertNull(ml.locateInTo(0, 0)); assertNull(ml.locateInTo(1, 13)); assertNull(ml.locateInTo(-1, 1)); } /** * Tests for method that locates ranges in the 'to' map for given range in the * 'from' map. */ @Test(groups ={ "Functional" }) public void testLocateInTo_withIntrons() { /* * Exons at positions [2, 3, 5] [6, 7, 9] [10, 12, 14] [16, 17, 18] i.e. * 2-3, 5-7, 9-10, 12-12, 14-14, 16-18 */ int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; /* * Mapped proteins at positions 1, 3, 4, 6 in the sequence */ int[] protein = { 1, 1, 3, 4, 6, 6 }; MapList ml = new MapList(codons, protein, 3, 1); /* * Can't map from an unmapped position */ assertNull(ml.locateInTo(1, 2)); assertNull(ml.locateInTo(2, 4)); assertNull(ml.locateInTo(4, 4)); /* * Valid range or subrange of codon1 maps to protein1. */ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 2))); assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(3, 3))); assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(3, 5))); assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 3))); assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 5))); // codon position 6 starts the next protein: assertEquals("[1, 1, 3, 3]", Arrays.toString(ml.locateInTo(3, 6))); // codon positions 7 to 17 (part) cover proteins 2/3/4 at positions 3/4/6 assertEquals("[3, 4, 6, 6]", Arrays.toString(ml.locateInTo(7, 17))); } /** * Test equals method. */ @Test(groups ={ "Functional" }) public void testEquals() { int[] codons = new int[] { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; int[] protein = new int[] { 1, 4 }; MapList ml = new MapList(codons, protein, 3, 1); MapList ml1 = new MapList(codons, protein, 3, 1); // same values MapList ml2 = new MapList(codons, protein, 2, 1); // fromRatio differs MapList ml3 = new MapList(codons, protein, 3, 2); // toRatio differs codons[2] = 4; MapList ml6 = new MapList(codons, protein, 3, 1); // fromShifts differ protein[1] = 3; MapList ml7 = new MapList(codons, protein, 3, 1); // toShifts differ assertTrue(ml.equals(ml)); assertTrue(ml.equals(ml1)); assertTrue(ml1.equals(ml)); assertFalse(ml.equals(null)); assertFalse(ml.equals("hello")); assertFalse(ml.equals(ml2)); assertFalse(ml.equals(ml3)); assertFalse(ml.equals(ml6)); assertFalse(ml.equals(ml7)); assertFalse(ml6.equals(ml7)); try { MapList ml4 = new MapList(codons, null, 3, 1); // toShifts null assertFalse(ml.equals(ml4)); } catch (NullPointerException e) { // actually thrown by constructor before equals can be called } try { MapList ml5 = new MapList(null, protein, 3, 1); // fromShifts null assertFalse(ml.equals(ml5)); } catch (NullPointerException e) { // actually thrown by constructor before equals can be called } } /** * Test for the method that flattens a list of ranges into a single array. */ @Test(groups ={ "Functional" }) public void testGetRanges() { List ranges = new ArrayList(); ranges.add(new int[] { 2, 3 }); ranges.add(new int[] { 5, 6 }); assertEquals("[2, 3, 5, 6]", Arrays.toString(MapList.getRanges(ranges))); } /** * Check state after construction */ @Test(groups ={ "Functional" }) public void testConstructor() { int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; int[] protein = { 1, 1, 3, 4, 6, 6 }; MapList ml = new MapList(codons, protein, 3, 1); assertEquals(3, ml.getFromRatio()); assertEquals(2, ml.getFromLowest()); assertEquals(18, ml.getFromHighest()); assertEquals(1, ml.getToLowest()); assertEquals(6, ml.getToHighest()); assertEquals("{[2, 3], [5, 7], [9, 10], [12, 12], [14, 14], [16, 18]}", prettyPrint(ml.getFromRanges())); assertEquals("{[1, 1], [3, 4], [6, 6]}", prettyPrint(ml.getToRanges())); /* * Also copy constructor */ MapList ml2 = new MapList(ml); assertEquals(3, ml2.getFromRatio()); assertEquals(2, ml2.getFromLowest()); assertEquals(18, ml2.getFromHighest()); assertEquals(1, ml2.getToLowest()); assertEquals(6, ml2.getToHighest()); assertEquals("{[2, 3], [5, 7], [9, 10], [12, 12], [14, 14], [16, 18]}", prettyPrint(ml2.getFromRanges())); assertEquals("{[1, 1], [3, 4], [6, 6]}", prettyPrint(ml2.getToRanges())); } /** * Convert a List of {[i, j], [k, l], ...} to "[[i, j], [k, l], ...]" * * @param ranges * @return */ private String prettyPrint(List ranges) { StringBuilder sb = new StringBuilder(ranges.size() * 5); boolean first = true; sb.append("{"); for (int[] range : ranges) { if (!first) { sb.append(", "); } sb.append(Arrays.toString(range)); first = false; } sb.append("}"); return sb.toString(); } /** * Test the method that creates an inverse mapping */ @Test(groups ={ "Functional" }) public void testGetInverse() { int[] codons = { 2, 3, 5, 7, 9, 10, 12, 12, 14, 14, 16, 18 }; int[] protein = { 1, 1, 3, 4, 6, 6 }; MapList ml = new MapList(codons, protein, 3, 1); MapList ml2 = ml.getInverse(); assertEquals(ml.getFromRatio(), ml2.getToRatio()); assertEquals(ml.getFromRatio(), ml2.getToRatio()); assertEquals(ml.getToHighest(), ml2.getFromHighest()); assertEquals(ml.getFromHighest(), ml2.getToHighest()); assertEquals(prettyPrint(ml.getFromRanges()), prettyPrint(ml2.getToRanges())); assertEquals(prettyPrint(ml.getToRanges()), prettyPrint(ml2.getFromRanges())); } @Test(groups ={ "Functional" }) public void testToString() { MapList ml = new MapList(new int[] { 1, 5, 10, 15, 25, 20 }, new int[] { 51, 1 }, 1, 3); String s = ml.toString(); assertEquals("From (1:3) [ [1, 5] [10, 15] [25, 20] ] To [ [51, 1] ]", s); } }