1 package jalview.datamodel.features;
3 import jalview.datamodel.SequenceFeature;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.HashMap;
8 import java.util.HashSet;
11 import java.util.Map.Entry;
15 * A class that stores sequence features in a way that supports efficient
16 * querying by type and location (overlap). Intended for (but not limited to)
17 * storage of features for one sequence.
22 public class SequenceFeatures implements SequenceFeaturesI
26 * map from feature type to structured store of features for that type
27 * null types are permitted (but not a good idea!)
29 private Map<String, FeatureStore> featureStore;
34 public SequenceFeatures()
36 featureStore = new HashMap<String, FeatureStore>();
43 public boolean add(SequenceFeature sf)
45 String type = sf.getType();
47 if (featureStore.get(type) == null)
49 featureStore.put(type, new FeatureStore());
51 return featureStore.get(type).addFeature(sf);
58 public List<SequenceFeature> findFeatures(int from, int to,
61 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
63 for (String featureType : varargToTypes(type))
65 FeatureStore features = featureStore.get(featureType);
68 result.addAll(features.findOverlappingFeatures(from, to));
79 public List<SequenceFeature> getAllFeatures(String... type)
81 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
83 result.addAll(getPositionalFeatures(type));
85 result.addAll(getNonPositionalFeatures(type));
94 public int getFeatureCount(boolean positional, String... type)
98 for (String featureType : varargToTypes(type))
100 FeatureStore featureSet = featureStore.get(featureType);
101 if (featureSet != null)
103 result += featureSet.getFeatureCount(positional);
113 public int getTotalFeatureLength(String... type)
117 for (String featureType : varargToTypes(type))
119 FeatureStore featureSet = featureStore.get(featureType);
120 if (featureSet != null)
122 result += featureSet.getTotalFeatureLength();
133 public List<SequenceFeature> getPositionalFeatures(String... type)
135 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
137 for (String featureType : varargToTypes(type))
139 FeatureStore featureSet = featureStore.get(featureType);
140 if (featureSet != null)
142 result.addAll(featureSet.getPositionalFeatures());
149 * A convenience method that converts a vararg for feature types to an
150 * Iterable, replacing the value with the stored feature types if it is null
156 protected Iterable<String> varargToTypes(String... type)
158 return type == null || type.length == 0 ? featureStore
159 .keySet() : Arrays.asList(type);
166 public List<SequenceFeature> getContactFeatures(String... type)
168 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
170 for (String featureType : varargToTypes(type))
172 FeatureStore featureSet = featureStore.get(featureType);
173 if (featureSet != null)
175 result.addAll(featureSet.getContactFeatures());
185 public List<SequenceFeature> getNonPositionalFeatures(String... type)
187 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
189 for (String featureType : varargToTypes(type))
191 FeatureStore featureSet = featureStore.get(featureType);
192 if (featureSet != null)
194 result.addAll(featureSet.getNonPositionalFeatures());
204 public boolean delete(SequenceFeature sf)
206 for (FeatureStore featureSet : featureStore.values())
208 if (featureSet.delete(sf))
220 public boolean hasFeatures()
222 for (FeatureStore featureSet : featureStore.values())
224 if (!featureSet.isEmpty())
236 public Set<String> getFeatureGroups(boolean positionalFeatures,
239 Set<String> groups = new HashSet<String>();
241 Iterable<String> types = varargToTypes(type);
243 for (String featureType : types)
245 FeatureStore featureSet = featureStore.get(featureType);
246 if (featureSet != null)
248 groups.addAll(featureSet.getFeatureGroups(positionalFeatures));
259 public Set<String> getFeatureTypesForGroups(boolean positionalFeatures,
262 Set<String> result = new HashSet<String>();
264 for (Entry<String, FeatureStore> featureType : featureStore.entrySet())
266 Set<String> featureGroups = featureType.getValue().getFeatureGroups(
268 for (String group : groups)
270 if (featureGroups.contains(group))
273 * yes this feature type includes one of the query groups
275 result.add(featureType.getKey());
288 public Set<String> getFeatureTypes()
290 Set<String> types = new HashSet<String>();
291 for (Entry<String, FeatureStore> entry : featureStore.entrySet())
293 if (!entry.getValue().isEmpty())
295 types.add(entry.getKey());
302 * Answers the minimum score held for positional or non-positional features
303 * for the specified type. This may be Float.NaN if there are no features, or
304 * none has a non-NaN score.
310 public float getMinimumScore(String type, boolean positional)
312 return featureStore.containsKey(type) ? featureStore.get(type)
313 .getMinimumScore(positional) : Float.NaN;
317 * Answers the maximum score held for positional or non-positional features
318 * for the specified type. This may be Float.NaN if there are no features, or
319 * none has a non-NaN score.
325 public float getMaximumScore(String type, boolean positional)
327 return featureStore.containsKey(type) ? featureStore.get(type)
328 .getMaximumScore(positional) : Float.NaN;