1 package jalview.schemes;
3 import jalview.api.AlignViewportI;
4 import jalview.datamodel.AnnotatedCollectionI;
5 import jalview.datamodel.HiddenMarkovModel;
6 import jalview.datamodel.SequenceI;
7 import jalview.util.ColorUtils;
8 import jalview.util.Comparison;
10 import java.awt.Color;
11 import java.util.List;
15 * Base class for colour schemes based on a selected Hidden Markov Model. The
16 * colour is with reference to an HMM consensus sequence and HMM profile
18 * <li>white for a gap</li>
19 * <li>red for an insertion (position is gapped in the HMM consensus)</li>
20 * <li>orange for negative information content</li>
21 * <li>white to blue for increasing information content</li>
23 * where information content is the log ratio
26 * log(profile match emission probability / residue background probability)
29 * Sub-class implementations use either global ('Uniprot') or local
30 * ('alignment') background frequencies.
35 public abstract class HmmerColourScheme extends ResidueColourScheme
37 private static final Color INSERTION_COLOUR = new Color(230, 0, 0); // reddish
40 * the aligned HMM consensus sequence to use as reference for colouring
42 private SequenceI hmmSeq;
44 private HiddenMarkovModel hmm;
46 private Map<Character, Float> frequencies;
49 * Constructor given a list of Hidden Markov Model consensus sequences. The
50 * first sequence provides the HMM profile from which we can read the emission
51 * probabilities that determine the colour.
55 public HmmerColourScheme(List<SequenceI> hmmSeqs)
57 hmmSeq = hmmSeqs.isEmpty() ? null : hmmSeqs.get(0);
58 hmm = hmmSeq == null ? null : hmmSeq.getHMM();
62 * Default constructor (required by ColourSchemes.loadColourSchemes)
64 public HmmerColourScheme()
69 public Color findColour(char symbol, int column, SequenceI seq,
70 String consensusResidue, float pid)
72 return findColour(symbol, column);
76 * Returns the colour at a particular symbol at a column in the alignment:
78 * <li>white for a gap</li>
79 * <li>red for an insertion</li>
80 * <li>orange for negative information content</li>
81 * <li>white to blue for increasing information content</li>
88 private Color findColour(char symbol, int column)
90 if (getHmm() == null || Comparison.isGap(symbol))
94 if (Comparison.isGap(hmmSeq.getCharAt(column)))
96 return INSERTION_COLOUR;
98 if (Character.isLowerCase(symbol))
100 symbol = Character.toUpperCase(symbol);
103 final double prob = getHmm().getMatchEmissionProbability(column,
108 if (!frequencies.containsKey(symbol))
114 freq = frequencies.get(symbol);
118 * Orange if match emission probability is less than background probability
120 double infoRatio = prob / freq.floatValue();
121 Color colour = Color.ORANGE;
125 * log-scale graduated shade of blue if prob is greater than background
127 float infoLog = (float) Math.log(infoRatio);
128 colour = ColorUtils.getGraduatedColour(infoLog, 0, Color.WHITE,
129 getMaxInformationScore(), Color.blue);
136 * Answers the maximum possible value of information score (log ratio), for
137 * use in scaling a graduated colour range
141 abstract float getMaxInformationScore();
144 * Answers a new colour scheme instance based on the HMM of the first sequence
145 * in ac that has an HMM
148 public ColourSchemeI getInstance(AlignViewportI viewport,
149 AnnotatedCollectionI ac)
151 return newInstance(ac);
155 * Answers a new instance of the colour scheme for the given HMM
160 protected abstract HmmerColourScheme newInstance(AnnotatedCollectionI ac);
163 public boolean isSimple()
169 * Answers true if the sequence collection has an HMM consensus sequence, else
173 public boolean isApplicableTo(AnnotatedCollectionI ac)
175 return !ac.getHmmSequences().isEmpty();
178 protected Map<Character, Float> getFrequencies()
183 protected void setFrequencies(Map<Character, Float> frequencies)
185 this.frequencies = frequencies;
188 protected HiddenMarkovModel getHmm()
193 protected SequenceI getHmmSequence()