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 assertEquals(overlaps.get(0).getEnd(), 20);
42 assertEquals(overlaps.get(1).getEnd(), 20);
43 assertEquals(overlaps.get(2).getEnd(), 25);
45 overlaps = fs.findOverlappingFeatures(33, 33);
46 assertEquals(overlaps.size(), 1);
47 assertEquals(overlaps.get(0).getEnd(), 35);
50 private FeatureStoreI newFeatureStore()
52 return new FeatureStoreJS();
53 // return new FeatureStoreImpl();
56 @Test(groups = "Functional")
57 public void testFindFeatures_nested()
59 FeatureStoreI fs = newFeatureStore();
60 SequenceFeature sf1 = addFeature(fs, 10, 50);
61 SequenceFeature sf2 = addFeature(fs, 10, 40);
62 SequenceFeature sf3 = addFeature(fs, 20, 30);
63 // fudge feature at same location but different group (so is added)
64 SequenceFeature sf4 = new SequenceFeature("", "", 20, 30, Float.NaN,
67 SequenceFeature sf5 = addFeature(fs, 35, 36);
69 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
70 assertTrue(overlaps.isEmpty());
72 overlaps = fs.findOverlappingFeatures(10, 15);
73 assertEquals(overlaps.size(), 2);
74 assertTrue(overlaps.contains(sf1));
75 assertTrue(overlaps.contains(sf2));
77 overlaps = fs.findOverlappingFeatures(45, 60);
78 assertEquals(overlaps.size(), 1);
79 assertTrue(overlaps.contains(sf1));
81 overlaps = fs.findOverlappingFeatures(32, 38);
82 assertEquals(overlaps.size(), 3);
83 assertTrue(overlaps.contains(sf1));
84 assertTrue(overlaps.contains(sf2));
85 assertTrue(overlaps.contains(sf5));
87 overlaps = fs.findOverlappingFeatures(15, 25);
88 assertEquals(overlaps.size(), 4);
89 assertTrue(overlaps.contains(sf1));
90 assertTrue(overlaps.contains(sf2));
91 assertTrue(overlaps.contains(sf3));
92 assertTrue(overlaps.contains(sf4));
95 @Test(groups = "Functional")
96 public void testFindFeatures_mixed()
98 FeatureStoreI fs = newFeatureStore();
99 SequenceFeature sf1 = addFeature(fs, 10, 50);
100 SequenceFeature sf2 = addFeature(fs, 1, 15);
101 SequenceFeature sf3 = addFeature(fs, 20, 30);
102 SequenceFeature sf4 = addFeature(fs, 40, 100);
103 SequenceFeature sf5 = addFeature(fs, 60, 100);
104 SequenceFeature sf6 = addFeature(fs, 70, 70);
106 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
107 assertTrue(overlaps.isEmpty());
109 overlaps = fs.findOverlappingFeatures(1, 9);
110 assertEquals(overlaps.size(), 1);
111 assertTrue(overlaps.contains(sf2));
113 overlaps = fs.findOverlappingFeatures(5, 18);
114 assertEquals(overlaps.size(), 2);
115 assertTrue(overlaps.contains(sf1));
116 assertTrue(overlaps.contains(sf2));
118 overlaps = fs.findOverlappingFeatures(30, 40);
119 assertEquals(overlaps.size(), 3);
120 assertTrue(overlaps.contains(sf1));
121 assertTrue(overlaps.contains(sf3));
122 assertTrue(overlaps.contains(sf4));
124 overlaps = fs.findOverlappingFeatures(80, 90);
125 assertEquals(overlaps.size(), 2);
126 assertTrue(overlaps.contains(sf4));
127 assertTrue(overlaps.contains(sf5));
129 overlaps = fs.findOverlappingFeatures(68, 70);
130 assertEquals(overlaps.size(), 3);
131 assertTrue(overlaps.contains(sf4));
132 assertTrue(overlaps.contains(sf5));
133 assertTrue(overlaps.contains(sf6));
137 * Helper method to add a feature of no particular type
144 SequenceFeature addFeature(FeatureStoreI fs, int from, int to)
146 SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN,
152 @Test(groups = "Functional")
153 public void testFindFeatures_contactFeatures()
155 FeatureStoreI fs = newFeatureStore();
157 SequenceFeature sf = new SequenceFeature("disulphide bond", "bond", 10,
158 20, Float.NaN, null);
162 * neither contact point in range
164 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
165 assertTrue(overlaps.isEmpty());
168 * neither contact point in range
170 overlaps = fs.findOverlappingFeatures(11, 19);
171 assertTrue(overlaps.isEmpty());
174 * first contact point in range
176 overlaps = fs.findOverlappingFeatures(5, 15);
177 assertEquals(overlaps.size(), 1);
178 assertTrue(overlaps.contains(sf));
181 * second contact point in range
183 overlaps = fs.findOverlappingFeatures(15, 25);
184 assertEquals(overlaps.size(), 1);
185 assertTrue(overlaps.contains(sf));
188 * both contact points in range
190 overlaps = fs.findOverlappingFeatures(5, 25);
191 assertEquals(overlaps.size(), 1);
192 assertTrue(overlaps.contains(sf));
195 @Test(groups = "Functional")
196 public void testGetPositionalFeatures()
198 FeatureStoreI store = newFeatureStore();
199 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
201 store.addFeature(sf1);
202 // same range, different description
203 SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
205 store.addFeature(sf2);
206 // discontiguous range
207 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40,
209 store.addFeature(sf3);
211 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35,
213 store.addFeature(sf4);
215 SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50,
217 store.addFeature(sf5);
218 // non-positional feature
219 SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0,
221 store.addFeature(sf6);
223 SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc",
224 18, 45, Float.NaN, null);
225 store.addFeature(sf7);
227 List<SequenceFeature> features = store.getPositionalFeatures();
228 assertEquals(features.size(), 6);
229 assertTrue(features.contains(sf1));
230 assertTrue(features.contains(sf2));
231 assertTrue(features.contains(sf3));
232 assertTrue(features.contains(sf4));
233 assertTrue(features.contains(sf5));
234 assertFalse(features.contains(sf6));
235 assertTrue(features.contains(sf7));
237 features = store.getNonPositionalFeatures();
238 assertEquals(features.size(), 1);
239 assertTrue(features.contains(sf6));
242 @Test(groups = "Functional")
243 public void testDelete()
245 FeatureStoreI store = newFeatureStore();
246 SequenceFeature sf1 = addFeature(store, 10, 20);
247 assertTrue(store.getPositionalFeatures().contains(sf1));
252 assertTrue(store.delete(sf1));
253 assertTrue(store.getPositionalFeatures().isEmpty());
256 * non-positional feature deletion
258 SequenceFeature sf2 = addFeature(store, 0, 0);
259 assertFalse(store.getPositionalFeatures().contains(sf2));
260 assertTrue(store.getNonPositionalFeatures().contains(sf2));
261 assertTrue(store.delete(sf2));
262 assertTrue(store.getNonPositionalFeatures().isEmpty());
265 * contact feature deletion
267 SequenceFeature sf3 = new SequenceFeature("", "Disulphide Bond", 11,
268 23, Float.NaN, null);
269 store.addFeature(sf3);
270 assertEquals(store.getPositionalFeatures().size(), 1);
271 assertTrue(store.getPositionalFeatures().contains(sf3));
272 assertTrue(store.delete(sf3));
273 assertTrue(store.getPositionalFeatures().isEmpty());
276 * nested feature deletion
278 SequenceFeature sf4 = addFeature(store, 20, 30);
279 SequenceFeature sf5 = addFeature(store, 22, 26); // to NCList
280 SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
281 SequenceFeature sf7 = addFeature(store, 25, 25); // sibling of sf6
282 SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
283 SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
284 assertEquals(store.getPositionalFeatures().size(), 6);
286 // delete a node with children - they take its place
287 assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5
288 assertEquals(store.getPositionalFeatures().size(), 5);
289 assertFalse(store.getPositionalFeatures().contains(sf6));
291 // delete a node with no children
292 assertTrue(store.delete(sf7));
293 assertEquals(store.getPositionalFeatures().size(), 4);
294 assertFalse(store.getPositionalFeatures().contains(sf7));
296 // delete root of NCList
297 assertTrue(store.delete(sf5));
298 assertEquals(store.getPositionalFeatures().size(), 3);
299 assertFalse(store.getPositionalFeatures().contains(sf5));
301 // continue the killing fields
302 assertTrue(store.delete(sf4));
303 assertEquals(store.getPositionalFeatures().size(), 2);
304 assertFalse(store.getPositionalFeatures().contains(sf4));
306 assertTrue(store.delete(sf9));
307 assertEquals(store.getPositionalFeatures().size(), 1);
308 assertFalse(store.getPositionalFeatures().contains(sf9));
310 assertTrue(store.delete(sf8));
311 assertTrue(store.getPositionalFeatures().isEmpty());
314 @Test(groups = "Functional")
315 public void testAddFeature()
317 FeatureStoreI fs = newFeatureStore();
319 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
321 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
324 assertTrue(fs.addFeature(sf1));
325 assertEquals(fs.getFeatureCount(true), 1); // positional
326 assertEquals(fs.getFeatureCount(false), 0); // non-positional
329 * re-adding the same or an identical feature should fail
331 assertFalse(fs.addFeature(sf1));
332 assertEquals(fs.getFeatureCount(true), 1);
333 assertFalse(fs.addFeature(sf2));
334 assertEquals(fs.getFeatureCount(true), 1);
339 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
341 assertTrue(fs.addFeature(sf3));
342 assertEquals(fs.getFeatureCount(true), 1); // positional
343 assertEquals(fs.getFeatureCount(false), 1); // non-positional
344 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
346 assertFalse(fs.addFeature(sf4)); // already stored
347 assertEquals(fs.getFeatureCount(true), 1); // positional
348 assertEquals(fs.getFeatureCount(false), 1); // non-positional
353 SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20,
355 assertTrue(fs.addFeature(sf5));
356 assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact
357 assertEquals(fs.getFeatureCount(false), 1); // non-positional
358 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20,
360 assertFalse(fs.addFeature(sf6)); // already stored
361 assertEquals(fs.getFeatureCount(true), 2); // no change
362 assertEquals(fs.getFeatureCount(false), 1); // no change
365 @Test(groups = "Functional")
366 public void testIsEmpty()
368 FeatureStoreI fs = newFeatureStore();
369 assertTrue(fs.isEmpty());
370 assertEquals(fs.getFeatureCount(true), 0);
375 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
378 assertFalse(fs.isEmpty());
379 assertEquals(fs.getFeatureCount(true), 1);
381 assertTrue(fs.isEmpty());
382 assertEquals(fs.getFeatureCount(true), 0);
385 * non-positional feature
387 sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null);
389 assertFalse(fs.isEmpty());
390 assertEquals(fs.getFeatureCount(false), 1); // non-positional
391 assertEquals(fs.getFeatureCount(true), 0); // positional
393 assertTrue(fs.isEmpty());
394 assertEquals(fs.getFeatureCount(false), 0);
399 sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN, null);
401 assertFalse(fs.isEmpty());
402 assertEquals(fs.getFeatureCount(true), 1);
404 assertTrue(fs.isEmpty());
405 assertEquals(fs.getFeatureCount(true), 0);
408 * sf2, sf3 added as nested features
410 sf1 = new SequenceFeature("Cath", "", 19, 49, Float.NaN, null);
411 SequenceFeature sf2 = new SequenceFeature("Cath", "", 20, 40,
413 SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35,
418 assertEquals(fs.getFeatureCount(true), 3);
419 assertTrue(fs.delete(sf1));
420 assertEquals(fs.getFeatureCount(true), 2);
421 assertEquals(fs.getFeatures().size(), 2);
422 assertFalse(fs.isEmpty());
423 assertTrue(fs.delete(sf2));
424 assertEquals(fs.getFeatureCount(true), 1);
425 assertFalse(fs.isEmpty());
426 assertTrue(fs.delete(sf3));
427 assertEquals(fs.getFeatureCount(true), 0);
428 assertTrue(fs.isEmpty()); // all gone
431 @Test(groups = "Functional")
432 public void testGetFeatureGroups()
434 FeatureStoreI fs = newFeatureStore();
435 assertTrue(fs.getFeatureGroups(true).isEmpty());
436 assertTrue(fs.getFeatureGroups(false).isEmpty());
438 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
440 Set<String> groups = fs.getFeatureGroups(true);
441 assertEquals(groups.size(), 1);
442 assertTrue(groups.contains("group1"));
445 * add another feature of the same group, delete one, delete both
447 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group1");
449 groups = fs.getFeatureGroups(true);
450 assertEquals(groups.size(), 1);
451 assertTrue(groups.contains("group1"));
453 groups = fs.getFeatureGroups(true);
454 assertEquals(groups.size(), 1);
455 assertTrue(groups.contains("group1"));
457 groups = fs.getFeatureGroups(true);
458 assertTrue(fs.getFeatureGroups(true).isEmpty());
460 SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group2");
462 SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "Group2");
464 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f, null);
466 groups = fs.getFeatureGroups(true);
467 assertEquals(groups.size(), 3);
468 assertTrue(groups.contains("group2"));
469 assertTrue(groups.contains("Group2")); // case sensitive
470 assertTrue(groups.contains(null)); // null allowed
471 assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional
474 groups = fs.getFeatureGroups(true);
475 assertEquals(groups.size(), 2);
476 assertFalse(groups.contains("group2"));
478 groups = fs.getFeatureGroups(true);
479 assertEquals(groups.size(), 1);
480 assertFalse(groups.contains("Group2"));
482 groups = fs.getFeatureGroups(true);
483 assertTrue(groups.isEmpty());
486 * add non-positional feature
488 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
491 groups = fs.getFeatureGroups(false);
492 assertEquals(groups.size(), 1);
493 assertTrue(groups.contains("CathGroup"));
494 assertTrue(fs.delete(sf6));
495 assertTrue(fs.getFeatureGroups(false).isEmpty());
498 @Test(groups = "Functional")
499 public void testGetTotalFeatureLength()
501 FeatureStoreI fs = newFeatureStore();
502 assertEquals(fs.getTotalFeatureLength(), 0);
504 addFeature(fs, 10, 20); // 11
505 assertEquals(fs.getTotalFeatureLength(), 11);
506 addFeature(fs, 17, 37); // 21
507 SequenceFeature sf1 = addFeature(fs, 14, 74); // 61
508 assertEquals(fs.getTotalFeatureLength(), 93);
510 // non-positional features don't count
511 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
514 assertEquals(fs.getTotalFeatureLength(), 93);
516 // contact features count 1
517 SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc",
518 15, 35, 1f, "group1");
520 assertEquals(fs.getTotalFeatureLength(), 94);
522 assertTrue(fs.delete(sf1));
523 assertEquals(fs.getTotalFeatureLength(), 33);
524 assertFalse(fs.delete(sf1));
525 assertEquals(fs.getTotalFeatureLength(), 33);
526 assertTrue(fs.delete(sf2));
527 assertEquals(fs.getTotalFeatureLength(), 33);
528 assertTrue(fs.delete(sf3));
529 assertEquals(fs.getTotalFeatureLength(), 32);
532 @Test(groups = "Functional")
533 public void testGetFeatureLength()
538 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
539 assertEquals(FeatureStore.getFeatureLength(sf1), 11);
542 * non-positional feature
544 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
546 assertEquals(FeatureStore.getFeatureLength(sf2), 0);
549 * contact feature counts 1
551 SequenceFeature sf3 = new SequenceFeature("Disulphide Bond", "desc",
552 14, 28, 1f, "AGroup");
553 assertEquals(FeatureStore.getFeatureLength(sf3), 1);
556 @Test(groups = "Functional")
557 public void testMin()
559 assertEquals(FeatureStore.min(Float.NaN, Float.NaN), Float.NaN);
560 assertEquals(FeatureStore.min(Float.NaN, 2f), 2f);
561 assertEquals(FeatureStore.min(-2f, Float.NaN), -2f);
562 assertEquals(FeatureStore.min(2f, -3f), -3f);
565 @Test(groups = "Functional")
566 public void testMax()
568 assertEquals(FeatureStore.max(Float.NaN, Float.NaN), Float.NaN);
569 assertEquals(FeatureStore.max(Float.NaN, 2f), 2f);
570 assertEquals(FeatureStore.max(-2f, Float.NaN), -2f);
571 assertEquals(FeatureStore.max(2f, -3f), 2f);
574 @Test(groups = "Functional")
575 public void testGetMinimumScore_getMaximumScore()
577 FeatureStoreI fs = newFeatureStore();
578 assertEquals(fs.getMinimumScore(true), Float.NaN); // positional
579 assertEquals(fs.getMaximumScore(true), Float.NaN);
580 assertEquals(fs.getMinimumScore(false), Float.NaN); // non-positional
581 assertEquals(fs.getMaximumScore(false), Float.NaN);
583 // add features with no score
584 SequenceFeature sf1 = new SequenceFeature("type", "desc", 0, 0,
587 SequenceFeature sf2 = new SequenceFeature("type", "desc", 10, 20,
590 assertEquals(fs.getMinimumScore(true), Float.NaN);
591 assertEquals(fs.getMaximumScore(true), Float.NaN);
592 assertEquals(fs.getMinimumScore(false), Float.NaN);
593 assertEquals(fs.getMaximumScore(false), Float.NaN);
595 // add positional features with score
596 SequenceFeature sf3 = new SequenceFeature("type", "desc", 10, 20, 1f,
599 SequenceFeature sf4 = new SequenceFeature("type", "desc", 12, 16, 4f,
602 assertEquals(fs.getMinimumScore(true), 1f);
603 assertEquals(fs.getMaximumScore(true), 4f);
604 assertEquals(fs.getMinimumScore(false), Float.NaN);
605 assertEquals(fs.getMaximumScore(false), Float.NaN);
607 // add non-positional features with score
608 SequenceFeature sf5 = new SequenceFeature("type", "desc", 0, 0, 11f,
611 SequenceFeature sf6 = new SequenceFeature("type", "desc", 0, 0, -7f,
614 assertEquals(fs.getMinimumScore(true), 1f);
615 assertEquals(fs.getMaximumScore(true), 4f);
616 assertEquals(fs.getMinimumScore(false), -7f);
617 assertEquals(fs.getMaximumScore(false), 11f);
619 // delete one positional and one non-positional
620 // min-max should be recomputed
621 assertTrue(fs.delete(sf6));
622 assertTrue(fs.delete(sf3));
623 assertEquals(fs.getMinimumScore(true), 4f);
624 assertEquals(fs.getMaximumScore(true), 4f);
625 assertEquals(fs.getMinimumScore(false), 11f);
626 assertEquals(fs.getMaximumScore(false), 11f);
628 // delete remaining features with score
629 assertTrue(fs.delete(sf4));
630 assertTrue(fs.delete(sf5));
631 assertEquals(fs.getMinimumScore(true), Float.NaN);
632 assertEquals(fs.getMaximumScore(true), Float.NaN);
633 assertEquals(fs.getMinimumScore(false), Float.NaN);
634 assertEquals(fs.getMaximumScore(false), Float.NaN);
636 // delete all features
637 assertTrue(fs.delete(sf1));
638 assertTrue(fs.delete(sf2));
639 assertTrue(fs.isEmpty());
640 assertEquals(fs.getMinimumScore(true), Float.NaN);
641 assertEquals(fs.getMaximumScore(true), Float.NaN);
642 assertEquals(fs.getMinimumScore(false), Float.NaN);
643 assertEquals(fs.getMaximumScore(false), Float.NaN);
646 @Test(groups = "Functional")
647 public void testListContains()
649 FeatureStoreI featureStore = newFeatureStore();
650 assertFalse(featureStore.listContains(null, null));
651 List<SequenceFeature> features = new ArrayList<>();
652 assertFalse(featureStore.listContains(features, null));
654 SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
656 assertFalse(featureStore.listContains(null, sf1));
657 assertFalse(featureStore.listContains(features, sf1));
660 SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
662 SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f,
665 // sf2.equals(sf1) so contains should return true
666 assertTrue(featureStore.listContains(features, sf2));
667 assertFalse(featureStore.listContains(features, sf3));
670 @Test(groups = "Functional")
671 public void testGetFeaturesForGroup()
673 FeatureStoreI fs = newFeatureStore();
678 assertTrue(fs.getFeaturesForGroup(true, null).isEmpty());
679 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
680 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
681 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
684 * sf1: positional feature in the null group
686 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
689 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
690 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
691 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
692 List<SequenceFeature> features = fs.getFeaturesForGroup(true, null);
693 assertEquals(features.size(), 1);
694 assertTrue(features.contains(sf1));
697 * sf2: non-positional feature in the null group
698 * sf3: positional feature in a non-null group
699 * sf4: non-positional feature in a non-null group
701 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
703 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
705 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
711 features = fs.getFeaturesForGroup(true, null);
712 assertEquals(features.size(), 1);
713 assertTrue(features.contains(sf1));
715 features = fs.getFeaturesForGroup(false, null);
716 assertEquals(features.size(), 1);
717 assertTrue(features.contains(sf2));
719 features = fs.getFeaturesForGroup(true, "Uniprot");
720 assertEquals(features.size(), 1);
721 assertTrue(features.contains(sf3));
723 features = fs.getFeaturesForGroup(false, "Rfam");
724 assertEquals(features.size(), 1);
725 assertTrue(features.contains(sf4));
728 @Test(groups = "Functional")
729 public void testShiftFeatures()
731 FeatureStoreI fs = newFeatureStore();
732 assertFalse(fs.shiftFeatures(0, 1)); // nothing to do
734 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
737 SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null);
740 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
743 // non-positional feature:
744 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null);
748 * shift all features right by 5
750 assertTrue(fs.shiftFeatures(0, 5));
752 // non-positional features untouched:
753 List<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
754 assertEquals(nonPos.size(), 1);
755 assertTrue(nonPos.contains(sf4));
757 // positional features are replaced
758 List<SequenceFeature> pos = fs.getPositionalFeatures();
759 assertEquals(pos.size(), 3);
760 assertFalse(pos.contains(sf1));
761 assertFalse(pos.contains(sf2));
762 assertFalse(pos.contains(sf3));
763 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
764 assertEquals(pos.get(0).getBegin(), 7);
765 assertEquals(pos.get(0).getEnd(), 10);
766 assertEquals(pos.get(1).getBegin(), 13);
767 assertEquals(pos.get(1).getEnd(), 19);
768 assertEquals(pos.get(2).getBegin(), 28);
769 assertEquals(pos.get(2).getEnd(), 37);
772 * now shift left by 15
773 * feature at [7-10] should be removed
774 * feature at [13-19] should become [1-4]
776 assertTrue(fs.shiftFeatures(0, -15));
777 pos = fs.getPositionalFeatures();
778 assertEquals(pos.size(), 2);
779 SequenceFeatures.sortFeatures(pos, true);
780 assertEquals(pos.get(0).getBegin(), 1);
781 assertEquals(pos.get(0).getEnd(), 4);
782 assertEquals(pos.get(1).getBegin(), 13);
783 assertEquals(pos.get(1).getEnd(), 22);
786 * shift right by 4 from position 2 onwards
787 * feature at [1-4] unchanged, feature at [13-22] shifts
789 assertTrue(fs.shiftFeatures(2, 4));
790 pos = fs.getPositionalFeatures();
791 assertEquals(pos.size(), 2);
792 SequenceFeatures.sortFeatures(pos, true);
793 assertEquals(pos.get(0).getBegin(), 1);
794 assertEquals(pos.get(0).getEnd(), 4);
795 assertEquals(pos.get(1).getBegin(), 17);
796 assertEquals(pos.get(1).getEnd(), 26);
799 * shift right by 4 from position 18 onwards
800 * should be no change
802 SequenceFeature f1 = pos.get(0);
803 SequenceFeature f2 = pos.get(1);
804 assertFalse(fs.shiftFeatures(18, 4)); // no update
805 pos = fs.getPositionalFeatures();
806 assertEquals(pos.size(), 2);
807 SequenceFeatures.sortFeatures(pos, true);
808 assertSame(pos.get(0), f1);
809 assertSame(pos.get(1), f2);
812 @Test(groups = "Functional")
813 public void testDelete_readd()
816 * add a feature and a nested feature
818 FeatureStoreI store = newFeatureStore();
819 SequenceFeature sf1 = addFeature(store, 10, 20);
820 // sf2 is nested in sf1 so will be stored in nestedFeatures
821 SequenceFeature sf2 = addFeature(store, 12, 14);
822 List<SequenceFeature> features = store.getPositionalFeatures();
823 assertEquals(features.size(), 2);
824 assertTrue(features.contains(sf1));
825 assertTrue(features.contains(sf2));
826 assertTrue(store.getFeatures().contains(sf1));
827 assertTrue(store.getFeatures().contains(sf2));
830 * delete the first feature
832 assertTrue(store.delete(sf1));
833 features = store.getPositionalFeatures();
834 assertFalse(features.contains(sf1));
835 assertTrue(features.contains(sf2));
838 * re-add the 'nested' feature; is it now duplicated?
840 store.addFeature(sf2);
841 features = store.getPositionalFeatures();
842 assertEquals(features.size(), 1);
843 assertTrue(features.contains(sf2));
846 @Test(groups = "Functional")
847 public void testContains()
849 FeatureStoreI fs = newFeatureStore();
850 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
851 Float.NaN, "group1");
852 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
853 Float.NaN, "group2");
854 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
856 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
858 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
859 Float.NaN, "group1");
860 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
861 Float.NaN, "group2");
866 assertTrue(fs.contains(sf1)); // positional feature
867 assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
868 assertFalse(fs.contains(sf2)); // different group
869 assertTrue(fs.contains(sf3)); // non-positional
870 assertTrue(fs.contains(new SequenceFeature(sf3)));
871 assertFalse(fs.contains(sf4)); // different score
872 assertTrue(fs.contains(sf5)); // contact feature
873 assertTrue(fs.contains(new SequenceFeature(sf5)));
874 assertFalse(fs.contains(sf6)); // different group
877 * add a nested feature
879 SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16,
880 Float.NaN, "group1");
882 assertTrue(fs.contains(sf7));
883 assertTrue(fs.contains(new SequenceFeature(sf7)));
886 * delete the outer (enclosing, non-nested) feature
889 assertFalse(fs.contains(sf1));
890 assertTrue(fs.contains(sf7));