X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2Ffeatures%2FSequenceFeatures.java;h=2101a2f50d8eba34ea94ca6c37a9681bbbc615ce;hb=14bfc6fb57f123b815f08dbf5b35544abd33b3af;hp=24f2081103afb4ebb6b73ec7ddfc36226434e368;hpb=5fc820296bd27badf71036b9d79980277d1dd095;p=jalview.git diff --git a/src/jalview/datamodel/features/SequenceFeatures.java b/src/jalview/datamodel/features/SequenceFeatures.java index 24f2081..2101a2f 100644 --- a/src/jalview/datamodel/features/SequenceFeatures.java +++ b/src/jalview/datamodel/features/SequenceFeatures.java @@ -1,14 +1,33 @@ +/* + * 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; +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; @@ -16,6 +35,8 @@ import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; +import intervalstore.api.IntervalI; + /** * A class that stores sequence features in a way that supports efficient * querying by type and location (overlap). Intended for (but not limited to) @@ -26,30 +47,6 @@ import java.util.TreeMap; */ public class SequenceFeatures implements SequenceFeaturesI { - /** - * a comparator for sorting features by start position ascending - */ - private static Comparator FORWARD_STRAND = new Comparator() - { - @Override - public int compare(ContiguousI o1, ContiguousI o2) - { - return Integer.compare(o1.getBegin(), o2.getBegin()); - } - }; - - /** - * a comparator for sorting features by end position descending - */ - private static Comparator REVERSE_STRAND = new Comparator() - { - @Override - public int compare(ContiguousI o1, ContiguousI o2) - { - return Integer.compare(o2.getEnd(), o1.getEnd()); - } - }; - /* * map from feature type to structured store of features for that type * null types are permitted (but not a good idea!) @@ -67,7 +64,7 @@ public class SequenceFeatures implements SequenceFeaturesI */ // featureStore = Collections // .synchronizedSortedMap(new TreeMap()); - featureStore = new TreeMap(); + featureStore = new TreeMap<>(); } /** @@ -113,12 +110,10 @@ public class SequenceFeatures implements SequenceFeaturesI String... type) { List result = new ArrayList<>(); - for (FeatureStore featureSet : varargToTypes(type)) { - result.addAll(featureSet.findOverlappingFeatures(from, to)); + featureSet.findFeatures(from, to, result); } - return result; } @@ -149,8 +144,16 @@ public class SequenceFeatures implements SequenceFeaturesI } Set featureTypes = getFeatureTypes(ontologyTerm); - return getAllFeatures(featureTypes.toArray(new String[featureTypes - .size()])); + if (featureTypes.isEmpty()) + { + /* + * no features of the specified type or any sub-type + */ + return new ArrayList<>(); + } + + return getAllFeatures( + featureTypes.toArray(new String[featureTypes.size()])); } /** @@ -193,7 +196,7 @@ public class SequenceFeatures implements SequenceFeaturesI for (FeatureStore featureSet : varargToTypes(type)) { - result.addAll(featureSet.getPositionalFeatures()); + featureSet.getPositionalFeatures(result); } return result; } @@ -237,7 +240,7 @@ public class SequenceFeatures implements SequenceFeaturesI for (FeatureStore featureSet : varargToTypes(type)) { - result.addAll(featureSet.getContactFeatures()); + featureSet.getContactFeatures(result); } return result; } @@ -252,7 +255,7 @@ public class SequenceFeatures implements SequenceFeaturesI for (FeatureStore featureSet : varargToTypes(type)) { - result.addAll(featureSet.getNonPositionalFeatures()); + featureSet.getNonPositionalFeatures(result); } return result; } @@ -296,7 +299,9 @@ public class SequenceFeatures implements SequenceFeaturesI public Set getFeatureGroups(boolean positionalFeatures, String... type) { - Set groups = new HashSet<>(); + // BH 2020.03.21 This is the set that orders the list of groups + // at the top of the FeatureSettings panel. + Set groups = Platform.getJavaOrderedHashSet(); for (FeatureStore featureSet : varargToTypes(type)) { @@ -313,12 +318,15 @@ public class SequenceFeatures implements SequenceFeaturesI public Set getFeatureTypesForGroups(boolean positionalFeatures, String... groups) { - Set result = new HashSet<>(); + // BH 2020.03.21 This set is the one that sets the initial ordering for + // feature rendering. We set it to new HashSet<>(16,0.75) to force it to + // be backed by a Java hash-ordered HashMap instead of a JavaScript Map. + Set result = Platform.getJavaOrderedHashSet(); 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)) @@ -341,7 +349,7 @@ public class SequenceFeatures implements SequenceFeaturesI @Override public Set getFeatureTypes(String... soTerm) { - Set types = new HashSet<>(); + Set types = new HashSet<>(15, 0.75f); for (Entry entry : featureStore.entrySet()) { String type = entry.getKey(); @@ -354,9 +362,10 @@ public class SequenceFeatures implements SequenceFeaturesI } /** - * Answers true if the given type is one of the specified sequence ontology - * terms (or a sub-type of one), or if no terms are supplied. Answers false if - * filter terms are specified and the given term does not match any of them. + * Answers true if the given type matches one of the specified terms (or is a + * sub-type of one in the Sequence Ontology), or if no terms are supplied. + * Answers false if filter terms are specified and the given term does not + * match any of them. * * @param type * @param soTerm @@ -368,10 +377,10 @@ public class SequenceFeatures implements SequenceFeaturesI { return true; } - SequenceOntologyI so = SequenceOntologyFactory.getInstance(); + SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology(); for (String term : soTerm) { - if (so.isA(type, term)) + if (type.equals(term) || so.isA(type, term)) { return true; } @@ -385,8 +394,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; } /** @@ -395,8 +405,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; } /** @@ -406,11 +417,12 @@ 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); + Collections.sort(features, + forwardStrand ? IntervalI.COMPARE_BEGIN_ASC + : IntervalI.COMPARE_END_DESC); } /** @@ -452,4 +464,33 @@ public class SequenceFeatures implements SequenceFeaturesI } return modified; } + + /** + * {@inheritDoc} + */ + @Override + public void deleteAll() + { + featureStore.clear(); + } + + @Override + public List findFeatures(int pos, String type, + List list) + { + FeatureStore fs = featureStore.get(type); + if (fs == null) + { + return list == null ? new ArrayList<>() : list; + } + return fs.findFeatures(pos, pos, list); + } + + @Override + public boolean hasFeatures(String type) + { + return featureStore.containsKey(type) + && !featureStore.get(type).isEmpty(); + } + }