Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.datamodel.features

File FeatureStoreTest.java

 

Code metrics

0
505
21
1
911
657
21
0.04
24.05
21
1

Classes

Class Line # Actions
FeatureStoreTest 15 505 21 0
1.0100%
 

Contributing tests

This file is covered by 20 tests. .

Source view

1    package jalview.datamodel.features;
2   
3    import static org.testng.Assert.assertEquals;
4    import static org.testng.Assert.assertFalse;
5    import static org.testng.Assert.assertTrue;
6   
7    import jalview.datamodel.SequenceFeature;
8   
9    import java.util.ArrayList;
10    import java.util.List;
11    import java.util.Set;
12   
13    import org.testng.annotations.Test;
14   
 
15    public class FeatureStoreTest
16    {
17   
 
18  1 toggle @Test(groups = "Functional")
19    public void testFindFeatures_nonNested()
20    {
21  1 FeatureStore fs = new FeatureStore();
22  1 fs.addFeature(new SequenceFeature("", "", 10, 20, Float.NaN,
23    null));
24    // same range different description
25  1 fs.addFeature(new SequenceFeature("", "desc", 10, 20, Float.NaN, null));
26  1 fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
27  1 fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
28   
29  1 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
30  1 assertTrue(overlaps.isEmpty());
31   
32  1 overlaps = fs.findOverlappingFeatures(8, 10);
33  1 assertEquals(overlaps.size(), 2);
34  1 assertEquals(overlaps.get(0).getEnd(), 20);
35  1 assertEquals(overlaps.get(1).getEnd(), 20);
36   
37  1 overlaps = fs.findOverlappingFeatures(12, 16);
38  1 assertEquals(overlaps.size(), 3);
39  1 assertEquals(overlaps.get(0).getEnd(), 20);
40  1 assertEquals(overlaps.get(1).getEnd(), 20);
41  1 assertEquals(overlaps.get(2).getEnd(), 25);
42   
43  1 overlaps = fs.findOverlappingFeatures(33, 33);
44  1 assertEquals(overlaps.size(), 1);
45  1 assertEquals(overlaps.get(0).getEnd(), 35);
46    }
47   
 
48  1 toggle @Test(groups = "Functional")
49    public void testFindFeatures_nested()
50    {
51  1 FeatureStore fs = new FeatureStore();
52  1 SequenceFeature sf1 = addFeature(fs, 10, 50);
53  1 SequenceFeature sf2 = addFeature(fs, 10, 40);
54  1 SequenceFeature sf3 = addFeature(fs, 20, 30);
55    // fudge feature at same location but different group (so is added)
56  1 SequenceFeature sf4 = new SequenceFeature("", "", 20, 30, Float.NaN,
57    "different group");
58  1 fs.addFeature(sf4);
59  1 SequenceFeature sf5 = addFeature(fs, 35, 36);
60   
61  1 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
62  1 assertTrue(overlaps.isEmpty());
63   
64  1 overlaps = fs.findOverlappingFeatures(10, 15);
65  1 assertEquals(overlaps.size(), 2);
66  1 assertTrue(overlaps.contains(sf1));
67  1 assertTrue(overlaps.contains(sf2));
68   
69  1 overlaps = fs.findOverlappingFeatures(45, 60);
70  1 assertEquals(overlaps.size(), 1);
71  1 assertTrue(overlaps.contains(sf1));
72   
73  1 overlaps = fs.findOverlappingFeatures(32, 38);
74  1 assertEquals(overlaps.size(), 3);
75  1 assertTrue(overlaps.contains(sf1));
76  1 assertTrue(overlaps.contains(sf2));
77  1 assertTrue(overlaps.contains(sf5));
78   
79  1 overlaps = fs.findOverlappingFeatures(15, 25);
80  1 assertEquals(overlaps.size(), 4);
81  1 assertTrue(overlaps.contains(sf1));
82  1 assertTrue(overlaps.contains(sf2));
83  1 assertTrue(overlaps.contains(sf3));
84  1 assertTrue(overlaps.contains(sf4));
85    }
86   
 
87  1 toggle @Test(groups = "Functional")
88    public void testFindFeatures_mixed()
89    {
90  1 FeatureStore fs = new FeatureStore();
91  1 SequenceFeature sf1 = addFeature(fs, 10, 50);
92  1 SequenceFeature sf2 = addFeature(fs, 1, 15);
93  1 SequenceFeature sf3 = addFeature(fs, 20, 30);
94  1 SequenceFeature sf4 = addFeature(fs, 40, 100);
95  1 SequenceFeature sf5 = addFeature(fs, 60, 100);
96  1 SequenceFeature sf6 = addFeature(fs, 70, 70);
97   
98  1 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
99  1 assertTrue(overlaps.isEmpty());
100   
101  1 overlaps = fs.findOverlappingFeatures(1, 9);
102  1 assertEquals(overlaps.size(), 1);
103  1 assertTrue(overlaps.contains(sf2));
104   
105  1 overlaps = fs.findOverlappingFeatures(5, 18);
106  1 assertEquals(overlaps.size(), 2);
107  1 assertTrue(overlaps.contains(sf1));
108  1 assertTrue(overlaps.contains(sf2));
109   
110  1 overlaps = fs.findOverlappingFeatures(30, 40);
111  1 assertEquals(overlaps.size(), 3);
112  1 assertTrue(overlaps.contains(sf1));
113  1 assertTrue(overlaps.contains(sf3));
114  1 assertTrue(overlaps.contains(sf4));
115   
116  1 overlaps = fs.findOverlappingFeatures(80, 90);
117  1 assertEquals(overlaps.size(), 2);
118  1 assertTrue(overlaps.contains(sf4));
119  1 assertTrue(overlaps.contains(sf5));
120   
121  1 overlaps = fs.findOverlappingFeatures(68, 70);
122  1 assertEquals(overlaps.size(), 3);
123  1 assertTrue(overlaps.contains(sf4));
124  1 assertTrue(overlaps.contains(sf5));
125  1 assertTrue(overlaps.contains(sf6));
126    }
127   
128    /**
129    * Helper method to add a feature of no particular type
130    *
131    * @param fs
132    * @param from
133    * @param to
134    * @return
135    */
 
136  23 toggle SequenceFeature addFeature(FeatureStore fs, int from, int to)
137    {
138  23 SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN,
139    null);
140  23 fs.addFeature(sf1);
141  23 return sf1;
142    }
143   
 
144  1 toggle @Test(groups = "Functional")
145    public void testFindFeatures_contactFeatures()
146    {
147  1 FeatureStore fs = new FeatureStore();
148   
149  1 SequenceFeature sf = new SequenceFeature("disulphide bond", "bond", 10,
150    20, Float.NaN, null);
151  1 fs.addFeature(sf);
152   
153    /*
154    * neither contact point in range
155    */
156  1 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
157  1 assertTrue(overlaps.isEmpty());
158   
159    /*
160    * neither contact point in range
161    */
162  1 overlaps = fs.findOverlappingFeatures(11, 19);
163  1 assertTrue(overlaps.isEmpty());
164   
165    /*
166    * first contact point in range
167    */
168  1 overlaps = fs.findOverlappingFeatures(5, 15);
169  1 assertEquals(overlaps.size(), 1);
170  1 assertTrue(overlaps.contains(sf));
171   
172    /*
173    * second contact point in range
174    */
175  1 overlaps = fs.findOverlappingFeatures(15, 25);
176  1 assertEquals(overlaps.size(), 1);
177  1 assertTrue(overlaps.contains(sf));
178   
179    /*
180    * both contact points in range
181    */
182  1 overlaps = fs.findOverlappingFeatures(5, 25);
183  1 assertEquals(overlaps.size(), 1);
184  1 assertTrue(overlaps.contains(sf));
185    }
186   
187    /**
188    * Tests for the method that returns false for an attempt to add a feature
189    * that would enclose, or be enclosed by, another feature
190    */
 
191  1 toggle @Test(groups = "Functional")
192    public void testAddNonNestedFeature()
193    {
194  1 FeatureStore fs = new FeatureStore();
195   
196  1 String type = "Domain";
197  1 SequenceFeature sf1 = new SequenceFeature(type, type, 10, 20,
198    Float.NaN, null);
199  1 assertTrue(fs.addNonNestedFeature(sf1));
200   
201    // co-located feature is ok
202  1 SequenceFeature sf2 = new SequenceFeature(type, type, 10, 20,
203    Float.NaN, null);
204  1 assertTrue(fs.addNonNestedFeature(sf2));
205   
206    // overlap left is ok
207  1 SequenceFeature sf3 = new SequenceFeature(type, type, 5, 15, Float.NaN,
208    null);
209  1 assertTrue(fs.addNonNestedFeature(sf3));
210   
211    // overlap right is ok
212  1 SequenceFeature sf4 = new SequenceFeature(type, type, 15, 25,
213    Float.NaN, null);
214  1 assertTrue(fs.addNonNestedFeature(sf4));
215   
216    // add enclosing feature is not ok
217  1 SequenceFeature sf5 = new SequenceFeature(type, type, 10, 21,
218    Float.NaN, null);
219  1 assertFalse(fs.addNonNestedFeature(sf5));
220  1 SequenceFeature sf6 = new SequenceFeature(type, type, 4, 15, Float.NaN,
221    null);
222  1 assertFalse(fs.addNonNestedFeature(sf6));
223  1 SequenceFeature sf7 = new SequenceFeature(type, type, 1, 50, Float.NaN,
224    null);
225  1 assertFalse(fs.addNonNestedFeature(sf7));
226   
227    // add enclosed feature is not ok
228  1 SequenceFeature sf8 = new SequenceFeature(type, type, 10, 19,
229    Float.NaN, null);
230  1 assertFalse(fs.addNonNestedFeature(sf8));
231  1 SequenceFeature sf9 = new SequenceFeature(type, type, 16, 25,
232    Float.NaN, null);
233  1 assertFalse(fs.addNonNestedFeature(sf9));
234  1 SequenceFeature sf10 = new SequenceFeature(type, type, 7, 7, Float.NaN,
235    null);
236  1 assertFalse(fs.addNonNestedFeature(sf10));
237    }
238   
 
239  1 toggle @Test(groups = "Functional")
240    public void testGetPositionalFeatures()
241    {
242  1 FeatureStore store = new FeatureStore();
243  1 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
244    Float.NaN, null);
245  1 store.addFeature(sf1);
246    // same range, different description
247  1 SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
248    Float.NaN, null);
249  1 store.addFeature(sf2);
250    // discontiguous range
251  1 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40,
252    Float.NaN, null);
253  1 store.addFeature(sf3);
254    // overlapping range
255  1 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35,
256    Float.NaN, null);
257  1 store.addFeature(sf4);
258    // enclosing range
259  1 SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50,
260    Float.NaN, null);
261  1 store.addFeature(sf5);
262    // non-positional feature
263  1 SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0,
264    Float.NaN, null);
265  1 store.addFeature(sf6);
266    // contact feature
267  1 SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc",
268    18, 45, Float.NaN, null);
269  1 store.addFeature(sf7);
270   
271  1 List<SequenceFeature> features = store.getPositionalFeatures();
272  1 assertEquals(features.size(), 6);
273  1 assertTrue(features.contains(sf1));
274  1 assertTrue(features.contains(sf2));
275  1 assertTrue(features.contains(sf3));
276  1 assertTrue(features.contains(sf4));
277  1 assertTrue(features.contains(sf5));
278  1 assertFalse(features.contains(sf6));
279  1 assertTrue(features.contains(sf7));
280   
281  1 features = store.getNonPositionalFeatures();
282  1 assertEquals(features.size(), 1);
283  1 assertTrue(features.contains(sf6));
284    }
285   
 
286  1 toggle @Test(groups = "Functional")
287    public void testDelete()
288    {
289  1 FeatureStore store = new FeatureStore();
290  1 SequenceFeature sf1 = addFeature(store, 10, 20);
291  1 assertTrue(store.getPositionalFeatures().contains(sf1));
292   
293    /*
294    * simple deletion
295    */
296  1 assertTrue(store.delete(sf1));
297  1 assertTrue(store.getPositionalFeatures().isEmpty());
298   
299    /*
300    * non-positional feature deletion
301    */
302  1 SequenceFeature sf2 = addFeature(store, 0, 0);
303  1 assertFalse(store.getPositionalFeatures().contains(sf2));
304  1 assertTrue(store.getNonPositionalFeatures().contains(sf2));
305  1 assertTrue(store.delete(sf2));
306  1 assertTrue(store.getNonPositionalFeatures().isEmpty());
307   
308    /*
309    * contact feature deletion
310    */
311  1 SequenceFeature sf3 = new SequenceFeature("", "Disulphide Bond", 11,
312    23, Float.NaN, null);
313  1 store.addFeature(sf3);
314  1 assertEquals(store.getPositionalFeatures().size(), 1);
315  1 assertTrue(store.getPositionalFeatures().contains(sf3));
316  1 assertTrue(store.delete(sf3));
317  1 assertTrue(store.getPositionalFeatures().isEmpty());
318   
319    /*
320    * nested feature deletion
321    */
322  1 SequenceFeature sf4 = addFeature(store, 20, 30);
323  1 SequenceFeature sf5 = addFeature(store, 22, 26); // to NCList
324  1 SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
325  1 SequenceFeature sf7 = addFeature(store, 25, 25); // sibling of sf6
326  1 SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
327  1 SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
328  1 assertEquals(store.getPositionalFeatures().size(), 6);
329   
330    // delete a node with children - they take its place
331  1 assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5
332  1 assertEquals(store.getPositionalFeatures().size(), 5);
333  1 assertFalse(store.getPositionalFeatures().contains(sf6));
334   
335    // delete a node with no children
336  1 assertTrue(store.delete(sf7));
337  1 assertEquals(store.getPositionalFeatures().size(), 4);
338  1 assertFalse(store.getPositionalFeatures().contains(sf7));
339   
340    // delete root of NCList
341  1 assertTrue(store.delete(sf5));
342  1 assertEquals(store.getPositionalFeatures().size(), 3);
343  1 assertFalse(store.getPositionalFeatures().contains(sf5));
344   
345    // continue the killing fields
346  1 assertTrue(store.delete(sf4));
347  1 assertEquals(store.getPositionalFeatures().size(), 2);
348  1 assertFalse(store.getPositionalFeatures().contains(sf4));
349   
350  1 assertTrue(store.delete(sf9));
351  1 assertEquals(store.getPositionalFeatures().size(), 1);
352  1 assertFalse(store.getPositionalFeatures().contains(sf9));
353   
354  1 assertTrue(store.delete(sf8));
355  1 assertTrue(store.getPositionalFeatures().isEmpty());
356    }
357   
 
358  1 toggle @Test(groups = "Functional")
359    public void testAddFeature()
360    {
361  1 FeatureStore fs = new FeatureStore();
362   
363  1 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
364    Float.NaN, null);
365  1 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
366    Float.NaN, null);
367   
368  1 assertTrue(fs.addFeature(sf1));
369  1 assertEquals(fs.getFeatureCount(true), 1); // positional
370  1 assertEquals(fs.getFeatureCount(false), 0); // non-positional
371   
372    /*
373    * re-adding the same or an identical feature should fail
374    */
375  1 assertFalse(fs.addFeature(sf1));
376  1 assertEquals(fs.getFeatureCount(true), 1);
377  1 assertFalse(fs.addFeature(sf2));
378  1 assertEquals(fs.getFeatureCount(true), 1);
379   
380    /*
381    * add non-positional
382    */
383  1 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
384    null);
385  1 assertTrue(fs.addFeature(sf3));
386  1 assertEquals(fs.getFeatureCount(true), 1); // positional
387  1 assertEquals(fs.getFeatureCount(false), 1); // non-positional
388  1 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
389    null);
390  1 assertFalse(fs.addFeature(sf4)); // already stored
391  1 assertEquals(fs.getFeatureCount(true), 1); // positional
392  1 assertEquals(fs.getFeatureCount(false), 1); // non-positional
393   
394    /*
395    * add contact
396    */
397  1 SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20,
398    Float.NaN, null);
399  1 assertTrue(fs.addFeature(sf5));
400  1 assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact
401  1 assertEquals(fs.getFeatureCount(false), 1); // non-positional
402  1 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20,
403    Float.NaN, null);
404  1 assertFalse(fs.addFeature(sf6)); // already stored
405  1 assertEquals(fs.getFeatureCount(true), 2); // no change
406  1 assertEquals(fs.getFeatureCount(false), 1); // no change
407    }
408   
 
409  1 toggle @Test(groups = "Functional")
410    public void testIsEmpty()
411    {
412  1 FeatureStore fs = new FeatureStore();
413  1 assertTrue(fs.isEmpty());
414  1 assertEquals(fs.getFeatureCount(true), 0);
415   
416    /*
417    * non-nested feature
418    */
419  1 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
420    Float.NaN, null);
421  1 fs.addFeature(sf1);
422  1 assertFalse(fs.isEmpty());
423  1 assertEquals(fs.getFeatureCount(true), 1);
424  1 fs.delete(sf1);
425  1 assertTrue(fs.isEmpty());
426  1 assertEquals(fs.getFeatureCount(true), 0);
427   
428    /*
429    * non-positional feature
430    */
431  1 sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null);
432  1 fs.addFeature(sf1);
433  1 assertFalse(fs.isEmpty());
434  1 assertEquals(fs.getFeatureCount(false), 1); // non-positional
435  1 assertEquals(fs.getFeatureCount(true), 0); // positional
436  1 fs.delete(sf1);
437  1 assertTrue(fs.isEmpty());
438  1 assertEquals(fs.getFeatureCount(false), 0);
439   
440    /*
441    * contact feature
442    */
443  1 sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN, null);
444  1 fs.addFeature(sf1);
445  1 assertFalse(fs.isEmpty());
446  1 assertEquals(fs.getFeatureCount(true), 1);
447  1 fs.delete(sf1);
448  1 assertTrue(fs.isEmpty());
449  1 assertEquals(fs.getFeatureCount(true), 0);
450   
451    /*
452    * sf2, sf3 added as nested features
453    */
454  1 sf1 = new SequenceFeature("Cath", "", 19, 49, Float.NaN, null);
455  1 SequenceFeature sf2 = new SequenceFeature("Cath", "", 20, 40,
456    Float.NaN, null);
457  1 SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35,
458    Float.NaN, null);
459  1 fs.addFeature(sf1);
460  1 fs.addFeature(sf2);
461  1 fs.addFeature(sf3);
462  1 assertEquals(fs.getFeatureCount(true), 3);
463  1 assertTrue(fs.delete(sf1));
464  1 assertEquals(fs.getFeatureCount(true), 2);
465    // FeatureStore should now only contain features in the NCList
466  1 assertTrue(fs.nonNestedFeatures.isEmpty());
467  1 assertEquals(fs.nestedFeatures.size(), 2);
468  1 assertFalse(fs.isEmpty());
469  1 assertTrue(fs.delete(sf2));
470  1 assertEquals(fs.getFeatureCount(true), 1);
471  1 assertFalse(fs.isEmpty());
472  1 assertTrue(fs.delete(sf3));
473  1 assertEquals(fs.getFeatureCount(true), 0);
474  1 assertTrue(fs.isEmpty()); // all gone
475    }
476   
 
477  1 toggle @Test(groups = "Functional")
478    public void testGetFeatureGroups()
479    {
480  1 FeatureStore fs = new FeatureStore();
481  1 assertTrue(fs.getFeatureGroups(true).isEmpty());
482  1 assertTrue(fs.getFeatureGroups(false).isEmpty());
483   
484  1 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
485  1 fs.addFeature(sf1);
486  1 Set<String> groups = fs.getFeatureGroups(true);
487  1 assertEquals(groups.size(), 1);
488  1 assertTrue(groups.contains("group1"));
489   
490    /*
491    * add another feature of the same group, delete one, delete both
492    */
493  1 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group1");
494  1 fs.addFeature(sf2);
495  1 groups = fs.getFeatureGroups(true);
496  1 assertEquals(groups.size(), 1);
497  1 assertTrue(groups.contains("group1"));
498  1 fs.delete(sf2);
499  1 groups = fs.getFeatureGroups(true);
500  1 assertEquals(groups.size(), 1);
501  1 assertTrue(groups.contains("group1"));
502  1 fs.delete(sf1);
503  1 groups = fs.getFeatureGroups(true);
504  1 assertTrue(fs.getFeatureGroups(true).isEmpty());
505   
506  1 SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group2");
507  1 fs.addFeature(sf3);
508  1 SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "Group2");
509  1 fs.addFeature(sf4);
510  1 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f, null);
511  1 fs.addFeature(sf5);
512  1 groups = fs.getFeatureGroups(true);
513  1 assertEquals(groups.size(), 3);
514  1 assertTrue(groups.contains("group2"));
515  1 assertTrue(groups.contains("Group2")); // case sensitive
516  1 assertTrue(groups.contains(null)); // null allowed
517  1 assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional
518   
519  1 fs.delete(sf3);
520  1 groups = fs.getFeatureGroups(true);
521  1 assertEquals(groups.size(), 2);
522  1 assertFalse(groups.contains("group2"));
523  1 fs.delete(sf4);
524  1 groups = fs.getFeatureGroups(true);
525  1 assertEquals(groups.size(), 1);
526  1 assertFalse(groups.contains("Group2"));
527  1 fs.delete(sf5);
528  1 groups = fs.getFeatureGroups(true);
529  1 assertTrue(groups.isEmpty());
530   
531    /*
532    * add non-positional feature
533    */
534  1 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
535    "CathGroup");
536  1 fs.addFeature(sf6);
537  1 groups = fs.getFeatureGroups(false);
538  1 assertEquals(groups.size(), 1);
539  1 assertTrue(groups.contains("CathGroup"));
540  1 assertTrue(fs.delete(sf6));
541  1 assertTrue(fs.getFeatureGroups(false).isEmpty());
542    }
543   
 
544  1 toggle @Test(groups = "Functional")
545    public void testGetTotalFeatureLength()
546    {
547  1 FeatureStore fs = new FeatureStore();
548  1 assertEquals(fs.getTotalFeatureLength(), 0);
549   
550  1 addFeature(fs, 10, 20); // 11
551  1 assertEquals(fs.getTotalFeatureLength(), 11);
552  1 addFeature(fs, 17, 37); // 21
553  1 SequenceFeature sf1 = addFeature(fs, 14, 74); // 61
554  1 assertEquals(fs.getTotalFeatureLength(), 93);
555   
556    // non-positional features don't count
557  1 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
558    "group1");
559  1 fs.addFeature(sf2);
560  1 assertEquals(fs.getTotalFeatureLength(), 93);
561   
562    // contact features count 1
563  1 SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc",
564    15, 35, 1f, "group1");
565  1 fs.addFeature(sf3);
566  1 assertEquals(fs.getTotalFeatureLength(), 94);
567   
568  1 assertTrue(fs.delete(sf1));
569  1 assertEquals(fs.getTotalFeatureLength(), 33);
570  1 assertFalse(fs.delete(sf1));
571  1 assertEquals(fs.getTotalFeatureLength(), 33);
572  1 assertTrue(fs.delete(sf2));
573  1 assertEquals(fs.getTotalFeatureLength(), 33);
574  1 assertTrue(fs.delete(sf3));
575  1 assertEquals(fs.getTotalFeatureLength(), 32);
576    }
577   
 
578  1 toggle @Test(groups = "Functional")
579    public void testGetFeatureLength()
580    {
581    /*
582    * positional feature
583    */
584  1 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
585  1 assertEquals(FeatureStore.getFeatureLength(sf1), 11);
586   
587    /*
588    * non-positional feature
589    */
590  1 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
591    "CathGroup");
592  1 assertEquals(FeatureStore.getFeatureLength(sf2), 0);
593   
594    /*
595    * contact feature counts 1
596    */
597  1 SequenceFeature sf3 = new SequenceFeature("Disulphide Bond", "desc",
598    14, 28, 1f, "AGroup");
599  1 assertEquals(FeatureStore.getFeatureLength(sf3), 1);
600    }
601   
 
602  1 toggle @Test(groups = "Functional")
603    public void testMin()
604    {
605  1 assertEquals(FeatureStore.min(Float.NaN, Float.NaN), Float.NaN);
606  1 assertEquals(FeatureStore.min(Float.NaN, 2f), 2f);
607  1 assertEquals(FeatureStore.min(-2f, Float.NaN), -2f);
608  1 assertEquals(FeatureStore.min(2f, -3f), -3f);
609    }
610   
 
611  1 toggle @Test(groups = "Functional")
612    public void testMax()
613    {
614  1 assertEquals(FeatureStore.max(Float.NaN, Float.NaN), Float.NaN);
615  1 assertEquals(FeatureStore.max(Float.NaN, 2f), 2f);
616  1 assertEquals(FeatureStore.max(-2f, Float.NaN), -2f);
617  1 assertEquals(FeatureStore.max(2f, -3f), 2f);
618    }
619   
 
620  1 toggle @Test(groups = "Functional")
621    public void testGetMinimumScore_getMaximumScore()
622    {
623  1 FeatureStore fs = new FeatureStore();
624  1 assertEquals(fs.getMinimumScore(true), Float.NaN); // positional
625  1 assertEquals(fs.getMaximumScore(true), Float.NaN);
626  1 assertEquals(fs.getMinimumScore(false), Float.NaN); // non-positional
627  1 assertEquals(fs.getMaximumScore(false), Float.NaN);
628   
629    // add features with no score
630  1 SequenceFeature sf1 = new SequenceFeature("type", "desc", 0, 0,
631    Float.NaN, "group");
632  1 fs.addFeature(sf1);
633  1 SequenceFeature sf2 = new SequenceFeature("type", "desc", 10, 20,
634    Float.NaN, "group");
635  1 fs.addFeature(sf2);
636  1 assertEquals(fs.getMinimumScore(true), Float.NaN);
637  1 assertEquals(fs.getMaximumScore(true), Float.NaN);
638  1 assertEquals(fs.getMinimumScore(false), Float.NaN);
639  1 assertEquals(fs.getMaximumScore(false), Float.NaN);
640   
641    // add positional features with score
642  1 SequenceFeature sf3 = new SequenceFeature("type", "desc", 10, 20, 1f,
643    "group");
644  1 fs.addFeature(sf3);
645  1 SequenceFeature sf4 = new SequenceFeature("type", "desc", 12, 16, 4f,
646    "group");
647  1 fs.addFeature(sf4);
648  1 assertEquals(fs.getMinimumScore(true), 1f);
649  1 assertEquals(fs.getMaximumScore(true), 4f);
650  1 assertEquals(fs.getMinimumScore(false), Float.NaN);
651  1 assertEquals(fs.getMaximumScore(false), Float.NaN);
652   
653    // add non-positional features with score
654  1 SequenceFeature sf5 = new SequenceFeature("type", "desc", 0, 0, 11f,
655    "group");
656  1 fs.addFeature(sf5);
657  1 SequenceFeature sf6 = new SequenceFeature("type", "desc", 0, 0, -7f,
658    "group");
659  1 fs.addFeature(sf6);
660  1 assertEquals(fs.getMinimumScore(true), 1f);
661  1 assertEquals(fs.getMaximumScore(true), 4f);
662  1 assertEquals(fs.getMinimumScore(false), -7f);
663  1 assertEquals(fs.getMaximumScore(false), 11f);
664   
665    // delete one positional and one non-positional
666    // min-max should be recomputed
667  1 assertTrue(fs.delete(sf6));
668  1 assertTrue(fs.delete(sf3));
669  1 assertEquals(fs.getMinimumScore(true), 4f);
670  1 assertEquals(fs.getMaximumScore(true), 4f);
671  1 assertEquals(fs.getMinimumScore(false), 11f);
672  1 assertEquals(fs.getMaximumScore(false), 11f);
673   
674    // delete remaining features with score
675  1 assertTrue(fs.delete(sf4));
676  1 assertTrue(fs.delete(sf5));
677  1 assertEquals(fs.getMinimumScore(true), Float.NaN);
678  1 assertEquals(fs.getMaximumScore(true), Float.NaN);
679  1 assertEquals(fs.getMinimumScore(false), Float.NaN);
680  1 assertEquals(fs.getMaximumScore(false), Float.NaN);
681   
682    // delete all features
683  1 assertTrue(fs.delete(sf1));
684  1 assertTrue(fs.delete(sf2));
685  1 assertTrue(fs.isEmpty());
686  1 assertEquals(fs.getMinimumScore(true), Float.NaN);
687  1 assertEquals(fs.getMaximumScore(true), Float.NaN);
688  1 assertEquals(fs.getMinimumScore(false), Float.NaN);
689  1 assertEquals(fs.getMaximumScore(false), Float.NaN);
690    }
691   
 
692  1 toggle @Test(groups = "Functional")
693    public void testListContains()
694    {
695  1 assertFalse(FeatureStore.listContains(null, null));
696  1 List<SequenceFeature> features = new ArrayList<SequenceFeature>();
697  1 assertFalse(FeatureStore.listContains(features, null));
698   
699  1 SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
700    "group1");
701  1 assertFalse(FeatureStore.listContains(null, sf1));
702  1 assertFalse(FeatureStore.listContains(features, sf1));
703   
704  1 features.add(sf1);
705  1 SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
706    "group1");
707  1 SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f,
708    "group1");
709   
710    // sf2.equals(sf1) so contains should return true
711  1 assertTrue(FeatureStore.listContains(features, sf2));
712  1 assertFalse(FeatureStore.listContains(features, sf3));
713    }
714   
 
715  1 toggle @Test(groups = "Functional")
716    public void testGetFeaturesForGroup()
717    {
718  1 FeatureStore fs = new FeatureStore();
719   
720    /*
721    * with no features
722    */
723  1 assertTrue(fs.getFeaturesForGroup(true, null).isEmpty());
724  1 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
725  1 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
726  1 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
727   
728    /*
729    * sf1: positional feature in the null group
730    */
731  1 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
732    null);
733  1 fs.addFeature(sf1);
734  1 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
735  1 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
736  1 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
737  1 List<SequenceFeature> features = fs.getFeaturesForGroup(true, null);
738  1 assertEquals(features.size(), 1);
739  1 assertTrue(features.contains(sf1));
740   
741    /*
742    * sf2: non-positional feature in the null group
743    * sf3: positional feature in a non-null group
744    * sf4: non-positional feature in a non-null group
745    */
746  1 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
747    null);
748  1 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
749    "Uniprot");
750  1 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
751    "Rfam");
752  1 fs.addFeature(sf2);
753  1 fs.addFeature(sf3);
754  1 fs.addFeature(sf4);
755   
756  1 features = fs.getFeaturesForGroup(true, null);
757  1 assertEquals(features.size(), 1);
758  1 assertTrue(features.contains(sf1));
759   
760  1 features = fs.getFeaturesForGroup(false, null);
761  1 assertEquals(features.size(), 1);
762  1 assertTrue(features.contains(sf2));
763   
764  1 features = fs.getFeaturesForGroup(true, "Uniprot");
765  1 assertEquals(features.size(), 1);
766  1 assertTrue(features.contains(sf3));
767   
768  1 features = fs.getFeaturesForGroup(false, "Rfam");
769  1 assertEquals(features.size(), 1);
770  1 assertTrue(features.contains(sf4));
771    }
772   
 
773  1 toggle @Test(groups = "Functional")
774    public void testShiftFeatures()
775    {
776  1 FeatureStore fs = new FeatureStore();
777  1 assertFalse(fs.shiftFeatures(1));
778   
779  1 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
780  1 fs.addFeature(sf1);
781    // nested feature:
782  1 SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null);
783  1 fs.addFeature(sf2);
784    // contact feature:
785  1 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
786    0f, null);
787  1 fs.addFeature(sf3);
788    // non-positional feature:
789  1 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null);
790  1 fs.addFeature(sf4);
791   
792    /*
793    * shift features right by 5
794    */
795  1 assertTrue(fs.shiftFeatures(5));
796   
797    // non-positional features untouched:
798  1 List<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
799  1 assertEquals(nonPos.size(), 1);
800  1 assertTrue(nonPos.contains(sf4));
801   
802    // positional features are replaced
803  1 List<SequenceFeature> pos = fs.getPositionalFeatures();
804  1 assertEquals(pos.size(), 3);
805  1 assertFalse(pos.contains(sf1));
806  1 assertFalse(pos.contains(sf2));
807  1 assertFalse(pos.contains(sf3));
808  1 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
809  1 assertEquals(pos.get(0).getBegin(), 7);
810  1 assertEquals(pos.get(0).getEnd(), 10);
811  1 assertEquals(pos.get(1).getBegin(), 13);
812  1 assertEquals(pos.get(1).getEnd(), 19);
813  1 assertEquals(pos.get(2).getBegin(), 28);
814  1 assertEquals(pos.get(2).getEnd(), 37);
815   
816    /*
817    * now shift left by 15
818    * feature at [7-10] should be removed
819    * feature at [13-19] should become [1-4]
820    */
821  1 assertTrue(fs.shiftFeatures(-15));
822  1 pos = fs.getPositionalFeatures();
823  1 assertEquals(pos.size(), 2);
824  1 SequenceFeatures.sortFeatures(pos, true);
825  1 assertEquals(pos.get(0).getBegin(), 1);
826  1 assertEquals(pos.get(0).getEnd(), 4);
827  1 assertEquals(pos.get(1).getBegin(), 13);
828  1 assertEquals(pos.get(1).getEnd(), 22);
829    }
830   
 
831  1 toggle @Test(groups = "Functional")
832    public void testDelete_readd()
833    {
834    /*
835    * add a feature and a nested feature
836    */
837  1 FeatureStore store = new FeatureStore();
838  1 SequenceFeature sf1 = addFeature(store, 10, 20);
839    // sf2 is nested in sf1 so will be stored in nestedFeatures
840  1 SequenceFeature sf2 = addFeature(store, 12, 14);
841  1 List<SequenceFeature> features = store.getPositionalFeatures();
842  1 assertEquals(features.size(), 2);
843  1 assertTrue(features.contains(sf1));
844  1 assertTrue(features.contains(sf2));
845  1 assertTrue(store.nonNestedFeatures.contains(sf1));
846  1 assertTrue(store.nestedFeatures.contains(sf2));
847   
848    /*
849    * delete the first feature
850    */
851  1 assertTrue(store.delete(sf1));
852  1 features = store.getPositionalFeatures();
853  1 assertFalse(features.contains(sf1));
854  1 assertTrue(features.contains(sf2));
855   
856    /*
857    * re-add the 'nested' feature; is it now duplicated?
858    */
859  1 store.addFeature(sf2);
860  1 features = store.getPositionalFeatures();
861  1 assertEquals(features.size(), 1);
862  1 assertTrue(features.contains(sf2));
863    }
864   
 
865  1 toggle @Test(groups = "Functional")
866    public void testContains()
867    {
868  1 FeatureStore fs = new FeatureStore();
869  1 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
870    Float.NaN, "group1");
871  1 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
872    Float.NaN, "group2");
873  1 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
874    "group1");
875  1 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
876    "group1");
877  1 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
878    Float.NaN, "group1");
879  1 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
880    Float.NaN, "group2");
881   
882  1 fs.addFeature(sf1);
883  1 fs.addFeature(sf3);
884  1 fs.addFeature(sf5);
885  1 assertTrue(fs.contains(sf1)); // positional feature
886  1 assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
887  1 assertFalse(fs.contains(sf2)); // different group
888  1 assertTrue(fs.contains(sf3)); // non-positional
889  1 assertTrue(fs.contains(new SequenceFeature(sf3)));
890  1 assertFalse(fs.contains(sf4)); // different score
891  1 assertTrue(fs.contains(sf5)); // contact feature
892  1 assertTrue(fs.contains(new SequenceFeature(sf5)));
893  1 assertFalse(fs.contains(sf6)); // different group
894   
895    /*
896    * add a nested feature
897    */
898  1 SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16,
899    Float.NaN, "group1");
900  1 fs.addFeature(sf7);
901  1 assertTrue(fs.contains(sf7));
902  1 assertTrue(fs.contains(new SequenceFeature(sf7)));
903   
904    /*
905    * delete the outer (enclosing, non-nested) feature
906    */
907  1 fs.delete(sf1);
908  1 assertFalse(fs.contains(sf1));
909  1 assertTrue(fs.contains(sf7));
910    }
911    }