JAL-1805 modified test setup's so the are ran for groups which requires them
[jalview.git] / test / jalview / datamodel / AlignmentTest.java
1 package jalview.datamodel;
2
3 import static org.testng.AssertJUnit.assertEquals;
4 import static org.testng.AssertJUnit.assertFalse;
5 import static org.testng.AssertJUnit.assertTrue;
6
7 import jalview.io.AppletFormatAdapter;
8 import jalview.io.FormatAdapter;
9 import jalview.util.MapList;
10
11 import java.io.IOException;
12 import java.util.Iterator;
13
14 import org.testng.annotations.BeforeMethod;
15 import org.testng.annotations.Test;
16
17 /**
18  * Unit tests for Alignment datamodel.
19  * 
20  * @author gmcarstairs
21  *
22  */
23 public class AlignmentTest
24 {
25   // @formatter:off
26   private static final String TEST_DATA = 
27           "# STOCKHOLM 1.0\n" +
28           "#=GS D.melanogaster.1 AC AY119185.1/838-902\n" +
29           "#=GS D.melanogaster.2 AC AC092237.1/57223-57161\n" +
30           "#=GS D.melanogaster.3 AC AY060611.1/560-627\n" +
31           "D.melanogaster.1          G.AGCC.CU...AUGAUCGA\n" +
32           "#=GR D.melanogaster.1 SS  ................((((\n" +
33           "D.melanogaster.2          C.AUUCAACU.UAUGAGGAU\n" +
34           "#=GR D.melanogaster.2 SS  ................((((\n" +
35           "D.melanogaster.3          G.UGGCGCU..UAUGACGCA\n" +
36           "#=GR D.melanogaster.3 SS  (.(((...(....(((((((\n" +
37           "//";
38
39   private static final String AA_SEQS_1 = 
40           ">Seq1Name\n" +
41           "K-QY--L\n" +
42           ">Seq2Name\n" +
43           "-R-FP-W-\n";
44
45   private static final String CDNA_SEQS_1 = 
46           ">Seq1Name\n" +
47           "AC-GG--CUC-CAA-CT\n" +
48           ">Seq2Name\n" +
49           "-CG-TTA--ACG---AAGT\n";
50
51   private static final String CDNA_SEQS_2 = 
52           ">Seq1Name\n" +
53           "GCTCGUCGTACT\n" +
54           ">Seq2Name\n" +
55           "GGGTCAGGCAGT\n";
56   // @formatter:on
57
58   private AlignmentI al;
59
60   /**
61    * Helper method to load an alignment and ensure dataset sequences are set up.
62    * 
63    * @param data
64    * @param format
65    *          TODO
66    * @return
67    * @throws IOException
68    */
69   protected AlignmentI loadAlignment(final String data, String format)
70           throws IOException
71   {
72     AlignmentI a = new FormatAdapter().readFile(data,
73             AppletFormatAdapter.PASTE, format);
74     a.setDataset(null);
75     return a;
76   }
77
78   /*
79    * Read in Stockholm format test data including secondary structure
80    * annotations.
81    */
82  @BeforeMethod(alwaysRun = true)
83   public void setUp() throws IOException
84   {
85     al = loadAlignment(TEST_DATA, "STH");
86     int i = 0;
87     for (AlignmentAnnotation ann : al.getAlignmentAnnotation())
88     {
89       ann.setCalcId("CalcIdFor" + al.getSequenceAt(i).getName());
90       i++;
91     }
92   }
93
94   /**
95    * Test method that returns annotations that match on calcId.
96    */
97   @Test(groups ={ "Functional" })
98   public void testFindAnnotation_byCalcId()
99   {
100     Iterable<AlignmentAnnotation> anns = al
101             .findAnnotation("CalcIdForD.melanogaster.2");
102     Iterator<AlignmentAnnotation> iter = anns.iterator();
103     assertTrue(iter.hasNext());
104     AlignmentAnnotation ann = iter.next();
105     assertEquals("D.melanogaster.2", ann.sequenceRef.getName());
106     assertFalse(iter.hasNext());
107   }
108
109   @Test(groups ={ "Functional" })
110   public void testDeleteAllAnnotations_includingAutocalculated()
111   {
112     AlignmentAnnotation aa = new AlignmentAnnotation("Consensus",
113             "Consensus", 0.5);
114     aa.autoCalculated = true;
115     al.addAnnotation(aa);
116     AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
117     assertEquals("Wrong number of annotations before deleting", 4,
118             anns.length);
119     al.deleteAllAnnotations(true);
120     assertEquals("Not all deleted", 0, al.getAlignmentAnnotation().length);
121   }
122
123   @Test(groups ={ "Functional" })
124   public void testDeleteAllAnnotations_excludingAutocalculated()
125   {
126     AlignmentAnnotation aa = new AlignmentAnnotation("Consensus",
127             "Consensus", 0.5);
128     aa.autoCalculated = true;
129     al.addAnnotation(aa);
130     AlignmentAnnotation[] anns = al.getAlignmentAnnotation();
131     assertEquals("Wrong number of annotations before deleting", 4,
132             anns.length);
133     al.deleteAllAnnotations(false);
134     assertEquals("Not just one annotation left", 1,
135             al.getAlignmentAnnotation().length);
136   }
137
138   /**
139    * Tests for realigning as per a supplied alignment: Dna as Dna.
140    * 
141    * Note: AlignedCodonFrame's state variables are named for protein-to-cDNA
142    * mapping, but can be exploited for a general 'sequence-to-sequence' mapping
143    * as here.
144    * 
145    * @throws IOException
146    */
147   @Test(groups ={ "Functional" })
148   public void testAlignAs_dnaAsDna() throws IOException
149   {
150     // aligned cDNA:
151     AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA");
152     // unaligned cDNA:
153     AlignmentI al2 = loadAlignment(CDNA_SEQS_2, "FASTA");
154
155     /*
156      * Make mappings between sequences. The 'aligned cDNA' is playing the role
157      * of what would normally be protein here.
158      */
159     AlignedCodonFrame acf = new AlignedCodonFrame();
160     MapList ml = new MapList(new int[]
161     { 1, 12 }, new int[]
162     { 1, 12 }, 1, 1);
163     acf.addMap(al2.getSequenceAt(0), al1.getSequenceAt(0), ml);
164     acf.addMap(al2.getSequenceAt(1), al1.getSequenceAt(1), ml);
165     al1.addCodonFrame(acf);
166
167     ((Alignment) al2).alignAs(al1, false, true);
168     assertEquals("GC-TC--GUC-GTA-CT", al2.getSequenceAt(0)
169             .getSequenceAsString());
170     assertEquals("-GG-GTC--AGG---CAGT", al2.getSequenceAt(1)
171             .getSequenceAsString());
172   }
173
174   /**
175    * Aligning protein from cDNA.
176    * 
177    * @throws IOException
178    */
179   @Test(groups ={ "Functional" })
180   public void testAlignAs_proteinAsCdna() throws IOException
181   {
182     // see also AlignmentUtilsTests
183     AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA");
184     AlignmentI al2 = loadAlignment(AA_SEQS_1, "FASTA");
185     AlignedCodonFrame acf = new AlignedCodonFrame();
186     MapList ml = new MapList(new int[]
187     { 1, 12 }, new int[]
188     { 1, 4 }, 3, 1);
189     acf.addMap(al1.getSequenceAt(0), al2.getSequenceAt(0), ml);
190     acf.addMap(al1.getSequenceAt(1), al2.getSequenceAt(1), ml);
191     al2.addCodonFrame(acf);
192
193     ((Alignment) al2).alignAs(al1, false, true);
194     assertEquals("K-Q-Y-L-", al2.getSequenceAt(0).getSequenceAsString());
195     assertEquals("-R-F-P-W", al2.getSequenceAt(1).getSequenceAsString());
196   }
197
198   /**
199    * Test aligning cdna as per protein alignment.
200    * 
201    * @throws IOException
202    */
203   @Test(groups ={ "Functional" })
204   public void testAlignAs_cdnaAsProtein() throws IOException
205   {
206     /*
207      * Load alignments and add mappings for cDNA to protein
208      */
209     AlignmentI al1 = loadAlignment(CDNA_SEQS_1, "FASTA");
210     AlignmentI al2 = loadAlignment(AA_SEQS_1, "FASTA");
211     AlignedCodonFrame acf = new AlignedCodonFrame();
212     MapList ml = new MapList(new int[]
213     { 1, 12 }, new int[]
214     { 1, 4 }, 3, 1);
215     acf.addMap(al1.getSequenceAt(0), al2.getSequenceAt(0), ml);
216     acf.addMap(al1.getSequenceAt(1), al2.getSequenceAt(1), ml);
217     al2.addCodonFrame(acf);
218
219     /*
220      * Realign DNA; currently keeping existing gaps in introns only
221      */
222     ((Alignment) al1).alignAs(al2, false, true);
223     assertEquals("ACG---GCUCCA------ACT", al1.getSequenceAt(0)
224             .getSequenceAsString());
225     assertEquals("---CGT---TAACGA---AGT", al1.getSequenceAt(1)
226             .getSequenceAsString());
227   }
228
229   /**
230    * Test aligning dna as per protein alignment, for the case where there are
231    * introns (i.e. some dna sites have no mapping from a peptide).
232    * 
233    * @throws IOException
234    */
235   @Test(groups ={ "Functional" })
236   public void testAlignAs_dnaAsProtein_withIntrons() throws IOException
237   {
238     /*
239      * Load alignments and add mappings for cDNA to protein
240      */
241     String dna1 = "A-Aa-gG-GCC-cT-TT";
242     String dna2 = "c--CCGgg-TT--T-AA-A";
243     AlignmentI al1 = loadAlignment(">Seq1\n" + dna1 + "\n>Seq2\n" + dna2
244             + "\n", "FASTA");
245     AlignmentI al2 = loadAlignment(">Seq1\n-P--YK\n>Seq2\nG-T--F\n",
246             "FASTA");
247     AlignedCodonFrame acf = new AlignedCodonFrame();
248     // Seq1 has intron at dna positions 3,4,9 so splice is AAG GCC TTT
249     // Seq2 has intron at dna positions 1,5,6 so splice is CCG TTT AAA
250     MapList ml1 = new MapList(new int[]
251     { 1, 2, 5, 8, 10, 12 }, new int[]
252     { 1, 3 }, 3, 1);
253     acf.addMap(al1.getSequenceAt(0), al2.getSequenceAt(0), ml1);
254     MapList ml2 = new MapList(new int[]
255     { 2, 4, 7, 12 }, new int[]
256     { 1, 3 }, 3, 1);
257     acf.addMap(al1.getSequenceAt(1), al2.getSequenceAt(1), ml2);
258     al2.addCodonFrame(acf);
259
260     /*
261      * Align ignoring gaps in dna introns and exons
262      */
263     ((Alignment) al1).alignAs(al2, false, false);
264     assertEquals("---AAagG------GCCcTTT", al1.getSequenceAt(0)
265             .getSequenceAsString());
266     // note 1 gap in protein corresponds to 'gg-' in DNA (3 positions)
267     assertEquals("cCCGgg-TTT------AAA", al1.getSequenceAt(1)
268             .getSequenceAsString());
269
270     /*
271      * Reset and realign, preserving gaps in dna introns and exons
272      */
273     al1.getSequenceAt(0).setSequence(dna1);
274     al1.getSequenceAt(1).setSequence(dna2);
275     ((Alignment) al1).alignAs(al2, true, true);
276     // String dna1 = "A-Aa-gG-GCC-cT-TT";
277     // String dna2 = "c--CCGgg-TT--T-AA-A";
278     // assumption: we include 'the greater of' protein/dna gap lengths, not both
279     assertEquals("---A-Aa-gG------GCC-cT-TT", al1.getSequenceAt(0)
280             .getSequenceAsString());
281     assertEquals("c--CCGgg-TT--T------AA-A", al1.getSequenceAt(1)
282             .getSequenceAsString());
283   }
284 }