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 FeatureStoreNCListBufferTest
19 private FeatureStore newFeatureStore()
21 return new FeatureStore(
22 FeatureStore.INTERVAL_STORE_NCARRAY);
25 @Test(groups = "Functional")
26 public void testFindFeatures_nonNested()
28 FeatureStore fs = newFeatureStore();
29 fs.addFeature(new SequenceFeature("", "", 10, 20, Float.NaN,
31 // same range different description
32 fs.addFeature(new SequenceFeature("", "desc", 10, 20, Float.NaN, null));
33 fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
34 fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
36 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
37 assertTrue(overlaps.isEmpty());
39 overlaps = fs.findOverlappingFeatures(8, 10);
40 assertEquals(overlaps.size(), 2);
41 assertEquals(overlaps.get(0).getEnd(), 20);
42 assertEquals(overlaps.get(1).getEnd(), 20);
44 overlaps = fs.findOverlappingFeatures(12, 16);
45 assertEquals(overlaps.size(), 3);
46 assertEquals(overlaps.get(0).getEnd(), 20);
47 assertEquals(overlaps.get(1).getEnd(), 20);
48 assertEquals(overlaps.get(2).getEnd(), 25);
50 overlaps = fs.findOverlappingFeatures(33, 33);
51 assertEquals(overlaps.size(), 1);
52 assertEquals(overlaps.get(0).getEnd(), 35);
55 @Test(groups = "Functional")
56 public void testFindFeatures_nested()
58 FeatureStore fs = newFeatureStore();
59 SequenceFeature sf1 = addFeature(fs, 10, 50);
60 SequenceFeature sf2 = addFeature(fs, 10, 40);
61 SequenceFeature sf3 = addFeature(fs, 20, 30);
62 // fudge feature at same location but different group (so is added)
63 SequenceFeature sf4 = new SequenceFeature("", "", 20, 30, Float.NaN,
66 SequenceFeature sf5 = addFeature(fs, 35, 36);
68 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
69 assertTrue(overlaps.isEmpty());
71 overlaps = fs.findOverlappingFeatures(10, 15);
72 assertEquals(overlaps.size(), 2);
73 assertTrue(overlaps.contains(sf1));
74 assertTrue(overlaps.contains(sf2));
76 overlaps = fs.findOverlappingFeatures(45, 60);
77 assertEquals(overlaps.size(), 1);
78 assertTrue(overlaps.contains(sf1));
80 overlaps = fs.findOverlappingFeatures(32, 38);
81 assertEquals(overlaps.size(), 3);
82 assertTrue(overlaps.contains(sf1));
83 assertTrue(overlaps.contains(sf2));
84 assertTrue(overlaps.contains(sf5));
86 overlaps = fs.findOverlappingFeatures(15, 25);
87 assertEquals(overlaps.size(), 4);
88 assertTrue(overlaps.contains(sf1));
89 assertTrue(overlaps.contains(sf2));
90 assertTrue(overlaps.contains(sf3));
91 assertTrue(overlaps.contains(sf4));
94 @Test(groups = "Functional")
95 public void testFindFeatures_mixed()
97 FeatureStore fs = newFeatureStore();
98 SequenceFeature sf1 = addFeature(fs, 10, 50);
99 SequenceFeature sf2 = addFeature(fs, 1, 15);
100 SequenceFeature sf3 = addFeature(fs, 20, 30);
101 SequenceFeature sf4 = addFeature(fs, 40, 100);
102 SequenceFeature sf5 = addFeature(fs, 60, 100);
103 SequenceFeature sf6 = addFeature(fs, 70, 70);
105 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
106 assertTrue(overlaps.isEmpty());
108 overlaps = fs.findOverlappingFeatures(1, 9);
109 assertEquals(overlaps.size(), 1);
110 assertTrue(overlaps.contains(sf2));
112 overlaps = fs.findOverlappingFeatures(5, 18);
113 assertEquals(overlaps.size(), 2);
114 assertTrue(overlaps.contains(sf1));
115 assertTrue(overlaps.contains(sf2));
117 overlaps = fs.findOverlappingFeatures(30, 40);
118 assertEquals(overlaps.size(), 3);
119 assertTrue(overlaps.contains(sf1));
120 assertTrue(overlaps.contains(sf3));
121 assertTrue(overlaps.contains(sf4));
123 overlaps = fs.findOverlappingFeatures(80, 90);
124 assertEquals(overlaps.size(), 2);
125 assertTrue(overlaps.contains(sf4));
126 assertTrue(overlaps.contains(sf5));
128 overlaps = fs.findOverlappingFeatures(68, 70);
129 assertEquals(overlaps.size(), 3);
130 assertTrue(overlaps.contains(sf4));
131 assertTrue(overlaps.contains(sf5));
132 assertTrue(overlaps.contains(sf6));
136 * Helper method to add a feature of no particular type
143 SequenceFeature addFeature(FeatureStore fs, int from, int to)
145 SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN,
151 @Test(groups = "Functional")
152 public void testFindFeatures_contactFeatures()
154 FeatureStore fs = newFeatureStore();
156 SequenceFeature sf = new SequenceFeature("disulphide bond", "bond", 10,
157 20, Float.NaN, null);
161 * neither contact point in range
163 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
164 assertTrue(overlaps.isEmpty());
167 * neither contact point in range
169 overlaps = fs.findOverlappingFeatures(11, 19);
170 assertTrue(overlaps.isEmpty());
173 * first contact point in range
175 overlaps = fs.findOverlappingFeatures(5, 15);
176 assertEquals(overlaps.size(), 1);
177 assertTrue(overlaps.contains(sf));
180 * second contact point in range
182 overlaps = fs.findOverlappingFeatures(15, 25);
183 assertEquals(overlaps.size(), 1);
184 assertTrue(overlaps.contains(sf));
187 * both contact points in range
189 overlaps = fs.findOverlappingFeatures(5, 25);
190 assertEquals(overlaps.size(), 1);
191 assertTrue(overlaps.contains(sf));
194 @Test(groups = "Functional")
195 public void testGetPositionalFeatures()
197 FeatureStore store = newFeatureStore();
198 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
200 store.addFeature(sf1);
201 // same range, different description
202 SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
204 store.addFeature(sf2);
205 // discontiguous range
206 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40,
208 store.addFeature(sf3);
210 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35,
212 store.addFeature(sf4);
214 SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50,
216 store.addFeature(sf5);
217 // non-positional feature
218 SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0,
220 store.addFeature(sf6);
222 SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc",
223 18, 45, Float.NaN, null);
224 store.addFeature(sf7);
226 List<SequenceFeature> features = store.getPositionalFeatures();
227 assertEquals(features.size(), 6);
228 assertTrue(features.contains(sf1));
229 assertTrue(features.contains(sf2));
230 assertTrue(features.contains(sf3));
231 assertTrue(features.contains(sf4));
232 assertTrue(features.contains(sf5));
233 assertFalse(features.contains(sf6));
234 assertTrue(features.contains(sf7));
236 features = store.getNonPositionalFeatures();
237 assertEquals(features.size(), 1);
238 assertTrue(features.contains(sf6));
241 @Test(groups = "Functional")
242 public void testDelete()
244 FeatureStore store = newFeatureStore();
245 SequenceFeature sf1 = addFeature(store, 10, 20);
246 assertTrue(store.getPositionalFeatures().contains(sf1));
251 assertTrue(store.delete(sf1));
252 assertTrue(store.getPositionalFeatures().isEmpty());
255 * non-positional feature deletion
257 SequenceFeature sf2 = addFeature(store, 0, 0);
258 assertFalse(store.getPositionalFeatures().contains(sf2));
259 assertTrue(store.getNonPositionalFeatures().contains(sf2));
260 assertTrue(store.delete(sf2));
261 assertTrue(store.getNonPositionalFeatures().isEmpty());
264 * contact feature deletion
266 SequenceFeature sf3 = new SequenceFeature("", "Disulphide Bond", 11,
267 23, Float.NaN, null);
268 store.addFeature(sf3);
269 assertEquals(store.getPositionalFeatures().size(), 1);
270 assertTrue(store.getPositionalFeatures().contains(sf3));
271 assertTrue(store.delete(sf3));
272 assertTrue(store.getPositionalFeatures().isEmpty());
275 * nested feature deletion
277 SequenceFeature sf4 = addFeature(store, 20, 30);
278 SequenceFeature sf5 = addFeature(store, 22, 26); // to NCList
279 SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
280 SequenceFeature sf7 = addFeature(store, 25, 25); // sibling of sf6
281 SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
282 SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
284 // SequenceFeature sf4 = addFeature(store, 20, 30);
285 //// SequenceFeature sf5 = addFeature(store, 22, 26);
286 ////// SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
287 //////// SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
288 //////// SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
289 ////// SequenceFeature sf7 = addFeature(store, 25, 25); // child of sf5
291 assertEquals(store.getPositionalFeatures().size(), 6);
293 // delete a node with children - they take its place
294 assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5
295 assertEquals(store.getPositionalFeatures().size(), 5);
296 assertFalse(store.getPositionalFeatures().contains(sf6));
298 // delete a node with no children
299 assertTrue(store.delete(sf7));
300 assertEquals(store.getPositionalFeatures().size(), 4);
301 assertFalse(store.getPositionalFeatures().contains(sf7));
303 // delete root of NCList
304 assertTrue(store.delete(sf5));
305 assertEquals(store.getPositionalFeatures().size(), 3);
306 assertFalse(store.getPositionalFeatures().contains(sf5));
308 // continue the killing fields
309 assertTrue(store.delete(sf4));
310 assertEquals(store.getPositionalFeatures().size(), 2);
311 assertFalse(store.getPositionalFeatures().contains(sf4));
313 assertTrue(store.delete(sf9));
314 assertEquals(store.getPositionalFeatures().size(), 1);
315 assertFalse(store.getPositionalFeatures().contains(sf9));
317 assertTrue(store.delete(sf8));
318 assertTrue(store.getPositionalFeatures().isEmpty());
321 @Test(groups = "Functional")
322 public void testAddFeature()
324 FeatureStore fs = newFeatureStore();
326 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
328 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
331 assertTrue(fs.addFeature(sf1));
332 assertEquals(fs.getFeatureCount(true), 1); // positional
333 assertEquals(fs.getFeatureCount(false), 0); // non-positional
336 * re-adding the same or an identical feature should fail
338 assertFalse(fs.addFeature(sf1));
339 assertEquals(fs.getFeatureCount(true), 1);
340 assertFalse(fs.addFeature(sf2));
341 assertEquals(fs.getFeatureCount(true), 1);
346 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
348 assertTrue(fs.addFeature(sf3));
349 assertEquals(fs.getFeatureCount(true), 1); // positional
350 assertEquals(fs.getFeatureCount(false), 1); // non-positional
351 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
353 assertFalse(fs.addFeature(sf4)); // already stored
354 assertEquals(fs.getFeatureCount(true), 1); // positional
355 assertEquals(fs.getFeatureCount(false), 1); // non-positional
360 SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20,
362 assertTrue(fs.addFeature(sf5));
363 assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact
364 assertEquals(fs.getFeatureCount(false), 1); // non-positional
365 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20,
367 assertFalse(fs.addFeature(sf6)); // already stored
368 assertEquals(fs.getFeatureCount(true), 2); // no change
369 assertEquals(fs.getFeatureCount(false), 1); // no change
372 @Test(groups = "Functional")
373 public void testIsEmpty()
375 FeatureStore fs = newFeatureStore();
376 assertTrue(fs.isEmpty());
377 assertEquals(fs.getFeatureCount(true), 0);
382 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
385 assertFalse(fs.isEmpty());
386 assertEquals(fs.getFeatureCount(true), 1);
388 assertTrue(fs.isEmpty());
389 assertEquals(fs.getFeatureCount(true), 0);
392 * non-positional feature
394 sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null);
396 assertFalse(fs.isEmpty());
397 assertEquals(fs.getFeatureCount(false), 1); // non-positional
398 assertEquals(fs.getFeatureCount(true), 0); // positional
400 assertTrue(fs.isEmpty());
401 assertEquals(fs.getFeatureCount(false), 0);
406 sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN, null);
408 assertFalse(fs.isEmpty());
409 assertEquals(fs.getFeatureCount(true), 1);
411 assertTrue(fs.isEmpty());
412 assertEquals(fs.getFeatureCount(true), 0);
415 * sf2, sf3 added as nested features
417 sf1 = new SequenceFeature("Cath", "", 19, 49, Float.NaN, null);
418 SequenceFeature sf2 = new SequenceFeature("Cath", "", 20, 40,
420 SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35,
425 assertEquals(fs.getFeatureCount(true), 3);
426 assertTrue(fs.delete(sf1));
427 assertEquals(fs.getFeatureCount(true), 2);
428 assertEquals(fs.getFeatures().size(), 2);
429 assertFalse(fs.isEmpty());
430 assertTrue(fs.delete(sf2));
431 assertEquals(fs.getFeatureCount(true), 1);
432 assertFalse(fs.isEmpty());
433 assertTrue(fs.delete(sf3));
434 assertEquals(fs.getFeatureCount(true), 0);
435 assertTrue(fs.isEmpty()); // all gone
438 @Test(groups = "Functional")
439 public void testGetFeatureGroups()
441 FeatureStore fs = newFeatureStore();
442 assertTrue(fs.getFeatureGroups(true).isEmpty());
443 assertTrue(fs.getFeatureGroups(false).isEmpty());
445 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
447 Set<String> groups = fs.getFeatureGroups(true);
448 assertEquals(groups.size(), 1);
449 assertTrue(groups.contains("group1"));
452 * add another feature of the same group, delete one, delete both
454 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group1");
456 groups = fs.getFeatureGroups(true);
457 assertEquals(groups.size(), 1);
458 assertTrue(groups.contains("group1"));
460 groups = fs.getFeatureGroups(true);
461 assertEquals(groups.size(), 1);
462 assertTrue(groups.contains("group1"));
464 groups = fs.getFeatureGroups(true);
465 assertTrue(fs.getFeatureGroups(true).isEmpty());
467 SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group2");
469 SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "Group2");
471 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f, null);
473 groups = fs.getFeatureGroups(true);
474 assertEquals(groups.size(), 3);
475 assertTrue(groups.contains("group2"));
476 assertTrue(groups.contains("Group2")); // case sensitive
477 assertTrue(groups.contains(null)); // null allowed
478 assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional
481 groups = fs.getFeatureGroups(true);
482 assertEquals(groups.size(), 2);
483 assertFalse(groups.contains("group2"));
485 groups = fs.getFeatureGroups(true);
486 assertEquals(groups.size(), 1);
487 assertFalse(groups.contains("Group2"));
489 groups = fs.getFeatureGroups(true);
490 assertTrue(groups.isEmpty());
493 * add non-positional feature
495 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
498 groups = fs.getFeatureGroups(false);
499 assertEquals(groups.size(), 1);
500 assertTrue(groups.contains("CathGroup"));
501 assertTrue(fs.delete(sf6));
502 assertTrue(fs.getFeatureGroups(false).isEmpty());
505 @Test(groups = "Functional")
506 public void testGetTotalFeatureLength()
508 FeatureStore fs = newFeatureStore();
509 assertEquals(fs.getTotalFeatureLength(), 0);
511 addFeature(fs, 10, 20); // 11
512 assertEquals(fs.getTotalFeatureLength(), 11);
513 addFeature(fs, 17, 37); // 21
514 SequenceFeature sf1 = addFeature(fs, 14, 74); // 61
515 assertEquals(fs.getTotalFeatureLength(), 93);
517 // non-positional features don't count
518 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
521 assertEquals(fs.getTotalFeatureLength(), 93);
523 // contact features count 1
524 SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc",
525 15, 35, 1f, "group1");
527 assertEquals(fs.getTotalFeatureLength(), 94);
529 assertTrue(fs.delete(sf1));
530 assertEquals(fs.getTotalFeatureLength(), 33);
531 assertFalse(fs.delete(sf1));
532 assertEquals(fs.getTotalFeatureLength(), 33);
533 assertTrue(fs.delete(sf2));
534 assertEquals(fs.getTotalFeatureLength(), 33);
535 assertTrue(fs.delete(sf3));
536 assertEquals(fs.getTotalFeatureLength(), 32);
539 @Test(groups = "Functional")
540 public void testGetFeatureLength()
545 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
546 assertEquals(FeatureStore.getFeatureLength(sf1), 11);
549 * non-positional feature
551 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
553 assertEquals(FeatureStore.getFeatureLength(sf2), 0);
556 * contact feature counts 1
558 SequenceFeature sf3 = new SequenceFeature("Disulphide Bond", "desc",
559 14, 28, 1f, "AGroup");
560 assertEquals(FeatureStore.getFeatureLength(sf3), 1);
563 @Test(groups = "Functional")
564 public void testMin()
566 assertEquals(FeatureStore.min(Float.NaN, Float.NaN), Float.NaN);
567 assertEquals(FeatureStore.min(Float.NaN, 2f), 2f);
568 assertEquals(FeatureStore.min(-2f, Float.NaN), -2f);
569 assertEquals(FeatureStore.min(2f, -3f), -3f);
572 @Test(groups = "Functional")
573 public void testMax()
575 assertEquals(FeatureStore.max(Float.NaN, Float.NaN), Float.NaN);
576 assertEquals(FeatureStore.max(Float.NaN, 2f), 2f);
577 assertEquals(FeatureStore.max(-2f, Float.NaN), -2f);
578 assertEquals(FeatureStore.max(2f, -3f), 2f);
581 @Test(groups = "Functional")
582 public void testGetMinimumScore_getMaximumScore()
584 FeatureStore fs = newFeatureStore();
585 assertEquals(fs.getMinimumScore(true), Float.NaN); // positional
586 assertEquals(fs.getMaximumScore(true), Float.NaN);
587 assertEquals(fs.getMinimumScore(false), Float.NaN); // non-positional
588 assertEquals(fs.getMaximumScore(false), Float.NaN);
590 // add features with no score
591 SequenceFeature sf1 = new SequenceFeature("type", "desc", 0, 0,
594 SequenceFeature sf2 = new SequenceFeature("type", "desc", 10, 20,
597 assertEquals(fs.getMinimumScore(true), Float.NaN);
598 assertEquals(fs.getMaximumScore(true), Float.NaN);
599 assertEquals(fs.getMinimumScore(false), Float.NaN);
600 assertEquals(fs.getMaximumScore(false), Float.NaN);
602 // add positional features with score
603 SequenceFeature sf3 = new SequenceFeature("type", "desc", 10, 20, 1f,
606 SequenceFeature sf4 = new SequenceFeature("type", "desc", 12, 16, 4f,
609 assertEquals(fs.getMinimumScore(true), 1f);
610 assertEquals(fs.getMaximumScore(true), 4f);
611 assertEquals(fs.getMinimumScore(false), Float.NaN);
612 assertEquals(fs.getMaximumScore(false), Float.NaN);
614 // add non-positional features with score
615 SequenceFeature sf5 = new SequenceFeature("type", "desc", 0, 0, 11f,
618 SequenceFeature sf6 = new SequenceFeature("type", "desc", 0, 0, -7f,
621 assertEquals(fs.getMinimumScore(true), 1f);
622 assertEquals(fs.getMaximumScore(true), 4f);
623 assertEquals(fs.getMinimumScore(false), -7f);
624 assertEquals(fs.getMaximumScore(false), 11f);
626 // delete one positional and one non-positional
627 // min-max should be recomputed
628 assertTrue(fs.delete(sf6));
629 assertTrue(fs.delete(sf3));
630 assertEquals(fs.getMinimumScore(true), 4f);
631 assertEquals(fs.getMaximumScore(true), 4f);
632 assertEquals(fs.getMinimumScore(false), 11f);
633 assertEquals(fs.getMaximumScore(false), 11f);
635 // delete remaining features with score
636 assertTrue(fs.delete(sf4));
637 assertTrue(fs.delete(sf5));
638 assertEquals(fs.getMinimumScore(true), Float.NaN);
639 assertEquals(fs.getMaximumScore(true), Float.NaN);
640 assertEquals(fs.getMinimumScore(false), Float.NaN);
641 assertEquals(fs.getMaximumScore(false), Float.NaN);
643 // delete all features
644 assertTrue(fs.delete(sf1));
645 assertTrue(fs.delete(sf2));
646 assertTrue(fs.isEmpty());
647 assertEquals(fs.getMinimumScore(true), Float.NaN);
648 assertEquals(fs.getMaximumScore(true), Float.NaN);
649 assertEquals(fs.getMinimumScore(false), Float.NaN);
650 assertEquals(fs.getMaximumScore(false), Float.NaN);
653 @Test(groups = "Functional")
654 public void testListContains()
656 FeatureStore featureStore = newFeatureStore();
657 assertFalse(featureStore.listContains(null, null));
658 List<SequenceFeature> features = new ArrayList<>();
659 assertFalse(featureStore.listContains(features, null));
661 SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
663 assertFalse(featureStore.listContains(null, sf1));
664 assertFalse(featureStore.listContains(features, sf1));
667 SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
669 SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f,
672 // sf2.equals(sf1) so contains should return true
673 assertTrue(featureStore.listContains(features, sf2));
674 assertFalse(featureStore.listContains(features, sf3));
677 @Test(groups = "Functional")
678 public void testGetFeaturesForGroup()
680 FeatureStore fs = newFeatureStore();
685 assertTrue(fs.getFeaturesForGroup(true, null).isEmpty());
686 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
687 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
688 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
691 * sf1: positional feature in the null group
693 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
696 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
697 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
698 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
699 List<SequenceFeature> features = fs.getFeaturesForGroup(true, null);
700 assertEquals(features.size(), 1);
701 assertTrue(features.contains(sf1));
704 * sf2: non-positional feature in the null group
705 * sf3: positional feature in a non-null group
706 * sf4: non-positional feature in a non-null group
708 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
710 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
712 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
718 features = fs.getFeaturesForGroup(true, null);
719 assertEquals(features.size(), 1);
720 assertTrue(features.contains(sf1));
722 features = fs.getFeaturesForGroup(false, null);
723 assertEquals(features.size(), 1);
724 assertTrue(features.contains(sf2));
726 features = fs.getFeaturesForGroup(true, "Uniprot");
727 assertEquals(features.size(), 1);
728 assertTrue(features.contains(sf3));
730 features = fs.getFeaturesForGroup(false, "Rfam");
731 assertEquals(features.size(), 1);
732 assertTrue(features.contains(sf4));
735 @Test(groups = "Functional")
736 public void testShiftFeatures()
738 FeatureStore fs = newFeatureStore();
739 assertFalse(fs.shiftFeatures(0, 1)); // nothing to do
741 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
744 SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null);
747 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
750 // non-positional feature:
751 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null);
755 * shift all features right by 5
757 assertTrue(fs.shiftFeatures(0, 5));
759 // non-positional features untouched:
760 List<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
761 assertEquals(nonPos.size(), 1);
762 assertTrue(nonPos.contains(sf4));
764 // positional features are replaced
765 List<SequenceFeature> pos = fs.getPositionalFeatures();
766 assertEquals(pos.size(), 3);
767 assertFalse(pos.contains(sf1));
768 assertFalse(pos.contains(sf2));
769 assertFalse(pos.contains(sf3));
770 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
771 assertEquals(pos.get(0).getBegin(), 7);
772 assertEquals(pos.get(0).getEnd(), 10);
773 assertEquals(pos.get(1).getBegin(), 13);
774 assertEquals(pos.get(1).getEnd(), 19);
775 assertEquals(pos.get(2).getBegin(), 28);
776 assertEquals(pos.get(2).getEnd(), 37);
779 * now shift left by 15
780 * feature at [7-10] should be removed
781 * feature at [13-19] should become [1-4]
783 assertTrue(fs.shiftFeatures(0, -15));
784 pos = fs.getPositionalFeatures();
785 assertEquals(pos.size(), 2);
786 SequenceFeatures.sortFeatures(pos, true);
787 assertEquals(pos.get(0).getBegin(), 1);
788 assertEquals(pos.get(0).getEnd(), 4);
789 assertEquals(pos.get(1).getBegin(), 13);
790 assertEquals(pos.get(1).getEnd(), 22);
793 * shift right by 4 from position 2 onwards
794 * feature at [1-4] unchanged, feature at [13-22] shifts
796 assertTrue(fs.shiftFeatures(2, 4));
797 pos = fs.getPositionalFeatures();
798 assertEquals(pos.size(), 2);
799 SequenceFeatures.sortFeatures(pos, true);
800 assertEquals(pos.get(0).getBegin(), 1);
801 assertEquals(pos.get(0).getEnd(), 4);
802 assertEquals(pos.get(1).getBegin(), 17);
803 assertEquals(pos.get(1).getEnd(), 26);
806 * shift right by 4 from position 18 onwards
807 * should be no change
809 SequenceFeature f1 = pos.get(0);
810 SequenceFeature f2 = pos.get(1);
811 assertFalse(fs.shiftFeatures(18, 4)); // no update
812 pos = fs.getPositionalFeatures();
813 assertEquals(pos.size(), 2);
814 SequenceFeatures.sortFeatures(pos, true);
815 assertSame(pos.get(0), f1);
816 assertSame(pos.get(1), f2);
819 @Test(groups = "Functional")
820 public void testDelete_readd()
823 * add a feature and a nested feature
825 FeatureStore store = newFeatureStore();
826 SequenceFeature sf1 = addFeature(store, 10, 20);
827 // sf2 is nested in sf1 so will be stored in nestedFeatures
828 SequenceFeature sf2 = addFeature(store, 12, 14);
829 List<SequenceFeature> features = store.getPositionalFeatures();
830 assertEquals(features.size(), 2);
831 assertTrue(features.contains(sf1));
832 assertTrue(features.contains(sf2));
833 assertTrue(store.getFeatures().contains(sf1));
834 assertTrue(store.getFeatures().contains(sf2));
837 * delete the first feature
839 assertTrue(store.delete(sf1));
840 features = store.getPositionalFeatures();
841 assertFalse(features.contains(sf1));
842 assertTrue(features.contains(sf2));
845 * re-add the 'nested' feature; is it now duplicated?
847 store.addFeature(sf2);
848 features = store.getPositionalFeatures();
849 assertEquals(features.size(), 1);
850 assertTrue(features.contains(sf2));
853 @Test(groups = "Functional")
854 public void testContains()
856 FeatureStore fs = newFeatureStore();
857 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
858 Float.NaN, "group1");
859 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
860 Float.NaN, "group2");
861 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
863 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
865 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
866 Float.NaN, "group1");
867 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
868 Float.NaN, "group2");
873 assertTrue(fs.contains(sf1)); // positional feature
874 assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
875 assertFalse(fs.contains(sf2)); // different group
876 assertTrue(fs.contains(sf3)); // non-positional
877 assertTrue(fs.contains(new SequenceFeature(sf3)));
878 assertFalse(fs.contains(sf4)); // different score
879 assertTrue(fs.contains(sf5)); // contact feature
880 assertTrue(fs.contains(new SequenceFeature(sf5)));
881 assertFalse(fs.contains(sf6)); // different group
884 * add a nested feature
886 SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16,
887 Float.NaN, "group1");
889 assertTrue(fs.contains(sf7));
890 assertTrue(fs.contains(new SequenceFeature(sf7)));
893 * delete the outer (enclosing, non-nested) feature
896 assertFalse(fs.contains(sf1));
897 assertTrue(fs.contains(sf7));