JAL-2418 updated JABAWS server in what’s new
[jalview.git] / test / jalview / io / gff / Gff3HelperTest.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.io.gff;
22
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertNull;
25 import static org.testng.AssertJUnit.assertSame;
26 import static org.testng.AssertJUnit.assertTrue;
27 import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
28
29 import jalview.datamodel.AlignedCodonFrame;
30 import jalview.datamodel.Alignment;
31 import jalview.datamodel.AlignmentI;
32 import jalview.datamodel.Sequence;
33 import jalview.datamodel.SequenceDummy;
34 import jalview.datamodel.SequenceFeature;
35 import jalview.datamodel.SequenceI;
36 import jalview.gui.JvOptionPane;
37
38 import java.io.IOException;
39 import java.util.ArrayList;
40 import java.util.List;
41
42 import org.testng.annotations.BeforeClass;
43 import org.testng.annotations.Test;
44
45 public class Gff3HelperTest
46 {
47
48   @BeforeClass(alwaysRun = true)
49   public void setUpJvOptionPane()
50   {
51     JvOptionPane.setInteractiveMode(false);
52     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
53   }
54
55   /**
56    * Test processing one PASA GFF line giving a match from forward strand to
57    * forward strand
58    * 
59    * @throws IOException
60    */
61   @Test(groups = "Functional")
62   public void testProcessCdnaMatch_forwardToForward() throws IOException
63   {
64     GffHelperBase testee = new Gff3Helper();
65     List<SequenceI> newseqs = new ArrayList<SequenceI>();
66     String[] gff = "gi|68711\tblat-pasa\tcDNA_match\t12923\t13060\t98.55\t+\t.\tID=align_68;Target=gi|N37351 1 138 +"
67             .split("\\t");
68     SequenceI seq = new Sequence("gi|68711",
69             "GAATTCGTTCATGTAGGTTGATTTTTATT");
70     seq.createDatasetSequence();
71     AlignmentI align = new Alignment(new SequenceI[] {});
72
73     /*
74      * this should create a mapping from gi|68711/12923-13060
75      * to virtual sequence gi|N37351 (added to newseqs) positions 1-138
76      */
77     testee.processGff(seq, gff, align, newseqs, false);
78     assertEquals(1, newseqs.size());
79     assertTrue(newseqs.get(0) instanceof SequenceDummy);
80     assertEquals("gi|N37351", newseqs.get(0).getName());
81     assertEquals(1, align.getCodonFrames().size());
82     AlignedCodonFrame mapping = align.getCodonFrames().iterator().next();
83
84     /*
85      * 'dnaseqs' (map from) is here [gi|68711]
86      * 'aaseqs' (map to) is here [gi|N37351]
87      */
88     // TODO use more suitable naming in AlignedCodonFrame
89     assertEquals(1, mapping.getAaSeqs().length);
90     assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]);
91     assertEquals(1, mapping.getdnaSeqs().length);
92     assertSame(newseqs.get(0), mapping.getAaSeqs()[0]);
93     assertEquals(1, mapping.getdnaToProt().length);
94     assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size());
95     assertArrayEquals(new int[] { 12923, 13060 }, mapping.getdnaToProt()[0]
96             .getFromRanges().get(0));
97     assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
98     assertArrayEquals(new int[] { 1, 138 }, mapping.getdnaToProt()[0]
99             .getToRanges().get(0));
100   }
101
102   /**
103    * Test processing one PASA GFF line giving a match from forward strand to
104    * reverse strand
105    * 
106    * @throws IOException
107    */
108   @Test(groups = "Functional")
109   public void testProcessCdnaMatch_forwardToReverse() throws IOException
110   {
111     GffHelperBase testee = new Gff3Helper();
112     List<SequenceI> newseqs = new ArrayList<SequenceI>();
113     String[] gff = "gi|68711\tblat-pasa\tcDNA_match\t12923\t13060\t98.55\t+\t.\tID=align_68;Target=gi|N37351 1 138 -"
114             .split("\\t");
115     SequenceI seq = new Sequence("gi|68711",
116             "GAATTCGTTCATGTAGGTTGATTTTTATT");
117     seq.createDatasetSequence();
118     AlignmentI align = new Alignment(new SequenceI[] {});
119
120     /*
121      * this should create a mapping from gi|68711/12923-13060
122      * to virtual sequence gi|N37351 (added to newseqs) positions 138-1
123      */
124     testee.processGff(seq, gff, align, newseqs, false);
125     assertEquals(1, newseqs.size());
126     assertTrue(newseqs.get(0) instanceof SequenceDummy);
127     assertEquals("gi|N37351", newseqs.get(0).getName());
128     assertEquals(1, align.getCodonFrames().size());
129     AlignedCodonFrame mapping = align.getCodonFrames().iterator().next();
130
131     /*
132      * 'dnaseqs' (map from) is here [gi|68711]
133      * 'aaseqs' (map to) is here [gi|N37351]
134      */
135     // TODO use more suitable naming in AlignedCodonFrame
136     assertEquals(1, mapping.getAaSeqs().length);
137     assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]);
138     assertEquals(1, mapping.getdnaSeqs().length);
139     assertSame(newseqs.get(0), mapping.getAaSeqs()[0]);
140     assertEquals(1, mapping.getdnaToProt().length);
141     assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size());
142     assertArrayEquals(new int[] { 12923, 13060 }, mapping.getdnaToProt()[0]
143             .getFromRanges().get(0));
144     assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
145     assertArrayEquals(new int[] { 138, 1 }, mapping.getdnaToProt()[0]
146             .getToRanges().get(0));
147   }
148
149   /**
150    * Test processing one PASA GFF line giving a match from reverse complement
151    * strand to forward strand
152    * 
153    * @throws IOException
154    */
155   @Test(groups = "Functional")
156   public void testProcessCdnaMatch_reverseToForward() throws IOException
157   {
158     GffHelperBase testee = new Gff3Helper();
159     List<SequenceI> newseqs = new ArrayList<SequenceI>();
160     String[] gff = "gi|68711\tblat-pasa\tcDNA_match\t12923\t13060\t98.55\t-\t.\tID=align_68;Target=gi|N37351 1 138 +"
161             .split("\\t");
162     SequenceI seq = new Sequence("gi|68711",
163             "GAATTCGTTCATGTAGGTTGATTTTTATT");
164     seq.createDatasetSequence();
165     AlignmentI align = new Alignment(new SequenceI[] {});
166
167     /*
168      * (For now) we don't process reverse complement mappings; to do this
169      * would require (a) creating a virtual sequence placeholder for the
170      * reverse complement (b) resolving the sequence by its id from some
171      * source (GFF ##FASTA or other) (c) creating the reverse complement
172      * sequence (d) updating the mapping to be to the reverse complement
173      */
174     SequenceFeature sf = testee.processGff(seq, gff, align, newseqs, false);
175     assertNull(sf);
176     assertTrue(newseqs.isEmpty());
177   }
178
179   /**
180    * Test processing two PASA GFF lines representing a spliced mapping
181    * 
182    * @throws IOException
183    */
184   @Test(groups = "Functional")
185   public void testProcessCdnaMatch_spliced() throws IOException
186   {
187     GffHelperBase testee = new Gff3Helper();
188     List<SequenceI> newseqs = new ArrayList<SequenceI>();
189     SequenceI seq = new Sequence("gi|68711",
190             "GAATTCGTTCATGTAGGTTGATTTTTATT");
191     seq.createDatasetSequence();
192     AlignmentI align = new Alignment(new SequenceI[] {});
193
194     // mapping from gi|68711 12923-13060 to gi|N37351 1-138
195     String[] gff = "gi|68711\tblat-pasa\tcDNA_match\t12923\t13060\t98.55\t+\t.\tID=align_68;Target=gi|N37351 1 138 +"
196             .split("\\t");
197     testee.processGff(seq, gff, align, newseqs, false);
198     // mapping from gi|68711 13411-13550 to gi|N37351 139-278
199     gff = "gi|68711\tblat-pasa\tcDNA_match\t13411\t13550\t98.55\t+\t.\tID=align_68;Target=gi|N37351 139 278 +"
200             .split("\\t");
201     testee.processGff(seq, gff, align, newseqs, false);
202
203     assertEquals(1, newseqs.size());
204     assertTrue(newseqs.get(0) instanceof SequenceDummy);
205     assertEquals("gi|N37351", newseqs.get(0).getName());
206
207     // only 1 AlignedCodonFrame added to the alignment with both mappings!
208     // (this is important for 'align cdna to genome' to work correctly)
209     assertEquals(1, align.getCodonFrames().size());
210     AlignedCodonFrame mapping = align.getCodonFrames().get(0);
211
212     /*
213      * 'dnaseqs' (map from) is here [gi|68711]
214      * 'aaseqs' (map to) is here [gi|N37351]
215      */
216     // TODO use more suitable naming in AlignedCodonFrame
217     assertEquals(1, mapping.getAaSeqs().length);
218     assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]);
219     assertEquals(1, mapping.getdnaSeqs().length);
220     assertSame(newseqs.get(0), mapping.getAaSeqs()[0]);
221     assertEquals(1, mapping.getdnaToProt().length);
222     assertEquals(2, mapping.getdnaToProt()[0].getFromRanges().size());
223     // the two spliced dna ranges are combined in one MapList
224     assertArrayEquals(new int[] { 12923, 13060 }, mapping.getdnaToProt()[0]
225             .getFromRanges().get(0));
226     assertArrayEquals(new int[] { 13411, 13550 }, mapping.getdnaToProt()[0]
227             .getFromRanges().get(1));
228     assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
229     // the two cdna ranges are merged into one contiguous region
230     assertArrayEquals(new int[] { 1, 278 }, mapping.getdnaToProt()[0]
231             .getToRanges().get(0));
232   }
233
234 }