1 /*********************************************************
2 * Copyright (C) 2005, BGI of Chinese Academy of Sciences
6 * Abstract: Definition of NG86 class.
9 * Author: Zhang Zhang (zhanghzhang@genomics.org.cn)
12 Reference: Nei M, Gojobori T (1986) Simple methods for
13 estimating the numbers of synonymous and nonsynonymous
14 nucleotide substitutions. Mol Biol Evol 3:418-426.
15 **********************************************************/
24 //Count synonymous(S) and nonsynonymous(N) sites
25 void NG86::getCondonSite(string codon
) {
31 if (getAminoAcid(codon
)=='!')
34 /* Synonymous sites only occur at first and third position in a codon */
35 for(i
=0, stop
=0; i
<3; i
+=2) {
38 if (j
!=convertChar(temp
[i
])) {
39 temp
[i
] = convertInt(j
);
40 if (getAminoAcid(temp
)=='!') {
44 if (getAminoAcid(temp
)==getAminoAcid(codon
))
51 N
+= (3-stop
/3.0-syn
/3.0);
54 //Count synonymous(Sd) and nonsynonymous(Nd) differences
55 void NG86::getCondonDifference(string codon1
, string codon2
) {
57 int i
,j
,k
,diff
[CODONLENGTH
];
66 if (getAminoAcid(codon1
)=='!' || getAminoAcid(codon2
)=='!')
69 for (i
=0; i
<CODONLENGTH
; i
++) {
71 if (codon1
[i
]!=codon2
[i
])
80 //Pathway of evolution from the differences
81 for (i
=1; i
<=num
; i
++)
84 //Only one difference between two codons
86 if (getAminoAcid(codon1
)==getAminoAcid(codon2
))
92 //Two differences between two codons
98 temp1
[diff
[i
]] = codon2
[diff
[i
]];
99 if (getAminoAcid(temp1
)!='!') {
102 if (getAminoAcid(temp1
)==getAminoAcid(codon1
)) sd_temp
++;
106 if (getAminoAcid(temp1
)==getAminoAcid(codon2
)) sd_temp
++;
113 //Three differences between two codons
118 if ((i
!=j
) && (i
!=k
) && (j
!=k
)) {
120 temp1
[diff
[i
]] = codon2
[diff
[i
]];
122 temp2
[diff
[j
]] = codon2
[diff
[j
]];
123 if (getAminoAcid(temp1
)!='!' && getAminoAcid(temp2
)!='!') {
125 if (getAminoAcid(temp1
)==getAminoAcid(codon1
)) sd_temp
++;
129 if (getAminoAcid(temp2
)==getAminoAcid(temp1
)) sd_temp
++;
133 if (getAminoAcid(codon2
)==getAminoAcid(temp2
)) sd_temp
++;
145 //All pathways are through stop codons
154 Sd
+= (double)(sd_temp
/(path
-stop
));
155 Nd
+= (double)(nd_temp
/(path
-stop
));
160 void NG86::PreProcess(string seq1
, string seq2
) {
164 //Count sites and differences
165 for(i
=0; i
<seq1
.length(); i
=i
+3) {
166 getCondonSite(seq1
.substr(i
,3));
167 getCondonSite(seq2
.substr(i
,3));
168 getCondonDifference(seq1
.substr(i
,3), seq2
.substr(i
,3));
174 //Scale the sum of S+N to the length of sequence.
175 double y
=seq1
.length()/(S
+N
);
180 /* Jukes & Cantor's one-parameter formula for correction */
181 double NG86::kaks_formula(double p
) {
182 //Equation (3) in the reference of NG86
183 double d
= 1-(4*p
)/3;
198 string
NG86::Run(string seq1
, string seq2
) {
200 PreProcess(seq1
, seq2
);
202 Ks
= kaks_formula(Sd
/S
);
203 Ka
= kaks_formula(Nd
/N
);
205 t
= (S
*Ks
+N
*Ka
)/(S
+N
);
207 return parseOutput();
212 /***********************************************************
213 NONE: an in-house algorithm in BGI for testing Ka and Ks.
214 NONE is NG86 without correction for multiple substitutions.
215 ************************************************************/
220 string
NONE::Run(string seq1
, string seq2
) {
222 PreProcess(seq1
, seq2
);
227 t
= (S
*Ks
+N
*Ka
)/(S
+N
);
229 return parseOutput();