Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
SequenceFeaturesTest | 39 | 717 | 23 |
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.datamodel.features; | |
22 | ||
23 | import static org.testng.Assert.assertEquals; | |
24 | import static org.testng.Assert.assertFalse; | |
25 | import static org.testng.Assert.assertSame; | |
26 | import static org.testng.Assert.assertTrue; | |
27 | ||
28 | import java.util.ArrayList; | |
29 | import java.util.Iterator; | |
30 | import java.util.List; | |
31 | import java.util.Map; | |
32 | import java.util.Set; | |
33 | ||
34 | import org.testng.annotations.Test; | |
35 | ||
36 | import jalview.datamodel.SequenceFeature; | |
37 | import junit.extensions.PA; | |
38 | ||
39 | public class SequenceFeaturesTest | |
40 | { | |
41 | 1 | @Test(groups = "Functional") |
42 | public void testConstructor() | |
43 | { | |
44 | 1 | SequenceFeaturesI store = new SequenceFeatures(); |
45 | 1 | assertFalse(store.hasFeatures()); |
46 | ||
47 | 1 | store = new SequenceFeatures((List<SequenceFeature>) null); |
48 | 1 | assertFalse(store.hasFeatures()); |
49 | ||
50 | 1 | List<SequenceFeature> features = new ArrayList<>(); |
51 | 1 | store = new SequenceFeatures(features); |
52 | 1 | assertFalse(store.hasFeatures()); |
53 | ||
54 | 1 | SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20, |
55 | Float.NaN, null); | |
56 | 1 | features.add(sf1); |
57 | 1 | SequenceFeature sf2 = new SequenceFeature("Metal", "desc", 15, 18, |
58 | Float.NaN, null); | |
59 | 1 | features.add(sf2); // nested |
60 | 1 | SequenceFeature sf3 = new SequenceFeature("Pfam", "desc2", 0, 0, |
61 | Float.NaN, null); // non-positional | |
62 | 1 | features.add(sf3); |
63 | 1 | store = new SequenceFeatures(features); |
64 | 1 | assertTrue(store.hasFeatures()); |
65 | 1 | assertEquals(2, store.getFeatureCount(true)); // positional |
66 | 1 | assertEquals(1, store.getFeatureCount(false)); // non-positional |
67 | 1 | assertFalse(store.add(sf1)); // already contained |
68 | 1 | assertFalse(store.add(sf2)); // already contained |
69 | 1 | assertFalse(store.add(sf3)); // already contained |
70 | } | |
71 | ||
72 | 1 | @Test(groups = "Functional") |
73 | public void testGetPositionalFeatures() | |
74 | { | |
75 | 1 | SequenceFeaturesI store = new SequenceFeatures(); |
76 | 1 | SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20, |
77 | Float.NaN, null); | |
78 | 1 | store.add(sf1); |
79 | // same range, different description | |
80 | 1 | SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20, |
81 | Float.NaN, null); | |
82 | 1 | store.add(sf2); |
83 | // discontiguous range | |
84 | 1 | SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40, |
85 | Float.NaN, null); | |
86 | 1 | store.add(sf3); |
87 | // overlapping range | |
88 | 1 | SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35, |
89 | Float.NaN, null); | |
90 | 1 | store.add(sf4); |
91 | // enclosing range | |
92 | 1 | SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50, |
93 | Float.NaN, null); | |
94 | 1 | store.add(sf5); |
95 | // non-positional feature | |
96 | 1 | SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0, |
97 | Float.NaN, null); | |
98 | 1 | store.add(sf6); |
99 | // contact feature | |
100 | 1 | SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc", 18, |
101 | 45, Float.NaN, null); | |
102 | 1 | store.add(sf7); |
103 | // different feature type | |
104 | 1 | SequenceFeature sf8 = new SequenceFeature("Pfam", "desc", 30, 40, |
105 | Float.NaN, null); | |
106 | 1 | store.add(sf8); |
107 | 1 | SequenceFeature sf9 = new SequenceFeature("Pfam", "desc", 15, 35, |
108 | Float.NaN, null); | |
109 | 1 | store.add(sf9); |
110 | ||
111 | /* | |
112 | * get all positional features | |
113 | */ | |
114 | 1 | List<SequenceFeature> features = store.getPositionalFeatures(); |
115 | 1 | assertEquals(features.size(), 8); |
116 | 1 | assertTrue(features.contains(sf1)); |
117 | 1 | assertTrue(features.contains(sf2)); |
118 | 1 | assertTrue(features.contains(sf3)); |
119 | 1 | assertTrue(features.contains(sf4)); |
120 | 1 | assertTrue(features.contains(sf5)); |
121 | 1 | assertFalse(features.contains(sf6)); // non-positional |
122 | 1 | assertTrue(features.contains(sf7)); |
123 | 1 | assertTrue(features.contains(sf8)); |
124 | 1 | assertTrue(features.contains(sf9)); |
125 | ||
126 | /* | |
127 | * get features by type | |
128 | */ | |
129 | 1 | assertTrue(store.getPositionalFeatures((String) null).isEmpty()); |
130 | 1 | assertTrue(store.getPositionalFeatures("Cath").isEmpty()); |
131 | 1 | assertTrue(store.getPositionalFeatures("METAL").isEmpty()); |
132 | ||
133 | 1 | features = store.getPositionalFeatures("Metal"); |
134 | 1 | assertEquals(features.size(), 5); |
135 | 1 | assertTrue(features.contains(sf1)); |
136 | 1 | assertTrue(features.contains(sf2)); |
137 | 1 | assertTrue(features.contains(sf3)); |
138 | 1 | assertTrue(features.contains(sf4)); |
139 | 1 | assertTrue(features.contains(sf5)); |
140 | 1 | assertFalse(features.contains(sf6)); |
141 | ||
142 | 1 | features = store.getPositionalFeatures("Disulphide bond"); |
143 | 1 | assertEquals(features.size(), 1); |
144 | 1 | assertTrue(features.contains(sf7)); |
145 | ||
146 | 1 | features = store.getPositionalFeatures("Pfam"); |
147 | 1 | assertEquals(features.size(), 2); |
148 | 1 | assertTrue(features.contains(sf8)); |
149 | 1 | assertTrue(features.contains(sf9)); |
150 | } | |
151 | ||
152 | 1 | @Test(groups = "Functional") |
153 | public void testGetContactFeatures() | |
154 | { | |
155 | 1 | SequenceFeaturesI store = new SequenceFeatures(); |
156 | // non-contact | |
157 | 1 | SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20, |
158 | Float.NaN, null); | |
159 | 1 | store.add(sf1); |
160 | // non-positional | |
161 | 1 | SequenceFeature sf2 = new SequenceFeature("Metal", "desc", 0, 0, |
162 | Float.NaN, null); | |
163 | 1 | store.add(sf2); |
164 | // contact feature | |
165 | 1 | SequenceFeature sf3 = new SequenceFeature("Disulphide bond", "desc", 18, |
166 | 45, Float.NaN, null); | |
167 | 1 | store.add(sf3); |
168 | // repeat for different feature type | |
169 | 1 | SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 10, 20, |
170 | Float.NaN, null); | |
171 | 1 | store.add(sf4); |
172 | 1 | SequenceFeature sf5 = new SequenceFeature("Pfam", "desc", 0, 0, |
173 | Float.NaN, null); | |
174 | 1 | store.add(sf5); |
175 | 1 | SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "desc", 18, |
176 | 45, Float.NaN, null); | |
177 | 1 | store.add(sf6); |
178 | ||
179 | /* | |
180 | * get all contact features | |
181 | */ | |
182 | 1 | List<SequenceFeature> features = store.getContactFeatures(); |
183 | 1 | assertEquals(features.size(), 2); |
184 | 1 | assertTrue(features.contains(sf3)); |
185 | 1 | assertTrue(features.contains(sf6)); |
186 | ||
187 | /* | |
188 | * get contact features by type | |
189 | */ | |
190 | 1 | assertTrue(store.getContactFeatures((String) null).isEmpty()); |
191 | 1 | assertTrue(store.getContactFeatures("Cath").isEmpty()); |
192 | 1 | assertTrue(store.getContactFeatures("Pfam").isEmpty()); |
193 | 1 | assertTrue(store.getContactFeatures("DISULPHIDE BOND").isEmpty()); |
194 | ||
195 | 1 | features = store.getContactFeatures("Disulphide bond"); |
196 | 1 | assertEquals(features.size(), 1); |
197 | 1 | assertTrue(features.contains(sf3)); |
198 | ||
199 | 1 | features = store.getContactFeatures("Disulfide bond"); |
200 | 1 | assertEquals(features.size(), 1); |
201 | 1 | assertTrue(features.contains(sf6)); |
202 | } | |
203 | ||
204 | 1 | @Test(groups = "Functional") |
205 | public void testGetNonPositionalFeatures() | |
206 | { | |
207 | 1 | SequenceFeaturesI store = new SequenceFeatures(); |
208 | // positional | |
209 | 1 | SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20, |
210 | Float.NaN, null); | |
211 | 1 | store.add(sf1); |
212 | // non-positional | |
213 | 1 | SequenceFeature sf2 = new SequenceFeature("Metal", "desc", 0, 0, |
214 | Float.NaN, null); | |
215 | 1 | store.add(sf2); |
216 | // contact feature | |
217 | 1 | SequenceFeature sf3 = new SequenceFeature("Disulphide bond", "desc", 18, |
218 | 45, Float.NaN, null); | |
219 | 1 | store.add(sf3); |
220 | // repeat for different feature type | |
221 | 1 | SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 10, 20, |
222 | Float.NaN, null); | |
223 | 1 | store.add(sf4); |
224 | 1 | SequenceFeature sf5 = new SequenceFeature("Pfam", "desc", 0, 0, |
225 | Float.NaN, null); | |
226 | 1 | store.add(sf5); |
227 | 1 | SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "desc", 18, |
228 | 45, Float.NaN, null); | |
229 | 1 | store.add(sf6); |
230 | // one more non-positional, different description | |
231 | 1 | SequenceFeature sf7 = new SequenceFeature("Pfam", "desc2", 0, 0, |
232 | Float.NaN, null); | |
233 | 1 | store.add(sf7); |
234 | ||
235 | /* | |
236 | * get all non-positional features | |
237 | */ | |
238 | 1 | List<SequenceFeature> features = store.getNonPositionalFeatures(); |
239 | 1 | assertEquals(features.size(), 3); |
240 | 1 | assertTrue(features.contains(sf2)); |
241 | 1 | assertTrue(features.contains(sf5)); |
242 | 1 | assertTrue(features.contains(sf7)); |
243 | ||
244 | /* | |
245 | * get non-positional features by type | |
246 | */ | |
247 | 1 | assertTrue(store.getNonPositionalFeatures((String) null).isEmpty()); |
248 | 1 | assertTrue(store.getNonPositionalFeatures("Cath").isEmpty()); |
249 | 1 | assertTrue(store.getNonPositionalFeatures("PFAM").isEmpty()); |
250 | ||
251 | 1 | features = store.getNonPositionalFeatures("Metal"); |
252 | 1 | assertEquals(features.size(), 1); |
253 | 1 | assertTrue(features.contains(sf2)); |
254 | ||
255 | 1 | features = store.getNonPositionalFeatures("Pfam"); |
256 | 1 | assertEquals(features.size(), 2); |
257 | 1 | assertTrue(features.contains(sf5)); |
258 | 1 | assertTrue(features.contains(sf7)); |
259 | } | |
260 | ||
261 | /** | |
262 | * Helper method to add a feature of no particular type | |
263 | * | |
264 | * @param sf | |
265 | * @param type | |
266 | * @param from | |
267 | * @param to | |
268 | * @return | |
269 | */ | |
270 | 14 | SequenceFeature addFeature(SequenceFeaturesI sf, String type, int from, |
271 | int to) | |
272 | { | |
273 | 14 | SequenceFeature sf1 = new SequenceFeature(type, "", from, to, Float.NaN, |
274 | null); | |
275 | 14 | sf.add(sf1); |
276 | 14 | return sf1; |
277 | } | |
278 | ||
279 | 1 | @Test(groups = "Functional") |
280 | public void testFindFeatures() | |
281 | { | |
282 | 1 | SequenceFeaturesI sf = new SequenceFeatures(); |
283 | 1 | SequenceFeature sf1 = addFeature(sf, "Pfam", 10, 50); |
284 | 1 | SequenceFeature sf2 = addFeature(sf, "Pfam", 1, 15); |
285 | 1 | SequenceFeature sf3 = addFeature(sf, "Pfam", 20, 30); |
286 | 1 | SequenceFeature sf4 = addFeature(sf, "Pfam", 40, 100); |
287 | 1 | SequenceFeature sf5 = addFeature(sf, "Pfam", 60, 100); |
288 | 1 | SequenceFeature sf6 = addFeature(sf, "Pfam", 70, 70); |
289 | 1 | SequenceFeature sf7 = addFeature(sf, "Cath", 10, 50); |
290 | 1 | SequenceFeature sf8 = addFeature(sf, "Cath", 1, 15); |
291 | 1 | SequenceFeature sf9 = addFeature(sf, "Cath", 20, 30); |
292 | 1 | SequenceFeature sf10 = addFeature(sf, "Cath", 40, 100); |
293 | 1 | SequenceFeature sf11 = addFeature(sf, "Cath", 60, 100); |
294 | 1 | SequenceFeature sf12 = addFeature(sf, "Cath", 70, 70); |
295 | ||
296 | 1 | List<SequenceFeature> overlaps = sf.findFeatures(200, 200, "Pfam"); |
297 | 1 | assertTrue(overlaps.isEmpty()); |
298 | ||
299 | 1 | overlaps = sf.findFeatures(1, 9, "Pfam"); |
300 | 1 | assertEquals(overlaps.size(), 1); |
301 | 1 | assertTrue(overlaps.contains(sf2)); |
302 | ||
303 | 1 | overlaps = sf.findFeatures(5, 18, "Pfam"); |
304 | 1 | assertEquals(overlaps.size(), 2); |
305 | 1 | assertTrue(overlaps.contains(sf1)); |
306 | 1 | assertTrue(overlaps.contains(sf2)); |
307 | ||
308 | 1 | overlaps = sf.findFeatures(30, 40, "Pfam"); |
309 | 1 | assertEquals(overlaps.size(), 3); |
310 | 1 | assertTrue(overlaps.contains(sf1)); |
311 | 1 | assertTrue(overlaps.contains(sf3)); |
312 | 1 | assertTrue(overlaps.contains(sf4)); |
313 | ||
314 | 1 | overlaps = sf.findFeatures(80, 90, "Pfam"); |
315 | 1 | assertEquals(overlaps.size(), 2); |
316 | 1 | assertTrue(overlaps.contains(sf4)); |
317 | 1 | assertTrue(overlaps.contains(sf5)); |
318 | ||
319 | 1 | overlaps = sf.findFeatures(68, 70, "Pfam"); |
320 | 1 | assertEquals(overlaps.size(), 3); |
321 | 1 | assertTrue(overlaps.contains(sf4)); |
322 | 1 | assertTrue(overlaps.contains(sf5)); |
323 | 1 | assertTrue(overlaps.contains(sf6)); |
324 | ||
325 | 1 | overlaps = sf.findFeatures(16, 69, "Cath"); |
326 | 1 | assertEquals(overlaps.size(), 4); |
327 | 1 | assertTrue(overlaps.contains(sf7)); |
328 | 1 | assertFalse(overlaps.contains(sf8)); |
329 | 1 | assertTrue(overlaps.contains(sf9)); |
330 | 1 | assertTrue(overlaps.contains(sf10)); |
331 | 1 | assertTrue(overlaps.contains(sf11)); |
332 | 1 | assertFalse(overlaps.contains(sf12)); |
333 | ||
334 | 1 | assertTrue(sf.findFeatures(0, 1000, "Metal").isEmpty()); |
335 | ||
336 | 1 | overlaps = sf.findFeatures(7, 7, (String) null); |
337 | 1 | assertTrue(overlaps.isEmpty()); |
338 | } | |
339 | ||
340 | 1 | @Test(groups = "Functional") |
341 | public void testDelete() | |
342 | { | |
343 | 1 | SequenceFeaturesI sf = new SequenceFeatures(); |
344 | 1 | SequenceFeature sf1 = addFeature(sf, "Pfam", 10, 50); |
345 | 1 | assertTrue(sf.getPositionalFeatures().contains(sf1)); |
346 | ||
347 | 1 | assertFalse(sf.delete(null)); |
348 | 1 | SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 15, 0f, null); |
349 | 1 | assertFalse(sf.delete(sf2)); // not added, can't delete it |
350 | 1 | assertTrue(sf.delete(sf1)); |
351 | 1 | assertTrue(sf.getPositionalFeatures().isEmpty()); |
352 | } | |
353 | ||
354 | 1 | @Test(groups = "Functional") |
355 | public void testHasFeatures() | |
356 | { | |
357 | 1 | SequenceFeaturesI sf = new SequenceFeatures(); |
358 | 1 | assertFalse(sf.hasFeatures()); |
359 | ||
360 | 1 | SequenceFeature sf1 = addFeature(sf, "Pfam", 10, 50); |
361 | 1 | assertTrue(sf.hasFeatures()); |
362 | ||
363 | 1 | sf.delete(sf1); |
364 | 1 | assertFalse(sf.hasFeatures()); |
365 | } | |
366 | ||
367 | /** | |
368 | * Tests for the method that gets feature groups for positional or | |
369 | * non-positional features | |
370 | */ | |
371 | 1 | @Test(groups = "Functional") |
372 | public void testGetFeatureGroups() | |
373 | { | |
374 | 1 | SequenceFeaturesI sf = new SequenceFeatures(); |
375 | 1 | assertTrue(sf.getFeatureGroups(true).isEmpty()); |
376 | 1 | assertTrue(sf.getFeatureGroups(false).isEmpty()); |
377 | ||
378 | /* | |
379 | * add a non-positional feature (begin/end = 0/0) | |
380 | */ | |
381 | 1 | SequenceFeature sfx = new SequenceFeature("AType", "Desc", 0, 0, 0f, |
382 | "AGroup"); | |
383 | 1 | sf.add(sfx); |
384 | 1 | Set<String> groups = sf.getFeatureGroups(true); // for positional |
385 | 1 | assertTrue(groups.isEmpty()); |
386 | 1 | groups = sf.getFeatureGroups(false); // for non-positional |
387 | 1 | assertEquals(groups.size(), 1); |
388 | 1 | assertTrue(groups.contains("AGroup")); |
389 | 1 | groups = sf.getFeatureGroups(false, "AType"); |
390 | 1 | assertEquals(groups.size(), 1); |
391 | 1 | assertTrue(groups.contains("AGroup")); |
392 | 1 | groups = sf.getFeatureGroups(true, "AnotherType"); |
393 | 1 | assertTrue(groups.isEmpty()); |
394 | ||
395 | /* | |
396 | * add, then delete, more non-positional features of different types | |
397 | */ | |
398 | 1 | SequenceFeature sfy = new SequenceFeature("AnotherType", "Desc", 0, 0, |
399 | 0f, "AnotherGroup"); | |
400 | 1 | sf.add(sfy); |
401 | 1 | SequenceFeature sfz = new SequenceFeature("AThirdType", "Desc", 0, 0, |
402 | 0f, null); | |
403 | 1 | sf.add(sfz); |
404 | 1 | groups = sf.getFeatureGroups(false); |
405 | 1 | assertEquals(groups.size(), 3); |
406 | 1 | assertTrue(groups.contains("AGroup")); |
407 | 1 | assertTrue(groups.contains("AnotherGroup")); |
408 | 1 | assertTrue(groups.contains(null)); // null is a possible group |
409 | 1 | sf.delete(sfz); |
410 | 1 | sf.delete(sfy); |
411 | 1 | groups = sf.getFeatureGroups(false); |
412 | 1 | assertEquals(groups.size(), 1); |
413 | 1 | assertTrue(groups.contains("AGroup")); |
414 | ||
415 | /* | |
416 | * add positional features | |
417 | */ | |
418 | 1 | SequenceFeature sf1 = new SequenceFeature("Pfam", "Desc", 10, 50, 0f, |
419 | "PfamGroup"); | |
420 | 1 | sf.add(sf1); |
421 | 1 | groups = sf.getFeatureGroups(true); |
422 | 1 | assertEquals(groups.size(), 1); |
423 | 1 | assertTrue(groups.contains("PfamGroup")); |
424 | 1 | groups = sf.getFeatureGroups(false); // non-positional unchanged |
425 | 1 | assertEquals(groups.size(), 1); |
426 | 1 | assertTrue(groups.contains("AGroup")); |
427 | ||
428 | 1 | SequenceFeature sf2 = new SequenceFeature("Cath", "Desc", 10, 50, 0f, |
429 | null); | |
430 | 1 | sf.add(sf2); |
431 | 1 | groups = sf.getFeatureGroups(true); |
432 | 1 | assertEquals(groups.size(), 2); |
433 | 1 | assertTrue(groups.contains("PfamGroup")); |
434 | 1 | assertTrue(groups.contains(null)); |
435 | ||
436 | 1 | sf.delete(sf1); |
437 | 1 | sf.delete(sf2); |
438 | 1 | assertTrue(sf.getFeatureGroups(true).isEmpty()); |
439 | ||
440 | 1 | SequenceFeature sf3 = new SequenceFeature("CDS", "", 10, 50, 0f, |
441 | "Ensembl"); | |
442 | 1 | sf.add(sf3); |
443 | 1 | SequenceFeature sf4 = new SequenceFeature("exon", "", 10, 50, 0f, |
444 | "Ensembl"); | |
445 | 1 | sf.add(sf4); |
446 | 1 | groups = sf.getFeatureGroups(true); |
447 | 1 | assertEquals(groups.size(), 1); |
448 | 1 | assertTrue(groups.contains("Ensembl")); |
449 | ||
450 | /* | |
451 | * delete last Ensembl group feature from CDS features | |
452 | * but still have one in exon features | |
453 | */ | |
454 | 1 | sf.delete(sf3); |
455 | 1 | groups = sf.getFeatureGroups(true); |
456 | 1 | assertEquals(groups.size(), 1); |
457 | 1 | assertTrue(groups.contains("Ensembl")); |
458 | ||
459 | /* | |
460 | * delete the last non-positional feature | |
461 | */ | |
462 | 1 | sf.delete(sfx); |
463 | 1 | groups = sf.getFeatureGroups(false); |
464 | 1 | assertTrue(groups.isEmpty()); |
465 | } | |
466 | ||
467 | 1 | @Test(groups = "Functional") |
468 | public void testGetFeatureTypesForGroups() | |
469 | { | |
470 | 1 | SequenceFeaturesI sf = new SequenceFeatures(); |
471 | 1 | assertTrue(sf.getFeatureTypesForGroups(true, (String) null).isEmpty()); |
472 | ||
473 | /* | |
474 | * add feature with group = "Uniprot", type = "helix" | |
475 | */ | |
476 | 1 | String groupUniprot = "Uniprot"; |
477 | 1 | SequenceFeature sf1 = new SequenceFeature("helix", "Desc", 10, 50, 0f, |
478 | groupUniprot); | |
479 | 1 | sf.add(sf1); |
480 | 1 | Set<String> groups = sf.getFeatureTypesForGroups(true, groupUniprot); |
481 | 1 | assertEquals(groups.size(), 1); |
482 | 1 | assertTrue(groups.contains("helix")); |
483 | 1 | assertTrue(sf.getFeatureTypesForGroups(true, (String) null).isEmpty()); |
484 | ||
485 | /* | |
486 | * add feature with group = "Uniprot", type = "strand" | |
487 | */ | |
488 | 1 | SequenceFeature sf2 = new SequenceFeature("strand", "Desc", 10, 50, 0f, |
489 | groupUniprot); | |
490 | 1 | sf.add(sf2); |
491 | 1 | groups = sf.getFeatureTypesForGroups(true, groupUniprot); |
492 | 1 | assertEquals(groups.size(), 2); |
493 | 1 | assertTrue(groups.contains("helix")); |
494 | 1 | assertTrue(groups.contains("strand")); |
495 | ||
496 | /* | |
497 | * delete the "strand" Uniprot feature - still have "helix" | |
498 | */ | |
499 | 1 | sf.delete(sf2); |
500 | 1 | groups = sf.getFeatureTypesForGroups(true, groupUniprot); |
501 | 1 | assertEquals(groups.size(), 1); |
502 | 1 | assertTrue(groups.contains("helix")); |
503 | ||
504 | /* | |
505 | * delete the "helix" Uniprot feature - none left | |
506 | */ | |
507 | 1 | sf.delete(sf1); |
508 | 1 | assertTrue(sf.getFeatureTypesForGroups(true, groupUniprot).isEmpty()); |
509 | ||
510 | /* | |
511 | * add some null group features | |
512 | */ | |
513 | 1 | SequenceFeature sf3 = new SequenceFeature("strand", "Desc", 10, 50, 0f, |
514 | null); | |
515 | 1 | sf.add(sf3); |
516 | 1 | SequenceFeature sf4 = new SequenceFeature("turn", "Desc", 10, 50, 0f, |
517 | null); | |
518 | 1 | sf.add(sf4); |
519 | 1 | groups = sf.getFeatureTypesForGroups(true, (String) null); |
520 | 1 | assertEquals(groups.size(), 2); |
521 | 1 | assertTrue(groups.contains("strand")); |
522 | 1 | assertTrue(groups.contains("turn")); |
523 | ||
524 | /* | |
525 | * add strand/Cath and turn/Scop and query for one or both groups | |
526 | * (find feature types for groups selected in Feature Settings) | |
527 | */ | |
528 | 1 | SequenceFeature sf5 = new SequenceFeature("strand", "Desc", 10, 50, 0f, |
529 | "Cath"); | |
530 | 1 | sf.add(sf5); |
531 | 1 | SequenceFeature sf6 = new SequenceFeature("turn", "Desc", 10, 50, 0f, |
532 | "Scop"); | |
533 | 1 | sf.add(sf6); |
534 | 1 | groups = sf.getFeatureTypesForGroups(true, "Cath"); |
535 | 1 | assertEquals(groups.size(), 1); |
536 | 1 | assertTrue(groups.contains("strand")); |
537 | 1 | groups = sf.getFeatureTypesForGroups(true, "Scop"); |
538 | 1 | assertEquals(groups.size(), 1); |
539 | 1 | assertTrue(groups.contains("turn")); |
540 | 1 | groups = sf.getFeatureTypesForGroups(true, "Cath", "Scop"); |
541 | 1 | assertEquals(groups.size(), 2); |
542 | 1 | assertTrue(groups.contains("turn")); |
543 | 1 | assertTrue(groups.contains("strand")); |
544 | // alternative vararg syntax | |
545 | 1 | groups = sf.getFeatureTypesForGroups(true, |
546 | new String[] | |
547 | { "Cath", "Scop" }); | |
548 | 1 | assertEquals(groups.size(), 2); |
549 | 1 | assertTrue(groups.contains("turn")); |
550 | 1 | assertTrue(groups.contains("strand")); |
551 | } | |
552 | ||
553 | 1 | @Test(groups = "Functional") |
554 | public void testGetFeatureTypes() | |
555 | { | |
556 | 1 | SequenceFeaturesI store = new SequenceFeatures(); |
557 | 1 | Set<String> types = store.getFeatureTypes(); |
558 | 1 | assertTrue(types.isEmpty()); |
559 | ||
560 | 1 | SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20, |
561 | Float.NaN, null); | |
562 | 1 | store.add(sf1); |
563 | 1 | types = store.getFeatureTypes(); |
564 | 1 | assertEquals(types.size(), 1); |
565 | 1 | assertTrue(types.contains("Metal")); |
566 | ||
567 | // null type is rejected... | |
568 | 1 | SequenceFeature sf2 = new SequenceFeature(null, "desc", 10, 20, |
569 | Float.NaN, null); | |
570 | 1 | assertFalse(store.add(sf2)); |
571 | 1 | types = store.getFeatureTypes(); |
572 | 1 | assertEquals(types.size(), 1); |
573 | 1 | assertFalse(types.contains(null)); |
574 | 1 | assertTrue(types.contains("Metal")); |
575 | ||
576 | /* | |
577 | * add non-positional feature | |
578 | */ | |
579 | 1 | SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 0, 0, |
580 | Float.NaN, null); | |
581 | 1 | store.add(sf3); |
582 | 1 | types = store.getFeatureTypes(); |
583 | 1 | assertEquals(types.size(), 2); |
584 | 1 | assertTrue(types.contains("Pfam")); |
585 | ||
586 | /* | |
587 | * add contact feature | |
588 | */ | |
589 | 1 | SequenceFeature sf4 = new SequenceFeature("Disulphide Bond", "desc", 10, |
590 | 20, Float.NaN, null); | |
591 | 1 | store.add(sf4); |
592 | 1 | types = store.getFeatureTypes(); |
593 | 1 | assertEquals(types.size(), 3); |
594 | 1 | assertTrue(types.contains("Disulphide Bond")); |
595 | ||
596 | /* | |
597 | * add another Pfam | |
598 | */ | |
599 | 1 | SequenceFeature sf5 = new SequenceFeature("Pfam", "desc", 10, 20, |
600 | Float.NaN, null); | |
601 | 1 | store.add(sf5); |
602 | 1 | types = store.getFeatureTypes(); |
603 | 1 | assertEquals(types.size(), 3); // unchanged |
604 | ||
605 | /* | |
606 | * delete first Pfam - still have one | |
607 | */ | |
608 | 1 | assertTrue(store.delete(sf3)); |
609 | 1 | types = store.getFeatureTypes(); |
610 | 1 | assertEquals(types.size(), 3); |
611 | 1 | assertTrue(types.contains("Pfam")); |
612 | ||
613 | /* | |
614 | * delete second Pfam - no longer have one | |
615 | */ | |
616 | 1 | assertTrue(store.delete(sf5)); |
617 | 1 | types = store.getFeatureTypes(); |
618 | 1 | assertEquals(types.size(), 2); |
619 | 1 | assertFalse(types.contains("Pfam")); |
620 | } | |
621 | ||
622 | 1 | @Test(groups = "Functional") |
623 | public void testGetFeatureCount() | |
624 | { | |
625 | 1 | SequenceFeaturesI store = new SequenceFeatures(); |
626 | 1 | assertEquals(store.getFeatureCount(true), 0); |
627 | 1 | assertEquals(store.getFeatureCount(false), 0); |
628 | ||
629 | /* | |
630 | * add positional | |
631 | */ | |
632 | 1 | SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20, |
633 | Float.NaN, null); | |
634 | 1 | store.add(sf1); |
635 | 1 | assertEquals(store.getFeatureCount(true), 1); |
636 | 1 | assertEquals(store.getFeatureCount(false), 0); |
637 | ||
638 | /* | |
639 | * null feature type is rejected | |
640 | */ | |
641 | 1 | SequenceFeature sf2 = new SequenceFeature(null, "desc", 10, 20, |
642 | Float.NaN, null); | |
643 | 1 | assertFalse(store.add(sf2)); |
644 | 1 | assertEquals(store.getFeatureCount(true), 1); |
645 | 1 | assertEquals(store.getFeatureCount(false), 0); |
646 | ||
647 | /* | |
648 | * add non-positional feature | |
649 | */ | |
650 | 1 | SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 0, 0, |
651 | Float.NaN, null); | |
652 | 1 | store.add(sf3); |
653 | 1 | assertEquals(store.getFeatureCount(true), 1); |
654 | 1 | assertEquals(store.getFeatureCount(false), 1); |
655 | ||
656 | /* | |
657 | * add contact feature (counts as 1) | |
658 | */ | |
659 | 1 | SequenceFeature sf4 = new SequenceFeature("Disulphide Bond", "desc", 10, |
660 | 20, Float.NaN, null); | |
661 | 1 | store.add(sf4); |
662 | 1 | assertEquals(store.getFeatureCount(true), 2); |
663 | 1 | assertEquals(store.getFeatureCount(false), 1); |
664 | ||
665 | /* | |
666 | * add another Pfam but this time as a positional feature | |
667 | */ | |
668 | 1 | SequenceFeature sf5 = new SequenceFeature("Pfam", "desc", 10, 20, |
669 | Float.NaN, null); | |
670 | 1 | store.add(sf5); |
671 | 1 | assertEquals(store.getFeatureCount(true), 3); // sf1, sf4, sf5 |
672 | 1 | assertEquals(store.getFeatureCount(false), 1); // sf3 |
673 | 1 | assertEquals(store.getFeatureCount(true, "Pfam"), 1); // positional |
674 | 1 | assertEquals(store.getFeatureCount(false, "Pfam"), 1); // non-positional |
675 | // search for type==null | |
676 | 1 | assertEquals(store.getFeatureCount(true, (String) null), 0); |
677 | // search with no type specified | |
678 | 1 | assertEquals(store.getFeatureCount(true, (String[]) null), 3); |
679 | 1 | assertEquals(store.getFeatureCount(true, "Metal", "Cath"), 1); |
680 | 1 | assertEquals(store.getFeatureCount(true, "Disulphide Bond"), 1); |
681 | 1 | assertEquals(store.getFeatureCount(true, "Metal", "Pfam", null), 2); |
682 | ||
683 | /* | |
684 | * delete first Pfam (non-positional) | |
685 | */ | |
686 | 1 | assertTrue(store.delete(sf3)); |
687 | 1 | assertEquals(store.getFeatureCount(true), 3); |
688 | 1 | assertEquals(store.getFeatureCount(false), 0); |
689 | ||
690 | /* | |
691 | * delete second Pfam (positional) | |
692 | */ | |
693 | 1 | assertTrue(store.delete(sf5)); |
694 | 1 | assertEquals(store.getFeatureCount(true), 2); |
695 | 1 | assertEquals(store.getFeatureCount(false), 0); |
696 | } | |
697 | ||
698 | 1 | @Test(groups = "Functional") |
699 | public void testGetAllFeatures() | |
700 | { | |
701 | 1 | SequenceFeaturesI store = new SequenceFeatures(); |
702 | 1 | List<SequenceFeature> features = store.getAllFeatures(); |
703 | 1 | assertTrue(features.isEmpty()); |
704 | ||
705 | 1 | SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20, |
706 | Float.NaN, null); | |
707 | 1 | store.add(sf1); |
708 | 1 | features = store.getAllFeatures(); |
709 | 1 | assertEquals(features.size(), 1); |
710 | 1 | assertTrue(features.contains(sf1)); |
711 | ||
712 | 1 | SequenceFeature sf2 = new SequenceFeature("Metallic", "desc", 10, 20, |
713 | Float.NaN, null); | |
714 | 1 | store.add(sf2); |
715 | 1 | features = store.getAllFeatures(); |
716 | 1 | assertEquals(features.size(), 2); |
717 | 1 | assertTrue(features.contains(sf2)); |
718 | ||
719 | /* | |
720 | * add non-positional feature | |
721 | */ | |
722 | 1 | SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 0, 0, |
723 | Float.NaN, null); | |
724 | 1 | store.add(sf3); |
725 | 1 | features = store.getAllFeatures(); |
726 | 1 | assertEquals(features.size(), 3); |
727 | 1 | assertTrue(features.contains(sf3)); |
728 | ||
729 | /* | |
730 | * add contact feature | |
731 | */ | |
732 | 1 | SequenceFeature sf4 = new SequenceFeature("Disulphide Bond", "desc", 10, |
733 | 20, Float.NaN, null); | |
734 | 1 | store.add(sf4); |
735 | 1 | features = store.getAllFeatures(); |
736 | 1 | assertEquals(features.size(), 4); |
737 | 1 | assertTrue(features.contains(sf4)); |
738 | ||
739 | /* | |
740 | * add another Pfam | |
741 | */ | |
742 | 1 | SequenceFeature sf5 = new SequenceFeature("Pfam", "desc", 10, 20, |
743 | Float.NaN, null); | |
744 | 1 | store.add(sf5); |
745 | 1 | features = store.getAllFeatures(); |
746 | 1 | assertEquals(features.size(), 5); |
747 | 1 | assertTrue(features.contains(sf5)); |
748 | ||
749 | /* | |
750 | * select by type does not apply to non-positional features | |
751 | */ | |
752 | 1 | features = store.getAllFeatures("Cath"); |
753 | 1 | assertEquals(features.size(), 1); |
754 | 1 | assertTrue(features.contains(sf3)); |
755 | ||
756 | 1 | features = store.getAllFeatures("Pfam", "Cath", "Metal"); |
757 | 1 | assertEquals(features.size(), 3); |
758 | 1 | assertTrue(features.contains(sf1)); |
759 | 1 | assertTrue(features.contains(sf3)); |
760 | 1 | assertTrue(features.contains(sf5)); |
761 | ||
762 | /* | |
763 | * delete first Pfam | |
764 | */ | |
765 | 1 | assertTrue(store.delete(sf3)); |
766 | 1 | features = store.getAllFeatures(); |
767 | 1 | assertEquals(features.size(), 4); |
768 | 1 | assertFalse(features.contains(sf3)); |
769 | ||
770 | /* | |
771 | * delete second Pfam | |
772 | */ | |
773 | 1 | assertTrue(store.delete(sf5)); |
774 | 1 | features = store.getAllFeatures(); |
775 | 1 | assertEquals(features.size(), 3); |
776 | 1 | assertFalse(features.contains(sf3)); |
777 | } | |
778 | ||
779 | 1 | @Test(groups = "Functional") |
780 | public void testGetTotalFeatureLength() | |
781 | { | |
782 | 1 | SequenceFeaturesI store = new SequenceFeatures(); |
783 | 1 | assertEquals(store.getTotalFeatureLength(), 0); |
784 | ||
785 | 1 | SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20, |
786 | Float.NaN, null); | |
787 | 1 | assertTrue(store.add(sf1)); |
788 | 1 | assertEquals(store.getTotalFeatureLength(), 11); |
789 | 1 | assertEquals(store.getTotalFeatureLength("Metal"), 11); |
790 | 1 | assertEquals(store.getTotalFeatureLength("Plastic"), 0); |
791 | ||
792 | // re-add does nothing! | |
793 | 1 | assertFalse(store.add(sf1)); |
794 | 1 | assertEquals(store.getTotalFeatureLength(), 11); |
795 | ||
796 | /* | |
797 | * add non-positional feature | |
798 | */ | |
799 | 1 | SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 0, 0, |
800 | Float.NaN, null); | |
801 | 1 | store.add(sf3); |
802 | 1 | assertEquals(store.getTotalFeatureLength(), 11); |
803 | ||
804 | /* | |
805 | * add contact feature - counts 1 to feature length | |
806 | */ | |
807 | 1 | SequenceFeature sf4 = new SequenceFeature("Disulphide Bond", "desc", 10, |
808 | 20, Float.NaN, null); | |
809 | 1 | store.add(sf4); |
810 | 1 | assertEquals(store.getTotalFeatureLength(), 12); |
811 | ||
812 | /* | |
813 | * add another Pfam | |
814 | */ | |
815 | 1 | SequenceFeature sf5 = new SequenceFeature("Pfam", "desc", 10, 20, |
816 | Float.NaN, null); | |
817 | 1 | store.add(sf5); |
818 | 1 | assertEquals(store.getTotalFeatureLength(), 23); |
819 | ||
820 | /* | |
821 | * delete features | |
822 | */ | |
823 | 1 | assertTrue(store.delete(sf3)); // non-positional |
824 | 1 | assertEquals(store.getTotalFeatureLength(), 23); // no change |
825 | ||
826 | 1 | assertTrue(store.delete(sf5)); |
827 | 1 | assertEquals(store.getTotalFeatureLength(), 12); |
828 | ||
829 | 1 | assertTrue(store.delete(sf4)); // contact |
830 | 1 | assertEquals(store.getTotalFeatureLength(), 11); |
831 | ||
832 | 1 | assertTrue(store.delete(sf1)); |
833 | 1 | assertEquals(store.getTotalFeatureLength(), 0); |
834 | } | |
835 | ||
836 | 1 | @Test(groups = "Functional") |
837 | public void testGetMinimumScore_getMaximumScore() | |
838 | { | |
839 | 1 | SequenceFeatures sf = new SequenceFeatures(); |
840 | 1 | SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 0, 0, |
841 | Float.NaN, "group"); // non-positional, no score | |
842 | 1 | sf.add(sf1); |
843 | 1 | SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 10, 20, |
844 | Float.NaN, "group"); // positional, no score | |
845 | 1 | sf.add(sf2); |
846 | 1 | SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 10, 20, 1f, |
847 | "group"); | |
848 | 1 | sf.add(sf3); |
849 | 1 | SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 12, 16, 4f, |
850 | "group"); | |
851 | 1 | sf.add(sf4); |
852 | 1 | SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 0, 0, 11f, |
853 | "group"); | |
854 | 1 | sf.add(sf5); |
855 | 1 | SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, -7f, |
856 | "group"); | |
857 | 1 | sf.add(sf6); |
858 | ||
859 | 1 | assertEquals(sf.getMinimumScore("nosuchtype", true), Float.NaN); |
860 | 1 | assertEquals(sf.getMinimumScore("nosuchtype", false), Float.NaN); |
861 | 1 | assertEquals(sf.getMaximumScore("nosuchtype", true), Float.NaN); |
862 | 1 | assertEquals(sf.getMaximumScore("nosuchtype", false), Float.NaN); |
863 | ||
864 | // positional features min-max: | |
865 | 1 | assertEquals(sf.getMinimumScore("Metal", true), 1f); |
866 | 1 | assertEquals(sf.getMaximumScore("Metal", true), 4f); |
867 | 1 | assertEquals(sf.getMinimumScore("Cath", true), Float.NaN); |
868 | 1 | assertEquals(sf.getMaximumScore("Cath", true), Float.NaN); |
869 | ||
870 | // non-positional features min-max: | |
871 | 1 | assertEquals(sf.getMinimumScore("Cath", false), -7f); |
872 | 1 | assertEquals(sf.getMaximumScore("Cath", false), 11f); |
873 | 1 | assertEquals(sf.getMinimumScore("Metal", false), Float.NaN); |
874 | 1 | assertEquals(sf.getMaximumScore("Metal", false), Float.NaN); |
875 | ||
876 | // delete features; min-max should get recomputed | |
877 | 1 | sf.delete(sf6); |
878 | 1 | assertEquals(sf.getMinimumScore("Cath", false), 11f); |
879 | 1 | assertEquals(sf.getMaximumScore("Cath", false), 11f); |
880 | 1 | sf.delete(sf4); |
881 | 1 | assertEquals(sf.getMinimumScore("Metal", true), 1f); |
882 | 1 | assertEquals(sf.getMaximumScore("Metal", true), 1f); |
883 | 1 | sf.delete(sf5); |
884 | 1 | assertEquals(sf.getMinimumScore("Cath", false), Float.NaN); |
885 | 1 | assertEquals(sf.getMaximumScore("Cath", false), Float.NaN); |
886 | 1 | sf.delete(sf3); |
887 | 1 | assertEquals(sf.getMinimumScore("Metal", true), Float.NaN); |
888 | 1 | assertEquals(sf.getMaximumScore("Metal", true), Float.NaN); |
889 | 1 | sf.delete(sf1); |
890 | 1 | sf.delete(sf2); |
891 | 1 | assertFalse(sf.hasFeatures()); |
892 | 1 | assertEquals(sf.getMinimumScore("Cath", false), Float.NaN); |
893 | 1 | assertEquals(sf.getMaximumScore("Cath", false), Float.NaN); |
894 | 1 | assertEquals(sf.getMinimumScore("Metal", true), Float.NaN); |
895 | 1 | assertEquals(sf.getMaximumScore("Metal", true), Float.NaN); |
896 | } | |
897 | ||
898 | 1 | @Test(groups = "Functional") |
899 | public void testVarargsToTypes() | |
900 | { | |
901 | 1 | SequenceFeatures sf = new SequenceFeatures(); |
902 | 1 | sf.add(new SequenceFeature("Metal", "desc", 0, 0, Float.NaN, "group")); |
903 | 1 | sf.add(new SequenceFeature("Cath", "desc", 10, 20, Float.NaN, "group")); |
904 | ||
905 | /* | |
906 | * no type specified - get all types stored | |
907 | * they are returned in keyset (alphabetical) order | |
908 | */ | |
909 | 1 | Map<String, FeatureStore> featureStores = (Map<String, FeatureStore>) PA |
910 | .getValue(sf, "featureStore"); | |
911 | ||
912 | 1 | Iterable<FeatureStore> types = sf.varargToTypes(); |
913 | 1 | Iterator<FeatureStore> iterator = types.iterator(); |
914 | 1 | assertTrue(iterator.hasNext()); |
915 | 1 | assertSame(iterator.next(), featureStores.get("Cath")); |
916 | 1 | assertTrue(iterator.hasNext()); |
917 | 1 | assertSame(iterator.next(), featureStores.get("Metal")); |
918 | 1 | assertFalse(iterator.hasNext()); |
919 | ||
920 | /* | |
921 | * empty array is the same as no vararg parameter supplied | |
922 | * so treated as all stored types | |
923 | */ | |
924 | 1 | types = sf.varargToTypes(new String[] {}); |
925 | 1 | iterator = types.iterator(); |
926 | 1 | assertTrue(iterator.hasNext()); |
927 | 1 | assertSame(iterator.next(), featureStores.get("Cath")); |
928 | 1 | assertTrue(iterator.hasNext()); |
929 | 1 | assertSame(iterator.next(), featureStores.get("Metal")); |
930 | 1 | assertFalse(iterator.hasNext()); |
931 | ||
932 | /* | |
933 | * null type specified; this is passed as vararg | |
934 | * String[1] {null} | |
935 | */ | |
936 | 1 | types = sf.varargToTypes((String) null); |
937 | 1 | assertFalse(types.iterator().hasNext()); |
938 | ||
939 | /* | |
940 | * null types array specified; this is passed as vararg null | |
941 | */ | |
942 | 1 | types = sf.varargToTypes((String[]) null); |
943 | 1 | iterator = types.iterator(); |
944 | 1 | assertTrue(iterator.hasNext()); |
945 | 1 | assertSame(iterator.next(), featureStores.get("Cath")); |
946 | 1 | assertTrue(iterator.hasNext()); |
947 | 1 | assertSame(iterator.next(), featureStores.get("Metal")); |
948 | 1 | assertFalse(iterator.hasNext()); |
949 | ||
950 | /* | |
951 | * one type specified | |
952 | */ | |
953 | 1 | types = sf.varargToTypes("Metal"); |
954 | 1 | iterator = types.iterator(); |
955 | 1 | assertTrue(iterator.hasNext()); |
956 | 1 | assertSame(iterator.next(), featureStores.get("Metal")); |
957 | 1 | assertFalse(iterator.hasNext()); |
958 | ||
959 | /* | |
960 | * two types specified - order is preserved | |
961 | */ | |
962 | 1 | types = sf.varargToTypes("Metal", "Cath"); |
963 | 1 | iterator = types.iterator(); |
964 | 1 | assertTrue(iterator.hasNext()); |
965 | 1 | assertSame(iterator.next(), featureStores.get("Metal")); |
966 | 1 | assertTrue(iterator.hasNext()); |
967 | 1 | assertSame(iterator.next(), featureStores.get("Cath")); |
968 | 1 | assertFalse(iterator.hasNext()); |
969 | ||
970 | /* | |
971 | * null type included - should be ignored | |
972 | */ | |
973 | 1 | types = sf.varargToTypes("Metal", null, "Helix"); |
974 | 1 | iterator = types.iterator(); |
975 | 1 | assertTrue(iterator.hasNext()); |
976 | 1 | assertSame(iterator.next(), featureStores.get("Metal")); |
977 | 1 | assertFalse(iterator.hasNext()); |
978 | } | |
979 | ||
980 | 1 | @Test(groups = "Functional") |
981 | public void testGetFeatureTypes_byOntology() | |
982 | { | |
983 | 1 | SequenceFeaturesI store = new SequenceFeatures(); |
984 | ||
985 | 1 | SequenceFeature sf1 = new SequenceFeature("transcript", "desc", 10, 20, |
986 | Float.NaN, null); | |
987 | 1 | store.add(sf1); |
988 | // mRNA isA mature_transcript isA transcript | |
989 | 1 | SequenceFeature sf2 = new SequenceFeature("mRNA", "desc", 10, 20, |
990 | Float.NaN, null); | |
991 | 1 | store.add(sf2); |
992 | // just to prove non-positional feature types are included | |
993 | 1 | SequenceFeature sf3 = new SequenceFeature("mRNA", "desc", 0, 0, |
994 | Float.NaN, null); | |
995 | 1 | store.add(sf3); |
996 | 1 | SequenceFeature sf4 = new SequenceFeature("CDS", "desc", 0, 0, |
997 | Float.NaN, null); | |
998 | 1 | store.add(sf4); |
999 | ||
1000 | 1 | Set<String> types = store.getFeatureTypes("transcript"); |
1001 | 1 | assertEquals(types.size(), 2); |
1002 | 1 | assertTrue(types.contains("transcript")); |
1003 | 1 | assertTrue(types.contains("mRNA")); |
1004 | ||
1005 | // matches include arguments whether SO terms or not | |
1006 | 1 | types = store.getFeatureTypes("transcript", "CDS"); |
1007 | 1 | assertEquals(types.size(), 3); |
1008 | 1 | assertTrue(types.contains("transcript")); |
1009 | 1 | assertTrue(types.contains("mRNA")); |
1010 | 1 | assertTrue(types.contains("CDS")); |
1011 | ||
1012 | 1 | types = store.getFeatureTypes("exon"); |
1013 | 1 | assertTrue(types.isEmpty()); |
1014 | } | |
1015 | ||
1016 | 1 | @Test(groups = "Functional") |
1017 | public void testGetFeaturesByOntology() | |
1018 | { | |
1019 | 1 | SequenceFeaturesI store = new SequenceFeatures(); |
1020 | 1 | List<SequenceFeature> features = store.getFeaturesByOntology(); |
1021 | 1 | assertTrue(features.isEmpty()); |
1022 | 1 | assertTrue(store.getFeaturesByOntology(new String[] {}).isEmpty()); |
1023 | 1 | assertTrue(store.getFeaturesByOntology((String[]) null).isEmpty()); |
1024 | ||
1025 | 1 | SequenceFeature transcriptFeature = new SequenceFeature("transcript", |
1026 | "desc", 10, 20, Float.NaN, null); | |
1027 | 1 | store.add(transcriptFeature); |
1028 | ||
1029 | /* | |
1030 | * mRNA is a sub-type of transcript; added here 'as if' non-positional | |
1031 | * just to show that non-positional features are included in results | |
1032 | */ | |
1033 | 1 | SequenceFeature mrnaFeature = new SequenceFeature("mRNA", "desc", 0, 0, |
1034 | Float.NaN, null); | |
1035 | 1 | store.add(mrnaFeature); |
1036 | ||
1037 | 1 | SequenceFeature pfamFeature = new SequenceFeature("Pfam", "desc", 30, |
1038 | 40, Float.NaN, null); | |
1039 | 1 | store.add(pfamFeature); |
1040 | ||
1041 | /* | |
1042 | * "transcript" matches both itself and the sub-term "mRNA" | |
1043 | */ | |
1044 | 1 | features = store.getFeaturesByOntology("transcript"); |
1045 | 1 | assertEquals(features.size(), 2); |
1046 | 1 | assertTrue(features.contains(transcriptFeature)); |
1047 | 1 | assertTrue(features.contains(mrnaFeature)); |
1048 | ||
1049 | /* | |
1050 | * "mRNA" matches itself but not parent term "transcript" | |
1051 | */ | |
1052 | 1 | features = store.getFeaturesByOntology("mRNA"); |
1053 | 1 | assertEquals(features.size(), 1); |
1054 | 1 | assertTrue(features.contains(mrnaFeature)); |
1055 | ||
1056 | /* | |
1057 | * "pfam" is not an SO term but is included as an exact match | |
1058 | */ | |
1059 | 1 | features = store.getFeaturesByOntology("mRNA", "Pfam"); |
1060 | 1 | assertEquals(features.size(), 2); |
1061 | 1 | assertTrue(features.contains(mrnaFeature)); |
1062 | 1 | assertTrue(features.contains(pfamFeature)); |
1063 | ||
1064 | 1 | features = store.getFeaturesByOntology("sequence_variant"); |
1065 | 1 | assertTrue(features.isEmpty()); |
1066 | } | |
1067 | ||
1068 | 1 | @Test(groups = "Functional") |
1069 | public void testSortFeatures() | |
1070 | { | |
1071 | 1 | List<SequenceFeature> sfs = new ArrayList<>(); |
1072 | 1 | SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 30, 60, |
1073 | Float.NaN, null); | |
1074 | 1 | sfs.add(sf1); |
1075 | 1 | SequenceFeature sf2 = new SequenceFeature("Rfam", "desc", 40, 50, |
1076 | Float.NaN, null); | |
1077 | 1 | sfs.add(sf2); |
1078 | 1 | SequenceFeature sf3 = new SequenceFeature("Rfam", "desc", 50, 60, |
1079 | Float.NaN, null); | |
1080 | 1 | sfs.add(sf3); |
1081 | 1 | SequenceFeature sf4 = new SequenceFeature("Xfam", "desc", 30, 80, |
1082 | Float.NaN, null); | |
1083 | 1 | sfs.add(sf4); |
1084 | 1 | SequenceFeature sf5 = new SequenceFeature("Xfam", "desc", 30, 90, |
1085 | Float.NaN, null); | |
1086 | 1 | sfs.add(sf5); |
1087 | ||
1088 | /* | |
1089 | * sort by end position descending, order unchanged if matched | |
1090 | */ | |
1091 | 1 | SequenceFeatures.sortFeatures(sfs, false); |
1092 | 1 | assertSame(sfs.get(0), sf5); // end 90 |
1093 | 1 | assertSame(sfs.get(1), sf4); // end 80 |
1094 | 1 | assertSame(sfs.get(2), sf1); // end 60, start 50 |
1095 | 1 | assertSame(sfs.get(3), sf3); // end 60, start 30 |
1096 | 1 | assertSame(sfs.get(4), sf2); // end 50 |
1097 | ||
1098 | /* | |
1099 | * resort {5, 4, 1, 3, 2} by start position ascending, end descending | |
1100 | */ | |
1101 | 1 | SequenceFeatures.sortFeatures(sfs, true); |
1102 | 1 | assertSame(sfs.get(0), sf5); // start 30, end 90 |
1103 | 1 | assertSame(sfs.get(1), sf4); // start 30, end 80 |
1104 | 1 | assertSame(sfs.get(2), sf1); // start 30, end 60 |
1105 | 1 | assertSame(sfs.get(3), sf2); // start 40 |
1106 | 1 | assertSame(sfs.get(4), sf3); // start 50 |
1107 | } | |
1108 | ||
1109 | 1 | @Test(groups = "Functional") |
1110 | public void testGetFeaturesForGroup() | |
1111 | { | |
1112 | 1 | SequenceFeaturesI store = new SequenceFeatures(); |
1113 | ||
1114 | 1 | List<SequenceFeature> features = store.getFeaturesForGroup(true, null); |
1115 | 1 | assertTrue(features.isEmpty()); |
1116 | 1 | assertTrue(store.getFeaturesForGroup(false, null).isEmpty()); |
1117 | 1 | assertTrue(store.getFeaturesForGroup(true, "Uniprot").isEmpty()); |
1118 | 1 | assertTrue(store.getFeaturesForGroup(false, "Uniprot").isEmpty()); |
1119 | ||
1120 | 1 | SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f, |
1121 | null); | |
1122 | 1 | SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f, |
1123 | null); | |
1124 | 1 | SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f, |
1125 | "Uniprot"); | |
1126 | 1 | SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 0, 0, 0f, |
1127 | "Rfam"); | |
1128 | 1 | SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 5, 15, 0f, |
1129 | null); | |
1130 | 1 | store.add(sf1); |
1131 | 1 | store.add(sf2); |
1132 | 1 | store.add(sf3); |
1133 | 1 | store.add(sf4); |
1134 | 1 | store.add(sf5); |
1135 | ||
1136 | // positional features for null group, any type | |
1137 | 1 | features = store.getFeaturesForGroup(true, null); |
1138 | 1 | assertEquals(features.size(), 2); |
1139 | 1 | assertTrue(features.contains(sf1)); |
1140 | 1 | assertTrue(features.contains(sf5)); |
1141 | ||
1142 | // positional features for null group, specified type | |
1143 | 1 | features = store.getFeaturesForGroup(true, null, |
1144 | new String[] | |
1145 | { "Pfam", "Xfam" }); | |
1146 | 1 | assertEquals(features.size(), 1); |
1147 | 1 | assertTrue(features.contains(sf1)); |
1148 | 1 | features = store.getFeaturesForGroup(true, null, |
1149 | new String[] | |
1150 | { "Pfam", "Xfam", "Cath" }); | |
1151 | 1 | assertEquals(features.size(), 2); |
1152 | 1 | assertTrue(features.contains(sf1)); |
1153 | 1 | assertTrue(features.contains(sf5)); |
1154 | ||
1155 | // positional features for non-null group, any type | |
1156 | 1 | features = store.getFeaturesForGroup(true, "Uniprot"); |
1157 | 1 | assertEquals(features.size(), 1); |
1158 | 1 | assertTrue(features.contains(sf3)); |
1159 | 1 | assertTrue(store.getFeaturesForGroup(true, "Rfam").isEmpty()); |
1160 | ||
1161 | // positional features for non-null group, specified type | |
1162 | 1 | features = store.getFeaturesForGroup(true, "Uniprot", "Pfam", "Xfam", |
1163 | "Rfam"); | |
1164 | 1 | assertEquals(features.size(), 1); |
1165 | 1 | assertTrue(features.contains(sf3)); |
1166 | 1 | assertTrue( |
1167 | store.getFeaturesForGroup(true, "Uniprot", "Cath").isEmpty()); | |
1168 | ||
1169 | // non-positional features for null group, any type | |
1170 | 1 | features = store.getFeaturesForGroup(false, null); |
1171 | 1 | assertEquals(features.size(), 1); |
1172 | 1 | assertTrue(features.contains(sf2)); |
1173 | ||
1174 | // non-positional features for null group, specified type | |
1175 | 1 | features = store.getFeaturesForGroup(false, null, "Pfam", "Xfam"); |
1176 | 1 | assertEquals(features.size(), 1); |
1177 | 1 | assertTrue(features.contains(sf2)); |
1178 | 1 | assertTrue(store.getFeaturesForGroup(false, null, "Cath").isEmpty()); |
1179 | ||
1180 | // non-positional features for non-null group, any type | |
1181 | 1 | features = store.getFeaturesForGroup(false, "Rfam"); |
1182 | 1 | assertEquals(features.size(), 1); |
1183 | 1 | assertTrue(features.contains(sf4)); |
1184 | 1 | assertTrue(store.getFeaturesForGroup(false, "Uniprot").isEmpty()); |
1185 | ||
1186 | // non-positional features for non-null group, specified type | |
1187 | 1 | features = store.getFeaturesForGroup(false, "Rfam", "Pfam", "Metal"); |
1188 | 1 | assertEquals(features.size(), 1); |
1189 | 1 | assertTrue(features.contains(sf4)); |
1190 | 1 | assertTrue(store.getFeaturesForGroup(false, "Rfam", "Cath", "Pfam") |
1191 | .isEmpty()); | |
1192 | } | |
1193 | ||
1194 | 1 | @Test(groups = "Functional") |
1195 | public void testShiftFeatures() | |
1196 | { | |
1197 | 1 | SequenceFeatures store = new SequenceFeatures(); |
1198 | 1 | assertFalse(store.shiftFeatures(0, 1)); |
1199 | ||
1200 | 1 | SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null); |
1201 | 1 | store.add(sf1); |
1202 | // nested feature: | |
1203 | 1 | SequenceFeature sf2 = new SequenceFeature("Metal", "", 8, 14, 0f, null); |
1204 | 1 | store.add(sf2); |
1205 | // contact feature: | |
1206 | 1 | SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32, |
1207 | 0f, null); | |
1208 | 1 | store.add(sf3); |
1209 | // non-positional feature: | |
1210 | 1 | SequenceFeature sf4 = new SequenceFeature("Pfam", "", 0, 0, 0f, null); |
1211 | 1 | store.add(sf4); |
1212 | ||
1213 | /* | |
1214 | * shift features right by 5 | |
1215 | */ | |
1216 | 1 | assertTrue(store.shiftFeatures(0, 5)); |
1217 | ||
1218 | // non-positional features untouched: | |
1219 | 1 | List<SequenceFeature> nonPos = store.getNonPositionalFeatures(); |
1220 | 1 | assertEquals(nonPos.size(), 1); |
1221 | 1 | assertTrue(nonPos.contains(sf4)); |
1222 | ||
1223 | // positional features are replaced | |
1224 | 1 | List<SequenceFeature> pos = store.getPositionalFeatures(); |
1225 | 1 | assertEquals(pos.size(), 3); |
1226 | 1 | assertFalse(pos.contains(sf1)); |
1227 | 1 | assertFalse(pos.contains(sf2)); |
1228 | 1 | assertFalse(pos.contains(sf3)); |
1229 | 1 | SequenceFeatures.sortFeatures(pos, true); // ascending start pos |
1230 | 1 | assertEquals(pos.get(0).getBegin(), 7); |
1231 | 1 | assertEquals(pos.get(0).getEnd(), 10); |
1232 | 1 | assertEquals(pos.get(0).getType(), "Cath"); |
1233 | 1 | assertEquals(pos.get(1).getBegin(), 13); |
1234 | 1 | assertEquals(pos.get(1).getEnd(), 19); |
1235 | 1 | assertEquals(pos.get(1).getType(), "Metal"); |
1236 | 1 | assertEquals(pos.get(2).getBegin(), 28); |
1237 | 1 | assertEquals(pos.get(2).getEnd(), 37); |
1238 | 1 | assertEquals(pos.get(2).getType(), "Disulfide bond"); |
1239 | ||
1240 | /* | |
1241 | * now shift left by 15 | |
1242 | * feature at [7-10] should be removed | |
1243 | * feature at [13-19] should become [1-4] | |
1244 | */ | |
1245 | 1 | assertTrue(store.shiftFeatures(0, -15)); |
1246 | 1 | pos = store.getPositionalFeatures(); |
1247 | 1 | assertEquals(pos.size(), 2); |
1248 | 1 | SequenceFeatures.sortFeatures(pos, true); |
1249 | 1 | assertEquals(pos.get(0).getBegin(), 1); |
1250 | 1 | assertEquals(pos.get(0).getEnd(), 4); |
1251 | 1 | assertEquals(pos.get(0).getType(), "Metal"); |
1252 | 1 | assertEquals(pos.get(1).getBegin(), 13); |
1253 | 1 | assertEquals(pos.get(1).getEnd(), 22); |
1254 | 1 | assertEquals(pos.get(1).getType(), "Disulfide bond"); |
1255 | ||
1256 | /* | |
1257 | * shift right by 4 from column 2 | |
1258 | * feature at [1-4] should be unchanged | |
1259 | * feature at [13-22] should become [17-26] | |
1260 | */ | |
1261 | 1 | assertTrue(store.shiftFeatures(2, 4)); |
1262 | 1 | pos = store.getPositionalFeatures(); |
1263 | 1 | assertEquals(pos.size(), 2); |
1264 | 1 | SequenceFeatures.sortFeatures(pos, true); |
1265 | 1 | assertEquals(pos.get(0).getBegin(), 1); |
1266 | 1 | assertEquals(pos.get(0).getEnd(), 4); |
1267 | 1 | assertEquals(pos.get(0).getType(), "Metal"); |
1268 | 1 | assertEquals(pos.get(1).getBegin(), 17); |
1269 | 1 | assertEquals(pos.get(1).getEnd(), 26); |
1270 | 1 | assertEquals(pos.get(1).getType(), "Disulfide bond"); |
1271 | ||
1272 | /* | |
1273 | * shift right from column 18 | |
1274 | * should be no updates | |
1275 | */ | |
1276 | 1 | SequenceFeature f1 = pos.get(0); |
1277 | 1 | SequenceFeature f2 = pos.get(1); |
1278 | 1 | assertFalse(store.shiftFeatures(18, 6)); |
1279 | 1 | pos = store.getPositionalFeatures(); |
1280 | 1 | assertEquals(pos.size(), 2); |
1281 | 1 | SequenceFeatures.sortFeatures(pos, true); |
1282 | 1 | assertSame(pos.get(0), f1); |
1283 | 1 | assertSame(pos.get(1), f2); |
1284 | } | |
1285 | ||
1286 | 1 | @Test(groups = "Functional") |
1287 | public void testIsOntologyTerm() | |
1288 | { | |
1289 | 1 | SequenceFeatures store = new SequenceFeatures(); |
1290 | 1 | assertTrue(store.isOntologyTerm("gobbledygook")); |
1291 | 1 | assertTrue(store.isOntologyTerm("transcript", "transcript")); |
1292 | 1 | assertTrue(store.isOntologyTerm("mRNA", "transcript")); |
1293 | 1 | assertFalse(store.isOntologyTerm("transcript", "mRNA")); |
1294 | 1 | assertTrue(store.isOntologyTerm("junk", "transcript", "junk")); |
1295 | 1 | assertTrue(store.isOntologyTerm("junk", new String[] {})); |
1296 | 1 | assertTrue(store.isOntologyTerm("junk", (String[]) null)); |
1297 | } | |
1298 | ||
1299 | 1 | @Test(groups = "Functional") |
1300 | public void testDeleteAll() | |
1301 | { | |
1302 | 1 | SequenceFeaturesI store = new SequenceFeatures(); |
1303 | 1 | assertFalse(store.hasFeatures()); |
1304 | 1 | store.deleteAll(); |
1305 | 1 | assertFalse(store.hasFeatures()); |
1306 | 1 | store.add(new SequenceFeature("Cath", "Desc", 12, 20, 0f, "Group")); |
1307 | 1 | store.add(new SequenceFeature("Pfam", "Desc", 6, 12, 2f, "Group2")); |
1308 | 1 | assertTrue(store.hasFeatures()); |
1309 | 1 | store.deleteAll(); |
1310 | 1 | assertFalse(store.hasFeatures()); |
1311 | } | |
1312 | } |