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;
9 import jalview.datamodel.features.FeatureStore.IntervalStoreType;
11 import java.util.ArrayList;
12 import java.util.List;
15 import org.testng.annotations.Test;
18 * Tests that exercise the 'NC array' implementation of IntervalStore
20 public class FeatureStoreNCListBufferTest
22 private FeatureStore newFeatureStore()
24 return new FeatureStore(IntervalStoreType.INTERVAL_STORE_NCARRAY);
27 @Test(groups = "Functional")
28 public void testFindFeatures_nonNested()
30 FeatureStore fs = newFeatureStore();
31 fs.addFeature(new SequenceFeature("", "", 10, 20, Float.NaN,
33 // same range different description
34 fs.addFeature(new SequenceFeature("", "desc", 10, 20, Float.NaN, null));
35 fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
36 fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
38 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
39 assertTrue(overlaps.isEmpty());
41 overlaps = fs.findOverlappingFeatures(8, 10);
42 assertEquals(overlaps.size(), 2);
43 assertEquals(overlaps.get(0).getEnd(), 20);
44 assertEquals(overlaps.get(1).getEnd(), 20);
46 overlaps = fs.findOverlappingFeatures(12, 16);
47 assertEquals(overlaps.size(), 3);
48 assertEquals(overlaps.get(0).getEnd(), 20);
49 assertEquals(overlaps.get(1).getEnd(), 20);
50 assertEquals(overlaps.get(2).getEnd(), 25);
52 overlaps = fs.findOverlappingFeatures(33, 33);
53 assertEquals(overlaps.size(), 1);
54 assertEquals(overlaps.get(0).getEnd(), 35);
57 @Test(groups = "Functional")
58 public void testFindFeatures_nested()
60 FeatureStore 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 FeatureStore 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(FeatureStore fs, int from, int to)
147 SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN,
153 @Test(groups = "Functional")
154 public void testFindFeatures_contactFeatures()
156 FeatureStore 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 FeatureStore 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 FeatureStore 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
286 // SequenceFeature sf4 = addFeature(store, 20, 30);
287 //// SequenceFeature sf5 = addFeature(store, 22, 26);
288 ////// SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
289 //////// SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
290 //////// SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
291 ////// SequenceFeature sf7 = addFeature(store, 25, 25); // child of sf5
293 assertEquals(store.getPositionalFeatures().size(), 6);
295 // delete a node with children - they take its place
296 assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5
297 assertEquals(store.getPositionalFeatures().size(), 5);
298 assertFalse(store.getPositionalFeatures().contains(sf6));
300 // delete a node with no children
301 assertTrue(store.delete(sf7));
302 assertEquals(store.getPositionalFeatures().size(), 4);
303 assertFalse(store.getPositionalFeatures().contains(sf7));
305 // delete root of NCList
306 assertTrue(store.delete(sf5));
307 assertEquals(store.getPositionalFeatures().size(), 3);
308 assertFalse(store.getPositionalFeatures().contains(sf5));
310 // continue the killing fields
311 assertTrue(store.delete(sf4));
312 assertEquals(store.getPositionalFeatures().size(), 2);
313 assertFalse(store.getPositionalFeatures().contains(sf4));
315 assertTrue(store.delete(sf9));
316 assertEquals(store.getPositionalFeatures().size(), 1);
317 assertFalse(store.getPositionalFeatures().contains(sf9));
319 assertTrue(store.delete(sf8));
320 assertTrue(store.getPositionalFeatures().isEmpty());
323 @Test(groups = "Functional")
324 public void testAddFeature()
326 FeatureStore fs = newFeatureStore();
328 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
330 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
333 assertTrue(fs.addFeature(sf1));
334 assertEquals(fs.getFeatureCount(true), 1); // positional
335 assertEquals(fs.getFeatureCount(false), 0); // non-positional
338 * re-adding the same or an identical feature should fail
340 assertFalse(fs.addFeature(sf1));
341 assertEquals(fs.getFeatureCount(true), 1);
342 assertFalse(fs.addFeature(sf2));
343 assertEquals(fs.getFeatureCount(true), 1);
348 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
350 assertTrue(fs.addFeature(sf3));
351 assertEquals(fs.getFeatureCount(true), 1); // positional
352 assertEquals(fs.getFeatureCount(false), 1); // non-positional
353 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
355 assertFalse(fs.addFeature(sf4)); // already stored
356 assertEquals(fs.getFeatureCount(true), 1); // positional
357 assertEquals(fs.getFeatureCount(false), 1); // non-positional
362 SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20,
364 assertTrue(fs.addFeature(sf5));
365 assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact
366 assertEquals(fs.getFeatureCount(false), 1); // non-positional
367 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20,
369 assertFalse(fs.addFeature(sf6)); // already stored
370 assertEquals(fs.getFeatureCount(true), 2); // no change
371 assertEquals(fs.getFeatureCount(false), 1); // no change
374 @Test(groups = "Functional")
375 public void testIsEmpty()
377 FeatureStore fs = newFeatureStore();
378 assertTrue(fs.isEmpty());
379 assertEquals(fs.getFeatureCount(true), 0);
384 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
387 assertFalse(fs.isEmpty());
388 assertEquals(fs.getFeatureCount(true), 1);
390 assertTrue(fs.isEmpty());
391 assertEquals(fs.getFeatureCount(true), 0);
394 * non-positional feature
396 sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null);
398 assertFalse(fs.isEmpty());
399 assertEquals(fs.getFeatureCount(false), 1); // non-positional
400 assertEquals(fs.getFeatureCount(true), 0); // positional
402 assertTrue(fs.isEmpty());
403 assertEquals(fs.getFeatureCount(false), 0);
408 sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN, null);
410 assertFalse(fs.isEmpty());
411 assertEquals(fs.getFeatureCount(true), 1);
413 assertTrue(fs.isEmpty());
414 assertEquals(fs.getFeatureCount(true), 0);
417 * sf2, sf3 added as nested features
419 sf1 = new SequenceFeature("Cath", "", 19, 49, Float.NaN, null);
420 SequenceFeature sf2 = new SequenceFeature("Cath", "", 20, 40,
422 SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35,
427 assertEquals(fs.getFeatureCount(true), 3);
428 assertTrue(fs.delete(sf1));
429 assertEquals(fs.getFeatureCount(true), 2);
430 assertEquals(fs.getFeatures().size(), 2);
431 assertFalse(fs.isEmpty());
432 assertTrue(fs.delete(sf2));
433 assertEquals(fs.getFeatureCount(true), 1);
434 assertFalse(fs.isEmpty());
435 assertTrue(fs.delete(sf3));
436 assertEquals(fs.getFeatureCount(true), 0);
437 assertTrue(fs.isEmpty()); // all gone
440 @Test(groups = "Functional")
441 public void testGetFeatureGroups()
443 FeatureStore fs = newFeatureStore();
444 assertTrue(fs.getFeatureGroups(true).isEmpty());
445 assertTrue(fs.getFeatureGroups(false).isEmpty());
447 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
449 Set<String> groups = fs.getFeatureGroups(true);
450 assertEquals(groups.size(), 1);
451 assertTrue(groups.contains("group1"));
454 * add another feature of the same group, delete one, delete both
456 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group1");
458 groups = fs.getFeatureGroups(true);
459 assertEquals(groups.size(), 1);
460 assertTrue(groups.contains("group1"));
462 groups = fs.getFeatureGroups(true);
463 assertEquals(groups.size(), 1);
464 assertTrue(groups.contains("group1"));
466 groups = fs.getFeatureGroups(true);
467 assertTrue(fs.getFeatureGroups(true).isEmpty());
469 SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group2");
471 SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "Group2");
473 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f, null);
475 groups = fs.getFeatureGroups(true);
476 assertEquals(groups.size(), 3);
477 assertTrue(groups.contains("group2"));
478 assertTrue(groups.contains("Group2")); // case sensitive
479 assertTrue(groups.contains(null)); // null allowed
480 assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional
483 groups = fs.getFeatureGroups(true);
484 assertEquals(groups.size(), 2);
485 assertFalse(groups.contains("group2"));
487 groups = fs.getFeatureGroups(true);
488 assertEquals(groups.size(), 1);
489 assertFalse(groups.contains("Group2"));
491 groups = fs.getFeatureGroups(true);
492 assertTrue(groups.isEmpty());
495 * add non-positional feature
497 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
500 groups = fs.getFeatureGroups(false);
501 assertEquals(groups.size(), 1);
502 assertTrue(groups.contains("CathGroup"));
503 assertTrue(fs.delete(sf6));
504 assertTrue(fs.getFeatureGroups(false).isEmpty());
507 @Test(groups = "Functional")
508 public void testGetTotalFeatureLength()
510 FeatureStore fs = newFeatureStore();
511 assertEquals(fs.getTotalFeatureLength(), 0);
513 addFeature(fs, 10, 20); // 11
514 assertEquals(fs.getTotalFeatureLength(), 11);
515 addFeature(fs, 17, 37); // 21
516 SequenceFeature sf1 = addFeature(fs, 14, 74); // 61
517 assertEquals(fs.getTotalFeatureLength(), 93);
519 // non-positional features don't count
520 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
523 assertEquals(fs.getTotalFeatureLength(), 93);
525 // contact features count 1
526 SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc",
527 15, 35, 1f, "group1");
529 assertEquals(fs.getTotalFeatureLength(), 94);
531 assertTrue(fs.delete(sf1));
532 assertEquals(fs.getTotalFeatureLength(), 33);
533 assertFalse(fs.delete(sf1));
534 assertEquals(fs.getTotalFeatureLength(), 33);
535 assertTrue(fs.delete(sf2));
536 assertEquals(fs.getTotalFeatureLength(), 33);
537 assertTrue(fs.delete(sf3));
538 assertEquals(fs.getTotalFeatureLength(), 32);
541 @Test(groups = "Functional")
542 public void testGetFeatureLength()
547 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
548 assertEquals(FeatureStore.getFeatureLength(sf1), 11);
551 * non-positional feature
553 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
555 assertEquals(FeatureStore.getFeatureLength(sf2), 0);
558 * contact feature counts 1
560 SequenceFeature sf3 = new SequenceFeature("Disulphide Bond", "desc",
561 14, 28, 1f, "AGroup");
562 assertEquals(FeatureStore.getFeatureLength(sf3), 1);
565 @Test(groups = "Functional")
566 public void testMin()
568 assertEquals(FeatureStore.min(Float.NaN, Float.NaN), Float.NaN);
569 assertEquals(FeatureStore.min(Float.NaN, 2f), 2f);
570 assertEquals(FeatureStore.min(-2f, Float.NaN), -2f);
571 assertEquals(FeatureStore.min(2f, -3f), -3f);
574 @Test(groups = "Functional")
575 public void testMax()
577 assertEquals(FeatureStore.max(Float.NaN, Float.NaN), Float.NaN);
578 assertEquals(FeatureStore.max(Float.NaN, 2f), 2f);
579 assertEquals(FeatureStore.max(-2f, Float.NaN), -2f);
580 assertEquals(FeatureStore.max(2f, -3f), 2f);
583 @Test(groups = "Functional")
584 public void testGetMinimumScore_getMaximumScore()
586 FeatureStore fs = newFeatureStore();
587 assertEquals(fs.getMinimumScore(true), Float.NaN); // positional
588 assertEquals(fs.getMaximumScore(true), Float.NaN);
589 assertEquals(fs.getMinimumScore(false), Float.NaN); // non-positional
590 assertEquals(fs.getMaximumScore(false), Float.NaN);
592 // add features with no score
593 SequenceFeature sf1 = new SequenceFeature("type", "desc", 0, 0,
596 SequenceFeature sf2 = new SequenceFeature("type", "desc", 10, 20,
599 assertEquals(fs.getMinimumScore(true), Float.NaN);
600 assertEquals(fs.getMaximumScore(true), Float.NaN);
601 assertEquals(fs.getMinimumScore(false), Float.NaN);
602 assertEquals(fs.getMaximumScore(false), Float.NaN);
604 // add positional features with score
605 SequenceFeature sf3 = new SequenceFeature("type", "desc", 10, 20, 1f,
608 SequenceFeature sf4 = new SequenceFeature("type", "desc", 12, 16, 4f,
611 assertEquals(fs.getMinimumScore(true), 1f);
612 assertEquals(fs.getMaximumScore(true), 4f);
613 assertEquals(fs.getMinimumScore(false), Float.NaN);
614 assertEquals(fs.getMaximumScore(false), Float.NaN);
616 // add non-positional features with score
617 SequenceFeature sf5 = new SequenceFeature("type", "desc", 0, 0, 11f,
620 SequenceFeature sf6 = new SequenceFeature("type", "desc", 0, 0, -7f,
623 assertEquals(fs.getMinimumScore(true), 1f);
624 assertEquals(fs.getMaximumScore(true), 4f);
625 assertEquals(fs.getMinimumScore(false), -7f);
626 assertEquals(fs.getMaximumScore(false), 11f);
628 // delete one positional and one non-positional
629 // min-max should be recomputed
630 assertTrue(fs.delete(sf6));
631 assertTrue(fs.delete(sf3));
632 assertEquals(fs.getMinimumScore(true), 4f);
633 assertEquals(fs.getMaximumScore(true), 4f);
634 assertEquals(fs.getMinimumScore(false), 11f);
635 assertEquals(fs.getMaximumScore(false), 11f);
637 // delete remaining features with score
638 assertTrue(fs.delete(sf4));
639 assertTrue(fs.delete(sf5));
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);
645 // delete all features
646 assertTrue(fs.delete(sf1));
647 assertTrue(fs.delete(sf2));
648 assertTrue(fs.isEmpty());
649 assertEquals(fs.getMinimumScore(true), Float.NaN);
650 assertEquals(fs.getMaximumScore(true), Float.NaN);
651 assertEquals(fs.getMinimumScore(false), Float.NaN);
652 assertEquals(fs.getMaximumScore(false), Float.NaN);
655 @Test(groups = "Functional")
656 public void testListContains()
658 FeatureStore featureStore = newFeatureStore();
659 assertFalse(featureStore.listContains(null, null));
660 List<SequenceFeature> features = new ArrayList<>();
661 assertFalse(featureStore.listContains(features, null));
663 SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
665 assertFalse(featureStore.listContains(null, sf1));
666 assertFalse(featureStore.listContains(features, sf1));
669 SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
671 SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f,
674 // sf2.equals(sf1) so contains should return true
675 assertTrue(featureStore.listContains(features, sf2));
676 assertFalse(featureStore.listContains(features, sf3));
679 @Test(groups = "Functional")
680 public void testGetFeaturesForGroup()
682 FeatureStore fs = newFeatureStore();
687 assertTrue(fs.getFeaturesForGroup(true, null).isEmpty());
688 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
689 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
690 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
693 * sf1: positional feature in the null group
695 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
698 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
699 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
700 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
701 List<SequenceFeature> features = fs.getFeaturesForGroup(true, null);
702 assertEquals(features.size(), 1);
703 assertTrue(features.contains(sf1));
706 * sf2: non-positional feature in the null group
707 * sf3: positional feature in a non-null group
708 * sf4: non-positional feature in a non-null group
710 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
712 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
714 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
720 features = fs.getFeaturesForGroup(true, null);
721 assertEquals(features.size(), 1);
722 assertTrue(features.contains(sf1));
724 features = fs.getFeaturesForGroup(false, null);
725 assertEquals(features.size(), 1);
726 assertTrue(features.contains(sf2));
728 features = fs.getFeaturesForGroup(true, "Uniprot");
729 assertEquals(features.size(), 1);
730 assertTrue(features.contains(sf3));
732 features = fs.getFeaturesForGroup(false, "Rfam");
733 assertEquals(features.size(), 1);
734 assertTrue(features.contains(sf4));
737 @Test(groups = "Functional")
738 public void testShiftFeatures()
740 FeatureStore fs = newFeatureStore();
741 assertFalse(fs.shiftFeatures(0, 1)); // nothing to do
743 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
746 SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null);
749 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
752 // non-positional feature:
753 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null);
757 * shift all features right by 5
759 assertTrue(fs.shiftFeatures(0, 5));
761 // non-positional features untouched:
762 List<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
763 assertEquals(nonPos.size(), 1);
764 assertTrue(nonPos.contains(sf4));
766 // positional features are replaced
767 List<SequenceFeature> pos = fs.getPositionalFeatures();
768 assertEquals(pos.size(), 3);
769 assertFalse(pos.contains(sf1));
770 assertFalse(pos.contains(sf2));
771 assertFalse(pos.contains(sf3));
772 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
773 assertEquals(pos.get(0).getBegin(), 7);
774 assertEquals(pos.get(0).getEnd(), 10);
775 assertEquals(pos.get(1).getBegin(), 13);
776 assertEquals(pos.get(1).getEnd(), 19);
777 assertEquals(pos.get(2).getBegin(), 28);
778 assertEquals(pos.get(2).getEnd(), 37);
781 * now shift left by 15
782 * feature at [7-10] should be removed
783 * feature at [13-19] should become [1-4]
785 assertTrue(fs.shiftFeatures(0, -15));
786 pos = fs.getPositionalFeatures();
787 assertEquals(pos.size(), 2);
788 SequenceFeatures.sortFeatures(pos, true);
789 assertEquals(pos.get(0).getBegin(), 1);
790 assertEquals(pos.get(0).getEnd(), 4);
791 assertEquals(pos.get(1).getBegin(), 13);
792 assertEquals(pos.get(1).getEnd(), 22);
795 * shift right by 4 from position 2 onwards
796 * feature at [1-4] unchanged, feature at [13-22] shifts
798 assertTrue(fs.shiftFeatures(2, 4));
799 pos = fs.getPositionalFeatures();
800 assertEquals(pos.size(), 2);
801 SequenceFeatures.sortFeatures(pos, true);
802 assertEquals(pos.get(0).getBegin(), 1);
803 assertEquals(pos.get(0).getEnd(), 4);
804 assertEquals(pos.get(1).getBegin(), 17);
805 assertEquals(pos.get(1).getEnd(), 26);
808 * shift right by 4 from position 18 onwards
809 * should be no change
811 SequenceFeature f1 = pos.get(0);
812 SequenceFeature f2 = pos.get(1);
813 assertFalse(fs.shiftFeatures(18, 4)); // no update
814 pos = fs.getPositionalFeatures();
815 assertEquals(pos.size(), 2);
816 SequenceFeatures.sortFeatures(pos, true);
817 assertSame(pos.get(0), f1);
818 assertSame(pos.get(1), f2);
821 @Test(groups = "Functional")
822 public void testDelete_readd()
825 * add a feature and a nested feature
827 FeatureStore store = newFeatureStore();
828 SequenceFeature sf1 = addFeature(store, 10, 20);
829 // sf2 is nested in sf1 so will be stored in nestedFeatures
830 SequenceFeature sf2 = addFeature(store, 12, 14);
831 List<SequenceFeature> features = store.getPositionalFeatures();
832 assertEquals(features.size(), 2);
833 assertTrue(features.contains(sf1));
834 assertTrue(features.contains(sf2));
835 assertTrue(store.getFeatures().contains(sf1));
836 assertTrue(store.getFeatures().contains(sf2));
839 * delete the first feature
841 assertTrue(store.delete(sf1));
842 features = store.getPositionalFeatures();
843 assertFalse(features.contains(sf1));
844 assertTrue(features.contains(sf2));
847 * re-add the 'nested' feature; is it now duplicated?
849 store.addFeature(sf2);
850 features = store.getPositionalFeatures();
851 assertEquals(features.size(), 1);
852 assertTrue(features.contains(sf2));
855 @Test(groups = "Functional")
856 public void testContains()
858 FeatureStore fs = newFeatureStore();
859 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
860 Float.NaN, "group1");
861 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
862 Float.NaN, "group2");
863 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
865 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
867 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
868 Float.NaN, "group1");
869 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
870 Float.NaN, "group2");
875 assertTrue(fs.contains(sf1)); // positional feature
876 assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
877 assertFalse(fs.contains(sf2)); // different group
878 assertTrue(fs.contains(sf3)); // non-positional
879 assertTrue(fs.contains(new SequenceFeature(sf3)));
880 assertFalse(fs.contains(sf4)); // different score
881 assertTrue(fs.contains(sf5)); // contact feature
882 assertTrue(fs.contains(new SequenceFeature(sf5)));
883 assertFalse(fs.contains(sf6)); // different group
886 * add a nested feature
888 SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16,
889 Float.NaN, "group1");
891 assertTrue(fs.contains(sf7));
892 assertTrue(fs.contains(new SequenceFeature(sf7)));
895 * delete the outer (enclosing, non-nested) feature
898 assertFalse(fs.contains(sf1));
899 assertTrue(fs.contains(sf7));