From e9b3b4078647e40fcdb23d5f0814c05954cf730f Mon Sep 17 00:00:00 2001 From: gmungoc Date: Fri, 27 Sep 2019 12:40:28 +0100 Subject: [PATCH] JAL-3443 findColourInt changes for Overview drawing --- src/jalview/renderer/OverviewRenderer.java | 6 +- src/jalview/renderer/OverviewResColourFinder.java | 72 +++++++++++++---- src/jalview/renderer/ResidueShader.java | 83 ++++++++++++++++++++ src/jalview/renderer/ResidueShaderI.java | 11 +++ .../renderer/seqfeatures/FeatureColourFinder.java | 30 +++++++ src/jalview/util/ColorUtils.java | 36 +++++++++ 6 files changed, 220 insertions(+), 18 deletions(-) diff --git a/src/jalview/renderer/OverviewRenderer.java b/src/jalview/renderer/OverviewRenderer.java index 82e89e5..f37b7ec 100644 --- a/src/jalview/renderer/OverviewRenderer.java +++ b/src/jalview/renderer/OverviewRenderer.java @@ -517,7 +517,7 @@ public class OverviewRenderer } /* - * Find the RGB value of the colour of a sequence at a specified column position + * Returns the RGB value of the colour of a sequence at a specified column position * * @param seq * sequence to get colour for @@ -530,8 +530,8 @@ public class OverviewRenderer { return (seq == null || icol >= seq.getLength() ? resColFinder.gapColourInt - : resColFinder.getResidueColour(true, shader, allGroups, seq, - icol, finder).getRGB()); + : resColFinder.getResidueColourInt(true, shader, allGroups, seq, + icol, finder)); } /** diff --git a/src/jalview/renderer/OverviewResColourFinder.java b/src/jalview/renderer/OverviewResColourFinder.java index 8206b32..b6aa33f 100644 --- a/src/jalview/renderer/OverviewResColourFinder.java +++ b/src/jalview/renderer/OverviewResColourFinder.java @@ -22,6 +22,7 @@ package jalview.renderer; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; +import jalview.renderer.seqfeatures.FeatureColourFinder; import jalview.util.Comparison; import java.awt.Color; @@ -37,10 +38,12 @@ public class OverviewResColourFinder extends ResidueColourFinder final Color gapColour; // colour to use for gaps - final int gapColourInt; // RGB value of gapColour + final int gapColourInt; final Color residueColour; // colour to use for uncoloured residues + final int residueColourInt; + final Color hiddenColour; // colour for hidden regions boolean useLegacy = false; @@ -77,33 +80,72 @@ public class OverviewResColourFinder extends ResidueColourFinder residueColour = Color.WHITE; } gapColourInt = gapColour.getRGB(); + residueColourInt = residueColour.getRGB(); hiddenColour = hiddenCol; } - /** - * Overrides the method to return the currently configured Overview colours - * for gaps, or residues with no colour scheme set. A custom colour scheme - * which specifies a colour for gaps overrides the normal gap colour. - */ @Override public Color getBoxColour(ResidueShaderI shader, SequenceI seq, int i) { + return new Color(getBoxColourInt(shader, seq, i)); + } + + public int getBoxColourInt(ResidueShaderI shader, SequenceI seq, int i) + { char currentChar = seq.getCharAt(i); + // In the overview window, gaps are coloured grey, unless the colour scheme + // specifies a gap colour, in which case gaps honour the colour scheme + // settings boolean isGap = Comparison.isGap(currentChar); if (shader.getColourScheme() == null) { - return (isGap ? gapColour : residueColour); + return (isGap ? gapColourInt : residueColourInt); } - return (isGap && !shader.getColourScheme().hasGapColour() ? gapColour - : shader.findColour(currentChar, i, seq)); + return (isGap && !shader.getColourScheme().hasGapColour() ? gapColourInt + : shader.findColourInt(currentChar, i, seq)); + } + + @Override + public Color getResidueColour(boolean showBoxes, ResidueShaderI shader, + SequenceGroup[] allGroups, final SequenceI seq, int i, + FeatureColourFinder finder) + { + Color col = getResidueBoxColour(showBoxes, shader, allGroups, seq, i); + + // if there's a FeatureColourFinder we might override the residue colour + // here with feature colouring + col = finder == null || finder.noFeaturesDisplayed() ? col + : finder.findFeatureColour(col, seq, i); + return col; + } + + public int getResidueColourInt(boolean showBoxes, ResidueShaderI shader, + SequenceGroup[] allGroups, final SequenceI seq, int i, + FeatureColourFinder finder) + { + int col = getResidueBoxColourInt(showBoxes, shader, allGroups, seq, i); + + // if there's a FeatureColourFinder we might override the residue colour + // here with feature colouring + col = finder == null || finder.noFeaturesDisplayed() ? col + : finder.findFeatureColourInt(col, seq, i); + return col; + } + + @Override + protected Color getResidueBoxColour(boolean showBoxes, + ResidueShaderI shader, SequenceGroup[] allGroups, SequenceI seq, + int i) + { + return new Color( + getResidueBoxColourInt(showBoxes, shader, allGroups, seq, i)); } /** * In the overview, the showBoxes setting is ignored, as the overview displays - * the colours regardless + * the colours regardless. */ - @Override - protected Color getResidueBoxColour(boolean showBoxes, + protected int getResidueBoxColourInt(boolean showBoxes, ResidueShaderI shader, SequenceGroup[] allGroups, SequenceI seq, int i) { @@ -111,13 +153,13 @@ public class OverviewResColourFinder extends ResidueColourFinder i); ResidueShaderI currentShader = (currentSequenceGroup == null ? shader : currentSequenceGroup.getGroupColourScheme()); - return getBoxColour(currentShader, seq, i); + return getBoxColourInt(currentShader, seq, i); } /** - * Returns the coloured configured for hidden regions in the Overview + * Supply hidden colour * - * @return + * @return colour of hidden regions */ protected Color getHiddenColour() { diff --git a/src/jalview/renderer/ResidueShader.java b/src/jalview/renderer/ResidueShader.java index c031170..73a5efd 100644 --- a/src/jalview/renderer/ResidueShader.java +++ b/src/jalview/renderer/ResidueShader.java @@ -262,6 +262,36 @@ public class ResidueShader implements ResidueShaderI return colour; } + @Override + public int findColourInt(char symbol, int position, SequenceI seq) + { + if (colourScheme == null) + { + return -1;// Color.white; // Colour is 'None' + } + + /* + * get 'base' colour + */ + ProfileI profile = consensus == null ? null : consensus.get(position); + String modalResidue = profile == null ? null + : profile.getModalResidue(); + float pid = profile == null ? 0f + : profile.getPercentageIdentity(ignoreGaps); + int colour = colourScheme + .findColour(symbol, position, seq, modalResidue, pid).getRGB(); + + /* + * apply PID threshold and consensus fading if in force + */ + if (!Comparison.isGap(symbol)) + { + colour = adjustColourInt(symbol, position, colour); + } + + return colour; + } + /** * Adjusts colour by applying thresholding or conservation shading, if in * force. That is @@ -293,6 +323,20 @@ public class ResidueShader implements ResidueShaderI return colour; } + protected int adjustColourInt(char symbol, int column, int colour) + { + if (!aboveThreshold(symbol, column)) + { + colour = -1;// Color.white; + } + + if (conservationColouring) + { + colour = applyConservationInt(colour, column); + } + return colour; + } + /** * Answers true if there is a consensus profile for the specified column, and * the given residue matches the consensus (or joint consensus) residue for @@ -398,6 +442,45 @@ public class ResidueShader implements ResidueShaderI return ColorUtils.bleachColour(currentColour, bleachFactor); } + protected int applyConservationInt(int currentColour, int column) + { + if (conservation == null || conservation.length <= column) + { + return currentColour; + } + char conservationScore = conservation[column]; + + /* + * if residues are fully conserved (* or 11), or all properties + * are conserved (+ or 10), leave colour unchanged + */ + if (conservationScore == '*' || conservationScore == '+' + || conservationScore == (char) 10 + || conservationScore == (char) 11) + { + return currentColour; + } + + if (Comparison.isGap(conservationScore)) + { + return -1;// Color.white; + } + + /* + * convert score 0-9 to a bleaching factor 1.1 - 0.2 + */ + float bleachFactor = (11 - (conservationScore - '0')) / 10f; + + /* + * scale this up by 0-5 (percentage slider / 20) + * as a result, scores of: 0 1 2 3 4 5 6 7 8 9 + * fade to white at slider value: 18 20 22 25 29 33 40 50 67 100% + */ + bleachFactor *= (conservationIncrement / 20f); + + return ColorUtils.bleachColourInt(currentColour, bleachFactor); + } + /** * @see jalview.renderer.ResidueShaderI#getColourScheme() */ diff --git a/src/jalview/renderer/ResidueShaderI.java b/src/jalview/renderer/ResidueShaderI.java index 4d97171..64e9632 100644 --- a/src/jalview/renderer/ResidueShaderI.java +++ b/src/jalview/renderer/ResidueShaderI.java @@ -78,6 +78,17 @@ public interface ResidueShaderI public abstract Color findColour(char symbol, int position, SequenceI seq); + /** + * A variant of findColour that returns the rgb value of the colour rather + * than a Color object + * + * @param symbol + * @param position + * @param seq + * @return + */ + public int findColourInt(char symbol, int position, SequenceI seq); + public abstract ColourSchemeI getColourScheme(); public abstract void setColourScheme(ColourSchemeI cs); diff --git a/src/jalview/renderer/seqfeatures/FeatureColourFinder.java b/src/jalview/renderer/seqfeatures/FeatureColourFinder.java index 703f220..a2ce35b 100644 --- a/src/jalview/renderer/seqfeatures/FeatureColourFinder.java +++ b/src/jalview/renderer/seqfeatures/FeatureColourFinder.java @@ -117,6 +117,36 @@ public class FeatureColourFinder return c; } + public int findFeatureColourInt(int defaultColour, SequenceI seq, + int column) + { + Graphics g = null; + + /* + * if transparency applies, provide a notional 1x1 graphics context + * that has been primed with the default colour + */ + if (featureRenderer.getTransparency() != 1f) + { + g = goff; + if (defaultColour != 0) + { + offscreenImage.setRGB(0, 0, defaultColour); + } + } + + Color c = featureRenderer.findFeatureColour(seq, column + 1, g); + if (c == null) + { + return defaultColour; + } + + if (g != null) + { + return offscreenImage.getRGB(0, 0); + } + return c.getRGB(); + } /** * Answers true if feature display is turned off, or there are no features * configured to be visible diff --git a/src/jalview/util/ColorUtils.java b/src/jalview/util/ColorUtils.java index 3eb080b..a2d8d3e 100644 --- a/src/jalview/util/ColorUtils.java +++ b/src/jalview/util/ColorUtils.java @@ -199,6 +199,42 @@ public class ColorUtils } } + public static int bleachColourInt(int colour, float bleachFactor) + { + if (bleachFactor >= 1f) + { + return -1;// Color.WHITE; + } + if (bleachFactor <= -1f) + { + return 0xFF000000;// Color.BLACK; + } + if (bleachFactor == 0f) + { + return colour; + } + + int red = (colour >> 16) & 0xFF;// getRed(); + int green = (colour >> 8) & 0xFF;// colour.getGreen(); + int blue = colour & 0xFF;// .getBlue(); + + if (bleachFactor > 0) + { + red += (255 - red) * bleachFactor; + green += (255 - green) * bleachFactor; + blue += (255 - blue) * bleachFactor; + } + else + { + float factor = 1 + bleachFactor; + red *= factor; + green *= factor; + blue *= factor; + } + return 0xFF000000 | (red << 16) | (green << 8) | blue;// new Color(red, + // green, blue); + } + /** * Parses a string into a Color, where the accepted formats are *