JAL-2110 random stuff
[jalview.git] / test / jalview / analysis / CrossRefsTest.java
1 package jalview.analysis;
2
3 import static org.testng.AssertJUnit.assertEquals;
4 import static org.testng.AssertJUnit.assertNotSame;
5 import static org.testng.AssertJUnit.assertNull;
6 import static org.testng.AssertJUnit.assertSame;
7 import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
8
9 import jalview.datamodel.Alignment;
10 import jalview.datamodel.AlignmentI;
11 import jalview.datamodel.DBRefEntry;
12 import jalview.datamodel.Mapping;
13 import jalview.datamodel.Sequence;
14 import jalview.datamodel.SequenceFeature;
15 import jalview.datamodel.SequenceI;
16 import jalview.util.MapList;
17 import jalview.ws.SequenceFetcher;
18 import jalview.ws.SequenceFetcherFactory;
19
20 import java.util.List;
21
22 import org.testng.annotations.Test;
23
24 public class CrossRefsTest
25 {
26
27   /**
28    * Test for finding 'product' sequences for the case where the selected
29    * sequence has a dbref with a mapping to a sequence
30    */
31   @Test(groups = { "Functional" })
32   public void testFindXrefSequences_fromDbRefMap()
33   {
34     /*
35      * two peptide sequences each with a DBRef and SequenceFeature
36      */
37     SequenceI pep1 = new Sequence("Q9ZTS2", "MALFQRSV");
38     pep1.addDBRef(new DBRefEntry("Pfam", "0", "PF00111"));
39     pep1.addSequenceFeature(new SequenceFeature("type", "desc", 12, 14, 1f,
40             "group"));
41     SequenceI pep2 = new Sequence("P30419", "MTRRSQIF");
42     pep2.addDBRef(new DBRefEntry("PDB", "0", "3JTK"));
43     pep2.addSequenceFeature(new SequenceFeature("type2", "desc2", 13, 15,
44             12f, "group2"));
45   
46     /*
47      * nucleotide sequence (to go in the alignment)
48      */
49     SequenceI dna1 = new Sequence("AF039662", "GGGGCAGCACAAGAAC");
50   
51     /*
52      * add DBRefEntry's to dna1 with mappings from dna to both peptides
53      */
54     MapList mapList = new MapList(new int[] { 1, 24 }, new int[] { 1, 3 },
55             3, 1);
56     Mapping map = new Mapping(pep1, mapList);
57     DBRefEntry dbRef1 = new DBRefEntry("UNIPROT", "0", "Q9ZTS2", map);
58     dna1.addDBRef(dbRef1);
59     mapList = new MapList(new int[] { 1, 24 }, new int[] { 1, 3 }, 3, 1);
60     map = new Mapping(pep2, mapList);
61     DBRefEntry dbRef2 = new DBRefEntry("UNIPROT", "0", "P30419", map);
62     dna1.addDBRef(dbRef2);
63   
64     /*
65      * find UNIPROT xrefs for nucleotide sequence - it should pick up 
66      * mapped sequences
67      */
68     AlignmentI al = new Alignment(new SequenceI[] { dna1 });
69     AlignmentI xrefs = CrossRefs.findXrefSequences(
70             new SequenceI[] { dna1 },
71             true, "UNIPROT", al);
72     assertEquals(2, xrefs.getHeight());
73   
74     /*
75      * cross-refs alignment holds copies of the mapped sequences
76      * including copies of their dbrefs and features
77      */
78     checkCopySequence(pep1, xrefs.getSequenceAt(0));
79     checkCopySequence(pep2, xrefs.getSequenceAt(1));
80   }
81
82   /**
83    * Test for finding 'product' sequences for the case where only an indirect
84    * xref is found - not on the peptide sequence but on a nucleotide sequence in
85    * the alignment which which it shares a protein dbref
86    */
87   @Test(groups = { "Functional" })
88   public void testFindXrefSequences_indirectDbrefToNucleotide()
89   {
90     /*
91      * Alignment setup:
92      *   - peptide    dbref  UNIPROT|Q9ZTS2
93      *   - nucleotide dbref  EMBL|AF039662, UNIPROT|Q9ZTS2
94      */
95     SequenceI uniprotSeq = new Sequence("Q9ZTS2", "MASVSATMISTS");
96     uniprotSeq.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
97     SequenceI emblSeq = new Sequence("AF039662", "GGGGCAGCACAAGAAC");
98     emblSeq.addDBRef(new DBRefEntry("EMBL", "0", "AF039662"));
99     emblSeq.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
100   
101     /*
102      * Find EMBL xrefs for peptide 
103      * - it has no EMBL dbref of its own
104      * - but nucleotide with matching peptide dbref does, so is returned
105      */
106     AlignmentI al = new Alignment(new SequenceI[] { emblSeq, uniprotSeq });
107     AlignmentI xrefs = CrossRefs.findXrefSequences(
108             new SequenceI[] { uniprotSeq }, false, "EMBL", al);
109     assertEquals(1, xrefs.getHeight());
110     assertSame(emblSeq, xrefs.getSequenceAt(0));
111   }
112
113   /**
114    * Test for finding 'product' sequences for the case where only an indirect
115    * xref is found - not on the nucleotide sequence but on a peptide sequence in
116    * the alignment which which it shares a nucleotide dbref
117    */
118   @Test(groups = { "Functional" })
119   public void testFindXrefSequences_indirectDbrefToProtein()
120   {
121     /*
122      * Alignment setup:
123      *   - nucleotide dbref  EMBL|AF039662
124      *   - peptide    dbrefs EMBL|AF039662, UNIPROT|Q9ZTS2
125      */
126     SequenceI emblSeq = new Sequence("AF039662", "GGGGCAGCACAAGAAC");
127     emblSeq.addDBRef(new DBRefEntry("EMBL", "0", "AF039662"));
128     SequenceI uniprotSeq = new Sequence("Q9ZTS2", "MASVSATMISTS");
129     uniprotSeq.addDBRef(new DBRefEntry("EMBL", "0", "AF039662"));
130     uniprotSeq.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
131   
132     /*
133      * Find UNIPROT xrefs for nucleotide 
134      * - it has no UNIPROT dbref of its own
135      * - but peptide with matching nucleotide dbref does, so is returned
136      */
137     AlignmentI al = new Alignment(new SequenceI[] { emblSeq, uniprotSeq });
138     AlignmentI xrefs = CrossRefs.findXrefSequences(
139             new SequenceI[] { emblSeq }, true, "UNIPROT", al);
140     assertEquals(1, xrefs.getHeight());
141     assertSame(uniprotSeq, xrefs.getSequenceAt(0));
142   }
143
144   /**
145    * Test for finding 'product' sequences for the case where the selected
146    * sequence has no dbref to the desired source, and there are no indirect
147    * references via another sequence in the alignment
148    */
149   @Test(groups = { "Functional" })
150   public void testFindXrefSequences_noDbrefs()
151   {
152     /*
153      * two nucleotide sequences, one with UNIPROT dbref
154      */
155     SequenceI dna1 = new Sequence("AF039662", "GGGGCAGCACAAGAAC");
156     dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
157     SequenceI dna2 = new Sequence("AJ307031", "AAACCCTTT");
158   
159     /*
160      * find UNIPROT xrefs for peptide sequence - it has no direct
161      * dbrefs, and the other sequence (which has a UNIPROT dbref) is not 
162      * equatable to it, so no results found
163      */
164     AlignmentI al = new Alignment(new SequenceI[] { dna1, dna2 });
165     AlignmentI xrefs = CrossRefs.findXrefSequences(
166             new SequenceI[] { dna2 },
167             true, "UNIPROT", al);
168     assertNull(xrefs);
169   }
170
171   /**
172    * Test for finding 'product' sequences for the case where the selected
173    * sequence has a dbref with no mapping, triggering a fetch from database
174    */
175   @Test(groups = { "Functional" })
176   public void testFindXrefSequences_withFetch()
177   {
178     SequenceI dna1 = new Sequence("AF039662", "GGGGCAGCACAAGAAC");
179     dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
180     dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "P30419"));
181     dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "P00314"));
182     final SequenceI pep1 = new Sequence("Q9ZTS2", "MYQLIRSSW");
183     final SequenceI pep2 = new Sequence("P00314", "MRKLLAASG");
184   
185     SequenceFetcher mockFetcher = new SequenceFetcher()
186     {
187   
188       @Override
189       public boolean isFetchable(String source)
190       {
191         return true;
192       }
193   
194       @Override
195       public SequenceI[] getSequences(List<DBRefEntry> refs, boolean dna)
196       {
197         return new SequenceI[] { pep1, pep2 };
198       }
199     };
200     SequenceFetcherFactory.setSequenceFetcher(mockFetcher);
201   
202     /*
203      * find UNIPROT xrefs for nucleotide sequence
204      */
205     AlignmentI al = new Alignment(new SequenceI[] { dna1 });
206     AlignmentI xrefs = CrossRefs.findXrefSequences(
207             new SequenceI[] { dna1 },
208             true, "UNIPROT", al);
209     assertEquals(2, xrefs.getHeight());
210     assertSame(pep1, xrefs.getSequenceAt(0));
211     assertSame(pep2, xrefs.getSequenceAt(1));
212   }
213
214   /**
215    * Helper method to assert seq1 looks like a copy of seq2
216    * 
217    * @param seq1
218    * @param seq2
219    */
220   private void checkCopySequence(SequenceI seq1, SequenceI seq2)
221   {
222     assertNotSame(seq1, seq2);
223     assertEquals(seq1.getName(), seq2.getName());
224     assertEquals(seq1.getStart(), seq2.getStart());
225     assertEquals(seq1.getEnd(), seq2.getEnd());
226     assertEquals(seq1.getSequenceAsString(), seq2.getSequenceAsString());
227   
228     /*
229      * compare dbrefs
230      */
231     assertArrayEquals(seq1.getDBRefs(), seq2.getDBRefs());
232     // check one to verify a copy, not the same object
233     if (seq1.getDBRefs().length > 0)
234     {
235       assertNotSame(seq1.getDBRefs()[0], seq2.getDBRefs()[0]);
236     }
237   
238     /*
239      * compare features
240      */
241     assertArrayEquals(seq1.getSequenceFeatures(),
242             seq2.getSequenceFeatures());
243     if (seq1.getSequenceFeatures().length > 0)
244     {
245       assertNotSame(seq1.getSequenceFeatures()[0],
246               seq2.getSequenceFeatures()[0]);
247     }
248   }
249
250   /**
251    * Test for finding 'product' sequences for the case where the selected
252    * sequence has two dbrefs with no mapping, triggering a fetch from database.
253    * 
254    * @see http://issues.jalview.org/browse/JAL-2029
255    */
256   @Test(groups = { "Functional" })
257   public void testFindXrefSequences_withFetchMultipleRefs()
258   {
259     /*
260      * EMBL|X07547 has a 
261      */
262     SequenceI dna1 = new Sequence("X07547", "GGGGCAGCACAAGAAC");
263     dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "B0BCM4"));
264     dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "P0CE20"));
265     final SequenceI pep1 = new Sequence("B0BCM4", "MGKGIL");
266     final SequenceI pep2 = new Sequence("P0CE20", "MGKGIL");
267   
268     SequenceFetcher mockFetcher = new SequenceFetcher()
269     {
270       int call = 0;
271
272       @Override
273       public boolean isFetchable(String source)
274       {
275         return true;
276       }
277       @Override
278       public SequenceI[] getSequences(List<DBRefEntry> refs, boolean dna)
279       {
280         // pending Mockito with its thenReturn(pep1).thenReturn(pep2) syntax!
281         return new SequenceI[] { call++ == 0 ? pep1 : pep2 };
282       }
283     };
284     SequenceFetcherFactory.setSequenceFetcher(mockFetcher);
285   
286     /*
287      * find UNIPROT xrefs for nucleotide sequence
288      */
289     AlignmentI al = new Alignment(new SequenceI[] { dna1 });
290     AlignmentI xrefs = CrossRefs.findXrefSequences(
291             new SequenceI[] { dna1 },
292             true, "UNIPROT", al);
293     assertEquals(2, xrefs.getHeight());
294     assertSame(pep1, xrefs.getSequenceAt(0));
295     assertSame(pep2, xrefs.getSequenceAt(1));
296   }
297
298 }