import jalview.io.DataSourceType;
import jalview.io.FileParse;
import jalview.io.HMMFile;
+import jalview.schemes.ResidueProperties;
import java.io.IOException;
import java.net.MalformedURLException;
+import java.util.Map;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class HiddenMarkovModelTest {
HiddenMarkovModel hmm;
- @Test(priority = 0)
- public void testGetMatchEmissionProbabilities()
- throws MalformedURLException, IOException
+ @BeforeClass(alwaysRun = true)
+ public void setUp() throws MalformedURLException, IOException
{
+ /*
+ * load hmm model of a Kinase domain to a HiddenMarkovModel
+ */
HMMFile file = new HMMFile(new FileParse(
"test/jalview/io/test_PKinase_hmm.txt", DataSourceType.FILE));
hmm = file.getHMM();
+ }
- double[] actual = new double[4];
- actual[0] = hmm.getMatchEmissionProbability(0, 'R');
- actual[1] = hmm.getMatchEmissionProbability(19, 'W');
- actual[2] = hmm.getMatchEmissionProbability(160, 'G');
- actual[3] = hmm.getMatchEmissionProbability(475, 'A');
-
- double[] expected = new double[4];
- expected[0] = 0.02537400637;
- expected[1] = 0.00588228492;
- expected[2] = 0;
- expected[3] = 0.04995163708;
-
- for (int i = 0; i < 4; i++)
- {
- assertEquals(actual[i], expected[i], 0.001d);
- }
+ @Test(groups = "Functional")
+ public void testGetMatchEmissionProbabilities()
+ throws MalformedURLException, IOException
+ {
+ /*
+ * raw value in file is 3.67403
+ * saved as probability e^-X = 0.05259
+ */
+ double mep = hmm.getMatchEmissionProbability(0, 'R');
+ assertEquals(mep, 0.02537400637, 0.0001d);
+ assertEquals(mep, Math.pow(Math.E, -3.67403), 0.0001d);
+
+ mep = hmm.getMatchEmissionProbability(19, 'W');
+ assertEquals(mep, 0.00588228492, 0.0001d);
+ assertEquals(mep, Math.pow(Math.E, -5.13581), 0.0001d);
+
+ // column 160 is a gapped region of the model
+ mep = hmm.getMatchEmissionProbability(160, 'G');
+ assertEquals(mep, 0D, 0.0001d);
+
+ mep = hmm.getMatchEmissionProbability(475, 'A');
+ assertEquals(mep, 0.04995163708, 0.0001d);
+ assertEquals(mep, Math.pow(Math.E, -2.99670), 0.0001d);
}
- @Test(priority = 1)
+ @Test(groups = "Functional")
public void testGetInsertEmissionProbabilities()
{
- double[] actual = new double[4];
- actual[0] = hmm.getInsertEmissionProbability(2, 'A');
- actual[1] = hmm.getInsertEmissionProbability(5, 'T');
- actual[2] = hmm.getInsertEmissionProbability(161, 'K');
- actual[3] = hmm.getInsertEmissionProbability(472, 'L');
-
- double[] expected = new double[4];
- expected[0] = 0.06841384927;
- expected[1] = 0.06233763141;
- expected[2] = 0;
- expected[3] = 0.06764038926;
-
- for (int i = 0; i < 4; i++)
- {
- assertEquals(actual[i], expected[i], 0.001d);
- }
+ double iep = hmm.getInsertEmissionProbability(2, 'A');
+ assertEquals(iep, Math.pow(Math.E, -2.68618), 0.0001d);
+
+ iep = hmm.getInsertEmissionProbability(5, 'T');
+ assertEquals(iep, Math.pow(Math.E, -2.77519), 0.0001d);
+
+ // column 161 is gapped in the hmm
+ iep = hmm.getInsertEmissionProbability(161, 'K');
+ assertEquals(iep, 0D, 0.0001d);
+
+ iep = hmm.getInsertEmissionProbability(472, 'L');
+ assertEquals(iep, Math.pow(Math.E, -2.69355), 0.0001d);
}
- @Test(priority = 1)
+ @Test(groups = "Functional")
public void testGetStateTransitionProbabilities()
{
- double[] actual = new double[4];
- actual[0] = hmm.getStateTransitionProbability(475, hmm.MATCHTODELETE);
- actual[1] = hmm.getStateTransitionProbability(8, hmm.MATCHTOINSERT);
- actual[2] = hmm.getStateTransitionProbability(80, hmm.INSERTTOINSERT);
- actual[3] = hmm.getStateTransitionProbability(475, hmm.DELETETOMATCH);
-
- double[] expected = new double[4];
- expected[0] = Double.NEGATIVE_INFINITY;
- expected[1] = 0.00662894243;
- expected[2] = 0.46183388908;
- expected[3] = 1;
-
- for (int i = 0; i < 4; i++)
- {
- assertEquals(actual[i], expected[i], 0.001d);
- }
+ // * in model file treated as negative infinity
+ double stp = hmm.getStateTransitionProbability(475,
+ HiddenMarkovModel.MATCHTODELETE);
+ assertEquals(stp, Double.NEGATIVE_INFINITY);
+
+ // file value is 5.01631, saved as e^-5.01631
+ stp = hmm.getStateTransitionProbability(8,
+ HiddenMarkovModel.MATCHTOINSERT);
+ assertEquals(stp, Math.pow(Math.E, -5.01631), 0.0001D);
+
+ stp = hmm.getStateTransitionProbability(36,
+ HiddenMarkovModel.MATCHTODELETE);
+ assertEquals(stp, Math.pow(Math.E, -5.73865), 0.0001D);
+
+ stp = hmm.getStateTransitionProbability(22,
+ HiddenMarkovModel.INSERTTOMATCH);
+ assertEquals(stp, Math.pow(Math.E, -0.61958), 0.0001D);
+
+ stp = hmm.getStateTransitionProbability(80,
+ HiddenMarkovModel.INSERTTOINSERT);
+ assertEquals(stp, Math.pow(Math.E, -0.77255), 0.0001D);
+
+ stp = hmm.getStateTransitionProbability(475,
+ HiddenMarkovModel.DELETETOMATCH);
+ assertEquals(stp, 1D, 0.0001D);
+
+ stp = hmm.getStateTransitionProbability(218,
+ HiddenMarkovModel.DELETETODELETE);
+ assertEquals(stp, Math.pow(Math.E, -0.95510), 0.0001D);
}
- @Test(priority = 1)
+ @Test(groups = "Functional")
public void testGetConsensusAtAlignColumn()
{
- char[] cons = new char[4];
- cons[0] = hmm.getConsensusAtAlignColumn(10);
- cons[1] = hmm.getConsensusAtAlignColumn(50);
+ assertEquals(hmm.getConsensusAtAlignColumn(10), 's');
+ assertEquals(hmm.getConsensusAtAlignColumn(50), 'k');
hmm.setConsensusResidueStatus(false);
- cons[2] = hmm.getConsensusAtAlignColumn(100);
- cons[3] = hmm.getConsensusAtAlignColumn(400);
-
- char[] expected = new char[4];
- expected[0] = 's';
- expected[1] = 'k';
- expected[2] = 'l';
- expected[3] = 'k';
-
- for (int i = 0; i < 4; i++)
- {
- assertEquals(cons[i], expected[i]);
- }
-
+ assertEquals(hmm.getConsensusAtAlignColumn(100), 'l');
+ assertEquals(hmm.getConsensusAtAlignColumn(400), 'k');
}
- @Test(priority = 1)
+ @Test(groups = "Functional")
public void testGetConsensusSequence()
{
SequenceI seq = hmm.getConsensusSequence();
subStr = seq.getSequenceAsString().substring(150, 161);
assertEquals(subStr, "-DLLK------");
}
+
+ /**
+ * A rather pointless test that reproduces the code implemented and asserts
+ * the result is the same...
+ */
+ @Test(groups = "Functional")
+ public void testGetInformationContent()
+ {
+ /*
+ * information measure is sum over all symbols of
+ * emissionProb * log(emissionProb / background) / log(2)
+ */
+ Map<Character, Float> uniprotFreqs = ResidueProperties.backgroundFrequencies
+ .get("amino");
+ int col = 4;
+ float expected = 0f;
+ for (char aa : hmm.getSymbols())
+ {
+ double mep = hmm.getMatchEmissionProbability(col, aa);
+ float background = uniprotFreqs.get(aa);
+ expected += mep * Math.log(mep / background);
+ }
+ expected /= Math.log(2D);
+
+ float actual = hmm.getInformationContent(col);
+ assertEquals(actual, expected, 0.0001d);
+ }
}