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 FeatureStoreJavaTest
18 private FeatureStore newFeatureStore()
20 return new FeatureStore();
23 @Test(groups = "Functional")
24 public void testFindFeatures_nonNested()
26 FeatureStore fs = newFeatureStore();
27 fs.addFeature(new SequenceFeature("", "", 10, 20, Float.NaN,
29 // same range different description
30 fs.addFeature(new SequenceFeature("", "desc", 10, 20, Float.NaN, null));
31 fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
32 fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
34 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
35 assertTrue(overlaps.isEmpty());
37 overlaps = fs.findOverlappingFeatures(8, 10);
38 assertEquals(overlaps.size(), 2);
39 assertEquals(overlaps.get(0).getEnd(), 20);
40 assertEquals(overlaps.get(1).getEnd(), 20);
42 overlaps = fs.findOverlappingFeatures(12, 16);
43 assertEquals(overlaps.size(), 3);
44 assertEquals(overlaps.get(0).getEnd(), 20);
45 assertEquals(overlaps.get(1).getEnd(), 20);
46 assertEquals(overlaps.get(2).getEnd(), 25);
48 overlaps = fs.findOverlappingFeatures(33, 33);
49 assertEquals(overlaps.size(), 1);
50 assertEquals(overlaps.get(0).getEnd(), 35);
53 @Test(groups = "Functional")
54 public void testFindFeatures_nested()
56 FeatureStore fs = newFeatureStore();
57 SequenceFeature sf1 = addFeature(fs, 10, 50);
58 SequenceFeature sf2 = addFeature(fs, 10, 40);
59 SequenceFeature sf3 = addFeature(fs, 20, 30);
60 // fudge feature at same location but different group (so is added)
61 SequenceFeature sf4 = new SequenceFeature("", "", 20, 30, Float.NaN,
64 SequenceFeature sf5 = addFeature(fs, 35, 36);
66 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
67 assertTrue(overlaps.isEmpty());
69 overlaps = fs.findOverlappingFeatures(10, 15);
70 assertEquals(overlaps.size(), 2);
71 assertTrue(overlaps.contains(sf1));
72 assertTrue(overlaps.contains(sf2));
74 overlaps = fs.findOverlappingFeatures(45, 60);
75 assertEquals(overlaps.size(), 1);
76 assertTrue(overlaps.contains(sf1));
78 overlaps = fs.findOverlappingFeatures(32, 38);
79 assertEquals(overlaps.size(), 3);
80 assertTrue(overlaps.contains(sf1));
81 assertTrue(overlaps.contains(sf2));
82 assertTrue(overlaps.contains(sf5));
84 overlaps = fs.findOverlappingFeatures(15, 25);
85 assertEquals(overlaps.size(), 4);
86 assertTrue(overlaps.contains(sf1));
87 assertTrue(overlaps.contains(sf2));
88 assertTrue(overlaps.contains(sf3));
89 assertTrue(overlaps.contains(sf4));
92 @Test(groups = "Functional")
93 public void testFindFeatures_mixed()
95 FeatureStore fs = newFeatureStore();
96 SequenceFeature sf1 = addFeature(fs, 10, 50);
97 SequenceFeature sf2 = addFeature(fs, 1, 15);
98 SequenceFeature sf3 = addFeature(fs, 20, 30);
99 SequenceFeature sf4 = addFeature(fs, 40, 100);
100 SequenceFeature sf5 = addFeature(fs, 60, 100);
101 SequenceFeature sf6 = addFeature(fs, 70, 70);
103 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
104 assertTrue(overlaps.isEmpty());
106 overlaps = fs.findOverlappingFeatures(1, 9);
107 assertEquals(overlaps.size(), 1);
108 assertTrue(overlaps.contains(sf2));
110 overlaps = fs.findOverlappingFeatures(5, 18);
111 assertEquals(overlaps.size(), 2);
112 assertTrue(overlaps.contains(sf1));
113 assertTrue(overlaps.contains(sf2));
115 overlaps = fs.findOverlappingFeatures(30, 40);
116 assertEquals(overlaps.size(), 3);
117 assertTrue(overlaps.contains(sf1));
118 assertTrue(overlaps.contains(sf3));
119 assertTrue(overlaps.contains(sf4));
121 overlaps = fs.findOverlappingFeatures(80, 90);
122 assertEquals(overlaps.size(), 2);
123 assertTrue(overlaps.contains(sf4));
124 assertTrue(overlaps.contains(sf5));
126 overlaps = fs.findOverlappingFeatures(68, 70);
127 assertEquals(overlaps.size(), 3);
128 assertTrue(overlaps.contains(sf4));
129 assertTrue(overlaps.contains(sf5));
130 assertTrue(overlaps.contains(sf6));
134 * Helper method to add a feature of no particular type
141 SequenceFeature addFeature(FeatureStore fs, int from, int to)
143 SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN,
149 @Test(groups = "Functional")
150 public void testFindFeatures_contactFeatures()
152 FeatureStore fs = newFeatureStore();
154 SequenceFeature sf = new SequenceFeature("disulphide bond", "bond", 10,
155 20, Float.NaN, null);
159 * neither contact point in range
161 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
162 assertTrue(overlaps.isEmpty());
165 * neither contact point in range
167 overlaps = fs.findOverlappingFeatures(11, 19);
168 assertTrue(overlaps.isEmpty());
171 * first contact point in range
173 overlaps = fs.findOverlappingFeatures(5, 15);
174 assertEquals(overlaps.size(), 1);
175 assertTrue(overlaps.contains(sf));
178 * second contact point in range
180 overlaps = fs.findOverlappingFeatures(15, 25);
181 assertEquals(overlaps.size(), 1);
182 assertTrue(overlaps.contains(sf));
185 * both contact points in range
187 overlaps = fs.findOverlappingFeatures(5, 25);
188 assertEquals(overlaps.size(), 1);
189 assertTrue(overlaps.contains(sf));
192 @Test(groups = "Functional")
193 public void testGetPositionalFeatures()
195 FeatureStore store = newFeatureStore();
196 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
198 store.addFeature(sf1);
199 // same range, different description
200 SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
202 store.addFeature(sf2);
203 // discontiguous range
204 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40,
206 store.addFeature(sf3);
208 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35,
210 store.addFeature(sf4);
212 SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50,
214 store.addFeature(sf5);
215 // non-positional feature
216 SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0,
218 store.addFeature(sf6);
220 SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc",
221 18, 45, Float.NaN, null);
222 store.addFeature(sf7);
224 List<SequenceFeature> features = store.getPositionalFeatures();
225 assertEquals(features.size(), 6);
226 assertTrue(features.contains(sf1));
227 assertTrue(features.contains(sf2));
228 assertTrue(features.contains(sf3));
229 assertTrue(features.contains(sf4));
230 assertTrue(features.contains(sf5));
231 assertFalse(features.contains(sf6));
232 assertTrue(features.contains(sf7));
234 features = store.getNonPositionalFeatures();
235 assertEquals(features.size(), 1);
236 assertTrue(features.contains(sf6));
239 @Test(groups = "Functional")
240 public void testDelete()
242 FeatureStore store = newFeatureStore();
243 SequenceFeature sf1 = addFeature(store, 10, 20);
244 assertTrue(store.getPositionalFeatures().contains(sf1));
249 assertTrue(store.delete(sf1));
250 assertTrue(store.getPositionalFeatures().isEmpty());
253 * non-positional feature deletion
255 SequenceFeature sf2 = addFeature(store, 0, 0);
256 assertFalse(store.getPositionalFeatures().contains(sf2));
257 assertTrue(store.getNonPositionalFeatures().contains(sf2));
258 assertTrue(store.delete(sf2));
259 assertTrue(store.getNonPositionalFeatures().isEmpty());
262 * contact feature deletion
264 SequenceFeature sf3 = new SequenceFeature("", "Disulphide Bond", 11,
265 23, Float.NaN, null);
266 store.addFeature(sf3);
267 assertEquals(store.getPositionalFeatures().size(), 1);
268 assertTrue(store.getPositionalFeatures().contains(sf3));
269 assertTrue(store.delete(sf3));
270 assertTrue(store.getPositionalFeatures().isEmpty());
273 * nested feature deletion
275 SequenceFeature sf4 = addFeature(store, 20, 30);
276 SequenceFeature sf5 = addFeature(store, 22, 26); // to NCList
277 SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
278 SequenceFeature sf7 = addFeature(store, 25, 25); // sibling of sf6
279 SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
280 SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
281 assertEquals(store.getPositionalFeatures().size(), 6);
283 // delete a node with children - they take its place
284 assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5
285 assertEquals(store.getPositionalFeatures().size(), 5);
286 assertFalse(store.getPositionalFeatures().contains(sf6));
288 // delete a node with no children
289 assertTrue(store.delete(sf7));
290 assertEquals(store.getPositionalFeatures().size(), 4);
291 assertFalse(store.getPositionalFeatures().contains(sf7));
293 // delete root of NCList
294 assertTrue(store.delete(sf5));
295 assertEquals(store.getPositionalFeatures().size(), 3);
296 assertFalse(store.getPositionalFeatures().contains(sf5));
298 // continue the killing fields
299 assertTrue(store.delete(sf4));
300 assertEquals(store.getPositionalFeatures().size(), 2);
301 assertFalse(store.getPositionalFeatures().contains(sf4));
303 assertTrue(store.delete(sf9));
304 assertEquals(store.getPositionalFeatures().size(), 1);
305 assertFalse(store.getPositionalFeatures().contains(sf9));
307 assertTrue(store.delete(sf8));
308 assertTrue(store.getPositionalFeatures().isEmpty());
311 @Test(groups = "Functional")
312 public void testAddFeature()
314 FeatureStore fs = newFeatureStore();
316 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
318 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
321 assertTrue(fs.addFeature(sf1));
322 assertEquals(fs.getFeatureCount(true), 1); // positional
323 assertEquals(fs.getFeatureCount(false), 0); // non-positional
326 * re-adding the same or an identical feature should fail
328 assertFalse(fs.addFeature(sf1));
329 assertEquals(fs.getFeatureCount(true), 1);
330 assertFalse(fs.addFeature(sf2));
331 assertEquals(fs.getFeatureCount(true), 1);
336 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
338 assertTrue(fs.addFeature(sf3));
339 assertEquals(fs.getFeatureCount(true), 1); // positional
340 assertEquals(fs.getFeatureCount(false), 1); // non-positional
341 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
343 assertFalse(fs.addFeature(sf4)); // already stored
344 assertEquals(fs.getFeatureCount(true), 1); // positional
345 assertEquals(fs.getFeatureCount(false), 1); // non-positional
350 SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20,
352 assertTrue(fs.addFeature(sf5));
353 assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact
354 assertEquals(fs.getFeatureCount(false), 1); // non-positional
355 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20,
357 assertFalse(fs.addFeature(sf6)); // already stored
358 assertEquals(fs.getFeatureCount(true), 2); // no change
359 assertEquals(fs.getFeatureCount(false), 1); // no change
362 @Test(groups = "Functional")
363 public void testIsEmpty()
365 FeatureStore fs = newFeatureStore();
366 assertTrue(fs.isEmpty());
367 assertEquals(fs.getFeatureCount(true), 0);
372 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
375 assertFalse(fs.isEmpty());
376 assertEquals(fs.getFeatureCount(true), 1);
378 assertTrue(fs.isEmpty());
379 assertEquals(fs.getFeatureCount(true), 0);
382 * non-positional feature
384 sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null);
386 assertFalse(fs.isEmpty());
387 assertEquals(fs.getFeatureCount(false), 1); // non-positional
388 assertEquals(fs.getFeatureCount(true), 0); // positional
390 assertTrue(fs.isEmpty());
391 assertEquals(fs.getFeatureCount(false), 0);
396 sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN, null);
398 assertFalse(fs.isEmpty());
399 assertEquals(fs.getFeatureCount(true), 1);
401 assertTrue(fs.isEmpty());
402 assertEquals(fs.getFeatureCount(true), 0);
405 * sf2, sf3 added as nested features
407 sf1 = new SequenceFeature("Cath", "", 19, 49, Float.NaN, null);
408 SequenceFeature sf2 = new SequenceFeature("Cath", "", 20, 40,
410 SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35,
415 assertEquals(fs.getFeatureCount(true), 3);
416 assertTrue(fs.delete(sf1));
417 assertEquals(fs.getFeatureCount(true), 2);
418 assertEquals(fs.getFeatures().size(), 2);
419 assertFalse(fs.isEmpty());
420 assertTrue(fs.delete(sf2));
421 assertEquals(fs.getFeatureCount(true), 1);
422 assertFalse(fs.isEmpty());
423 assertTrue(fs.delete(sf3));
424 assertEquals(fs.getFeatureCount(true), 0);
425 assertTrue(fs.isEmpty()); // all gone
428 @Test(groups = "Functional")
429 public void testGetFeatureGroups()
431 FeatureStore fs = newFeatureStore();
432 assertTrue(fs.getFeatureGroups(true).isEmpty());
433 assertTrue(fs.getFeatureGroups(false).isEmpty());
435 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
437 Set<String> groups = fs.getFeatureGroups(true);
438 assertEquals(groups.size(), 1);
439 assertTrue(groups.contains("group1"));
442 * add another feature of the same group, delete one, delete both
444 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group1");
446 groups = fs.getFeatureGroups(true);
447 assertEquals(groups.size(), 1);
448 assertTrue(groups.contains("group1"));
450 groups = fs.getFeatureGroups(true);
451 assertEquals(groups.size(), 1);
452 assertTrue(groups.contains("group1"));
454 groups = fs.getFeatureGroups(true);
455 assertTrue(fs.getFeatureGroups(true).isEmpty());
457 SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group2");
459 SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "Group2");
461 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f, null);
463 groups = fs.getFeatureGroups(true);
464 assertEquals(groups.size(), 3);
465 assertTrue(groups.contains("group2"));
466 assertTrue(groups.contains("Group2")); // case sensitive
467 assertTrue(groups.contains(null)); // null allowed
468 assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional
471 groups = fs.getFeatureGroups(true);
472 assertEquals(groups.size(), 2);
473 assertFalse(groups.contains("group2"));
475 groups = fs.getFeatureGroups(true);
476 assertEquals(groups.size(), 1);
477 assertFalse(groups.contains("Group2"));
479 groups = fs.getFeatureGroups(true);
480 assertTrue(groups.isEmpty());
483 * add non-positional feature
485 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
488 groups = fs.getFeatureGroups(false);
489 assertEquals(groups.size(), 1);
490 assertTrue(groups.contains("CathGroup"));
491 assertTrue(fs.delete(sf6));
492 assertTrue(fs.getFeatureGroups(false).isEmpty());
495 @Test(groups = "Functional")
496 public void testGetTotalFeatureLength()
498 FeatureStore fs = newFeatureStore();
499 assertEquals(fs.getTotalFeatureLength(), 0);
501 addFeature(fs, 10, 20); // 11
502 assertEquals(fs.getTotalFeatureLength(), 11);
503 addFeature(fs, 17, 37); // 21
504 SequenceFeature sf1 = addFeature(fs, 14, 74); // 61
505 assertEquals(fs.getTotalFeatureLength(), 93);
507 // non-positional features don't count
508 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
511 assertEquals(fs.getTotalFeatureLength(), 93);
513 // contact features count 1
514 SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc",
515 15, 35, 1f, "group1");
517 assertEquals(fs.getTotalFeatureLength(), 94);
519 assertTrue(fs.delete(sf1));
520 assertEquals(fs.getTotalFeatureLength(), 33);
521 assertFalse(fs.delete(sf1));
522 assertEquals(fs.getTotalFeatureLength(), 33);
523 assertTrue(fs.delete(sf2));
524 assertEquals(fs.getTotalFeatureLength(), 33);
525 assertTrue(fs.delete(sf3));
526 assertEquals(fs.getTotalFeatureLength(), 32);
529 @Test(groups = "Functional")
530 public void testGetFeatureLength()
535 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
536 assertEquals(FeatureStore.getFeatureLength(sf1), 11);
539 * non-positional feature
541 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
543 assertEquals(FeatureStore.getFeatureLength(sf2), 0);
546 * contact feature counts 1
548 SequenceFeature sf3 = new SequenceFeature("Disulphide Bond", "desc",
549 14, 28, 1f, "AGroup");
550 assertEquals(FeatureStore.getFeatureLength(sf3), 1);
553 @Test(groups = "Functional")
554 public void testMin()
556 assertEquals(FeatureStore.min(Float.NaN, Float.NaN), Float.NaN);
557 assertEquals(FeatureStore.min(Float.NaN, 2f), 2f);
558 assertEquals(FeatureStore.min(-2f, Float.NaN), -2f);
559 assertEquals(FeatureStore.min(2f, -3f), -3f);
562 @Test(groups = "Functional")
563 public void testMax()
565 assertEquals(FeatureStore.max(Float.NaN, Float.NaN), Float.NaN);
566 assertEquals(FeatureStore.max(Float.NaN, 2f), 2f);
567 assertEquals(FeatureStore.max(-2f, Float.NaN), -2f);
568 assertEquals(FeatureStore.max(2f, -3f), 2f);
571 @Test(groups = "Functional")
572 public void testGetMinimumScore_getMaximumScore()
574 FeatureStore fs = newFeatureStore();
575 assertEquals(fs.getMinimumScore(true), Float.NaN); // positional
576 assertEquals(fs.getMaximumScore(true), Float.NaN);
577 assertEquals(fs.getMinimumScore(false), Float.NaN); // non-positional
578 assertEquals(fs.getMaximumScore(false), Float.NaN);
580 // add features with no score
581 SequenceFeature sf1 = new SequenceFeature("type", "desc", 0, 0,
584 SequenceFeature sf2 = new SequenceFeature("type", "desc", 10, 20,
587 assertEquals(fs.getMinimumScore(true), Float.NaN);
588 assertEquals(fs.getMaximumScore(true), Float.NaN);
589 assertEquals(fs.getMinimumScore(false), Float.NaN);
590 assertEquals(fs.getMaximumScore(false), Float.NaN);
592 // add positional features with score
593 SequenceFeature sf3 = new SequenceFeature("type", "desc", 10, 20, 1f,
596 SequenceFeature sf4 = new SequenceFeature("type", "desc", 12, 16, 4f,
599 assertEquals(fs.getMinimumScore(true), 1f);
600 assertEquals(fs.getMaximumScore(true), 4f);
601 assertEquals(fs.getMinimumScore(false), Float.NaN);
602 assertEquals(fs.getMaximumScore(false), Float.NaN);
604 // add non-positional features with score
605 SequenceFeature sf5 = new SequenceFeature("type", "desc", 0, 0, 11f,
608 SequenceFeature sf6 = new SequenceFeature("type", "desc", 0, 0, -7f,
611 assertEquals(fs.getMinimumScore(true), 1f);
612 assertEquals(fs.getMaximumScore(true), 4f);
613 assertEquals(fs.getMinimumScore(false), -7f);
614 assertEquals(fs.getMaximumScore(false), 11f);
616 // delete one positional and one non-positional
617 // min-max should be recomputed
618 assertTrue(fs.delete(sf6));
619 assertTrue(fs.delete(sf3));
620 assertEquals(fs.getMinimumScore(true), 4f);
621 assertEquals(fs.getMaximumScore(true), 4f);
622 assertEquals(fs.getMinimumScore(false), 11f);
623 assertEquals(fs.getMaximumScore(false), 11f);
625 // delete remaining features with score
626 assertTrue(fs.delete(sf4));
627 assertTrue(fs.delete(sf5));
628 assertEquals(fs.getMinimumScore(true), Float.NaN);
629 assertEquals(fs.getMaximumScore(true), Float.NaN);
630 assertEquals(fs.getMinimumScore(false), Float.NaN);
631 assertEquals(fs.getMaximumScore(false), Float.NaN);
633 // delete all features
634 assertTrue(fs.delete(sf1));
635 assertTrue(fs.delete(sf2));
636 assertTrue(fs.isEmpty());
637 assertEquals(fs.getMinimumScore(true), Float.NaN);
638 assertEquals(fs.getMaximumScore(true), Float.NaN);
639 assertEquals(fs.getMinimumScore(false), Float.NaN);
640 assertEquals(fs.getMaximumScore(false), Float.NaN);
643 @Test(groups = "Functional")
644 public void testListContains()
646 FeatureStore featureStore = newFeatureStore();
647 assertFalse(featureStore.listContains(null, null));
648 List<SequenceFeature> features = new ArrayList<>();
649 assertFalse(featureStore.listContains(features, null));
651 SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
653 assertFalse(featureStore.listContains(null, sf1));
654 assertFalse(featureStore.listContains(features, sf1));
657 SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
659 SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f,
662 // sf2.equals(sf1) so contains should return true
663 assertTrue(featureStore.listContains(features, sf2));
664 assertFalse(featureStore.listContains(features, sf3));
667 @Test(groups = "Functional")
668 public void testGetFeaturesForGroup()
670 FeatureStore fs = newFeatureStore();
675 assertTrue(fs.getFeaturesForGroup(true, null).isEmpty());
676 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
677 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
678 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
681 * sf1: positional feature in the null group
683 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
686 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
687 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
688 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
689 List<SequenceFeature> features = fs.getFeaturesForGroup(true, null);
690 assertEquals(features.size(), 1);
691 assertTrue(features.contains(sf1));
694 * sf2: non-positional feature in the null group
695 * sf3: positional feature in a non-null group
696 * sf4: non-positional feature in a non-null group
698 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
700 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
702 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
708 features = fs.getFeaturesForGroup(true, null);
709 assertEquals(features.size(), 1);
710 assertTrue(features.contains(sf1));
712 features = fs.getFeaturesForGroup(false, null);
713 assertEquals(features.size(), 1);
714 assertTrue(features.contains(sf2));
716 features = fs.getFeaturesForGroup(true, "Uniprot");
717 assertEquals(features.size(), 1);
718 assertTrue(features.contains(sf3));
720 features = fs.getFeaturesForGroup(false, "Rfam");
721 assertEquals(features.size(), 1);
722 assertTrue(features.contains(sf4));
725 @Test(groups = "Functional")
726 public void testShiftFeatures()
728 FeatureStore fs = newFeatureStore();
729 assertFalse(fs.shiftFeatures(0, 1)); // nothing to do
731 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
734 SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null);
737 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
740 // non-positional feature:
741 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null);
745 * shift all features right by 5
747 assertTrue(fs.shiftFeatures(0, 5));
749 // non-positional features untouched:
750 List<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
751 assertEquals(nonPos.size(), 1);
752 assertTrue(nonPos.contains(sf4));
754 // positional features are replaced
755 List<SequenceFeature> pos = fs.getPositionalFeatures();
756 assertEquals(pos.size(), 3);
757 assertFalse(pos.contains(sf1));
758 assertFalse(pos.contains(sf2));
759 assertFalse(pos.contains(sf3));
760 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
761 assertEquals(pos.get(0).getBegin(), 7);
762 assertEquals(pos.get(0).getEnd(), 10);
763 assertEquals(pos.get(1).getBegin(), 13);
764 assertEquals(pos.get(1).getEnd(), 19);
765 assertEquals(pos.get(2).getBegin(), 28);
766 assertEquals(pos.get(2).getEnd(), 37);
769 * now shift left by 15
770 * feature at [7-10] should be removed
771 * feature at [13-19] should become [1-4]
773 assertTrue(fs.shiftFeatures(0, -15));
774 pos = fs.getPositionalFeatures();
775 assertEquals(pos.size(), 2);
776 SequenceFeatures.sortFeatures(pos, true);
777 assertEquals(pos.get(0).getBegin(), 1);
778 assertEquals(pos.get(0).getEnd(), 4);
779 assertEquals(pos.get(1).getBegin(), 13);
780 assertEquals(pos.get(1).getEnd(), 22);
783 * shift right by 4 from position 2 onwards
784 * feature at [1-4] unchanged, feature at [13-22] shifts
786 assertTrue(fs.shiftFeatures(2, 4));
787 pos = fs.getPositionalFeatures();
788 assertEquals(pos.size(), 2);
789 SequenceFeatures.sortFeatures(pos, true);
790 assertEquals(pos.get(0).getBegin(), 1);
791 assertEquals(pos.get(0).getEnd(), 4);
792 assertEquals(pos.get(1).getBegin(), 17);
793 assertEquals(pos.get(1).getEnd(), 26);
796 * shift right by 4 from position 18 onwards
797 * should be no change
799 SequenceFeature f1 = pos.get(0);
800 SequenceFeature f2 = pos.get(1);
801 assertFalse(fs.shiftFeatures(18, 4)); // no update
802 pos = fs.getPositionalFeatures();
803 assertEquals(pos.size(), 2);
804 SequenceFeatures.sortFeatures(pos, true);
805 assertSame(pos.get(0), f1);
806 assertSame(pos.get(1), f2);
809 @Test(groups = "Functional")
810 public void testDelete_readd()
813 * add a feature and a nested feature
815 FeatureStore store = newFeatureStore();
816 SequenceFeature sf1 = addFeature(store, 10, 20);
817 // sf2 is nested in sf1 so will be stored in nestedFeatures
818 SequenceFeature sf2 = addFeature(store, 12, 14);
819 List<SequenceFeature> features = store.getPositionalFeatures();
820 assertEquals(features.size(), 2);
821 assertTrue(features.contains(sf1));
822 assertTrue(features.contains(sf2));
823 assertTrue(store.getFeatures().contains(sf1));
824 assertTrue(store.getFeatures().contains(sf2));
827 * delete the first feature
829 assertTrue(store.delete(sf1));
830 features = store.getPositionalFeatures();
831 assertFalse(features.contains(sf1));
832 assertTrue(features.contains(sf2));
835 * re-add the 'nested' feature; is it now duplicated?
837 store.addFeature(sf2);
838 features = store.getPositionalFeatures();
839 assertEquals(features.size(), 1);
840 assertTrue(features.contains(sf2));
843 @Test(groups = "Functional")
844 public void testContains()
846 FeatureStore fs = newFeatureStore();
847 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
848 Float.NaN, "group1");
849 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
850 Float.NaN, "group2");
851 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
853 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
855 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
856 Float.NaN, "group1");
857 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
858 Float.NaN, "group2");
863 assertTrue(fs.contains(sf1)); // positional feature
864 assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
865 assertFalse(fs.contains(sf2)); // different group
866 assertTrue(fs.contains(sf3)); // non-positional
867 assertTrue(fs.contains(new SequenceFeature(sf3)));
868 assertFalse(fs.contains(sf4)); // different score
869 assertTrue(fs.contains(sf5)); // contact feature
870 assertTrue(fs.contains(new SequenceFeature(sf5)));
871 assertFalse(fs.contains(sf6)); // different group
874 * add a nested feature
876 SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16,
877 Float.NaN, "group1");
879 assertTrue(fs.contains(sf7));
880 assertTrue(fs.contains(new SequenceFeature(sf7)));
883 * delete the outer (enclosing, non-nested) feature
886 assertFalse(fs.contains(sf1));
887 assertTrue(fs.contains(sf7));