JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
}
- @Test(groups = { "Functional" })
+ @Test(groups = { "Functional" }, enabled = false)
public void testSomething()
{
MapList ml = new MapList(new int[] { 1, 5, 10, 15, 25, 20 },
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)));
+ // reversed range treated as if forwards:
+ assertEquals("[1, 9]", Arrays.toString(ml.locateInFrom(3, 1)));
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)));
- // reversing the range reverses the result:
- assertEquals("[12, 7]", Arrays.toString(ml.locateInFrom(4, 3))); // fails with [10, 9] !
+ /*
+ * partial overlap
+ */
+ assertEquals("[1, 12]", Arrays.toString(ml.locateInFrom(1, 5)));
+ assertEquals("[1, 3]", Arrays.toString(ml.locateInFrom(-1, 1)));
+
+ /*
+ * no overlap
+ */
assertNull(ml.locateInFrom(0, 0));
- assertNull(ml.locateInFrom(1, 5));
- assertNull(ml.locateInFrom(-1, 1));
}
/**
assertEquals("[12, 10]", Arrays.toString(ml.locateInFrom(1, 1)));
assertEquals("[9, 4]", Arrays.toString(ml.locateInFrom(2, 3)));
}
-
- /**
+
+ /**
* Tests for method that locates ranges in the 'to' map for given range in the
* 'from' map.
*/
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)));
- // reversing the 'from' range reverses the result
- assertEquals("[4, 2]", Arrays.toString(ml.locateInTo(12, 4)));
+ // reverse range treated as if forwards:
+ assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(12, 4)));
/*
* A part codon is treated as if a whole one.
assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(3, 11)));
assertEquals("[2, 4]", Arrays.toString(ml.locateInTo(5, 11)));
+ /*
+ * partial overlap
+ */
+ assertEquals("[1, 4]", Arrays.toString(ml.locateInTo(1, 13)));
+ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(-1, 2)));
+
+ /*
+ * no overlap
+ */
assertNull(ml.locateInTo(0, 0));
- assertNull(ml.locateInTo(1, 13));
- assertNull(ml.locateInTo(-1, 1));
}
/**
MapList ml = new MapList(codons, protein, 3, 1);
/*
- * Can't map from an unmapped position
- */
- assertNull(ml.locateInTo(1, 2));
- assertNull(ml.locateInTo(1, 4));
- 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)));
// 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)));
+
+ /*
+ * partial overlap
+ */
+ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 2)));
+ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(1, 4)));
+ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(2, 4)));
+
+ /*
+ * no overlap
+ */
+ assertNull(ml.locateInTo(4, 4));
}
/**
assertArrayEquals(new int[] { 71, 126 }, toRanges.get(1));
/*
- * method returns null if not all regions are mapped through
+ * if not all regions are mapped through, returns what is
*/
ml1 = new MapList(new int[] { 1, 50 }, new int[] { 101, 150 }, 1, 1);
- ml2 = new MapList(new int[] { 131, 180 }, new int[] { 201, 250 }, 1, 3);
+ ml2 = new MapList(new int[] { 131, 180 }, new int[] { 201, 250 }, 1, 1);
compound = ml1.traverse(ml2);
assertNull(compound);
}
assertEquals("[4, 9]", Arrays.toString(ml.locateInFrom(2, 3)));
assertEquals("[7, 12, 12, 17]", Arrays.toString(ml.locateInFrom(3, 6)));
+ /*
+ * partial overlap of range
+ */
+ assertEquals("[4, 12, 12, 17]", Arrays.toString(ml.locateInFrom(2, 7)));
+ assertEquals("[1, 3]", Arrays.toString(ml.locateInFrom(-1, 1)));
+
+ /*
+ * no overlap in range
+ */
assertNull(ml.locateInFrom(0, 0));
- assertNull(ml.locateInFrom(1, 7));
- assertNull(ml.locateInFrom(-1, 1));
/*
* gene to CDS...from EMBL:MN908947
*/
- int [] gene = new int[] { 266, 13468, 13468, 21555 };
- int [] cds = new int[] { 1, 21291 };
+ int[] gene = new int[] { 266, 13468, 13468, 21555 };
+ int[] cds = new int[] { 1, 21291 };
ml = new MapList(gene, cds, 1, 1);
- assertEquals("[13468, 13468]", Arrays.toString(ml.locateInFrom(13203, 13203)));
- assertEquals("[13468, 13468]", Arrays.toString(ml.locateInFrom(13204, 13204)));
- assertEquals("[13468, 13468]", Arrays.toString(ml.locateInFrom(13203, 13204)));
+ assertEquals("[13468, 13468]",
+ Arrays.toString(ml.locateInFrom(13203, 13203)));
+ assertEquals("[13468, 13468]",
+ Arrays.toString(ml.locateInFrom(13204, 13204)));
+ assertEquals("[13468, 13468, 13468, 13468]",
+ Arrays.toString(ml.locateInFrom(13203, 13204)));
}
/**
assertEquals("[4, 6]", Arrays.toString(ml.locateInTo(11, 15)));
assertEquals("[6, 6]", Arrays.toString(ml.locateInTo(15, 17)));
+ /*
+ * no overlap
+ */
assertNull(ml.locateInTo(0, 0));
- assertNull(ml.locateInTo(1, 18));
- assertNull(ml.locateInTo(-1, 1));
+
+ /*
+ * partial overlap
+ */
+ assertEquals("[1, 6]", Arrays.toString(ml.locateInTo(1, 18)));
+ assertEquals("[1, 1]", Arrays.toString(ml.locateInTo(-1, 1)));
/*
* gene to CDS...from EMBL:MN908947
+ * the base at 13468 is used twice in transcription
*/
- int [] gene = new int[] { 266, 13468, 13468, 21555 };
- int [] cds = new int[] { 1, 21291 };
+ int[] gene = new int[] { 266, 13468, 13468, 21555 };
+ int[] cds = new int[] { 1, 21291 };
ml = new MapList(gene, cds, 1, 1);
- assertEquals("[13203, 13204]", Arrays.toString(ml.locateInTo(13468, 13468)));
+ assertEquals("[13203, 13204]",
+ Arrays.toString(ml.locateInTo(13468, 13468)));
+
+ /*
+ * gene to protein
+ * the base at 13468 is in the codon for 4401N and also 4402R
+ */
+ gene = new int[] { 266, 13468, 13468, 21552 }; // stop codon excluded
+ protein = new int[] { 1, 7096 };
+ ml = new MapList(gene, protein, 3, 1);
+ assertEquals("[4401, 4402]",
+ Arrays.toString(ml.locateInTo(13468, 13468)));
}
@Test(groups = { "Functional" })
}
List<int[]> intervals = new ArrayList<>();
- assertNull(MapList.countPositions(intervals, 1));
-
+ assertNull(MapList.countPositions(intervals, 1));
+
/*
* forward strand
*/
- intervals.add(new int[] {10, 20});
- assertNull(MapList.countPositions(intervals, 9));
- assertNull(MapList.countPositions(intervals, 21));
- assertArrayEquals(new int[] {1, 1}, MapList.countPositions(intervals, 10));
- assertArrayEquals(new int[] {6, 1}, MapList.countPositions(intervals, 15));
- assertArrayEquals(new int[] {11, 1}, MapList.countPositions(intervals, 20));
-
- intervals.add(new int[] {25, 25});
- assertArrayEquals(new int[] {12, 1}, MapList.countPositions(intervals, 25));
-
- // next interval repeats position 25 - which should be counted twice if traversed
- intervals.add(new int[] {25, 26});
- assertArrayEquals(new int[] {12, 1}, MapList.countPositions(intervals, 25));
- assertArrayEquals(new int[] {14, 1}, MapList.countPositions(intervals, 26));
-
+ intervals.add(new int[] { 10, 20 });
+ assertNull(MapList.countPositions(intervals, 9));
+ assertNull(MapList.countPositions(intervals, 21));
+ assertArrayEquals(new int[] { 1, 1 },
+ MapList.countPositions(intervals, 10));
+ assertArrayEquals(new int[] { 6, 1 },
+ MapList.countPositions(intervals, 15));
+ assertArrayEquals(new int[] { 11, 1 },
+ MapList.countPositions(intervals, 20));
+
+ intervals.add(new int[] { 25, 25 });
+ assertArrayEquals(new int[] { 12, 1 },
+ MapList.countPositions(intervals, 25));
+
+ // next interval repeats position 25 - which should be counted twice if
+ // traversed
+ intervals.add(new int[] { 25, 26 });
+ assertArrayEquals(new int[] { 12, 1 },
+ MapList.countPositions(intervals, 25));
+ assertArrayEquals(new int[] { 14, 1 },
+ MapList.countPositions(intervals, 26));
+
/*
* reverse strand
*/
intervals.clear();
- intervals.add(new int[] {5, -5});
- assertNull(MapList.countPositions(intervals, 6));
- assertNull(MapList.countPositions(intervals, -6));
- assertArrayEquals(new int[] {1, -1}, MapList.countPositions(intervals, 5));
- assertArrayEquals(new int[] {7, -1}, MapList.countPositions(intervals, -1));
- assertArrayEquals(new int[] {11, -1}, MapList.countPositions(intervals, -5));
-
+ intervals.add(new int[] { 5, -5 });
+ assertNull(MapList.countPositions(intervals, 6));
+ assertNull(MapList.countPositions(intervals, -6));
+ assertArrayEquals(new int[] { 1, -1 },
+ MapList.countPositions(intervals, 5));
+ assertArrayEquals(new int[] { 7, -1 },
+ MapList.countPositions(intervals, -1));
+ assertArrayEquals(new int[] { 11, -1 },
+ MapList.countPositions(intervals, -5));
+
/*
* reverse then forward
*/
- intervals.add(new int[] {5, 10});
- assertArrayEquals(new int[] {13, 1}, MapList.countPositions(intervals, 6));
-
+ intervals.add(new int[] { 5, 10 });
+ assertArrayEquals(new int[] { 13, 1 },
+ MapList.countPositions(intervals, 6));
+
/*
* reverse then forward then reverse
*/
- intervals.add(new int[] {-10, -20});
- assertArrayEquals(new int[] {20, -1}, MapList.countPositions(intervals, -12));
-
+ intervals.add(new int[] { -10, -20 });
+ assertArrayEquals(new int[] { 20, -1 },
+ MapList.countPositions(intervals, -12));
+
/*
* an interval [x, x] is treated as forward
*/
- intervals.add(new int[] {30, 30});
- assertArrayEquals(new int[] {29, 1}, MapList.countPositions(intervals, 30));
-
+ intervals.add(new int[] { 30, 30 });
+ assertArrayEquals(new int[] { 29, 1 },
+ MapList.countPositions(intervals, 30));
+
/*
* it is the first matched occurrence that is returned
*/
intervals.clear();
- intervals.add(new int[] {1, 2});
- intervals.add(new int[] {2, 3});
- assertArrayEquals(new int[] {2, 1}, MapList.countPositions(intervals, 2));
- intervals.add(new int[] {-1, -2});
- intervals.add(new int[] {-2, -3});
- assertArrayEquals(new int[] {6, -1}, MapList.countPositions(intervals, -2));
+ intervals.add(new int[] { 1, 2 });
+ intervals.add(new int[] { 2, 3 });
+ assertArrayEquals(new int[] { 2, 1 },
+ MapList.countPositions(intervals, 2));
+ intervals.add(new int[] { -1, -2 });
+ intervals.add(new int[] { -2, -3 });
+ assertArrayEquals(new int[] { 6, -1 },
+ MapList.countPositions(intervals, -2));
+ }
+
+ /**
+ * Tests for helper method that adds any overlap (plus offset) to a list of
+ * overlaps
+ */
+ @Test(groups = { "Functional" })
+ public void testAddOverlap()
+ {
+ List<int[]> overlaps = new ArrayList<>();
+ int[] candidate = new int[] { 10, 19 };
+ MapList.addOverlap(overlaps, 5, candidate, 20, 30); // doesn't overlap
+ assertTrue(overlaps.isEmpty());
+ MapList.addOverlap(overlaps, 5, candidate, 31, 40); // doesn't overlap
+ assertTrue(overlaps.isEmpty());
+
+ /*
+ * 10-19 overlaps 15-25 at 15-19, which is offset 5-9 in 10-19
+ * + 5 initial offset
+ */
+ MapList.addOverlap(overlaps, 5, candidate, 15, 25);
+ assertEquals(1, overlaps.size());
+ assertArrayEquals(new int[] { 10, 14 }, overlaps.get(0));
+
+ /*
+ * reverse range overlap:
+ * 300-20 overlaps 15-25 at 25-20, which is offset 275-280 in 300-20
+ * + 8 initial offset
+ */
+ overlaps.clear();
+ candidate = new int[] { 300, 20 };
+ MapList.addOverlap(overlaps, 8, candidate, 15, 25);
+ assertEquals(1, overlaps.size());
+ assertArrayEquals(new int[] { 283, 288 }, overlaps.get(0));
}
@Test(groups = { "Functional" })
public void testFindOverlapPositions()
{
List<int[]> ranges = new ArrayList<>();
- List<int[]> overlaps = MapList.findOverlapPositions(ranges, 20, 30);
+ List<int[]> overlaps = MapList.findOverlapPositions(ranges, 20, 30);
+ assertTrue(overlaps.isEmpty()); // nothing to overlap
+
+ ranges.add(new int[] { 15, 25 });
+ overlaps = MapList.findOverlapPositions(ranges, 5, 10);
+ assertTrue(overlaps.isEmpty()); // no overlap
+
+ overlaps = MapList.findOverlapPositions(ranges, 20, 20);
+ assertEquals(1, overlaps.size());
+ assertArrayEquals(new int[] { 5, 5 }, overlaps.get(0));
+
+ overlaps = MapList.findOverlapPositions(ranges, 5, 19);
+ assertEquals(1, overlaps.size());
+ assertArrayEquals(new int[] { 0, 4 }, overlaps.get(0));
+
+ ranges.add(new int[] { 35, 45 });
+ overlaps = MapList.findOverlapPositions(ranges, 26, 34);
assertTrue(overlaps.isEmpty());
- ranges.add(new int[] {15, 25});
- overlaps = MapList.findOverlapPositions(ranges, 20, 30);
+
+ /*
+ * 24-37 overlaps the end of 15-25 and the start of 35-45
+ * - offset positions are contiguous in the map so merged
+ */
+ overlaps = MapList.findOverlapPositions(ranges, 24, 37);
assertEquals(1, overlaps.size());
- assertArrayEquals(new int[] {6, 11}, overlaps.get(0));
+ assertArrayEquals(new int[] { 9, 13 }, overlaps.get(0));
+
+ /*
+ * EMBL:MN908947 https://www.ebi.ac.uk/ena/browser/api/embl/MN908947
+ * (Covid-SARS-2) CDS mapping with 'slippage'
+ * (base 13468 is used twice in transcription)
+ */
+ ranges.clear();
+ ranges.add(new int[] { 266, 13468 });
+ ranges.add(new int[] { 13468, 21555 });
+
+ // 13468 occupies two offsets in the range list
+ overlaps = MapList.findOverlapPositions(ranges, 13468, 13468);
+ assertEquals(1, overlaps.size());
+ assertArrayEquals(new int[] { 13202, 13203 }, overlaps.get(0));
+ overlaps = MapList.findOverlapPositions(ranges, 13469, 13470);
+ assertEquals(1, overlaps.size());
+ assertArrayEquals(new int[] { 13204, 13205 }, overlaps.get(0));
+
+ /*
+ * EMBL:J03321 https://www.ebi.ac.uk/ena/browser/api/embl/J03321
+ * circular dna: CDS at [7022-7502, 1-437]
+ * = 481 + 437 = 918 bases = 305 aa's + stop codon
+ */
+ ranges.clear();
+ ranges.add(new int[] { 7022, 7502 });
+ ranges.add(new int[] { 1, 437 });
+
+ overlaps = MapList.findOverlapPositions(ranges, 438, 7021);
+ assertTrue(overlaps.isEmpty());
+
+ // overlap first exon only:
+ overlaps = MapList.findOverlapPositions(ranges, 7000, 7100);
+ assertEquals(1, overlaps.size());
+ assertArrayEquals(new int[] { 0, 78 }, overlaps.get(0));
+
+ // overlap second exon only: offset to mapping includes first exon
+ overlaps = MapList.findOverlapPositions(ranges, 400, 500);
+ assertEquals(1, overlaps.size());
+ assertArrayEquals(new int[] { 880, 917 }, overlaps.get(0));
+
+ // overlap both exons: first exon overlap precedes second exon overlap
+ // offsets of overlaps are not contiguous
+ overlaps = MapList.findOverlapPositions(ranges, 200, 7500);
+ assertEquals(2, overlaps.size());
+ // first overlap is offsets of 7022-7500 in exon 1 (7022-7502):
+ assertArrayEquals(new int[] { 0, 478 }, overlaps.get(0));
+ // second overlap offsets is (first exon length = 481) + (200-437)
+ assertArrayEquals(new int[] { 680, 917 }, overlaps.get(1));
}
@Test(groups = { "Functional" })
public void testMapWords()
{
List<int[]> ranges = new ArrayList<>();
-
+
/*
* 1:1 (trivial) case
*/
- ranges.add(new int[] {2, 4});
- ranges.add(new int[] {6, 9});
- MapList.mapWords(ranges, 1, 1);
+ ranges.add(new int[] { 2, 4 });
+ ranges.add(new int[] { 6, 9 });
+ MapList.mapWords(ranges, 1, 1);
assertEquals(ranges.size(), 2);
- assertArrayEquals(new int[] {2, 4}, ranges.get(0));
- assertArrayEquals(new int[] {6, 9}, ranges.get(1));
-
+ assertArrayEquals(new int[] { 2, 4 }, ranges.get(0));
+ assertArrayEquals(new int[] { 6, 9 }, ranges.get(1));
+
/*
* 1:3 case (peptide to codon ranges)
*/
- MapList.mapWords(ranges, 1, 3);
+ MapList.mapWords(ranges, 1, 3);
assertEquals(ranges.size(), 2);
- assertArrayEquals(new int[] {6, 14}, ranges.get(0));
- assertArrayEquals(new int[] {18, 29}, ranges.get(1));
-
+ assertArrayEquals(new int[] { 6, 14 }, ranges.get(0));
+ assertArrayEquals(new int[] { 18, 29 }, ranges.get(1));
+
/*
* 3:1 case (codon or part codon to peptide)
*/
ranges.clear();
- ranges.add(new int[] {0, 5}); // 2 whole codons
- ranges.add(new int[] {7, 11}); // part + whole codon
- ranges.add(new int[] {15, 19}); // whole + part codon
- ranges.add(new int[] {23, 27}); // part + part codon
- ranges.add(new int[] {30, 30}); // first base of codon
- ranges.add(new int[] {31, 31}); // second base of codon
- ranges.add(new int[] {32, 32}); // third base of codon
- MapList.mapWords(ranges, 3, 1);
+ ranges.add(new int[] { 0, 5 }); // 2 whole codons
+ ranges.add(new int[] { 7, 11 }); // part + whole codon
+ ranges.add(new int[] { 15, 19 }); // whole + part codon
+ ranges.add(new int[] { 23, 27 }); // part + part codon
+ ranges.add(new int[] { 30, 30 }); // first base of codon
+ ranges.add(new int[] { 31, 31 }); // second base of codon
+ ranges.add(new int[] { 32, 32 }); // third base of codon
+ MapList.mapWords(ranges, 3, 1);
assertEquals(ranges.size(), 7);
- assertArrayEquals(new int[] {0, 1}, ranges.get(0));
- assertArrayEquals(new int[] {2, 3}, ranges.get(1));
- assertArrayEquals(new int[] {5, 6}, ranges.get(2));
- assertArrayEquals(new int[] {7, 9}, ranges.get(3));
- assertArrayEquals(new int[] {10, 10}, ranges.get(4));
- assertArrayEquals(new int[] {10, 10}, ranges.get(5));
- assertArrayEquals(new int[] {10, 10}, ranges.get(6));
+ assertArrayEquals(new int[] { 0, 1 }, ranges.get(0));
+ assertArrayEquals(new int[] { 2, 3 }, ranges.get(1));
+ assertArrayEquals(new int[] { 5, 6 }, ranges.get(2));
+ assertArrayEquals(new int[] { 7, 9 }, ranges.get(3));
+ assertArrayEquals(new int[] { 10, 10 }, ranges.get(4));
+ assertArrayEquals(new int[] { 10, 10 }, ranges.get(5));
+ assertArrayEquals(new int[] { 10, 10 }, ranges.get(6));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testLocateInFrom2()
+ {
+ /*
+ * codons at 11-16, 21-26, 31-36 mapped to peptide positions 1, 3-4, 6-8
+ */
+ MapList ml = new MapList(new int[] { 11, 16, 21, 26, 31, 36 },
+ new int[]
+ { 1, 1, 3, 4, 6, 8 }, 3, 1);
+ assertArrayEquals(new int[] { 11, 13 }, ml.locateInFrom2(1, 1));
+ assertArrayEquals(new int[] { 11, 16 }, ml.locateInFrom2(1, 3));
+ assertArrayEquals(new int[] { 11, 16, 21, 23 }, ml.locateInFrom2(1, 4));
+ assertArrayEquals(new int[] { 14, 16, 21, 23 }, ml.locateInFrom2(3, 4));
}
}