/**
* Base class for colour schemes based on a selected Hidden Markov Model. The
- * colour is
+ * colour is with reference to an HMM consensus sequence and HMM profile
* <ul>
* <li>white for a gap</li>
- * <li>red for an insertion</li>
+ * <li>red for an insertion (position is gapped in the HMM consensus)</li>
* <li>orange for negative information content</li>
* <li>white to blue for increasing information content</li>
* </ul>
{
private static final Color INSERTION_COLOUR = new Color(230, 0, 0); // reddish
+ /*
+ * the aligned HMM consensus sequence to use as reference for colouring
+ */
+ private SequenceI hmmSeq;
+
private HiddenMarkovModel hmm;
private Map<Character, Float> frequencies;
/**
- * Constructor given a Hidden Markov Model
+ * Constructor given a Hidden Markov Model consensus sequence. This provides
+ * the HMM profile from which we can read the emission probabilities that
+ * determine the colour.
*
- * @param markov
+ * @param consensusSeq
*/
- public HmmerColourScheme(HiddenMarkovModel markov)
+ public HmmerColourScheme(SequenceI consensusSeq)
{
- hmm = markov;
+ hmmSeq = consensusSeq;
+ hmm = hmmSeq == null ? null : hmmSeq.getHMM();
}
/**
}
@Override
- public Color findColour(char symbol, int position, SequenceI seq,
+ public Color findColour(char symbol, int column, SequenceI seq,
String consensusResidue, float pid)
{
- return findColour(symbol, position);
+ return findColour(symbol, column);
}
/**
{
return Color.white;
}
+ if (Comparison.isGap(hmmSeq.getCharAt(column)))
+ {
+ return INSERTION_COLOUR;
+ }
if (Character.isLowerCase(symbol))
{
symbol = Character.toUpperCase(symbol);
{
freq = frequencies.get(symbol);
}
- if (prob == 0D)
- {
- return INSERTION_COLOUR;
- }
- double value = Math.log(prob / freq.floatValue());
- Color colour = null;
- if (value < 0)
+
+ /*
+ * Orange if match emission probability is less than background probability
+ */
+ double infoRatio = prob / freq.floatValue();
+ Color colour = Color.ORANGE;
+ if (infoRatio >= 1)
{
- return Color.ORANGE;
+ /*
+ * log-scale graduated shade of blue if prob is greater than background
+ */
+ float infoLog = (float) Math.log(infoRatio);
+ colour = ColorUtils.getGraduatedColour(infoLog, 0, Color.WHITE,
+ getMaxInformationScore(), Color.blue);
}
- colour = ColorUtils.getGraduatedColour((float) value, 0, Color.WHITE,
- getMaxInformationScore(), Color.blue);
return colour;
}
*/
abstract float getMaxInformationScore();
- @Override
- public void alignmentChanged(AnnotatedCollectionI collection,
- Map<SequenceI, SequenceCollectionI> hiddenReps)
- {
- /*
- * ? 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 ac that has an HMM
public ColourSchemeI getInstance(AnnotatedCollectionI ac,
Map<SequenceI, SequenceCollectionI> hiddenRepSequences)
{
- SequenceI hmmSeq = ac.getHmmConsensus();
- HiddenMarkovModel model = hmmSeq == null ? null : hmmSeq.getHMM();
-
- return newInstance(ac, model);
+ return newInstance(ac);
}
/**
* Answers a new instance of the colour scheme for the given HMM
*
* @param ac
- * @param model
* @return
*/
- protected abstract HmmerColourScheme newInstance(AnnotatedCollectionI ac,
- HiddenMarkovModel model);
+ protected abstract HmmerColourScheme newInstance(AnnotatedCollectionI ac);
@Override
public boolean isSimple()
return hmm;
}
+ protected SequenceI getHmmSequence()
+ {
+ return hmmSeq;
+ }
}
package jalview.schemes;
import jalview.datamodel.AnnotatedCollectionI;
-import jalview.datamodel.HiddenMarkovModel;
/**
* An HMM colour scheme that uses global ('Uniprot') background frequencies for
*
* @param markov
*/
- public HmmerGlobalBackground(HiddenMarkovModel markov)
+ public HmmerGlobalBackground(AnnotatedCollectionI ac)
{
- super(markov);
- String alphabetType = markov == null ? ResidueProperties.ALPHABET_AMINO
- : markov.getAlphabetType();
+ super(ac.getHmmConsensus());
+ String alphabetType = getHmm() == null
+ ? ResidueProperties.ALPHABET_AMINO
+ : getHmm().getAlphabetType();
setFrequencies(
ResidueProperties.backgroundFrequencies.get(alphabetType));
}
}
@Override
- protected HmmerColourScheme newInstance(AnnotatedCollectionI ac,
- HiddenMarkovModel model)
+ protected HmmerColourScheme newInstance(AnnotatedCollectionI ac)
{
- return new HmmerGlobalBackground(model);
+ return new HmmerGlobalBackground(ac);
}
@Override
package jalview.schemes;
import jalview.datamodel.AnnotatedCollectionI;
-import jalview.datamodel.HiddenMarkovModel;
import jalview.datamodel.ResidueCount;
+import jalview.datamodel.SequenceI;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
*
* @param markov
*/
- public HmmerLocalBackground(AnnotatedCollectionI sg,
- HiddenMarkovModel markov)
+ public HmmerLocalBackground(AnnotatedCollectionI ac)
{
- super(markov);
- countFrequencies(sg);
+ super(ac.getHmmConsensus());
+ countFrequencies(ac);
}
/**
/**
* Counts and stores the relative frequency of every residue in the alignment
+ * (apart from any HMM consensus sequences)
*
* @param sg
*/
public void countFrequencies(AnnotatedCollectionI sg)
{
+ // TODO or total counts in Consensus Profile (how do we get at it?)?
Map<Character, Float> freqs = new HashMap<>();
- ResidueCount counts = new ResidueCount(sg.getSequences());
+
+ /*
+ * count symbols, excluding any HMM consensus sequences
+ */
+ ResidueCount counts = new ResidueCount();
+ List<SequenceI> seqs = sg.getSequences();
+ for (SequenceI seq : seqs)
+ {
+ if (!seq.isHMMConsensusSequence())
+ {
+ for (char c : seq.getSequence())
+ {
+ counts.add(c);
+ }
+ }
+ }
int total = counts.getTotalResidueCount(); // excludes gaps
for (char symbol : counts.getSymbolCounts().symbols)
}
@Override
- protected HmmerColourScheme newInstance(AnnotatedCollectionI ac,
- HiddenMarkovModel model)
+ protected HmmerColourScheme newInstance(AnnotatedCollectionI ac)
{
- return new HmmerLocalBackground(ac, model);
+ return new HmmerLocalBackground(ac);
}
}