1 package jalview.datamodel.features;
3 import static org.testng.Assert.assertEquals;
4 import static org.testng.Assert.assertFalse;
5 import static org.testng.Assert.assertSame;
6 import static org.testng.Assert.assertTrue;
8 import jalview.datamodel.SequenceFeature;
10 import java.util.ArrayList;
11 import java.util.List;
14 import org.testng.annotations.Test;
16 public class FeatureStoreJSTest
19 @Test(groups = "Functional")
20 public void testFindFeatures_nonNested()
22 FeatureStoreI fs = newFeatureStore();
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);
40 assertEquals(overlaps.size(), 3);
41 // BH note, this is reversed from IS-NCList 2 1 0, not 0 1 2
42 assertEquals(overlaps.get(2).getEnd(), 20);
43 assertEquals(overlaps.get(1).getEnd(), 20);
44 assertEquals(overlaps.get(0).getEnd(), 25);
46 overlaps = fs.findOverlappingFeatures(33, 33);
47 assertEquals(overlaps.size(), 1);
48 assertEquals(overlaps.get(0).getEnd(), 35);
51 private FeatureStoreI newFeatureStore()
53 return new FeatureStoreJS();
54 // return new FeatureStoreImpl();
57 @Test(groups = "Functional")
58 public void testFindFeatures_nested()
60 FeatureStoreI fs = newFeatureStore();
61 SequenceFeature sf1 = addFeature(fs, 10, 50);
62 SequenceFeature sf2 = addFeature(fs, 10, 40);
63 SequenceFeature sf3 = addFeature(fs, 20, 30);
64 // fudge feature at same location but different group (so is added)
65 SequenceFeature sf4 = new SequenceFeature("", "", 20, 30, Float.NaN,
68 SequenceFeature sf5 = addFeature(fs, 35, 36);
70 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
71 assertTrue(overlaps.isEmpty());
73 overlaps = fs.findOverlappingFeatures(10, 15);
74 assertEquals(overlaps.size(), 2);
75 assertTrue(overlaps.contains(sf1));
76 assertTrue(overlaps.contains(sf2));
78 overlaps = fs.findOverlappingFeatures(45, 60);
79 assertEquals(overlaps.size(), 1);
80 assertTrue(overlaps.contains(sf1));
82 overlaps = fs.findOverlappingFeatures(32, 38);
83 assertEquals(overlaps.size(), 3);
84 assertTrue(overlaps.contains(sf1));
85 assertTrue(overlaps.contains(sf2));
86 assertTrue(overlaps.contains(sf5));
88 overlaps = fs.findOverlappingFeatures(15, 25);
89 assertEquals(overlaps.size(), 4);
90 assertTrue(overlaps.contains(sf1));
91 assertTrue(overlaps.contains(sf2));
92 assertTrue(overlaps.contains(sf3));
93 assertTrue(overlaps.contains(sf4));
96 @Test(groups = "Functional")
97 public void testFindFeatures_mixed()
99 FeatureStoreI fs = newFeatureStore();
100 SequenceFeature sf1 = addFeature(fs, 10, 50);
101 SequenceFeature sf2 = addFeature(fs, 1, 15);
102 SequenceFeature sf3 = addFeature(fs, 20, 30);
103 SequenceFeature sf4 = addFeature(fs, 40, 100);
104 SequenceFeature sf5 = addFeature(fs, 60, 100);
105 SequenceFeature sf6 = addFeature(fs, 70, 70);
107 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
108 assertTrue(overlaps.isEmpty());
110 overlaps = fs.findOverlappingFeatures(1, 9);
111 assertEquals(overlaps.size(), 1);
112 assertTrue(overlaps.contains(sf2));
114 overlaps = fs.findOverlappingFeatures(5, 18);
115 assertEquals(overlaps.size(), 2);
116 assertTrue(overlaps.contains(sf1));
117 assertTrue(overlaps.contains(sf2));
119 overlaps = fs.findOverlappingFeatures(30, 40);
120 assertEquals(overlaps.size(), 3);
121 assertTrue(overlaps.contains(sf1));
122 assertTrue(overlaps.contains(sf3));
123 assertTrue(overlaps.contains(sf4));
125 overlaps = fs.findOverlappingFeatures(80, 90);
126 assertEquals(overlaps.size(), 2);
127 assertTrue(overlaps.contains(sf4));
128 assertTrue(overlaps.contains(sf5));
130 overlaps = fs.findOverlappingFeatures(68, 70);
131 assertEquals(overlaps.size(), 3);
132 assertTrue(overlaps.contains(sf4));
133 assertTrue(overlaps.contains(sf5));
134 assertTrue(overlaps.contains(sf6));
138 * Helper method to add a feature of no particular type
145 SequenceFeature addFeature(FeatureStoreI fs, int from, int to)
147 SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN,
153 @Test(groups = "Functional")
154 public void testFindFeatures_contactFeatures()
156 FeatureStoreI fs = newFeatureStore();
158 SequenceFeature sf = new SequenceFeature("disulphide bond", "bond", 10,
159 20, Float.NaN, null);
163 * neither contact point in range
165 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
166 assertTrue(overlaps.isEmpty());
169 * neither contact point in range
171 overlaps = fs.findOverlappingFeatures(11, 19);
172 assertTrue(overlaps.isEmpty());
175 * first contact point in range
177 overlaps = fs.findOverlappingFeatures(5, 15);
178 assertEquals(overlaps.size(), 1);
179 assertTrue(overlaps.contains(sf));
182 * second contact point in range
184 overlaps = fs.findOverlappingFeatures(15, 25);
185 assertEquals(overlaps.size(), 1);
186 assertTrue(overlaps.contains(sf));
189 * both contact points in range
191 overlaps = fs.findOverlappingFeatures(5, 25);
192 assertEquals(overlaps.size(), 1);
193 assertTrue(overlaps.contains(sf));
196 @Test(groups = "Functional")
197 public void testGetPositionalFeatures()
199 FeatureStoreI store = newFeatureStore();
200 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
202 store.addFeature(sf1);
203 // same range, different description
204 SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
206 store.addFeature(sf2);
207 // discontiguous range
208 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40,
210 store.addFeature(sf3);
212 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35,
214 store.addFeature(sf4);
216 SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50,
218 store.addFeature(sf5);
219 // non-positional feature
220 SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0,
222 store.addFeature(sf6);
224 SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc",
225 18, 45, Float.NaN, null);
226 store.addFeature(sf7);
228 List<SequenceFeature> features = store.getPositionalFeatures();
229 assertEquals(features.size(), 6);
230 assertTrue(features.contains(sf1));
231 assertTrue(features.contains(sf2));
232 assertTrue(features.contains(sf3));
233 assertTrue(features.contains(sf4));
234 assertTrue(features.contains(sf5));
235 assertFalse(features.contains(sf6));
236 assertTrue(features.contains(sf7));
238 features = store.getNonPositionalFeatures();
239 assertEquals(features.size(), 1);
240 assertTrue(features.contains(sf6));
243 @Test(groups = "Functional")
244 public void testDelete()
246 FeatureStoreI store = newFeatureStore();
247 SequenceFeature sf1 = addFeature(store, 10, 20);
248 assertTrue(store.getPositionalFeatures().contains(sf1));
253 assertTrue(store.delete(sf1));
254 assertTrue(store.getPositionalFeatures().isEmpty());
257 * non-positional feature deletion
259 SequenceFeature sf2 = addFeature(store, 0, 0);
260 assertFalse(store.getPositionalFeatures().contains(sf2));
261 assertTrue(store.getNonPositionalFeatures().contains(sf2));
262 assertTrue(store.delete(sf2));
263 assertTrue(store.getNonPositionalFeatures().isEmpty());
266 * contact feature deletion
268 SequenceFeature sf3 = new SequenceFeature("", "Disulphide Bond", 11,
269 23, Float.NaN, null);
270 store.addFeature(sf3);
271 assertEquals(store.getPositionalFeatures().size(), 1);
272 assertTrue(store.getPositionalFeatures().contains(sf3));
273 assertTrue(store.delete(sf3));
274 assertTrue(store.getPositionalFeatures().isEmpty());
277 * nested feature deletion
279 SequenceFeature sf4 = addFeature(store, 20, 30);
280 SequenceFeature sf5 = addFeature(store, 22, 26); // to NCList
281 SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
282 SequenceFeature sf7 = addFeature(store, 25, 25); // sibling of sf6
283 SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
284 SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
285 assertEquals(store.getPositionalFeatures().size(), 6);
287 // delete a node with children - they take its place
288 assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5
289 assertEquals(store.getPositionalFeatures().size(), 5);
290 assertFalse(store.getPositionalFeatures().contains(sf6));
292 // delete a node with no children
293 assertTrue(store.delete(sf7));
294 assertEquals(store.getPositionalFeatures().size(), 4);
295 assertFalse(store.getPositionalFeatures().contains(sf7));
297 // delete root of NCList
298 assertTrue(store.delete(sf5));
299 assertEquals(store.getPositionalFeatures().size(), 3);
300 assertFalse(store.getPositionalFeatures().contains(sf5));
302 // continue the killing fields
303 assertTrue(store.delete(sf4));
304 assertEquals(store.getPositionalFeatures().size(), 2);
305 assertFalse(store.getPositionalFeatures().contains(sf4));
307 assertTrue(store.delete(sf9));
308 assertEquals(store.getPositionalFeatures().size(), 1);
309 assertFalse(store.getPositionalFeatures().contains(sf9));
311 assertTrue(store.delete(sf8));
312 assertTrue(store.getPositionalFeatures().isEmpty());
315 @Test(groups = "Functional")
316 public void testAddFeature()
318 FeatureStoreI fs = newFeatureStore();
320 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
322 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
325 assertTrue(fs.addFeature(sf1));
326 assertEquals(fs.getFeatureCount(true), 1); // positional
327 assertEquals(fs.getFeatureCount(false), 0); // non-positional
330 * re-adding the same or an identical feature should fail
332 assertFalse(fs.addFeature(sf1));
333 assertEquals(fs.getFeatureCount(true), 1);
334 assertFalse(fs.addFeature(sf2));
335 assertEquals(fs.getFeatureCount(true), 1);
340 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
342 assertTrue(fs.addFeature(sf3));
343 assertEquals(fs.getFeatureCount(true), 1); // positional
344 assertEquals(fs.getFeatureCount(false), 1); // non-positional
345 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
347 assertFalse(fs.addFeature(sf4)); // already stored
348 assertEquals(fs.getFeatureCount(true), 1); // positional
349 assertEquals(fs.getFeatureCount(false), 1); // non-positional
354 SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20,
356 assertTrue(fs.addFeature(sf5));
357 assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact
358 assertEquals(fs.getFeatureCount(false), 1); // non-positional
359 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20,
361 assertFalse(fs.addFeature(sf6)); // already stored
362 assertEquals(fs.getFeatureCount(true), 2); // no change
363 assertEquals(fs.getFeatureCount(false), 1); // no change
366 @Test(groups = "Functional")
367 public void testIsEmpty()
369 FeatureStoreI fs = newFeatureStore();
370 assertTrue(fs.isEmpty());
371 assertEquals(fs.getFeatureCount(true), 0);
376 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
379 assertFalse(fs.isEmpty());
380 assertEquals(fs.getFeatureCount(true), 1);
382 assertTrue(fs.isEmpty());
383 assertEquals(fs.getFeatureCount(true), 0);
386 * non-positional feature
388 sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null);
390 assertFalse(fs.isEmpty());
391 assertEquals(fs.getFeatureCount(false), 1); // non-positional
392 assertEquals(fs.getFeatureCount(true), 0); // positional
394 assertTrue(fs.isEmpty());
395 assertEquals(fs.getFeatureCount(false), 0);
400 sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN, null);
402 assertFalse(fs.isEmpty());
403 assertEquals(fs.getFeatureCount(true), 1);
405 assertTrue(fs.isEmpty());
406 assertEquals(fs.getFeatureCount(true), 0);
409 * sf2, sf3 added as nested features
411 sf1 = new SequenceFeature("Cath", "", 19, 49, Float.NaN, null);
412 SequenceFeature sf2 = new SequenceFeature("Cath", "", 20, 40,
414 SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35,
419 assertEquals(fs.getFeatureCount(true), 3);
420 assertTrue(fs.delete(sf1));
421 assertEquals(fs.getFeatureCount(true), 2);
422 assertEquals(fs.getFeatures().size(), 2);
423 assertFalse(fs.isEmpty());
424 assertTrue(fs.delete(sf2));
425 assertEquals(fs.getFeatureCount(true), 1);
426 assertFalse(fs.isEmpty());
427 assertTrue(fs.delete(sf3));
428 assertEquals(fs.getFeatureCount(true), 0);
429 assertTrue(fs.isEmpty()); // all gone
432 @Test(groups = "Functional")
433 public void testGetFeatureGroups()
435 FeatureStoreI fs = newFeatureStore();
436 assertTrue(fs.getFeatureGroups(true).isEmpty());
437 assertTrue(fs.getFeatureGroups(false).isEmpty());
439 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
441 Set<String> groups = fs.getFeatureGroups(true);
442 assertEquals(groups.size(), 1);
443 assertTrue(groups.contains("group1"));
446 * add another feature of the same group, delete one, delete both
448 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group1");
450 groups = fs.getFeatureGroups(true);
451 assertEquals(groups.size(), 1);
452 assertTrue(groups.contains("group1"));
454 groups = fs.getFeatureGroups(true);
455 assertEquals(groups.size(), 1);
456 assertTrue(groups.contains("group1"));
458 groups = fs.getFeatureGroups(true);
459 assertTrue(fs.getFeatureGroups(true).isEmpty());
461 SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group2");
463 SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "Group2");
465 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f, null);
467 groups = fs.getFeatureGroups(true);
468 assertEquals(groups.size(), 3);
469 assertTrue(groups.contains("group2"));
470 assertTrue(groups.contains("Group2")); // case sensitive
471 assertTrue(groups.contains(null)); // null allowed
472 assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional
475 groups = fs.getFeatureGroups(true);
476 assertEquals(groups.size(), 2);
477 assertFalse(groups.contains("group2"));
479 groups = fs.getFeatureGroups(true);
480 assertEquals(groups.size(), 1);
481 assertFalse(groups.contains("Group2"));
483 groups = fs.getFeatureGroups(true);
484 assertTrue(groups.isEmpty());
487 * add non-positional feature
489 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
492 groups = fs.getFeatureGroups(false);
493 assertEquals(groups.size(), 1);
494 assertTrue(groups.contains("CathGroup"));
495 assertTrue(fs.delete(sf6));
496 assertTrue(fs.getFeatureGroups(false).isEmpty());
499 @Test(groups = "Functional")
500 public void testGetTotalFeatureLength()
502 FeatureStoreI fs = newFeatureStore();
503 assertEquals(fs.getTotalFeatureLength(), 0);
505 addFeature(fs, 10, 20); // 11
506 assertEquals(fs.getTotalFeatureLength(), 11);
507 addFeature(fs, 17, 37); // 21
508 SequenceFeature sf1 = addFeature(fs, 14, 74); // 61
509 assertEquals(fs.getTotalFeatureLength(), 93);
511 // non-positional features don't count
512 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
515 assertEquals(fs.getTotalFeatureLength(), 93);
517 // contact features count 1
518 SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc",
519 15, 35, 1f, "group1");
521 assertEquals(fs.getTotalFeatureLength(), 94);
523 assertTrue(fs.delete(sf1));
524 assertEquals(fs.getTotalFeatureLength(), 33);
525 assertFalse(fs.delete(sf1));
526 assertEquals(fs.getTotalFeatureLength(), 33);
527 assertTrue(fs.delete(sf2));
528 assertEquals(fs.getTotalFeatureLength(), 33);
529 assertTrue(fs.delete(sf3));
530 assertEquals(fs.getTotalFeatureLength(), 32);
533 @Test(groups = "Functional")
534 public void testGetFeatureLength()
539 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
540 assertEquals(FeatureStore.getFeatureLength(sf1), 11);
543 * non-positional feature
545 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
547 assertEquals(FeatureStore.getFeatureLength(sf2), 0);
550 * contact feature counts 1
552 SequenceFeature sf3 = new SequenceFeature("Disulphide Bond", "desc",
553 14, 28, 1f, "AGroup");
554 assertEquals(FeatureStore.getFeatureLength(sf3), 1);
557 @Test(groups = "Functional")
558 public void testMin()
560 assertEquals(FeatureStore.min(Float.NaN, Float.NaN), Float.NaN);
561 assertEquals(FeatureStore.min(Float.NaN, 2f), 2f);
562 assertEquals(FeatureStore.min(-2f, Float.NaN), -2f);
563 assertEquals(FeatureStore.min(2f, -3f), -3f);
566 @Test(groups = "Functional")
567 public void testMax()
569 assertEquals(FeatureStore.max(Float.NaN, Float.NaN), Float.NaN);
570 assertEquals(FeatureStore.max(Float.NaN, 2f), 2f);
571 assertEquals(FeatureStore.max(-2f, Float.NaN), -2f);
572 assertEquals(FeatureStore.max(2f, -3f), 2f);
575 @Test(groups = "Functional")
576 public void testGetMinimumScore_getMaximumScore()
578 FeatureStoreI fs = newFeatureStore();
579 assertEquals(fs.getMinimumScore(true), Float.NaN); // positional
580 assertEquals(fs.getMaximumScore(true), Float.NaN);
581 assertEquals(fs.getMinimumScore(false), Float.NaN); // non-positional
582 assertEquals(fs.getMaximumScore(false), Float.NaN);
584 // add features with no score
585 SequenceFeature sf1 = new SequenceFeature("type", "desc", 0, 0,
588 SequenceFeature sf2 = new SequenceFeature("type", "desc", 10, 20,
591 assertEquals(fs.getMinimumScore(true), Float.NaN);
592 assertEquals(fs.getMaximumScore(true), Float.NaN);
593 assertEquals(fs.getMinimumScore(false), Float.NaN);
594 assertEquals(fs.getMaximumScore(false), Float.NaN);
596 // add positional features with score
597 SequenceFeature sf3 = new SequenceFeature("type", "desc", 10, 20, 1f,
600 SequenceFeature sf4 = new SequenceFeature("type", "desc", 12, 16, 4f,
603 assertEquals(fs.getMinimumScore(true), 1f);
604 assertEquals(fs.getMaximumScore(true), 4f);
605 assertEquals(fs.getMinimumScore(false), Float.NaN);
606 assertEquals(fs.getMaximumScore(false), Float.NaN);
608 // add non-positional features with score
609 SequenceFeature sf5 = new SequenceFeature("type", "desc", 0, 0, 11f,
612 SequenceFeature sf6 = new SequenceFeature("type", "desc", 0, 0, -7f,
615 assertEquals(fs.getMinimumScore(true), 1f);
616 assertEquals(fs.getMaximumScore(true), 4f);
617 assertEquals(fs.getMinimumScore(false), -7f);
618 assertEquals(fs.getMaximumScore(false), 11f);
620 // delete one positional and one non-positional
621 // min-max should be recomputed
622 assertTrue(fs.delete(sf6));
623 assertTrue(fs.delete(sf3));
624 assertEquals(fs.getMinimumScore(true), 4f);
625 assertEquals(fs.getMaximumScore(true), 4f);
626 assertEquals(fs.getMinimumScore(false), 11f);
627 assertEquals(fs.getMaximumScore(false), 11f);
629 // delete remaining features with score
630 assertTrue(fs.delete(sf4));
631 assertTrue(fs.delete(sf5));
632 assertEquals(fs.getMinimumScore(true), Float.NaN);
633 assertEquals(fs.getMaximumScore(true), Float.NaN);
634 assertEquals(fs.getMinimumScore(false), Float.NaN);
635 assertEquals(fs.getMaximumScore(false), Float.NaN);
637 // delete all features
638 assertTrue(fs.delete(sf1));
639 assertTrue(fs.delete(sf2));
640 assertTrue(fs.isEmpty());
641 assertEquals(fs.getMinimumScore(true), Float.NaN);
642 assertEquals(fs.getMaximumScore(true), Float.NaN);
643 assertEquals(fs.getMinimumScore(false), Float.NaN);
644 assertEquals(fs.getMaximumScore(false), Float.NaN);
647 @Test(groups = "Functional")
648 public void testListContains()
650 FeatureStoreI featureStore = newFeatureStore();
651 assertFalse(featureStore.listContains(null, null));
652 List<SequenceFeature> features = new ArrayList<>();
653 assertFalse(featureStore.listContains(features, null));
655 SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
657 assertFalse(featureStore.listContains(null, sf1));
658 assertFalse(featureStore.listContains(features, sf1));
661 SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
663 SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f,
666 // sf2.equals(sf1) so contains should return true
667 assertTrue(featureStore.listContains(features, sf2));
668 assertFalse(featureStore.listContains(features, sf3));
671 @Test(groups = "Functional")
672 public void testGetFeaturesForGroup()
674 FeatureStoreI fs = newFeatureStore();
679 assertTrue(fs.getFeaturesForGroup(true, null).isEmpty());
680 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
681 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
682 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
685 * sf1: positional feature in the null group
687 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
690 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
691 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
692 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
693 List<SequenceFeature> features = fs.getFeaturesForGroup(true, null);
694 assertEquals(features.size(), 1);
695 assertTrue(features.contains(sf1));
698 * sf2: non-positional feature in the null group
699 * sf3: positional feature in a non-null group
700 * sf4: non-positional feature in a non-null group
702 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
704 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
706 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
712 features = fs.getFeaturesForGroup(true, null);
713 assertEquals(features.size(), 1);
714 assertTrue(features.contains(sf1));
716 features = fs.getFeaturesForGroup(false, null);
717 assertEquals(features.size(), 1);
718 assertTrue(features.contains(sf2));
720 features = fs.getFeaturesForGroup(true, "Uniprot");
721 assertEquals(features.size(), 1);
722 assertTrue(features.contains(sf3));
724 features = fs.getFeaturesForGroup(false, "Rfam");
725 assertEquals(features.size(), 1);
726 assertTrue(features.contains(sf4));
729 @Test(groups = "Functional")
730 public void testShiftFeatures()
732 FeatureStoreI fs = newFeatureStore();
733 assertFalse(fs.shiftFeatures(0, 1)); // nothing to do
735 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
738 SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null);
741 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
744 // non-positional feature:
745 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null);
749 * shift all features right by 5
751 assertTrue(fs.shiftFeatures(0, 5));
753 // non-positional features untouched:
754 List<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
755 assertEquals(nonPos.size(), 1);
756 assertTrue(nonPos.contains(sf4));
758 // positional features are replaced
759 List<SequenceFeature> pos = fs.getPositionalFeatures();
760 assertEquals(pos.size(), 3);
761 assertFalse(pos.contains(sf1));
762 assertFalse(pos.contains(sf2));
763 assertFalse(pos.contains(sf3));
764 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
765 assertEquals(pos.get(0).getBegin(), 7);
766 assertEquals(pos.get(0).getEnd(), 10);
767 assertEquals(pos.get(1).getBegin(), 13);
768 assertEquals(pos.get(1).getEnd(), 19);
769 assertEquals(pos.get(2).getBegin(), 28);
770 assertEquals(pos.get(2).getEnd(), 37);
773 * now shift left by 15
774 * feature at [7-10] should be removed
775 * feature at [13-19] should become [1-4]
777 assertTrue(fs.shiftFeatures(0, -15));
778 pos = fs.getPositionalFeatures();
779 assertEquals(pos.size(), 2);
780 SequenceFeatures.sortFeatures(pos, true);
781 assertEquals(pos.get(0).getBegin(), 1);
782 assertEquals(pos.get(0).getEnd(), 4);
783 assertEquals(pos.get(1).getBegin(), 13);
784 assertEquals(pos.get(1).getEnd(), 22);
787 * shift right by 4 from position 2 onwards
788 * feature at [1-4] unchanged, feature at [13-22] shifts
790 assertTrue(fs.shiftFeatures(2, 4));
791 pos = fs.getPositionalFeatures();
792 assertEquals(pos.size(), 2);
793 SequenceFeatures.sortFeatures(pos, true);
794 assertEquals(pos.get(0).getBegin(), 1);
795 assertEquals(pos.get(0).getEnd(), 4);
796 assertEquals(pos.get(1).getBegin(), 17);
797 assertEquals(pos.get(1).getEnd(), 26);
800 * shift right by 4 from position 18 onwards
801 * should be no change
803 SequenceFeature f1 = pos.get(0);
804 SequenceFeature f2 = pos.get(1);
805 assertFalse(fs.shiftFeatures(18, 4)); // no update
806 pos = fs.getPositionalFeatures();
807 assertEquals(pos.size(), 2);
808 SequenceFeatures.sortFeatures(pos, true);
809 assertSame(pos.get(0), f1);
810 assertSame(pos.get(1), f2);
813 @Test(groups = "Functional")
814 public void testDelete_readd()
817 * add a feature and a nested feature
819 FeatureStoreI store = newFeatureStore();
820 SequenceFeature sf1 = addFeature(store, 10, 20);
821 // sf2 is nested in sf1 so will be stored in nestedFeatures
822 SequenceFeature sf2 = addFeature(store, 12, 14);
823 List<SequenceFeature> features = store.getPositionalFeatures();
824 assertEquals(features.size(), 2);
825 assertTrue(features.contains(sf1));
826 assertTrue(features.contains(sf2));
827 assertTrue(store.getFeatures().contains(sf1));
828 assertTrue(store.getFeatures().contains(sf2));
831 * delete the first feature
833 assertTrue(store.delete(sf1));
834 features = store.getPositionalFeatures();
835 assertFalse(features.contains(sf1));
836 assertTrue(features.contains(sf2));
839 * re-add the 'nested' feature; is it now duplicated?
841 store.addFeature(sf2);
842 features = store.getPositionalFeatures();
843 assertEquals(features.size(), 1);
844 assertTrue(features.contains(sf2));
847 @Test(groups = "Functional")
848 public void testContains()
850 FeatureStoreI fs = newFeatureStore();
851 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
852 Float.NaN, "group1");
853 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
854 Float.NaN, "group2");
855 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
857 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
859 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
860 Float.NaN, "group1");
861 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
862 Float.NaN, "group2");
867 assertTrue(fs.contains(sf1)); // positional feature
868 assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
869 assertFalse(fs.contains(sf2)); // different group
870 assertTrue(fs.contains(sf3)); // non-positional
871 assertTrue(fs.contains(new SequenceFeature(sf3)));
872 assertFalse(fs.contains(sf4)); // different score
873 assertTrue(fs.contains(sf5)); // contact feature
874 assertTrue(fs.contains(new SequenceFeature(sf5)));
875 assertFalse(fs.contains(sf6)); // different group
878 * add a nested feature
880 SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16,
881 Float.NaN, "group1");
883 assertTrue(fs.contains(sf7));
884 assertTrue(fs.contains(new SequenceFeature(sf7)));
887 * delete the outer (enclosing, non-nested) feature
890 assertFalse(fs.contains(sf1));
891 assertTrue(fs.contains(sf7));