X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2Ffeatures%2FSequenceFeatures.java;h=cb2b8cc1f13d483ec592adbca3b3e045aefe3d60;hb=80634498762666e6acc92368716bf1a4d4f42f7b;hp=bd102f6d39d01c561d41c08c4435ea873e2448f5;hpb=81d2ea57ab71c0806a036833f73711bc4ad5c76d;p=jalview.git diff --git a/src/jalview/datamodel/features/SequenceFeatures.java b/src/jalview/datamodel/features/SequenceFeatures.java index bd102f6..cb2b8cc 100644 --- a/src/jalview/datamodel/features/SequenceFeatures.java +++ b/src/jalview/datamodel/features/SequenceFeatures.java @@ -23,11 +23,10 @@ package jalview.datamodel.features; import jalview.datamodel.SequenceFeature; import jalview.io.gff.SequenceOntologyFactory; import jalview.io.gff.SequenceOntologyI; +import jalview.util.Platform; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -47,35 +46,38 @@ import intervalstore.api.IntervalI; */ public class SequenceFeatures implements SequenceFeaturesI { + + /* + * map from feature type to structured store of features for that type + * null types are permitted (but not a good idea!) + */ + private Map featureStore; + /** - * a comparator for sorting features by start position ascending + * original NCList-based IntervalStore */ - private static Comparator FORWARD_STRAND = new Comparator() - { - @Override - public int compare(IntervalI o1, IntervalI o2) - { - return Integer.compare(o1.getBegin(), o2.getBegin()); - } - }; + private final static int INTERVAL_STORE_NCLIST = 0; /** - * a comparator for sorting features by end position descending + * linked-list deferred-sort IntervalStore - experimental only; unused */ - private static Comparator REVERSE_STRAND = new Comparator() - { - @Override - public int compare(IntervalI o1, IntervalI o2) - { - return Integer.compare(o2.getEnd(), o1.getEnd()); - } - }; + private final static int INTERVAL_STORE_LINKED_LIST_NO_PRESORT = 1; - /* - * map from feature type to structured store of features for that type - * null types are permitted (but not a good idea!) + /** + * linked-list IntervalStore option for JavaScript + */ + private final static int INTERVAL_STORE_LINKED_LIST = -1; + + /** + * mode for Java or JavaScript; can be set differently for testing, but + * default is LINKED_LIST for JalviewJS and NCLIST for Java */ - private Map featureStore; + private final int INTERVAL_STORE_MODE = ( + // true || // + Platform.isJS() ? // + INTERVAL_STORE_LINKED_LIST // + : INTERVAL_STORE_NCLIST// + ); /** * Constructor @@ -87,7 +89,7 @@ public class SequenceFeatures implements SequenceFeaturesI * ? wrap as a synchronized map for add and delete operations */ // featureStore = Collections - // .synchronizedSortedMap(new TreeMap()); + // .synchronizedSortedMap(new TreeMap()); featureStore = new TreeMap<>(); } @@ -121,11 +123,25 @@ public class SequenceFeatures implements SequenceFeaturesI if (featureStore.get(type) == null) { - featureStore.put(type, new FeatureStore()); + featureStore.put(type, newFeatureStore()); } return featureStore.get(type).addFeature(sf); } + private FeatureStoreI newFeatureStore() + { + switch (INTERVAL_STORE_MODE) + { + default: + case INTERVAL_STORE_NCLIST: + return new FeatureStoreImpl(true); + case INTERVAL_STORE_LINKED_LIST_NO_PRESORT: + return new FeatureStoreImpl(false); + case INTERVAL_STORE_LINKED_LIST: + return new FeatureStoreJS(); + } + } + /** * {@inheritDoc} */ @@ -134,12 +150,14 @@ public class SequenceFeatures implements SequenceFeaturesI String... type) { List result = new ArrayList<>(); - - for (FeatureStore featureSet : varargToTypes(type)) + for (FeatureStoreI featureSet : varargToTypes(type)) { - result.addAll(featureSet.findOverlappingFeatures(from, to)); + // System.err.println("SF findFeature " + System.currentTimeMillis() + // + " " + from + " " + to + " " + // + featureSet.getPositionalFeatures().get(0).type); + // + result.addAll(featureSet.findOverlappingFeatures(from, to, null)); } - return result; } @@ -178,8 +196,8 @@ public class SequenceFeatures implements SequenceFeaturesI return new ArrayList<>(); } - return getAllFeatures(featureTypes.toArray(new String[featureTypes - .size()])); + return getAllFeatures( + featureTypes.toArray(new String[featureTypes.size()])); } /** @@ -190,7 +208,7 @@ public class SequenceFeatures implements SequenceFeaturesI { int result = 0; - for (FeatureStore featureSet : varargToTypes(type)) + for (FeatureStoreI featureSet : varargToTypes(type)) { result += featureSet.getFeatureCount(positional); } @@ -205,7 +223,7 @@ public class SequenceFeatures implements SequenceFeaturesI { int result = 0; - for (FeatureStore featureSet : varargToTypes(type)) + for (FeatureStoreI featureSet : varargToTypes(type)) { result += featureSet.getTotalFeatureLength(); } @@ -220,9 +238,9 @@ public class SequenceFeatures implements SequenceFeaturesI { List result = new ArrayList<>(); - for (FeatureStore featureSet : varargToTypes(type)) + for (FeatureStoreI featureSet : varargToTypes(type)) { - result.addAll(featureSet.getPositionalFeatures()); + featureSet.getPositionalFeatures(result); } return result; } @@ -234,7 +252,7 @@ public class SequenceFeatures implements SequenceFeaturesI * @param type * @return */ - protected Iterable varargToTypes(String... type) + protected Iterable varargToTypes(String... type) { if (type == null || type.length == 0) { @@ -244,9 +262,9 @@ public class SequenceFeatures implements SequenceFeaturesI return featureStore.values(); } - List types = new ArrayList<>(); + List types = new ArrayList<>(); List args = Arrays.asList(type); - for (Entry featureType : featureStore.entrySet()) + for (Entry featureType : featureStore.entrySet()) { if (args.contains(featureType.getKey())) { @@ -264,9 +282,9 @@ public class SequenceFeatures implements SequenceFeaturesI { List result = new ArrayList<>(); - for (FeatureStore featureSet : varargToTypes(type)) + for (FeatureStoreI featureSet : varargToTypes(type)) { - result.addAll(featureSet.getContactFeatures()); + featureSet.getContactFeatures(result); } return result; } @@ -279,9 +297,9 @@ public class SequenceFeatures implements SequenceFeaturesI { List result = new ArrayList<>(); - for (FeatureStore featureSet : varargToTypes(type)) + for (FeatureStoreI featureSet : varargToTypes(type)) { - result.addAll(featureSet.getNonPositionalFeatures()); + featureSet.getNonPositionalFeatures(result); } return result; } @@ -292,7 +310,7 @@ public class SequenceFeatures implements SequenceFeaturesI @Override public boolean delete(SequenceFeature sf) { - for (FeatureStore featureSet : featureStore.values()) + for (FeatureStoreI featureSet : featureStore.values()) { if (featureSet.delete(sf)) { @@ -308,7 +326,7 @@ public class SequenceFeatures implements SequenceFeaturesI @Override public boolean hasFeatures() { - for (FeatureStore featureSet : featureStore.values()) + for (FeatureStoreI featureSet : featureStore.values()) { if (!featureSet.isEmpty()) { @@ -327,7 +345,7 @@ public class SequenceFeatures implements SequenceFeaturesI { Set groups = new HashSet<>(); - for (FeatureStore featureSet : varargToTypes(type)) + for (FeatureStoreI featureSet : varargToTypes(type)) { groups.addAll(featureSet.getFeatureGroups(positionalFeatures)); } @@ -344,10 +362,10 @@ public class SequenceFeatures implements SequenceFeaturesI { Set result = new HashSet<>(); - for (Entry featureType : featureStore.entrySet()) + for (Entry featureType : featureStore.entrySet()) { - Set featureGroups = featureType.getValue().getFeatureGroups( - positionalFeatures); + Set featureGroups = featureType.getValue() + .getFeatureGroups(positionalFeatures); for (String group : groups) { if (featureGroups.contains(group)) @@ -371,7 +389,7 @@ public class SequenceFeatures implements SequenceFeaturesI public Set getFeatureTypes(String... soTerm) { Set types = new HashSet<>(); - for (Entry entry : featureStore.entrySet()) + for (Entry entry : featureStore.entrySet()) { String type = entry.getKey(); if (!entry.getValue().isEmpty() && isOntologyTerm(type, soTerm)) @@ -398,7 +416,7 @@ public class SequenceFeatures implements SequenceFeaturesI { return true; } - SequenceOntologyI so = SequenceOntologyFactory.getInstance(); + SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology(); for (String term : soTerm) { if (type.equals(term) || so.isA(type, term)) @@ -415,8 +433,9 @@ public class SequenceFeatures implements SequenceFeaturesI @Override public float getMinimumScore(String type, boolean positional) { - return featureStore.containsKey(type) ? featureStore.get(type) - .getMinimumScore(positional) : Float.NaN; + return featureStore.containsKey(type) + ? featureStore.get(type).getMinimumScore(positional) + : Float.NaN; } /** @@ -425,8 +444,9 @@ public class SequenceFeatures implements SequenceFeaturesI @Override public float getMaximumScore(String type, boolean positional) { - return featureStore.containsKey(type) ? featureStore.get(type) - .getMaximumScore(positional) : Float.NaN; + return featureStore.containsKey(type) + ? featureStore.get(type).getMaximumScore(positional) + : Float.NaN; } /** @@ -436,11 +456,10 @@ public class SequenceFeatures implements SequenceFeaturesI * @param features * @param forwardStrand */ - public static void sortFeatures(List features, + public static void sortFeatures(List features, final boolean forwardStrand) { - Collections.sort(features, forwardStrand ? FORWARD_STRAND - : REVERSE_STRAND); + IntervalI.sortIntervals(features, forwardStrand); } /** @@ -459,7 +478,7 @@ public class SequenceFeatures implements SequenceFeaturesI String group, String... type) { List result = new ArrayList<>(); - for (FeatureStore featureSet : varargToTypes(type)) + for (FeatureStoreI featureSet : varargToTypes(type)) { if (featureSet.getFeatureGroups(positional).contains(group)) { @@ -473,13 +492,81 @@ public class SequenceFeatures implements SequenceFeaturesI * {@inheritDoc} */ @Override - public boolean shiftFeatures(int shift) + public boolean shiftFeatures(int fromPosition, int shiftBy) { boolean modified = false; - for (FeatureStore fs : featureStore.values()) + for (FeatureStoreI fs : featureStore.values()) { - modified |= fs.shiftFeatures(shift); + modified |= fs.shiftFeatures(fromPosition, shiftBy); } return modified; } -} \ No newline at end of file + + /** + * {@inheritDoc} + */ + @Override + public void deleteAll() + { + featureStore.clear(); + } + + /** + * Simplified find for features associated with a given position. + * + * JavaScript set to not use IntervalI, but easily testable by setting false + * to true in javadoc + * + * FeatureRenderer has checked already that featureStore does contain type. + * + * @author Bob Hanson 2019.07.30 + */ + @Override + public List findFeatures(int pos, String type, + List list) + { + FeatureStoreI fs = featureStore.get(type); + return fs.findOverlappingFeatures(pos, pos, list); + } + + // Chrome; developer console closed + + // BH 2019.08.01 useIntervalStore true, redraw false: + // Platform: timer mark 13.848 0.367 overviewrender 16000 pixels row:14 + // Platform: timer mark 15.391 0.39 overviewrender 16000 pixels row:14 + // Platform: timer mark 16.498 0.39 overviewrender 16000 pixels row:14 + // Platform: timer mark 17.596 0.401 overviewrender 16000 pixels row:14 + // Platform: timer mark 18.738 0.363 overviewrender 16000 pixels row:14 + // Platform: timer mark 19.659 0.358 overviewrender 16000 pixels row:14 + // Platform: timer mark 20.737 0.359 overviewrender 16000 pixels row:14 + // Platform: timer mark 21.797 0.391 overviewrender 16000 pixels row:14 + // Platform: timer mark 22.851 0.361 overviewrender 16000 pixels row:14 + // Platform: timer mark 24.019 0.395 overviewrender 16000 pixels row:14 + + // BH 2019.08.01 useIntervalStore false, redraw false: + // Platform: timer mark 19.011 0.181 overviewrender 16000 pixels row:14 + // Platform: timer mark 20.311 0.183 overviewrender 16000 pixels row:14 + // Platform: timer mark 21.368 0.175 overviewrender 16000 pixels row:14 + // Platform: timer mark 22.347 0.178 overviewrender 16000 pixels row:14 + // Platform: timer mark 23.605 0.216 overviewrender 16000 pixels row:14 + // Platform: timer mark 24.836 0.191 overviewrender 16000 pixels row:14 + // Platform: timer mark 26.016 0.181 overviewrender 16000 pixels row:14 + // Platform: timer mark 27.278 0.178 overviewrender 16000 pixels row:14 + // Platform: timer mark 28.158 0.181 overviewrender 16000 pixels row:14 + // Platform: timer mark 29.227 0.196 overviewrender 16000 pixels row:14 + // Platform: timer mark 30.1 0.171 overviewrender 16000 pixels row:14 + // Platform: timer mark 31.684 0.196 overviewrender 16000 pixels row:14 + // Platform: timer mark 32.779 0.18 overviewrender 16000 pixels row:14 + // Platform: timer mark 52.355 0.185 overviewrender 16000 pixels row:14 + // Platform: timer mark 53.829 0.186 overviewrender 16000 pixels row:14 + + /** + * @author Bob Hanson 2019.08.01 + */ + @Override + public boolean hasFeatures(String type) + { + return featureStore.containsKey(type); + } + +}