import java.util.List;
import java.util.Map;
+/**
+ * A colour scheme based on a selected Hidden Markov Model. The colour is
+ * <ul>
+ * <li>white for a gap</li>
+ * <li>red for an insertion</li>
+ * <li>orange for negative information content</li>
+ * <li>white to blue for increasing information content</li>
+ * </ul>
+ * where information content is the log ratio
+ *
+ * <pre>
+ * log(profile match emission probability / residue background probability>
+ * </pre>
+ *
+ * using global ('Uniprot') background frequencies for residues.
+ *
+ * @author tzvanaalten
+ *
+ */
public class HMMERColourScheme extends ResidueColourScheme
{
+ /*
+ * The highest possible log ratio is when match emission probability in
+ * the HMM model is 1, and background (for W) is 0.0109 giving
+ * log(1/0.0109) = log(91.743) = 4.519
+ */
+ private static final float MAX_LOG_RATIO = 4.519f;
- AnnotatedCollectionI alignment;
+ private static final Color REDDISH = new Color(230, 0, 0);
HiddenMarkovModel hmm;
-
- boolean peptideSpecific;
-
- boolean nucleotideSpecific;
+ /**
+ * Constructor given a Hidden Markov Model
+ *
+ * @param markov
+ */
public HMMERColourScheme(HiddenMarkovModel markov)
{
hmm = markov;
}
+
+ /**
+ * Default constructor (required by ColourSchemes.loadColourSchemes)
+ */
public HMMERColourScheme()
{
-
}
-
@Override
public Color findColour(char symbol, int position, SequenceI seq,
String consensusResidue, float pid)
{
- if (hmm ==null)
- {
- return Color.white;
- }
return findColour(symbol, position);
}
/**
- * Returns the colour at a particular symbol at a column in the alignment.
+ * Returns the colour at a particular symbol at a column in the alignment:
+ * <ul>
+ * <li>white for a gap</li>
+ * <li>red for an insertion</li>
+ * <li>orange for negative information content</li>
+ * <li>white to blue for increasing information content</li>
+ * </ul>
*
* @param symbol
- * @param position
- * @return Red for an insertion, white for a gap, orange for a negative
- * information content, white to blue for increasing information
- * content.
+ * @param column
+ * @return
*/
- private Color findColour(char symbol, int position)
+ private Color findColour(char symbol, int column)
{
-
- if (Comparison.isGap(symbol))
+ if (hmm == null || Comparison.isGap(symbol))
{
return Color.white;
}
{
symbol = Character.toUpperCase(symbol);
}
- Double prob;
- prob = hmm.getMatchEmissionProbability(position, symbol);
- double freq = 0;
+
+ double prob = hmm.getMatchEmissionProbability(column, symbol);
+ Float freq = 0f;
String alpha = hmm.getAlphabetType();
- if (!ResidueProperties.backgroundFrequencies.get(alpha).containsKey(symbol))
+ if (!ResidueProperties.backgroundFrequencies.get(alpha)
+ .containsKey(symbol))
{
- return Color.white;
+ return Color.WHITE;
}
else
{
freq = ResidueProperties.backgroundFrequencies.get(alpha).get(symbol);
}
- if (prob == 0)
+ if (prob == 0D)
{
- return new Color(230, 0, 0);
+ return REDDISH;
}
- Double value = Math.log(prob / freq);
+ double value = Math.log(prob / freq.floatValue());
Color colour = null;
if (value > 0)
{
-
- colour = ColorUtils.getGraduatedColour(value.floatValue(), 0,
- Color.WHITE, 4.52f, Color.blue);
+ colour = ColorUtils.getGraduatedColour((float) value, 0,
+ Color.WHITE, MAX_LOG_RATIO, Color.blue);
}
else if (value < 0)
{
return Color.ORANGE;
-
}
return colour;
-
}
-
-
-
-
-
@Override
public void alignmentChanged(AnnotatedCollectionI collection,
Map<SequenceI, SequenceCollectionI> hiddenReps)
{
- List<SequenceI> seqs = collection.getSequences();
- for (SequenceI seq : seqs)
- {
- if (seq.isHMMConsensusSequence())
- {
- hmm = seq.getHMM();
- break;
- }
- }
-
+ /*
+ * ? no need to do anything if alignment is adjusted
+ * since findColour() handles everything
+ */
}
-
-
+ /**
+ * Answers a new colour scheme instance based on the HMM of the first sequence
+ * in sg that has an HMM
+ */
@Override
public ColourSchemeI getInstance(AnnotatedCollectionI sg,
Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
{
- HiddenMarkovModel markov = null;
- List<SequenceI> seqs = sg.getSequences();
- for (SequenceI seq : seqs)
- {
- if (seq.isHMMConsensusSequence())
- {
- markov = seq.getHMM();
- break;
- }
- }
- HMMERColourScheme colour = new HMMERColourScheme(markov);
- return colour;
-
+ HiddenMarkovModel model = null;
+ List<SequenceI> seqs = sg.getHMMConsensusSequences();
+ if (!seqs.isEmpty())
+ {
+ model = seqs.get(0).getHMM();
+ }
+ HMMERColourScheme colour = new HMMERColourScheme(model);
+ return colour;
}
@Override
- public boolean isApplicableTo(AnnotatedCollectionI ac)
+ public String getSchemeName()
{
- return true;
-
+ return JalviewColourScheme.HMMERU.toString();
}
@Override
- public String getSchemeName()
+ public boolean isSimple()
{
-
- return JalviewColourScheme.HMMERU.name();
+ return false;
}
@Override
- public boolean isSimple()
+ public boolean isApplicableTo(AnnotatedCollectionI ac)
{
- return false;
+ return !ac.getHMMConsensusSequences().isEmpty();
}
}