package jalview.analysis; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotSame; import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertSame; import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentI; import jalview.datamodel.DBRefEntry; import jalview.datamodel.Mapping; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.util.MapList; import jalview.ws.SequenceFetcher; import jalview.ws.SequenceFetcherFactory; import java.util.List; import org.testng.annotations.Test; public class CrossRefsTest { /** * Test for finding 'product' sequences for the case where the selected * sequence has a dbref with a mapping to a sequence */ @Test(groups = { "Functional" }) public void testFindXrefSequences_fromDbRefMap() { /* * two peptide sequences each with a DBRef and SequenceFeature */ SequenceI pep1 = new Sequence("Q9ZTS2", "MALFQRSV"); pep1.addDBRef(new DBRefEntry("Pfam", "0", "PF00111")); pep1.addSequenceFeature(new SequenceFeature("type", "desc", 12, 14, 1f, "group")); SequenceI pep2 = new Sequence("P30419", "MTRRSQIF"); pep2.addDBRef(new DBRefEntry("PDB", "0", "3JTK")); pep2.addSequenceFeature(new SequenceFeature("type2", "desc2", 13, 15, 12f, "group2")); /* * nucleotide sequence (to go in the alignment) */ SequenceI dna1 = new Sequence("AF039662", "GGGGCAGCACAAGAAC"); /* * add DBRefEntry's to dna1 with mappings from dna to both peptides */ MapList mapList = new MapList(new int[] { 1, 24 }, new int[] { 1, 3 }, 3, 1); Mapping map = new Mapping(pep1, mapList); DBRefEntry dbRef1 = new DBRefEntry("UNIPROT", "0", "Q9ZTS2", map); dna1.addDBRef(dbRef1); mapList = new MapList(new int[] { 1, 24 }, new int[] { 1, 3 }, 3, 1); map = new Mapping(pep2, mapList); DBRefEntry dbRef2 = new DBRefEntry("UNIPROT", "0", "P30419", map); dna1.addDBRef(dbRef2); /* * find UNIPROT xrefs for nucleotide sequence - it should pick up * mapped sequences */ AlignmentI al = new Alignment(new SequenceI[] { dna1 }); AlignmentI xrefs = CrossRefs.findXrefSequences( new SequenceI[] { dna1 }, true, "UNIPROT", al); assertEquals(2, xrefs.getHeight()); /* * cross-refs alignment holds copies of the mapped sequences * including copies of their dbrefs and features */ checkCopySequence(pep1, xrefs.getSequenceAt(0)); checkCopySequence(pep2, xrefs.getSequenceAt(1)); } /** * Test for finding 'product' sequences for the case where only an indirect * xref is found - not on the peptide sequence but on a nucleotide sequence in * the alignment which which it shares a protein dbref */ @Test(groups = { "Functional" }) public void testFindXrefSequences_indirectDbrefToNucleotide() { /* * Alignment setup: * - peptide dbref UNIPROT|Q9ZTS2 * - nucleotide dbref EMBL|AF039662, UNIPROT|Q9ZTS2 */ SequenceI uniprotSeq = new Sequence("Q9ZTS2", "MASVSATMISTS"); uniprotSeq.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2")); SequenceI emblSeq = new Sequence("AF039662", "GGGGCAGCACAAGAAC"); emblSeq.addDBRef(new DBRefEntry("EMBL", "0", "AF039662")); emblSeq.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2")); /* * Find EMBL xrefs for peptide * - it has no EMBL dbref of its own * - but nucleotide with matching peptide dbref does, so is returned */ AlignmentI al = new Alignment(new SequenceI[] { emblSeq, uniprotSeq }); AlignmentI xrefs = CrossRefs.findXrefSequences( new SequenceI[] { uniprotSeq }, false, "EMBL", al); assertEquals(1, xrefs.getHeight()); assertSame(emblSeq, xrefs.getSequenceAt(0)); } /** * Test for finding 'product' sequences for the case where only an indirect * xref is found - not on the nucleotide sequence but on a peptide sequence in * the alignment which which it shares a nucleotide dbref */ @Test(groups = { "Functional" }) public void testFindXrefSequences_indirectDbrefToProtein() { /* * Alignment setup: * - nucleotide dbref EMBL|AF039662 * - peptide dbrefs EMBL|AF039662, UNIPROT|Q9ZTS2 */ SequenceI emblSeq = new Sequence("AF039662", "GGGGCAGCACAAGAAC"); emblSeq.addDBRef(new DBRefEntry("EMBL", "0", "AF039662")); SequenceI uniprotSeq = new Sequence("Q9ZTS2", "MASVSATMISTS"); uniprotSeq.addDBRef(new DBRefEntry("EMBL", "0", "AF039662")); uniprotSeq.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2")); /* * Find UNIPROT xrefs for nucleotide * - it has no UNIPROT dbref of its own * - but peptide with matching nucleotide dbref does, so is returned */ AlignmentI al = new Alignment(new SequenceI[] { emblSeq, uniprotSeq }); AlignmentI xrefs = CrossRefs.findXrefSequences( new SequenceI[] { emblSeq }, true, "UNIPROT", al); assertEquals(1, xrefs.getHeight()); assertSame(uniprotSeq, xrefs.getSequenceAt(0)); } /** * Test for finding 'product' sequences for the case where the selected * sequence has no dbref to the desired source, and there are no indirect * references via another sequence in the alignment */ @Test(groups = { "Functional" }) public void testFindXrefSequences_noDbrefs() { /* * two nucleotide sequences, one with UNIPROT dbref */ SequenceI dna1 = new Sequence("AF039662", "GGGGCAGCACAAGAAC"); dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2")); SequenceI dna2 = new Sequence("AJ307031", "AAACCCTTT"); /* * find UNIPROT xrefs for peptide sequence - it has no direct * dbrefs, and the other sequence (which has a UNIPROT dbref) is not * equatable to it, so no results found */ AlignmentI al = new Alignment(new SequenceI[] { dna1, dna2 }); AlignmentI xrefs = CrossRefs.findXrefSequences( new SequenceI[] { dna2 }, true, "UNIPROT", al); assertNull(xrefs); } /** * Test for finding 'product' sequences for the case where the selected * sequence has a dbref with no mapping, triggering a fetch from database */ @Test(groups = { "Functional" }) public void testFindXrefSequences_withFetch() { SequenceI dna1 = new Sequence("AF039662", "GGGGCAGCACAAGAAC"); dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2")); dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "P30419")); dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "P00314")); final SequenceI pep1 = new Sequence("Q9ZTS2", "MYQLIRSSW"); final SequenceI pep2 = new Sequence("P00314", "MRKLLAASG"); SequenceFetcher mockFetcher = new SequenceFetcher() { @Override public boolean isFetchable(String source) { return true; } @Override public SequenceI[] getSequences(List refs, boolean dna) { return new SequenceI[] { pep1, pep2 }; } }; SequenceFetcherFactory.setSequenceFetcher(mockFetcher); /* * find UNIPROT xrefs for nucleotide sequence */ AlignmentI al = new Alignment(new SequenceI[] { dna1 }); AlignmentI xrefs = CrossRefs.findXrefSequences( new SequenceI[] { dna1 }, true, "UNIPROT", al); assertEquals(2, xrefs.getHeight()); assertSame(pep1, xrefs.getSequenceAt(0)); assertSame(pep2, xrefs.getSequenceAt(1)); } /** * Helper method to assert seq1 looks like a copy of seq2 * * @param seq1 * @param seq2 */ private void checkCopySequence(SequenceI seq1, SequenceI seq2) { assertNotSame(seq1, seq2); assertEquals(seq1.getName(), seq2.getName()); assertEquals(seq1.getStart(), seq2.getStart()); assertEquals(seq1.getEnd(), seq2.getEnd()); assertEquals(seq1.getSequenceAsString(), seq2.getSequenceAsString()); /* * compare dbrefs */ assertArrayEquals(seq1.getDBRefs(), seq2.getDBRefs()); // check one to verify a copy, not the same object if (seq1.getDBRefs().length > 0) { assertNotSame(seq1.getDBRefs()[0], seq2.getDBRefs()[0]); } /* * compare features */ assertArrayEquals(seq1.getSequenceFeatures(), seq2.getSequenceFeatures()); if (seq1.getSequenceFeatures().length > 0) { assertNotSame(seq1.getSequenceFeatures()[0], seq2.getSequenceFeatures()[0]); } } /** * Test for finding 'product' sequences for the case where the selected * sequence has two dbrefs with no mapping, triggering a fetch from database. * * @see http://issues.jalview.org/browse/JAL-2029 */ @Test(groups = { "Functional" }) public void testFindXrefSequences_withFetchMultipleRefs() { /* * EMBL|X07547 has a */ SequenceI dna1 = new Sequence("X07547", "GGGGCAGCACAAGAAC"); dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "B0BCM4")); dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "P0CE20")); final SequenceI pep1 = new Sequence("B0BCM4", "MGKGIL"); final SequenceI pep2 = new Sequence("P0CE20", "MGKGIL"); SequenceFetcher mockFetcher = new SequenceFetcher() { int call = 0; @Override public boolean isFetchable(String source) { return true; } @Override public SequenceI[] getSequences(List refs, boolean dna) { // pending Mockito with its thenReturn(pep1).thenReturn(pep2) syntax! return new SequenceI[] { call++ == 0 ? pep1 : pep2 }; } }; SequenceFetcherFactory.setSequenceFetcher(mockFetcher); /* * find UNIPROT xrefs for nucleotide sequence */ AlignmentI al = new Alignment(new SequenceI[] { dna1 }); AlignmentI xrefs = CrossRefs.findXrefSequences( new SequenceI[] { dna1 }, true, "UNIPROT", al); assertEquals(2, xrefs.getHeight()); assertSame(pep1, xrefs.getSequenceAt(0)); assertSame(pep2, xrefs.getSequenceAt(1)); } }