X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2Ffeatures%2FSequenceFeatures.java;h=fcf1b536409a3579a74c2fe1556d6c0b074d5dac;hb=f5cadfa2a55d78a08268a0df9a7c3f64d1c43e8a;hp=73ddac788eb0c62c67d27661bc0301fb6c3de7fc;hpb=87a85be7fc7678455c298287349b03fdd12fd3ad;p=jalview.git diff --git a/src/jalview/datamodel/features/SequenceFeatures.java b/src/jalview/datamodel/features/SequenceFeatures.java index 73ddac7..fcf1b53 100644 --- a/src/jalview/datamodel/features/SequenceFeatures.java +++ b/src/jalview/datamodel/features/SequenceFeatures.java @@ -1,5 +1,26 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ package jalview.datamodel.features; +import jalview.datamodel.ContiguousI; import jalview.datamodel.SequenceFeature; import jalview.io.gff.SequenceOntologyFactory; import jalview.io.gff.SequenceOntologyI; @@ -62,7 +83,7 @@ public class SequenceFeatures implements SequenceFeaturesI { /* * use a TreeMap so that features are returned in alphabetical order of type - * wrap as a synchronized map for add and delete operations + * ? wrap as a synchronized map for add and delete operations */ // featureStore = Collections // .synchronizedSortedMap(new TreeMap()); @@ -70,6 +91,21 @@ public class SequenceFeatures implements SequenceFeaturesI } /** + * Constructor given a list of features + */ + public SequenceFeatures(List features) + { + this(); + if (features != null) + { + for (SequenceFeature feature : features) + { + add(feature); + } + } + } + + /** * {@inheritDoc} */ @Override @@ -96,15 +132,11 @@ public class SequenceFeatures implements SequenceFeaturesI public List findFeatures(int from, int to, String... type) { - List result = new ArrayList(); + List result = new ArrayList<>(); - for (String featureType : varargToTypes(type)) + for (FeatureStore featureSet : varargToTypes(type)) { - FeatureStore features = featureStore.get(featureType); - if (features != null) - { - result.addAll(features.findOverlappingFeatures(from, to)); - } + result.addAll(featureSet.findOverlappingFeatures(from, to)); } return result; @@ -116,11 +148,11 @@ public class SequenceFeatures implements SequenceFeaturesI @Override public List getAllFeatures(String... type) { - List result = new ArrayList(); + List result = new ArrayList<>(); result.addAll(getPositionalFeatures(type)); - result.addAll(getNonPositionalFeatures(type)); + result.addAll(getNonPositionalFeatures()); return result; } @@ -133,10 +165,18 @@ public class SequenceFeatures implements SequenceFeaturesI { if (ontologyTerm == null || ontologyTerm.length == 0) { - return new ArrayList(); + return new ArrayList<>(); } Set featureTypes = getFeatureTypes(ontologyTerm); + if (featureTypes.isEmpty()) + { + /* + * no features of the specified type or any sub-type + */ + return new ArrayList<>(); + } + return getAllFeatures(featureTypes.toArray(new String[featureTypes .size()])); } @@ -149,13 +189,9 @@ public class SequenceFeatures implements SequenceFeaturesI { int result = 0; - for (String featureType : varargToTypes(type)) + for (FeatureStore featureSet : varargToTypes(type)) { - FeatureStore featureSet = featureStore.get(featureType); - if (featureSet != null) - { - result += featureSet.getFeatureCount(positional); - } + result += featureSet.getFeatureCount(positional); } return result; } @@ -168,16 +204,11 @@ public class SequenceFeatures implements SequenceFeaturesI { int result = 0; - for (String featureType : varargToTypes(type)) + for (FeatureStore featureSet : varargToTypes(type)) { - FeatureStore featureSet = featureStore.get(featureType); - if (featureSet != null) - { - result += featureSet.getTotalFeatureLength(); - } + result += featureSet.getTotalFeatureLength(); } return result; - } /** @@ -186,43 +217,41 @@ public class SequenceFeatures implements SequenceFeaturesI @Override public List getPositionalFeatures(String... type) { - List result = new ArrayList(); + List result = new ArrayList<>(); - for (String featureType : varargToTypes(type)) + for (FeatureStore featureSet : varargToTypes(type)) { - FeatureStore featureSet = featureStore.get(featureType); - if (featureSet != null) - { - result.addAll(featureSet.getPositionalFeatures()); - } + result.addAll(featureSet.getPositionalFeatures()); } return result; } /** * A convenience method that converts a vararg for feature types to an - * Iterable, replacing the value with the stored feature types if it is null - * or empty + * Iterable over matched feature sets in key order * * @param type * @return */ - protected Iterable varargToTypes(String... type) + protected Iterable varargToTypes(String... type) { if (type == null || type.length == 0) { /* - * no vararg parameter supplied + * no vararg parameter supplied - return all */ - return featureStore.keySet(); + return featureStore.values(); } - /* - * else make a copy of the list, and remove any null value just in case, - * as it would cause errors looking up the features Map - */ - List types = new ArrayList(Arrays.asList(type)); - types.remove(null); + List types = new ArrayList<>(); + List args = Arrays.asList(type); + for (Entry featureType : featureStore.entrySet()) + { + if (args.contains(featureType.getKey())) + { + types.add(featureType.getValue()); + } + } return types; } @@ -232,15 +261,11 @@ public class SequenceFeatures implements SequenceFeaturesI @Override public List getContactFeatures(String... type) { - List result = new ArrayList(); + List result = new ArrayList<>(); - for (String featureType : varargToTypes(type)) + for (FeatureStore featureSet : varargToTypes(type)) { - FeatureStore featureSet = featureStore.get(featureType); - if (featureSet != null) - { - result.addAll(featureSet.getContactFeatures()); - } + result.addAll(featureSet.getContactFeatures()); } return result; } @@ -251,15 +276,11 @@ public class SequenceFeatures implements SequenceFeaturesI @Override public List getNonPositionalFeatures(String... type) { - List result = new ArrayList(); + List result = new ArrayList<>(); - for (String featureType : varargToTypes(type)) + for (FeatureStore featureSet : varargToTypes(type)) { - FeatureStore featureSet = featureStore.get(featureType); - if (featureSet != null) - { - result.addAll(featureSet.getNonPositionalFeatures()); - } + result.addAll(featureSet.getNonPositionalFeatures()); } return result; } @@ -303,17 +324,11 @@ public class SequenceFeatures implements SequenceFeaturesI public Set getFeatureGroups(boolean positionalFeatures, String... type) { - Set groups = new HashSet(); - - Iterable types = varargToTypes(type); + Set groups = new HashSet<>(); - for (String featureType : types) + for (FeatureStore featureSet : varargToTypes(type)) { - FeatureStore featureSet = featureStore.get(featureType); - if (featureSet != null) - { - groups.addAll(featureSet.getFeatureGroups(positionalFeatures)); - } + groups.addAll(featureSet.getFeatureGroups(positionalFeatures)); } return groups; @@ -326,7 +341,7 @@ public class SequenceFeatures implements SequenceFeaturesI public Set getFeatureTypesForGroups(boolean positionalFeatures, String... groups) { - Set result = new HashSet(); + Set result = new HashSet<>(); for (Entry featureType : featureStore.entrySet()) { @@ -354,7 +369,7 @@ public class SequenceFeatures implements SequenceFeaturesI @Override public Set getFeatureTypes(String... soTerm) { - Set types = new HashSet(); + Set types = new HashSet<>(); for (Entry entry : featureStore.entrySet()) { String type = entry.getKey(); @@ -425,4 +440,44 @@ public class SequenceFeatures implements SequenceFeaturesI Collections.sort(features, forwardStrand ? FORWARD_STRAND : REVERSE_STRAND); } + + /** + * {@inheritDoc} This method is 'semi-optimised': it only inspects features + * for types that include the specified group, but has to inspect every + * feature of those types for matching feature group. This is efficient unless + * a sequence has features that share the same type but are in different + * groups - an unlikely case. + *

+ * For example, if RESNUM feature is created with group = PDBID, then features + * would only be retrieved for those sequences associated with the target + * PDBID (group). + */ + @Override + public List getFeaturesForGroup(boolean positional, + String group, String... type) + { + List result = new ArrayList<>(); + for (FeatureStore featureSet : varargToTypes(type)) + { + if (featureSet.getFeatureGroups(positional).contains(group)) + { + result.addAll(featureSet.getFeaturesForGroup(positional, group)); + } + } + return result; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean shiftFeatures(int shift) + { + boolean modified = false; + for (FeatureStore fs : featureStore.values()) + { + modified |= fs.shiftFeatures(shift); + } + return modified; + } } \ No newline at end of file