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 FeatureStoreNoNCTest
19 private FeatureStoreI newFeatureStore()
21 return new FeatureStoreImpl(false);
24 @Test(groups = "Functional")
25 public void testFindFeatures_nonNested()
27 FeatureStoreI fs = newFeatureStore();
28 fs.addFeature(new SequenceFeature("", "", 10, 20, Float.NaN,
30 // same range different description
31 fs.addFeature(new SequenceFeature("", "desc", 10, 20, Float.NaN, null));
32 fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
33 fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
35 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
36 assertTrue(overlaps.isEmpty());
38 overlaps = fs.findOverlappingFeatures(8, 10);
39 assertEquals(overlaps.size(), 2);
40 assertEquals(overlaps.get(0).getEnd(), 20);
41 assertEquals(overlaps.get(1).getEnd(), 20);
43 overlaps = fs.findOverlappingFeatures(12, 16);
44 assertEquals(overlaps.size(), 3);
45 assertEquals(overlaps.get(0).getEnd(), 20);
46 assertEquals(overlaps.get(1).getEnd(), 20);
47 assertEquals(overlaps.get(2).getEnd(), 25);
49 overlaps = fs.findOverlappingFeatures(33, 33);
50 assertEquals(overlaps.size(), 1);
51 assertEquals(overlaps.get(0).getEnd(), 35);
54 @Test(groups = "Functional")
55 public void testFindFeatures_nested()
57 FeatureStoreI fs = newFeatureStore();
58 SequenceFeature sf1 = addFeature(fs, 10, 50);
59 SequenceFeature sf2 = addFeature(fs, 10, 40);
60 SequenceFeature sf3 = addFeature(fs, 20, 30);
61 // fudge feature at same location but different group (so is added)
62 SequenceFeature sf4 = new SequenceFeature("", "", 20, 30, Float.NaN,
65 SequenceFeature sf5 = addFeature(fs, 35, 36);
67 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
68 assertTrue(overlaps.isEmpty());
70 overlaps = fs.findOverlappingFeatures(10, 15);
71 assertEquals(overlaps.size(), 2);
72 assertTrue(overlaps.contains(sf1));
73 assertTrue(overlaps.contains(sf2));
75 overlaps = fs.findOverlappingFeatures(45, 60);
76 assertEquals(overlaps.size(), 1);
77 assertTrue(overlaps.contains(sf1));
79 overlaps = fs.findOverlappingFeatures(32, 38);
80 assertEquals(overlaps.size(), 3);
81 assertTrue(overlaps.contains(sf1));
82 assertTrue(overlaps.contains(sf2));
83 assertTrue(overlaps.contains(sf5));
85 overlaps = fs.findOverlappingFeatures(15, 25);
86 assertEquals(overlaps.size(), 4);
87 assertTrue(overlaps.contains(sf1));
88 assertTrue(overlaps.contains(sf2));
89 assertTrue(overlaps.contains(sf3));
90 assertTrue(overlaps.contains(sf4));
93 @Test(groups = "Functional")
94 public void testFindFeatures_mixed()
96 FeatureStoreI fs = newFeatureStore();
97 SequenceFeature sf1 = addFeature(fs, 10, 50);
98 SequenceFeature sf2 = addFeature(fs, 1, 15);
99 SequenceFeature sf3 = addFeature(fs, 20, 30);
100 SequenceFeature sf4 = addFeature(fs, 40, 100);
101 SequenceFeature sf5 = addFeature(fs, 60, 100);
102 SequenceFeature sf6 = addFeature(fs, 70, 70);
104 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
105 assertTrue(overlaps.isEmpty());
107 overlaps = fs.findOverlappingFeatures(1, 9);
108 assertEquals(overlaps.size(), 1);
109 assertTrue(overlaps.contains(sf2));
111 overlaps = fs.findOverlappingFeatures(5, 18);
112 assertEquals(overlaps.size(), 2);
113 assertTrue(overlaps.contains(sf1));
114 assertTrue(overlaps.contains(sf2));
116 overlaps = fs.findOverlappingFeatures(30, 40);
117 assertEquals(overlaps.size(), 3);
118 assertTrue(overlaps.contains(sf1));
119 assertTrue(overlaps.contains(sf3));
120 assertTrue(overlaps.contains(sf4));
122 overlaps = fs.findOverlappingFeatures(80, 90);
123 assertEquals(overlaps.size(), 2);
124 assertTrue(overlaps.contains(sf4));
125 assertTrue(overlaps.contains(sf5));
127 overlaps = fs.findOverlappingFeatures(68, 70);
128 assertEquals(overlaps.size(), 3);
129 assertTrue(overlaps.contains(sf4));
130 assertTrue(overlaps.contains(sf5));
131 assertTrue(overlaps.contains(sf6));
135 * Helper method to add a feature of no particular type
142 SequenceFeature addFeature(FeatureStoreI fs, int from, int to)
144 SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN,
150 @Test(groups = "Functional")
151 public void testFindFeatures_contactFeatures()
153 FeatureStoreI fs = newFeatureStore();
155 SequenceFeature sf = new SequenceFeature("disulphide bond", "bond", 10,
156 20, Float.NaN, null);
160 * neither contact point in range
162 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
163 assertTrue(overlaps.isEmpty());
166 * neither contact point in range
168 overlaps = fs.findOverlappingFeatures(11, 19);
169 assertTrue(overlaps.isEmpty());
172 * first contact point in range
174 overlaps = fs.findOverlappingFeatures(5, 15);
175 assertEquals(overlaps.size(), 1);
176 assertTrue(overlaps.contains(sf));
179 * second contact point in range
181 overlaps = fs.findOverlappingFeatures(15, 25);
182 assertEquals(overlaps.size(), 1);
183 assertTrue(overlaps.contains(sf));
186 * both contact points in range
188 overlaps = fs.findOverlappingFeatures(5, 25);
189 assertEquals(overlaps.size(), 1);
190 assertTrue(overlaps.contains(sf));
193 @Test(groups = "Functional")
194 public void testGetPositionalFeatures()
196 FeatureStoreI store = newFeatureStore();
197 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
199 store.addFeature(sf1);
200 // same range, different description
201 SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
203 store.addFeature(sf2);
204 // discontiguous range
205 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40,
207 store.addFeature(sf3);
209 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35,
211 store.addFeature(sf4);
213 SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50,
215 store.addFeature(sf5);
216 // non-positional feature
217 SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0,
219 store.addFeature(sf6);
221 SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc",
222 18, 45, Float.NaN, null);
223 store.addFeature(sf7);
225 List<SequenceFeature> features = store.getPositionalFeatures();
226 assertEquals(features.size(), 6);
227 assertTrue(features.contains(sf1));
228 assertTrue(features.contains(sf2));
229 assertTrue(features.contains(sf3));
230 assertTrue(features.contains(sf4));
231 assertTrue(features.contains(sf5));
232 assertFalse(features.contains(sf6));
233 assertTrue(features.contains(sf7));
235 features = store.getNonPositionalFeatures();
236 assertEquals(features.size(), 1);
237 assertTrue(features.contains(sf6));
240 @Test(groups = "Functional")
241 public void testDelete()
243 FeatureStoreI store = newFeatureStore();
244 SequenceFeature sf1 = addFeature(store, 10, 20);
245 assertTrue(store.getPositionalFeatures().contains(sf1));
250 assertTrue(store.delete(sf1));
251 assertTrue(store.getPositionalFeatures().isEmpty());
254 * non-positional feature deletion
256 SequenceFeature sf2 = addFeature(store, 0, 0);
257 assertFalse(store.getPositionalFeatures().contains(sf2));
258 assertTrue(store.getNonPositionalFeatures().contains(sf2));
259 assertTrue(store.delete(sf2));
260 assertTrue(store.getNonPositionalFeatures().isEmpty());
263 * contact feature deletion
265 SequenceFeature sf3 = new SequenceFeature("", "Disulphide Bond", 11,
266 23, Float.NaN, null);
267 store.addFeature(sf3);
268 assertEquals(store.getPositionalFeatures().size(), 1);
269 assertTrue(store.getPositionalFeatures().contains(sf3));
270 assertTrue(store.delete(sf3));
271 assertTrue(store.getPositionalFeatures().isEmpty());
274 * nested feature deletion
276 SequenceFeature sf4 = addFeature(store, 20, 30);
277 SequenceFeature sf5 = addFeature(store, 22, 26); // to NCList
278 SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
279 SequenceFeature sf7 = addFeature(store, 25, 25); // sibling of sf6
280 SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
281 SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
283 // SequenceFeature sf4 = addFeature(store, 20, 30);
284 //// SequenceFeature sf5 = addFeature(store, 22, 26);
285 ////// SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
286 //////// SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
287 //////// SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
288 ////// SequenceFeature sf7 = addFeature(store, 25, 25); // child of sf5
290 assertEquals(store.getPositionalFeatures().size(), 6);
292 // delete a node with children - they take its place
293 assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5
294 assertEquals(store.getPositionalFeatures().size(), 5);
295 assertFalse(store.getPositionalFeatures().contains(sf6));
297 // delete a node with no children
298 assertTrue(store.delete(sf7));
299 assertEquals(store.getPositionalFeatures().size(), 4);
300 assertFalse(store.getPositionalFeatures().contains(sf7));
302 // delete root of NCList
303 assertTrue(store.delete(sf5));
304 assertEquals(store.getPositionalFeatures().size(), 3);
305 assertFalse(store.getPositionalFeatures().contains(sf5));
307 // continue the killing fields
308 assertTrue(store.delete(sf4));
309 assertEquals(store.getPositionalFeatures().size(), 2);
310 assertFalse(store.getPositionalFeatures().contains(sf4));
312 assertTrue(store.delete(sf9));
313 assertEquals(store.getPositionalFeatures().size(), 1);
314 assertFalse(store.getPositionalFeatures().contains(sf9));
316 assertTrue(store.delete(sf8));
317 assertTrue(store.getPositionalFeatures().isEmpty());
320 @Test(groups = "Functional")
321 public void testAddFeature()
323 FeatureStoreI fs = newFeatureStore();
325 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
327 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
330 assertTrue(fs.addFeature(sf1));
331 assertEquals(fs.getFeatureCount(true), 1); // positional
332 assertEquals(fs.getFeatureCount(false), 0); // non-positional
335 * re-adding the same or an identical feature should fail
337 assertFalse(fs.addFeature(sf1));
338 assertEquals(fs.getFeatureCount(true), 1);
339 assertFalse(fs.addFeature(sf2));
340 assertEquals(fs.getFeatureCount(true), 1);
345 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
347 assertTrue(fs.addFeature(sf3));
348 assertEquals(fs.getFeatureCount(true), 1); // positional
349 assertEquals(fs.getFeatureCount(false), 1); // non-positional
350 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
352 assertFalse(fs.addFeature(sf4)); // already stored
353 assertEquals(fs.getFeatureCount(true), 1); // positional
354 assertEquals(fs.getFeatureCount(false), 1); // non-positional
359 SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20,
361 assertTrue(fs.addFeature(sf5));
362 assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact
363 assertEquals(fs.getFeatureCount(false), 1); // non-positional
364 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20,
366 assertFalse(fs.addFeature(sf6)); // already stored
367 assertEquals(fs.getFeatureCount(true), 2); // no change
368 assertEquals(fs.getFeatureCount(false), 1); // no change
371 @Test(groups = "Functional")
372 public void testIsEmpty()
374 FeatureStoreI fs = newFeatureStore();
375 assertTrue(fs.isEmpty());
376 assertEquals(fs.getFeatureCount(true), 0);
381 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
384 assertFalse(fs.isEmpty());
385 assertEquals(fs.getFeatureCount(true), 1);
387 assertTrue(fs.isEmpty());
388 assertEquals(fs.getFeatureCount(true), 0);
391 * non-positional feature
393 sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null);
395 assertFalse(fs.isEmpty());
396 assertEquals(fs.getFeatureCount(false), 1); // non-positional
397 assertEquals(fs.getFeatureCount(true), 0); // positional
399 assertTrue(fs.isEmpty());
400 assertEquals(fs.getFeatureCount(false), 0);
405 sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN, null);
407 assertFalse(fs.isEmpty());
408 assertEquals(fs.getFeatureCount(true), 1);
410 assertTrue(fs.isEmpty());
411 assertEquals(fs.getFeatureCount(true), 0);
414 * sf2, sf3 added as nested features
416 sf1 = new SequenceFeature("Cath", "", 19, 49, Float.NaN, null);
417 SequenceFeature sf2 = new SequenceFeature("Cath", "", 20, 40,
419 SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35,
424 assertEquals(fs.getFeatureCount(true), 3);
425 assertTrue(fs.delete(sf1));
426 assertEquals(fs.getFeatureCount(true), 2);
427 assertEquals(fs.getFeatures().size(), 2);
428 assertFalse(fs.isEmpty());
429 assertTrue(fs.delete(sf2));
430 assertEquals(fs.getFeatureCount(true), 1);
431 assertFalse(fs.isEmpty());
432 assertTrue(fs.delete(sf3));
433 assertEquals(fs.getFeatureCount(true), 0);
434 assertTrue(fs.isEmpty()); // all gone
437 @Test(groups = "Functional")
438 public void testGetFeatureGroups()
440 FeatureStoreI fs = newFeatureStore();
441 assertTrue(fs.getFeatureGroups(true).isEmpty());
442 assertTrue(fs.getFeatureGroups(false).isEmpty());
444 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
446 Set<String> groups = fs.getFeatureGroups(true);
447 assertEquals(groups.size(), 1);
448 assertTrue(groups.contains("group1"));
451 * add another feature of the same group, delete one, delete both
453 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group1");
455 groups = fs.getFeatureGroups(true);
456 assertEquals(groups.size(), 1);
457 assertTrue(groups.contains("group1"));
459 groups = fs.getFeatureGroups(true);
460 assertEquals(groups.size(), 1);
461 assertTrue(groups.contains("group1"));
463 groups = fs.getFeatureGroups(true);
464 assertTrue(fs.getFeatureGroups(true).isEmpty());
466 SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group2");
468 SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "Group2");
470 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f, null);
472 groups = fs.getFeatureGroups(true);
473 assertEquals(groups.size(), 3);
474 assertTrue(groups.contains("group2"));
475 assertTrue(groups.contains("Group2")); // case sensitive
476 assertTrue(groups.contains(null)); // null allowed
477 assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional
480 groups = fs.getFeatureGroups(true);
481 assertEquals(groups.size(), 2);
482 assertFalse(groups.contains("group2"));
484 groups = fs.getFeatureGroups(true);
485 assertEquals(groups.size(), 1);
486 assertFalse(groups.contains("Group2"));
488 groups = fs.getFeatureGroups(true);
489 assertTrue(groups.isEmpty());
492 * add non-positional feature
494 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
497 groups = fs.getFeatureGroups(false);
498 assertEquals(groups.size(), 1);
499 assertTrue(groups.contains("CathGroup"));
500 assertTrue(fs.delete(sf6));
501 assertTrue(fs.getFeatureGroups(false).isEmpty());
504 @Test(groups = "Functional")
505 public void testGetTotalFeatureLength()
507 FeatureStoreI fs = newFeatureStore();
508 assertEquals(fs.getTotalFeatureLength(), 0);
510 addFeature(fs, 10, 20); // 11
511 assertEquals(fs.getTotalFeatureLength(), 11);
512 addFeature(fs, 17, 37); // 21
513 SequenceFeature sf1 = addFeature(fs, 14, 74); // 61
514 assertEquals(fs.getTotalFeatureLength(), 93);
516 // non-positional features don't count
517 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
520 assertEquals(fs.getTotalFeatureLength(), 93);
522 // contact features count 1
523 SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc",
524 15, 35, 1f, "group1");
526 assertEquals(fs.getTotalFeatureLength(), 94);
528 assertTrue(fs.delete(sf1));
529 assertEquals(fs.getTotalFeatureLength(), 33);
530 assertFalse(fs.delete(sf1));
531 assertEquals(fs.getTotalFeatureLength(), 33);
532 assertTrue(fs.delete(sf2));
533 assertEquals(fs.getTotalFeatureLength(), 33);
534 assertTrue(fs.delete(sf3));
535 assertEquals(fs.getTotalFeatureLength(), 32);
538 @Test(groups = "Functional")
539 public void testGetFeatureLength()
544 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
545 assertEquals(FeatureStore.getFeatureLength(sf1), 11);
548 * non-positional feature
550 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
552 assertEquals(FeatureStore.getFeatureLength(sf2), 0);
555 * contact feature counts 1
557 SequenceFeature sf3 = new SequenceFeature("Disulphide Bond", "desc",
558 14, 28, 1f, "AGroup");
559 assertEquals(FeatureStore.getFeatureLength(sf3), 1);
562 @Test(groups = "Functional")
563 public void testMin()
565 assertEquals(FeatureStore.min(Float.NaN, Float.NaN), Float.NaN);
566 assertEquals(FeatureStore.min(Float.NaN, 2f), 2f);
567 assertEquals(FeatureStore.min(-2f, Float.NaN), -2f);
568 assertEquals(FeatureStore.min(2f, -3f), -3f);
571 @Test(groups = "Functional")
572 public void testMax()
574 assertEquals(FeatureStore.max(Float.NaN, Float.NaN), Float.NaN);
575 assertEquals(FeatureStore.max(Float.NaN, 2f), 2f);
576 assertEquals(FeatureStore.max(-2f, Float.NaN), -2f);
577 assertEquals(FeatureStore.max(2f, -3f), 2f);
580 @Test(groups = "Functional")
581 public void testGetMinimumScore_getMaximumScore()
583 FeatureStoreI fs = newFeatureStore();
584 assertEquals(fs.getMinimumScore(true), Float.NaN); // positional
585 assertEquals(fs.getMaximumScore(true), Float.NaN);
586 assertEquals(fs.getMinimumScore(false), Float.NaN); // non-positional
587 assertEquals(fs.getMaximumScore(false), Float.NaN);
589 // add features with no score
590 SequenceFeature sf1 = new SequenceFeature("type", "desc", 0, 0,
593 SequenceFeature sf2 = new SequenceFeature("type", "desc", 10, 20,
596 assertEquals(fs.getMinimumScore(true), Float.NaN);
597 assertEquals(fs.getMaximumScore(true), Float.NaN);
598 assertEquals(fs.getMinimumScore(false), Float.NaN);
599 assertEquals(fs.getMaximumScore(false), Float.NaN);
601 // add positional features with score
602 SequenceFeature sf3 = new SequenceFeature("type", "desc", 10, 20, 1f,
605 SequenceFeature sf4 = new SequenceFeature("type", "desc", 12, 16, 4f,
608 assertEquals(fs.getMinimumScore(true), 1f);
609 assertEquals(fs.getMaximumScore(true), 4f);
610 assertEquals(fs.getMinimumScore(false), Float.NaN);
611 assertEquals(fs.getMaximumScore(false), Float.NaN);
613 // add non-positional features with score
614 SequenceFeature sf5 = new SequenceFeature("type", "desc", 0, 0, 11f,
617 SequenceFeature sf6 = new SequenceFeature("type", "desc", 0, 0, -7f,
620 assertEquals(fs.getMinimumScore(true), 1f);
621 assertEquals(fs.getMaximumScore(true), 4f);
622 assertEquals(fs.getMinimumScore(false), -7f);
623 assertEquals(fs.getMaximumScore(false), 11f);
625 // delete one positional and one non-positional
626 // min-max should be recomputed
627 assertTrue(fs.delete(sf6));
628 assertTrue(fs.delete(sf3));
629 assertEquals(fs.getMinimumScore(true), 4f);
630 assertEquals(fs.getMaximumScore(true), 4f);
631 assertEquals(fs.getMinimumScore(false), 11f);
632 assertEquals(fs.getMaximumScore(false), 11f);
634 // delete remaining features with score
635 assertTrue(fs.delete(sf4));
636 assertTrue(fs.delete(sf5));
637 assertEquals(fs.getMinimumScore(true), Float.NaN);
638 assertEquals(fs.getMaximumScore(true), Float.NaN);
639 assertEquals(fs.getMinimumScore(false), Float.NaN);
640 assertEquals(fs.getMaximumScore(false), Float.NaN);
642 // delete all features
643 assertTrue(fs.delete(sf1));
644 assertTrue(fs.delete(sf2));
645 assertTrue(fs.isEmpty());
646 assertEquals(fs.getMinimumScore(true), Float.NaN);
647 assertEquals(fs.getMaximumScore(true), Float.NaN);
648 assertEquals(fs.getMinimumScore(false), Float.NaN);
649 assertEquals(fs.getMaximumScore(false), Float.NaN);
652 @Test(groups = "Functional")
653 public void testListContains()
655 FeatureStoreI featureStore = newFeatureStore();
656 assertFalse(featureStore.listContains(null, null));
657 List<SequenceFeature> features = new ArrayList<>();
658 assertFalse(featureStore.listContains(features, null));
660 SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
662 assertFalse(featureStore.listContains(null, sf1));
663 assertFalse(featureStore.listContains(features, sf1));
666 SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
668 SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f,
671 // sf2.equals(sf1) so contains should return true
672 assertTrue(featureStore.listContains(features, sf2));
673 assertFalse(featureStore.listContains(features, sf3));
676 @Test(groups = "Functional")
677 public void testGetFeaturesForGroup()
679 FeatureStoreI fs = newFeatureStore();
684 assertTrue(fs.getFeaturesForGroup(true, null).isEmpty());
685 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
686 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
687 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
690 * sf1: positional feature in the null group
692 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
695 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
696 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
697 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
698 List<SequenceFeature> features = fs.getFeaturesForGroup(true, null);
699 assertEquals(features.size(), 1);
700 assertTrue(features.contains(sf1));
703 * sf2: non-positional feature in the null group
704 * sf3: positional feature in a non-null group
705 * sf4: non-positional feature in a non-null group
707 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
709 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
711 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
717 features = fs.getFeaturesForGroup(true, null);
718 assertEquals(features.size(), 1);
719 assertTrue(features.contains(sf1));
721 features = fs.getFeaturesForGroup(false, null);
722 assertEquals(features.size(), 1);
723 assertTrue(features.contains(sf2));
725 features = fs.getFeaturesForGroup(true, "Uniprot");
726 assertEquals(features.size(), 1);
727 assertTrue(features.contains(sf3));
729 features = fs.getFeaturesForGroup(false, "Rfam");
730 assertEquals(features.size(), 1);
731 assertTrue(features.contains(sf4));
734 @Test(groups = "Functional")
735 public void testShiftFeatures()
737 FeatureStoreI fs = newFeatureStore();
738 assertFalse(fs.shiftFeatures(0, 1)); // nothing to do
740 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
743 SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null);
746 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
749 // non-positional feature:
750 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null);
754 * shift all features right by 5
756 assertTrue(fs.shiftFeatures(0, 5));
758 // non-positional features untouched:
759 List<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
760 assertEquals(nonPos.size(), 1);
761 assertTrue(nonPos.contains(sf4));
763 // positional features are replaced
764 List<SequenceFeature> pos = fs.getPositionalFeatures();
765 assertEquals(pos.size(), 3);
766 assertFalse(pos.contains(sf1));
767 assertFalse(pos.contains(sf2));
768 assertFalse(pos.contains(sf3));
769 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
770 assertEquals(pos.get(0).getBegin(), 7);
771 assertEquals(pos.get(0).getEnd(), 10);
772 assertEquals(pos.get(1).getBegin(), 13);
773 assertEquals(pos.get(1).getEnd(), 19);
774 assertEquals(pos.get(2).getBegin(), 28);
775 assertEquals(pos.get(2).getEnd(), 37);
778 * now shift left by 15
779 * feature at [7-10] should be removed
780 * feature at [13-19] should become [1-4]
782 assertTrue(fs.shiftFeatures(0, -15));
783 pos = fs.getPositionalFeatures();
784 assertEquals(pos.size(), 2);
785 SequenceFeatures.sortFeatures(pos, true);
786 assertEquals(pos.get(0).getBegin(), 1);
787 assertEquals(pos.get(0).getEnd(), 4);
788 assertEquals(pos.get(1).getBegin(), 13);
789 assertEquals(pos.get(1).getEnd(), 22);
792 * shift right by 4 from position 2 onwards
793 * feature at [1-4] unchanged, feature at [13-22] shifts
795 assertTrue(fs.shiftFeatures(2, 4));
796 pos = fs.getPositionalFeatures();
797 assertEquals(pos.size(), 2);
798 SequenceFeatures.sortFeatures(pos, true);
799 assertEquals(pos.get(0).getBegin(), 1);
800 assertEquals(pos.get(0).getEnd(), 4);
801 assertEquals(pos.get(1).getBegin(), 17);
802 assertEquals(pos.get(1).getEnd(), 26);
805 * shift right by 4 from position 18 onwards
806 * should be no change
808 SequenceFeature f1 = pos.get(0);
809 SequenceFeature f2 = pos.get(1);
810 assertFalse(fs.shiftFeatures(18, 4)); // no update
811 pos = fs.getPositionalFeatures();
812 assertEquals(pos.size(), 2);
813 SequenceFeatures.sortFeatures(pos, true);
814 assertSame(pos.get(0), f1);
815 assertSame(pos.get(1), f2);
818 @Test(groups = "Functional")
819 public void testDelete_readd()
822 * add a feature and a nested feature
824 FeatureStoreI store = newFeatureStore();
825 SequenceFeature sf1 = addFeature(store, 10, 20);
826 // sf2 is nested in sf1 so will be stored in nestedFeatures
827 SequenceFeature sf2 = addFeature(store, 12, 14);
828 List<SequenceFeature> features = store.getPositionalFeatures();
829 assertEquals(features.size(), 2);
830 assertTrue(features.contains(sf1));
831 assertTrue(features.contains(sf2));
832 assertTrue(store.getFeatures().contains(sf1));
833 assertTrue(store.getFeatures().contains(sf2));
836 * delete the first feature
838 assertTrue(store.delete(sf1));
839 features = store.getPositionalFeatures();
840 assertFalse(features.contains(sf1));
841 assertTrue(features.contains(sf2));
844 * re-add the 'nested' feature; is it now duplicated?
846 store.addFeature(sf2);
847 features = store.getPositionalFeatures();
848 assertEquals(features.size(), 1);
849 assertTrue(features.contains(sf2));
852 @Test(groups = "Functional")
853 public void testContains()
855 FeatureStoreI fs = newFeatureStore();
856 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
857 Float.NaN, "group1");
858 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
859 Float.NaN, "group2");
860 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
862 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
864 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
865 Float.NaN, "group1");
866 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
867 Float.NaN, "group2");
872 assertTrue(fs.contains(sf1)); // positional feature
873 assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
874 assertFalse(fs.contains(sf2)); // different group
875 assertTrue(fs.contains(sf3)); // non-positional
876 assertTrue(fs.contains(new SequenceFeature(sf3)));
877 assertFalse(fs.contains(sf4)); // different score
878 assertTrue(fs.contains(sf5)); // contact feature
879 assertTrue(fs.contains(new SequenceFeature(sf5)));
880 assertFalse(fs.contains(sf6)); // different group
883 * add a nested feature
885 SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16,
886 Float.NaN, "group1");
888 assertTrue(fs.contains(sf7));
889 assertTrue(fs.contains(new SequenceFeature(sf7)));
892 * delete the outer (enclosing, non-nested) feature
895 assertFalse(fs.contains(sf1));
896 assertTrue(fs.contains(sf7));