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 FeatureStoreLinkedTest
19 private FeatureStore newFeatureStore()
21 return new FeatureStore(
22 FeatureStore.INTERVAL_STORE_LINKED_LIST_PRESORT);
25 @Test(groups = "Functional")
26 public void testFindFeatures_nonNested()
28 FeatureStore fs = newFeatureStore();
29 SequenceFeature sf0 = new SequenceFeature("", "", 10, 20, Float.NaN,
32 // same range different description
33 SequenceFeature sf1 = new SequenceFeature("", "desc", 10, 20, Float.NaN, null);
35 SequenceFeature sf2 = new SequenceFeature("", "", 15, 25, Float.NaN, null);
37 SequenceFeature sf3 = new SequenceFeature("", "", 20, 35, Float.NaN, null);
40 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
41 assertTrue(overlaps.isEmpty());
43 overlaps = fs.findOverlappingFeatures(8, 10);
44 assertEquals(overlaps.size(), 2);
45 assertTrue(overlaps.contains(sf0));
46 assertTrue(overlaps.contains(sf1));
48 overlaps = fs.findOverlappingFeatures(12, 16);
49 assertEquals(overlaps.size(), 3);
50 assertTrue(overlaps.contains(sf0));
51 assertTrue(overlaps.contains(sf1));
52 assertTrue(overlaps.contains(sf2));
54 overlaps = fs.findOverlappingFeatures(33, 33);
55 assertEquals(overlaps.size(), 1);
56 assertTrue(overlaps.contains(sf3));
59 @Test(groups = "Functional")
60 public void testFindFeatures_nested()
62 FeatureStore fs = newFeatureStore();
63 SequenceFeature sf1 = addFeature(fs, 10, 50);
64 SequenceFeature sf2 = addFeature(fs, 10, 40);
65 SequenceFeature sf3 = addFeature(fs, 20, 30);
66 // fudge feature at same location but different group (so is added)
67 SequenceFeature sf4 = new SequenceFeature("", "", 20, 30, Float.NaN,
70 SequenceFeature sf5 = addFeature(fs, 35, 36);
72 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
73 assertTrue(overlaps.isEmpty());
75 overlaps = fs.findOverlappingFeatures(10, 15);
76 assertEquals(overlaps.size(), 2);
77 assertTrue(overlaps.contains(sf1));
78 assertTrue(overlaps.contains(sf2));
80 overlaps = fs.findOverlappingFeatures(45, 60);
81 assertEquals(overlaps.size(), 1);
82 assertTrue(overlaps.contains(sf1));
84 overlaps = fs.findOverlappingFeatures(32, 38);
85 assertEquals(overlaps.size(), 3);
86 assertTrue(overlaps.contains(sf1));
87 assertTrue(overlaps.contains(sf2));
88 assertTrue(overlaps.contains(sf5));
90 overlaps = fs.findOverlappingFeatures(15, 25);
91 assertEquals(overlaps.size(), 4);
92 assertTrue(overlaps.contains(sf1));
93 assertTrue(overlaps.contains(sf2));
94 assertTrue(overlaps.contains(sf3));
95 assertTrue(overlaps.contains(sf4));
98 @Test(groups = "Functional")
99 public void testFindFeatures_mixed()
101 FeatureStore fs = newFeatureStore();
102 SequenceFeature sf1 = addFeature(fs, 10, 50);
103 SequenceFeature sf2 = addFeature(fs, 1, 15);
104 SequenceFeature sf3 = addFeature(fs, 20, 30);
105 SequenceFeature sf4 = addFeature(fs, 40, 100);
106 SequenceFeature sf5 = addFeature(fs, 60, 100);
107 SequenceFeature sf6 = addFeature(fs, 70, 70);
109 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
110 assertTrue(overlaps.isEmpty());
112 overlaps = fs.findOverlappingFeatures(1, 9);
113 assertEquals(overlaps.size(), 1);
114 assertTrue(overlaps.contains(sf2));
116 overlaps = fs.findOverlappingFeatures(5, 18);
117 assertEquals(overlaps.size(), 2);
118 assertTrue(overlaps.contains(sf1));
119 assertTrue(overlaps.contains(sf2));
121 overlaps = fs.findOverlappingFeatures(30, 40);
122 assertEquals(overlaps.size(), 3);
123 assertTrue(overlaps.contains(sf1));
124 assertTrue(overlaps.contains(sf3));
125 assertTrue(overlaps.contains(sf4));
127 overlaps = fs.findOverlappingFeatures(80, 90);
128 assertEquals(overlaps.size(), 2);
129 assertTrue(overlaps.contains(sf4));
130 assertTrue(overlaps.contains(sf5));
132 overlaps = fs.findOverlappingFeatures(68, 70);
133 assertEquals(overlaps.size(), 3);
134 assertTrue(overlaps.contains(sf4));
135 assertTrue(overlaps.contains(sf5));
136 assertTrue(overlaps.contains(sf6));
140 * Helper method to add a feature of no particular type
147 SequenceFeature addFeature(FeatureStore fs, int from, int to)
149 SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN,
155 @Test(groups = "Functional")
156 public void testFindFeatures_contactFeatures()
158 FeatureStore fs = newFeatureStore();
160 SequenceFeature sf = new SequenceFeature("disulphide bond", "bond", 10,
161 20, Float.NaN, null);
165 * neither contact point in range
167 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
168 assertTrue(overlaps.isEmpty());
171 * neither contact point in range
173 overlaps = fs.findOverlappingFeatures(11, 19);
174 assertTrue(overlaps.isEmpty());
177 * first contact point in range
179 overlaps = fs.findOverlappingFeatures(5, 15);
180 assertEquals(overlaps.size(), 1);
181 assertTrue(overlaps.contains(sf));
184 * second contact point in range
186 overlaps = fs.findOverlappingFeatures(15, 25);
187 assertEquals(overlaps.size(), 1);
188 assertTrue(overlaps.contains(sf));
191 * both contact points in range
193 overlaps = fs.findOverlappingFeatures(5, 25);
194 assertEquals(overlaps.size(), 1);
195 assertTrue(overlaps.contains(sf));
198 @Test(groups = "Functional")
199 public void testGetPositionalFeatures()
201 FeatureStore store = newFeatureStore();
202 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
204 store.addFeature(sf1);
205 // same range, different description
206 SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
208 store.addFeature(sf2);
209 // discontiguous range
210 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40,
212 store.addFeature(sf3);
214 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35,
216 store.addFeature(sf4);
218 SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50,
220 store.addFeature(sf5);
221 // non-positional feature
222 SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0,
224 store.addFeature(sf6);
226 SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc",
227 18, 45, Float.NaN, null);
228 store.addFeature(sf7);
230 List<SequenceFeature> features = store.getPositionalFeatures();
231 assertEquals(features.size(), 6);
232 assertTrue(features.contains(sf1));
233 assertTrue(features.contains(sf2));
234 assertTrue(features.contains(sf3));
235 assertTrue(features.contains(sf4));
236 assertTrue(features.contains(sf5));
237 assertFalse(features.contains(sf6));
238 assertTrue(features.contains(sf7));
240 features = store.getNonPositionalFeatures();
241 assertEquals(features.size(), 1);
242 assertTrue(features.contains(sf6));
245 @Test(groups = "Functional")
246 public void testDelete()
248 FeatureStore store = newFeatureStore();
249 SequenceFeature sf1 = addFeature(store, 10, 20);
250 assertTrue(store.getPositionalFeatures().contains(sf1));
255 assertTrue(store.delete(sf1));
256 assertTrue(store.getPositionalFeatures().isEmpty());
259 * non-positional feature deletion
261 SequenceFeature sf2 = addFeature(store, 0, 0);
262 assertFalse(store.getPositionalFeatures().contains(sf2));
263 assertTrue(store.getNonPositionalFeatures().contains(sf2));
264 assertTrue(store.delete(sf2));
265 assertTrue(store.getNonPositionalFeatures().isEmpty());
268 * contact feature deletion
270 SequenceFeature sf3 = new SequenceFeature("", "Disulphide Bond", 11,
271 23, Float.NaN, null);
272 store.addFeature(sf3);
273 assertEquals(store.getPositionalFeatures().size(), 1);
274 assertTrue(store.getPositionalFeatures().contains(sf3));
275 assertTrue(store.delete(sf3));
276 assertTrue(store.getPositionalFeatures().isEmpty());
279 * nested feature deletion
281 SequenceFeature sf4 = addFeature(store, 20, 30);
282 SequenceFeature sf5 = addFeature(store, 22, 26); // to NCList
283 SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
284 SequenceFeature sf7 = addFeature(store, 25, 25); // sibling of sf6
285 SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
286 SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
288 // SequenceFeature sf4 = addFeature(store, 20, 30);
289 //// SequenceFeature sf5 = addFeature(store, 22, 26);
290 ////// SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
291 //////// SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
292 //////// SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
293 ////// SequenceFeature sf7 = addFeature(store, 25, 25); // child of sf5
295 assertEquals(store.getPositionalFeatures().size(), 6);
297 // delete a node with children - they take its place
298 assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5
299 assertEquals(store.getPositionalFeatures().size(), 5);
300 assertFalse(store.getPositionalFeatures().contains(sf6));
302 // delete a node with no children
303 assertTrue(store.delete(sf7));
304 assertEquals(store.getPositionalFeatures().size(), 4);
305 assertFalse(store.getPositionalFeatures().contains(sf7));
307 // delete root of NCList
308 assertTrue(store.delete(sf5));
309 assertEquals(store.getPositionalFeatures().size(), 3);
310 assertFalse(store.getPositionalFeatures().contains(sf5));
312 // continue the killing fields
313 assertTrue(store.delete(sf4));
314 assertEquals(store.getPositionalFeatures().size(), 2);
315 assertFalse(store.getPositionalFeatures().contains(sf4));
317 assertTrue(store.delete(sf9));
318 assertEquals(store.getPositionalFeatures().size(), 1);
319 assertFalse(store.getPositionalFeatures().contains(sf9));
321 assertTrue(store.delete(sf8));
322 assertTrue(store.getPositionalFeatures().isEmpty());
325 @Test(groups = "Functional")
326 public void testAddFeature()
328 FeatureStore fs = newFeatureStore();
330 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
332 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
335 assertTrue(fs.addFeature(sf1));
336 assertEquals(fs.getFeatureCount(true), 1); // positional
337 assertEquals(fs.getFeatureCount(false), 0); // non-positional
340 * re-adding the same or an identical feature should fail
342 assertFalse(fs.addFeature(sf1));
343 assertEquals(fs.getFeatureCount(true), 1);
344 assertFalse(fs.addFeature(sf2));
345 assertEquals(fs.getFeatureCount(true), 1);
350 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
352 assertTrue(fs.addFeature(sf3));
353 assertEquals(fs.getFeatureCount(true), 1); // positional
354 assertEquals(fs.getFeatureCount(false), 1); // non-positional
355 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
357 assertFalse(fs.addFeature(sf4)); // already stored
358 assertEquals(fs.getFeatureCount(true), 1); // positional
359 assertEquals(fs.getFeatureCount(false), 1); // non-positional
364 SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20,
366 assertTrue(fs.addFeature(sf5));
367 assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact
368 assertEquals(fs.getFeatureCount(false), 1); // non-positional
369 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20,
371 assertFalse(fs.addFeature(sf6)); // already stored
372 assertEquals(fs.getFeatureCount(true), 2); // no change
373 assertEquals(fs.getFeatureCount(false), 1); // no change
376 @Test(groups = "Functional")
377 public void testIsEmpty()
379 FeatureStore fs = newFeatureStore();
380 assertTrue(fs.isEmpty());
381 assertEquals(fs.getFeatureCount(true), 0);
386 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
389 assertFalse(fs.isEmpty());
390 assertEquals(fs.getFeatureCount(true), 1);
392 assertTrue(fs.isEmpty());
393 assertEquals(fs.getFeatureCount(true), 0);
396 * non-positional feature
398 sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null);
400 assertFalse(fs.isEmpty());
401 assertEquals(fs.getFeatureCount(false), 1); // non-positional
402 assertEquals(fs.getFeatureCount(true), 0); // positional
404 assertTrue(fs.isEmpty());
405 assertEquals(fs.getFeatureCount(false), 0);
410 sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN, null);
412 assertFalse(fs.isEmpty());
413 assertEquals(fs.getFeatureCount(true), 1);
415 assertTrue(fs.isEmpty());
416 assertEquals(fs.getFeatureCount(true), 0);
419 * sf2, sf3 added as nested features
421 sf1 = new SequenceFeature("Cath", "", 19, 49, Float.NaN, null);
422 SequenceFeature sf2 = new SequenceFeature("Cath", "", 20, 40,
424 SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35,
429 assertEquals(fs.getFeatureCount(true), 3);
430 assertTrue(fs.delete(sf1));
431 assertEquals(fs.getFeatureCount(true), 2);
432 assertEquals(fs.getFeatures().size(), 2);
433 assertFalse(fs.isEmpty());
434 assertTrue(fs.delete(sf2));
435 assertEquals(fs.getFeatureCount(true), 1);
436 assertFalse(fs.isEmpty());
437 assertTrue(fs.delete(sf3));
438 assertEquals(fs.getFeatureCount(true), 0);
439 assertTrue(fs.isEmpty()); // all gone
442 @Test(groups = "Functional")
443 public void testGetFeatureGroups()
445 FeatureStore fs = newFeatureStore();
446 assertTrue(fs.getFeatureGroups(true).isEmpty());
447 assertTrue(fs.getFeatureGroups(false).isEmpty());
449 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
451 Set<String> groups = fs.getFeatureGroups(true);
452 assertEquals(groups.size(), 1);
453 assertTrue(groups.contains("group1"));
456 * add another feature of the same group, delete one, delete both
458 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group1");
460 groups = fs.getFeatureGroups(true);
461 assertEquals(groups.size(), 1);
462 assertTrue(groups.contains("group1"));
464 groups = fs.getFeatureGroups(true);
465 assertEquals(groups.size(), 1);
466 assertTrue(groups.contains("group1"));
468 groups = fs.getFeatureGroups(true);
469 assertTrue(fs.getFeatureGroups(true).isEmpty());
471 SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group2");
473 SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "Group2");
475 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f, null);
477 groups = fs.getFeatureGroups(true);
478 assertEquals(groups.size(), 3);
479 assertTrue(groups.contains("group2"));
480 assertTrue(groups.contains("Group2")); // case sensitive
481 assertTrue(groups.contains(null)); // null allowed
482 assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional
485 groups = fs.getFeatureGroups(true);
486 assertEquals(groups.size(), 2);
487 assertFalse(groups.contains("group2"));
489 groups = fs.getFeatureGroups(true);
490 assertEquals(groups.size(), 1);
491 assertFalse(groups.contains("Group2"));
493 groups = fs.getFeatureGroups(true);
494 assertTrue(groups.isEmpty());
497 * add non-positional feature
499 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
502 groups = fs.getFeatureGroups(false);
503 assertEquals(groups.size(), 1);
504 assertTrue(groups.contains("CathGroup"));
505 assertTrue(fs.delete(sf6));
506 assertTrue(fs.getFeatureGroups(false).isEmpty());
509 @Test(groups = "Functional")
510 public void testGetTotalFeatureLength()
512 FeatureStore fs = newFeatureStore();
513 assertEquals(fs.getTotalFeatureLength(), 0);
515 addFeature(fs, 10, 20); // 11
516 assertEquals(fs.getTotalFeatureLength(), 11);
517 addFeature(fs, 17, 37); // 21
518 SequenceFeature sf1 = addFeature(fs, 14, 74); // 61
519 assertEquals(fs.getTotalFeatureLength(), 93);
521 // non-positional features don't count
522 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
525 assertEquals(fs.getTotalFeatureLength(), 93);
527 // contact features count 1
528 SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc",
529 15, 35, 1f, "group1");
531 assertEquals(fs.getTotalFeatureLength(), 94);
533 assertTrue(fs.delete(sf1));
534 assertEquals(fs.getTotalFeatureLength(), 33);
535 assertFalse(fs.delete(sf1));
536 assertEquals(fs.getTotalFeatureLength(), 33);
537 assertTrue(fs.delete(sf2));
538 assertEquals(fs.getTotalFeatureLength(), 33);
539 assertTrue(fs.delete(sf3));
540 assertEquals(fs.getTotalFeatureLength(), 32);
543 @Test(groups = "Functional")
544 public void testGetFeatureLength()
549 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
550 assertEquals(FeatureStore.getFeatureLength(sf1), 11);
553 * non-positional feature
555 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
557 assertEquals(FeatureStore.getFeatureLength(sf2), 0);
560 * contact feature counts 1
562 SequenceFeature sf3 = new SequenceFeature("Disulphide Bond", "desc",
563 14, 28, 1f, "AGroup");
564 assertEquals(FeatureStore.getFeatureLength(sf3), 1);
567 @Test(groups = "Functional")
568 public void testMin()
570 assertEquals(FeatureStore.min(Float.NaN, Float.NaN), Float.NaN);
571 assertEquals(FeatureStore.min(Float.NaN, 2f), 2f);
572 assertEquals(FeatureStore.min(-2f, Float.NaN), -2f);
573 assertEquals(FeatureStore.min(2f, -3f), -3f);
576 @Test(groups = "Functional")
577 public void testMax()
579 assertEquals(FeatureStore.max(Float.NaN, Float.NaN), Float.NaN);
580 assertEquals(FeatureStore.max(Float.NaN, 2f), 2f);
581 assertEquals(FeatureStore.max(-2f, Float.NaN), -2f);
582 assertEquals(FeatureStore.max(2f, -3f), 2f);
585 @Test(groups = "Functional")
586 public void testGetMinimumScore_getMaximumScore()
588 FeatureStore fs = newFeatureStore();
589 assertEquals(fs.getMinimumScore(true), Float.NaN); // positional
590 assertEquals(fs.getMaximumScore(true), Float.NaN);
591 assertEquals(fs.getMinimumScore(false), Float.NaN); // non-positional
592 assertEquals(fs.getMaximumScore(false), Float.NaN);
594 // add features with no score
595 SequenceFeature sf1 = new SequenceFeature("type", "desc", 0, 0,
598 SequenceFeature sf2 = new SequenceFeature("type", "desc", 10, 20,
601 assertEquals(fs.getMinimumScore(true), Float.NaN);
602 assertEquals(fs.getMaximumScore(true), Float.NaN);
603 assertEquals(fs.getMinimumScore(false), Float.NaN);
604 assertEquals(fs.getMaximumScore(false), Float.NaN);
606 // add positional features with score
607 SequenceFeature sf3 = new SequenceFeature("type", "desc", 10, 20, 1f,
610 SequenceFeature sf4 = new SequenceFeature("type", "desc", 12, 16, 4f,
613 assertEquals(fs.getMinimumScore(true), 1f);
614 assertEquals(fs.getMaximumScore(true), 4f);
615 assertEquals(fs.getMinimumScore(false), Float.NaN);
616 assertEquals(fs.getMaximumScore(false), Float.NaN);
618 // add non-positional features with score
619 SequenceFeature sf5 = new SequenceFeature("type", "desc", 0, 0, 11f,
622 SequenceFeature sf6 = new SequenceFeature("type", "desc", 0, 0, -7f,
625 assertEquals(fs.getMinimumScore(true), 1f);
626 assertEquals(fs.getMaximumScore(true), 4f);
627 assertEquals(fs.getMinimumScore(false), -7f);
628 assertEquals(fs.getMaximumScore(false), 11f);
630 // delete one positional and one non-positional
631 // min-max should be recomputed
632 assertTrue(fs.delete(sf6));
633 assertTrue(fs.delete(sf3));
634 assertEquals(fs.getMinimumScore(true), 4f);
635 assertEquals(fs.getMaximumScore(true), 4f);
636 assertEquals(fs.getMinimumScore(false), 11f);
637 assertEquals(fs.getMaximumScore(false), 11f);
639 // delete remaining features with score
640 assertTrue(fs.delete(sf4));
641 assertTrue(fs.delete(sf5));
642 assertEquals(fs.getMinimumScore(true), Float.NaN);
643 assertEquals(fs.getMaximumScore(true), Float.NaN);
644 assertEquals(fs.getMinimumScore(false), Float.NaN);
645 assertEquals(fs.getMaximumScore(false), Float.NaN);
647 // delete all features
648 assertTrue(fs.delete(sf1));
649 assertTrue(fs.delete(sf2));
650 assertTrue(fs.isEmpty());
651 assertEquals(fs.getMinimumScore(true), Float.NaN);
652 assertEquals(fs.getMaximumScore(true), Float.NaN);
653 assertEquals(fs.getMinimumScore(false), Float.NaN);
654 assertEquals(fs.getMaximumScore(false), Float.NaN);
657 @Test(groups = "Functional")
658 public void testListContains()
660 FeatureStore featureStore = newFeatureStore();
661 assertFalse(featureStore.listContains(null, null));
662 List<SequenceFeature> features = new ArrayList<>();
663 assertFalse(featureStore.listContains(features, null));
665 SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
667 assertFalse(featureStore.listContains(null, sf1));
668 assertFalse(featureStore.listContains(features, sf1));
671 SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
673 SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f,
676 // sf2.equals(sf1) so contains should return true
677 assertTrue(featureStore.listContains(features, sf2));
678 assertFalse(featureStore.listContains(features, sf3));
681 @Test(groups = "Functional")
682 public void testGetFeaturesForGroup()
684 FeatureStore fs = newFeatureStore();
689 assertTrue(fs.getFeaturesForGroup(true, null).isEmpty());
690 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
691 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
692 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
695 * sf1: positional feature in the null group
697 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
700 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
701 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
702 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
703 List<SequenceFeature> features = fs.getFeaturesForGroup(true, null);
704 assertEquals(features.size(), 1);
705 assertTrue(features.contains(sf1));
708 * sf2: non-positional feature in the null group
709 * sf3: positional feature in a non-null group
710 * sf4: non-positional feature in a non-null group
712 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
714 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
716 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
722 features = fs.getFeaturesForGroup(true, null);
723 assertEquals(features.size(), 1);
724 assertTrue(features.contains(sf1));
726 features = fs.getFeaturesForGroup(false, null);
727 assertEquals(features.size(), 1);
728 assertTrue(features.contains(sf2));
730 features = fs.getFeaturesForGroup(true, "Uniprot");
731 assertEquals(features.size(), 1);
732 assertTrue(features.contains(sf3));
734 features = fs.getFeaturesForGroup(false, "Rfam");
735 assertEquals(features.size(), 1);
736 assertTrue(features.contains(sf4));
739 @Test(groups = "Functional")
740 public void testShiftFeatures()
742 FeatureStore fs = newFeatureStore();
743 assertFalse(fs.shiftFeatures(0, 1)); // nothing to do
745 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
748 SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null);
751 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
754 // non-positional feature:
755 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null);
759 * shift all features right by 5
761 assertTrue(fs.shiftFeatures(0, 5));
763 // non-positional features untouched:
764 List<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
765 assertEquals(nonPos.size(), 1);
766 assertTrue(nonPos.contains(sf4));
768 // positional features are replaced
769 List<SequenceFeature> pos = fs.getPositionalFeatures();
770 assertEquals(pos.size(), 3);
771 assertFalse(pos.contains(sf1));
772 assertFalse(pos.contains(sf2));
773 assertFalse(pos.contains(sf3));
774 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
775 assertEquals(pos.get(0).getBegin(), 7);
776 assertEquals(pos.get(0).getEnd(), 10);
777 assertEquals(pos.get(1).getBegin(), 13);
778 assertEquals(pos.get(1).getEnd(), 19);
779 assertEquals(pos.get(2).getBegin(), 28);
780 assertEquals(pos.get(2).getEnd(), 37);
783 * now shift left by 15
784 * feature at [7-10] should be removed
785 * feature at [13-19] should become [1-4]
787 assertTrue(fs.shiftFeatures(0, -15));
788 pos = fs.getPositionalFeatures();
789 assertEquals(pos.size(), 2);
790 SequenceFeatures.sortFeatures(pos, true);
791 assertEquals(pos.get(0).getBegin(), 1);
792 assertEquals(pos.get(0).getEnd(), 4);
793 assertEquals(pos.get(1).getBegin(), 13);
794 assertEquals(pos.get(1).getEnd(), 22);
797 * shift right by 4 from position 2 onwards
798 * feature at [1-4] unchanged, feature at [13-22] shifts
800 assertTrue(fs.shiftFeatures(2, 4));
801 pos = fs.getPositionalFeatures();
802 assertEquals(pos.size(), 2);
803 SequenceFeatures.sortFeatures(pos, true);
804 assertEquals(pos.get(0).getBegin(), 1);
805 assertEquals(pos.get(0).getEnd(), 4);
806 assertEquals(pos.get(1).getBegin(), 17);
807 assertEquals(pos.get(1).getEnd(), 26);
810 * shift right by 4 from position 18 onwards
811 * should be no change
813 SequenceFeature f1 = pos.get(0);
814 SequenceFeature f2 = pos.get(1);
815 assertFalse(fs.shiftFeatures(18, 4)); // no update
816 pos = fs.getPositionalFeatures();
817 assertEquals(pos.size(), 2);
818 SequenceFeatures.sortFeatures(pos, true);
819 assertSame(pos.get(0), f1);
820 assertSame(pos.get(1), f2);
823 @Test(groups = "Functional")
824 public void testDelete_readd()
827 * add a feature and a nested feature
829 FeatureStore store = newFeatureStore();
830 SequenceFeature sf1 = addFeature(store, 10, 20);
831 // sf2 is nested in sf1 so will be stored in nestedFeatures
832 SequenceFeature sf2 = addFeature(store, 12, 14);
833 List<SequenceFeature> features = store.getPositionalFeatures();
834 assertEquals(features.size(), 2);
835 assertTrue(features.contains(sf1));
836 assertTrue(features.contains(sf2));
837 assertTrue(store.getFeatures().contains(sf1));
838 assertTrue(store.getFeatures().contains(sf2));
841 * delete the first feature
843 assertTrue(store.delete(sf1));
844 features = store.getPositionalFeatures();
845 assertFalse(features.contains(sf1));
846 assertTrue(features.contains(sf2));
849 * re-add the 'nested' feature; is it now duplicated?
851 store.addFeature(sf2);
852 features = store.getPositionalFeatures();
853 assertEquals(features.size(), 1);
854 assertTrue(features.contains(sf2));
857 @Test(groups = "Functional")
858 public void testContains()
860 FeatureStore fs = newFeatureStore();
861 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
862 Float.NaN, "group1");
863 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
864 Float.NaN, "group2");
865 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
867 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
869 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
870 Float.NaN, "group1");
871 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
872 Float.NaN, "group2");
877 assertTrue(fs.contains(sf1)); // positional feature
878 assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
879 assertFalse(fs.contains(sf2)); // different group
880 assertTrue(fs.contains(sf3)); // non-positional
881 assertTrue(fs.contains(new SequenceFeature(sf3)));
882 assertFalse(fs.contains(sf4)); // different score
883 assertTrue(fs.contains(sf5)); // contact feature
884 assertTrue(fs.contains(new SequenceFeature(sf5)));
885 assertFalse(fs.contains(sf6)); // different group
888 * add a nested feature
890 SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16,
891 Float.NaN, "group1");
893 assertTrue(fs.contains(sf7));
894 assertTrue(fs.contains(new SequenceFeature(sf7)));
897 * delete the outer (enclosing, non-nested) feature
900 assertFalse(fs.contains(sf1));
901 assertTrue(fs.contains(sf7));