/* * 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.schemes; import jalview.analysis.AAFrequency; import jalview.analysis.Conservation; import jalview.datamodel.AnnotatedCollectionI; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceI; import jalview.util.Comparison; import jalview.util.MessageManager; import java.awt.Color; import java.util.Hashtable; import java.util.Map; /** * DOCUMENT ME! * * @author $author$ * @version $Revision$ */ public class ResidueColourScheme implements ColourSchemeI { final int[] symbolIndex; boolean conservationColouring = false; Color[] colors = null; int threshold = 0; /* Set when threshold colouring to either pid_gaps or pid_nogaps */ protected String ignoreGaps = AAFrequency.PID_GAPS; /** Consenus as a hashtable array */ Hashtable[] consensus; /** Conservation string as a char array */ char[] conservation; int conservationLength = 0; /** DOCUMENT ME!! */ int inc = 30; /** * Creates a new ResidueColourScheme object. * * @param final int[] index table into colors (ResidueProperties.naIndex or * ResidueProperties.aaIndex) * @param colors * colours for symbols in sequences * @param threshold * threshold for conservation shading */ public ResidueColourScheme(int[] aaOrnaIndex, Color[] colours, int threshold) { symbolIndex = aaOrnaIndex; this.colors = colours; this.threshold = threshold; } /** * Creates a new ResidueColourScheme object with a lookup table for indexing * the colour map */ public ResidueColourScheme(int[] aaOrNaIndex) { symbolIndex = aaOrNaIndex; } /** * Creates a new ResidueColourScheme object - default constructor for * non-sequence dependent colourschemes */ public ResidueColourScheme() { symbolIndex = null; } /** * Find a colour without an index in a sequence */ public Color findColour(char c) { return colors == null ? Color.white : colors[symbolIndex[c]]; } @Override public Color findColourSeq(char c, int j, SequenceI seq) { Color currentColour; if (colors != null && symbolIndex != null && (threshold == 0) || aboveThreshold(c, j)) { currentColour = colors[symbolIndex[c]]; } else { currentColour = Color.white; } if (conservationColouring) { currentColour = applyConservation(currentColour, j); } return currentColour; } /** * Get the percentage threshold for this colour scheme * * @return Returns the percentage threshold */ public int getThreshold() { return threshold; } /** * DOCUMENT ME! * * @param ct * DOCUMENT ME! */ public void setThreshold(int ct, boolean ignoreGaps) { threshold = ct; if (ignoreGaps) { this.ignoreGaps = AAFrequency.PID_NOGAPS; } else { this.ignoreGaps = AAFrequency.PID_GAPS; } } /** * DOCUMENT ME! * * @param s * DOCUMENT ME! * @param j * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean aboveThreshold(char c, int j) { if ('a' <= c && c <= 'z') { // TO UPPERCASE !!! // Faster than toUpperCase c -= ('a' - 'A'); } if (consensus == null || consensus.length < j || consensus[j] == null) { return false; } if ((((Integer) consensus[j].get(AAFrequency.MAXCOUNT)).intValue() != -1) && consensus[j].contains(String.valueOf(c))) { if (((Float) consensus[j].get(ignoreGaps)).floatValue() >= threshold) { return true; } } return false; } public boolean conservationApplied() { return conservationColouring; } @Override public void setConservationApplied(boolean conservationApplied) { conservationColouring = conservationApplied; } public void setConservationInc(int i) { inc = i; } public int getConservationInc() { return inc; } /** * DOCUMENT ME! * * @param consensus * DOCUMENT ME! */ public void setConsensus(Hashtable[] consensus) { if (consensus == null) { return; } this.consensus = consensus; } public void setConservation(Conservation cons) { if (cons == null) { conservationColouring = false; conservation = null; } else { conservationColouring = true; int i, iSize = cons.getConsSequence().getLength(); conservation = new char[iSize]; for (i = 0; i < iSize; i++) { conservation[i] = cons.getConsSequence().getCharAt(i); } conservationLength = conservation.length; } } /** * DOCUMENT ME! * * @param s * DOCUMENT ME! * @param i * DOCUMENT ME! * * @return DOCUMENT ME! */ Color applyConservation(Color currentColour, int i) { if ((conservationLength > i) && (conservation[i] != '*') && (conservation[i] != '+')) { if (Comparison.isGap(conservation[i])) { currentColour = Color.white; } else { float t = 11 - (conservation[i] - '0'); if (t == 0) { return Color.white; } int red = currentColour.getRed(); int green = currentColour.getGreen(); int blue = currentColour.getBlue(); int dr = 255 - red; int dg = 255 - green; int db = 255 - blue; dr *= t / 10f; dg *= t / 10f; db *= t / 10f; red += (inc / 20f) * dr; green += (inc / 20f) * dg; blue += (inc / 20f) * db; if (red > 255 || green > 255 || blue > 255) { currentColour = Color.white; } else { currentColour = new Color(red, green, blue); } } } return currentColour; } @Override public void alignmentChanged(AnnotatedCollectionI alignment, Map hiddenReps) { } @Override public ColourSchemeI applyTo(AnnotatedCollectionI sg, Map hiddenRepSequences) { try { return getClass().newInstance(); } catch (Exception q) { throw new Error(MessageManager.formatMessage("error.implementation_error_cannot_duplicate_colour_scheme", new String[]{getClass().getName()}), q); } } }