1 package jalview.schemes;
3 import jalview.datamodel.AnnotatedCollectionI;
4 import jalview.datamodel.HiddenMarkovModel;
5 import jalview.datamodel.SequenceCollectionI;
6 import jalview.datamodel.SequenceI;
7 import jalview.util.ColorUtils;
8 import jalview.util.Comparison;
10 import java.awt.Color;
14 * Base class for colour schemes based on a selected Hidden Markov Model. The
15 * colour is with reference to an HMM consensus sequence and HMM profile
17 * <li>white for a gap</li>
18 * <li>red for an insertion (position is gapped in the HMM consensus)</li>
19 * <li>orange for negative information content</li>
20 * <li>white to blue for increasing information content</li>
22 * where information content is the log ratio
25 * log(profile match emission probability / residue background probability)
28 * Sub-class implementations use either global ('Uniprot') or local
29 * ('alignment') background frequencies.
34 public abstract class HmmerColourScheme extends ResidueColourScheme
36 private static final Color INSERTION_COLOUR = new Color(230, 0, 0); // reddish
39 * the aligned HMM consensus sequence to use as reference for colouring
41 private SequenceI hmmSeq;
43 private HiddenMarkovModel hmm;
45 private Map<Character, Float> frequencies;
48 * Constructor given a Hidden Markov Model consensus sequence. This provides
49 * the HMM profile from which we can read the emission probabilities that
50 * determine the colour.
54 public HmmerColourScheme(SequenceI consensusSeq)
56 hmmSeq = consensusSeq;
57 hmm = hmmSeq == null ? null : hmmSeq.getHMM();
61 * Default constructor (required by ColourSchemes.loadColourSchemes)
63 public HmmerColourScheme()
68 public Color findColour(char symbol, int column, SequenceI seq,
69 String consensusResidue, float pid)
71 return findColour(symbol, column);
75 * Returns the colour at a particular symbol at a column in the alignment:
77 * <li>white for a gap</li>
78 * <li>red for an insertion</li>
79 * <li>orange for negative information content</li>
80 * <li>white to blue for increasing information content</li>
87 private Color findColour(char symbol, int column)
89 if (getHmm() == null || Comparison.isGap(symbol))
93 if (Comparison.isGap(hmmSeq.getCharAt(column)))
95 return INSERTION_COLOUR;
97 if (Character.isLowerCase(symbol))
99 symbol = Character.toUpperCase(symbol);
102 final double prob = getHmm().getMatchEmissionProbability(column,
107 if (!frequencies.containsKey(symbol))
113 freq = frequencies.get(symbol);
117 * Orange if match emission probability is less than background probability
119 double infoRatio = prob / freq.floatValue();
120 Color colour = Color.ORANGE;
124 * log-scale graduated shade of blue if prob is greater than background
126 float infoLog = (float) Math.log(infoRatio);
127 colour = ColorUtils.getGraduatedColour(infoLog, 0, Color.WHITE,
128 getMaxInformationScore(), Color.blue);
135 * Answers the maximum possible value of information score (log ratio), for
136 * use in scaling a graduated colour range
140 abstract float getMaxInformationScore();
143 * Answers a new colour scheme instance based on the HMM of the first sequence
144 * in ac that has an HMM
147 public ColourSchemeI getInstance(AnnotatedCollectionI ac,
148 Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
150 return newInstance(ac);
154 * Answers a new instance of the colour scheme for the given HMM
159 protected abstract HmmerColourScheme newInstance(AnnotatedCollectionI ac);
162 public boolean isSimple()
168 * Answers true if the sequence collection has an HMM consensus sequence, else
172 public boolean isApplicableTo(AnnotatedCollectionI ac)
174 return ac.getHmmConsensus() != null;
177 protected Map<Character, Float> getFrequencies()
182 protected void setFrequencies(Map<Character, Float> frequencies)
184 this.frequencies = frequencies;
187 protected HiddenMarkovModel getHmm()
192 protected SequenceI getHmmSequence()