001 package calhoun.analysis.crf.features.supporting.phylogenetic;
002
003 import org.apache.commons.logging.Log;
004 import org.apache.commons.logging.LogFactory;
005
006 import calhoun.util.Assert;
007
008 public class HKY85Model extends NucleotideSubstitutionModel {
009 private static final long serialVersionUID = -1555350959092722736L;
010 private static final Log log = LogFactory.getLog(HKY85Model.class);
011 // Model for nucleotide substitution proposed by Kimura in 1980.
012 // Models the overall rate of nucleotide substitution and the difference
013 // between rate of transitions and transversions.
014
015 double ts;
016 double tv;
017 double piA;
018 double piC;
019 double piG;
020 double piT;
021
022 /* HKY85 Nucleotide substitution model
023 * 1. Website: http://www.mun.ca/biology/scarr/Transitions_vs_Transversions.htm
024 * 2. Reviw article: Pietro Lio and Nick Goldman, "Models of Molecular Evolution and Phylogeny", Genome Research, 1998.
025 * 3. Primary article: Hasegawa, Kishino, Yano, 1985, "Dating of the human-ape splitting by a molecular clock of mitochondrial DNA", J. Molecular Evolution. 22, 160-174.
026 */
027
028 public HKY85Model(double[] parms) {
029 setParameters(parms);
030 }
031
032 public HKY85Model() {
033 // Provide some reasonable seed values
034 ts = 0.6;
035 tv = 0.2;
036 piA = 0.25;
037 piC = 0.25;
038 piG = 0.25;
039 piT = 0.25;
040 }
041
042 @Override
043 public String getEvolutionaryModelName() {
044 return "HKY85_nucleotide_evolution_model";
045 }
046
047 @Override
048 public double[] getParameters() {
049 double[] ret = new double[6];
050 ret[0] = ts;
051 ret[1] = tv;
052 ret[2] = piA;
053 ret[3] = piC;
054 ret[4] = piG;
055 ret[5] = piT;
056 return ret;
057 }
058
059
060 @Override
061 public void setParameters(double[] parms) {
062 Assert.a(parms.length == 5);
063 for (int j=0; j<5; j++) {
064 Assert.a(parms[j] > 0);
065 }
066
067 ts = parms[0];
068 tv = parms[1];
069 piA = parms[2];
070 piC = parms[3];
071 piG = parms[4];
072 piT = 1 - piA - piC - piG;
073 Assert.a(piT>0);
074
075 // Maybe here I should be using a hashing function, but let's first just write it out;
076 double[][] X = new double[4][4];
077 int A=0, C=1, G=2, T=3;
078 // Given an i base, X[i][j] is rate of changing to base j.
079 X[A][A]=0; X[A][C]=tv*piC; X[A][G]=ts*piG; X[A][T]=tv*piT;
080 X[C][A]=tv*piA; X[C][C]=0; X[C][G]=tv*piG; X[C][T]=ts*piT;
081 X[G][A]=ts*piA; X[G][C]=tv*piC; X[G][G]=0; X[G][T]=tv*piT;
082 X[T][A]=tv*piA; X[T][C]=ts*piC; X[T][G]=tv*piG; X[T][T]=0;
083 for (int i=0; i<4; i++) {
084 for (int j=0; j<4; j++) {
085 if (j!=i) {
086 X[i][i] -= X[i][j];
087 }
088 }
089 }
090
091 R.assign(X);
092 }
093
094 @Override
095 public void summarize() {
096 log.debug("HKY85 Nucleotide substitution rate matrix; ts=" + ts + " tv=" + tv + " piA="+piA+" piC="+piC+" piG="+piG+" piT="+piT);
097 }
098 }