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,
25 // same range different description
26 fs.addFeature(new SequenceFeature("", "desc", 10, 20, Float.NaN, null));
27 fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
28 fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
30 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
31 assertTrue(overlaps.isEmpty());
33 overlaps = fs.findOverlappingFeatures(8, 10);
34 assertEquals(overlaps.size(), 2);
35 assertEquals(overlaps.get(0).getEnd(), 20);
36 assertEquals(overlaps.get(1).getEnd(), 20);
38 overlaps = fs.findOverlappingFeatures(12, 16);
39 assertEquals(overlaps.size(), 3);
40 assertEquals(overlaps.get(0).getEnd(), 20);
41 assertEquals(overlaps.get(1).getEnd(), 20);
42 assertEquals(overlaps.get(2).getEnd(), 25);
44 overlaps = fs.findOverlappingFeatures(33, 33);
45 assertEquals(overlaps.size(), 1);
46 assertEquals(overlaps.get(0).getEnd(), 35);
49 @Test(groups = "Functional")
50 public void testFindFeatures_nested()
52 FeatureStore fs = new FeatureStore();
53 SequenceFeature sf1 = addFeature(fs, 10, 50);
54 SequenceFeature sf2 = addFeature(fs, 10, 40);
55 SequenceFeature sf3 = addFeature(fs, 20, 30);
56 // fudge feature at same location but different group (so is added)
57 SequenceFeature sf4 = new SequenceFeature("", "", 20, 30, Float.NaN,
60 SequenceFeature sf5 = addFeature(fs, 35, 36);
62 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
63 assertTrue(overlaps.isEmpty());
65 overlaps = fs.findOverlappingFeatures(10, 15);
66 assertEquals(overlaps.size(), 2);
67 assertTrue(overlaps.contains(sf1));
68 assertTrue(overlaps.contains(sf2));
70 overlaps = fs.findOverlappingFeatures(45, 60);
71 assertEquals(overlaps.size(), 1);
72 assertTrue(overlaps.contains(sf1));
74 overlaps = fs.findOverlappingFeatures(32, 38);
75 assertEquals(overlaps.size(), 3);
76 assertTrue(overlaps.contains(sf1));
77 assertTrue(overlaps.contains(sf2));
78 assertTrue(overlaps.contains(sf5));
80 overlaps = fs.findOverlappingFeatures(15, 25);
81 assertEquals(overlaps.size(), 4);
82 assertTrue(overlaps.contains(sf1));
83 assertTrue(overlaps.contains(sf2));
84 assertTrue(overlaps.contains(sf3));
85 assertTrue(overlaps.contains(sf4));
88 @Test(groups = "Functional")
89 public void testFindFeatures_mixed()
91 FeatureStore fs = new FeatureStore();
92 SequenceFeature sf1 = addFeature(fs, 10, 50);
93 SequenceFeature sf2 = addFeature(fs, 1, 15);
94 SequenceFeature sf3 = addFeature(fs, 20, 30);
95 SequenceFeature sf4 = addFeature(fs, 40, 100);
96 SequenceFeature sf5 = addFeature(fs, 60, 100);
97 SequenceFeature sf6 = addFeature(fs, 70, 70);
99 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
100 assertTrue(overlaps.isEmpty());
102 overlaps = fs.findOverlappingFeatures(1, 9);
103 assertEquals(overlaps.size(), 1);
104 assertTrue(overlaps.contains(sf2));
106 overlaps = fs.findOverlappingFeatures(5, 18);
107 assertEquals(overlaps.size(), 2);
108 assertTrue(overlaps.contains(sf1));
109 assertTrue(overlaps.contains(sf2));
111 overlaps = fs.findOverlappingFeatures(30, 40);
112 assertEquals(overlaps.size(), 3);
113 assertTrue(overlaps.contains(sf1));
114 assertTrue(overlaps.contains(sf3));
115 assertTrue(overlaps.contains(sf4));
117 overlaps = fs.findOverlappingFeatures(80, 90);
118 assertEquals(overlaps.size(), 2);
119 assertTrue(overlaps.contains(sf4));
120 assertTrue(overlaps.contains(sf5));
122 overlaps = fs.findOverlappingFeatures(68, 70);
123 assertEquals(overlaps.size(), 3);
124 assertTrue(overlaps.contains(sf4));
125 assertTrue(overlaps.contains(sf5));
126 assertTrue(overlaps.contains(sf6));
130 * Helper method to add a feature of no particular type
137 SequenceFeature addFeature(FeatureStore fs, int from, int to)
139 SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN,
145 @Test(groups = "Functional")
146 public void testFindFeatures_contactFeatures()
148 FeatureStore fs = new FeatureStore();
150 SequenceFeature sf = new SequenceFeature("disulphide bond", "bond", 10,
151 20, Float.NaN, null);
155 * neither contact point in range
157 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
158 assertTrue(overlaps.isEmpty());
161 * neither contact point in range
163 overlaps = fs.findOverlappingFeatures(11, 19);
164 assertTrue(overlaps.isEmpty());
167 * first contact point in range
169 overlaps = fs.findOverlappingFeatures(5, 15);
170 assertEquals(overlaps.size(), 1);
171 assertTrue(overlaps.contains(sf));
174 * second contact point in range
176 overlaps = fs.findOverlappingFeatures(15, 25);
177 assertEquals(overlaps.size(), 1);
178 assertTrue(overlaps.contains(sf));
181 * both contact points in range
183 overlaps = fs.findOverlappingFeatures(5, 25);
184 assertEquals(overlaps.size(), 1);
185 assertTrue(overlaps.contains(sf));
188 @Test(groups = "Functional")
189 public void testGetPositionalFeatures()
191 FeatureStore store = new FeatureStore();
192 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
194 store.addFeature(sf1);
195 // same range, different description
196 SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
198 store.addFeature(sf2);
199 // discontiguous range
200 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40,
202 store.addFeature(sf3);
204 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35,
206 store.addFeature(sf4);
208 SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50,
210 store.addFeature(sf5);
211 // non-positional feature
212 SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0,
214 store.addFeature(sf6);
216 SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc",
217 18, 45, Float.NaN, null);
218 store.addFeature(sf7);
220 List<SequenceFeature> features = store.getPositionalFeatures();
221 assertEquals(features.size(), 6);
222 assertTrue(features.contains(sf1));
223 assertTrue(features.contains(sf2));
224 assertTrue(features.contains(sf3));
225 assertTrue(features.contains(sf4));
226 assertTrue(features.contains(sf5));
227 assertFalse(features.contains(sf6));
228 assertTrue(features.contains(sf7));
230 features = store.getNonPositionalFeatures();
231 assertEquals(features.size(), 1);
232 assertTrue(features.contains(sf6));
235 @Test(groups = "Functional")
236 public void testDelete()
238 FeatureStore store = new FeatureStore();
239 SequenceFeature sf1 = addFeature(store, 10, 20);
240 assertTrue(store.getPositionalFeatures().contains(sf1));
245 assertTrue(store.delete(sf1));
246 assertTrue(store.getPositionalFeatures().isEmpty());
249 * non-positional feature deletion
251 SequenceFeature sf2 = addFeature(store, 0, 0);
252 assertFalse(store.getPositionalFeatures().contains(sf2));
253 assertTrue(store.getNonPositionalFeatures().contains(sf2));
254 assertTrue(store.delete(sf2));
255 assertTrue(store.getNonPositionalFeatures().isEmpty());
258 * contact feature deletion
260 SequenceFeature sf3 = new SequenceFeature("", "Disulphide Bond", 11,
261 23, Float.NaN, null);
262 store.addFeature(sf3);
263 assertEquals(store.getPositionalFeatures().size(), 1);
264 assertTrue(store.getPositionalFeatures().contains(sf3));
265 assertTrue(store.delete(sf3));
266 assertTrue(store.getPositionalFeatures().isEmpty());
269 * nested feature deletion
271 SequenceFeature sf4 = addFeature(store, 20, 30);
272 SequenceFeature sf5 = addFeature(store, 22, 26); // to NCList
273 SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
274 SequenceFeature sf7 = addFeature(store, 25, 25); // sibling of sf6
275 SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
276 SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
277 assertEquals(store.getPositionalFeatures().size(), 6);
279 // delete a node with children - they take its place
280 assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5
281 assertEquals(store.getPositionalFeatures().size(), 5);
282 assertFalse(store.getPositionalFeatures().contains(sf6));
284 // delete a node with no children
285 assertTrue(store.delete(sf7));
286 assertEquals(store.getPositionalFeatures().size(), 4);
287 assertFalse(store.getPositionalFeatures().contains(sf7));
289 // delete root of NCList
290 assertTrue(store.delete(sf5));
291 assertEquals(store.getPositionalFeatures().size(), 3);
292 assertFalse(store.getPositionalFeatures().contains(sf5));
294 // continue the killing fields
295 assertTrue(store.delete(sf4));
296 assertEquals(store.getPositionalFeatures().size(), 2);
297 assertFalse(store.getPositionalFeatures().contains(sf4));
299 assertTrue(store.delete(sf9));
300 assertEquals(store.getPositionalFeatures().size(), 1);
301 assertFalse(store.getPositionalFeatures().contains(sf9));
303 assertTrue(store.delete(sf8));
304 assertTrue(store.getPositionalFeatures().isEmpty());
307 @Test(groups = "Functional")
308 public void testAddFeature()
310 FeatureStore fs = new FeatureStore();
312 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
314 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
317 assertTrue(fs.addFeature(sf1));
318 assertEquals(fs.getFeatureCount(true), 1); // positional
319 assertEquals(fs.getFeatureCount(false), 0); // non-positional
322 * re-adding the same or an identical feature should fail
324 assertFalse(fs.addFeature(sf1));
325 assertEquals(fs.getFeatureCount(true), 1);
326 assertFalse(fs.addFeature(sf2));
327 assertEquals(fs.getFeatureCount(true), 1);
332 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
334 assertTrue(fs.addFeature(sf3));
335 assertEquals(fs.getFeatureCount(true), 1); // positional
336 assertEquals(fs.getFeatureCount(false), 1); // non-positional
337 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
339 assertFalse(fs.addFeature(sf4)); // already stored
340 assertEquals(fs.getFeatureCount(true), 1); // positional
341 assertEquals(fs.getFeatureCount(false), 1); // non-positional
346 SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20,
348 assertTrue(fs.addFeature(sf5));
349 assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact
350 assertEquals(fs.getFeatureCount(false), 1); // non-positional
351 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20,
353 assertFalse(fs.addFeature(sf6)); // already stored
354 assertEquals(fs.getFeatureCount(true), 2); // no change
355 assertEquals(fs.getFeatureCount(false), 1); // no change
358 @Test(groups = "Functional")
359 public void testIsEmpty()
361 FeatureStore fs = new FeatureStore();
362 assertTrue(fs.isEmpty());
363 assertEquals(fs.getFeatureCount(true), 0);
368 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
371 assertFalse(fs.isEmpty());
372 assertEquals(fs.getFeatureCount(true), 1);
374 assertTrue(fs.isEmpty());
375 assertEquals(fs.getFeatureCount(true), 0);
378 * non-positional feature
380 sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null);
382 assertFalse(fs.isEmpty());
383 assertEquals(fs.getFeatureCount(false), 1); // non-positional
384 assertEquals(fs.getFeatureCount(true), 0); // positional
386 assertTrue(fs.isEmpty());
387 assertEquals(fs.getFeatureCount(false), 0);
392 sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN, null);
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,
406 SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35,
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, "group1");
433 Set<String> groups = fs.getFeatureGroups(true);
434 assertEquals(groups.size(), 1);
435 assertTrue(groups.contains("group1"));
438 * add another feature of the same group, delete one, delete both
440 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group1");
442 groups = fs.getFeatureGroups(true);
443 assertEquals(groups.size(), 1);
444 assertTrue(groups.contains("group1"));
446 groups = fs.getFeatureGroups(true);
447 assertEquals(groups.size(), 1);
448 assertTrue(groups.contains("group1"));
450 groups = fs.getFeatureGroups(true);
451 assertTrue(fs.getFeatureGroups(true).isEmpty());
453 SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group2");
455 SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "Group2");
457 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f, null);
459 groups = fs.getFeatureGroups(true);
460 assertEquals(groups.size(), 3);
461 assertTrue(groups.contains("group2"));
462 assertTrue(groups.contains("Group2")); // case sensitive
463 assertTrue(groups.contains(null)); // null allowed
464 assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional
467 groups = fs.getFeatureGroups(true);
468 assertEquals(groups.size(), 2);
469 assertFalse(groups.contains("group2"));
471 groups = fs.getFeatureGroups(true);
472 assertEquals(groups.size(), 1);
473 assertFalse(groups.contains("Group2"));
475 groups = fs.getFeatureGroups(true);
476 assertTrue(groups.isEmpty());
479 * add non-positional feature
481 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
484 groups = fs.getFeatureGroups(false);
485 assertEquals(groups.size(), 1);
486 assertTrue(groups.contains("CathGroup"));
487 assertTrue(fs.delete(sf6));
488 assertTrue(fs.getFeatureGroups(false).isEmpty());
491 @Test(groups = "Functional")
492 public void testGetTotalFeatureLength()
494 FeatureStore fs = new FeatureStore();
495 assertEquals(fs.getTotalFeatureLength(), 0);
497 addFeature(fs, 10, 20); // 11
498 assertEquals(fs.getTotalFeatureLength(), 11);
499 addFeature(fs, 17, 37); // 21
500 SequenceFeature sf1 = addFeature(fs, 14, 74); // 61
501 assertEquals(fs.getTotalFeatureLength(), 93);
503 // non-positional features don't count
504 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
507 assertEquals(fs.getTotalFeatureLength(), 93);
509 // contact features count 1
510 SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc",
511 15, 35, 1f, "group1");
513 assertEquals(fs.getTotalFeatureLength(), 94);
515 assertTrue(fs.delete(sf1));
516 assertEquals(fs.getTotalFeatureLength(), 33);
517 assertFalse(fs.delete(sf1));
518 assertEquals(fs.getTotalFeatureLength(), 33);
519 assertTrue(fs.delete(sf2));
520 assertEquals(fs.getTotalFeatureLength(), 33);
521 assertTrue(fs.delete(sf3));
522 assertEquals(fs.getTotalFeatureLength(), 32);
525 @Test(groups = "Functional")
526 public void testGetFeatureLength()
531 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
532 assertEquals(FeatureStore.getFeatureLength(sf1), 11);
535 * non-positional feature
537 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
539 assertEquals(FeatureStore.getFeatureLength(sf2), 0);
542 * contact feature counts 1
544 SequenceFeature sf3 = new SequenceFeature("Disulphide Bond", "desc",
545 14, 28, 1f, "AGroup");
546 assertEquals(FeatureStore.getFeatureLength(sf3), 1);
549 @Test(groups = "Functional")
550 public void testMin()
552 assertEquals(FeatureStore.min(Float.NaN, Float.NaN), Float.NaN);
553 assertEquals(FeatureStore.min(Float.NaN, 2f), 2f);
554 assertEquals(FeatureStore.min(-2f, Float.NaN), -2f);
555 assertEquals(FeatureStore.min(2f, -3f), -3f);
558 @Test(groups = "Functional")
559 public void testMax()
561 assertEquals(FeatureStore.max(Float.NaN, Float.NaN), Float.NaN);
562 assertEquals(FeatureStore.max(Float.NaN, 2f), 2f);
563 assertEquals(FeatureStore.max(-2f, Float.NaN), -2f);
564 assertEquals(FeatureStore.max(2f, -3f), 2f);
567 @Test(groups = "Functional")
568 public void testGetMinimumScore_getMaximumScore()
570 FeatureStore fs = new FeatureStore();
571 assertEquals(fs.getMinimumScore(true), Float.NaN); // positional
572 assertEquals(fs.getMaximumScore(true), Float.NaN);
573 assertEquals(fs.getMinimumScore(false), Float.NaN); // non-positional
574 assertEquals(fs.getMaximumScore(false), Float.NaN);
576 // add features with no score
577 SequenceFeature sf1 = new SequenceFeature("type", "desc", 0, 0,
580 SequenceFeature sf2 = new SequenceFeature("type", "desc", 10, 20,
583 assertEquals(fs.getMinimumScore(true), Float.NaN);
584 assertEquals(fs.getMaximumScore(true), Float.NaN);
585 assertEquals(fs.getMinimumScore(false), Float.NaN);
586 assertEquals(fs.getMaximumScore(false), Float.NaN);
588 // add positional features with score
589 SequenceFeature sf3 = new SequenceFeature("type", "desc", 10, 20, 1f,
592 SequenceFeature sf4 = new SequenceFeature("type", "desc", 12, 16, 4f,
595 assertEquals(fs.getMinimumScore(true), 1f);
596 assertEquals(fs.getMaximumScore(true), 4f);
597 assertEquals(fs.getMinimumScore(false), Float.NaN);
598 assertEquals(fs.getMaximumScore(false), Float.NaN);
600 // add non-positional features with score
601 SequenceFeature sf5 = new SequenceFeature("type", "desc", 0, 0, 11f,
604 SequenceFeature sf6 = new SequenceFeature("type", "desc", 0, 0, -7f,
607 assertEquals(fs.getMinimumScore(true), 1f);
608 assertEquals(fs.getMaximumScore(true), 4f);
609 assertEquals(fs.getMinimumScore(false), -7f);
610 assertEquals(fs.getMaximumScore(false), 11f);
612 // delete one positional and one non-positional
613 // min-max should be recomputed
614 assertTrue(fs.delete(sf6));
615 assertTrue(fs.delete(sf3));
616 assertEquals(fs.getMinimumScore(true), 4f);
617 assertEquals(fs.getMaximumScore(true), 4f);
618 assertEquals(fs.getMinimumScore(false), 11f);
619 assertEquals(fs.getMaximumScore(false), 11f);
621 // delete remaining features with score
622 assertTrue(fs.delete(sf4));
623 assertTrue(fs.delete(sf5));
624 assertEquals(fs.getMinimumScore(true), Float.NaN);
625 assertEquals(fs.getMaximumScore(true), Float.NaN);
626 assertEquals(fs.getMinimumScore(false), Float.NaN);
627 assertEquals(fs.getMaximumScore(false), Float.NaN);
629 // delete all features
630 assertTrue(fs.delete(sf1));
631 assertTrue(fs.delete(sf2));
632 assertTrue(fs.isEmpty());
633 assertEquals(fs.getMinimumScore(true), Float.NaN);
634 assertEquals(fs.getMaximumScore(true), Float.NaN);
635 assertEquals(fs.getMinimumScore(false), Float.NaN);
636 assertEquals(fs.getMaximumScore(false), Float.NaN);
639 @Test(groups = "Functional")
640 public void testListContains()
642 assertFalse(FeatureStore.listContains(null, null));
643 List<SequenceFeature> features = new ArrayList<>();
644 assertFalse(FeatureStore.listContains(features, null));
646 SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
648 assertFalse(FeatureStore.listContains(null, sf1));
649 assertFalse(FeatureStore.listContains(features, sf1));
652 SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
654 SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f,
657 // sf2.equals(sf1) so contains should return true
658 assertTrue(FeatureStore.listContains(features, sf2));
659 assertFalse(FeatureStore.listContains(features, sf3));
662 @Test(groups = "Functional")
663 public void testGetFeaturesForGroup()
665 FeatureStore fs = new FeatureStore();
670 assertTrue(fs.getFeaturesForGroup(true, null).isEmpty());
671 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
672 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
673 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
676 * sf1: positional feature in the null group
678 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
681 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
682 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
683 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
684 List<SequenceFeature> features = fs.getFeaturesForGroup(true, null);
685 assertEquals(features.size(), 1);
686 assertTrue(features.contains(sf1));
689 * sf2: non-positional feature in the null group
690 * sf3: positional feature in a non-null group
691 * sf4: non-positional feature in a non-null group
693 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
695 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
697 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
703 features = fs.getFeaturesForGroup(true, null);
704 assertEquals(features.size(), 1);
705 assertTrue(features.contains(sf1));
707 features = fs.getFeaturesForGroup(false, null);
708 assertEquals(features.size(), 1);
709 assertTrue(features.contains(sf2));
711 features = fs.getFeaturesForGroup(true, "Uniprot");
712 assertEquals(features.size(), 1);
713 assertTrue(features.contains(sf3));
715 features = fs.getFeaturesForGroup(false, "Rfam");
716 assertEquals(features.size(), 1);
717 assertTrue(features.contains(sf4));
720 @Test(groups = "Functional")
721 public void testShiftFeatures()
723 FeatureStore fs = new FeatureStore();
724 assertFalse(fs.shiftFeatures(0, 1)); // nothing to do
726 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
729 SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null);
732 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
735 // non-positional feature:
736 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null);
740 * shift all features right by 5
742 assertTrue(fs.shiftFeatures(0, 5));
744 // non-positional features untouched:
745 List<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
746 assertEquals(nonPos.size(), 1);
747 assertTrue(nonPos.contains(sf4));
749 // positional features are replaced
750 List<SequenceFeature> pos = fs.getPositionalFeatures();
751 assertEquals(pos.size(), 3);
752 assertFalse(pos.contains(sf1));
753 assertFalse(pos.contains(sf2));
754 assertFalse(pos.contains(sf3));
755 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
756 assertEquals(pos.get(0).getBegin(), 7);
757 assertEquals(pos.get(0).getEnd(), 10);
758 assertEquals(pos.get(1).getBegin(), 13);
759 assertEquals(pos.get(1).getEnd(), 19);
760 assertEquals(pos.get(2).getBegin(), 28);
761 assertEquals(pos.get(2).getEnd(), 37);
764 * now shift left by 15
765 * feature at [7-10] should be removed
766 * feature at [13-19] should become [1-4]
768 assertTrue(fs.shiftFeatures(0, -15));
769 pos = fs.getPositionalFeatures();
770 assertEquals(pos.size(), 2);
771 SequenceFeatures.sortFeatures(pos, true);
772 assertEquals(pos.get(0).getBegin(), 1);
773 assertEquals(pos.get(0).getEnd(), 4);
774 assertEquals(pos.get(1).getBegin(), 13);
775 assertEquals(pos.get(1).getEnd(), 22);
778 * shift right by 4 from position 2 onwards
779 * feature at [1-4] unchanged, feature at [13-22] shifts
781 assertTrue(fs.shiftFeatures(2, 4));
782 pos = fs.getPositionalFeatures();
783 assertEquals(pos.size(), 2);
784 SequenceFeatures.sortFeatures(pos, true);
785 assertEquals(pos.get(0).getBegin(), 1);
786 assertEquals(pos.get(0).getEnd(), 4);
787 assertEquals(pos.get(1).getBegin(), 17);
788 assertEquals(pos.get(1).getEnd(), 26);
791 * shift right by 4 from position 18 onwards
792 * should be no change
794 SequenceFeature f1 = pos.get(0);
795 SequenceFeature f2 = pos.get(1);
796 assertFalse(fs.shiftFeatures(18, 4)); // no update
797 pos = fs.getPositionalFeatures();
798 assertEquals(pos.size(), 2);
799 SequenceFeatures.sortFeatures(pos, true);
800 assertSame(pos.get(0), f1);
801 assertSame(pos.get(1), f2);
804 @Test(groups = "Functional")
805 public void testDelete_readd()
808 * add a feature and a nested feature
810 FeatureStore store = new FeatureStore();
811 SequenceFeature sf1 = addFeature(store, 10, 20);
812 // sf2 is nested in sf1 so will be stored in nestedFeatures
813 SequenceFeature sf2 = addFeature(store, 12, 14);
814 List<SequenceFeature> features = store.getPositionalFeatures();
815 assertEquals(features.size(), 2);
816 assertTrue(features.contains(sf1));
817 assertTrue(features.contains(sf2));
818 assertTrue(store.features.contains(sf1));
819 assertTrue(store.features.contains(sf2));
822 * delete the first feature
824 assertTrue(store.delete(sf1));
825 features = store.getPositionalFeatures();
826 assertFalse(features.contains(sf1));
827 assertTrue(features.contains(sf2));
830 * re-add the 'nested' feature; is it now duplicated?
832 store.addFeature(sf2);
833 features = store.getPositionalFeatures();
834 assertEquals(features.size(), 1);
835 assertTrue(features.contains(sf2));
838 @Test(groups = "Functional")
839 public void testContains()
841 FeatureStore fs = new FeatureStore();
842 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
843 Float.NaN, "group1");
844 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
845 Float.NaN, "group2");
846 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
848 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
850 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
851 Float.NaN, "group1");
852 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
853 Float.NaN, "group2");
858 assertTrue(fs.contains(sf1)); // positional feature
859 assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
860 assertFalse(fs.contains(sf2)); // different group
861 assertTrue(fs.contains(sf3)); // non-positional
862 assertTrue(fs.contains(new SequenceFeature(sf3)));
863 assertFalse(fs.contains(sf4)); // different score
864 assertTrue(fs.contains(sf5)); // contact feature
865 assertTrue(fs.contains(new SequenceFeature(sf5)));
866 assertFalse(fs.contains(sf6)); // different group
869 * add a nested feature
871 SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16,
872 Float.NaN, "group1");
874 assertTrue(fs.contains(sf7));
875 assertTrue(fs.contains(new SequenceFeature(sf7)));
878 * delete the outer (enclosing, non-nested) feature
881 assertFalse(fs.contains(sf1));
882 assertTrue(fs.contains(sf7));