X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fschemes%2FFeatureColour.java;h=2007f8b831a60990ab5443c2646cd4f1beaac970;hb=94202c5a8e9ddccf471659d63025f6174811df7f;hp=ed3e02d370bbef3266d0a944d542a2929b92b82d;hpb=fb2d7072a283815141262d70d5f11a5e966d500b;p=jalview.git diff --git a/src/jalview/schemes/FeatureColour.java b/src/jalview/schemes/FeatureColour.java index ed3e02d..2007f8b 100644 --- a/src/jalview/schemes/FeatureColour.java +++ b/src/jalview/schemes/FeatureColour.java @@ -33,13 +33,23 @@ import java.util.StringTokenizer; */ public class FeatureColour implements FeatureColourI { - private static final String BAR = "|"; + private static final float _255F = 255f; - final private Color colour; + private static final String ABOVE = "above"; - final private Color minColour; + private static final String BELOW = "below"; - final private Color maxColour; + private static final String ABSO = "abso"; + + private static final String LABEL = "label"; + + private static final String PIPE = "|"; + + private final Color colour; + + private final Color minColour; + + private final Color maxColour; private boolean graduatedColour; @@ -61,17 +71,118 @@ public class FeatureColour implements FeatureColourI private boolean autoScaled; - final private float minRed; + private final float minRed; + + private final float minGreen; + + private final float minBlue; - final private float minGreen; + private final float deltaRed; - final private float minBlue; + private final float deltaGreen; + + private final float deltaBlue; + + /** + * Default constructor + */ + public FeatureColour() + { + this((Color) null); + } - final private float deltaRed; + /** + * Constructor given a simple colour + * + * @param c + */ + public FeatureColour(Color c) + { + minColour = Color.WHITE; + maxColour = Color.BLACK; + minRed = 0f; + minGreen = 0f; + minBlue = 0f; + deltaRed = 0f; + deltaGreen = 0f; + deltaBlue = 0f; + colour = c; + } + + /** + * Constructor given a colour range and a score range + * + * @param low + * @param high + * @param min + * @param max + */ + public FeatureColour(Color low, Color high, float min, float max) + { + graduatedColour = true; + colour = null; + minColour = low == null ? Color.WHITE : low; + maxColour = high == null ? Color.BLACK : high; + threshold = Float.NaN; + isHighToLow = min >= max; + minRed = minColour.getRed() / _255F; + minGreen = minColour.getGreen() / _255F; + minBlue = minColour.getBlue() / _255F; + deltaRed = (maxColour.getRed() / _255F) - minRed; + deltaGreen = (maxColour.getGreen() / _255F) - minGreen; + deltaBlue = (maxColour.getBlue() / _255F) - minBlue; + if (isHighToLow) + { + base = max; + range = min - max; + } + else + { + base = min; + range = max - min; + } + } - final private float deltaGreen; + /** + * Copy constructor + * + * @param fc + */ + public FeatureColour(FeatureColour fc) + { + graduatedColour = fc.graduatedColour; + colour = fc.colour; + minColour = fc.minColour; + maxColour = fc.maxColour; + minRed = fc.minRed; + minGreen = fc.minGreen; + minBlue = fc.minBlue; + deltaRed = fc.deltaRed; + deltaGreen = fc.deltaGreen; + deltaBlue = fc.deltaBlue; + base = fc.base; + range = fc.range; + isHighToLow = fc.isHighToLow; + setAboveThreshold(fc.isAboveThreshold()); + setBelowThreshold(fc.isBelowThreshold()); + setThreshold(fc.getThreshold()); + setAutoScaled(fc.isAutoScaled()); + setColourByLabel(fc.isColourByLabel()); + } - final private float deltaBlue; + /** + * Copy constructor with new min/max ranges + * + * @param fc + * @param min + * @param max + */ + public FeatureColour(FeatureColour fc, float min, float max) + { + this(fc); + graduatedColour = true; + updateBounds(min, max); + } /** * Parses a Jalview features file format colour descriptor @@ -96,20 +207,20 @@ public class FeatureColour implements FeatureColourI */ public static FeatureColour parseJalviewFeatureColour(String descriptor) { - StringTokenizer gcol = new StringTokenizer(descriptor, "|", true); + StringTokenizer gcol = new StringTokenizer(descriptor, PIPE, true); float min = Float.MIN_VALUE; float max = Float.MAX_VALUE; boolean labelColour = false; String mincol = gcol.nextToken(); - if (mincol == "|") + if (mincol == PIPE) { throw new IllegalArgumentException( "Expected either 'label' or a colour specification in the line: " + descriptor); } String maxcol = null; - if (mincol.toLowerCase().indexOf("label") == 0) + if (mincol.toLowerCase().indexOf(LABEL) == 0) { labelColour = true; mincol = (gcol.hasMoreTokens() ? gcol.nextToken() : null); @@ -125,8 +236,8 @@ public class FeatureColour implements FeatureColourI Color colour = ColorUtils.parseColourString(descriptor); if (colour == null) { - throw new IllegalArgumentException("Invalid colour descriptor: " - + descriptor); + throw new IllegalArgumentException( + "Invalid colour descriptor: " + descriptor); } return new FeatureColour(colour); } @@ -136,11 +247,13 @@ public class FeatureColour implements FeatureColourI * autoScaled == false ('abso'): colours range over min/max range */ boolean autoScaled = true; - String tok = null, minval, maxval; + String tok = null; + String minval; + String maxval; if (mincol != null) { // at least four more tokens - if (mincol.equals("|")) + if (mincol.equals(PIPE)) { mincol = ""; } @@ -149,7 +262,7 @@ public class FeatureColour implements FeatureColourI gcol.nextToken(); // skip next '|' } maxcol = gcol.nextToken(); - if (maxcol.equals("|")) + if (maxcol.equals(PIPE)) { maxcol = ""; } @@ -159,7 +272,7 @@ public class FeatureColour implements FeatureColourI } tok = gcol.nextToken(); gcol.nextToken(); // skip next '|' - if (tok.toLowerCase().startsWith("abso")) + if (tok.toLowerCase().startsWith(ABSO)) { minval = gcol.nextToken(); gcol.nextToken(); // skip next '|' @@ -180,7 +293,7 @@ public class FeatureColour implements FeatureColourI { min = new Float(minval).floatValue(); } - } catch (Exception e) + } catch (NumberFormatException e) { throw new IllegalArgumentException( "Couldn't parse the minimum value for graduated colour (" @@ -192,7 +305,7 @@ public class FeatureColour implements FeatureColourI { max = new Float(maxval).floatValue(); } - } catch (Exception e) + } catch (NumberFormatException e) { throw new IllegalArgumentException( "Couldn't parse the maximum value for graduated colour (" @@ -219,16 +332,17 @@ public class FeatureColour implements FeatureColourI featureColour.setColourByLabel(labelColour); featureColour.setAutoScaled(autoScaled); // add in any additional parameters - String ttype = null, tval = null; + String ttype = null; + String tval = null; if (gcol.hasMoreTokens()) { // threshold type and possibly a threshold value ttype = gcol.nextToken(); - if (ttype.toLowerCase().startsWith("below")) + if (ttype.toLowerCase().startsWith(BELOW)) { featureColour.setBelowThreshold(true); } - else if (ttype.toLowerCase().startsWith("above")) + else if (ttype.toLowerCase().startsWith(ABOVE)) { featureColour.setAboveThreshold(true); } @@ -236,8 +350,8 @@ public class FeatureColour implements FeatureColourI { if (!ttype.toLowerCase().startsWith("no")) { - System.err.println("Ignoring unrecognised threshold type : " - + ttype); + System.err.println( + "Ignoring unrecognised threshold type : " + ttype); } } } @@ -248,7 +362,7 @@ public class FeatureColour implements FeatureColourI gcol.nextToken(); tval = gcol.nextToken(); featureColour.setThreshold(new Float(tval).floatValue()); - } catch (Exception e) + } catch (NumberFormatException e) { System.err.println("Couldn't parse threshold value as a float: (" + tval + ")"); @@ -256,11 +370,11 @@ public class FeatureColour implements FeatureColourI } if (gcol.hasMoreTokens()) { - System.err - .println("Ignoring additional tokens in parameters in graduated colour specification\n"); + System.err.println( + "Ignoring additional tokens in parameters in graduated colour specification\n"); while (gcol.hasMoreTokens()) { - System.err.println("|" + gcol.nextToken()); + System.err.println(PIPE + gcol.nextToken()); } System.err.println("\n"); } @@ -271,115 +385,6 @@ public class FeatureColour implements FeatureColourI } } - /** - * Default constructor - */ - public FeatureColour() - { - this((Color) null); - } - - /** - * Constructor given a simple colour - * - * @param c - */ - public FeatureColour(Color c) - { - minColour = Color.WHITE; - maxColour = Color.BLACK; - minRed = 0f; - minGreen = 0f; - minBlue = 0f; - deltaRed = 0f; - deltaGreen = 0f; - deltaBlue = 0f; - colour = c; - } - - /** - * Constructor given a colour range and a score range - * - * @param low - * @param high - * @param min - * @param max - */ - public FeatureColour(Color low, Color high, float min, float max) - { - if (low == null) - { - low = Color.white; - } - if (high == null) - { - high = Color.black; - } - graduatedColour = true; - colour = null; - minColour = low; - maxColour = high; - threshold = Float.NaN; - isHighToLow = min >= max; - minRed = low.getRed() / 255f; - minGreen = low.getGreen() / 255f; - minBlue = low.getBlue() / 255f; - deltaRed = (high.getRed() / 255f) - minRed; - deltaGreen = (high.getGreen() / 255f) - minGreen; - deltaBlue = (high.getBlue() / 255f) - minBlue; - if (isHighToLow) - { - base = max; - range = min - max; - } - else - { - base = min; - range = max - min; - } - } - - /** - * Copy constructor - * - * @param fc - */ - public FeatureColour(FeatureColour fc) - { - graduatedColour = fc.graduatedColour; - colour = fc.colour; - minColour = fc.minColour; - maxColour = fc.maxColour; - minRed = fc.minRed; - minGreen = fc.minGreen; - minBlue = fc.minBlue; - deltaRed = fc.deltaRed; - deltaGreen = fc.deltaGreen; - deltaBlue = fc.deltaBlue; - base = fc.base; - range = fc.range; - isHighToLow = fc.isHighToLow; - setAboveThreshold(fc.isAboveThreshold()); - setBelowThreshold(fc.isBelowThreshold()); - setThreshold(fc.getThreshold()); - setAutoScaled(fc.isAutoScaled()); - setColourByLabel(fc.isColourByLabel()); - } - - /** - * Copy constructor with new min/max ranges - * - * @param fc - * @param min - * @param max - */ - public FeatureColour(FeatureColour fc, float min, float max) - { - this(fc); - graduatedColour = true; - updateBounds(min, max); - } - @Override public boolean isGraduatedColour() { @@ -529,64 +534,70 @@ public class FeatureColour implements FeatureColourI } /** - * Returns the colour for the given instance of the feature. This may be a - * simple colour, a colour generated from the feature description (if - * isColourByLabel()), or a colour derived from the feature score (if - * isGraduatedColour()). + * {@inheritDoc} * * @param feature * @return */ @Override - public Color getColor(SequenceFeature feature) + public Color getColour(SequenceFeature feature) { - if (isColourByLabel()) - { - return ColorUtils - .createColourFromName(feature.getDescription()); - } - - if (!isGraduatedColour()) + if (isSimpleColour()) { return getColour(); } /* - * graduated colour case, optionally with threshold - * (treating Float.NaN as within visible range here) + * return null if score is outwith any threshold + * (for graduated colour or colour by label) */ float scr = feature.getScore(); - if (isAboveThreshold() && scr <= threshold) - { - return null; - } - if (isBelowThreshold() && scr >= threshold) + boolean isNan = Float.isNaN(scr); + if (!isNan) { - return null; - } - if (range == 0.0) - { - return getMaxColour(); + boolean isAbove = isAboveThreshold() && scr <= threshold; + boolean isBelow = !isNan && isBelowThreshold() && scr >= threshold; + if (isAbove || isBelow) + { + return null; + } } - if (Float.isNaN(scr)) + + if (isColourByLabel()) { - return getMinColour(); + return ColorUtils.createColourFromName(feature.getDescription()); } - float scl = (scr - base) / range; - if (isHighToLow) + + Color result = null; + + if (isNan) { - scl = -scl; + result = getMinColour(); } - if (scl < 0f) + else if (range == 0.0) { - scl = 0f; + result = getMaxColour(); } - if (scl > 1f) + else { - scl = 1f; + float scl = (scr - base) / range; + if (isHighToLow) + { + scl = -scl; + } + if (scl < 0f) + { + scl = 0f; + } + if (scl > 1f) + { + scl = 1f; + } + result = new Color(minRed + scl * deltaRed, + minGreen + scl * deltaGreen, minBlue + scl * deltaBlue); } - return new Color(minRed + scl * deltaRed, minGreen + scl * deltaGreen, - minBlue + scl * deltaBlue); + + return result; } /** @@ -638,32 +649,32 @@ public class FeatureColour implements FeatureColourI StringBuilder sb = new StringBuilder(32); if (isColourByLabel()) { - sb.append("label"); + sb.append(LABEL); if (hasThreshold()) { - sb.append(BAR).append(BAR).append(BAR); + sb.append(PIPE).append(PIPE).append(PIPE); } } if (isGraduatedColour()) { - sb.append(Format.getHexString(getMinColour())).append(BAR); - sb.append(Format.getHexString(getMaxColour())).append(BAR); + sb.append(Format.getHexString(getMinColour())).append(PIPE); + sb.append(Format.getHexString(getMaxColour())).append(PIPE); if (!isAutoScaled()) { - sb.append("abso").append(BAR); + sb.append(ABSO).append(PIPE); } } if (hasThreshold() || isGraduatedColour()) { - sb.append(getMin()).append(BAR); - sb.append(getMax()).append(BAR); + sb.append(getMin()).append(PIPE); + sb.append(getMax()).append(PIPE); if (isBelowThreshold()) { - sb.append("below").append(BAR).append(getThreshold()); + sb.append(BELOW).append(PIPE).append(getThreshold()); } else if (isAboveThreshold()) { - sb.append("above").append(BAR).append(getThreshold()); + sb.append(ABOVE).append(PIPE).append(getThreshold()); } else {