From ee8d9bad4fcb0109fd38dc362b77076d3046fec4 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Fri, 3 Nov 2017 11:50:45 +0000 Subject: [PATCH] JAL-2808 JAL-2069 record feature attributes descriptions and min-max --- src/jalview/datamodel/SequenceFeature.java | 23 +++- .../datamodel/features/FeatureAttributes.java | 120 ++++++++++++++++++-- 2 files changed, 131 insertions(+), 12 deletions(-) diff --git a/src/jalview/datamodel/SequenceFeature.java b/src/jalview/datamodel/SequenceFeature.java index ffbd497..2110632 100755 --- a/src/jalview/datamodel/SequenceFeature.java +++ b/src/jalview/datamodel/SequenceFeature.java @@ -442,10 +442,31 @@ public class SequenceFeature implements FeatureLocationI } otherDetails.put(key, value); - FeatureAttributes.getInstance().addAttribute(this.type, key); + recordAttribute(key, value); } } + /** + * Notifies the addition of a feature attribute. This lets us keep track of + * which attributes are present on each feature type, and also the range of + * numerical-valued attributes. + * + * @param key + * @param value + */ + protected void recordAttribute(String key, Object value) + { + String attDesc = null; + if (source != null) + { + attDesc = FeatureSources.getInstance().getSource(source) + .getAttributeName(key); + } + + FeatureAttributes.getInstance().addAttribute(this.type, key, attDesc, + value.toString()); + } + /* * The following methods are added to maintain the castor Uniprot mapping file * for the moment. diff --git a/src/jalview/datamodel/features/FeatureAttributes.java b/src/jalview/datamodel/features/FeatureAttributes.java index d4e9fb0..ed65750 100644 --- a/src/jalview/datamodel/features/FeatureAttributes.java +++ b/src/jalview/datamodel/features/FeatureAttributes.java @@ -5,8 +5,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.TreeSet; +import java.util.TreeMap; /** * A singleton class to hold the set of attributes known for each feature type @@ -15,7 +14,73 @@ public class FeatureAttributes { private static FeatureAttributes instance = new FeatureAttributes(); - private Map> attributes; + private Map> attributes; + + private class AttributeData + { + /* + * description(s) for this attribute, if known + * (different feature source might have differing descriptions) + */ + List description; + + /* + * minimum value (of any numeric values recorded) + */ + float min = 0f; + + /* + * maximum value (of any numeric values recorded) + */ + float max = 0f; + + /** + * Note one instance of this attribute, recording unique, non-null names, + * and the min/max of any numerical values + * + * @param desc + * @param value + */ + void addInstance(String desc, String value) + { + if (desc != null) + { + if (description == null) + { + description = new ArrayList<>(); + } + if (!description.contains(desc)) + { + description.add(desc); + } + if (value != null) + { + try + { + float f = Float.valueOf(value); + min = Float.min(min, f); + max = Float.max(max, f); + } catch (NumberFormatException e) + { + // ok, wasn't a number + } + } + } + } + + /** + * Answers the description of the attribute, if recorded and unique, or null if either no, or more than description is recorded + * @return + */ + public String getDescription() + { + if (description != null && description.size() == 1) + { + return description.get(0); + } + return null; + } + } /** * Answers the singleton instance of this class @@ -46,7 +111,7 @@ public class FeatureAttributes return Collections. emptyList(); } - return new ArrayList<>(attributes.get(featureType)); + return new ArrayList<>(attributes.get(featureType).keySet()); } /** @@ -58,7 +123,6 @@ public class FeatureAttributes */ public boolean hasAttributes(String featureType) { - if (attributes.containsKey(featureType)) { if (!attributes.get(featureType).isEmpty()) @@ -70,24 +134,58 @@ public class FeatureAttributes } /** - * Records the given attribute name for the given feature type + * Records the given attribute name and description for the given feature + * type, and updates the min-max for any numeric value * * @param featureType * @param attName + * @param description + * @param value */ - public void addAttribute(String featureType, String attName) + public void addAttribute(String featureType, String attName, + String description, String value) { if (featureType == null || attName == null) { return; } - if (!attributes.containsKey(featureType)) + Map atts = attributes.get(featureType); + if (atts == null) + { + atts = new TreeMap( + String.CASE_INSENSITIVE_ORDER); + attributes.put(featureType, atts); + } + AttributeData attData = atts.get(attName); + if (attData == null) { - attributes.put(featureType, new TreeSet( - String.CASE_INSENSITIVE_ORDER)); + attData = new AttributeData(); + atts.put(attName, attData); } + attData.addInstance(description, value); + } - attributes.get(featureType).add(attName); + /** + * Answers the description of the given attribute for the given feature type, + * if known and unique, else null + * + * @param featureType + * @param attName + * @return + */ + public String getDescription(String featureType, String attName) + { + String desc = null; + Map atts = attributes.get(featureType); + if (atts != null) + { + AttributeData attData = atts.get(attName); + if (attData != null) + { + desc = attData.getDescription(); + } + } + return desc; } } -- 1.7.10.2