From 9b0d1162a0c5a08aa477b87b033bc841d840ea95 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Fri, 30 Mar 2018 10:42:33 +0100 Subject: [PATCH] JAL-2938 revisions to implementation details --- src/jalview/schemes/HmmerColourScheme.java | 74 +++++++++++--------- src/jalview/schemes/HmmerGlobalBackground.java | 15 ++-- src/jalview/schemes/HmmerLocalBackground.java | 34 ++++++--- .../jalview/schemes/HmmerGlobalBackgroundTest.java | 8 ++- test/jalview/schemes/HmmerLocalBackgroundTest.java | 9 ++- 5 files changed, 84 insertions(+), 56 deletions(-) diff --git a/src/jalview/schemes/HmmerColourScheme.java b/src/jalview/schemes/HmmerColourScheme.java index d31f0e1..9ea468d 100644 --- a/src/jalview/schemes/HmmerColourScheme.java +++ b/src/jalview/schemes/HmmerColourScheme.java @@ -12,10 +12,10 @@ import java.util.Map; /** * 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 * @@ -35,18 +35,26 @@ public abstract class HmmerColourScheme extends ResidueColourScheme { 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 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(); } /** @@ -57,10 +65,10 @@ public abstract class HmmerColourScheme extends ResidueColourScheme } @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); } /** @@ -82,6 +90,10 @@ public abstract class HmmerColourScheme extends ResidueColourScheme { return Color.white; } + if (Comparison.isGap(hmmSeq.getCharAt(column))) + { + return INSERTION_COLOUR; + } if (Character.isLowerCase(symbol)) { symbol = Character.toUpperCase(symbol); @@ -100,19 +112,22 @@ public abstract class HmmerColourScheme extends ResidueColourScheme { 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; } @@ -124,16 +139,6 @@ public abstract class HmmerColourScheme extends ResidueColourScheme */ abstract float getMaxInformationScore(); - @Override - public void alignmentChanged(AnnotatedCollectionI collection, - Map 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 @@ -142,21 +147,16 @@ public abstract class HmmerColourScheme extends ResidueColourScheme public ColourSchemeI getInstance(AnnotatedCollectionI ac, Map 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() @@ -189,4 +189,8 @@ public abstract class HmmerColourScheme extends ResidueColourScheme return hmm; } + protected SequenceI getHmmSequence() + { + return hmmSeq; + } } diff --git a/src/jalview/schemes/HmmerGlobalBackground.java b/src/jalview/schemes/HmmerGlobalBackground.java index e1d00bb..d5508f1 100644 --- a/src/jalview/schemes/HmmerGlobalBackground.java +++ b/src/jalview/schemes/HmmerGlobalBackground.java @@ -1,7 +1,6 @@ package jalview.schemes; import jalview.datamodel.AnnotatedCollectionI; -import jalview.datamodel.HiddenMarkovModel; /** * An HMM colour scheme that uses global ('Uniprot') background frequencies for @@ -23,11 +22,12 @@ public class HmmerGlobalBackground extends HmmerColourScheme * * @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)); } @@ -46,10 +46,9 @@ public class HmmerGlobalBackground extends HmmerColourScheme } @Override - protected HmmerColourScheme newInstance(AnnotatedCollectionI ac, - HiddenMarkovModel model) + protected HmmerColourScheme newInstance(AnnotatedCollectionI ac) { - return new HmmerGlobalBackground(model); + return new HmmerGlobalBackground(ac); } @Override diff --git a/src/jalview/schemes/HmmerLocalBackground.java b/src/jalview/schemes/HmmerLocalBackground.java index b878b9e..d7a5e65 100644 --- a/src/jalview/schemes/HmmerLocalBackground.java +++ b/src/jalview/schemes/HmmerLocalBackground.java @@ -1,10 +1,11 @@ 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; /** @@ -24,11 +25,10 @@ public class HmmerLocalBackground extends HmmerColourScheme * * @param markov */ - public HmmerLocalBackground(AnnotatedCollectionI sg, - HiddenMarkovModel markov) + public HmmerLocalBackground(AnnotatedCollectionI ac) { - super(markov); - countFrequencies(sg); + super(ac.getHmmConsensus()); + countFrequencies(ac); } /** @@ -46,13 +46,30 @@ public class HmmerLocalBackground extends HmmerColourScheme /** * 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 freqs = new HashMap<>(); - ResidueCount counts = new ResidueCount(sg.getSequences()); + + /* + * count symbols, excluding any HMM consensus sequences + */ + ResidueCount counts = new ResidueCount(); + List 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) @@ -73,9 +90,8 @@ public class HmmerLocalBackground extends HmmerColourScheme } @Override - protected HmmerColourScheme newInstance(AnnotatedCollectionI ac, - HiddenMarkovModel model) + protected HmmerColourScheme newInstance(AnnotatedCollectionI ac) { - return new HmmerLocalBackground(ac, model); + return new HmmerLocalBackground(ac); } } diff --git a/test/jalview/schemes/HmmerGlobalBackgroundTest.java b/test/jalview/schemes/HmmerGlobalBackgroundTest.java index b417482..13bf47b 100644 --- a/test/jalview/schemes/HmmerGlobalBackgroundTest.java +++ b/test/jalview/schemes/HmmerGlobalBackgroundTest.java @@ -2,6 +2,9 @@ package jalview.schemes; import static org.testng.Assert.assertEquals; +import jalview.datamodel.Alignment; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SequenceI; import jalview.io.DataSourceType; import jalview.io.HMMFile; @@ -19,7 +22,10 @@ public class HmmerGlobalBackgroundTest { HMMFile file = new HMMFile("test/jalview/io/test_PKinase_hmm.txt", DataSourceType.FILE); - ColourSchemeI scheme = new HmmerGlobalBackground(file.getHMM()); + SequenceI hmmSeq = file.getSeqsAsArray()[0]; + AlignmentI al = new Alignment(new SequenceI[] { hmmSeq }); + al.setHmmConsensus(hmmSeq); + ColourSchemeI scheme = new HmmerGlobalBackground(al); /* * 'A' in column 1, node 2, match emission 2.77204 diff --git a/test/jalview/schemes/HmmerLocalBackgroundTest.java b/test/jalview/schemes/HmmerLocalBackgroundTest.java index 991adb5..7467ab2 100644 --- a/test/jalview/schemes/HmmerLocalBackgroundTest.java +++ b/test/jalview/schemes/HmmerLocalBackgroundTest.java @@ -33,9 +33,12 @@ public class HmmerLocalBackgroundTest { */ SequenceI seq1 = new Sequence("seq1", "AAMMMKKKVV"); SequenceI seq2 = new Sequence("seq2", "aAM-QKRSSSL"); - AnnotatedCollectionI ac = new Alignment(new SequenceI[] { seq1, seq2 }); - ColourSchemeI scheme = new HmmerLocalBackground(ac, - file.getHMM()); + SequenceI hmmSeq = file.getSeqsAsArray()[0]; + AnnotatedCollectionI ac = new Alignment( + new SequenceI[] + { hmmSeq, seq1, seq2 }); + ac.setHmmConsensus(hmmSeq); + ColourSchemeI scheme = new HmmerLocalBackground(ac); /* * 'A' in column 1, node 2, match emission 2.77204 -- 1.7.10.2