- }
-
- /**
- * Scans all positional features to check whether the given feature group is
- * found, and returns true if found, else false
- *
- * @param featureGroup
- * @return
- */
- protected boolean findFeatureGroup(String featureGroup)
- {
- for (SequenceFeature sf : getPositionalFeatures())
- {
- String group = sf.getFeatureGroup();
- if (group == featureGroup
- || (group != null && group.equals(featureGroup)))
- {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Answers true if this store has no features, else false
- *
- * @return
- */
- public boolean isEmpty()
- {
- boolean hasFeatures = !nonNestedFeatures.isEmpty()
- || (contactFeatureStarts != null && !contactFeatureStarts
- .isEmpty())
- || (nonPositionalFeatures != null && !nonPositionalFeatures
- .isEmpty())
- || (nestedFeatures != null && nestedFeatures.size() > 0);
-
- return !hasFeatures;
- }
-
- /**
- * Answers the set of distinct feature groups stored, possibly including null,
- * as an unmodifiable view of the set. The parameter determines whether the
- * groups for positional or for non-positional features are returned.
- *
- * @param positionalFeatures
- * @return
- */
- public Set<String> getFeatureGroups(boolean positionalFeatures)
- {
- if (positionalFeatures)
- {
- return Collections.unmodifiableSet(positionalFeatureGroups);
- }
- else
- {
- return nonPositionalFeatureGroups == null ? Collections
- .<String> emptySet() : Collections
- .unmodifiableSet(nonPositionalFeatureGroups);
- }
- }
-
- /**
- * Performs a binary search of the (sorted) list to find the index of the
- * first entry which returns true for the given comparator function. Returns
- * the length of the list if there is no such entry.
- *
- * @param features
- * @param sc
- * @return
- */
- protected static int binarySearch(List<SequenceFeature> features,
- SearchCriterion sc)
- {
- int start = 0;
- int end = features.size() - 1;
- int matched = features.size();
-
- while (start <= end)
- {
- int mid = (start + end) / 2;
- SequenceFeature entry = features.get(mid);
- boolean compare = sc.compare(entry);
- if (compare)
- {
- matched = mid;
- end = mid - 1;
- }
- else
- {
- start = mid + 1;
- }
- }
-
- return matched;
- }
-
- /**
- * Answers the number of positional (or non-positional) features stored.
- * Contact features count as 1.
- *
- * @param positional
- * @return
- */
- public int getFeatureCount(boolean positional)
- {
- if (!positional)
- {
- return nonPositionalFeatures == null ? 0 : nonPositionalFeatures
- .size();
- }
-
- int size = nonNestedFeatures.size();
-
- if (contactFeatureStarts != null)
- {
- // note a contact feature (start/end) counts as one
- size += contactFeatureStarts.size();
- }
-
- if (nestedFeatures != null)
- {
- size += nestedFeatures.size();
- }
-
- return size;
- }
-
- /**
- * Answers the total length of positional features (or zero if there are
- * none). Contact features contribute a value of 1 to the total.
- *
- * @return
- */
- public int getTotalFeatureLength()
- {
- return totalExtent;
- }
-
- /**
- * Answers the minimum score held for positional or non-positional features.
- * This may be Float.NaN if there are no features, are none has a non-NaN
- * score.
- *
- * @param positional
- * @return
- */
- public float getMinimumScore(boolean positional)
- {
- return positional ? positionalMinScore : nonPositionalMinScore;
- }
-
- /**
- * Answers the maximum score held for positional or non-positional features.
- * This may be Float.NaN if there are no features, are none has a non-NaN
- * score.
- *
- * @param positional
- * @return
- */
- public float getMaximumScore(boolean positional)
- {
- return positional ? positionalMaxScore : nonPositionalMaxScore;
- }
-
- /**
- * Answers a list of all either positional or non-positional features whose
- * feature group matches the given group (which may be null)
- *
- * @param positional
- * @param group
- * @return
- */
- public List<SequenceFeature> getFeaturesForGroup(boolean positional,
- String group)
- {
- List<SequenceFeature> result = new ArrayList<SequenceFeature>();
-
- /*
- * if we know features don't include the target group, no need
- * to inspect them for matches
- */
- if (positional && !positionalFeatureGroups.contains(group)
- || !positional && !nonPositionalFeatureGroups.contains(group))
- {
- return result;
- }
-
- List<SequenceFeature> sfs = positional ? getPositionalFeatures()
- : getNonPositionalFeatures();