Clover icon

Coverage Report

  1. Project Clover database Thu Nov 7 2024 17:01:39 GMT
  2. Package jalview.datamodel.features

File SequenceFeaturesTest.java

 

Code metrics

0
717
23
1
1,312
917
23
0.03
31.17
23
1

Classes

Class Line # Actions
SequenceFeaturesTest 39 717 23
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.datamodel.features;
22   
23    import static org.testng.Assert.assertEquals;
24    import static org.testng.Assert.assertFalse;
25    import static org.testng.Assert.assertSame;
26    import static org.testng.Assert.assertTrue;
27   
28    import java.util.ArrayList;
29    import java.util.Iterator;
30    import java.util.List;
31    import java.util.Map;
32    import java.util.Set;
33   
34    import org.testng.annotations.Test;
35   
36    import jalview.datamodel.SequenceFeature;
37    import junit.extensions.PA;
38   
 
39    public class SequenceFeaturesTest
40    {
 
41  0 toggle @Test(groups = "Functional")
42    public void testConstructor()
43    {
44  0 SequenceFeaturesI store = new SequenceFeatures();
45  0 assertFalse(store.hasFeatures());
46   
47  0 store = new SequenceFeatures((List<SequenceFeature>) null);
48  0 assertFalse(store.hasFeatures());
49   
50  0 List<SequenceFeature> features = new ArrayList<>();
51  0 store = new SequenceFeatures(features);
52  0 assertFalse(store.hasFeatures());
53   
54  0 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
55    Float.NaN, null);
56  0 features.add(sf1);
57  0 SequenceFeature sf2 = new SequenceFeature("Metal", "desc", 15, 18,
58    Float.NaN, null);
59  0 features.add(sf2); // nested
60  0 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc2", 0, 0,
61    Float.NaN, null); // non-positional
62  0 features.add(sf3);
63  0 store = new SequenceFeatures(features);
64  0 assertTrue(store.hasFeatures());
65  0 assertEquals(2, store.getFeatureCount(true)); // positional
66  0 assertEquals(1, store.getFeatureCount(false)); // non-positional
67  0 assertFalse(store.add(sf1)); // already contained
68  0 assertFalse(store.add(sf2)); // already contained
69  0 assertFalse(store.add(sf3)); // already contained
70    }
71   
 
72  0 toggle @Test(groups = "Functional")
73    public void testGetPositionalFeatures()
74    {
75  0 SequenceFeaturesI store = new SequenceFeatures();
76  0 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
77    Float.NaN, null);
78  0 store.add(sf1);
79    // same range, different description
80  0 SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
81    Float.NaN, null);
82  0 store.add(sf2);
83    // discontiguous range
84  0 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40,
85    Float.NaN, null);
86  0 store.add(sf3);
87    // overlapping range
88  0 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35,
89    Float.NaN, null);
90  0 store.add(sf4);
91    // enclosing range
92  0 SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50,
93    Float.NaN, null);
94  0 store.add(sf5);
95    // non-positional feature
96  0 SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0,
97    Float.NaN, null);
98  0 store.add(sf6);
99    // contact feature
100  0 SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc", 18,
101    45, Float.NaN, null);
102  0 store.add(sf7);
103    // different feature type
104  0 SequenceFeature sf8 = new SequenceFeature("Pfam", "desc", 30, 40,
105    Float.NaN, null);
106  0 store.add(sf8);
107  0 SequenceFeature sf9 = new SequenceFeature("Pfam", "desc", 15, 35,
108    Float.NaN, null);
109  0 store.add(sf9);
110   
111    /*
112    * get all positional features
113    */
114  0 List<SequenceFeature> features = store.getPositionalFeatures();
115  0 assertEquals(features.size(), 8);
116  0 assertTrue(features.contains(sf1));
117  0 assertTrue(features.contains(sf2));
118  0 assertTrue(features.contains(sf3));
119  0 assertTrue(features.contains(sf4));
120  0 assertTrue(features.contains(sf5));
121  0 assertFalse(features.contains(sf6)); // non-positional
122  0 assertTrue(features.contains(sf7));
123  0 assertTrue(features.contains(sf8));
124  0 assertTrue(features.contains(sf9));
125   
126    /*
127    * get features by type
128    */
129  0 assertTrue(store.getPositionalFeatures((String) null).isEmpty());
130  0 assertTrue(store.getPositionalFeatures("Cath").isEmpty());
131  0 assertTrue(store.getPositionalFeatures("METAL").isEmpty());
132   
133  0 features = store.getPositionalFeatures("Metal");
134  0 assertEquals(features.size(), 5);
135  0 assertTrue(features.contains(sf1));
136  0 assertTrue(features.contains(sf2));
137  0 assertTrue(features.contains(sf3));
138  0 assertTrue(features.contains(sf4));
139  0 assertTrue(features.contains(sf5));
140  0 assertFalse(features.contains(sf6));
141   
142  0 features = store.getPositionalFeatures("Disulphide bond");
143  0 assertEquals(features.size(), 1);
144  0 assertTrue(features.contains(sf7));
145   
146  0 features = store.getPositionalFeatures("Pfam");
147  0 assertEquals(features.size(), 2);
148  0 assertTrue(features.contains(sf8));
149  0 assertTrue(features.contains(sf9));
150    }
151   
 
152  0 toggle @Test(groups = "Functional")
153    public void testGetContactFeatures()
154    {
155  0 SequenceFeaturesI store = new SequenceFeatures();
156    // non-contact
157  0 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
158    Float.NaN, null);
159  0 store.add(sf1);
160    // non-positional
161  0 SequenceFeature sf2 = new SequenceFeature("Metal", "desc", 0, 0,
162    Float.NaN, null);
163  0 store.add(sf2);
164    // contact feature
165  0 SequenceFeature sf3 = new SequenceFeature("Disulphide bond", "desc", 18,
166    45, Float.NaN, null);
167  0 store.add(sf3);
168    // repeat for different feature type
169  0 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 10, 20,
170    Float.NaN, null);
171  0 store.add(sf4);
172  0 SequenceFeature sf5 = new SequenceFeature("Pfam", "desc", 0, 0,
173    Float.NaN, null);
174  0 store.add(sf5);
175  0 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "desc", 18,
176    45, Float.NaN, null);
177  0 store.add(sf6);
178   
179    /*
180    * get all contact features
181    */
182  0 List<SequenceFeature> features = store.getContactFeatures();
183  0 assertEquals(features.size(), 2);
184  0 assertTrue(features.contains(sf3));
185  0 assertTrue(features.contains(sf6));
186   
187    /*
188    * get contact features by type
189    */
190  0 assertTrue(store.getContactFeatures((String) null).isEmpty());
191  0 assertTrue(store.getContactFeatures("Cath").isEmpty());
192  0 assertTrue(store.getContactFeatures("Pfam").isEmpty());
193  0 assertTrue(store.getContactFeatures("DISULPHIDE BOND").isEmpty());
194   
195  0 features = store.getContactFeatures("Disulphide bond");
196  0 assertEquals(features.size(), 1);
197  0 assertTrue(features.contains(sf3));
198   
199  0 features = store.getContactFeatures("Disulfide bond");
200  0 assertEquals(features.size(), 1);
201  0 assertTrue(features.contains(sf6));
202    }
203   
 
204  0 toggle @Test(groups = "Functional")
205    public void testGetNonPositionalFeatures()
206    {
207  0 SequenceFeaturesI store = new SequenceFeatures();
208    // positional
209  0 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
210    Float.NaN, null);
211  0 store.add(sf1);
212    // non-positional
213  0 SequenceFeature sf2 = new SequenceFeature("Metal", "desc", 0, 0,
214    Float.NaN, null);
215  0 store.add(sf2);
216    // contact feature
217  0 SequenceFeature sf3 = new SequenceFeature("Disulphide bond", "desc", 18,
218    45, Float.NaN, null);
219  0 store.add(sf3);
220    // repeat for different feature type
221  0 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 10, 20,
222    Float.NaN, null);
223  0 store.add(sf4);
224  0 SequenceFeature sf5 = new SequenceFeature("Pfam", "desc", 0, 0,
225    Float.NaN, null);
226  0 store.add(sf5);
227  0 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "desc", 18,
228    45, Float.NaN, null);
229  0 store.add(sf6);
230    // one more non-positional, different description
231  0 SequenceFeature sf7 = new SequenceFeature("Pfam", "desc2", 0, 0,
232    Float.NaN, null);
233  0 store.add(sf7);
234   
235    /*
236    * get all non-positional features
237    */
238  0 List<SequenceFeature> features = store.getNonPositionalFeatures();
239  0 assertEquals(features.size(), 3);
240  0 assertTrue(features.contains(sf2));
241  0 assertTrue(features.contains(sf5));
242  0 assertTrue(features.contains(sf7));
243   
244    /*
245    * get non-positional features by type
246    */
247  0 assertTrue(store.getNonPositionalFeatures((String) null).isEmpty());
248  0 assertTrue(store.getNonPositionalFeatures("Cath").isEmpty());
249  0 assertTrue(store.getNonPositionalFeatures("PFAM").isEmpty());
250   
251  0 features = store.getNonPositionalFeatures("Metal");
252  0 assertEquals(features.size(), 1);
253  0 assertTrue(features.contains(sf2));
254   
255  0 features = store.getNonPositionalFeatures("Pfam");
256  0 assertEquals(features.size(), 2);
257  0 assertTrue(features.contains(sf5));
258  0 assertTrue(features.contains(sf7));
259    }
260   
261    /**
262    * Helper method to add a feature of no particular type
263    *
264    * @param sf
265    * @param type
266    * @param from
267    * @param to
268    * @return
269    */
 
270  0 toggle SequenceFeature addFeature(SequenceFeaturesI sf, String type, int from,
271    int to)
272    {
273  0 SequenceFeature sf1 = new SequenceFeature(type, "", from, to, Float.NaN,
274    null);
275  0 sf.add(sf1);
276  0 return sf1;
277    }
278   
 
279  0 toggle @Test(groups = "Functional")
280    public void testFindFeatures()
281    {
282  0 SequenceFeaturesI sf = new SequenceFeatures();
283  0 SequenceFeature sf1 = addFeature(sf, "Pfam", 10, 50);
284  0 SequenceFeature sf2 = addFeature(sf, "Pfam", 1, 15);
285  0 SequenceFeature sf3 = addFeature(sf, "Pfam", 20, 30);
286  0 SequenceFeature sf4 = addFeature(sf, "Pfam", 40, 100);
287  0 SequenceFeature sf5 = addFeature(sf, "Pfam", 60, 100);
288  0 SequenceFeature sf6 = addFeature(sf, "Pfam", 70, 70);
289  0 SequenceFeature sf7 = addFeature(sf, "Cath", 10, 50);
290  0 SequenceFeature sf8 = addFeature(sf, "Cath", 1, 15);
291  0 SequenceFeature sf9 = addFeature(sf, "Cath", 20, 30);
292  0 SequenceFeature sf10 = addFeature(sf, "Cath", 40, 100);
293  0 SequenceFeature sf11 = addFeature(sf, "Cath", 60, 100);
294  0 SequenceFeature sf12 = addFeature(sf, "Cath", 70, 70);
295   
296  0 List<SequenceFeature> overlaps = sf.findFeatures(200, 200, "Pfam");
297  0 assertTrue(overlaps.isEmpty());
298   
299  0 overlaps = sf.findFeatures(1, 9, "Pfam");
300  0 assertEquals(overlaps.size(), 1);
301  0 assertTrue(overlaps.contains(sf2));
302   
303  0 overlaps = sf.findFeatures(5, 18, "Pfam");
304  0 assertEquals(overlaps.size(), 2);
305  0 assertTrue(overlaps.contains(sf1));
306  0 assertTrue(overlaps.contains(sf2));
307   
308  0 overlaps = sf.findFeatures(30, 40, "Pfam");
309  0 assertEquals(overlaps.size(), 3);
310  0 assertTrue(overlaps.contains(sf1));
311  0 assertTrue(overlaps.contains(sf3));
312  0 assertTrue(overlaps.contains(sf4));
313   
314  0 overlaps = sf.findFeatures(80, 90, "Pfam");
315  0 assertEquals(overlaps.size(), 2);
316  0 assertTrue(overlaps.contains(sf4));
317  0 assertTrue(overlaps.contains(sf5));
318   
319  0 overlaps = sf.findFeatures(68, 70, "Pfam");
320  0 assertEquals(overlaps.size(), 3);
321  0 assertTrue(overlaps.contains(sf4));
322  0 assertTrue(overlaps.contains(sf5));
323  0 assertTrue(overlaps.contains(sf6));
324   
325  0 overlaps = sf.findFeatures(16, 69, "Cath");
326  0 assertEquals(overlaps.size(), 4);
327  0 assertTrue(overlaps.contains(sf7));
328  0 assertFalse(overlaps.contains(sf8));
329  0 assertTrue(overlaps.contains(sf9));
330  0 assertTrue(overlaps.contains(sf10));
331  0 assertTrue(overlaps.contains(sf11));
332  0 assertFalse(overlaps.contains(sf12));
333   
334  0 assertTrue(sf.findFeatures(0, 1000, "Metal").isEmpty());
335   
336  0 overlaps = sf.findFeatures(7, 7, (String) null);
337  0 assertTrue(overlaps.isEmpty());
338    }
339   
 
340  0 toggle @Test(groups = "Functional")
341    public void testDelete()
342    {
343  0 SequenceFeaturesI sf = new SequenceFeatures();
344  0 SequenceFeature sf1 = addFeature(sf, "Pfam", 10, 50);
345  0 assertTrue(sf.getPositionalFeatures().contains(sf1));
346   
347  0 assertFalse(sf.delete(null));
348  0 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 15, 0f, null);
349  0 assertFalse(sf.delete(sf2)); // not added, can't delete it
350  0 assertTrue(sf.delete(sf1));
351  0 assertTrue(sf.getPositionalFeatures().isEmpty());
352    }
353   
 
354  0 toggle @Test(groups = "Functional")
355    public void testHasFeatures()
356    {
357  0 SequenceFeaturesI sf = new SequenceFeatures();
358  0 assertFalse(sf.hasFeatures());
359   
360  0 SequenceFeature sf1 = addFeature(sf, "Pfam", 10, 50);
361  0 assertTrue(sf.hasFeatures());
362   
363  0 sf.delete(sf1);
364  0 assertFalse(sf.hasFeatures());
365    }
366   
367    /**
368    * Tests for the method that gets feature groups for positional or
369    * non-positional features
370    */
 
371  0 toggle @Test(groups = "Functional")
372    public void testGetFeatureGroups()
373    {
374  0 SequenceFeaturesI sf = new SequenceFeatures();
375  0 assertTrue(sf.getFeatureGroups(true).isEmpty());
376  0 assertTrue(sf.getFeatureGroups(false).isEmpty());
377   
378    /*
379    * add a non-positional feature (begin/end = 0/0)
380    */
381  0 SequenceFeature sfx = new SequenceFeature("AType", "Desc", 0, 0, 0f,
382    "AGroup");
383  0 sf.add(sfx);
384  0 Set<String> groups = sf.getFeatureGroups(true); // for positional
385  0 assertTrue(groups.isEmpty());
386  0 groups = sf.getFeatureGroups(false); // for non-positional
387  0 assertEquals(groups.size(), 1);
388  0 assertTrue(groups.contains("AGroup"));
389  0 groups = sf.getFeatureGroups(false, "AType");
390  0 assertEquals(groups.size(), 1);
391  0 assertTrue(groups.contains("AGroup"));
392  0 groups = sf.getFeatureGroups(true, "AnotherType");
393  0 assertTrue(groups.isEmpty());
394   
395    /*
396    * add, then delete, more non-positional features of different types
397    */
398  0 SequenceFeature sfy = new SequenceFeature("AnotherType", "Desc", 0, 0,
399    0f, "AnotherGroup");
400  0 sf.add(sfy);
401  0 SequenceFeature sfz = new SequenceFeature("AThirdType", "Desc", 0, 0,
402    0f, null);
403  0 sf.add(sfz);
404  0 groups = sf.getFeatureGroups(false);
405  0 assertEquals(groups.size(), 3);
406  0 assertTrue(groups.contains("AGroup"));
407  0 assertTrue(groups.contains("AnotherGroup"));
408  0 assertTrue(groups.contains(null)); // null is a possible group
409  0 sf.delete(sfz);
410  0 sf.delete(sfy);
411  0 groups = sf.getFeatureGroups(false);
412  0 assertEquals(groups.size(), 1);
413  0 assertTrue(groups.contains("AGroup"));
414   
415    /*
416    * add positional features
417    */
418  0 SequenceFeature sf1 = new SequenceFeature("Pfam", "Desc", 10, 50, 0f,
419    "PfamGroup");
420  0 sf.add(sf1);
421  0 groups = sf.getFeatureGroups(true);
422  0 assertEquals(groups.size(), 1);
423  0 assertTrue(groups.contains("PfamGroup"));
424  0 groups = sf.getFeatureGroups(false); // non-positional unchanged
425  0 assertEquals(groups.size(), 1);
426  0 assertTrue(groups.contains("AGroup"));
427   
428  0 SequenceFeature sf2 = new SequenceFeature("Cath", "Desc", 10, 50, 0f,
429    null);
430  0 sf.add(sf2);
431  0 groups = sf.getFeatureGroups(true);
432  0 assertEquals(groups.size(), 2);
433  0 assertTrue(groups.contains("PfamGroup"));
434  0 assertTrue(groups.contains(null));
435   
436  0 sf.delete(sf1);
437  0 sf.delete(sf2);
438  0 assertTrue(sf.getFeatureGroups(true).isEmpty());
439   
440  0 SequenceFeature sf3 = new SequenceFeature("CDS", "", 10, 50, 0f,
441    "Ensembl");
442  0 sf.add(sf3);
443  0 SequenceFeature sf4 = new SequenceFeature("exon", "", 10, 50, 0f,
444    "Ensembl");
445  0 sf.add(sf4);
446  0 groups = sf.getFeatureGroups(true);
447  0 assertEquals(groups.size(), 1);
448  0 assertTrue(groups.contains("Ensembl"));
449   
450    /*
451    * delete last Ensembl group feature from CDS features
452    * but still have one in exon features
453    */
454  0 sf.delete(sf3);
455  0 groups = sf.getFeatureGroups(true);
456  0 assertEquals(groups.size(), 1);
457  0 assertTrue(groups.contains("Ensembl"));
458   
459    /*
460    * delete the last non-positional feature
461    */
462  0 sf.delete(sfx);
463  0 groups = sf.getFeatureGroups(false);
464  0 assertTrue(groups.isEmpty());
465    }
466   
 
467  0 toggle @Test(groups = "Functional")
468    public void testGetFeatureTypesForGroups()
469    {
470  0 SequenceFeaturesI sf = new SequenceFeatures();
471  0 assertTrue(sf.getFeatureTypesForGroups(true, (String) null).isEmpty());
472   
473    /*
474    * add feature with group = "Uniprot", type = "helix"
475    */
476  0 String groupUniprot = "Uniprot";
477  0 SequenceFeature sf1 = new SequenceFeature("helix", "Desc", 10, 50, 0f,
478    groupUniprot);
479  0 sf.add(sf1);
480  0 Set<String> groups = sf.getFeatureTypesForGroups(true, groupUniprot);
481  0 assertEquals(groups.size(), 1);
482  0 assertTrue(groups.contains("helix"));
483  0 assertTrue(sf.getFeatureTypesForGroups(true, (String) null).isEmpty());
484   
485    /*
486    * add feature with group = "Uniprot", type = "strand"
487    */
488  0 SequenceFeature sf2 = new SequenceFeature("strand", "Desc", 10, 50, 0f,
489    groupUniprot);
490  0 sf.add(sf2);
491  0 groups = sf.getFeatureTypesForGroups(true, groupUniprot);
492  0 assertEquals(groups.size(), 2);
493  0 assertTrue(groups.contains("helix"));
494  0 assertTrue(groups.contains("strand"));
495   
496    /*
497    * delete the "strand" Uniprot feature - still have "helix"
498    */
499  0 sf.delete(sf2);
500  0 groups = sf.getFeatureTypesForGroups(true, groupUniprot);
501  0 assertEquals(groups.size(), 1);
502  0 assertTrue(groups.contains("helix"));
503   
504    /*
505    * delete the "helix" Uniprot feature - none left
506    */
507  0 sf.delete(sf1);
508  0 assertTrue(sf.getFeatureTypesForGroups(true, groupUniprot).isEmpty());
509   
510    /*
511    * add some null group features
512    */
513  0 SequenceFeature sf3 = new SequenceFeature("strand", "Desc", 10, 50, 0f,
514    null);
515  0 sf.add(sf3);
516  0 SequenceFeature sf4 = new SequenceFeature("turn", "Desc", 10, 50, 0f,
517    null);
518  0 sf.add(sf4);
519  0 groups = sf.getFeatureTypesForGroups(true, (String) null);
520  0 assertEquals(groups.size(), 2);
521  0 assertTrue(groups.contains("strand"));
522  0 assertTrue(groups.contains("turn"));
523   
524    /*
525    * add strand/Cath and turn/Scop and query for one or both groups
526    * (find feature types for groups selected in Feature Settings)
527    */
528  0 SequenceFeature sf5 = new SequenceFeature("strand", "Desc", 10, 50, 0f,
529    "Cath");
530  0 sf.add(sf5);
531  0 SequenceFeature sf6 = new SequenceFeature("turn", "Desc", 10, 50, 0f,
532    "Scop");
533  0 sf.add(sf6);
534  0 groups = sf.getFeatureTypesForGroups(true, "Cath");
535  0 assertEquals(groups.size(), 1);
536  0 assertTrue(groups.contains("strand"));
537  0 groups = sf.getFeatureTypesForGroups(true, "Scop");
538  0 assertEquals(groups.size(), 1);
539  0 assertTrue(groups.contains("turn"));
540  0 groups = sf.getFeatureTypesForGroups(true, "Cath", "Scop");
541  0 assertEquals(groups.size(), 2);
542  0 assertTrue(groups.contains("turn"));
543  0 assertTrue(groups.contains("strand"));
544    // alternative vararg syntax
545  0 groups = sf.getFeatureTypesForGroups(true,
546    new String[]
547    { "Cath", "Scop" });
548  0 assertEquals(groups.size(), 2);
549  0 assertTrue(groups.contains("turn"));
550  0 assertTrue(groups.contains("strand"));
551    }
552   
 
553  0 toggle @Test(groups = "Functional")
554    public void testGetFeatureTypes()
555    {
556  0 SequenceFeaturesI store = new SequenceFeatures();
557  0 Set<String> types = store.getFeatureTypes();
558  0 assertTrue(types.isEmpty());
559   
560  0 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
561    Float.NaN, null);
562  0 store.add(sf1);
563  0 types = store.getFeatureTypes();
564  0 assertEquals(types.size(), 1);
565  0 assertTrue(types.contains("Metal"));
566   
567    // null type is rejected...
568  0 SequenceFeature sf2 = new SequenceFeature(null, "desc", 10, 20,
569    Float.NaN, null);
570  0 assertFalse(store.add(sf2));
571  0 types = store.getFeatureTypes();
572  0 assertEquals(types.size(), 1);
573  0 assertFalse(types.contains(null));
574  0 assertTrue(types.contains("Metal"));
575   
576    /*
577    * add non-positional feature
578    */
579  0 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 0, 0,
580    Float.NaN, null);
581  0 store.add(sf3);
582  0 types = store.getFeatureTypes();
583  0 assertEquals(types.size(), 2);
584  0 assertTrue(types.contains("Pfam"));
585   
586    /*
587    * add contact feature
588    */
589  0 SequenceFeature sf4 = new SequenceFeature("Disulphide Bond", "desc", 10,
590    20, Float.NaN, null);
591  0 store.add(sf4);
592  0 types = store.getFeatureTypes();
593  0 assertEquals(types.size(), 3);
594  0 assertTrue(types.contains("Disulphide Bond"));
595   
596    /*
597    * add another Pfam
598    */
599  0 SequenceFeature sf5 = new SequenceFeature("Pfam", "desc", 10, 20,
600    Float.NaN, null);
601  0 store.add(sf5);
602  0 types = store.getFeatureTypes();
603  0 assertEquals(types.size(), 3); // unchanged
604   
605    /*
606    * delete first Pfam - still have one
607    */
608  0 assertTrue(store.delete(sf3));
609  0 types = store.getFeatureTypes();
610  0 assertEquals(types.size(), 3);
611  0 assertTrue(types.contains("Pfam"));
612   
613    /*
614    * delete second Pfam - no longer have one
615    */
616  0 assertTrue(store.delete(sf5));
617  0 types = store.getFeatureTypes();
618  0 assertEquals(types.size(), 2);
619  0 assertFalse(types.contains("Pfam"));
620    }
621   
 
622  0 toggle @Test(groups = "Functional")
623    public void testGetFeatureCount()
624    {
625  0 SequenceFeaturesI store = new SequenceFeatures();
626  0 assertEquals(store.getFeatureCount(true), 0);
627  0 assertEquals(store.getFeatureCount(false), 0);
628   
629    /*
630    * add positional
631    */
632  0 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
633    Float.NaN, null);
634  0 store.add(sf1);
635  0 assertEquals(store.getFeatureCount(true), 1);
636  0 assertEquals(store.getFeatureCount(false), 0);
637   
638    /*
639    * null feature type is rejected
640    */
641  0 SequenceFeature sf2 = new SequenceFeature(null, "desc", 10, 20,
642    Float.NaN, null);
643  0 assertFalse(store.add(sf2));
644  0 assertEquals(store.getFeatureCount(true), 1);
645  0 assertEquals(store.getFeatureCount(false), 0);
646   
647    /*
648    * add non-positional feature
649    */
650  0 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 0, 0,
651    Float.NaN, null);
652  0 store.add(sf3);
653  0 assertEquals(store.getFeatureCount(true), 1);
654  0 assertEquals(store.getFeatureCount(false), 1);
655   
656    /*
657    * add contact feature (counts as 1)
658    */
659  0 SequenceFeature sf4 = new SequenceFeature("Disulphide Bond", "desc", 10,
660    20, Float.NaN, null);
661  0 store.add(sf4);
662  0 assertEquals(store.getFeatureCount(true), 2);
663  0 assertEquals(store.getFeatureCount(false), 1);
664   
665    /*
666    * add another Pfam but this time as a positional feature
667    */
668  0 SequenceFeature sf5 = new SequenceFeature("Pfam", "desc", 10, 20,
669    Float.NaN, null);
670  0 store.add(sf5);
671  0 assertEquals(store.getFeatureCount(true), 3); // sf1, sf4, sf5
672  0 assertEquals(store.getFeatureCount(false), 1); // sf3
673  0 assertEquals(store.getFeatureCount(true, "Pfam"), 1); // positional
674  0 assertEquals(store.getFeatureCount(false, "Pfam"), 1); // non-positional
675    // search for type==null
676  0 assertEquals(store.getFeatureCount(true, (String) null), 0);
677    // search with no type specified
678  0 assertEquals(store.getFeatureCount(true, (String[]) null), 3);
679  0 assertEquals(store.getFeatureCount(true, "Metal", "Cath"), 1);
680  0 assertEquals(store.getFeatureCount(true, "Disulphide Bond"), 1);
681  0 assertEquals(store.getFeatureCount(true, "Metal", "Pfam", null), 2);
682   
683    /*
684    * delete first Pfam (non-positional)
685    */
686  0 assertTrue(store.delete(sf3));
687  0 assertEquals(store.getFeatureCount(true), 3);
688  0 assertEquals(store.getFeatureCount(false), 0);
689   
690    /*
691    * delete second Pfam (positional)
692    */
693  0 assertTrue(store.delete(sf5));
694  0 assertEquals(store.getFeatureCount(true), 2);
695  0 assertEquals(store.getFeatureCount(false), 0);
696    }
697   
 
698  0 toggle @Test(groups = "Functional")
699    public void testGetAllFeatures()
700    {
701  0 SequenceFeaturesI store = new SequenceFeatures();
702  0 List<SequenceFeature> features = store.getAllFeatures();
703  0 assertTrue(features.isEmpty());
704   
705  0 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
706    Float.NaN, null);
707  0 store.add(sf1);
708  0 features = store.getAllFeatures();
709  0 assertEquals(features.size(), 1);
710  0 assertTrue(features.contains(sf1));
711   
712  0 SequenceFeature sf2 = new SequenceFeature("Metallic", "desc", 10, 20,
713    Float.NaN, null);
714  0 store.add(sf2);
715  0 features = store.getAllFeatures();
716  0 assertEquals(features.size(), 2);
717  0 assertTrue(features.contains(sf2));
718   
719    /*
720    * add non-positional feature
721    */
722  0 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 0, 0,
723    Float.NaN, null);
724  0 store.add(sf3);
725  0 features = store.getAllFeatures();
726  0 assertEquals(features.size(), 3);
727  0 assertTrue(features.contains(sf3));
728   
729    /*
730    * add contact feature
731    */
732  0 SequenceFeature sf4 = new SequenceFeature("Disulphide Bond", "desc", 10,
733    20, Float.NaN, null);
734  0 store.add(sf4);
735  0 features = store.getAllFeatures();
736  0 assertEquals(features.size(), 4);
737  0 assertTrue(features.contains(sf4));
738   
739    /*
740    * add another Pfam
741    */
742  0 SequenceFeature sf5 = new SequenceFeature("Pfam", "desc", 10, 20,
743    Float.NaN, null);
744  0 store.add(sf5);
745  0 features = store.getAllFeatures();
746  0 assertEquals(features.size(), 5);
747  0 assertTrue(features.contains(sf5));
748   
749    /*
750    * select by type does not apply to non-positional features
751    */
752  0 features = store.getAllFeatures("Cath");
753  0 assertEquals(features.size(), 1);
754  0 assertTrue(features.contains(sf3));
755   
756  0 features = store.getAllFeatures("Pfam", "Cath", "Metal");
757  0 assertEquals(features.size(), 3);
758  0 assertTrue(features.contains(sf1));
759  0 assertTrue(features.contains(sf3));
760  0 assertTrue(features.contains(sf5));
761   
762    /*
763    * delete first Pfam
764    */
765  0 assertTrue(store.delete(sf3));
766  0 features = store.getAllFeatures();
767  0 assertEquals(features.size(), 4);
768  0 assertFalse(features.contains(sf3));
769   
770    /*
771    * delete second Pfam
772    */
773  0 assertTrue(store.delete(sf5));
774  0 features = store.getAllFeatures();
775  0 assertEquals(features.size(), 3);
776  0 assertFalse(features.contains(sf3));
777    }
778   
 
779  0 toggle @Test(groups = "Functional")
780    public void testGetTotalFeatureLength()
781    {
782  0 SequenceFeaturesI store = new SequenceFeatures();
783  0 assertEquals(store.getTotalFeatureLength(), 0);
784   
785  0 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
786    Float.NaN, null);
787  0 assertTrue(store.add(sf1));
788  0 assertEquals(store.getTotalFeatureLength(), 11);
789  0 assertEquals(store.getTotalFeatureLength("Metal"), 11);
790  0 assertEquals(store.getTotalFeatureLength("Plastic"), 0);
791   
792    // re-add does nothing!
793  0 assertFalse(store.add(sf1));
794  0 assertEquals(store.getTotalFeatureLength(), 11);
795   
796    /*
797    * add non-positional feature
798    */
799  0 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 0, 0,
800    Float.NaN, null);
801  0 store.add(sf3);
802  0 assertEquals(store.getTotalFeatureLength(), 11);
803   
804    /*
805    * add contact feature - counts 1 to feature length
806    */
807  0 SequenceFeature sf4 = new SequenceFeature("Disulphide Bond", "desc", 10,
808    20, Float.NaN, null);
809  0 store.add(sf4);
810  0 assertEquals(store.getTotalFeatureLength(), 12);
811   
812    /*
813    * add another Pfam
814    */
815  0 SequenceFeature sf5 = new SequenceFeature("Pfam", "desc", 10, 20,
816    Float.NaN, null);
817  0 store.add(sf5);
818  0 assertEquals(store.getTotalFeatureLength(), 23);
819   
820    /*
821    * delete features
822    */
823  0 assertTrue(store.delete(sf3)); // non-positional
824  0 assertEquals(store.getTotalFeatureLength(), 23); // no change
825   
826  0 assertTrue(store.delete(sf5));
827  0 assertEquals(store.getTotalFeatureLength(), 12);
828   
829  0 assertTrue(store.delete(sf4)); // contact
830  0 assertEquals(store.getTotalFeatureLength(), 11);
831   
832  0 assertTrue(store.delete(sf1));
833  0 assertEquals(store.getTotalFeatureLength(), 0);
834    }
835   
 
836  0 toggle @Test(groups = "Functional")
837    public void testGetMinimumScore_getMaximumScore()
838    {
839  0 SequenceFeatures sf = new SequenceFeatures();
840  0 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 0, 0,
841    Float.NaN, "group"); // non-positional, no score
842  0 sf.add(sf1);
843  0 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 10, 20,
844    Float.NaN, "group"); // positional, no score
845  0 sf.add(sf2);
846  0 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 10, 20, 1f,
847    "group");
848  0 sf.add(sf3);
849  0 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 12, 16, 4f,
850    "group");
851  0 sf.add(sf4);
852  0 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 0, 0, 11f,
853    "group");
854  0 sf.add(sf5);
855  0 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, -7f,
856    "group");
857  0 sf.add(sf6);
858   
859  0 assertEquals(sf.getMinimumScore("nosuchtype", true), Float.NaN);
860  0 assertEquals(sf.getMinimumScore("nosuchtype", false), Float.NaN);
861  0 assertEquals(sf.getMaximumScore("nosuchtype", true), Float.NaN);
862  0 assertEquals(sf.getMaximumScore("nosuchtype", false), Float.NaN);
863   
864    // positional features min-max:
865  0 assertEquals(sf.getMinimumScore("Metal", true), 1f);
866  0 assertEquals(sf.getMaximumScore("Metal", true), 4f);
867  0 assertEquals(sf.getMinimumScore("Cath", true), Float.NaN);
868  0 assertEquals(sf.getMaximumScore("Cath", true), Float.NaN);
869   
870    // non-positional features min-max:
871  0 assertEquals(sf.getMinimumScore("Cath", false), -7f);
872  0 assertEquals(sf.getMaximumScore("Cath", false), 11f);
873  0 assertEquals(sf.getMinimumScore("Metal", false), Float.NaN);
874  0 assertEquals(sf.getMaximumScore("Metal", false), Float.NaN);
875   
876    // delete features; min-max should get recomputed
877  0 sf.delete(sf6);
878  0 assertEquals(sf.getMinimumScore("Cath", false), 11f);
879  0 assertEquals(sf.getMaximumScore("Cath", false), 11f);
880  0 sf.delete(sf4);
881  0 assertEquals(sf.getMinimumScore("Metal", true), 1f);
882  0 assertEquals(sf.getMaximumScore("Metal", true), 1f);
883  0 sf.delete(sf5);
884  0 assertEquals(sf.getMinimumScore("Cath", false), Float.NaN);
885  0 assertEquals(sf.getMaximumScore("Cath", false), Float.NaN);
886  0 sf.delete(sf3);
887  0 assertEquals(sf.getMinimumScore("Metal", true), Float.NaN);
888  0 assertEquals(sf.getMaximumScore("Metal", true), Float.NaN);
889  0 sf.delete(sf1);
890  0 sf.delete(sf2);
891  0 assertFalse(sf.hasFeatures());
892  0 assertEquals(sf.getMinimumScore("Cath", false), Float.NaN);
893  0 assertEquals(sf.getMaximumScore("Cath", false), Float.NaN);
894  0 assertEquals(sf.getMinimumScore("Metal", true), Float.NaN);
895  0 assertEquals(sf.getMaximumScore("Metal", true), Float.NaN);
896    }
897   
 
898  0 toggle @Test(groups = "Functional")
899    public void testVarargsToTypes()
900    {
901  0 SequenceFeatures sf = new SequenceFeatures();
902  0 sf.add(new SequenceFeature("Metal", "desc", 0, 0, Float.NaN, "group"));
903  0 sf.add(new SequenceFeature("Cath", "desc", 10, 20, Float.NaN, "group"));
904   
905    /*
906    * no type specified - get all types stored
907    * they are returned in keyset (alphabetical) order
908    */
909  0 Map<String, FeatureStore> featureStores = (Map<String, FeatureStore>) PA
910    .getValue(sf, "featureStore");
911   
912  0 Iterable<FeatureStore> types = sf.varargToTypes();
913  0 Iterator<FeatureStore> iterator = types.iterator();
914  0 assertTrue(iterator.hasNext());
915  0 assertSame(iterator.next(), featureStores.get("Cath"));
916  0 assertTrue(iterator.hasNext());
917  0 assertSame(iterator.next(), featureStores.get("Metal"));
918  0 assertFalse(iterator.hasNext());
919   
920    /*
921    * empty array is the same as no vararg parameter supplied
922    * so treated as all stored types
923    */
924  0 types = sf.varargToTypes(new String[] {});
925  0 iterator = types.iterator();
926  0 assertTrue(iterator.hasNext());
927  0 assertSame(iterator.next(), featureStores.get("Cath"));
928  0 assertTrue(iterator.hasNext());
929  0 assertSame(iterator.next(), featureStores.get("Metal"));
930  0 assertFalse(iterator.hasNext());
931   
932    /*
933    * null type specified; this is passed as vararg
934    * String[1] {null}
935    */
936  0 types = sf.varargToTypes((String) null);
937  0 assertFalse(types.iterator().hasNext());
938   
939    /*
940    * null types array specified; this is passed as vararg null
941    */
942  0 types = sf.varargToTypes((String[]) null);
943  0 iterator = types.iterator();
944  0 assertTrue(iterator.hasNext());
945  0 assertSame(iterator.next(), featureStores.get("Cath"));
946  0 assertTrue(iterator.hasNext());
947  0 assertSame(iterator.next(), featureStores.get("Metal"));
948  0 assertFalse(iterator.hasNext());
949   
950    /*
951    * one type specified
952    */
953  0 types = sf.varargToTypes("Metal");
954  0 iterator = types.iterator();
955  0 assertTrue(iterator.hasNext());
956  0 assertSame(iterator.next(), featureStores.get("Metal"));
957  0 assertFalse(iterator.hasNext());
958   
959    /*
960    * two types specified - order is preserved
961    */
962  0 types = sf.varargToTypes("Metal", "Cath");
963  0 iterator = types.iterator();
964  0 assertTrue(iterator.hasNext());
965  0 assertSame(iterator.next(), featureStores.get("Metal"));
966  0 assertTrue(iterator.hasNext());
967  0 assertSame(iterator.next(), featureStores.get("Cath"));
968  0 assertFalse(iterator.hasNext());
969   
970    /*
971    * null type included - should be ignored
972    */
973  0 types = sf.varargToTypes("Metal", null, "Helix");
974  0 iterator = types.iterator();
975  0 assertTrue(iterator.hasNext());
976  0 assertSame(iterator.next(), featureStores.get("Metal"));
977  0 assertFalse(iterator.hasNext());
978    }
979   
 
980  0 toggle @Test(groups = "Functional")
981    public void testGetFeatureTypes_byOntology()
982    {
983  0 SequenceFeaturesI store = new SequenceFeatures();
984   
985  0 SequenceFeature sf1 = new SequenceFeature("transcript", "desc", 10, 20,
986    Float.NaN, null);
987  0 store.add(sf1);
988    // mRNA isA mature_transcript isA transcript
989  0 SequenceFeature sf2 = new SequenceFeature("mRNA", "desc", 10, 20,
990    Float.NaN, null);
991  0 store.add(sf2);
992    // just to prove non-positional feature types are included
993  0 SequenceFeature sf3 = new SequenceFeature("mRNA", "desc", 0, 0,
994    Float.NaN, null);
995  0 store.add(sf3);
996  0 SequenceFeature sf4 = new SequenceFeature("CDS", "desc", 0, 0,
997    Float.NaN, null);
998  0 store.add(sf4);
999   
1000  0 Set<String> types = store.getFeatureTypes("transcript");
1001  0 assertEquals(types.size(), 2);
1002  0 assertTrue(types.contains("transcript"));
1003  0 assertTrue(types.contains("mRNA"));
1004   
1005    // matches include arguments whether SO terms or not
1006  0 types = store.getFeatureTypes("transcript", "CDS");
1007  0 assertEquals(types.size(), 3);
1008  0 assertTrue(types.contains("transcript"));
1009  0 assertTrue(types.contains("mRNA"));
1010  0 assertTrue(types.contains("CDS"));
1011   
1012  0 types = store.getFeatureTypes("exon");
1013  0 assertTrue(types.isEmpty());
1014    }
1015   
 
1016  0 toggle @Test(groups = "Functional")
1017    public void testGetFeaturesByOntology()
1018    {
1019  0 SequenceFeaturesI store = new SequenceFeatures();
1020  0 List<SequenceFeature> features = store.getFeaturesByOntology();
1021  0 assertTrue(features.isEmpty());
1022  0 assertTrue(store.getFeaturesByOntology(new String[] {}).isEmpty());
1023  0 assertTrue(store.getFeaturesByOntology((String[]) null).isEmpty());
1024   
1025  0 SequenceFeature transcriptFeature = new SequenceFeature("transcript",
1026    "desc", 10, 20, Float.NaN, null);
1027  0 store.add(transcriptFeature);
1028   
1029    /*
1030    * mRNA is a sub-type of transcript; added here 'as if' non-positional
1031    * just to show that non-positional features are included in results
1032    */
1033  0 SequenceFeature mrnaFeature = new SequenceFeature("mRNA", "desc", 0, 0,
1034    Float.NaN, null);
1035  0 store.add(mrnaFeature);
1036   
1037  0 SequenceFeature pfamFeature = new SequenceFeature("Pfam", "desc", 30,
1038    40, Float.NaN, null);
1039  0 store.add(pfamFeature);
1040   
1041    /*
1042    * "transcript" matches both itself and the sub-term "mRNA"
1043    */
1044  0 features = store.getFeaturesByOntology("transcript");
1045  0 assertEquals(features.size(), 2);
1046  0 assertTrue(features.contains(transcriptFeature));
1047  0 assertTrue(features.contains(mrnaFeature));
1048   
1049    /*
1050    * "mRNA" matches itself but not parent term "transcript"
1051    */
1052  0 features = store.getFeaturesByOntology("mRNA");
1053  0 assertEquals(features.size(), 1);
1054  0 assertTrue(features.contains(mrnaFeature));
1055   
1056    /*
1057    * "pfam" is not an SO term but is included as an exact match
1058    */
1059  0 features = store.getFeaturesByOntology("mRNA", "Pfam");
1060  0 assertEquals(features.size(), 2);
1061  0 assertTrue(features.contains(mrnaFeature));
1062  0 assertTrue(features.contains(pfamFeature));
1063   
1064  0 features = store.getFeaturesByOntology("sequence_variant");
1065  0 assertTrue(features.isEmpty());
1066    }
1067   
 
1068  0 toggle @Test(groups = "Functional")
1069    public void testSortFeatures()
1070    {
1071  0 List<SequenceFeature> sfs = new ArrayList<>();
1072  0 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 30, 60,
1073    Float.NaN, null);
1074  0 sfs.add(sf1);
1075  0 SequenceFeature sf2 = new SequenceFeature("Rfam", "desc", 40, 50,
1076    Float.NaN, null);
1077  0 sfs.add(sf2);
1078  0 SequenceFeature sf3 = new SequenceFeature("Rfam", "desc", 50, 60,
1079    Float.NaN, null);
1080  0 sfs.add(sf3);
1081  0 SequenceFeature sf4 = new SequenceFeature("Xfam", "desc", 30, 80,
1082    Float.NaN, null);
1083  0 sfs.add(sf4);
1084  0 SequenceFeature sf5 = new SequenceFeature("Xfam", "desc", 30, 90,
1085    Float.NaN, null);
1086  0 sfs.add(sf5);
1087   
1088    /*
1089    * sort by end position descending, order unchanged if matched
1090    */
1091  0 SequenceFeatures.sortFeatures(sfs, false);
1092  0 assertSame(sfs.get(0), sf5); // end 90
1093  0 assertSame(sfs.get(1), sf4); // end 80
1094  0 assertSame(sfs.get(2), sf1); // end 60, start 50
1095  0 assertSame(sfs.get(3), sf3); // end 60, start 30
1096  0 assertSame(sfs.get(4), sf2); // end 50
1097   
1098    /*
1099    * resort {5, 4, 1, 3, 2} by start position ascending, end descending
1100    */
1101  0 SequenceFeatures.sortFeatures(sfs, true);
1102  0 assertSame(sfs.get(0), sf5); // start 30, end 90
1103  0 assertSame(sfs.get(1), sf4); // start 30, end 80
1104  0 assertSame(sfs.get(2), sf1); // start 30, end 60
1105  0 assertSame(sfs.get(3), sf2); // start 40
1106  0 assertSame(sfs.get(4), sf3); // start 50
1107    }
1108   
 
1109  0 toggle @Test(groups = "Functional")
1110    public void testGetFeaturesForGroup()
1111    {
1112  0 SequenceFeaturesI store = new SequenceFeatures();
1113   
1114  0 List<SequenceFeature> features = store.getFeaturesForGroup(true, null);
1115  0 assertTrue(features.isEmpty());
1116  0 assertTrue(store.getFeaturesForGroup(false, null).isEmpty());
1117  0 assertTrue(store.getFeaturesForGroup(true, "Uniprot").isEmpty());
1118  0 assertTrue(store.getFeaturesForGroup(false, "Uniprot").isEmpty());
1119   
1120  0 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
1121    null);
1122  0 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
1123    null);
1124  0 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
1125    "Uniprot");
1126  0 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 0, 0, 0f,
1127    "Rfam");
1128  0 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 5, 15, 0f,
1129    null);
1130  0 store.add(sf1);
1131  0 store.add(sf2);
1132  0 store.add(sf3);
1133  0 store.add(sf4);
1134  0 store.add(sf5);
1135   
1136    // positional features for null group, any type
1137  0 features = store.getFeaturesForGroup(true, null);
1138  0 assertEquals(features.size(), 2);
1139  0 assertTrue(features.contains(sf1));
1140  0 assertTrue(features.contains(sf5));
1141   
1142    // positional features for null group, specified type
1143  0 features = store.getFeaturesForGroup(true, null,
1144    new String[]
1145    { "Pfam", "Xfam" });
1146  0 assertEquals(features.size(), 1);
1147  0 assertTrue(features.contains(sf1));
1148  0 features = store.getFeaturesForGroup(true, null,
1149    new String[]
1150    { "Pfam", "Xfam", "Cath" });
1151  0 assertEquals(features.size(), 2);
1152  0 assertTrue(features.contains(sf1));
1153  0 assertTrue(features.contains(sf5));
1154   
1155    // positional features for non-null group, any type
1156  0 features = store.getFeaturesForGroup(true, "Uniprot");
1157  0 assertEquals(features.size(), 1);
1158  0 assertTrue(features.contains(sf3));
1159  0 assertTrue(store.getFeaturesForGroup(true, "Rfam").isEmpty());
1160   
1161    // positional features for non-null group, specified type
1162  0 features = store.getFeaturesForGroup(true, "Uniprot", "Pfam", "Xfam",
1163    "Rfam");
1164  0 assertEquals(features.size(), 1);
1165  0 assertTrue(features.contains(sf3));
1166  0 assertTrue(
1167    store.getFeaturesForGroup(true, "Uniprot", "Cath").isEmpty());
1168   
1169    // non-positional features for null group, any type
1170  0 features = store.getFeaturesForGroup(false, null);
1171  0 assertEquals(features.size(), 1);
1172  0 assertTrue(features.contains(sf2));
1173   
1174    // non-positional features for null group, specified type
1175  0 features = store.getFeaturesForGroup(false, null, "Pfam", "Xfam");
1176  0 assertEquals(features.size(), 1);
1177  0 assertTrue(features.contains(sf2));
1178  0 assertTrue(store.getFeaturesForGroup(false, null, "Cath").isEmpty());
1179   
1180    // non-positional features for non-null group, any type
1181  0 features = store.getFeaturesForGroup(false, "Rfam");
1182  0 assertEquals(features.size(), 1);
1183  0 assertTrue(features.contains(sf4));
1184  0 assertTrue(store.getFeaturesForGroup(false, "Uniprot").isEmpty());
1185   
1186    // non-positional features for non-null group, specified type
1187  0 features = store.getFeaturesForGroup(false, "Rfam", "Pfam", "Metal");
1188  0 assertEquals(features.size(), 1);
1189  0 assertTrue(features.contains(sf4));
1190  0 assertTrue(store.getFeaturesForGroup(false, "Rfam", "Cath", "Pfam")
1191    .isEmpty());
1192    }
1193   
 
1194  0 toggle @Test(groups = "Functional")
1195    public void testShiftFeatures()
1196    {
1197  0 SequenceFeatures store = new SequenceFeatures();
1198  0 assertFalse(store.shiftFeatures(0, 1));
1199   
1200  0 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
1201  0 store.add(sf1);
1202    // nested feature:
1203  0 SequenceFeature sf2 = new SequenceFeature("Metal", "", 8, 14, 0f, null);
1204  0 store.add(sf2);
1205    // contact feature:
1206  0 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
1207    0f, null);
1208  0 store.add(sf3);
1209    // non-positional feature:
1210  0 SequenceFeature sf4 = new SequenceFeature("Pfam", "", 0, 0, 0f, null);
1211  0 store.add(sf4);
1212   
1213    /*
1214    * shift features right by 5
1215    */
1216  0 assertTrue(store.shiftFeatures(0, 5));
1217   
1218    // non-positional features untouched:
1219  0 List<SequenceFeature> nonPos = store.getNonPositionalFeatures();
1220  0 assertEquals(nonPos.size(), 1);
1221  0 assertTrue(nonPos.contains(sf4));
1222   
1223    // positional features are replaced
1224  0 List<SequenceFeature> pos = store.getPositionalFeatures();
1225  0 assertEquals(pos.size(), 3);
1226  0 assertFalse(pos.contains(sf1));
1227  0 assertFalse(pos.contains(sf2));
1228  0 assertFalse(pos.contains(sf3));
1229  0 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
1230  0 assertEquals(pos.get(0).getBegin(), 7);
1231  0 assertEquals(pos.get(0).getEnd(), 10);
1232  0 assertEquals(pos.get(0).getType(), "Cath");
1233  0 assertEquals(pos.get(1).getBegin(), 13);
1234  0 assertEquals(pos.get(1).getEnd(), 19);
1235  0 assertEquals(pos.get(1).getType(), "Metal");
1236  0 assertEquals(pos.get(2).getBegin(), 28);
1237  0 assertEquals(pos.get(2).getEnd(), 37);
1238  0 assertEquals(pos.get(2).getType(), "Disulfide bond");
1239   
1240    /*
1241    * now shift left by 15
1242    * feature at [7-10] should be removed
1243    * feature at [13-19] should become [1-4]
1244    */
1245  0 assertTrue(store.shiftFeatures(0, -15));
1246  0 pos = store.getPositionalFeatures();
1247  0 assertEquals(pos.size(), 2);
1248  0 SequenceFeatures.sortFeatures(pos, true);
1249  0 assertEquals(pos.get(0).getBegin(), 1);
1250  0 assertEquals(pos.get(0).getEnd(), 4);
1251  0 assertEquals(pos.get(0).getType(), "Metal");
1252  0 assertEquals(pos.get(1).getBegin(), 13);
1253  0 assertEquals(pos.get(1).getEnd(), 22);
1254  0 assertEquals(pos.get(1).getType(), "Disulfide bond");
1255   
1256    /*
1257    * shift right by 4 from column 2
1258    * feature at [1-4] should be unchanged
1259    * feature at [13-22] should become [17-26]
1260    */
1261  0 assertTrue(store.shiftFeatures(2, 4));
1262  0 pos = store.getPositionalFeatures();
1263  0 assertEquals(pos.size(), 2);
1264  0 SequenceFeatures.sortFeatures(pos, true);
1265  0 assertEquals(pos.get(0).getBegin(), 1);
1266  0 assertEquals(pos.get(0).getEnd(), 4);
1267  0 assertEquals(pos.get(0).getType(), "Metal");
1268  0 assertEquals(pos.get(1).getBegin(), 17);
1269  0 assertEquals(pos.get(1).getEnd(), 26);
1270  0 assertEquals(pos.get(1).getType(), "Disulfide bond");
1271   
1272    /*
1273    * shift right from column 18
1274    * should be no updates
1275    */
1276  0 SequenceFeature f1 = pos.get(0);
1277  0 SequenceFeature f2 = pos.get(1);
1278  0 assertFalse(store.shiftFeatures(18, 6));
1279  0 pos = store.getPositionalFeatures();
1280  0 assertEquals(pos.size(), 2);
1281  0 SequenceFeatures.sortFeatures(pos, true);
1282  0 assertSame(pos.get(0), f1);
1283  0 assertSame(pos.get(1), f2);
1284    }
1285   
 
1286  0 toggle @Test(groups = "Functional")
1287    public void testIsOntologyTerm()
1288    {
1289  0 SequenceFeatures store = new SequenceFeatures();
1290  0 assertTrue(store.isOntologyTerm("gobbledygook"));
1291  0 assertTrue(store.isOntologyTerm("transcript", "transcript"));
1292  0 assertTrue(store.isOntologyTerm("mRNA", "transcript"));
1293  0 assertFalse(store.isOntologyTerm("transcript", "mRNA"));
1294  0 assertTrue(store.isOntologyTerm("junk", "transcript", "junk"));
1295  0 assertTrue(store.isOntologyTerm("junk", new String[] {}));
1296  0 assertTrue(store.isOntologyTerm("junk", (String[]) null));
1297    }
1298   
 
1299  0 toggle @Test(groups = "Functional")
1300    public void testDeleteAll()
1301    {
1302  0 SequenceFeaturesI store = new SequenceFeatures();
1303  0 assertFalse(store.hasFeatures());
1304  0 store.deleteAll();
1305  0 assertFalse(store.hasFeatures());
1306  0 store.add(new SequenceFeature("Cath", "Desc", 12, 20, 0f, "Group"));
1307  0 store.add(new SequenceFeature("Pfam", "Desc", 6, 12, 2f, "Group2"));
1308  0 assertTrue(store.hasFeatures());
1309  0 store.deleteAll();
1310  0 assertFalse(store.hasFeatures());
1311    }
1312    }