1 package jalview.datamodel.features;
3 import jalview.datamodel.SequenceFeature;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.Collections;
8 import java.util.HashMap;
9 import java.util.HashSet;
10 import java.util.List;
12 import java.util.Map.Entry;
16 * A class that stores sequence features in a way that supports efficient
17 * querying by type and location (overlap). Intended for (but not limited to)
18 * storage of features for one sequence.
23 public class SequenceFeatures implements SequenceFeaturesI
27 * map from feature type to structured store of features for that type
28 * null types are permitted (but not a good idea!)
30 private Map<String, FeatureStore> featureStore;
35 public SequenceFeatures()
37 featureStore = new HashMap<String, FeatureStore>();
41 * @see jalview.datamodel.features.SequenceFeaturesI#add(jalview.datamodel.SequenceFeature)
44 public boolean add(SequenceFeature sf)
46 String type = sf.getType();
48 if (featureStore.get(type) == null)
50 featureStore.put(type, new FeatureStore());
52 return featureStore.get(type).addFeature(sf);
56 * @see jalview.datamodel.features.SequenceFeaturesI#findFeatures(int, int, java.lang.String)
59 public List<SequenceFeature> findFeatures(int from, int to,
62 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
64 for (String featureType : varargToTypes(type))
66 FeatureStore features = featureStore.get(featureType);
69 result.addAll(features.findOverlappingFeatures(from, to));
77 * @see jalview.datamodel.features.SequenceFeaturesI#getAllFeatures(java.lang.String)
80 public List<SequenceFeature> getAllFeatures(String... type)
82 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
84 result.addAll(getPositionalFeatures(type));
86 result.addAll(getNonPositionalFeatures(type));
92 * @see jalview.datamodel.features.SequenceFeaturesI#getFeatureCount(boolean, java.lang.String)
95 public int getFeatureCount(boolean positional, String... type)
98 for (FeatureStore fs : featureStore.values())
100 result += fs.size(positional);
107 * @see jalview.datamodel.features.SequenceFeaturesI#getPositionalFeatures(java.lang.String)
110 public List<SequenceFeature> getPositionalFeatures(String... type)
112 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
114 for (String featureType : varargToTypes(type))
116 FeatureStore featureSet = featureStore.get(featureType);
117 if (featureSet != null)
119 result.addAll(featureSet.getPositionalFeatures());
126 * A convenience method that converts a vararg for feature types to an
127 * Iterable, replacing the value with the stored feature types if it is null
133 protected Iterable<String> varargToTypes(String... type)
135 return type == null || type.length == 0 ? featureStore
136 .keySet() : Arrays.asList(type);
140 * @see jalview.datamodel.features.SequenceFeaturesI#getContactFeatures(java.lang.String)
143 public List<SequenceFeature> getContactFeatures(String... type)
145 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
147 for (String featureType : varargToTypes(type))
149 FeatureStore featureSet = featureStore.get(featureType);
150 if (featureSet != null)
152 result.addAll(featureSet.getContactFeatures());
159 * @see jalview.datamodel.features.SequenceFeaturesI#getNonPositionalFeatures(java.lang.String)
162 public List<SequenceFeature> getNonPositionalFeatures(String... type)
164 List<SequenceFeature> result = new ArrayList<SequenceFeature>();
166 for (String featureType : varargToTypes(type))
168 FeatureStore featureSet = featureStore.get(featureType);
169 if (featureSet != null)
171 result.addAll(featureSet.getNonPositionalFeatures());
178 * @see jalview.datamodel.features.SequenceFeaturesI#delete(jalview.datamodel.SequenceFeature)
181 public boolean delete(SequenceFeature sf)
183 for (FeatureStore featureSet : featureStore.values())
185 if (featureSet.delete(sf))
194 * @see jalview.datamodel.features.SequenceFeaturesI#hasFeatures()
197 public boolean hasFeatures()
199 for (FeatureStore featureSet : featureStore.values())
201 if (!featureSet.isEmpty())
210 * @see jalview.datamodel.features.SequenceFeaturesI#getFeatureGroups(boolean, java.lang.String)
213 public Set<String> getFeatureGroups(boolean positionalFeatures,
216 Set<String> groups = new HashSet<String>();
218 Iterable<String> types = varargToTypes(type);
220 for (String featureType : types)
222 FeatureStore featureSet = featureStore.get(featureType);
223 if (featureSet != null)
225 groups.addAll(featureSet.getFeatureGroups(positionalFeatures));
233 * @see jalview.datamodel.features.SequenceFeaturesI#getFeatureTypesForGroups(boolean, java.lang.String)
236 public Set<String> getFeatureTypesForGroups(boolean positionalFeatures,
239 Set<String> result = new HashSet<String>();
241 for (Entry<String, FeatureStore> featureType : featureStore.entrySet())
243 Set<String> featureGroups = featureType.getValue().getFeatureGroups(
245 for (String group : groups)
247 if (featureGroups.contains(group))
250 * yes this feature type includes one of the query groups
252 result.add(featureType.getKey());
262 * @see jalview.datamodel.features.SequenceFeaturesI#getFeatureTypes()
265 public Set<String> getFeatureTypes()
267 return Collections.unmodifiableSet(featureStore.keySet());