return true;
}
+ /**
+ * A helper method that adds to the result list any features from the
+ * collection provided whose feature group matches the specified group
+ *
+ * @param group
+ * @param sfs
+ * @param result
+ */
private void addFeaturesForGroup(String group,
Collection<SequenceFeature> sfs, List<SequenceFeature> result)
{
return removed;
}
- public List<SequenceFeature> findOverlappingFeatures(long start, long end)
+ public List<SequenceFeature> findFeatures(long start, long end)
{
- return findOverlappingFeatures(start, end, null);
+ return findFeatures(start, end, null);
+ }
+
+ /**
+ * Returns a (possibly empty) list of features whose extent overlaps the given
+ * range. The returned list is not ordered. Contact features are included if
+ * either of the contact points lies within the range. If the {@code result}
+ * parameter is not null, new entries are added to this list and the (possibly
+ * extended) list returned.
+ *
+ * @param start
+ * start position of overlap range (inclusive)
+ * @param end
+ * end position of overlap range (inclusive)
+ * @param result
+ * @return
+ */
+ public List<SequenceFeature> findFeatures(long start, long end,
+ List<SequenceFeature> result)
+ {
+ if (result == null)
+ {
+ result = new ArrayList<>();
+ }
+
+ findContactFeatures(start, end, result);
+ features.findOverlaps(start, end, result);
+
+ return result;
}
public List<SequenceFeature> getContactFeatures()
: nonPositionalFeatures.size();
}
- return (contactFeatureStarts == null ? 0 : contactFeatureStarts.size())
- + features.size();
+ int size = 0;
+
+ if (contactFeatureStarts != null)
+ {
+ // note a contact feature (start/end) counts as one
+ size += contactFeatureStarts.size();
+ }
+
+ if (features != null)
+ {
+ size += features.size();
+ }
+ return size;
}
/**
return positional ? positionalMinScore : nonPositionalMinScore;
}
+ /**
+ * Answers a (possibly empty) list of all non-positional features
+ *
+ * @return
+ */
public List<SequenceFeature> getNonPositionalFeatures()
{
- return getNonPositionalFeatures(new ArrayList<>());
+ List<SequenceFeature> result = new ArrayList<>();
+ getNonPositionalFeatures(result);
+ return result;
}
/**
- * Answers a list of all non-positional features. If there are none, returns
- * an immutable empty list.
+ * Adds any stored non-positional features to the result list
*
* @return
*/
- public List<SequenceFeature> getNonPositionalFeatures(
- List<SequenceFeature> result)
+ public void getNonPositionalFeatures(List<SequenceFeature> result)
{
if (nonPositionalFeatures != null)
{
result.addAll(nonPositionalFeatures);
}
- return result;
}
+ /**
+ * Returns a (possibly empty) list of all positional features stored
+ *
+ * @return
+ */
public List<SequenceFeature> getPositionalFeatures()
{
- return getPositionalFeatures(new ArrayList<>());
+ List<SequenceFeature> result = new ArrayList<>();
+ getPositionalFeatures(result);
+
+ return result;
}
/**
- * Answers a list of all positional features stored, in no guaranteed order
- *
- * @return
+ * Adds all positional features stored to the result list, in no guaranteed
+ * order, and with no check for duplicates
*/
- public List<SequenceFeature> getPositionalFeatures(
- List<SequenceFeature> result)
+ public void getPositionalFeatures(List<SequenceFeature> result)
{
-
/*
* add any contact features - from the list by start position
*/
{
result.addAll(features);
}
-
- return result;
}
/**
&& !contactFeatureStarts.isEmpty())
|| (nonPositionalFeatures != null
&& !nonPositionalFeatures.isEmpty())
- || features.size() > 0;
+ || (features != null && features.size() > 0);
return !hasFeatures;
}
}
}
- /**
- * Returns a (possibly empty) list of features whose extent overlaps the given
- * range. The returned list is not ordered. Contact features are included if
- * either of the contact points lies within the range. If the {@code result}
- * parameter is not null, new entries are added to this list and the (possibly
- * extended) list returned.
- *
- * @param start
- * start position of overlap range (inclusive)
- * @param end
- * end position of overlap range (inclusive)
- * @param result
- * @return
- */
- public List<SequenceFeature> findOverlappingFeatures(long start, long end,
- List<SequenceFeature> result)
- {
- if (result == null)
- {
- result = new ArrayList<>();
- }
-
- findContactFeatures(start, end, result);
- features.findOverlaps(start, end, result);
-
- return result;
- }
-
}
List<SequenceFeature> result = new ArrayList<>();
for (FeatureStore featureSet : varargToTypes(type))
{
- featureSet.findOverlappingFeatures(from, to, result);
+ featureSet.findFeatures(from, to, result);
}
return result;
}
{
return list == null ? new ArrayList<>() : list;
}
- return fs.findOverlappingFeatures(pos, pos, list);
+ return fs.findFeatures(pos, pos, list);
}
@Override
SequenceFeature sf3 = new SequenceFeature("", "", 20, 35, Float.NaN, null);
fs.addFeature(sf3);
- List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+ List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
assertTrue(overlaps.isEmpty());
- overlaps = fs.findOverlappingFeatures(8, 10);
+ overlaps = fs.findFeatures(8, 10);
assertEquals(overlaps.size(), 2);
assertTrue(overlaps.contains(sf0));
assertTrue(overlaps.contains(sf1));
- overlaps = fs.findOverlappingFeatures(12, 16);
+ overlaps = fs.findFeatures(12, 16);
assertEquals(overlaps.size(), 3);
assertTrue(overlaps.contains(sf0));
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf2));
- overlaps = fs.findOverlappingFeatures(33, 33);
+ overlaps = fs.findFeatures(33, 33);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf3));
}
fs.addFeature(sf4);
SequenceFeature sf5 = addFeature(fs, 35, 36);
- List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+ List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
assertTrue(overlaps.isEmpty());
- overlaps = fs.findOverlappingFeatures(10, 15);
+ overlaps = fs.findFeatures(10, 15);
assertEquals(overlaps.size(), 2);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf2));
- overlaps = fs.findOverlappingFeatures(45, 60);
+ overlaps = fs.findFeatures(45, 60);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf1));
- overlaps = fs.findOverlappingFeatures(32, 38);
+ overlaps = fs.findFeatures(32, 38);
assertEquals(overlaps.size(), 3);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf2));
assertTrue(overlaps.contains(sf5));
- overlaps = fs.findOverlappingFeatures(15, 25);
+ overlaps = fs.findFeatures(15, 25);
assertEquals(overlaps.size(), 4);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf2));
SequenceFeature sf5 = addFeature(fs, 60, 100);
SequenceFeature sf6 = addFeature(fs, 70, 70);
- List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
+ List<SequenceFeature> overlaps = fs.findFeatures(200, 200);
assertTrue(overlaps.isEmpty());
- overlaps = fs.findOverlappingFeatures(1, 9);
+ overlaps = fs.findFeatures(1, 9);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf2));
- overlaps = fs.findOverlappingFeatures(5, 18);
+ overlaps = fs.findFeatures(5, 18);
assertEquals(overlaps.size(), 2);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf2));
- overlaps = fs.findOverlappingFeatures(30, 40);
+ overlaps = fs.findFeatures(30, 40);
assertEquals(overlaps.size(), 3);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf3));
assertTrue(overlaps.contains(sf4));
- overlaps = fs.findOverlappingFeatures(80, 90);
+ overlaps = fs.findFeatures(80, 90);
assertEquals(overlaps.size(), 2);
assertTrue(overlaps.contains(sf4));
assertTrue(overlaps.contains(sf5));
- overlaps = fs.findOverlappingFeatures(68, 70);
+ overlaps = fs.findFeatures(68, 70);
assertEquals(overlaps.size(), 3);
assertTrue(overlaps.contains(sf4));
assertTrue(overlaps.contains(sf5));
/*
* neither contact point in range
*/
- List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+ List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
assertTrue(overlaps.isEmpty());
/*
* neither contact point in range
*/
- overlaps = fs.findOverlappingFeatures(11, 19);
+ overlaps = fs.findFeatures(11, 19);
assertTrue(overlaps.isEmpty());
/*
* first contact point in range
*/
- overlaps = fs.findOverlappingFeatures(5, 15);
+ overlaps = fs.findFeatures(5, 15);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf));
/*
* second contact point in range
*/
- overlaps = fs.findOverlappingFeatures(15, 25);
+ overlaps = fs.findFeatures(15, 25);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf));
/*
* both contact points in range
*/
- overlaps = fs.findOverlappingFeatures(5, 25);
+ overlaps = fs.findFeatures(5, 25);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf));
}
fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
- List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+ List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
assertTrue(overlaps.isEmpty());
- overlaps = fs.findOverlappingFeatures(8, 10);
+ overlaps = fs.findFeatures(8, 10);
assertEquals(overlaps.size(), 2);
assertEquals(overlaps.get(0).getEnd(), 20);
assertEquals(overlaps.get(1).getEnd(), 20);
- overlaps = fs.findOverlappingFeatures(12, 16);
+ overlaps = fs.findFeatures(12, 16);
assertEquals(overlaps.size(), 3);
assertEquals(overlaps.get(0).getEnd(), 20);
assertEquals(overlaps.get(1).getEnd(), 20);
assertEquals(overlaps.get(2).getEnd(), 25);
- overlaps = fs.findOverlappingFeatures(33, 33);
+ overlaps = fs.findFeatures(33, 33);
assertEquals(overlaps.size(), 1);
assertEquals(overlaps.get(0).getEnd(), 35);
}
fs.addFeature(sf4);
SequenceFeature sf5 = addFeature(fs, 35, 36);
- List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+ List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
assertTrue(overlaps.isEmpty());
- overlaps = fs.findOverlappingFeatures(10, 15);
+ overlaps = fs.findFeatures(10, 15);
assertEquals(overlaps.size(), 2);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf2));
- overlaps = fs.findOverlappingFeatures(45, 60);
+ overlaps = fs.findFeatures(45, 60);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf1));
- overlaps = fs.findOverlappingFeatures(32, 38);
+ overlaps = fs.findFeatures(32, 38);
assertEquals(overlaps.size(), 3);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf2));
assertTrue(overlaps.contains(sf5));
- overlaps = fs.findOverlappingFeatures(15, 25);
+ overlaps = fs.findFeatures(15, 25);
assertEquals(overlaps.size(), 4);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf2));
SequenceFeature sf5 = addFeature(fs, 60, 100);
SequenceFeature sf6 = addFeature(fs, 70, 70);
- List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
+ List<SequenceFeature> overlaps = fs.findFeatures(200, 200);
assertTrue(overlaps.isEmpty());
- overlaps = fs.findOverlappingFeatures(1, 9);
+ overlaps = fs.findFeatures(1, 9);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf2));
- overlaps = fs.findOverlappingFeatures(5, 18);
+ overlaps = fs.findFeatures(5, 18);
assertEquals(overlaps.size(), 2);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf2));
- overlaps = fs.findOverlappingFeatures(30, 40);
+ overlaps = fs.findFeatures(30, 40);
assertEquals(overlaps.size(), 3);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf3));
assertTrue(overlaps.contains(sf4));
- overlaps = fs.findOverlappingFeatures(80, 90);
+ overlaps = fs.findFeatures(80, 90);
assertEquals(overlaps.size(), 2);
assertTrue(overlaps.contains(sf4));
assertTrue(overlaps.contains(sf5));
- overlaps = fs.findOverlappingFeatures(68, 70);
+ overlaps = fs.findFeatures(68, 70);
assertEquals(overlaps.size(), 3);
assertTrue(overlaps.contains(sf4));
assertTrue(overlaps.contains(sf5));
/*
* neither contact point in range
*/
- List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+ List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
assertTrue(overlaps.isEmpty());
/*
* neither contact point in range
*/
- overlaps = fs.findOverlappingFeatures(11, 19);
+ overlaps = fs.findFeatures(11, 19);
assertTrue(overlaps.isEmpty());
/*
* first contact point in range
*/
- overlaps = fs.findOverlappingFeatures(5, 15);
+ overlaps = fs.findFeatures(5, 15);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf));
/*
* second contact point in range
*/
- overlaps = fs.findOverlappingFeatures(15, 25);
+ overlaps = fs.findFeatures(15, 25);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf));
/*
* both contact points in range
*/
- overlaps = fs.findOverlappingFeatures(5, 25);
+ overlaps = fs.findFeatures(5, 25);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf));
}
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
import jalview.datamodel.SequenceFeature;
fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
- List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+ List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
assertTrue(overlaps.isEmpty());
- overlaps = fs.findOverlappingFeatures(8, 10);
+ overlaps = fs.findFeatures(8, 10);
assertEquals(overlaps.size(), 2);
assertEquals(overlaps.get(0).getEnd(), 20);
assertEquals(overlaps.get(1).getEnd(), 20);
- overlaps = fs.findOverlappingFeatures(12, 16);
+ overlaps = fs.findFeatures(12, 16);
assertEquals(overlaps.size(), 3);
assertEquals(overlaps.get(0).getEnd(), 20);
assertEquals(overlaps.get(1).getEnd(), 20);
assertEquals(overlaps.get(2).getEnd(), 25);
- overlaps = fs.findOverlappingFeatures(33, 33);
+ overlaps = fs.findFeatures(33, 33);
assertEquals(overlaps.size(), 1);
assertEquals(overlaps.get(0).getEnd(), 35);
}
fs.addFeature(sf4);
SequenceFeature sf5 = addFeature(fs, 35, 36);
- List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+ List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
assertTrue(overlaps.isEmpty());
- overlaps = fs.findOverlappingFeatures(10, 15);
+ overlaps = fs.findFeatures(10, 15);
assertEquals(overlaps.size(), 2);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf2));
- overlaps = fs.findOverlappingFeatures(45, 60);
+ overlaps = fs.findFeatures(45, 60);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf1));
- overlaps = fs.findOverlappingFeatures(32, 38);
+ overlaps = fs.findFeatures(32, 38);
assertEquals(overlaps.size(), 3);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf2));
assertTrue(overlaps.contains(sf5));
- overlaps = fs.findOverlappingFeatures(15, 25);
+ overlaps = fs.findFeatures(15, 25);
assertEquals(overlaps.size(), 4);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf2));
SequenceFeature sf5 = addFeature(fs, 60, 100);
SequenceFeature sf6 = addFeature(fs, 70, 70);
- List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
+ List<SequenceFeature> overlaps = fs.findFeatures(200, 200);
assertTrue(overlaps.isEmpty());
- overlaps = fs.findOverlappingFeatures(1, 9);
+ overlaps = fs.findFeatures(1, 9);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf2));
- overlaps = fs.findOverlappingFeatures(5, 18);
+ overlaps = fs.findFeatures(5, 18);
assertEquals(overlaps.size(), 2);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf2));
- overlaps = fs.findOverlappingFeatures(30, 40);
+ overlaps = fs.findFeatures(30, 40);
assertEquals(overlaps.size(), 3);
assertTrue(overlaps.contains(sf1));
assertTrue(overlaps.contains(sf3));
assertTrue(overlaps.contains(sf4));
- overlaps = fs.findOverlappingFeatures(80, 90);
+ overlaps = fs.findFeatures(80, 90);
assertEquals(overlaps.size(), 2);
assertTrue(overlaps.contains(sf4));
assertTrue(overlaps.contains(sf5));
- overlaps = fs.findOverlappingFeatures(68, 70);
+ overlaps = fs.findFeatures(68, 70);
assertEquals(overlaps.size(), 3);
assertTrue(overlaps.contains(sf4));
assertTrue(overlaps.contains(sf5));
/*
* neither contact point in range
*/
- List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
+ List<SequenceFeature> overlaps = fs.findFeatures(1, 9);
assertTrue(overlaps.isEmpty());
/*
* neither contact point in range
*/
- overlaps = fs.findOverlappingFeatures(11, 19);
+ overlaps = fs.findFeatures(11, 19);
assertTrue(overlaps.isEmpty());
/*
* first contact point in range
*/
- overlaps = fs.findOverlappingFeatures(5, 15);
+ overlaps = fs.findFeatures(5, 15);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf));
/*
* second contact point in range
*/
- overlaps = fs.findOverlappingFeatures(15, 25);
+ overlaps = fs.findFeatures(15, 25);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf));
/*
* both contact points in range
*/
- overlaps = fs.findOverlappingFeatures(5, 25);
+ overlaps = fs.findFeatures(5, 25);
assertEquals(overlaps.size(), 1);
assertTrue(overlaps.contains(sf));
}
@Test(groups = "Functional")
+ public void testGetPositionalFeatures_withResultList()
+ {
+ FeatureStore store = newFeatureStore();
+ SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
+ Float.NaN, null);
+ store.addFeature(sf1);
+ // contact feature
+ SequenceFeature sf2 = new SequenceFeature("Disulphide bond", "desc", 18,
+ 45, Float.NaN, null);
+ store.addFeature(sf2);
+
+ List<SequenceFeature> features = new ArrayList<>();
+ store.getPositionalFeatures(features);
+ assertEquals(features.size(), 2);
+ assertTrue(features.contains(sf1));
+ assertTrue(features.contains(sf2));
+
+ /*
+ * no check for duplicates
+ */
+ features.remove(sf1);
+ assertEquals(features.size(), 1);
+ assertTrue(features.contains(sf2));
+ store.getPositionalFeatures(features);
+ assertEquals(features.size(), 3);
+ assertTrue(features.contains(sf1));
+ assertTrue(features.contains(sf2)); // two copies now
+ features.remove(sf2);
+ assertTrue(features.contains(sf2)); // one copy left
+ assertEquals(features.size(), 2);
+
+ /*
+ * null argument throws exception
+ */
+ try
+ {
+ store.getPositionalFeatures(null);
+ fail("expected exception");
+ } catch (NullPointerException e)
+ {
+ // expected
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testGetNonPositionalFeatures()
+ {
+ FeatureStore store = newFeatureStore();
+ List<SequenceFeature> features = store.getNonPositionalFeatures();
+ assertTrue(features.isEmpty());
+
+ SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
+ Float.NaN, null);
+ store.addFeature(sf1);
+ assertTrue(features.isEmpty());
+
+ SequenceFeature sf2 = new SequenceFeature("Metal", "desc", 0, 0,
+ Float.NaN, null);
+ store.addFeature(sf2);
+ features = store.getNonPositionalFeatures();
+ assertEquals(features.size(), 1);
+ assertTrue(features.contains(sf2));
+
+ /*
+ * with result list argument
+ */
+ features.clear();
+ store.getNonPositionalFeatures(features);
+ assertEquals(features.size(), 1);
+ assertTrue(features.contains(sf2));
+
+ /*
+ * no check for duplicates
+ */
+ store.getNonPositionalFeatures(features);
+ assertEquals(features.size(), 2);
+ assertTrue(features.contains(sf2)); // two copies
+ features.remove(sf2);
+ assertTrue(features.contains(sf2));
+
+ /*
+ * null argument throws exception
+ */
+ try
+ {
+ store.getNonPositionalFeatures(null);
+ fail("expected exception");
+ } catch (NullPointerException e)
+ {
+ // expected
+ }
+ }
+
+ @Test(groups = "Functional")
public void testGetPositionalFeatures()
{
FeatureStore store = newFeatureStore();
SequenceFeature sf2 = addFeature(fs, 150, 250);
List<SequenceFeature> overlaps = new ArrayList<>();
- List<SequenceFeature> result = fs.findOverlappingFeatures(200, 200,
+ List<SequenceFeature> result = fs.findFeatures(200, 200,
overlaps);
assertSame(result, overlaps);
assertEquals(result.size(), 1);
/*
* if no list supplied, method creates one
*/
- result = fs.findOverlappingFeatures(200, 200, null);
+ result = fs.findFeatures(200, 200, null);
assertEquals(result.size(), 1);
assertTrue(result.contains(sf2));
assertFalse(result.contains(sf1));