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 FeatureStoreTest
19 @Test(groups = "Functional")
20 public void testFindFeatures_nonNested()
22 FeatureStore fs = new FeatureStore();
23 fs.addFeature(new SequenceFeature("", "", 10, 20, Float.NaN, null));
24 // same range different description
25 fs.addFeature(new SequenceFeature("", "desc", 10, 20, Float.NaN, null));
26 fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
27 fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
29 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
30 assertTrue(overlaps.isEmpty());
32 overlaps = fs.findOverlappingFeatures(8, 10);
33 assertEquals(overlaps.size(), 2);
34 assertEquals(overlaps.get(0).getEnd(), 20);
35 assertEquals(overlaps.get(1).getEnd(), 20);
37 overlaps = fs.findOverlappingFeatures(12, 16);
38 assertEquals(overlaps.size(), 3);
39 assertEquals(overlaps.get(0).getEnd(), 20);
40 assertEquals(overlaps.get(1).getEnd(), 20);
41 assertEquals(overlaps.get(2).getEnd(), 25);
43 overlaps = fs.findOverlappingFeatures(33, 33);
44 assertEquals(overlaps.size(), 1);
45 assertEquals(overlaps.get(0).getEnd(), 35);
48 @Test(groups = "Functional")
49 public void testFindFeatures_nested()
51 FeatureStore fs = new FeatureStore();
52 SequenceFeature sf1 = addFeature(fs, 10, 50);
53 SequenceFeature sf2 = addFeature(fs, 10, 40);
54 SequenceFeature sf3 = addFeature(fs, 20, 30);
55 // fudge feature at same location but different group (so is added)
56 SequenceFeature sf4 = new SequenceFeature("", "", 20, 30, Float.NaN,
59 SequenceFeature sf5 = addFeature(fs, 35, 36);
61 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
62 assertTrue(overlaps.isEmpty());
64 overlaps = fs.findOverlappingFeatures(10, 15);
65 assertEquals(overlaps.size(), 2);
66 assertTrue(overlaps.contains(sf1));
67 assertTrue(overlaps.contains(sf2));
69 overlaps = fs.findOverlappingFeatures(45, 60);
70 assertEquals(overlaps.size(), 1);
71 assertTrue(overlaps.contains(sf1));
73 overlaps = fs.findOverlappingFeatures(32, 38);
74 assertEquals(overlaps.size(), 3);
75 assertTrue(overlaps.contains(sf1));
76 assertTrue(overlaps.contains(sf2));
77 assertTrue(overlaps.contains(sf5));
79 overlaps = fs.findOverlappingFeatures(15, 25);
80 assertEquals(overlaps.size(), 4);
81 assertTrue(overlaps.contains(sf1));
82 assertTrue(overlaps.contains(sf2));
83 assertTrue(overlaps.contains(sf3));
84 assertTrue(overlaps.contains(sf4));
87 @Test(groups = "Functional")
88 public void testFindFeatures_mixed()
90 FeatureStore fs = new FeatureStore();
91 SequenceFeature sf1 = addFeature(fs, 10, 50);
92 SequenceFeature sf2 = addFeature(fs, 1, 15);
93 SequenceFeature sf3 = addFeature(fs, 20, 30);
94 SequenceFeature sf4 = addFeature(fs, 40, 100);
95 SequenceFeature sf5 = addFeature(fs, 60, 100);
96 SequenceFeature sf6 = addFeature(fs, 70, 70);
98 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
99 assertTrue(overlaps.isEmpty());
101 overlaps = fs.findOverlappingFeatures(1, 9);
102 assertEquals(overlaps.size(), 1);
103 assertTrue(overlaps.contains(sf2));
105 overlaps = fs.findOverlappingFeatures(5, 18);
106 assertEquals(overlaps.size(), 2);
107 assertTrue(overlaps.contains(sf1));
108 assertTrue(overlaps.contains(sf2));
110 overlaps = fs.findOverlappingFeatures(30, 40);
111 assertEquals(overlaps.size(), 3);
112 assertTrue(overlaps.contains(sf1));
113 assertTrue(overlaps.contains(sf3));
114 assertTrue(overlaps.contains(sf4));
116 overlaps = fs.findOverlappingFeatures(80, 90);
117 assertEquals(overlaps.size(), 2);
118 assertTrue(overlaps.contains(sf4));
119 assertTrue(overlaps.contains(sf5));
121 overlaps = fs.findOverlappingFeatures(68, 70);
122 assertEquals(overlaps.size(), 3);
123 assertTrue(overlaps.contains(sf4));
124 assertTrue(overlaps.contains(sf5));
125 assertTrue(overlaps.contains(sf6));
129 * Helper method to add a feature of no particular type
136 SequenceFeature addFeature(FeatureStore fs, int from, int to)
138 SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN,
144 @Test(groups = "Functional")
145 public void testFindFeatures_contactFeatures()
147 FeatureStore fs = new FeatureStore();
149 SequenceFeature sf = new SequenceFeature("disulphide bond", "bond", 10,
150 20, Float.NaN, null);
154 * neither contact point in range
156 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
157 assertTrue(overlaps.isEmpty());
160 * neither contact point in range
162 overlaps = fs.findOverlappingFeatures(11, 19);
163 assertTrue(overlaps.isEmpty());
166 * first contact point in range
168 overlaps = fs.findOverlappingFeatures(5, 15);
169 assertEquals(overlaps.size(), 1);
170 assertTrue(overlaps.contains(sf));
173 * second contact point in range
175 overlaps = fs.findOverlappingFeatures(15, 25);
176 assertEquals(overlaps.size(), 1);
177 assertTrue(overlaps.contains(sf));
180 * both contact points in range
182 overlaps = fs.findOverlappingFeatures(5, 25);
183 assertEquals(overlaps.size(), 1);
184 assertTrue(overlaps.contains(sf));
187 @Test(groups = "Functional")
188 public void testGetPositionalFeatures()
190 FeatureStore store = new FeatureStore();
191 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
193 store.addFeature(sf1);
194 // same range, different description
195 SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
197 store.addFeature(sf2);
198 // discontiguous range
199 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40,
201 store.addFeature(sf3);
203 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35,
205 store.addFeature(sf4);
207 SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50,
209 store.addFeature(sf5);
210 // non-positional feature
211 SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0,
213 store.addFeature(sf6);
215 SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc", 18,
216 45, Float.NaN, null);
217 store.addFeature(sf7);
219 List<SequenceFeature> features = store.getPositionalFeatures();
220 assertEquals(features.size(), 6);
221 assertTrue(features.contains(sf1));
222 assertTrue(features.contains(sf2));
223 assertTrue(features.contains(sf3));
224 assertTrue(features.contains(sf4));
225 assertTrue(features.contains(sf5));
226 assertFalse(features.contains(sf6));
227 assertTrue(features.contains(sf7));
229 features = store.getNonPositionalFeatures();
230 assertEquals(features.size(), 1);
231 assertTrue(features.contains(sf6));
234 @Test(groups = "Functional")
235 public void testDelete()
237 FeatureStore store = new FeatureStore();
238 SequenceFeature sf1 = addFeature(store, 10, 20);
239 assertTrue(store.getPositionalFeatures().contains(sf1));
244 assertTrue(store.delete(sf1));
245 assertTrue(store.getPositionalFeatures().isEmpty());
248 * non-positional feature deletion
250 SequenceFeature sf2 = addFeature(store, 0, 0);
251 assertFalse(store.getPositionalFeatures().contains(sf2));
252 assertTrue(store.getNonPositionalFeatures().contains(sf2));
253 assertTrue(store.delete(sf2));
254 assertTrue(store.getNonPositionalFeatures().isEmpty());
257 * contact feature deletion
259 SequenceFeature sf3 = new SequenceFeature("", "Disulphide Bond", 11, 23,
261 store.addFeature(sf3);
262 assertEquals(store.getPositionalFeatures().size(), 1);
263 assertTrue(store.getPositionalFeatures().contains(sf3));
264 assertTrue(store.delete(sf3));
265 assertTrue(store.getPositionalFeatures().isEmpty());
268 * nested feature deletion
270 SequenceFeature sf4 = addFeature(store, 20, 30);
271 SequenceFeature sf5 = addFeature(store, 22, 26); // to NCList
272 SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
273 SequenceFeature sf7 = addFeature(store, 25, 25); // sibling of sf6
274 SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
275 SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
276 assertEquals(store.getPositionalFeatures().size(), 6);
278 // delete a node with children - they take its place
279 assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5
280 assertEquals(store.getPositionalFeatures().size(), 5);
281 assertFalse(store.getPositionalFeatures().contains(sf6));
283 // delete a node with no children
284 assertTrue(store.delete(sf7));
285 assertEquals(store.getPositionalFeatures().size(), 4);
286 assertFalse(store.getPositionalFeatures().contains(sf7));
288 // delete root of NCList
289 assertTrue(store.delete(sf5));
290 assertEquals(store.getPositionalFeatures().size(), 3);
291 assertFalse(store.getPositionalFeatures().contains(sf5));
293 // continue the killing fields
294 assertTrue(store.delete(sf4));
295 assertEquals(store.getPositionalFeatures().size(), 2);
296 assertFalse(store.getPositionalFeatures().contains(sf4));
298 assertTrue(store.delete(sf9));
299 assertEquals(store.getPositionalFeatures().size(), 1);
300 assertFalse(store.getPositionalFeatures().contains(sf9));
302 assertTrue(store.delete(sf8));
303 assertTrue(store.getPositionalFeatures().isEmpty());
306 @Test(groups = "Functional")
307 public void testAddFeature()
309 FeatureStore fs = new FeatureStore();
311 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20, Float.NaN,
313 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20, Float.NaN,
316 assertTrue(fs.addFeature(sf1));
317 assertEquals(fs.getFeatureCount(true), 1); // positional
318 assertEquals(fs.getFeatureCount(false), 0); // non-positional
321 * re-adding the same or an identical feature should fail
323 assertFalse(fs.addFeature(sf1));
324 assertEquals(fs.getFeatureCount(true), 1);
325 assertFalse(fs.addFeature(sf2));
326 assertEquals(fs.getFeatureCount(true), 1);
331 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
333 assertTrue(fs.addFeature(sf3));
334 assertEquals(fs.getFeatureCount(true), 1); // positional
335 assertEquals(fs.getFeatureCount(false), 1); // non-positional
336 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
338 assertFalse(fs.addFeature(sf4)); // already stored
339 assertEquals(fs.getFeatureCount(true), 1); // positional
340 assertEquals(fs.getFeatureCount(false), 1); // non-positional
345 SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20,
347 assertTrue(fs.addFeature(sf5));
348 assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact
349 assertEquals(fs.getFeatureCount(false), 1); // non-positional
350 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20,
352 assertFalse(fs.addFeature(sf6)); // already stored
353 assertEquals(fs.getFeatureCount(true), 2); // no change
354 assertEquals(fs.getFeatureCount(false), 1); // no change
357 @Test(groups = "Functional")
358 public void testIsEmpty()
360 FeatureStore fs = new FeatureStore();
361 assertTrue(fs.isEmpty());
362 assertEquals(fs.getFeatureCount(true), 0);
367 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20, Float.NaN,
370 assertFalse(fs.isEmpty());
371 assertEquals(fs.getFeatureCount(true), 1);
373 assertTrue(fs.isEmpty());
374 assertEquals(fs.getFeatureCount(true), 0);
377 * non-positional feature
379 sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null);
381 assertFalse(fs.isEmpty());
382 assertEquals(fs.getFeatureCount(false), 1); // non-positional
383 assertEquals(fs.getFeatureCount(true), 0); // positional
385 assertTrue(fs.isEmpty());
386 assertEquals(fs.getFeatureCount(false), 0);
391 sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN,
394 assertFalse(fs.isEmpty());
395 assertEquals(fs.getFeatureCount(true), 1);
397 assertTrue(fs.isEmpty());
398 assertEquals(fs.getFeatureCount(true), 0);
401 * sf2, sf3 added as nested features
403 sf1 = new SequenceFeature("Cath", "", 19, 49, Float.NaN, null);
404 SequenceFeature sf2 = new SequenceFeature("Cath", "", 20, 40, Float.NaN,
406 SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35, Float.NaN,
411 assertEquals(fs.getFeatureCount(true), 3);
412 assertTrue(fs.delete(sf1));
413 assertEquals(fs.getFeatureCount(true), 2);
414 assertEquals(fs.features.size(), 2);
415 assertFalse(fs.isEmpty());
416 assertTrue(fs.delete(sf2));
417 assertEquals(fs.getFeatureCount(true), 1);
418 assertFalse(fs.isEmpty());
419 assertTrue(fs.delete(sf3));
420 assertEquals(fs.getFeatureCount(true), 0);
421 assertTrue(fs.isEmpty()); // all gone
424 @Test(groups = "Functional")
425 public void testGetFeatureGroups()
427 FeatureStore fs = new FeatureStore();
428 assertTrue(fs.getFeatureGroups(true).isEmpty());
429 assertTrue(fs.getFeatureGroups(false).isEmpty());
431 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f,
434 Set<String> groups = fs.getFeatureGroups(true);
435 assertEquals(groups.size(), 1);
436 assertTrue(groups.contains("group1"));
439 * add another feature of the same group, delete one, delete both
441 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f,
444 groups = fs.getFeatureGroups(true);
445 assertEquals(groups.size(), 1);
446 assertTrue(groups.contains("group1"));
448 groups = fs.getFeatureGroups(true);
449 assertEquals(groups.size(), 1);
450 assertTrue(groups.contains("group1"));
452 groups = fs.getFeatureGroups(true);
453 assertTrue(fs.getFeatureGroups(true).isEmpty());
455 SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f,
458 SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f,
461 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f,
464 groups = fs.getFeatureGroups(true);
465 assertEquals(groups.size(), 3);
466 assertTrue(groups.contains("group2"));
467 assertTrue(groups.contains("Group2")); // case sensitive
468 assertTrue(groups.contains(null)); // null allowed
469 assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional
472 groups = fs.getFeatureGroups(true);
473 assertEquals(groups.size(), 2);
474 assertFalse(groups.contains("group2"));
476 groups = fs.getFeatureGroups(true);
477 assertEquals(groups.size(), 1);
478 assertFalse(groups.contains("Group2"));
480 groups = fs.getFeatureGroups(true);
481 assertTrue(groups.isEmpty());
484 * add non-positional feature
486 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
489 groups = fs.getFeatureGroups(false);
490 assertEquals(groups.size(), 1);
491 assertTrue(groups.contains("CathGroup"));
492 assertTrue(fs.delete(sf6));
493 assertTrue(fs.getFeatureGroups(false).isEmpty());
496 @Test(groups = "Functional")
497 public void testGetTotalFeatureLength()
499 FeatureStore fs = new FeatureStore();
500 assertEquals(fs.getTotalFeatureLength(), 0);
502 addFeature(fs, 10, 20); // 11
503 assertEquals(fs.getTotalFeatureLength(), 11);
504 addFeature(fs, 17, 37); // 21
505 SequenceFeature sf1 = addFeature(fs, 14, 74); // 61
506 assertEquals(fs.getTotalFeatureLength(), 93);
508 // non-positional features don't count
509 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
512 assertEquals(fs.getTotalFeatureLength(), 93);
514 // contact features count 1
515 SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc", 15,
518 assertEquals(fs.getTotalFeatureLength(), 94);
520 assertTrue(fs.delete(sf1));
521 assertEquals(fs.getTotalFeatureLength(), 33);
522 assertFalse(fs.delete(sf1));
523 assertEquals(fs.getTotalFeatureLength(), 33);
524 assertTrue(fs.delete(sf2));
525 assertEquals(fs.getTotalFeatureLength(), 33);
526 assertTrue(fs.delete(sf3));
527 assertEquals(fs.getTotalFeatureLength(), 32);
530 @Test(groups = "Functional")
531 public void testGetFeatureLength()
536 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f,
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", 14,
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 FeatureStore fs = new FeatureStore();
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 assertFalse(FeatureStore.listContains(null, null));
649 List<SequenceFeature> features = new ArrayList<>();
650 assertFalse(FeatureStore.listContains(features, null));
652 SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
654 assertFalse(FeatureStore.listContains(null, sf1));
655 assertFalse(FeatureStore.listContains(features, sf1));
658 SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
660 SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f,
663 // sf2.equals(sf1) so contains should return true
664 assertTrue(FeatureStore.listContains(features, sf2));
665 assertFalse(FeatureStore.listContains(features, sf3));
668 @Test(groups = "Functional")
669 public void testGetFeaturesForGroup()
671 FeatureStore fs = new FeatureStore();
676 assertTrue(fs.getFeaturesForGroup(true, null).isEmpty());
677 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
678 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
679 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
682 * sf1: positional feature in the null group
684 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
687 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
688 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
689 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
690 List<SequenceFeature> features = fs.getFeaturesForGroup(true, null);
691 assertEquals(features.size(), 1);
692 assertTrue(features.contains(sf1));
695 * sf2: non-positional feature in the null group
696 * sf3: positional feature in a non-null group
697 * sf4: non-positional feature in a non-null group
699 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
701 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
703 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
709 features = fs.getFeaturesForGroup(true, null);
710 assertEquals(features.size(), 1);
711 assertTrue(features.contains(sf1));
713 features = fs.getFeaturesForGroup(false, null);
714 assertEquals(features.size(), 1);
715 assertTrue(features.contains(sf2));
717 features = fs.getFeaturesForGroup(true, "Uniprot");
718 assertEquals(features.size(), 1);
719 assertTrue(features.contains(sf3));
721 features = fs.getFeaturesForGroup(false, "Rfam");
722 assertEquals(features.size(), 1);
723 assertTrue(features.contains(sf4));
726 @Test(groups = "Functional")
727 public void testShiftFeatures()
729 FeatureStore fs = new FeatureStore();
730 assertFalse(fs.shiftFeatures(0, 1)); // nothing to do
732 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
735 SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null);
738 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
741 // non-positional feature:
742 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null);
746 * shift all features right by 5
748 assertTrue(fs.shiftFeatures(0, 5));
750 // non-positional features untouched:
751 List<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
752 assertEquals(nonPos.size(), 1);
753 assertTrue(nonPos.contains(sf4));
755 // positional features are replaced
756 List<SequenceFeature> pos = fs.getPositionalFeatures();
757 assertEquals(pos.size(), 3);
758 assertFalse(pos.contains(sf1));
759 assertFalse(pos.contains(sf2));
760 assertFalse(pos.contains(sf3));
761 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
762 assertEquals(pos.get(0).getBegin(), 7);
763 assertEquals(pos.get(0).getEnd(), 10);
764 assertEquals(pos.get(1).getBegin(), 13);
765 assertEquals(pos.get(1).getEnd(), 19);
766 assertEquals(pos.get(2).getBegin(), 28);
767 assertEquals(pos.get(2).getEnd(), 37);
770 * now shift left by 15
771 * feature at [7-10] should be removed
772 * feature at [13-19] should become [1-4]
774 assertTrue(fs.shiftFeatures(0, -15));
775 pos = fs.getPositionalFeatures();
776 assertEquals(pos.size(), 2);
777 SequenceFeatures.sortFeatures(pos, true);
778 assertEquals(pos.get(0).getBegin(), 1);
779 assertEquals(pos.get(0).getEnd(), 4);
780 assertEquals(pos.get(1).getBegin(), 13);
781 assertEquals(pos.get(1).getEnd(), 22);
784 * shift right by 4 from position 2 onwards
785 * feature at [1-4] unchanged, feature at [13-22] shifts
787 assertTrue(fs.shiftFeatures(2, 4));
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(), 17);
794 assertEquals(pos.get(1).getEnd(), 26);
797 * shift right by 4 from position 18 onwards
798 * should be no change
800 SequenceFeature f1 = pos.get(0);
801 SequenceFeature f2 = pos.get(1);
802 assertFalse(fs.shiftFeatures(18, 4)); // no update
803 pos = fs.getPositionalFeatures();
804 assertEquals(pos.size(), 2);
805 SequenceFeatures.sortFeatures(pos, true);
806 assertSame(pos.get(0), f1);
807 assertSame(pos.get(1), f2);
810 @Test(groups = "Functional")
811 public void testDelete_readd()
814 * add a feature and a nested feature
816 FeatureStore store = new FeatureStore();
817 SequenceFeature sf1 = addFeature(store, 10, 20);
818 // sf2 is nested in sf1 so will be stored in nestedFeatures
819 SequenceFeature sf2 = addFeature(store, 12, 14);
820 List<SequenceFeature> features = store.getPositionalFeatures();
821 assertEquals(features.size(), 2);
822 assertTrue(features.contains(sf1));
823 assertTrue(features.contains(sf2));
824 assertTrue(store.features.contains(sf1));
825 assertTrue(store.features.contains(sf2));
828 * delete the first feature
830 assertTrue(store.delete(sf1));
831 features = store.getPositionalFeatures();
832 assertFalse(features.contains(sf1));
833 assertTrue(features.contains(sf2));
836 * re-add the 'nested' feature; is it now duplicated?
838 store.addFeature(sf2);
839 features = store.getPositionalFeatures();
840 assertEquals(features.size(), 1);
841 assertTrue(features.contains(sf2));
844 @Test(groups = "Functional")
845 public void testContains()
847 FeatureStore fs = new FeatureStore();
848 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20, Float.NaN,
850 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20, Float.NaN,
852 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
854 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
856 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
857 Float.NaN, "group1");
858 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
859 Float.NaN, "group2");
864 assertTrue(fs.contains(sf1)); // positional feature
865 assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
866 assertFalse(fs.contains(sf2)); // different group
867 assertTrue(fs.contains(sf3)); // non-positional
868 assertTrue(fs.contains(new SequenceFeature(sf3)));
869 assertFalse(fs.contains(sf4)); // different score
870 assertTrue(fs.contains(sf5)); // contact feature
871 assertTrue(fs.contains(new SequenceFeature(sf5)));
872 assertFalse(fs.contains(sf6)); // different group
875 * add a nested feature
877 SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16, Float.NaN,
880 assertTrue(fs.contains(sf7));
881 assertTrue(fs.contains(new SequenceFeature(sf7)));
884 * delete the outer (enclosing, non-nested) feature
887 assertFalse(fs.contains(sf1));
888 assertTrue(fs.contains(sf7));