JAL-98 minor fixes to / tests for annotation derivation
[jalview.git] / test / jalview / analysis / AAFrequencyTest.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.analysis;
22
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertNull;
25
26 import jalview.datamodel.AlignmentAnnotation;
27 import jalview.datamodel.Annotation;
28 import jalview.datamodel.Sequence;
29 import jalview.datamodel.SequenceI;
30
31 import org.testng.annotations.Test;
32
33 public class AAFrequencyTest
34 {
35   @Test(groups = { "Functional" })
36   public void testCalculate_noProfile()
37   {
38     SequenceI seq1 = new Sequence("Seq1", "CAG-T");
39     SequenceI seq2 = new Sequence("Seq2", "CAC-T");
40     SequenceI seq3 = new Sequence("Seq3", "C---G");
41     SequenceI seq4 = new Sequence("Seq4", "CA--t");
42     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
43     Profile[] result = new Profile[seq1.getLength()];
44
45     AAFrequency.calculate(seqs, 0, seq1.getLength(), result, false);
46
47     // col 0 is 100% C
48     Profile col = result[0];
49     assertEquals(100f, col.getPercentageIdentity(false));
50     assertEquals(100f, col.getPercentageIdentity(true));
51     assertEquals(4, col.getMaxCount());
52     assertEquals("C", col.getModalResidue());
53     assertNull(col.getCounts());
54
55     // col 1 is 75% A
56     col = result[1];
57     assertEquals(75f, col.getPercentageIdentity(false));
58     assertEquals(100f, col.getPercentageIdentity(true));
59     assertEquals(3, col.getMaxCount());
60     assertEquals("A", col.getModalResidue());
61
62     // col 2 is 50% G 50% C or 25/25 counting gaps
63     col = result[2];
64     assertEquals(25f, col.getPercentageIdentity(false));
65     assertEquals(50f, col.getPercentageIdentity(true));
66     assertEquals(1, col.getMaxCount());
67     assertEquals("CG", col.getModalResidue());
68
69     // col 3 is all gaps
70     col = result[3];
71     assertEquals(0f, col.getPercentageIdentity(false));
72     assertEquals(0f, col.getPercentageIdentity(true));
73     assertEquals(0, col.getMaxCount());
74     assertEquals("", col.getModalResidue());
75
76     // col 4 is 75% T 25% G
77     col = result[4];
78     assertEquals(75f, col.getPercentageIdentity(false));
79     assertEquals(75f, col.getPercentageIdentity(true));
80     assertEquals(3, col.getMaxCount());
81     assertEquals("T", col.getModalResidue());
82   }
83
84   @Test(groups = { "Functional" })
85   public void testCalculate_withProfile()
86   {
87     SequenceI seq1 = new Sequence("Seq1", "CAGT");
88     SequenceI seq2 = new Sequence("Seq2", "CACT");
89     SequenceI seq3 = new Sequence("Seq3", "C--G");
90     SequenceI seq4 = new Sequence("Seq4", "CA-t");
91     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
92     Profile[] result = new Profile[seq1.getLength()];
93
94     AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true);
95     Profile profile = result[0];
96     assertEquals(4, profile.getCounts().getCount('C'));
97     assertEquals(4, profile.getHeight());
98     assertEquals(4, profile.getNonGapped());
99
100     profile = result[1];
101     assertEquals(3, profile.getCounts().getCount('A'));
102     assertEquals(4, profile.getHeight());
103     assertEquals(3, profile.getNonGapped());
104
105     profile = result[2];
106     assertEquals(1, profile.getCounts().getCount('C'));
107     assertEquals(1, profile.getCounts().getCount('G'));
108     assertEquals(4, profile.getHeight());
109     assertEquals(2, profile.getNonGapped());
110
111     profile = result[3];
112     assertEquals(3, profile.getCounts().getCount('T'));
113     assertEquals(1, profile.getCounts().getCount('G'));
114     assertEquals(4, profile.getHeight());
115     assertEquals(4, profile.getNonGapped());
116   }
117
118   @Test(groups = { "Functional" }, enabled = false)
119   public void testCalculate_withProfileTiming()
120   {
121     SequenceI seq1 = new Sequence("Seq1", "CAGT");
122     SequenceI seq2 = new Sequence("Seq2", "CACT");
123     SequenceI seq3 = new Sequence("Seq3", "C--G");
124     SequenceI seq4 = new Sequence("Seq4", "CA-t");
125     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
126     Profile[] result = new Profile[seq1.getLength()];
127
128     // ensure class loaded and initialized
129     AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true);
130     int reps = 100000;
131     long start = System.currentTimeMillis();
132     for (int i = 0; i < reps; i++)
133     {
134       AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true);
135     }
136     System.out.println(System.currentTimeMillis() - start);
137   }
138
139   /**
140    * Test generation of consensus annotation with options 'include gaps'
141    * (profile percentages are of all sequences, whether gapped or not), and
142    * 'show logo' (the full profile with all residue percentages is reported in
143    * the description for the tooltip)
144    */
145   @Test(groups = { "Functional" })
146   public void testCompleteConsensus_includeGaps_showLogo()
147   {
148     /*
149      * first compute the profiles
150      */
151     SequenceI seq1 = new Sequence("Seq1", "CAG-T");
152     SequenceI seq2 = new Sequence("Seq2", "CAC-T");
153     SequenceI seq3 = new Sequence("Seq3", "C---G");
154     SequenceI seq4 = new Sequence("Seq4", "CA--t");
155     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
156     Profile[] profiles = new Profile[seq1.getLength()];
157     AAFrequency.calculate(seqs, 0, seq1.getLength(), profiles, true);
158
159     AlignmentAnnotation consensus = new AlignmentAnnotation("Consensus",
160             "PID", new Annotation[seq1.getLength()]);
161     AAFrequency
162             .completeConsensus(consensus, profiles, 0, 5, false, true, 4);
163
164     Annotation ann = consensus.annotations[0];
165     assertEquals("C 100%", ann.description);
166     assertEquals("C", ann.displayCharacter);
167     ann = consensus.annotations[1];
168     assertEquals("A 75%", ann.description);
169     assertEquals("A", ann.displayCharacter);
170     ann = consensus.annotations[2];
171     assertEquals("C 25%; G 25%", ann.description);
172     assertEquals("+", ann.displayCharacter);
173     ann = consensus.annotations[3];
174     assertEquals("", ann.description);
175     assertEquals("-", ann.displayCharacter);
176     ann = consensus.annotations[4];
177     assertEquals("T 75%; G 25%", ann.description);
178     assertEquals("T", ann.displayCharacter);
179   }
180
181   /**
182    * Test generation of consensus annotation with options 'ignore gaps' (profile
183    * percentages are of the non-gapped sequences) and 'no logo' (only the modal
184    * residue[s] percentage is reported in the description for the tooltip)
185    */
186   @Test(groups = { "Functional" })
187   public void testCompleteConsensus_ignoreGaps_noLogo()
188   {
189     /*
190      * first compute the profiles
191      */
192     SequenceI seq1 = new Sequence("Seq1", "CAG-T");
193     SequenceI seq2 = new Sequence("Seq2", "CAC-T");
194     SequenceI seq3 = new Sequence("Seq3", "C---G");
195     SequenceI seq4 = new Sequence("Seq4", "CA--t");
196     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
197     Profile[] profiles = new Profile[seq1.getLength()];
198     AAFrequency.calculate(seqs, 0, seq1.getLength(), profiles, true);
199   
200     AlignmentAnnotation consensus = new AlignmentAnnotation("Consensus",
201             "PID", new Annotation[seq1.getLength()]);
202     AAFrequency
203             .completeConsensus(consensus, profiles, 0, 5, true, false, 4);
204   
205     Annotation ann = consensus.annotations[0];
206     assertEquals("C 100%", ann.description);
207     assertEquals("C", ann.displayCharacter);
208     ann = consensus.annotations[1];
209     assertEquals("A 100%", ann.description);
210     assertEquals("A", ann.displayCharacter);
211     ann = consensus.annotations[2];
212     assertEquals("[CG] 50%", ann.description);
213     assertEquals("+", ann.displayCharacter);
214     ann = consensus.annotations[3];
215     assertEquals("", ann.description);
216     assertEquals("-", ann.displayCharacter);
217     ann = consensus.annotations[4];
218     assertEquals("T 75%", ann.description);
219     assertEquals("T", ann.displayCharacter);
220   }
221 }