1 package jalview.datamodel.features;
3 import jalview.datamodel.SequenceFeature;
5 import java.util.ArrayList;
6 import java.util.Collections;
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
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>();
40 * Adds one sequence feature to the store, and returns true, unless the
41 * feature is already contained in the store, in which case this method
42 * returns false. Containment is determined by SequenceFeature.equals()
47 public boolean add(SequenceFeature sf)
49 String type = sf.getType();
51 if (featureStore.get(type) == null)
53 featureStore.put(type, new FeatureStore());
55 return featureStore.get(type).addFeature(sf);
59 * Returns a (possibly empty) list of features of the given type which overlap
60 * the (inclusive) sequence position range
67 public List<SequenceFeature> findFeatures(String type, int from,
70 FeatureStore features = featureStore.get(type);
73 return Collections.emptyList();
75 return features.findOverlappingFeatures(from, to);
79 * Answers a list of all positional features stored, in no particular
84 public List<SequenceFeature> getPositionalFeatures()
86 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
87 for (FeatureStore featureSet : featureStore.values())
89 result.addAll(featureSet.getPositionalFeatures());
95 * Answers a list of all features stored, in no particular guaranteed order
99 public List<SequenceFeature> getAllFeatures()
101 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
103 result.addAll(getPositionalFeatures());
105 result.addAll(getNonPositionalFeatures());
111 * Answers a list of all features stored of the specified type, in no
112 * particular guaranteed order
116 public List<SequenceFeature> getAllFeatures(String type)
118 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
120 result.addAll(getPositionalFeatures(type));
122 result.addAll(getNonPositionalFeatures(type));
128 * Answers a list of all non-positional features stored, in no particular
133 public List<SequenceFeature> getNonPositionalFeatures()
135 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
136 for (FeatureStore featureSet : featureStore.values())
138 result.addAll(featureSet.getNonPositionalFeatures());
144 * Answers a list of all contact features stored, in no particular guaranteed
149 public List<SequenceFeature> getContactFeatures()
151 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
152 for (FeatureStore featureSet : featureStore.values())
154 result.addAll(featureSet.getContactFeatures());
160 * Answers a list of all positional features of the given type, in no
161 * particular guaranteed order
165 public List<SequenceFeature> getPositionalFeatures(String type)
167 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
168 FeatureStore featureSet = featureStore.get(type);
169 if (featureSet != null)
171 result.addAll(featureSet.getPositionalFeatures());
177 * Answers a list of all contact features of the given type, in no particular
182 public List<SequenceFeature> getContactFeatures(String type)
184 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
185 FeatureStore featureSet = featureStore.get(type);
186 if (featureSet != null)
188 result.addAll(featureSet.getContactFeatures());
194 * Answers a list of all non-positional features of the given type, in no
195 * particular guaranteed order
199 public List<SequenceFeature> getNonPositionalFeatures(String type)
201 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
202 FeatureStore featureSet = featureStore.get(type);
203 if (featureSet != null)
205 result.addAll(featureSet.getNonPositionalFeatures());
211 * Deletes the given feature from the store, returning true if it was found
212 * (and deleted), else false. This method makes no assumption that the feature
213 * is in the 'expected' place in the store, in case it has been modified since
218 public boolean delete(SequenceFeature sf)
220 for (FeatureStore featureSet : featureStore.values())
222 if (featureSet.delete(sf))
231 * Answers true if this store contains at least one feature, else false
235 public boolean hasFeatures()
237 for (FeatureStore featureSet : featureStore.values())
239 if (!featureSet.isEmpty())
248 * Returns a set of the distinct feature groups present in the collection. The
249 * set may include null. The parameter determines whether the groups for
250 * positional or for non-positional features are returned.
252 * @param positionalFeatures
255 public Set<String> getFeatureGroups(boolean positionalFeatures)
257 Set<String> groups = new HashSet<String>();
258 for (FeatureStore featureSet : featureStore.values())
260 groups.addAll(featureSet.getFeatureGroups(positionalFeatures));
266 * Answers the set of distinct feature types for which there is at least one
267 * feature with one of the given feature group(s). The parameter determines
268 * whether the groups for positional or for non-positional features are
271 * @param positionalFeatures
275 public Set<String> getFeatureTypesForGroups(boolean positionalFeatures,
278 Set<String> result = new HashSet<String>();
279 for (Entry<String, FeatureStore> featureType : featureStore.entrySet())
281 Set<String> featureGroups = featureType.getValue().getFeatureGroups(
283 for (String group : groups)
285 if (featureGroups.contains(group))
288 * yes this feature type includes one of the query groups
290 result.add(featureType.getKey());