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 private int intervalStoreOption = FeatureStore.intervalStoreJSOption;
21 @Test(groups = "Functional")
22 public void testFindFeatures_nonNested()
24 FeatureStore fs = newFeatureStore();
25 fs.addFeature(new SequenceFeature("", "", 10, 20, Float.NaN,
27 // same range different description
28 fs.addFeature(new SequenceFeature("", "desc", 10, 20, Float.NaN, null));
29 fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
30 fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
32 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
33 assertTrue(overlaps.isEmpty());
35 overlaps = fs.findOverlappingFeatures(8, 10);
36 assertEquals(overlaps.size(), 2);
37 assertEquals(overlaps.get(0).getEnd(), 20);
38 assertEquals(overlaps.get(1).getEnd(), 20);
40 overlaps = fs.findOverlappingFeatures(12, 16);
42 assertEquals(overlaps.size(), 3);
43 assertEquals(overlaps.get(2).getEnd(), 25);
44 assertEquals(overlaps.get(1).getEnd(), 20);
45 assertEquals(overlaps.get(0).getEnd(), 20);
47 overlaps = fs.findOverlappingFeatures(33, 33);
48 assertEquals(overlaps.size(), 1);
49 assertEquals(overlaps.get(0).getEnd(), 35);
52 private FeatureStore newFeatureStore()
54 return new FeatureStore(intervalStoreOption);
57 @Test(groups = "Functional")
58 public void testFindFeatures_nested()
60 FeatureStore fs = newFeatureStore();
61 SequenceFeature sf1 = addFeature(fs, 10, 50);
62 SequenceFeature sf2 = addFeature(fs, 10, 40);
63 SequenceFeature sf3 = addFeature(fs, 20, 30);
64 // fudge feature at same location but different group (so is added)
65 SequenceFeature sf4 = new SequenceFeature("", "", 20, 30, Float.NaN,
68 SequenceFeature sf5 = addFeature(fs, 35, 36);
70 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
71 assertTrue(overlaps.isEmpty());
73 overlaps = fs.findOverlappingFeatures(10, 15);
74 assertEquals(overlaps.size(), 2);
75 assertTrue(overlaps.contains(sf1));
76 assertTrue(overlaps.contains(sf2));
78 overlaps = fs.findOverlappingFeatures(45, 60);
79 assertEquals(overlaps.size(), 1);
80 assertTrue(overlaps.contains(sf1));
82 overlaps = fs.findOverlappingFeatures(32, 38);
83 assertEquals(overlaps.size(), 3);
84 assertTrue(overlaps.contains(sf1));
85 assertTrue(overlaps.contains(sf2));
86 assertTrue(overlaps.contains(sf5));
88 overlaps = fs.findOverlappingFeatures(15, 25);
89 assertEquals(overlaps.size(), 4);
90 assertTrue(overlaps.contains(sf1));
91 assertTrue(overlaps.contains(sf2));
92 assertTrue(overlaps.contains(sf3));
93 assertTrue(overlaps.contains(sf4));
96 private void testFind()
98 FeatureStore fs1 = newFeatureStore();
100 SequenceFeature sf = addFeature(fs1, 1, 3000);
102 for (int i = 1; i < 1000; i++)
106 addFeature(fs1, 1 + i, 1000 + i);
117 List<SequenceFeature> overlaps1 = fs1.findOverlappingFeatures(2000,
120 assertEquals(overlaps1.size(), 1);
122 assertTrue(overlaps1.contains(sf));
126 @Test(groups = "Functional")
127 public void testFindFeatures_mixed()
131 FeatureStore fs = newFeatureStore();
132 SequenceFeature sf1 = addFeature(fs, 10, 50);
133 SequenceFeature sf2 = addFeature(fs, 1, 15);
134 SequenceFeature sf3 = addFeature(fs, 20, 30);
135 SequenceFeature sf4 = addFeature(fs, 40, 100);
136 SequenceFeature sf5 = addFeature(fs, 60, 100);
137 SequenceFeature sf6 = addFeature(fs, 70, 70);
139 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
140 assertTrue(overlaps.isEmpty());
142 overlaps = fs.findOverlappingFeatures(1, 9);
143 assertEquals(overlaps.size(), 1);
144 assertTrue(overlaps.contains(sf2));
146 overlaps = fs.findOverlappingFeatures(5, 18);
147 assertEquals(overlaps.size(), 2);
148 assertTrue(overlaps.contains(sf1));
149 assertTrue(overlaps.contains(sf2));
151 overlaps = fs.findOverlappingFeatures(30, 40);
152 assertEquals(overlaps.size(), 3);
153 assertTrue(overlaps.contains(sf1));
154 assertTrue(overlaps.contains(sf3));
155 assertTrue(overlaps.contains(sf4));
157 overlaps = fs.findOverlappingFeatures(80, 90);
158 assertEquals(overlaps.size(), 2);
159 assertTrue(overlaps.contains(sf4));
160 assertTrue(overlaps.contains(sf5));
162 overlaps = fs.findOverlappingFeatures(68, 70);
163 assertEquals(overlaps.size(), 3);
164 assertTrue(overlaps.contains(sf4));
165 assertTrue(overlaps.contains(sf5));
166 assertTrue(overlaps.contains(sf6));
170 * Helper method to add a feature of no particular type
177 SequenceFeature addFeature(FeatureStore fs, int from, int to)
179 SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN,
185 @Test(groups = "Functional")
186 public void testFindFeatures_contactFeatures()
188 FeatureStore fs = newFeatureStore();
190 SequenceFeature sf = new SequenceFeature("disulphide bond", "bond", 10,
191 20, Float.NaN, null);
195 * neither contact point in range
197 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
198 assertTrue(overlaps.isEmpty());
201 * neither contact point in range
203 overlaps = fs.findOverlappingFeatures(11, 19);
204 assertTrue(overlaps.isEmpty());
207 * first contact point in range
209 overlaps = fs.findOverlappingFeatures(5, 15);
210 assertEquals(overlaps.size(), 1);
211 assertTrue(overlaps.contains(sf));
214 * second contact point in range
216 overlaps = fs.findOverlappingFeatures(15, 25);
217 assertEquals(overlaps.size(), 1);
218 assertTrue(overlaps.contains(sf));
221 * both contact points in range
223 overlaps = fs.findOverlappingFeatures(5, 25);
224 assertEquals(overlaps.size(), 1);
225 assertTrue(overlaps.contains(sf));
228 @Test(groups = "Functional")
229 public void testGetPositionalFeatures()
231 FeatureStore store = newFeatureStore();
232 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
234 store.addFeature(sf1);
235 // same range, different description
236 SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
238 store.addFeature(sf2);
239 // discontiguous range
240 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40,
242 store.addFeature(sf3);
244 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35,
246 store.addFeature(sf4);
248 SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50,
250 store.addFeature(sf5);
251 // non-positional feature
252 SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0,
254 store.addFeature(sf6);
256 SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc",
257 18, 45, Float.NaN, null);
258 store.addFeature(sf7);
260 List<SequenceFeature> features = store.getPositionalFeatures();
261 assertEquals(features.size(), 6);
262 assertTrue(features.contains(sf1));
263 assertTrue(features.contains(sf2));
264 assertTrue(features.contains(sf3));
265 assertTrue(features.contains(sf4));
266 assertTrue(features.contains(sf5));
267 assertFalse(features.contains(sf6));
268 assertTrue(features.contains(sf7));
270 features = store.getNonPositionalFeatures();
271 assertEquals(features.size(), 1);
272 assertTrue(features.contains(sf6));
275 @Test(groups = "Functional")
276 public void testDelete()
278 FeatureStore store = newFeatureStore();
279 SequenceFeature sf1 = addFeature(store, 10, 20);
280 assertTrue(store.getPositionalFeatures().contains(sf1));
285 assertTrue(store.delete(sf1));
286 assertTrue(store.getPositionalFeatures().isEmpty());
289 * non-positional feature deletion
291 SequenceFeature sf2 = addFeature(store, 0, 0);
292 assertFalse(store.getPositionalFeatures().contains(sf2));
293 assertTrue(store.getNonPositionalFeatures().contains(sf2));
294 assertTrue(store.delete(sf2));
295 assertTrue(store.getNonPositionalFeatures().isEmpty());
298 * contact feature deletion
300 SequenceFeature sf3 = new SequenceFeature("", "Disulphide Bond", 11,
301 23, Float.NaN, null);
302 store.addFeature(sf3);
303 assertEquals(store.getPositionalFeatures().size(), 1);
304 assertTrue(store.getPositionalFeatures().contains(sf3));
305 assertTrue(store.delete(sf3));
306 assertTrue(store.getPositionalFeatures().isEmpty());
309 * nested feature deletion
311 SequenceFeature sf4 = addFeature(store, 20, 30);
312 SequenceFeature sf5 = addFeature(store, 22, 26); // to NCList
313 SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
314 SequenceFeature sf7 = addFeature(store, 25, 25); // sibling of sf6
315 SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
316 SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
317 assertEquals(store.getPositionalFeatures().size(), 6);
319 // delete a node with children - they take its place
320 assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5
321 assertEquals(store.getPositionalFeatures().size(), 5);
322 assertFalse(store.getPositionalFeatures().contains(sf6));
324 // delete a node with no children
325 assertTrue(store.delete(sf7));
326 assertEquals(store.getPositionalFeatures().size(), 4);
327 assertFalse(store.getPositionalFeatures().contains(sf7));
329 // delete root of NCList
330 assertTrue(store.delete(sf5));
331 assertEquals(store.getPositionalFeatures().size(), 3);
332 assertFalse(store.getPositionalFeatures().contains(sf5));
334 // continue the killing fields
335 assertTrue(store.delete(sf4));
336 assertEquals(store.getPositionalFeatures().size(), 2);
337 assertFalse(store.getPositionalFeatures().contains(sf4));
339 assertTrue(store.delete(sf9));
340 assertEquals(store.getPositionalFeatures().size(), 1);
341 assertFalse(store.getPositionalFeatures().contains(sf9));
343 assertTrue(store.delete(sf8));
344 assertTrue(store.getPositionalFeatures().isEmpty());
347 @Test(groups = "Functional")
348 public void testAddFeature()
350 FeatureStore fs = newFeatureStore();
352 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
354 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
357 assertTrue(fs.addFeature(sf1));
358 assertEquals(fs.getFeatureCount(true), 1); // positional
359 assertEquals(fs.getFeatureCount(false), 0); // non-positional
362 * re-adding the same or an identical feature should fail
364 assertFalse(fs.addFeature(sf1));
365 assertEquals(fs.getFeatureCount(true), 1);
366 assertFalse(fs.addFeature(sf2));
367 assertEquals(fs.getFeatureCount(true), 1);
372 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
374 assertTrue(fs.addFeature(sf3));
375 assertEquals(fs.getFeatureCount(true), 1); // positional
376 assertEquals(fs.getFeatureCount(false), 1); // non-positional
377 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
379 assertFalse(fs.addFeature(sf4)); // already stored
380 assertEquals(fs.getFeatureCount(true), 1); // positional
381 assertEquals(fs.getFeatureCount(false), 1); // non-positional
386 SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20,
388 assertTrue(fs.addFeature(sf5));
389 assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact
390 assertEquals(fs.getFeatureCount(false), 1); // non-positional
391 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20,
393 assertFalse(fs.addFeature(sf6)); // already stored
394 assertEquals(fs.getFeatureCount(true), 2); // no change
395 assertEquals(fs.getFeatureCount(false), 1); // no change
398 @Test(groups = "Functional")
399 public void testIsEmpty()
401 FeatureStore fs = newFeatureStore();
402 assertTrue(fs.isEmpty());
403 assertEquals(fs.getFeatureCount(true), 0);
408 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
411 assertFalse(fs.isEmpty());
412 assertEquals(fs.getFeatureCount(true), 1);
414 assertTrue(fs.isEmpty());
415 assertEquals(fs.getFeatureCount(true), 0);
418 * non-positional feature
420 sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null);
422 assertFalse(fs.isEmpty());
423 assertEquals(fs.getFeatureCount(false), 1); // non-positional
424 assertEquals(fs.getFeatureCount(true), 0); // positional
426 assertTrue(fs.isEmpty());
427 assertEquals(fs.getFeatureCount(false), 0);
432 sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN, null);
434 assertFalse(fs.isEmpty());
435 assertEquals(fs.getFeatureCount(true), 1);
437 assertTrue(fs.isEmpty());
438 assertEquals(fs.getFeatureCount(true), 0);
441 * sf2, sf3 added as nested features
443 sf1 = new SequenceFeature("Cath", "", 19, 49, Float.NaN, null);
444 SequenceFeature sf2 = new SequenceFeature("Cath", "", 20, 40,
446 SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35,
451 assertEquals(fs.getFeatureCount(true), 3);
452 assertTrue(fs.delete(sf1));
453 assertEquals(fs.getFeatureCount(true), 2);
454 assertEquals(fs.getFeatures().size(), 2);
455 assertFalse(fs.isEmpty());
456 assertTrue(fs.delete(sf2));
457 assertEquals(fs.getFeatureCount(true), 1);
458 assertFalse(fs.isEmpty());
459 assertTrue(fs.delete(sf3));
460 assertEquals(fs.getFeatureCount(true), 0);
461 assertTrue(fs.isEmpty()); // all gone
464 @Test(groups = "Functional")
465 public void testGetFeatureGroups()
467 FeatureStore fs = newFeatureStore();
468 assertTrue(fs.getFeatureGroups(true).isEmpty());
469 assertTrue(fs.getFeatureGroups(false).isEmpty());
471 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
473 Set<String> groups = fs.getFeatureGroups(true);
474 assertEquals(groups.size(), 1);
475 assertTrue(groups.contains("group1"));
478 * add another feature of the same group, delete one, delete both
480 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group1");
482 groups = fs.getFeatureGroups(true);
483 assertEquals(groups.size(), 1);
484 assertTrue(groups.contains("group1"));
486 groups = fs.getFeatureGroups(true);
487 assertEquals(groups.size(), 1);
488 assertTrue(groups.contains("group1"));
490 groups = fs.getFeatureGroups(true);
491 assertTrue(fs.getFeatureGroups(true).isEmpty());
493 SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group2");
495 SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "Group2");
497 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f, null);
499 groups = fs.getFeatureGroups(true);
500 assertEquals(groups.size(), 3);
501 assertTrue(groups.contains("group2"));
502 assertTrue(groups.contains("Group2")); // case sensitive
503 assertTrue(groups.contains(null)); // null allowed
504 assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional
507 groups = fs.getFeatureGroups(true);
508 assertEquals(groups.size(), 2);
509 assertFalse(groups.contains("group2"));
511 groups = fs.getFeatureGroups(true);
512 assertEquals(groups.size(), 1);
513 assertFalse(groups.contains("Group2"));
515 groups = fs.getFeatureGroups(true);
516 assertTrue(groups.isEmpty());
519 * add non-positional feature
521 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
524 groups = fs.getFeatureGroups(false);
525 assertEquals(groups.size(), 1);
526 assertTrue(groups.contains("CathGroup"));
527 assertTrue(fs.delete(sf6));
528 assertTrue(fs.getFeatureGroups(false).isEmpty());
531 @Test(groups = "Functional")
532 public void testGetTotalFeatureLength()
534 FeatureStore fs = newFeatureStore();
535 assertEquals(fs.getTotalFeatureLength(), 0);
537 addFeature(fs, 10, 20); // 11
538 assertEquals(fs.getTotalFeatureLength(), 11);
539 addFeature(fs, 17, 37); // 21
540 SequenceFeature sf1 = addFeature(fs, 14, 74); // 61
541 assertEquals(fs.getTotalFeatureLength(), 93);
543 // non-positional features don't count
544 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
547 assertEquals(fs.getTotalFeatureLength(), 93);
549 // contact features count 1
550 SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc",
551 15, 35, 1f, "group1");
553 assertEquals(fs.getTotalFeatureLength(), 94);
555 assertTrue(fs.delete(sf1));
556 assertEquals(fs.getTotalFeatureLength(), 33);
557 assertFalse(fs.delete(sf1));
558 assertEquals(fs.getTotalFeatureLength(), 33);
559 assertTrue(fs.delete(sf2));
560 assertEquals(fs.getTotalFeatureLength(), 33);
561 assertTrue(fs.delete(sf3));
562 assertEquals(fs.getTotalFeatureLength(), 32);
565 @Test(groups = "Functional")
566 public void testGetFeatureLength()
571 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
572 assertEquals(FeatureStore.getFeatureLength(sf1), 11);
575 * non-positional feature
577 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
579 assertEquals(FeatureStore.getFeatureLength(sf2), 0);
582 * contact feature counts 1
584 SequenceFeature sf3 = new SequenceFeature("Disulphide Bond", "desc",
585 14, 28, 1f, "AGroup");
586 assertEquals(FeatureStore.getFeatureLength(sf3), 1);
589 @Test(groups = "Functional")
590 public void testMin()
592 assertEquals(FeatureStore.min(Float.NaN, Float.NaN), Float.NaN);
593 assertEquals(FeatureStore.min(Float.NaN, 2f), 2f);
594 assertEquals(FeatureStore.min(-2f, Float.NaN), -2f);
595 assertEquals(FeatureStore.min(2f, -3f), -3f);
598 @Test(groups = "Functional")
599 public void testMax()
601 assertEquals(FeatureStore.max(Float.NaN, Float.NaN), Float.NaN);
602 assertEquals(FeatureStore.max(Float.NaN, 2f), 2f);
603 assertEquals(FeatureStore.max(-2f, Float.NaN), -2f);
604 assertEquals(FeatureStore.max(2f, -3f), 2f);
607 @Test(groups = "Functional")
608 public void testGetMinimumScore_getMaximumScore()
610 FeatureStore fs = newFeatureStore();
611 assertEquals(fs.getMinimumScore(true), Float.NaN); // positional
612 assertEquals(fs.getMaximumScore(true), Float.NaN);
613 assertEquals(fs.getMinimumScore(false), Float.NaN); // non-positional
614 assertEquals(fs.getMaximumScore(false), Float.NaN);
616 // add features with no score
617 SequenceFeature sf1 = new SequenceFeature("type", "desc", 0, 0,
620 SequenceFeature sf2 = new SequenceFeature("type", "desc", 10, 20,
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 // add positional features with score
629 SequenceFeature sf3 = new SequenceFeature("type", "desc", 10, 20, 1f,
632 SequenceFeature sf4 = new SequenceFeature("type", "desc", 12, 16, 4f,
635 assertEquals(fs.getMinimumScore(true), 1f);
636 assertEquals(fs.getMaximumScore(true), 4f);
637 assertEquals(fs.getMinimumScore(false), Float.NaN);
638 assertEquals(fs.getMaximumScore(false), Float.NaN);
640 // add non-positional features with score
641 SequenceFeature sf5 = new SequenceFeature("type", "desc", 0, 0, 11f,
644 SequenceFeature sf6 = new SequenceFeature("type", "desc", 0, 0, -7f,
647 assertEquals(fs.getMinimumScore(true), 1f);
648 assertEquals(fs.getMaximumScore(true), 4f);
649 assertEquals(fs.getMinimumScore(false), -7f);
650 assertEquals(fs.getMaximumScore(false), 11f);
652 // delete one positional and one non-positional
653 // min-max should be recomputed
654 assertTrue(fs.delete(sf6));
655 assertTrue(fs.delete(sf3));
656 assertEquals(fs.getMinimumScore(true), 4f);
657 assertEquals(fs.getMaximumScore(true), 4f);
658 assertEquals(fs.getMinimumScore(false), 11f);
659 assertEquals(fs.getMaximumScore(false), 11f);
661 // delete remaining features with score
662 assertTrue(fs.delete(sf4));
663 assertTrue(fs.delete(sf5));
664 assertEquals(fs.getMinimumScore(true), Float.NaN);
665 assertEquals(fs.getMaximumScore(true), Float.NaN);
666 assertEquals(fs.getMinimumScore(false), Float.NaN);
667 assertEquals(fs.getMaximumScore(false), Float.NaN);
669 // delete all features
670 assertTrue(fs.delete(sf1));
671 assertTrue(fs.delete(sf2));
672 assertTrue(fs.isEmpty());
673 assertEquals(fs.getMinimumScore(true), Float.NaN);
674 assertEquals(fs.getMaximumScore(true), Float.NaN);
675 assertEquals(fs.getMinimumScore(false), Float.NaN);
676 assertEquals(fs.getMaximumScore(false), Float.NaN);
679 @Test(groups = "Functional")
680 public void testListContains()
682 FeatureStore featureStore = newFeatureStore();
683 assertFalse(featureStore.listContains(null, null));
684 List<SequenceFeature> features = new ArrayList<>();
685 assertFalse(featureStore.listContains(features, null));
687 SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
689 assertFalse(featureStore.listContains(null, sf1));
690 assertFalse(featureStore.listContains(features, sf1));
693 SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
695 SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f,
698 // sf2.equals(sf1) so contains should return true
699 assertTrue(featureStore.listContains(features, sf2));
700 assertFalse(featureStore.listContains(features, sf3));
703 @Test(groups = "Functional")
704 public void testGetFeaturesForGroup()
706 FeatureStore fs = newFeatureStore();
711 assertTrue(fs.getFeaturesForGroup(true, null).isEmpty());
712 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
713 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
714 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
717 * sf1: positional feature in the null group
719 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
722 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
723 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
724 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
725 List<SequenceFeature> features = fs.getFeaturesForGroup(true, null);
726 assertEquals(features.size(), 1);
727 assertTrue(features.contains(sf1));
730 * sf2: non-positional feature in the null group
731 * sf3: positional feature in a non-null group
732 * sf4: non-positional feature in a non-null group
734 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
736 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
738 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
744 features = fs.getFeaturesForGroup(true, null);
745 assertEquals(features.size(), 1);
746 assertTrue(features.contains(sf1));
748 features = fs.getFeaturesForGroup(false, null);
749 assertEquals(features.size(), 1);
750 assertTrue(features.contains(sf2));
752 features = fs.getFeaturesForGroup(true, "Uniprot");
753 assertEquals(features.size(), 1);
754 assertTrue(features.contains(sf3));
756 features = fs.getFeaturesForGroup(false, "Rfam");
757 assertEquals(features.size(), 1);
758 assertTrue(features.contains(sf4));
761 @Test(groups = "Functional")
762 public void testShiftFeatures()
764 FeatureStore fs = newFeatureStore();
765 assertFalse(fs.shiftFeatures(0, 1)); // nothing to do
767 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
770 SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null);
773 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
776 // non-positional feature:
777 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null);
781 * shift all features right by 5
783 assertTrue(fs.shiftFeatures(0, 5));
785 // non-positional features untouched:
786 List<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
787 assertEquals(nonPos.size(), 1);
788 assertTrue(nonPos.contains(sf4));
790 // positional features are replaced
791 List<SequenceFeature> pos = fs.getPositionalFeatures();
792 assertEquals(pos.size(), 3);
793 assertFalse(pos.contains(sf1));
794 assertFalse(pos.contains(sf2));
795 assertFalse(pos.contains(sf3));
796 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
797 assertEquals(pos.get(0).getBegin(), 7);
798 assertEquals(pos.get(0).getEnd(), 10);
799 assertEquals(pos.get(1).getBegin(), 13);
800 assertEquals(pos.get(1).getEnd(), 19);
801 assertEquals(pos.get(2).getBegin(), 28);
802 assertEquals(pos.get(2).getEnd(), 37);
805 * now shift left by 15
806 * feature at [7-10] should be removed
807 * feature at [13-19] should become [1-4]
809 assertTrue(fs.shiftFeatures(0, -15));
810 pos = fs.getPositionalFeatures();
811 assertEquals(pos.size(), 2);
812 SequenceFeatures.sortFeatures(pos, true);
813 assertEquals(pos.get(0).getBegin(), 1);
814 assertEquals(pos.get(0).getEnd(), 4);
815 assertEquals(pos.get(1).getBegin(), 13);
816 assertEquals(pos.get(1).getEnd(), 22);
819 * shift right by 4 from position 2 onwards
820 * feature at [1-4] unchanged, feature at [13-22] shifts
822 assertTrue(fs.shiftFeatures(2, 4));
823 pos = fs.getPositionalFeatures();
824 assertEquals(pos.size(), 2);
825 SequenceFeatures.sortFeatures(pos, true);
826 assertEquals(pos.get(0).getBegin(), 1);
827 assertEquals(pos.get(0).getEnd(), 4);
828 assertEquals(pos.get(1).getBegin(), 17);
829 assertEquals(pos.get(1).getEnd(), 26);
832 * shift right by 4 from position 18 onwards
833 * should be no change
835 SequenceFeature f1 = pos.get(0);
836 SequenceFeature f2 = pos.get(1);
837 assertFalse(fs.shiftFeatures(18, 4)); // no update
838 pos = fs.getPositionalFeatures();
839 assertEquals(pos.size(), 2);
840 SequenceFeatures.sortFeatures(pos, true);
841 assertSame(pos.get(0), f1);
842 assertSame(pos.get(1), f2);
845 @Test(groups = "Functional")
846 public void testDelete_readd()
849 * add a feature and a nested feature
851 FeatureStore store = newFeatureStore();
852 SequenceFeature sf1 = addFeature(store, 10, 20);
853 // sf2 is nested in sf1 so will be stored in nestedFeatures
854 SequenceFeature sf2 = addFeature(store, 12, 14);
855 List<SequenceFeature> features = store.getPositionalFeatures();
856 assertEquals(features.size(), 2);
857 assertTrue(features.contains(sf1));
858 assertTrue(features.contains(sf2));
859 assertTrue(store.getFeatures().contains(sf1));
860 assertTrue(store.getFeatures().contains(sf2));
863 * delete the first feature
865 assertTrue(store.delete(sf1));
866 features = store.getPositionalFeatures();
867 assertFalse(features.contains(sf1));
868 assertTrue(features.contains(sf2));
871 * re-add the 'nested' feature; is it now duplicated?
873 store.addFeature(sf2);
874 features = store.getPositionalFeatures();
875 assertEquals(features.size(), 1);
876 assertTrue(features.contains(sf2));
879 @Test(groups = "Functional")
880 public void testContains()
882 FeatureStore fs = newFeatureStore();
883 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
884 Float.NaN, "group1");
885 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
886 Float.NaN, "group2");
887 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
889 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
891 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
892 Float.NaN, "group1");
893 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
894 Float.NaN, "group2");
899 assertTrue(fs.contains(sf1)); // positional feature
900 assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
901 assertFalse(fs.contains(sf2)); // different group
902 assertTrue(fs.contains(sf3)); // non-positional
903 assertTrue(fs.contains(new SequenceFeature(sf3)));
904 assertFalse(fs.contains(sf4)); // different score
905 assertTrue(fs.contains(sf5)); // contact feature
906 assertTrue(fs.contains(new SequenceFeature(sf5)));
907 assertFalse(fs.contains(sf6)); // different group
910 * add a nested feature
912 SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16,
913 Float.NaN, "group1");
915 assertTrue(fs.contains(sf7));
916 assertTrue(fs.contains(new SequenceFeature(sf7)));
919 * delete the outer (enclosing, non-nested) feature
922 assertFalse(fs.contains(sf1));
923 assertTrue(fs.contains(sf7));