1 package jalview.datamodel.features;
3 import static org.testng.Assert.assertEquals;
4 import static org.testng.Assert.assertFalse;
5 import static org.testng.Assert.assertTrue;
7 import jalview.datamodel.SequenceFeature;
9 import java.util.ArrayList;
10 import java.util.List;
13 import org.testng.annotations.Test;
15 public class FeatureStoreTest
18 @Test(groups = "Functional")
19 public void testFindFeatures_nonNested()
21 FeatureStore fs = new FeatureStore();
22 fs.addFeature(new SequenceFeature("", "", 10, 20, Float.NaN,
24 // same range different description
25 fs.addFeature(new SequenceFeature("", "desc", 10, 20, Float.NaN, null));
26 fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
27 fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
29 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
30 assertTrue(overlaps.isEmpty());
32 overlaps = fs.findOverlappingFeatures(8, 10);
33 assertEquals(overlaps.size(), 2);
34 assertEquals(overlaps.get(0).getEnd(), 20);
35 assertEquals(overlaps.get(1).getEnd(), 20);
37 overlaps = fs.findOverlappingFeatures(12, 16);
38 assertEquals(overlaps.size(), 3);
39 assertEquals(overlaps.get(0).getEnd(), 20);
40 assertEquals(overlaps.get(1).getEnd(), 20);
41 assertEquals(overlaps.get(2).getEnd(), 25);
43 overlaps = fs.findOverlappingFeatures(33, 33);
44 assertEquals(overlaps.size(), 1);
45 assertEquals(overlaps.get(0).getEnd(), 35);
48 @Test(groups = "Functional")
49 public void testFindFeatures_nested()
51 FeatureStore fs = new FeatureStore();
52 SequenceFeature sf1 = addFeature(fs, 10, 50);
53 SequenceFeature sf2 = addFeature(fs, 10, 40);
54 SequenceFeature sf3 = addFeature(fs, 20, 30);
55 // fudge feature at same location but different group (so is added)
56 SequenceFeature sf4 = new SequenceFeature("", "", 20, 30, Float.NaN,
59 SequenceFeature sf5 = addFeature(fs, 35, 36);
61 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
62 assertTrue(overlaps.isEmpty());
64 overlaps = fs.findOverlappingFeatures(10, 15);
65 assertEquals(overlaps.size(), 2);
66 assertTrue(overlaps.contains(sf1));
67 assertTrue(overlaps.contains(sf2));
69 overlaps = fs.findOverlappingFeatures(45, 60);
70 assertEquals(overlaps.size(), 1);
71 assertTrue(overlaps.contains(sf1));
73 overlaps = fs.findOverlappingFeatures(32, 38);
74 assertEquals(overlaps.size(), 3);
75 assertTrue(overlaps.contains(sf1));
76 assertTrue(overlaps.contains(sf2));
77 assertTrue(overlaps.contains(sf5));
79 overlaps = fs.findOverlappingFeatures(15, 25);
80 assertEquals(overlaps.size(), 4);
81 assertTrue(overlaps.contains(sf1));
82 assertTrue(overlaps.contains(sf2));
83 assertTrue(overlaps.contains(sf3));
84 assertTrue(overlaps.contains(sf4));
87 @Test(groups = "Functional")
88 public void testFindFeatures_mixed()
90 FeatureStore fs = new FeatureStore();
91 SequenceFeature sf1 = addFeature(fs, 10, 50);
92 SequenceFeature sf2 = addFeature(fs, 1, 15);
93 SequenceFeature sf3 = addFeature(fs, 20, 30);
94 SequenceFeature sf4 = addFeature(fs, 40, 100);
95 SequenceFeature sf5 = addFeature(fs, 60, 100);
96 SequenceFeature sf6 = addFeature(fs, 70, 70);
98 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
99 assertTrue(overlaps.isEmpty());
101 overlaps = fs.findOverlappingFeatures(1, 9);
102 assertEquals(overlaps.size(), 1);
103 assertTrue(overlaps.contains(sf2));
105 overlaps = fs.findOverlappingFeatures(5, 18);
106 assertEquals(overlaps.size(), 2);
107 assertTrue(overlaps.contains(sf1));
108 assertTrue(overlaps.contains(sf2));
110 overlaps = fs.findOverlappingFeatures(30, 40);
111 assertEquals(overlaps.size(), 3);
112 assertTrue(overlaps.contains(sf1));
113 assertTrue(overlaps.contains(sf3));
114 assertTrue(overlaps.contains(sf4));
116 overlaps = fs.findOverlappingFeatures(80, 90);
117 assertEquals(overlaps.size(), 2);
118 assertTrue(overlaps.contains(sf4));
119 assertTrue(overlaps.contains(sf5));
121 overlaps = fs.findOverlappingFeatures(68, 70);
122 assertEquals(overlaps.size(), 3);
123 assertTrue(overlaps.contains(sf4));
124 assertTrue(overlaps.contains(sf5));
125 assertTrue(overlaps.contains(sf6));
129 * Helper method to add a feature of no particular type
136 SequenceFeature addFeature(FeatureStore fs, int from, int to)
138 SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN,
144 @Test(groups = "Functional")
145 public void testFindFeatures_contactFeatures()
147 FeatureStore fs = new FeatureStore();
149 SequenceFeature sf = new SequenceFeature("disulphide bond", "bond", 10,
150 20, Float.NaN, null);
154 * neither contact point in range
156 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
157 assertTrue(overlaps.isEmpty());
160 * neither contact point in range
162 overlaps = fs.findOverlappingFeatures(11, 19);
163 assertTrue(overlaps.isEmpty());
166 * first contact point in range
168 overlaps = fs.findOverlappingFeatures(5, 15);
169 assertEquals(overlaps.size(), 1);
170 assertTrue(overlaps.contains(sf));
173 * second contact point in range
175 overlaps = fs.findOverlappingFeatures(15, 25);
176 assertEquals(overlaps.size(), 1);
177 assertTrue(overlaps.contains(sf));
180 * both contact points in range
182 overlaps = fs.findOverlappingFeatures(5, 25);
183 assertEquals(overlaps.size(), 1);
184 assertTrue(overlaps.contains(sf));
187 @Test(groups = "Functional")
188 public void testGetPositionalFeatures()
190 FeatureStore store = new FeatureStore();
191 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
193 store.addFeature(sf1);
194 // same range, different description
195 SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
197 store.addFeature(sf2);
198 // discontiguous range
199 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40,
201 store.addFeature(sf3);
203 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35,
205 store.addFeature(sf4);
207 SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50,
209 store.addFeature(sf5);
210 // non-positional feature
211 SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0,
213 store.addFeature(sf6);
215 SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc",
216 18, 45, Float.NaN, null);
217 store.addFeature(sf7);
219 List<SequenceFeature> features = store.getPositionalFeatures();
220 assertEquals(features.size(), 6);
221 assertTrue(features.contains(sf1));
222 assertTrue(features.contains(sf2));
223 assertTrue(features.contains(sf3));
224 assertTrue(features.contains(sf4));
225 assertTrue(features.contains(sf5));
226 assertFalse(features.contains(sf6));
227 assertTrue(features.contains(sf7));
229 features = store.getNonPositionalFeatures();
230 assertEquals(features.size(), 1);
231 assertTrue(features.contains(sf6));
234 @Test(groups = "Functional")
235 public void testDelete()
237 FeatureStore store = new FeatureStore();
238 SequenceFeature sf1 = addFeature(store, 10, 20);
239 assertTrue(store.getPositionalFeatures().contains(sf1));
244 assertTrue(store.delete(sf1));
245 assertTrue(store.getPositionalFeatures().isEmpty());
248 * non-positional feature deletion
250 SequenceFeature sf2 = addFeature(store, 0, 0);
251 assertFalse(store.getPositionalFeatures().contains(sf2));
252 assertTrue(store.getNonPositionalFeatures().contains(sf2));
253 assertTrue(store.delete(sf2));
254 assertTrue(store.getNonPositionalFeatures().isEmpty());
257 * contact feature deletion
259 SequenceFeature sf3 = new SequenceFeature("", "Disulphide Bond", 11,
260 23, Float.NaN, null);
261 store.addFeature(sf3);
262 assertEquals(store.getPositionalFeatures().size(), 1);
263 assertTrue(store.getPositionalFeatures().contains(sf3));
264 assertTrue(store.delete(sf3));
265 assertTrue(store.getPositionalFeatures().isEmpty());
268 * nested feature deletion
270 SequenceFeature sf4 = addFeature(store, 20, 30);
271 SequenceFeature sf5 = addFeature(store, 22, 26); // to NCList
272 SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
273 SequenceFeature sf7 = addFeature(store, 25, 25); // sibling of sf6
274 SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
275 SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
276 assertEquals(store.getPositionalFeatures().size(), 6);
278 // delete a node with children - they take its place
279 assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5
280 assertEquals(store.getPositionalFeatures().size(), 5);
281 assertFalse(store.getPositionalFeatures().contains(sf6));
283 // delete a node with no children
284 assertTrue(store.delete(sf7));
285 assertEquals(store.getPositionalFeatures().size(), 4);
286 assertFalse(store.getPositionalFeatures().contains(sf7));
288 // delete root of NCList
289 assertTrue(store.delete(sf5));
290 assertEquals(store.getPositionalFeatures().size(), 3);
291 assertFalse(store.getPositionalFeatures().contains(sf5));
293 // continue the killing fields
294 assertTrue(store.delete(sf4));
295 assertEquals(store.getPositionalFeatures().size(), 2);
296 assertFalse(store.getPositionalFeatures().contains(sf4));
298 assertTrue(store.delete(sf9));
299 assertEquals(store.getPositionalFeatures().size(), 1);
300 assertFalse(store.getPositionalFeatures().contains(sf9));
302 assertTrue(store.delete(sf8));
303 assertTrue(store.getPositionalFeatures().isEmpty());
306 @Test(groups = "Functional")
307 public void testAddFeature()
309 FeatureStore fs = new FeatureStore();
311 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
313 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
316 assertTrue(fs.addFeature(sf1));
317 assertEquals(fs.getFeatureCount(true), 1); // positional
318 assertEquals(fs.getFeatureCount(false), 0); // non-positional
321 * re-adding the same or an identical feature should fail
323 assertFalse(fs.addFeature(sf1));
324 assertEquals(fs.getFeatureCount(true), 1);
325 assertFalse(fs.addFeature(sf2));
326 assertEquals(fs.getFeatureCount(true), 1);
331 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
333 assertTrue(fs.addFeature(sf3));
334 assertEquals(fs.getFeatureCount(true), 1); // positional
335 assertEquals(fs.getFeatureCount(false), 1); // non-positional
336 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
338 assertFalse(fs.addFeature(sf4)); // already stored
339 assertEquals(fs.getFeatureCount(true), 1); // positional
340 assertEquals(fs.getFeatureCount(false), 1); // non-positional
345 SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20,
347 assertTrue(fs.addFeature(sf5));
348 assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact
349 assertEquals(fs.getFeatureCount(false), 1); // non-positional
350 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20,
352 assertFalse(fs.addFeature(sf6)); // already stored
353 assertEquals(fs.getFeatureCount(true), 2); // no change
354 assertEquals(fs.getFeatureCount(false), 1); // no change
357 @Test(groups = "Functional")
358 public void testIsEmpty()
360 FeatureStore fs = new FeatureStore();
361 assertTrue(fs.isEmpty());
362 assertEquals(fs.getFeatureCount(true), 0);
367 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
370 assertFalse(fs.isEmpty());
371 assertEquals(fs.getFeatureCount(true), 1);
373 assertTrue(fs.isEmpty());
374 assertEquals(fs.getFeatureCount(true), 0);
377 * non-positional feature
379 sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null);
381 assertFalse(fs.isEmpty());
382 assertEquals(fs.getFeatureCount(false), 1); // non-positional
383 assertEquals(fs.getFeatureCount(true), 0); // positional
385 assertTrue(fs.isEmpty());
386 assertEquals(fs.getFeatureCount(false), 0);
391 sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN, null);
393 assertFalse(fs.isEmpty());
394 assertEquals(fs.getFeatureCount(true), 1);
396 assertTrue(fs.isEmpty());
397 assertEquals(fs.getFeatureCount(true), 0);
400 * sf2, sf3 added as nested features
402 sf1 = new SequenceFeature("Cath", "", 19, 49, Float.NaN, null);
403 SequenceFeature sf2 = new SequenceFeature("Cath", "", 20, 40,
405 SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35,
410 assertEquals(fs.getFeatureCount(true), 3);
411 assertTrue(fs.delete(sf1));
412 assertEquals(fs.getFeatureCount(true), 2);
413 assertEquals(fs.features.size(), 2);
414 assertFalse(fs.isEmpty());
415 assertTrue(fs.delete(sf2));
416 assertEquals(fs.getFeatureCount(true), 1);
417 assertFalse(fs.isEmpty());
418 assertTrue(fs.delete(sf3));
419 assertEquals(fs.getFeatureCount(true), 0);
420 assertTrue(fs.isEmpty()); // all gone
423 @Test(groups = "Functional")
424 public void testGetFeatureGroups()
426 FeatureStore fs = new FeatureStore();
427 assertTrue(fs.getFeatureGroups(true).isEmpty());
428 assertTrue(fs.getFeatureGroups(false).isEmpty());
430 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
432 Set<String> groups = fs.getFeatureGroups(true);
433 assertEquals(groups.size(), 1);
434 assertTrue(groups.contains("group1"));
437 * add another feature of the same group, delete one, delete both
439 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group1");
441 groups = fs.getFeatureGroups(true);
442 assertEquals(groups.size(), 1);
443 assertTrue(groups.contains("group1"));
445 groups = fs.getFeatureGroups(true);
446 assertEquals(groups.size(), 1);
447 assertTrue(groups.contains("group1"));
449 groups = fs.getFeatureGroups(true);
450 assertTrue(fs.getFeatureGroups(true).isEmpty());
452 SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group2");
454 SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "Group2");
456 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f, null);
458 groups = fs.getFeatureGroups(true);
459 assertEquals(groups.size(), 3);
460 assertTrue(groups.contains("group2"));
461 assertTrue(groups.contains("Group2")); // case sensitive
462 assertTrue(groups.contains(null)); // null allowed
463 assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional
466 groups = fs.getFeatureGroups(true);
467 assertEquals(groups.size(), 2);
468 assertFalse(groups.contains("group2"));
470 groups = fs.getFeatureGroups(true);
471 assertEquals(groups.size(), 1);
472 assertFalse(groups.contains("Group2"));
474 groups = fs.getFeatureGroups(true);
475 assertTrue(groups.isEmpty());
478 * add non-positional feature
480 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
483 groups = fs.getFeatureGroups(false);
484 assertEquals(groups.size(), 1);
485 assertTrue(groups.contains("CathGroup"));
486 assertTrue(fs.delete(sf6));
487 assertTrue(fs.getFeatureGroups(false).isEmpty());
490 @Test(groups = "Functional")
491 public void testGetTotalFeatureLength()
493 FeatureStore fs = new FeatureStore();
494 assertEquals(fs.getTotalFeatureLength(), 0);
496 addFeature(fs, 10, 20); // 11
497 assertEquals(fs.getTotalFeatureLength(), 11);
498 addFeature(fs, 17, 37); // 21
499 SequenceFeature sf1 = addFeature(fs, 14, 74); // 61
500 assertEquals(fs.getTotalFeatureLength(), 93);
502 // non-positional features don't count
503 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
506 assertEquals(fs.getTotalFeatureLength(), 93);
508 // contact features count 1
509 SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc",
510 15, 35, 1f, "group1");
512 assertEquals(fs.getTotalFeatureLength(), 94);
514 assertTrue(fs.delete(sf1));
515 assertEquals(fs.getTotalFeatureLength(), 33);
516 assertFalse(fs.delete(sf1));
517 assertEquals(fs.getTotalFeatureLength(), 33);
518 assertTrue(fs.delete(sf2));
519 assertEquals(fs.getTotalFeatureLength(), 33);
520 assertTrue(fs.delete(sf3));
521 assertEquals(fs.getTotalFeatureLength(), 32);
524 @Test(groups = "Functional")
525 public void testGetFeatureLength()
530 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
531 assertEquals(FeatureStore.getFeatureLength(sf1), 11);
534 * non-positional feature
536 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
538 assertEquals(FeatureStore.getFeatureLength(sf2), 0);
541 * contact feature counts 1
543 SequenceFeature sf3 = new SequenceFeature("Disulphide Bond", "desc",
544 14, 28, 1f, "AGroup");
545 assertEquals(FeatureStore.getFeatureLength(sf3), 1);
548 @Test(groups = "Functional")
549 public void testMin()
551 assertEquals(FeatureStore.min(Float.NaN, Float.NaN), Float.NaN);
552 assertEquals(FeatureStore.min(Float.NaN, 2f), 2f);
553 assertEquals(FeatureStore.min(-2f, Float.NaN), -2f);
554 assertEquals(FeatureStore.min(2f, -3f), -3f);
557 @Test(groups = "Functional")
558 public void testMax()
560 assertEquals(FeatureStore.max(Float.NaN, Float.NaN), Float.NaN);
561 assertEquals(FeatureStore.max(Float.NaN, 2f), 2f);
562 assertEquals(FeatureStore.max(-2f, Float.NaN), -2f);
563 assertEquals(FeatureStore.max(2f, -3f), 2f);
566 @Test(groups = "Functional")
567 public void testGetMinimumScore_getMaximumScore()
569 FeatureStore fs = new FeatureStore();
570 assertEquals(fs.getMinimumScore(true), Float.NaN); // positional
571 assertEquals(fs.getMaximumScore(true), Float.NaN);
572 assertEquals(fs.getMinimumScore(false), Float.NaN); // non-positional
573 assertEquals(fs.getMaximumScore(false), Float.NaN);
575 // add features with no score
576 SequenceFeature sf1 = new SequenceFeature("type", "desc", 0, 0,
579 SequenceFeature sf2 = new SequenceFeature("type", "desc", 10, 20,
582 assertEquals(fs.getMinimumScore(true), Float.NaN);
583 assertEquals(fs.getMaximumScore(true), Float.NaN);
584 assertEquals(fs.getMinimumScore(false), Float.NaN);
585 assertEquals(fs.getMaximumScore(false), Float.NaN);
587 // add positional features with score
588 SequenceFeature sf3 = new SequenceFeature("type", "desc", 10, 20, 1f,
591 SequenceFeature sf4 = new SequenceFeature("type", "desc", 12, 16, 4f,
594 assertEquals(fs.getMinimumScore(true), 1f);
595 assertEquals(fs.getMaximumScore(true), 4f);
596 assertEquals(fs.getMinimumScore(false), Float.NaN);
597 assertEquals(fs.getMaximumScore(false), Float.NaN);
599 // add non-positional features with score
600 SequenceFeature sf5 = new SequenceFeature("type", "desc", 0, 0, 11f,
603 SequenceFeature sf6 = new SequenceFeature("type", "desc", 0, 0, -7f,
606 assertEquals(fs.getMinimumScore(true), 1f);
607 assertEquals(fs.getMaximumScore(true), 4f);
608 assertEquals(fs.getMinimumScore(false), -7f);
609 assertEquals(fs.getMaximumScore(false), 11f);
611 // delete one positional and one non-positional
612 // min-max should be recomputed
613 assertTrue(fs.delete(sf6));
614 assertTrue(fs.delete(sf3));
615 assertEquals(fs.getMinimumScore(true), 4f);
616 assertEquals(fs.getMaximumScore(true), 4f);
617 assertEquals(fs.getMinimumScore(false), 11f);
618 assertEquals(fs.getMaximumScore(false), 11f);
620 // delete remaining features with score
621 assertTrue(fs.delete(sf4));
622 assertTrue(fs.delete(sf5));
623 assertEquals(fs.getMinimumScore(true), Float.NaN);
624 assertEquals(fs.getMaximumScore(true), Float.NaN);
625 assertEquals(fs.getMinimumScore(false), Float.NaN);
626 assertEquals(fs.getMaximumScore(false), Float.NaN);
628 // delete all features
629 assertTrue(fs.delete(sf1));
630 assertTrue(fs.delete(sf2));
631 assertTrue(fs.isEmpty());
632 assertEquals(fs.getMinimumScore(true), Float.NaN);
633 assertEquals(fs.getMaximumScore(true), Float.NaN);
634 assertEquals(fs.getMinimumScore(false), Float.NaN);
635 assertEquals(fs.getMaximumScore(false), Float.NaN);
638 @Test(groups = "Functional")
639 public void testListContains()
641 assertFalse(FeatureStore.listContains(null, null));
642 List<SequenceFeature> features = new ArrayList<>();
643 assertFalse(FeatureStore.listContains(features, null));
645 SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
647 assertFalse(FeatureStore.listContains(null, sf1));
648 assertFalse(FeatureStore.listContains(features, sf1));
651 SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
653 SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f,
656 // sf2.equals(sf1) so contains should return true
657 assertTrue(FeatureStore.listContains(features, sf2));
658 assertFalse(FeatureStore.listContains(features, sf3));
661 @Test(groups = "Functional")
662 public void testGetFeaturesForGroup()
664 FeatureStore fs = new FeatureStore();
669 assertTrue(fs.getFeaturesForGroup(true, null).isEmpty());
670 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
671 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
672 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
675 * sf1: positional feature in the null group
677 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
680 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
681 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
682 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
683 List<SequenceFeature> features = fs.getFeaturesForGroup(true, null);
684 assertEquals(features.size(), 1);
685 assertTrue(features.contains(sf1));
688 * sf2: non-positional feature in the null group
689 * sf3: positional feature in a non-null group
690 * sf4: non-positional feature in a non-null group
692 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
694 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
696 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
702 features = fs.getFeaturesForGroup(true, null);
703 assertEquals(features.size(), 1);
704 assertTrue(features.contains(sf1));
706 features = fs.getFeaturesForGroup(false, null);
707 assertEquals(features.size(), 1);
708 assertTrue(features.contains(sf2));
710 features = fs.getFeaturesForGroup(true, "Uniprot");
711 assertEquals(features.size(), 1);
712 assertTrue(features.contains(sf3));
714 features = fs.getFeaturesForGroup(false, "Rfam");
715 assertEquals(features.size(), 1);
716 assertTrue(features.contains(sf4));
719 @Test(groups = "Functional")
720 public void testShiftFeatures()
722 FeatureStore fs = new FeatureStore();
723 assertFalse(fs.shiftFeatures(1));
725 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
728 SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null);
731 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
734 // non-positional feature:
735 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null);
739 * shift features right by 5
741 assertTrue(fs.shiftFeatures(5));
743 // non-positional features untouched:
744 List<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
745 assertEquals(nonPos.size(), 1);
746 assertTrue(nonPos.contains(sf4));
748 // positional features are replaced
749 List<SequenceFeature> pos = fs.getPositionalFeatures();
750 assertEquals(pos.size(), 3);
751 assertFalse(pos.contains(sf1));
752 assertFalse(pos.contains(sf2));
753 assertFalse(pos.contains(sf3));
754 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
755 assertEquals(pos.get(0).getBegin(), 7);
756 assertEquals(pos.get(0).getEnd(), 10);
757 assertEquals(pos.get(1).getBegin(), 13);
758 assertEquals(pos.get(1).getEnd(), 19);
759 assertEquals(pos.get(2).getBegin(), 28);
760 assertEquals(pos.get(2).getEnd(), 37);
763 * now shift left by 15
764 * feature at [7-10] should be removed
765 * feature at [13-19] should become [1-4]
767 assertTrue(fs.shiftFeatures(-15));
768 pos = fs.getPositionalFeatures();
769 assertEquals(pos.size(), 2);
770 SequenceFeatures.sortFeatures(pos, true);
771 assertEquals(pos.get(0).getBegin(), 1);
772 assertEquals(pos.get(0).getEnd(), 4);
773 assertEquals(pos.get(1).getBegin(), 13);
774 assertEquals(pos.get(1).getEnd(), 22);
777 @Test(groups = "Functional")
778 public void testDelete_readd()
781 * add a feature and a nested feature
783 FeatureStore store = new FeatureStore();
784 SequenceFeature sf1 = addFeature(store, 10, 20);
785 // sf2 is nested in sf1 so will be stored in nestedFeatures
786 SequenceFeature sf2 = addFeature(store, 12, 14);
787 List<SequenceFeature> features = store.getPositionalFeatures();
788 assertEquals(features.size(), 2);
789 assertTrue(features.contains(sf1));
790 assertTrue(features.contains(sf2));
791 assertTrue(store.features.contains(sf1));
792 assertTrue(store.features.contains(sf2));
795 * delete the first feature
797 assertTrue(store.delete(sf1));
798 features = store.getPositionalFeatures();
799 assertFalse(features.contains(sf1));
800 assertTrue(features.contains(sf2));
803 * re-add the 'nested' feature; is it now duplicated?
805 store.addFeature(sf2);
806 features = store.getPositionalFeatures();
807 assertEquals(features.size(), 1);
808 assertTrue(features.contains(sf2));
811 @Test(groups = "Functional")
812 public void testContains()
814 FeatureStore fs = new FeatureStore();
815 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
816 Float.NaN, "group1");
817 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
818 Float.NaN, "group2");
819 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
821 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
823 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
824 Float.NaN, "group1");
825 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
826 Float.NaN, "group2");
831 assertTrue(fs.contains(sf1)); // positional feature
832 assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
833 assertFalse(fs.contains(sf2)); // different group
834 assertTrue(fs.contains(sf3)); // non-positional
835 assertTrue(fs.contains(new SequenceFeature(sf3)));
836 assertFalse(fs.contains(sf4)); // different score
837 assertTrue(fs.contains(sf5)); // contact feature
838 assertTrue(fs.contains(new SequenceFeature(sf5)));
839 assertFalse(fs.contains(sf6)); // different group
842 * add a nested feature
844 SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16,
845 Float.NaN, "group1");
847 assertTrue(fs.contains(sf7));
848 assertTrue(fs.contains(new SequenceFeature(sf7)));
851 * delete the outer (enclosing, non-nested) feature
854 assertFalse(fs.contains(sf1));
855 assertTrue(fs.contains(sf7));