JAL-2480 SequenceFeaturesI encapsulates features api
[jalview.git] / src / jalview / datamodel / features / FeatureStore.java
index 721ac18..d6a94e2 100644 (file)
@@ -121,6 +121,12 @@ public class FeatureStore
    */
   Set<String> nonPositionalFeatureGroups;
 
+  /*
+   * the total length of all positional features; contact features count 1 to
+   * the total and 1 to size(), consistent with an average 'feature length' of 1
+   */
+  int totalExtent;
+
   /**
    * Constructor
    */
@@ -176,6 +182,18 @@ public class FeatureStore
       }
     }
 
+    /*
+     * record the total extent of positional features, to make
+     * getAverageFeatureLength possible; we count the length of a 
+     * contact feature as 1
+     */
+    if (added && !feature.isNonPositional())
+    {
+      int featureLength = feature.isContactFeature() ? 1 : 1
+              + feature.getEnd() - feature.getBegin();
+      totalExtent += featureLength;
+    }
+
     return added;
   }
 
@@ -622,6 +640,7 @@ public class FeatureStore
     if (removed)
     {
       rebuildFeatureGroups(sf.getFeatureGroup(), removedNonPositional);
+      // TODO and recalculate totalExtent (feature may have changed length!)
     }
 
     return removed;
@@ -756,4 +775,46 @@ public class FeatureStore
 
     return matched;
   }
+
+  /**
+   * Answers the number of positional (or non-positional) features stored
+   * 
+   * @param positional
+   * @return
+   */
+  public int size(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 average length of positional features (or zero if there are
+   * none). Contact features contribute a value of 1 to the average.
+   * 
+   * @return
+   */
+  public float getAverageFeatureLength()
+  {
+    int d = size(true);
+    return d == 0 ? 0f : (float) totalExtent / d;
+  }
 }