X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=test%2Fjalview%2Fanalysis%2FAlignmentUtilsTests.java;h=4aed7e71d2a62018ce35196175f4255612204d00;hb=37de9310bec3501cbc6381e0c3dcb282fcaad812;hp=9394385430c99ab0878c0d0638a2fa85d54477ff;hpb=f931c557266d95b3f4ab5b64bd108123c90e85ab;p=jalview.git diff --git a/test/jalview/analysis/AlignmentUtilsTests.java b/test/jalview/analysis/AlignmentUtilsTests.java index 9394385..4aed7e7 100644 --- a/test/jalview/analysis/AlignmentUtilsTests.java +++ b/test/jalview/analysis/AlignmentUtilsTests.java @@ -22,6 +22,7 @@ package jalview.analysis; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertSame; import static org.testng.AssertJUnit.assertTrue; @@ -438,7 +439,8 @@ public class AlignmentUtilsTests SequenceI alignFrom = new Sequence("Seq2", alignModel); alignFrom.createDatasetSequence(); AlignedCodonFrame acf = new AlignedCodonFrame(); - acf.addMap(alignMe.getDatasetSequence(), alignFrom.getDatasetSequence(), map); + acf.addMap(alignMe.getDatasetSequence(), + alignFrom.getDatasetSequence(), map); AlignmentUtils.alignSequenceAs(alignMe, alignFrom, acf, "---", '-', preserveMappedGaps, preserveUnmappedGaps); @@ -973,10 +975,17 @@ public class AlignmentUtilsTests @Test(groups = { "Functional" }) public void testMakeCdsAlignment() { + /* + * scenario: + * dna1 --> [4, 6] [10,12] --> pep1 + * dna2 --> [1, 3] [7, 9] [13,15] --> pep2 + */ SequenceI dna1 = new Sequence("dna1", "aaaGGGcccTTTaaa"); SequenceI dna2 = new Sequence("dna2", "GGGcccTTTaaaCCC"); SequenceI pep1 = new Sequence("pep1", "GF"); SequenceI pep2 = new Sequence("pep2", "GFP"); + pep1.addDBRef(new DBRefEntry("UNIPROT", "0", "pep1")); + pep2.addDBRef(new DBRefEntry("UNIPROT", "0", "pep2")); dna1.createDatasetSequence(); dna2.createDatasetSequence(); pep1.createDatasetSequence(); @@ -984,23 +993,60 @@ public class AlignmentUtilsTests AlignmentI dna = new Alignment(new SequenceI[] { dna1, dna2 }); dna.setDataset(null); - MapList map = new MapList(new int[] { 4, 6, 10, 12 }, - new int[] { 1, 2 }, 3, 1); + /* + * put a variant feature on dna2 base 8 + * - should transfer to cds2 base 5 + */ + dna2.addSequenceFeature(new SequenceFeature("variant", "hgmd", 8, 8, + 0f, null)); + + /* + * need a sourceDbRef if we are to construct dbrefs to the CDS + * sequence from the dna contig sequences + */ + DBRefEntry dbref = new DBRefEntry("ENSEMBL", "0", "dna1"); + dna1.getDatasetSequence().addDBRef(dbref); + org.testng.Assert.assertEquals(dbref, dna1.getPrimaryDBRefs().get(0)); + dbref = new DBRefEntry("ENSEMBL", "0", "dna2"); + dna2.getDatasetSequence().addDBRef(dbref); + org.testng.Assert.assertEquals(dbref, dna2.getPrimaryDBRefs().get(0)); + + /* + * CDS sequences are 'discovered' from dna-to-protein mappings on the alignment + * dataset (e.g. added from dbrefs by CrossRef.findXrefSequences) + */ + MapList mapfordna1 = new MapList(new int[] { 4, 6, 10, 12 }, new int[] { + 1, 2 }, 3, 1); AlignedCodonFrame acf = new AlignedCodonFrame(); - acf.addMap(dna1.getDatasetSequence(), pep1.getDatasetSequence(), map); + acf.addMap(dna1.getDatasetSequence(), pep1.getDatasetSequence(), + mapfordna1); dna.addCodonFrame(acf); - map = new MapList(new int[] { 1, 3, 7, 9, 13, 15 }, new int[] { 1, 3 }, - 3, 1); + MapList mapfordna2 = new MapList(new int[] { 1, 3, 7, 9, 13, 15 }, + new int[] { 1, 3 }, 3, 1); acf = new AlignedCodonFrame(); - acf.addMap(dna2.getDatasetSequence(), pep2.getDatasetSequence(), map); + acf.addMap(dna2.getDatasetSequence(), pep2.getDatasetSequence(), + mapfordna2); dna.addCodonFrame(acf); /* + * In this case, mappings originally came from matching Uniprot accessions - so need an xref on dna involving those regions. These are normally constructed from CDS annotation + */ + DBRefEntry dna1xref = new DBRefEntry("UNIPROT", "ENSEMBL", "pep1", + new Mapping(mapfordna1)); + dna1.getDatasetSequence().addDBRef(dna1xref); + DBRefEntry dna2xref = new DBRefEntry("UNIPROT", "ENSEMBL", "pep2", + new Mapping(mapfordna2)); + dna2.getDatasetSequence().addDBRef(dna2xref); + + /* * execute method under test: */ AlignmentI cds = AlignmentUtils.makeCdsAlignment(new SequenceI[] { dna1, dna2 }, dna.getDataset(), null); + /* + * verify cds sequences + */ assertEquals(2, cds.getSequences().size()); assertEquals("GGGTTT", cds.getSequenceAt(0).getSequenceAsString()); assertEquals("GGGTTTCCC", cds.getSequenceAt(1).getSequenceAsString()); @@ -1009,18 +1055,40 @@ public class AlignmentUtilsTests * verify shared, extended alignment dataset */ assertSame(dna.getDataset(), cds.getDataset()); - assertTrue(dna.getDataset().getSequences() - .contains(cds.getSequenceAt(0).getDatasetSequence())); - assertTrue(dna.getDataset().getSequences() - .contains(cds.getSequenceAt(1).getDatasetSequence())); + SequenceI cds1Dss = cds.getSequenceAt(0).getDatasetSequence(); + SequenceI cds2Dss = cds.getSequenceAt(1).getDatasetSequence(); + assertTrue(dna.getDataset().getSequences().contains(cds1Dss)); + assertTrue(dna.getDataset().getSequences().contains(cds2Dss)); + + /* + * verify CDS has a dbref with mapping to peptide + */ + assertNotNull(cds1Dss.getDBRefs()); + assertEquals(2, cds1Dss.getDBRefs().length); + dbref = cds1Dss.getDBRefs()[0]; + assertEquals(dna1xref.getSource(), dbref.getSource()); + // version is via ensembl's primary ref + assertEquals(dna1xref.getVersion(), dbref.getVersion()); + assertEquals(dna1xref.getAccessionId(), dbref.getAccessionId()); + assertNotNull(dbref.getMap()); + assertSame(pep1.getDatasetSequence(), dbref.getMap().getTo()); + MapList cdsMapping = new MapList(new int[] { 1, 6 }, + new int[] { 1, 2 }, 3, 1); + assertEquals(cdsMapping, dbref.getMap().getMap()); /* - * verify cds has dbref with mapping to protein and vice versa + * verify peptide has added a dbref with reverse mapping to CDS */ - DBRefEntry[] cdsDbrefs = cds.getSequenceAt(0).getDBRefs(); - // assertNotNull(cdsDbrefs); - // assertEquals(1, cdsDbrefs.length); - // assertNotNull(cdsDbrefs[0].getMap()); + assertNotNull(pep1.getDBRefs()); + // FIXME pep1.getDBRefs() is 1 - is that the correct behaviour ? + assertEquals(2, pep1.getDBRefs().length); + dbref = pep1.getDBRefs()[1]; + assertEquals("ENSEMBL", dbref.getSource()); + assertEquals("0", dbref.getVersion()); + assertEquals("CDS|dna1", dbref.getAccessionId()); + assertNotNull(dbref.getMap()); + assertSame(cds1Dss, dbref.getMap().getTo()); + assertEquals(cdsMapping.getInverse(), dbref.getMap().getMap()); /* * Verify mappings from CDS to peptide, cDNA to CDS, and cDNA to peptide @@ -1054,13 +1122,13 @@ public class AlignmentUtilsTests SearchResults sr = MappingUtils.buildSearchResults(pep1, 1, mappings); assertEquals(1, sr.getResults().size()); Match m = sr.getResults().get(0); - assertSame(cds.getSequenceAt(0).getDatasetSequence(), m.getSequence()); + assertSame(cds1Dss, m.getSequence()); assertEquals(1, m.getStart()); assertEquals(3, m.getEnd()); // map F to TTT sr = MappingUtils.buildSearchResults(pep1, 2, mappings); m = sr.getResults().get(0); - assertSame(cds.getSequenceAt(0).getDatasetSequence(), m.getSequence()); + assertSame(cds1Dss, m.getSequence()); assertEquals(4, m.getStart()); assertEquals(6, m.getEnd()); @@ -1078,21 +1146,31 @@ public class AlignmentUtilsTests sr = MappingUtils.buildSearchResults(pep2, 1, mappings); assertEquals(1, sr.getResults().size()); m = sr.getResults().get(0); - assertSame(cds.getSequenceAt(1).getDatasetSequence(), m.getSequence()); + assertSame(cds2Dss, m.getSequence()); assertEquals(1, m.getStart()); assertEquals(3, m.getEnd()); // map F to TTT sr = MappingUtils.buildSearchResults(pep2, 2, mappings); m = sr.getResults().get(0); - assertSame(cds.getSequenceAt(1).getDatasetSequence(), m.getSequence()); + assertSame(cds2Dss, m.getSequence()); assertEquals(4, m.getStart()); assertEquals(6, m.getEnd()); // map P to CCC sr = MappingUtils.buildSearchResults(pep2, 3, mappings); m = sr.getResults().get(0); - assertSame(cds.getSequenceAt(1).getDatasetSequence(), m.getSequence()); + assertSame(cds2Dss, m.getSequence()); assertEquals(7, m.getStart()); assertEquals(9, m.getEnd()); + + /* + * check cds2 acquired a variant feature in position 5 + */ + SequenceFeature[] sfs = cds2Dss.getSequenceFeatures(); + assertNotNull(sfs); + assertEquals(1, sfs.length); + assertEquals("variant", sfs[0].type); + assertEquals(5, sfs[0].begin); + assertEquals(5, sfs[0].end); } /** @@ -1175,7 +1253,7 @@ public class AlignmentUtilsTests SequenceI cdsSeq = cds.get(0); assertEquals("GGGTTT", cdsSeq.getSequenceAsString()); // assertEquals("dna1|A12345", cdsSeq.getName()); - assertEquals("dna1|pep1", cdsSeq.getName()); + assertEquals("CDS|dna1", cdsSeq.getName()); // assertEquals(1, cdsSeq.getDBRefs().length); // DBRefEntry cdsRef = cdsSeq.getDBRefs()[0]; // assertEquals("EMBLCDS", cdsRef.getSource()); @@ -1185,7 +1263,7 @@ public class AlignmentUtilsTests cdsSeq = cds.get(1); assertEquals("aaaccc", cdsSeq.getSequenceAsString()); // assertEquals("dna1|A12346", cdsSeq.getName()); - assertEquals("dna1|pep2", cdsSeq.getName()); + assertEquals("CDS|dna1", cdsSeq.getName()); // assertEquals(1, cdsSeq.getDBRefs().length); // cdsRef = cdsSeq.getDBRefs()[0]; // assertEquals("EMBLCDS", cdsRef.getSource()); @@ -1195,7 +1273,7 @@ public class AlignmentUtilsTests cdsSeq = cds.get(2); assertEquals("aaaTTT", cdsSeq.getSequenceAsString()); // assertEquals("dna1|A12347", cdsSeq.getName()); - assertEquals("dna1|pep3", cdsSeq.getName()); + assertEquals("CDS|dna1", cdsSeq.getName()); // assertEquals(1, cdsSeq.getDBRefs().length); // cdsRef = cdsSeq.getDBRefs()[0]; // assertEquals("EMBLCDS", cdsRef.getSource()); @@ -1232,8 +1310,7 @@ public class AlignmentUtilsTests .findMappingsForSequence(cds.get(0), dnaMappings); Mapping mapping = dnaToCds1Mappings.get(0).getMappings().get(0) .getMapping(); - assertSame(cds.get(0).getDatasetSequence(), mapping - .getTo()); + assertSame(cds.get(0).getDatasetSequence(), mapping.getTo()); assertEquals("G(1) in CDS should map to G(4) in DNA", 4, mapping .getMap().getToPosition(1)); @@ -1301,8 +1378,7 @@ public class AlignmentUtilsTests * @throws IOException */ @Test(groups = { "Functional" }) - public void testMapCdnaToProtein_forSubsequence() - throws IOException + public void testMapCdnaToProtein_forSubsequence() throws IOException { SequenceI prot = new Sequence("UNIPROT|V12345", "E-I--Q", 10, 12); prot.createDatasetSequence(); @@ -1323,7 +1399,7 @@ public class AlignmentUtilsTests @Test(groups = { "Functional" }) public void testAlignSequenceAs_mappedProteinProtein() { - + SequenceI alignMe = new Sequence("Match", "MGAASEV"); alignMe.createDatasetSequence(); SequenceI alignFrom = new Sequence("Query", "LQTGYMGAASEVMFSPTRR"); @@ -1334,7 +1410,7 @@ public class AlignmentUtilsTests MapList map = new MapList(new int[] { 6, 12 }, new int[] { 1, 7 }, 1, 1); acf.addMap(alignFrom.getDatasetSequence(), alignMe.getDatasetSequence(), map); - + AlignmentUtils.alignSequenceAs(alignMe, alignFrom, acf, "-", '-', true, true); assertEquals("-----MGAASEV-------", alignMe.getSequenceAsString()); @@ -1349,7 +1425,7 @@ public class AlignmentUtilsTests { // map first 3 codons to KPF; G is a trailing unmapped residue MapList map = new MapList(new int[] { 1, 9 }, new int[] { 1, 3 }, 3, 1); - + checkAlignSequenceAs("AAACCCTTT", "K-PFG", true, true, map, "AAA---CCCTTT---"); } @@ -1448,7 +1524,7 @@ public class AlignmentUtilsTests MapList map = new MapList(new int[] { 4, 6, 10, 12 }, new int[] { 1, 6 }, 1, 1); - + // [5, 11] maps to [2, 5] dna.addSequenceFeature(new SequenceFeature("type4", "desc4", 5, 11, 4f, null)); @@ -1458,12 +1534,12 @@ public class AlignmentUtilsTests // [12, 12] maps to [6, 6] dna.addSequenceFeature(new SequenceFeature("type8", "desc8", 12, 12, 8f, null)); - + // desc4 and desc8 are the 'omit these' varargs AlignmentUtils.transferFeatures(dna, cds, map, null, "type4", "type8"); SequenceFeature[] sfs = cds.getSequenceFeatures(); assertEquals(1, sfs.length); - + SequenceFeature sf = sfs[0]; assertEquals("type5", sf.getType()); assertEquals(1, sf.getBegin()); @@ -1478,10 +1554,10 @@ public class AlignmentUtilsTests { SequenceI dna = new Sequence("dna/20-34", "acgTAGcaaGCCcgt"); SequenceI cds = new Sequence("cds/10-15", "TAGGCC"); - + MapList map = new MapList(new int[] { 4, 6, 10, 12 }, new int[] { 1, 6 }, 1, 1); - + // [5, 11] maps to [2, 5] dna.addSequenceFeature(new SequenceFeature("type4", "desc4", 5, 11, 4f, null)); @@ -1491,12 +1567,12 @@ public class AlignmentUtilsTests // [12, 12] maps to [6, 6] dna.addSequenceFeature(new SequenceFeature("type8", "desc8", 12, 12, 8f, null)); - + // "type5" is the 'select this type' argument AlignmentUtils.transferFeatures(dna, cds, map, "type5"); SequenceFeature[] sfs = cds.getSequenceFeatures(); assertEquals(1, sfs.length); - + SequenceFeature sf = sfs[0]; assertEquals("type5", sf.getType()); assertEquals(1, sf.getBegin()); @@ -1525,26 +1601,25 @@ public class AlignmentUtilsTests AlignmentI dna = new Alignment(new SequenceI[] { dna1, dna2, dna3 }); dna.setDataset(null); - + MapList map = new MapList(new int[] { 4, 12, 16, 18 }, new int[] { 1, 4 }, 3, 1); AlignedCodonFrame acf = new AlignedCodonFrame(); acf.addMap(dna1.getDatasetSequence(), pep1.getDatasetSequence(), map); dna.addCodonFrame(acf); map = new MapList(new int[] { 4, 8, 12, 12, 16, 18 }, - new int[] { 1, 3 }, - 3, 1); + new int[] { 1, 3 }, 3, 1); acf = new AlignedCodonFrame(); acf.addMap(dna2.getDatasetSequence(), pep2.getDatasetSequence(), map); dna.addCodonFrame(acf); - + AlignmentI cds = AlignmentUtils.makeCdsAlignment(new SequenceI[] { dna1, dna2, dna3 }, dna.getDataset(), null); List cdsSeqs = cds.getSequences(); assertEquals(2, cdsSeqs.size()); assertEquals("GGGCCCTTTGGG", cdsSeqs.get(0).getSequenceAsString()); assertEquals("GGGCCTGGG", cdsSeqs.get(1).getSequenceAsString()); - + /* * verify shared, extended alignment dataset */ @@ -1560,7 +1635,7 @@ public class AlignmentUtilsTests */ List mappings = cds.getCodonFrames(); assertEquals(6, mappings.size()); - + /* * 2 mappings involve pep1 */ @@ -1579,8 +1654,7 @@ public class AlignmentUtilsTests pep1CdsMappings); assertEquals(1, sr.getResults().size()); Match m = sr.getResults().get(0); - assertEquals(cds.getSequenceAt(0).getDatasetSequence(), - m.getSequence()); + assertEquals(cds.getSequenceAt(0).getDatasetSequence(), m.getSequence()); assertEquals(1, m.getStart()); assertEquals(3, m.getEnd()); sr = MappingUtils.buildSearchResults(pep1, 2, pep1CdsMappings); @@ -1595,7 +1669,7 @@ public class AlignmentUtilsTests m = sr.getResults().get(0); assertEquals(10, m.getStart()); assertEquals(12, m.getEnd()); - + /* * Get mapping of pep2 to cds2 and verify it * maps GPG in pep2 to 1-3,4-6,7-9 in second CDS sequence @@ -1609,8 +1683,7 @@ public class AlignmentUtilsTests sr = MappingUtils.buildSearchResults(pep2, 1, pep2CdsMappings); assertEquals(1, sr.getResults().size()); m = sr.getResults().get(0); - assertEquals(cds.getSequenceAt(1).getDatasetSequence(), - m.getSequence()); + assertEquals(cds.getSequenceAt(1).getDatasetSequence(), m.getSequence()); assertEquals(1, m.getStart()); assertEquals(3, m.getEnd()); sr = MappingUtils.buildSearchResults(pep2, 2, pep2CdsMappings); @@ -1637,7 +1710,7 @@ public class AlignmentUtilsTests SequenceI dna3 = new Sequence("Seq3", "ccaaa-ttt-GGG-"); AlignmentI dna = new Alignment(new SequenceI[] { dna1, dna2, dna3 }); dna.setDataset(null); - + // prot1 has 'X' for incomplete start codon (not mapped) SequenceI prot1 = new Sequence("Seq1", "XKFG"); // X for incomplete start SequenceI prot2 = new Sequence("Seq2", "NG"); @@ -1645,7 +1718,7 @@ public class AlignmentUtilsTests AlignmentI protein = new Alignment(new SequenceI[] { prot1, prot2, prot3 }); protein.setDataset(null); - + // map dna1 [3, 11] to prot1 [2, 4] KFG MapList map = new MapList(new int[] { 3, 11 }, new int[] { 2, 4 }, 3, 1); AlignedCodonFrame acf = new AlignedCodonFrame(); @@ -1684,7 +1757,7 @@ public class AlignmentUtilsTests 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 @@ -1692,9 +1765,9 @@ public class AlignmentUtilsTests // CDS for dna 13-15 sf = new SequenceFeature("CDS_predicted", "", 13, 15, 0f, null); ds.addSequenceFeature(sf); - + List ranges = AlignmentUtils.findCdsPositions(dnaSeq); - + /* * check the mapping starts with the first complete codon */ @@ -1716,7 +1789,7 @@ public class AlignmentUtilsTests SequenceI dnaSeq = new Sequence("dna", "aaaGGGcccAAATTTttt"); dnaSeq.createDatasetSequence(); SequenceI ds = dnaSeq.getDatasetSequence(); - + // CDS for dna 10-12 SequenceFeature sf = new SequenceFeature("CDS_predicted", "", 10, 12, 0f, null); @@ -1729,7 +1802,7 @@ public class AlignmentUtilsTests // exon feature should be ignored here sf = new SequenceFeature("exon", "", 7, 9, 0f, null); ds.addSequenceFeature(sf); - + List ranges = AlignmentUtils.findCdsPositions(dnaSeq); /* * verify ranges { [4-6], [12-10] } @@ -1893,13 +1966,15 @@ public class AlignmentUtilsTests public void testComputePeptideVariants() { /* - * scenario: AAATTTCCC codes for KFP, with variants - * GAA -> E - * CAA -> Q - * AAG synonymous - * AAT -> N - * TTC synonymous - * CAC,CGC -> H,R (as one variant) + * scenario: AAATTTCCC codes for KFP + * variants: + * GAA -> E source: Ensembl + * CAA -> Q source: dbSNP + * AAG synonymous source: COSMIC + * AAT -> N source: Ensembl + * ...TTC synonymous source: dbSNP + * ......CAC,CGC -> H,R source: COSMIC + * (one variant with two alleles) */ SequenceI peptide = new Sequence("pep/10-12", "KFP"); @@ -1907,32 +1982,35 @@ public class AlignmentUtilsTests * two distinct variants for codon 1 position 1 * second one has clinical significance */ + String ensembl = "Ensembl"; + String dbSnp = "dbSNP"; + String cosmic = "COSMIC"; SequenceFeature sf1 = new SequenceFeature("sequence_variant", "", 1, 1, - 0f, null); + 0f, ensembl); sf1.setValue("alleles", "A,G"); // GAA -> E sf1.setValue("ID", "var1.125A>G"); SequenceFeature sf2 = new SequenceFeature("sequence_variant", "", 1, 1, - 0f, null); + 0f, dbSnp); sf2.setValue("alleles", "A,C"); // CAA -> Q sf2.setValue("ID", "var2"); sf2.setValue("clinical_significance", "Dodgy"); SequenceFeature sf3 = new SequenceFeature("sequence_variant", "", 3, 3, - 0f, null); + 0f, cosmic); sf3.setValue("alleles", "A,G"); // synonymous sf3.setValue("ID", "var3"); sf3.setValue("clinical_significance", "None"); SequenceFeature sf4 = new SequenceFeature("sequence_variant", "", 3, 3, - 0f, null); + 0f, ensembl); sf4.setValue("alleles", "A,T"); // AAT -> N sf4.setValue("ID", "sequence_variant:var4"); // prefix gets stripped off sf4.setValue("clinical_significance", "Benign"); SequenceFeature sf5 = new SequenceFeature("sequence_variant", "", 6, 6, - 0f, null); + 0f, dbSnp); sf5.setValue("alleles", "T,C"); // synonymous sf5.setValue("ID", "var5"); sf5.setValue("clinical_significance", "Bad"); SequenceFeature sf6 = new SequenceFeature("sequence_variant", "", 8, 8, - 0f, null); + 0f, cosmic); sf6.setValue("alleles", "C,A,G"); // CAC,CGC -> H,R sf6.setValue("ID", "var6"); sf6.setValue("clinical_significance", "Good"); @@ -1980,14 +2058,15 @@ public class AlignmentUtilsTests /* * verify added sequence features for - * var1 K -> E - * var2 K -> Q - * var4 K -> N - * var6 P -> H - * var6 P -> R + * var1 K -> E Ensembl + * var2 K -> Q dbSNP + * var4 K -> N Ensembl + * var6 P -> H COSMIC + * var6 P -> R COSMIC */ SequenceFeature[] sfs = peptide.getSequenceFeatures(); assertEquals(5, sfs.length); + SequenceFeature sf = sfs[0]; assertEquals(1, sf.getBegin()); assertEquals(1, sf.getEnd()); @@ -2000,7 +2079,8 @@ public class AlignmentUtilsTests assertEquals( "p.Lys1Glu var1.125A>G|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var1.125A%3EG", sf.links.get(0)); - assertEquals("Jalview", sf.getFeatureGroup()); + assertEquals(ensembl, sf.getFeatureGroup()); + sf = sfs[1]; assertEquals(1, sf.getBegin()); assertEquals(1, sf.getEnd()); @@ -2012,7 +2092,8 @@ public class AlignmentUtilsTests assertEquals( "p.Lys1Gln var2|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var2", sf.links.get(0)); - assertEquals("Jalview", sf.getFeatureGroup()); + assertEquals(dbSnp, sf.getFeatureGroup()); + sf = sfs[2]; assertEquals(1, sf.getBegin()); assertEquals(1, sf.getEnd()); @@ -2024,7 +2105,9 @@ public class AlignmentUtilsTests assertEquals( "p.Lys1Asn var4|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var4", sf.links.get(0)); - assertEquals("Jalview", sf.getFeatureGroup()); + assertEquals(ensembl, sf.getFeatureGroup()); + + // var5 generates two distinct protein variant features sf = sfs[3]; assertEquals(3, sf.getBegin()); assertEquals(3, sf.getEnd()); @@ -2036,8 +2119,8 @@ public class AlignmentUtilsTests assertEquals( "p.Pro3His var6|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var6", sf.links.get(0)); - // var5 generates two distinct protein variant features - assertEquals("Jalview", sf.getFeatureGroup()); + assertEquals(cosmic, sf.getFeatureGroup()); + sf = sfs[4]; assertEquals(3, sf.getBegin()); assertEquals(3, sf.getEnd()); @@ -2049,7 +2132,7 @@ public class AlignmentUtilsTests assertEquals( "p.Pro3Arg var6|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var6", sf.links.get(0)); - assertEquals("Jalview", sf.getFeatureGroup()); + assertEquals(cosmic, sf.getFeatureGroup()); } /** @@ -2064,7 +2147,7 @@ public class AlignmentUtilsTests SequenceI dnaSeq = new Sequence("dna", "aaaGGGcccAAATTTttt"); dnaSeq.createDatasetSequence(); SequenceI ds = dnaSeq.getDatasetSequence(); - + // CDS for dna 4-6 SequenceFeature sf = new SequenceFeature("CDS", "", 4, 6, 0f, null); sf.setStrand("-"); @@ -2076,7 +2159,7 @@ public class AlignmentUtilsTests sf = new SequenceFeature("CDS_predicted", "", 10, 12, 0f, null); sf.setStrand("-"); ds.addSequenceFeature(sf); - + List ranges = AlignmentUtils.findCdsPositions(dnaSeq); /* * verify ranges { [12-10], [6-4] } @@ -2102,7 +2185,7 @@ public class AlignmentUtilsTests SequenceI dnaSeq = new Sequence("dna", "aaagGGCCCaaaTTTttt"); dnaSeq.createDatasetSequence(); SequenceI ds = dnaSeq.getDatasetSequence(); - + // CDS for dna 5-9 SequenceFeature sf = new SequenceFeature("CDS", "", 5, 9, 0f, null); sf.setStrand("-"); @@ -2112,9 +2195,9 @@ public class AlignmentUtilsTests sf.setStrand("-"); sf.setPhase("2"); // skip 2 bases to start of next codon ds.addSequenceFeature(sf); - + List ranges = AlignmentUtils.findCdsPositions(dnaSeq); - + /* * check the mapping starts with the first complete codon * expect ranges [13, 13], [9, 5] @@ -2167,8 +2250,7 @@ public class AlignmentUtilsTests from.createDatasetSequence(); seq1.createDatasetSequence(); Mapping mapping = new Mapping(seq1, new MapList( - new int[] { 3, 6, 9, 10 }, - new int[] { 1, 6 }, 1, 1)); + new int[] { 3, 6, 9, 10 }, new int[] { 1, 6 }, 1, 1)); Map> map = new TreeMap>(); AlignmentUtils.addMappedPositions(seq1, from, mapping, map); @@ -2200,11 +2282,10 @@ public class AlignmentUtilsTests from.createDatasetSequence(); seq1.createDatasetSequence(); Mapping mapping = new Mapping(seq1, new MapList( - new int[] { 3, 6, 9, 10 }, - new int[] { 1, 6 }, 1, 1)); + new int[] { 3, 6, 9, 10 }, new int[] { 1, 6 }, 1, 1)); Map> map = new TreeMap>(); AlignmentUtils.addMappedPositions(seq1, from, mapping, map); - + /* * verify map has seq1 residues in columns 3,4,6,7,11,12 */ @@ -2242,7 +2323,7 @@ public class AlignmentUtilsTests dna.setDataset(null); AlignmentI emblPeptides = new Alignment(new SequenceI[] { pep3, pep4 }); emblPeptides.setDataset(null); - + AlignedCodonFrame acf = new AlignedCodonFrame(); MapList map = new MapList(new int[] { 4, 6, 10, 12 }, new int[] { 1, 2 }, 3, 1); @@ -2256,17 +2337,17 @@ public class AlignmentUtilsTests acf.addMap(dna2.getDatasetSequence(), pep2.getDatasetSequence(), map); acf.addMap(dna2.getDatasetSequence(), pep4.getDatasetSequence(), map); dna.addCodonFrame(acf); - + /* * execute method under test to find CDS for EMBL peptides only */ AlignmentI cds = AlignmentUtils.makeCdsAlignment(new SequenceI[] { - dna1, dna2 }, dna.getDataset(), emblPeptides); - + dna1, dna2 }, dna.getDataset(), emblPeptides.getSequencesArray()); + assertEquals(2, cds.getSequences().size()); assertEquals("GGGTTT", cds.getSequenceAt(0).getSequenceAsString()); assertEquals("GGGTTTCCC", cds.getSequenceAt(1).getSequenceAsString()); - + /* * verify shared, extended alignment dataset */ @@ -2275,7 +2356,7 @@ public class AlignmentUtilsTests .contains(cds.getSequenceAt(0).getDatasetSequence())); assertTrue(dna.getDataset().getSequences() .contains(cds.getSequenceAt(1).getDatasetSequence())); - + /* * Verify mappings from CDS to peptide, cDNA to CDS, and cDNA to peptide * the mappings are on the shared alignment dataset @@ -2285,7 +2366,7 @@ public class AlignmentUtilsTests * 6 mappings, 2*(DNA->CDS), 2*(DNA->Pep), 2*(CDS->Pep) */ assertEquals(6, cdsMappings.size()); - + /* * verify that mapping sets for dna and cds alignments are different * [not current behaviour - all mappings are on the alignment dataset] @@ -2294,7 +2375,7 @@ public class AlignmentUtilsTests // Assert.assertNotSame(dna.getCodonFrames(), cds.getCodonFrames()); // assertEquals(4, dna.getCodonFrames().size()); // assertEquals(4, cds.getCodonFrames().size()); - + /* * Two mappings involve pep3 (dna to pep3, cds to pep3) * Mapping from pep3 to GGGTTT in first new exon sequence @@ -2305,7 +2386,7 @@ public class AlignmentUtilsTests List mappings = MappingUtils .findMappingsForSequence(cds.getSequenceAt(0), pep3Mappings); assertEquals(1, mappings.size()); - + // map G to GGG SearchResults sr = MappingUtils.buildSearchResults(pep3, 1, mappings); assertEquals(1, sr.getResults().size()); @@ -2319,7 +2400,7 @@ public class AlignmentUtilsTests assertSame(cds.getSequenceAt(0).getDatasetSequence(), m.getSequence()); assertEquals(4, m.getStart()); assertEquals(6, m.getEnd()); - + /* * Two mappings involve pep4 (dna to pep4, cds to pep4) * Verify mapping from pep4 to GGGTTTCCC in second new exon sequence @@ -2350,4 +2431,85 @@ public class AlignmentUtilsTests assertEquals(7, m.getStart()); assertEquals(9, m.getEnd()); } + + /** + * Test the method that just copies aligned sequences, provided all sequences + * to be aligned share the aligned sequence's dataset + */ + @Test(groups = "Functional") + public void testAlignAsSameSequences() + { + SequenceI dna1 = new Sequence("dna1", "cccGGGTTTaaa"); + SequenceI dna2 = new Sequence("dna2", "CCCgggtttAAA"); + AlignmentI al1 = new Alignment(new SequenceI[] { dna1, dna2 }); + ((Alignment) al1).createDatasetAlignment(); + + SequenceI dna3 = new Sequence(dna1); + SequenceI dna4 = new Sequence(dna2); + assertSame(dna3.getDatasetSequence(), dna1.getDatasetSequence()); + assertSame(dna4.getDatasetSequence(), dna2.getDatasetSequence()); + String seq1 = "-cc-GG-GT-TT--aaa"; + dna3.setSequence(seq1); + String seq2 = "C--C-Cgg--gtt-tAA-A-"; + dna4.setSequence(seq2); + AlignmentI al2 = new Alignment(new SequenceI[] { dna3, dna4 }); + ((Alignment) al2).createDatasetAlignment(); + + assertTrue(AlignmentUtils.alignAsSameSequences(al1, al2)); + assertEquals(seq1, al1.getSequenceAt(0).getSequenceAsString()); + assertEquals(seq2, al1.getSequenceAt(1).getSequenceAsString()); + + /* + * add another sequence to 'aligned' - should still succeed, since + * unaligned sequences still share a dataset with aligned sequences + */ + SequenceI dna5 = new Sequence("dna5", "CCCgggtttAAA"); + dna5.createDatasetSequence(); + al2.addSequence(dna5); + assertTrue(AlignmentUtils.alignAsSameSequences(al1, al2)); + assertEquals(seq1, al1.getSequenceAt(0).getSequenceAsString()); + assertEquals(seq2, al1.getSequenceAt(1).getSequenceAsString()); + + /* + * add another sequence to 'unaligned' - should fail, since now not + * all unaligned sequences share a dataset with aligned sequences + */ + SequenceI dna6 = new Sequence("dna6", "CCCgggtttAAA"); + dna6.createDatasetSequence(); + al1.addSequence(dna6); + // JAL-2110 JBP Comment: what's the use case for this behaviour ? + assertFalse(AlignmentUtils.alignAsSameSequences(al1, al2)); + } + + @Test(groups = "Functional") + public void testAlignAsSameSequencesMultipleSubSeq() + { + SequenceI dna1 = new Sequence("dna1", "cccGGGTTTaaa"); + SequenceI dna2 = new Sequence("dna2", "CCCgggtttAAA"); + SequenceI as1 = dna1.deriveSequence(); + SequenceI as2 = dna1.deriveSequence().getSubSequence(3, 7); + SequenceI as3 = dna2.deriveSequence(); + as1.insertCharAt(6, 5, '-'); + String s_as1 = as1.getSequenceAsString(); + as2.insertCharAt(6, 5, '-'); + String s_as2 = as2.getSequenceAsString(); + as3.insertCharAt(6, 5, '-'); + String s_as3 = as3.getSequenceAsString(); + AlignmentI aligned = new Alignment(new SequenceI[] { as1, as2, as3 }); + + // why do we need to cast this still ? + ((Alignment) aligned).createDatasetAlignment(); + SequenceI uas1 = dna1.deriveSequence(); + SequenceI uas2 = dna1.deriveSequence().getSubSequence(3, 7); + SequenceI uas3 = dna2.deriveSequence(); + AlignmentI tobealigned = new Alignment(new SequenceI[] { uas1, uas2, + uas3 }); + ((Alignment) tobealigned).createDatasetAlignment(); + + assertTrue(AlignmentUtils.alignAsSameSequences(tobealigned, aligned)); + assertEquals(s_as1, uas1.getSequenceAsString()); + assertEquals(s_as2, uas2.getSequenceAsString()); + assertEquals(s_as3, uas3.getSequenceAsString()); + } + }