2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
21 package jalview.analysis;
23 import static org.testng.Assert.assertEquals;
24 import static org.testng.Assert.assertTrue;
26 import jalview.datamodel.Sequence;
27 import jalview.datamodel.SequenceI;
28 import jalview.gui.JvOptionPane;
30 import java.util.ArrayList;
31 import java.util.HashMap;
32 import java.util.List;
35 import org.testng.annotations.BeforeClass;
36 import org.testng.annotations.Test;
38 public class ConservationTest
41 @BeforeClass(alwaysRun = true)
42 public void setUpJvOptionPane()
44 JvOptionPane.setInteractiveMode(false);
45 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
48 @Test(groups = "Functional")
49 public void testRecordConservation()
51 Map<String, Integer> resultMap = new HashMap<String, Integer>();
53 // V is hydrophobic, aliphatic, small
54 Conservation.recordConservation(resultMap, "V");
55 assertEquals(resultMap.get("hydrophobic").intValue(), 1);
56 assertEquals(resultMap.get("aliphatic").intValue(), 1);
57 assertEquals(resultMap.get("small").intValue(), 1);
58 assertEquals(resultMap.get("tiny").intValue(), 0);
59 assertEquals(resultMap.get("polar").intValue(), 0);
60 assertEquals(resultMap.get("charged").intValue(), 0);
62 // now add S: not hydrophobic, small, tiny, polar, not aliphatic
63 Conservation.recordConservation(resultMap, "s");
64 assertEquals(resultMap.get("hydrophobic").intValue(), -1);
65 assertEquals(resultMap.get("aliphatic").intValue(), -1);
66 assertEquals(resultMap.get("small").intValue(), 1);
67 assertEquals(resultMap.get("tiny").intValue(), -1);
68 assertEquals(resultMap.get("polar").intValue(), -1);
69 assertEquals(resultMap.get("charged").intValue(), 0);
72 @Test(groups = "Functional")
73 public void testCountConservationAndGaps()
75 List<SequenceI> seqs = new ArrayList<SequenceI>();
76 seqs.add(new Sequence("seq1", "VGnY")); // not case sensitive
77 seqs.add(new Sequence("seq2", "-G-y"));
78 seqs.add(new Sequence("seq3", "VG-Y"));
79 seqs.add(new Sequence("seq4", "VGNW"));
81 Conservation cons = new Conservation("", seqs, 0, 50);
82 int[] counts = cons.countConservationAndGaps(0);
83 assertEquals(counts[0], 1); // conserved
84 assertEquals(counts[1], 1); // gap count
85 counts = cons.countConservationAndGaps(1);
86 assertEquals(counts[0], 1);
87 assertEquals(counts[1], 0);
88 counts = cons.countConservationAndGaps(2);
89 assertEquals(counts[0], 1);
90 assertEquals(counts[1], 2);
91 counts = cons.countConservationAndGaps(3);
92 assertEquals(counts[0], 0); // not conserved
93 assertEquals(counts[1], 0);
96 @Test(groups = "Functional")
97 public void testCalculate_noThreshold()
99 List<SequenceI> seqs = new ArrayList<SequenceI>();
100 seqs.add(new Sequence("seq1", "VGIV-N"));
101 seqs.add(new Sequence("seq2", "V-iL-N")); // not case sensitive
102 seqs.add(new Sequence("seq3", "V-IW-N"));
103 seqs.add(new Sequence("seq4", "VGLH-L"));
105 Conservation cons = new Conservation("", 0, seqs, 0, 5);
109 * column 0: all V (hydrophobic/aliphatic/small)
111 Map<String, Integer> colCons = cons.total[0];
112 assertEquals(colCons.get("hydrophobic").intValue(), 1);
113 assertEquals(colCons.get("aliphatic").intValue(), 1);
114 assertEquals(colCons.get("small").intValue(), 1);
115 assertEquals(colCons.get("tiny").intValue(), 0);
116 assertEquals(colCons.get("proline").intValue(), 0);
117 assertEquals(colCons.get("charged").intValue(), 0);
118 assertEquals(colCons.get("negative").intValue(), 0);
119 assertEquals(colCons.get("polar").intValue(), 0);
120 assertEquals(colCons.get("positive").intValue(), 0);
121 assertEquals(colCons.get("aromatic").intValue(), 0);
124 * column 1: all G (hydrophobic/small/tiny)
125 * gaps take default value of property present
127 colCons = cons.total[1];
128 assertEquals(colCons.get("hydrophobic").intValue(), 1);
129 assertEquals(colCons.get("aliphatic").intValue(), -1);
130 assertEquals(colCons.get("small").intValue(), 1);
131 assertEquals(colCons.get("tiny").intValue(), 1);
132 assertEquals(colCons.get("proline").intValue(), -1);
133 assertEquals(colCons.get("charged").intValue(), -1);
134 assertEquals(colCons.get("negative").intValue(), -1);
135 assertEquals(colCons.get("polar").intValue(), -1);
136 assertEquals(colCons.get("positive").intValue(), -1);
137 assertEquals(colCons.get("aromatic").intValue(), -1);
140 * column 2: I/L (aliphatic/hydrophobic), all others negatively conserved
142 colCons = cons.total[2];
143 assertEquals(colCons.get("hydrophobic").intValue(), 1);
144 assertEquals(colCons.get("aliphatic").intValue(), 1);
145 assertEquals(colCons.get("small").intValue(), 0);
146 assertEquals(colCons.get("tiny").intValue(), 0);
147 assertEquals(colCons.get("proline").intValue(), 0);
148 assertEquals(colCons.get("charged").intValue(), 0);
149 assertEquals(colCons.get("negative").intValue(), 0);
150 assertEquals(colCons.get("polar").intValue(), 0);
151 assertEquals(colCons.get("positive").intValue(), 0);
152 assertEquals(colCons.get("aromatic").intValue(), 0);
155 * column 3: VLWH all hydrophobic, none is tiny, negative or proline
157 colCons = cons.total[3];
158 assertEquals(colCons.get("hydrophobic").intValue(), 1);
159 assertEquals(colCons.get("aliphatic").intValue(), -1);
160 assertEquals(colCons.get("small").intValue(), -1);
161 assertEquals(colCons.get("tiny").intValue(), 0);
162 assertEquals(colCons.get("proline").intValue(), 0);
163 assertEquals(colCons.get("charged").intValue(), -1);
164 assertEquals(colCons.get("negative").intValue(), 0);
165 assertEquals(colCons.get("polar").intValue(), -1);
166 assertEquals(colCons.get("positive").intValue(), -1);
167 assertEquals(colCons.get("aromatic").intValue(), -1);
170 * column 4: all gaps - counted as having all properties
172 colCons = cons.total[4];
173 assertEquals(colCons.get("hydrophobic").intValue(), 1);
174 assertEquals(colCons.get("aliphatic").intValue(), 1);
175 assertEquals(colCons.get("small").intValue(), 1);
176 assertEquals(colCons.get("tiny").intValue(), 1);
177 assertEquals(colCons.get("proline").intValue(), 1);
178 assertEquals(colCons.get("charged").intValue(), 1);
179 assertEquals(colCons.get("negative").intValue(), 1);
180 assertEquals(colCons.get("polar").intValue(), 1);
181 assertEquals(colCons.get("positive").intValue(), 1);
182 assertEquals(colCons.get("aromatic").intValue(), 1);
185 * column 5: N (small polar) and L (aliphatic hydrophobic)
186 * have nothing in common!
188 colCons = cons.total[5];
189 assertEquals(colCons.get("hydrophobic").intValue(), -1);
190 assertEquals(colCons.get("aliphatic").intValue(), -1);
191 assertEquals(colCons.get("small").intValue(), -1);
192 assertEquals(colCons.get("tiny").intValue(), 0);
193 assertEquals(colCons.get("proline").intValue(), 0);
194 assertEquals(colCons.get("charged").intValue(), 0);
195 assertEquals(colCons.get("negative").intValue(), 0);
196 assertEquals(colCons.get("polar").intValue(), -1);
197 assertEquals(colCons.get("positive").intValue(), 0);
198 assertEquals(colCons.get("aromatic").intValue(), 0);
202 * Test for the case whether the number of non-gapped sequences in a column
203 * has to be above a threshold
205 @Test(groups = "Functional")
206 public void testCalculate_threshold()
208 List<SequenceI> seqs = new ArrayList<SequenceI>();
209 seqs.add(new Sequence("seq1", "VGIV-"));
210 seqs.add(new Sequence("seq2", "V-iL-")); // not case sensitive
211 seqs.add(new Sequence("seq3", "V-IW-"));
212 seqs.add(new Sequence("seq4", "VGLH-"));
213 seqs.add(new Sequence("seq5", "VGLH-"));
216 * threshold 50% means a residue has to occur 3 or more times
217 * in a column to be counted for conservation
219 // TODO: ConservationThread uses a value of 3
220 // calculateConservation states it is the minimum number of sequences
221 // but it is treated as percentage threshold in calculate() ?
222 Conservation cons = new Conservation("", 50, seqs, 0, 4);
226 * column 0: all V (hydrophobic/aliphatic/small)
228 Map<String, Integer> colCons = cons.total[0];
229 assertEquals(colCons.get("hydrophobic").intValue(), 1);
230 assertEquals(colCons.get("aliphatic").intValue(), 1);
231 assertEquals(colCons.get("small").intValue(), 1);
232 assertEquals(colCons.get("tiny").intValue(), 0);
233 assertEquals(colCons.get("proline").intValue(), 0);
234 assertEquals(colCons.get("charged").intValue(), 0);
235 assertEquals(colCons.get("negative").intValue(), 0);
236 assertEquals(colCons.get("polar").intValue(), 0);
237 assertEquals(colCons.get("positive").intValue(), 0);
238 assertEquals(colCons.get("aromatic").intValue(), 0);
241 * column 1: all G (hydrophobic/small/tiny)
242 * gaps are ignored as not above threshold
244 colCons = cons.total[1];
245 assertEquals(colCons.get("hydrophobic").intValue(), 1);
246 assertEquals(colCons.get("aliphatic").intValue(), 0);
247 assertEquals(colCons.get("small").intValue(), 1);
248 assertEquals(colCons.get("tiny").intValue(), 1);
249 assertEquals(colCons.get("proline").intValue(), 0);
250 assertEquals(colCons.get("charged").intValue(), 0);
251 assertEquals(colCons.get("negative").intValue(), 0);
252 assertEquals(colCons.get("polar").intValue(), 0);
253 assertEquals(colCons.get("positive").intValue(), 0);
254 assertEquals(colCons.get("aromatic").intValue(), 0);
257 * column 2: I/L (aliphatic/hydrophobic), all others negatively conserved
259 colCons = cons.total[2];
260 assertEquals(colCons.get("hydrophobic").intValue(), 1);
261 assertEquals(colCons.get("aliphatic").intValue(), 1);
262 assertEquals(colCons.get("small").intValue(), 0);
263 assertEquals(colCons.get("tiny").intValue(), 0);
264 assertEquals(colCons.get("proline").intValue(), 0);
265 assertEquals(colCons.get("charged").intValue(), 0);
266 assertEquals(colCons.get("negative").intValue(), 0);
267 assertEquals(colCons.get("polar").intValue(), 0);
268 assertEquals(colCons.get("positive").intValue(), 0);
269 assertEquals(colCons.get("aromatic").intValue(), 0);
272 * column 3: nothing above threshold
274 colCons = cons.total[3];
275 assertTrue(colCons.isEmpty());
278 * column 4: all gaps - counted as having all properties
280 colCons = cons.total[4];
281 assertEquals(colCons.get("hydrophobic").intValue(), 1);
282 assertEquals(colCons.get("aliphatic").intValue(), 1);
283 assertEquals(colCons.get("small").intValue(), 1);
284 assertEquals(colCons.get("tiny").intValue(), 1);
285 assertEquals(colCons.get("proline").intValue(), 1);
286 assertEquals(colCons.get("charged").intValue(), 1);
287 assertEquals(colCons.get("negative").intValue(), 1);
288 assertEquals(colCons.get("polar").intValue(), 1);
289 assertEquals(colCons.get("positive").intValue(), 1);
290 assertEquals(colCons.get("aromatic").intValue(), 1);
294 * Test the method that derives the conservation 'sequence' and the mouseover
295 * tooltips from the computed conservation
297 @Test(groups = "Functional")
298 public void testVerdict()
300 List<SequenceI> seqs = new ArrayList<SequenceI>();
301 seqs.add(new Sequence("seq1", "VGIVV-H"));
302 seqs.add(new Sequence("seq2", "VGILL-H"));
303 seqs.add(new Sequence("seq3", "VGIW--R"));
304 seqs.add(new Sequence("seq4", "VGLHH--"));
305 seqs.add(new Sequence("seq5", "VGLHH-R"));
306 seqs.add(new Sequence("seq6", "VGLHH--"));
307 seqs.add(new Sequence("seq7", "VGLHH-R"));
308 seqs.add(new Sequence("seq8", "VGLHH-R"));
310 // calculate with no threshold
311 Conservation cons = new Conservation("", 0, seqs, 0, 6);
313 // positive and negative conservation where <25% gaps in columns
314 cons.verdict(false, 25);
317 * verify conservation 'sequence'
318 * cols 0 fully conserved and above threshold (*)
319 * col 2 properties fully conserved (+)
320 * col 3 VLWH 1 positively and 3 negatively conserved properties
321 * col 4 has 1 positively conserved property, but because gap contributes a
322 * 'positive' for all properties, no negative conservation is counted
324 * col 6 has 25% gaps so fails threshold test
326 assertEquals(cons.getConsSequence().getSequenceAsString(), "**+41--");
329 * verify tooltips; conserved properties are sorted alphabetically within
330 * positive followed by negative
334 "aliphatic hydrophobic small !aromatic !charged !negative !polar !positive !proline !tiny");
337 "hydrophobic small tiny !aliphatic !aromatic !charged !negative !polar !positive !proline");
340 "aliphatic hydrophobic !aromatic !charged !negative !polar !positive !proline !small !tiny");
341 assertEquals(cons.getTooltip(3), "hydrophobic !negative !proline !tiny");
342 assertEquals(cons.getTooltip(4), "hydrophobic");
343 assertEquals(cons.getTooltip(5), "");
344 assertEquals(cons.getTooltip(6), "");