+
+ /**
+ * Tests for the method that maps the subset of a dna sequence that has CDS
+ * (or subtype) feature - case where the start codon is incomplete.
+ */
+ @Test(groups = "Functional")
+ public void testGetCdsRanges_fivePrimeIncomplete()
+ {
+ SequenceI dnaSeq = new Sequence("dna", "aaagGGCCCaaaTTTttt");
+ dnaSeq.createDatasetSequence();
+ SequenceI ds = dnaSeq.getDatasetSequence();
+
+ // CDS for dna 5-6 (incomplete codon), 7-9
+ SequenceFeature sf = new SequenceFeature("CDS", "", 5, 9, 0f, null);
+ sf.setPhase("2"); // skip 2 bases to start of next codon
+ ds.addSequenceFeature(sf);
+ // CDS for dna 13-15
+ sf = new SequenceFeature("CDS_predicted", "", 13, 15, 0f, null);
+ ds.addSequenceFeature(sf);
+
+ List<int[]> ranges = AlignmentUtils.findCdsPositions(dnaSeq);
+
+ /*
+ * check the mapping starts with the first complete codon
+ */
+ assertEquals(6, MappingUtils.getLength(ranges));
+ assertEquals(2, ranges.size());
+ assertEquals(7, ranges.get(0)[0]);
+ assertEquals(9, ranges.get(0)[1]);
+ assertEquals(13, ranges.get(1)[0]);
+ assertEquals(15, ranges.get(1)[1]);
+ }
+
+ /**
+ * Tests for the method that maps the subset of a dna sequence that has CDS
+ * (or subtype) feature.
+ */
+ @Test(groups = "Functional")
+ public void testGetCdsRanges()
+ {
+ SequenceI dnaSeq = new Sequence("dna", "aaaGGGcccAAATTTttt");
+ dnaSeq.createDatasetSequence();
+ SequenceI ds = dnaSeq.getDatasetSequence();
+
+ // CDS for dna 3-6
+ SequenceFeature sf = new SequenceFeature("CDS", "", 4, 6, 0f, null);
+ ds.addSequenceFeature(sf);
+ // exon feature should be ignored here
+ sf = new SequenceFeature("exon", "", 7, 9, 0f, null);
+ ds.addSequenceFeature(sf);
+ // CDS for dna 10-12
+ sf = new SequenceFeature("CDS_predicted", "", 10, 12, 0f, null);
+ ds.addSequenceFeature(sf);
+
+ List<int[]> ranges = AlignmentUtils.findCdsPositions(dnaSeq);
+ assertEquals(6, MappingUtils.getLength(ranges));
+ assertEquals(2, ranges.size());
+ assertEquals(4, ranges.get(0)[0]);
+ assertEquals(6, ranges.get(0)[1]);
+ assertEquals(10, ranges.get(1)[0]);
+ assertEquals(12, ranges.get(1)[1]);
+ }
+
+ /**
+ * Test the method that computes a map of codon variants for each protein
+ * position from "sequence_variant" features on dna
+ */
+ @Test(groups = "Functional")
+ public void testBuildDnaVariantsMap()
+ {
+ SequenceI dna = new Sequence("dna", "atgAAATTTGGGCCCtag");
+ MapList map = new MapList(new int[] { 1, 18 }, new int[] { 1, 5 }, 3, 1);
+
+ /*
+ * first with no variants on dna
+ */
+ LinkedHashMap<Integer, String[][]> variantsMap = AlignmentUtils
+ .buildDnaVariantsMap(dna, map);
+ assertTrue(variantsMap.isEmpty());
+
+ // single allele codon 1, on base 1
+ SequenceFeature sf = new SequenceFeature("sequence_variant", "", 1, 1,
+ 0f, null);
+ sf.setValue("alleles", "T");
+ dna.addSequenceFeature(sf);
+
+ // two alleles codon 2, on bases 2 and 3
+ sf = new SequenceFeature("sequence_variant", "", 5, 5, 0f, null);
+ sf.setValue("alleles", "T");
+ dna.addSequenceFeature(sf);
+ sf = new SequenceFeature("sequence_variant", "", 6, 6, 0f, null);
+ sf.setValue("alleles", "G");
+ dna.addSequenceFeature(sf);
+
+ // two alleles codon 3, both on base 2
+ sf = new SequenceFeature("sequence_variant", "", 8, 8, 0f, null);
+ sf.setValue("alleles", "C, G");
+ dna.addSequenceFeature(sf);
+
+ // no alleles on codon 4
+ // alleles on codon 5 on all 3 bases
+ sf = new SequenceFeature("sequence_variant", "", 13, 13, 0f, null);
+ sf.setValue("alleles", "C, G"); // (C duplicates given base value)
+ dna.addSequenceFeature(sf);
+ sf = new SequenceFeature("sequence_variant", "", 14, 14, 0f, null);
+ sf.setValue("alleles", "g, a"); // should force to upper-case
+ dna.addSequenceFeature(sf);
+ sf = new SequenceFeature("sequence_variant", "", 15, 15, 0f, null);
+ sf.setValue("alleles", "A, T");
+ dna.addSequenceFeature(sf);
+
+ variantsMap = AlignmentUtils.buildDnaVariantsMap(dna, map);
+ assertEquals(4, variantsMap.size());
+ assertTrue(Arrays.deepEquals(new String[][] { { "A", "T" }, { "T" },
+ { "G" } }, variantsMap.get(1)));
+ assertTrue(Arrays.deepEquals(new String[][] { { "A" }, { "A", "T" },
+ { "A", "G" } }, variantsMap.get(2)));
+ assertTrue(Arrays.deepEquals(new String[][] { { "T" },
+ { "T", "C", "G" }, { "T" } }, variantsMap.get(3)));
+ // duplicated bases are not removed here, handled in computePeptideVariants
+ assertTrue(Arrays.deepEquals(new String[][] { { "C", "C", "G" },
+ { "C", "G", "A" }, { "C", "A", "T" } }, variantsMap.get(5)));
+ }
+
+ /**
+ * Tests for the method that computes all peptide variants given codon
+ * variants
+ */
+ @Test(groups = "Functional")
+ public void testComputePeptideVariants()
+ {
+ String[][] codonVariants = new String[][] { { "A" }, { "G" }, { "T" } };
+
+ /*
+ * AGT codes for S - this is not included in the variants returned
+ */
+ List<String> variants = AlignmentUtils.computePeptideVariants(codonVariants, "S");
+ assertEquals("[]", variants.toString());
+
+ // S is reported if it differs from the current value (A):
+ variants = AlignmentUtils.computePeptideVariants(codonVariants, "A");
+ assertEquals("[S]", variants.toString());
+
+ /*
+ * synonymous variant is not reported
+ */
+ codonVariants = new String[][] { { "A" }, { "G" }, { "C", "T" } };
+ // AGC and AGT both code for S
+ variants = AlignmentUtils.computePeptideVariants(codonVariants, "s");
+ assertEquals("[]", variants.toString());
+
+ /*
+ * equivalent variants are only reported once
+ */
+ codonVariants = new String[][] { { "C" }, { "T" },
+ { "A", "C", "G", "T" } };
+ // CTA CTC CTG CTT all code for L
+ variants = AlignmentUtils.computePeptideVariants(codonVariants, "S");
+ assertEquals("[L]", variants.toString());
+
+ /*
+ * vary codons 1 and 2; variant products are sorted and non-redundant
+ */
+ codonVariants = new String[][] { { "a", "C" }, { "g", "T" }, { "A" } };
+ // aga ata cga cta code for R, I, R, L
+ variants = AlignmentUtils.computePeptideVariants(codonVariants, "S");
+ assertEquals("[I, L, R]", variants.toString());
+
+ /*
+ * vary codons 2 and 3
+ */
+ codonVariants = new String[][] { { "a" }, { "g", "T" }, { "A", "c" } };
+ // aga agc ata atc code for R, S, I, I
+ variants = AlignmentUtils.computePeptideVariants(codonVariants, "S");
+ assertEquals("[I, R]", variants.toString());
+
+ /*
+ * vary codons 1 and 3
+ */
+ codonVariants = new String[][] { { "a", "t" }, { "a" }, { "t", "g" } };
+ // aat aag tat tag code for N, K, Y, STOP - STOP sorted to end
+ variants = AlignmentUtils.computePeptideVariants(codonVariants, "S");
+ assertEquals("[K, N, Y, STOP]", variants.toString());
+
+ /*
+ * vary codons 1, 2 and 3
+ */
+ codonVariants = new String[][] { { "a", "t" }, { "G", "C" },
+ { "t", "g" } };
+ // agt agg act acg tgt tgg tct tcg code for S, R, T, T, C, W, S, S
+ variants = AlignmentUtils.computePeptideVariants(codonVariants, "S");
+ assertEquals("[C, R, T, W]", variants.toString());
+ }