1 package jalview.analysis;
3 import static org.testng.Assert.assertEquals;
4 import static org.testng.Assert.assertTrue;
6 import jalview.datamodel.Sequence;
7 import jalview.datamodel.SequenceI;
9 import java.util.ArrayList;
10 import java.util.HashMap;
11 import java.util.List;
14 import org.testng.annotations.Test;
16 public class ConservationTest
18 @Test(groups = "Functional")
19 public void testRecordConservation()
21 Map<String, Integer> resultMap = new HashMap<String, Integer>();
23 // V is hydrophobic, aliphatic, small
24 Conservation.recordConservation(resultMap, "V");
25 assertEquals(resultMap.get("hydrophobic").intValue(), 1);
26 assertEquals(resultMap.get("aliphatic").intValue(), 1);
27 assertEquals(resultMap.get("small").intValue(), 1);
28 assertEquals(resultMap.get("tiny").intValue(), 0);
29 assertEquals(resultMap.get("polar").intValue(), 0);
30 assertEquals(resultMap.get("charged").intValue(), 0);
32 // now add S: not hydrophobic, small, tiny, polar, not aliphatic
33 Conservation.recordConservation(resultMap, "s");
34 assertEquals(resultMap.get("hydrophobic").intValue(), -1);
35 assertEquals(resultMap.get("aliphatic").intValue(), -1);
36 assertEquals(resultMap.get("small").intValue(), 1);
37 assertEquals(resultMap.get("tiny").intValue(), -1);
38 assertEquals(resultMap.get("polar").intValue(), -1);
39 assertEquals(resultMap.get("charged").intValue(), 0);
42 @Test(groups = "Functional")
43 public void testCountConservationAndGaps()
45 List<SequenceI> seqs = new ArrayList<SequenceI>();
46 seqs.add(new Sequence("seq1", "VGnY")); // not case sensitive
47 seqs.add(new Sequence("seq2", "-G-y"));
48 seqs.add(new Sequence("seq3", "VG-Y"));
49 seqs.add(new Sequence("seq4", "VGNW"));
51 Conservation cons = new Conservation("", seqs, 0, 50);
52 int[] counts = cons.countConservationAndGaps(0);
53 assertEquals(counts[0], 1); // conserved
54 assertEquals(counts[1], 1); // gap count
55 counts = cons.countConservationAndGaps(1);
56 assertEquals(counts[0], 1);
57 assertEquals(counts[1], 0);
58 counts = cons.countConservationAndGaps(2);
59 assertEquals(counts[0], 1);
60 assertEquals(counts[1], 2);
61 counts = cons.countConservationAndGaps(3);
62 assertEquals(counts[0], 0); // not conserved
63 assertEquals(counts[1], 0);
66 @Test(groups = "Functional")
67 public void testCalculate_noThreshold()
69 List<SequenceI> seqs = new ArrayList<SequenceI>();
70 seqs.add(new Sequence("seq1", "VGIV-N"));
71 seqs.add(new Sequence("seq2", "V-iL-N")); // not case sensitive
72 seqs.add(new Sequence("seq3", "V-IW-N"));
73 seqs.add(new Sequence("seq4", "VGLH-L"));
75 Conservation cons = new Conservation("", 0, seqs, 0, 5);
79 * column 0: all V (hydrophobic/aliphatic/small)
81 Map<String, Integer> colCons = cons.total[0];
82 assertEquals(colCons.get("hydrophobic").intValue(), 1);
83 assertEquals(colCons.get("aliphatic").intValue(), 1);
84 assertEquals(colCons.get("small").intValue(), 1);
85 assertEquals(colCons.get("tiny").intValue(), 0);
86 assertEquals(colCons.get("proline").intValue(), 0);
87 assertEquals(colCons.get("charged").intValue(), 0);
88 assertEquals(colCons.get("negative").intValue(), 0);
89 assertEquals(colCons.get("polar").intValue(), 0);
90 assertEquals(colCons.get("positive").intValue(), 0);
91 assertEquals(colCons.get("aromatic").intValue(), 0);
94 * column 1: all G (hydrophobic/small/tiny)
95 * gaps take default value of property present
97 colCons = cons.total[1];
98 assertEquals(colCons.get("hydrophobic").intValue(), 1);
99 assertEquals(colCons.get("aliphatic").intValue(), -1);
100 assertEquals(colCons.get("small").intValue(), 1);
101 assertEquals(colCons.get("tiny").intValue(), 1);
102 assertEquals(colCons.get("proline").intValue(), -1);
103 assertEquals(colCons.get("charged").intValue(), -1);
104 assertEquals(colCons.get("negative").intValue(), -1);
105 assertEquals(colCons.get("polar").intValue(), -1);
106 assertEquals(colCons.get("positive").intValue(), -1);
107 assertEquals(colCons.get("aromatic").intValue(), -1);
110 * column 2: I/L (aliphatic/hydrophobic), all others negatively conserved
112 colCons = cons.total[2];
113 assertEquals(colCons.get("hydrophobic").intValue(), 1);
114 assertEquals(colCons.get("aliphatic").intValue(), 1);
115 assertEquals(colCons.get("small").intValue(), 0);
116 assertEquals(colCons.get("tiny").intValue(), 0);
117 assertEquals(colCons.get("proline").intValue(), 0);
118 assertEquals(colCons.get("charged").intValue(), 0);
119 assertEquals(colCons.get("negative").intValue(), 0);
120 assertEquals(colCons.get("polar").intValue(), 0);
121 assertEquals(colCons.get("positive").intValue(), 0);
122 assertEquals(colCons.get("aromatic").intValue(), 0);
125 * column 3: VLWH all hydrophobic, none is tiny, negative or proline
127 colCons = cons.total[3];
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(), 0);
132 assertEquals(colCons.get("proline").intValue(), 0);
133 assertEquals(colCons.get("charged").intValue(), -1);
134 assertEquals(colCons.get("negative").intValue(), 0);
135 assertEquals(colCons.get("polar").intValue(), -1);
136 assertEquals(colCons.get("positive").intValue(), -1);
137 assertEquals(colCons.get("aromatic").intValue(), -1);
140 * column 4: all gaps - counted as having all properties
142 colCons = cons.total[4];
143 assertEquals(colCons.get("hydrophobic").intValue(), 1);
144 assertEquals(colCons.get("aliphatic").intValue(), 1);
145 assertEquals(colCons.get("small").intValue(), 1);
146 assertEquals(colCons.get("tiny").intValue(), 1);
147 assertEquals(colCons.get("proline").intValue(), 1);
148 assertEquals(colCons.get("charged").intValue(), 1);
149 assertEquals(colCons.get("negative").intValue(), 1);
150 assertEquals(colCons.get("polar").intValue(), 1);
151 assertEquals(colCons.get("positive").intValue(), 1);
152 assertEquals(colCons.get("aromatic").intValue(), 1);
155 * column 5: N (small polar) and L (aliphatic hydrophobic)
156 * have nothing in common!
158 colCons = cons.total[5];
159 assertEquals(colCons.get("hydrophobic").intValue(), -1);
160 assertEquals(colCons.get("aliphatic").intValue(), -1);
161 assertEquals(colCons.get("small").intValue(), -1);
162 assertEquals(colCons.get("tiny").intValue(), 0);
163 assertEquals(colCons.get("proline").intValue(), 0);
164 assertEquals(colCons.get("charged").intValue(), 0);
165 assertEquals(colCons.get("negative").intValue(), 0);
166 assertEquals(colCons.get("polar").intValue(), -1);
167 assertEquals(colCons.get("positive").intValue(), 0);
168 assertEquals(colCons.get("aromatic").intValue(), 0);
172 * Test for the case whether the number of non-gapped sequences in a column
173 * has to be above a threshold
175 @Test(groups = "Functional")
176 public void testCalculate_threshold()
178 List<SequenceI> seqs = new ArrayList<SequenceI>();
179 seqs.add(new Sequence("seq1", "VGIV-"));
180 seqs.add(new Sequence("seq2", "V-iL-")); // not case sensitive
181 seqs.add(new Sequence("seq3", "V-IW-"));
182 seqs.add(new Sequence("seq4", "VGLH-"));
183 seqs.add(new Sequence("seq5", "VGLH-"));
186 * threshold 50% means a residue has to occur 3 or more times
187 * in a column to be counted for conservation
189 // TODO: ConservationThread uses a value of 3
190 // calculateConservation states it is the minimum number of sequences
191 // but it is treated as percentage threshold in calculate() ?
192 Conservation cons = new Conservation("", 50, seqs, 0, 4);
196 * column 0: all V (hydrophobic/aliphatic/small)
198 Map<String, Integer> colCons = cons.total[0];
199 assertEquals(colCons.get("hydrophobic").intValue(), 1);
200 assertEquals(colCons.get("aliphatic").intValue(), 1);
201 assertEquals(colCons.get("small").intValue(), 1);
202 assertEquals(colCons.get("tiny").intValue(), 0);
203 assertEquals(colCons.get("proline").intValue(), 0);
204 assertEquals(colCons.get("charged").intValue(), 0);
205 assertEquals(colCons.get("negative").intValue(), 0);
206 assertEquals(colCons.get("polar").intValue(), 0);
207 assertEquals(colCons.get("positive").intValue(), 0);
208 assertEquals(colCons.get("aromatic").intValue(), 0);
211 * column 1: all G (hydrophobic/small/tiny)
212 * gaps are ignored as not above threshold
214 colCons = cons.total[1];
215 assertEquals(colCons.get("hydrophobic").intValue(), 1);
216 assertEquals(colCons.get("aliphatic").intValue(), 0);
217 assertEquals(colCons.get("small").intValue(), 1);
218 assertEquals(colCons.get("tiny").intValue(), 1);
219 assertEquals(colCons.get("proline").intValue(), 0);
220 assertEquals(colCons.get("charged").intValue(), 0);
221 assertEquals(colCons.get("negative").intValue(), 0);
222 assertEquals(colCons.get("polar").intValue(), 0);
223 assertEquals(colCons.get("positive").intValue(), 0);
224 assertEquals(colCons.get("aromatic").intValue(), 0);
227 * column 2: I/L (aliphatic/hydrophobic), all others negatively conserved
229 colCons = cons.total[2];
230 assertEquals(colCons.get("hydrophobic").intValue(), 1);
231 assertEquals(colCons.get("aliphatic").intValue(), 1);
232 assertEquals(colCons.get("small").intValue(), 0);
233 assertEquals(colCons.get("tiny").intValue(), 0);
234 assertEquals(colCons.get("proline").intValue(), 0);
235 assertEquals(colCons.get("charged").intValue(), 0);
236 assertEquals(colCons.get("negative").intValue(), 0);
237 assertEquals(colCons.get("polar").intValue(), 0);
238 assertEquals(colCons.get("positive").intValue(), 0);
239 assertEquals(colCons.get("aromatic").intValue(), 0);
242 * column 3: nothing above threshold
244 colCons = cons.total[3];
245 assertTrue(colCons.isEmpty());
248 * column 4: all gaps - counted as having all properties
250 colCons = cons.total[4];
251 assertEquals(colCons.get("hydrophobic").intValue(), 1);
252 assertEquals(colCons.get("aliphatic").intValue(), 1);
253 assertEquals(colCons.get("small").intValue(), 1);
254 assertEquals(colCons.get("tiny").intValue(), 1);
255 assertEquals(colCons.get("proline").intValue(), 1);
256 assertEquals(colCons.get("charged").intValue(), 1);
257 assertEquals(colCons.get("negative").intValue(), 1);
258 assertEquals(colCons.get("polar").intValue(), 1);
259 assertEquals(colCons.get("positive").intValue(), 1);
260 assertEquals(colCons.get("aromatic").intValue(), 1);
264 * Test the method that derives the conservation 'sequence' and the mouseover
265 * tooltips from the computed conservation
267 @Test(groups = "Functional")
268 public void testVerdict()
270 List<SequenceI> seqs = new ArrayList<SequenceI>();
271 seqs.add(new Sequence("seq1", "VGIVV-H"));
272 seqs.add(new Sequence("seq2", "VGILL-H"));
273 seqs.add(new Sequence("seq3", "VGIW--R"));
274 seqs.add(new Sequence("seq4", "VGLHH--"));
275 seqs.add(new Sequence("seq5", "VGLHH-R"));
276 seqs.add(new Sequence("seq6", "VGLHH--"));
277 seqs.add(new Sequence("seq7", "VGLHH-R"));
278 seqs.add(new Sequence("seq8", "VGLHH-R"));
280 // calculate with no threshold
281 Conservation cons = new Conservation("", 0, seqs, 0, 6);
283 // positive and negative conservation where <25% gaps in columns
284 cons.verdict(false, 25);
287 * verify conservation 'sequence'
288 * cols 0 fully conserved and above threshold (*)
289 * col 2 properties fully conserved (+)
290 * col 3 VLWH 1 positively and 3 negatively conserved properties
291 * col 4 has 1 positively conserved property, but because gap contributes a
292 * 'positive' for all properties, no negative conservation is counted
294 * col 6 has 25% gaps so fails threshold test
296 assertEquals(cons.getConsSequence().getSequenceAsString(), "**+41--");
299 * verify tooltips; conserved properties are sorted alphabetically within
300 * positive followed by negative
304 "aliphatic hydrophobic small !aromatic !charged !negative !polar !positive !proline !tiny");
307 "hydrophobic small tiny !aliphatic !aromatic !charged !negative !polar !positive !proline");
310 "aliphatic hydrophobic !aromatic !charged !negative !polar !positive !proline !small !tiny");
311 assertEquals(cons.getTooltip(3), "hydrophobic !negative !proline !tiny");
312 assertEquals(cons.getTooltip(4), "hydrophobic");
313 assertEquals(cons.getTooltip(5), "");
314 assertEquals(cons.getTooltip(6), "");