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.assertSame;
6 import static org.testng.Assert.assertTrue;
8 import jalview.datamodel.SequenceFeature;
10 import java.util.ArrayList;
11 import java.util.List;
14 import org.testng.annotations.Test;
16 public class FeatureStoreJSTest
19 @Test(groups = "Functional")
20 public void testFindFeatures_nonNested()
22 FeatureStoreI fs = newFeatureStore();
23 fs.addFeature(new SequenceFeature("", "", 10, 20, Float.NaN,
25 // same range different description
26 fs.addFeature(new SequenceFeature("", "desc", 10, 20, Float.NaN, null));
27 fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
28 fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
30 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
31 assertTrue(overlaps.isEmpty());
33 overlaps = fs.findOverlappingFeatures(8, 10);
34 assertEquals(overlaps.size(), 2);
35 assertEquals(overlaps.get(0).getEnd(), 20);
36 assertEquals(overlaps.get(1).getEnd(), 20);
38 overlaps = fs.findOverlappingFeatures(12, 16);
39 assertEquals(overlaps.size(), 3);
40 assertEquals(overlaps.get(0).getEnd(), 20);
41 assertEquals(overlaps.get(1).getEnd(), 20);
42 assertEquals(overlaps.get(2).getEnd(), 25);
44 overlaps = fs.findOverlappingFeatures(33, 33);
45 assertEquals(overlaps.size(), 1);
46 assertEquals(overlaps.get(0).getEnd(), 35);
49 private FeatureStoreI newFeatureStore()
51 return new FeatureStoreJS();
52 // return new FeatureStoreImpl();
55 @Test(groups = "Functional")
56 public void testFindFeatures_nested()
58 FeatureStoreI fs = newFeatureStore();
59 SequenceFeature sf1 = addFeature(fs, 10, 50);
60 SequenceFeature sf2 = addFeature(fs, 10, 40);
61 SequenceFeature sf3 = addFeature(fs, 20, 30);
62 // fudge feature at same location but different group (so is added)
63 SequenceFeature sf4 = new SequenceFeature("", "", 20, 30, Float.NaN,
66 SequenceFeature sf5 = addFeature(fs, 35, 36);
68 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
69 assertTrue(overlaps.isEmpty());
71 overlaps = fs.findOverlappingFeatures(10, 15);
72 assertEquals(overlaps.size(), 2);
73 assertTrue(overlaps.contains(sf1));
74 assertTrue(overlaps.contains(sf2));
76 overlaps = fs.findOverlappingFeatures(45, 60);
77 assertEquals(overlaps.size(), 1);
78 assertTrue(overlaps.contains(sf1));
80 overlaps = fs.findOverlappingFeatures(32, 38);
81 assertEquals(overlaps.size(), 3);
82 assertTrue(overlaps.contains(sf1));
83 assertTrue(overlaps.contains(sf2));
84 assertTrue(overlaps.contains(sf5));
86 overlaps = fs.findOverlappingFeatures(15, 25);
87 assertEquals(overlaps.size(), 4);
88 assertTrue(overlaps.contains(sf1));
89 assertTrue(overlaps.contains(sf2));
90 assertTrue(overlaps.contains(sf3));
91 assertTrue(overlaps.contains(sf4));
94 @Test(groups = "Functional")
95 public void testFindFeatures_mixed()
97 FeatureStoreI fs = newFeatureStore();
98 SequenceFeature sf1 = addFeature(fs, 10, 50);
99 SequenceFeature sf2 = addFeature(fs, 1, 15);
100 SequenceFeature sf3 = addFeature(fs, 20, 30);
101 SequenceFeature sf4 = addFeature(fs, 40, 100);
102 SequenceFeature sf5 = addFeature(fs, 60, 100);
103 SequenceFeature sf6 = addFeature(fs, 70, 70);
105 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
106 assertTrue(overlaps.isEmpty());
108 overlaps = fs.findOverlappingFeatures(1, 9);
109 assertEquals(overlaps.size(), 1);
110 assertTrue(overlaps.contains(sf2));
112 overlaps = fs.findOverlappingFeatures(5, 18);
113 assertEquals(overlaps.size(), 2);
114 assertTrue(overlaps.contains(sf1));
115 assertTrue(overlaps.contains(sf2));
117 overlaps = fs.findOverlappingFeatures(30, 40);
118 assertEquals(overlaps.size(), 3);
119 assertTrue(overlaps.contains(sf1));
120 assertTrue(overlaps.contains(sf3));
121 assertTrue(overlaps.contains(sf4));
123 overlaps = fs.findOverlappingFeatures(80, 90);
124 assertEquals(overlaps.size(), 2);
125 assertTrue(overlaps.contains(sf4));
126 assertTrue(overlaps.contains(sf5));
128 overlaps = fs.findOverlappingFeatures(68, 70);
129 assertEquals(overlaps.size(), 3);
130 assertTrue(overlaps.contains(sf4));
131 assertTrue(overlaps.contains(sf5));
132 assertTrue(overlaps.contains(sf6));
136 * Helper method to add a feature of no particular type
143 SequenceFeature addFeature(FeatureStoreI fs, int from, int to)
145 SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN,
151 @Test(groups = "Functional")
152 public void testFindFeatures_contactFeatures()
154 FeatureStoreI fs = newFeatureStore();
156 SequenceFeature sf = new SequenceFeature("disulphide bond", "bond", 10,
157 20, Float.NaN, null);
161 * neither contact point in range
163 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
164 assertTrue(overlaps.isEmpty());
167 * neither contact point in range
169 overlaps = fs.findOverlappingFeatures(11, 19);
170 assertTrue(overlaps.isEmpty());
173 * first contact point in range
175 overlaps = fs.findOverlappingFeatures(5, 15);
176 assertEquals(overlaps.size(), 1);
177 assertTrue(overlaps.contains(sf));
180 * second contact point in range
182 overlaps = fs.findOverlappingFeatures(15, 25);
183 assertEquals(overlaps.size(), 1);
184 assertTrue(overlaps.contains(sf));
187 * both contact points in range
189 overlaps = fs.findOverlappingFeatures(5, 25);
190 assertEquals(overlaps.size(), 1);
191 assertTrue(overlaps.contains(sf));
194 @Test(groups = "Functional")
195 public void testGetPositionalFeatures()
197 FeatureStoreI store = newFeatureStore();
198 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
200 store.addFeature(sf1);
201 // same range, different description
202 SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
204 store.addFeature(sf2);
205 // discontiguous range
206 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40,
208 store.addFeature(sf3);
210 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35,
212 store.addFeature(sf4);
214 SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50,
216 store.addFeature(sf5);
217 // non-positional feature
218 SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0,
220 store.addFeature(sf6);
222 SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc",
223 18, 45, Float.NaN, null);
224 store.addFeature(sf7);
226 List<SequenceFeature> features = store.getPositionalFeatures();
227 assertEquals(features.size(), 6);
228 assertTrue(features.contains(sf1));
229 assertTrue(features.contains(sf2));
230 assertTrue(features.contains(sf3));
231 assertTrue(features.contains(sf4));
232 assertTrue(features.contains(sf5));
233 assertFalse(features.contains(sf6));
234 assertTrue(features.contains(sf7));
236 features = store.getNonPositionalFeatures();
237 assertEquals(features.size(), 1);
238 assertTrue(features.contains(sf6));
241 @Test(groups = "Functional")
242 public void testDelete()
244 FeatureStoreI store = newFeatureStore();
245 SequenceFeature sf1 = addFeature(store, 10, 20);
246 assertTrue(store.getPositionalFeatures().contains(sf1));
251 assertTrue(store.delete(sf1));
252 assertTrue(store.getPositionalFeatures().isEmpty());
255 * non-positional feature deletion
257 SequenceFeature sf2 = addFeature(store, 0, 0);
258 assertFalse(store.getPositionalFeatures().contains(sf2));
259 assertTrue(store.getNonPositionalFeatures().contains(sf2));
260 assertTrue(store.delete(sf2));
261 assertTrue(store.getNonPositionalFeatures().isEmpty());
264 * contact feature deletion
266 SequenceFeature sf3 = new SequenceFeature("", "Disulphide Bond", 11,
267 23, Float.NaN, null);
268 store.addFeature(sf3);
269 assertEquals(store.getPositionalFeatures().size(), 1);
270 assertTrue(store.getPositionalFeatures().contains(sf3));
271 assertTrue(store.delete(sf3));
272 assertTrue(store.getPositionalFeatures().isEmpty());
275 * nested feature deletion
277 SequenceFeature sf4 = addFeature(store, 20, 30);
278 SequenceFeature sf5 = addFeature(store, 22, 26); // to NCList
279 SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
280 SequenceFeature sf7 = addFeature(store, 25, 25); // sibling of sf6
281 SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
282 SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
283 assertEquals(store.getPositionalFeatures().size(), 6);
285 // delete a node with children - they take its place
286 assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5
287 assertEquals(store.getPositionalFeatures().size(), 5);
288 assertFalse(store.getPositionalFeatures().contains(sf6));
290 // delete a node with no children
291 assertTrue(store.delete(sf7));
292 assertEquals(store.getPositionalFeatures().size(), 4);
293 assertFalse(store.getPositionalFeatures().contains(sf7));
295 // delete root of NCList
296 assertTrue(store.delete(sf5));
297 assertEquals(store.getPositionalFeatures().size(), 3);
298 assertFalse(store.getPositionalFeatures().contains(sf5));
300 // continue the killing fields
301 assertTrue(store.delete(sf4));
302 assertEquals(store.getPositionalFeatures().size(), 2);
303 assertFalse(store.getPositionalFeatures().contains(sf4));
305 assertTrue(store.delete(sf9));
306 assertEquals(store.getPositionalFeatures().size(), 1);
307 assertFalse(store.getPositionalFeatures().contains(sf9));
309 assertTrue(store.delete(sf8));
310 assertTrue(store.getPositionalFeatures().isEmpty());
313 @Test(groups = "Functional")
314 public void testAddFeature()
316 FeatureStoreI fs = newFeatureStore();
318 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
320 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
323 assertTrue(fs.addFeature(sf1));
324 assertEquals(fs.getFeatureCount(true), 1); // positional
325 assertEquals(fs.getFeatureCount(false), 0); // non-positional
328 * re-adding the same or an identical feature should fail
330 assertFalse(fs.addFeature(sf1));
331 assertEquals(fs.getFeatureCount(true), 1);
332 assertFalse(fs.addFeature(sf2));
333 assertEquals(fs.getFeatureCount(true), 1);
338 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
340 assertTrue(fs.addFeature(sf3));
341 assertEquals(fs.getFeatureCount(true), 1); // positional
342 assertEquals(fs.getFeatureCount(false), 1); // non-positional
343 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
345 assertFalse(fs.addFeature(sf4)); // already stored
346 assertEquals(fs.getFeatureCount(true), 1); // positional
347 assertEquals(fs.getFeatureCount(false), 1); // non-positional
352 SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20,
354 assertTrue(fs.addFeature(sf5));
355 assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact
356 assertEquals(fs.getFeatureCount(false), 1); // non-positional
357 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20,
359 assertFalse(fs.addFeature(sf6)); // already stored
360 assertEquals(fs.getFeatureCount(true), 2); // no change
361 assertEquals(fs.getFeatureCount(false), 1); // no change
364 @Test(groups = "Functional")
365 public void testIsEmpty()
367 FeatureStoreI fs = newFeatureStore();
368 assertTrue(fs.isEmpty());
369 assertEquals(fs.getFeatureCount(true), 0);
374 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
377 assertFalse(fs.isEmpty());
378 assertEquals(fs.getFeatureCount(true), 1);
380 assertTrue(fs.isEmpty());
381 assertEquals(fs.getFeatureCount(true), 0);
384 * non-positional feature
386 sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null);
388 assertFalse(fs.isEmpty());
389 assertEquals(fs.getFeatureCount(false), 1); // non-positional
390 assertEquals(fs.getFeatureCount(true), 0); // positional
392 assertTrue(fs.isEmpty());
393 assertEquals(fs.getFeatureCount(false), 0);
398 sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN, null);
400 assertFalse(fs.isEmpty());
401 assertEquals(fs.getFeatureCount(true), 1);
403 assertTrue(fs.isEmpty());
404 assertEquals(fs.getFeatureCount(true), 0);
407 * sf2, sf3 added as nested features
409 sf1 = new SequenceFeature("Cath", "", 19, 49, Float.NaN, null);
410 SequenceFeature sf2 = new SequenceFeature("Cath", "", 20, 40,
412 SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35,
417 assertEquals(fs.getFeatureCount(true), 3);
418 assertTrue(fs.delete(sf1));
419 assertEquals(fs.getFeatureCount(true), 2);
420 assertEquals(fs.getFeatures().size(), 2);
421 assertFalse(fs.isEmpty());
422 assertTrue(fs.delete(sf2));
423 assertEquals(fs.getFeatureCount(true), 1);
424 assertFalse(fs.isEmpty());
425 assertTrue(fs.delete(sf3));
426 assertEquals(fs.getFeatureCount(true), 0);
427 assertTrue(fs.isEmpty()); // all gone
430 @Test(groups = "Functional")
431 public void testGetFeatureGroups()
433 FeatureStoreI fs = newFeatureStore();
434 assertTrue(fs.getFeatureGroups(true).isEmpty());
435 assertTrue(fs.getFeatureGroups(false).isEmpty());
437 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
439 Set<String> groups = fs.getFeatureGroups(true);
440 assertEquals(groups.size(), 1);
441 assertTrue(groups.contains("group1"));
444 * add another feature of the same group, delete one, delete both
446 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group1");
448 groups = fs.getFeatureGroups(true);
449 assertEquals(groups.size(), 1);
450 assertTrue(groups.contains("group1"));
452 groups = fs.getFeatureGroups(true);
453 assertEquals(groups.size(), 1);
454 assertTrue(groups.contains("group1"));
456 groups = fs.getFeatureGroups(true);
457 assertTrue(fs.getFeatureGroups(true).isEmpty());
459 SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group2");
461 SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "Group2");
463 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f, null);
465 groups = fs.getFeatureGroups(true);
466 assertEquals(groups.size(), 3);
467 assertTrue(groups.contains("group2"));
468 assertTrue(groups.contains("Group2")); // case sensitive
469 assertTrue(groups.contains(null)); // null allowed
470 assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional
473 groups = fs.getFeatureGroups(true);
474 assertEquals(groups.size(), 2);
475 assertFalse(groups.contains("group2"));
477 groups = fs.getFeatureGroups(true);
478 assertEquals(groups.size(), 1);
479 assertFalse(groups.contains("Group2"));
481 groups = fs.getFeatureGroups(true);
482 assertTrue(groups.isEmpty());
485 * add non-positional feature
487 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
490 groups = fs.getFeatureGroups(false);
491 assertEquals(groups.size(), 1);
492 assertTrue(groups.contains("CathGroup"));
493 assertTrue(fs.delete(sf6));
494 assertTrue(fs.getFeatureGroups(false).isEmpty());
497 @Test(groups = "Functional")
498 public void testGetTotalFeatureLength()
500 FeatureStoreI fs = newFeatureStore();
501 assertEquals(fs.getTotalFeatureLength(), 0);
503 addFeature(fs, 10, 20); // 11
504 assertEquals(fs.getTotalFeatureLength(), 11);
505 addFeature(fs, 17, 37); // 21
506 SequenceFeature sf1 = addFeature(fs, 14, 74); // 61
507 assertEquals(fs.getTotalFeatureLength(), 93);
509 // non-positional features don't count
510 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
513 assertEquals(fs.getTotalFeatureLength(), 93);
515 // contact features count 1
516 SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc",
517 15, 35, 1f, "group1");
519 assertEquals(fs.getTotalFeatureLength(), 94);
521 assertTrue(fs.delete(sf1));
522 assertEquals(fs.getTotalFeatureLength(), 33);
523 assertFalse(fs.delete(sf1));
524 assertEquals(fs.getTotalFeatureLength(), 33);
525 assertTrue(fs.delete(sf2));
526 assertEquals(fs.getTotalFeatureLength(), 33);
527 assertTrue(fs.delete(sf3));
528 assertEquals(fs.getTotalFeatureLength(), 32);
531 @Test(groups = "Functional")
532 public void testGetFeatureLength()
537 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
538 assertEquals(FeatureStore.getFeatureLength(sf1), 11);
541 * non-positional feature
543 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
545 assertEquals(FeatureStore.getFeatureLength(sf2), 0);
548 * contact feature counts 1
550 SequenceFeature sf3 = new SequenceFeature("Disulphide Bond", "desc",
551 14, 28, 1f, "AGroup");
552 assertEquals(FeatureStore.getFeatureLength(sf3), 1);
555 @Test(groups = "Functional")
556 public void testMin()
558 assertEquals(FeatureStore.min(Float.NaN, Float.NaN), Float.NaN);
559 assertEquals(FeatureStore.min(Float.NaN, 2f), 2f);
560 assertEquals(FeatureStore.min(-2f, Float.NaN), -2f);
561 assertEquals(FeatureStore.min(2f, -3f), -3f);
564 @Test(groups = "Functional")
565 public void testMax()
567 assertEquals(FeatureStore.max(Float.NaN, Float.NaN), Float.NaN);
568 assertEquals(FeatureStore.max(Float.NaN, 2f), 2f);
569 assertEquals(FeatureStore.max(-2f, Float.NaN), -2f);
570 assertEquals(FeatureStore.max(2f, -3f), 2f);
573 @Test(groups = "Functional")
574 public void testGetMinimumScore_getMaximumScore()
576 FeatureStoreI fs = newFeatureStore();
577 assertEquals(fs.getMinimumScore(true), Float.NaN); // positional
578 assertEquals(fs.getMaximumScore(true), Float.NaN);
579 assertEquals(fs.getMinimumScore(false), Float.NaN); // non-positional
580 assertEquals(fs.getMaximumScore(false), Float.NaN);
582 // add features with no score
583 SequenceFeature sf1 = new SequenceFeature("type", "desc", 0, 0,
586 SequenceFeature sf2 = new SequenceFeature("type", "desc", 10, 20,
589 assertEquals(fs.getMinimumScore(true), Float.NaN);
590 assertEquals(fs.getMaximumScore(true), Float.NaN);
591 assertEquals(fs.getMinimumScore(false), Float.NaN);
592 assertEquals(fs.getMaximumScore(false), Float.NaN);
594 // add positional features with score
595 SequenceFeature sf3 = new SequenceFeature("type", "desc", 10, 20, 1f,
598 SequenceFeature sf4 = new SequenceFeature("type", "desc", 12, 16, 4f,
601 assertEquals(fs.getMinimumScore(true), 1f);
602 assertEquals(fs.getMaximumScore(true), 4f);
603 assertEquals(fs.getMinimumScore(false), Float.NaN);
604 assertEquals(fs.getMaximumScore(false), Float.NaN);
606 // add non-positional features with score
607 SequenceFeature sf5 = new SequenceFeature("type", "desc", 0, 0, 11f,
610 SequenceFeature sf6 = new SequenceFeature("type", "desc", 0, 0, -7f,
613 assertEquals(fs.getMinimumScore(true), 1f);
614 assertEquals(fs.getMaximumScore(true), 4f);
615 assertEquals(fs.getMinimumScore(false), -7f);
616 assertEquals(fs.getMaximumScore(false), 11f);
618 // delete one positional and one non-positional
619 // min-max should be recomputed
620 assertTrue(fs.delete(sf6));
621 assertTrue(fs.delete(sf3));
622 assertEquals(fs.getMinimumScore(true), 4f);
623 assertEquals(fs.getMaximumScore(true), 4f);
624 assertEquals(fs.getMinimumScore(false), 11f);
625 assertEquals(fs.getMaximumScore(false), 11f);
627 // delete remaining features with score
628 assertTrue(fs.delete(sf4));
629 assertTrue(fs.delete(sf5));
630 assertEquals(fs.getMinimumScore(true), Float.NaN);
631 assertEquals(fs.getMaximumScore(true), Float.NaN);
632 assertEquals(fs.getMinimumScore(false), Float.NaN);
633 assertEquals(fs.getMaximumScore(false), Float.NaN);
635 // delete all features
636 assertTrue(fs.delete(sf1));
637 assertTrue(fs.delete(sf2));
638 assertTrue(fs.isEmpty());
639 assertEquals(fs.getMinimumScore(true), Float.NaN);
640 assertEquals(fs.getMaximumScore(true), Float.NaN);
641 assertEquals(fs.getMinimumScore(false), Float.NaN);
642 assertEquals(fs.getMaximumScore(false), Float.NaN);
645 @Test(groups = "Functional")
646 public void testListContains()
648 FeatureStoreI featureStore = newFeatureStore();
649 assertFalse(featureStore.listContains(null, null));
650 List<SequenceFeature> features = new ArrayList<>();
651 assertFalse(featureStore.listContains(features, null));
653 SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
655 assertFalse(featureStore.listContains(null, sf1));
656 assertFalse(featureStore.listContains(features, sf1));
659 SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
661 SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f,
664 // sf2.equals(sf1) so contains should return true
665 assertTrue(featureStore.listContains(features, sf2));
666 assertFalse(featureStore.listContains(features, sf3));
669 @Test(groups = "Functional")
670 public void testGetFeaturesForGroup()
672 FeatureStoreI fs = newFeatureStore();
677 assertTrue(fs.getFeaturesForGroup(true, null).isEmpty());
678 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
679 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
680 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
683 * sf1: positional feature in the null group
685 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
688 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
689 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
690 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
691 List<SequenceFeature> features = fs.getFeaturesForGroup(true, null);
692 assertEquals(features.size(), 1);
693 assertTrue(features.contains(sf1));
696 * sf2: non-positional feature in the null group
697 * sf3: positional feature in a non-null group
698 * sf4: non-positional feature in a non-null group
700 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
702 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
704 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
710 features = fs.getFeaturesForGroup(true, null);
711 assertEquals(features.size(), 1);
712 assertTrue(features.contains(sf1));
714 features = fs.getFeaturesForGroup(false, null);
715 assertEquals(features.size(), 1);
716 assertTrue(features.contains(sf2));
718 features = fs.getFeaturesForGroup(true, "Uniprot");
719 assertEquals(features.size(), 1);
720 assertTrue(features.contains(sf3));
722 features = fs.getFeaturesForGroup(false, "Rfam");
723 assertEquals(features.size(), 1);
724 assertTrue(features.contains(sf4));
727 @Test(groups = "Functional")
728 public void testShiftFeatures()
730 FeatureStoreI fs = newFeatureStore();
731 assertFalse(fs.shiftFeatures(0, 1)); // nothing to do
733 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
736 SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null);
739 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
742 // non-positional feature:
743 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null);
747 * shift all features right by 5
749 assertTrue(fs.shiftFeatures(0, 5));
751 // non-positional features untouched:
752 List<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
753 assertEquals(nonPos.size(), 1);
754 assertTrue(nonPos.contains(sf4));
756 // positional features are replaced
757 List<SequenceFeature> pos = fs.getPositionalFeatures();
758 assertEquals(pos.size(), 3);
759 assertFalse(pos.contains(sf1));
760 assertFalse(pos.contains(sf2));
761 assertFalse(pos.contains(sf3));
762 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
763 assertEquals(pos.get(0).getBegin(), 7);
764 assertEquals(pos.get(0).getEnd(), 10);
765 assertEquals(pos.get(1).getBegin(), 13);
766 assertEquals(pos.get(1).getEnd(), 19);
767 assertEquals(pos.get(2).getBegin(), 28);
768 assertEquals(pos.get(2).getEnd(), 37);
771 * now shift left by 15
772 * feature at [7-10] should be removed
773 * feature at [13-19] should become [1-4]
775 assertTrue(fs.shiftFeatures(0, -15));
776 pos = fs.getPositionalFeatures();
777 assertEquals(pos.size(), 2);
778 SequenceFeatures.sortFeatures(pos, true);
779 assertEquals(pos.get(0).getBegin(), 1);
780 assertEquals(pos.get(0).getEnd(), 4);
781 assertEquals(pos.get(1).getBegin(), 13);
782 assertEquals(pos.get(1).getEnd(), 22);
785 * shift right by 4 from position 2 onwards
786 * feature at [1-4] unchanged, feature at [13-22] shifts
788 assertTrue(fs.shiftFeatures(2, 4));
789 pos = fs.getPositionalFeatures();
790 assertEquals(pos.size(), 2);
791 SequenceFeatures.sortFeatures(pos, true);
792 assertEquals(pos.get(0).getBegin(), 1);
793 assertEquals(pos.get(0).getEnd(), 4);
794 assertEquals(pos.get(1).getBegin(), 17);
795 assertEquals(pos.get(1).getEnd(), 26);
798 * shift right by 4 from position 18 onwards
799 * should be no change
801 SequenceFeature f1 = pos.get(0);
802 SequenceFeature f2 = pos.get(1);
803 assertFalse(fs.shiftFeatures(18, 4)); // no update
804 pos = fs.getPositionalFeatures();
805 assertEquals(pos.size(), 2);
806 SequenceFeatures.sortFeatures(pos, true);
807 assertSame(pos.get(0), f1);
808 assertSame(pos.get(1), f2);
811 @Test(groups = "Functional")
812 public void testDelete_readd()
815 * add a feature and a nested feature
817 FeatureStoreI store = newFeatureStore();
818 SequenceFeature sf1 = addFeature(store, 10, 20);
819 // sf2 is nested in sf1 so will be stored in nestedFeatures
820 SequenceFeature sf2 = addFeature(store, 12, 14);
821 List<SequenceFeature> features = store.getPositionalFeatures();
822 assertEquals(features.size(), 2);
823 assertTrue(features.contains(sf1));
824 assertTrue(features.contains(sf2));
825 assertTrue(store.getFeatures().contains(sf1));
826 assertTrue(store.getFeatures().contains(sf2));
829 * delete the first feature
831 assertTrue(store.delete(sf1));
832 features = store.getPositionalFeatures();
833 assertFalse(features.contains(sf1));
834 assertTrue(features.contains(sf2));
837 * re-add the 'nested' feature; is it now duplicated?
839 store.addFeature(sf2);
840 features = store.getPositionalFeatures();
841 assertEquals(features.size(), 1);
842 assertTrue(features.contains(sf2));
845 @Test(groups = "Functional")
846 public void testContains()
848 FeatureStoreI fs = newFeatureStore();
849 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
850 Float.NaN, "group1");
851 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
852 Float.NaN, "group2");
853 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
855 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
857 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
858 Float.NaN, "group1");
859 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
860 Float.NaN, "group2");
865 assertTrue(fs.contains(sf1)); // positional feature
866 assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
867 assertFalse(fs.contains(sf2)); // different group
868 assertTrue(fs.contains(sf3)); // non-positional
869 assertTrue(fs.contains(new SequenceFeature(sf3)));
870 assertFalse(fs.contains(sf4)); // different score
871 assertTrue(fs.contains(sf5)); // contact feature
872 assertTrue(fs.contains(new SequenceFeature(sf5)));
873 assertFalse(fs.contains(sf6)); // different group
876 * add a nested feature
878 SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16,
879 Float.NaN, "group1");
881 assertTrue(fs.contains(sf7));
882 assertTrue(fs.contains(new SequenceFeature(sf7)));
885 * delete the outer (enclosing, non-nested) feature
888 assertFalse(fs.contains(sf1));
889 assertTrue(fs.contains(sf7));