00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <cmath>
00026 #include <cfloat>
00027 #include <cctype>
00028 #ifdef HAVE_IEEEFP_H
00029 #include <ieeefp.h>
00030 #endif
00031 #include <Sequence/Seq.hpp>
00032 #include <Sequence/Comparisons.hpp>
00033 #include <Sequence/SeqEnums.hpp>
00034 #include <Sequence/SeqExceptions.hpp>
00035 #include <Sequence/Kimura80.hpp>
00036
00041
00042 using std::log;
00043 using std::isfinite;
00044
00045 namespace Sequence
00046 {
00047 Kimura80::Kimura80 (const Sequence::Seq * seqa, const Sequence::Seq * seqb):
00048 seqlen (seqa->length())
00054 {
00055 if (seqa->length () != seqb->length ())
00056 throw SeqException ("Sequence::Kimura80::Kimura80(): constructor called with two sequence objects of unequal length");
00057 num_Ts = 0;
00058 num_Tv = 0;
00059 divergence = 0.0;
00060 P = 0.0;
00061 Q = 0.0;
00062 sites_compared = 0;
00063 Compute (seqa,seqb);
00064 }
00065
00066 void Kimura80::Compute (const Sequence::Seq *seq1, const Sequence::Seq *seq2)
00067 {
00068 unsigned i;
00069
00070 unsigned ungapped_sites = 0;
00071 for (i = 0; i < seqlen; ++i)
00072 {
00073 int type = 0;
00074 if (NotAGap((*seq1)[i]) && NotAGap((*seq2)[i]))
00075 {
00076 ++ungapped_sites;
00077 if (std::toupper((*seq1)[i]) !=
00078 std::toupper((*seq2)[i]))
00079 {
00080 type = TsTv ((*seq1)[i], (*seq2)[i]);
00081
00082 if (type == Mutations(Ts))
00083 {
00084 ++num_Ts;
00085 }
00086 else if (type == Mutations(Tv))
00087 {
00088 ++num_Tv;
00089 }
00090 }
00091 }
00092 }
00093
00094
00095 sites_compared = (ungapped_sites < seqlen) ? ungapped_sites : seqlen;
00096
00097 P = double (num_Ts) / double (sites_compared);
00098 Q = double (num_Tv) / double (sites_compared);
00099
00100
00101 if (fabs(1.0 - 2.0 * P - Q) > DBL_EPSILON)
00102 {
00103 divergence = -1.0 * 0.5 * log ((1.0 - 2.0 * P - Q)
00104 * pow ((1 - 2.0 * Q), 0.5));
00105 }
00106 else
00107 {
00108 divergence = 0.;
00109 }
00110
00111 if (divergence <= 0.0-DBL_EPSILON)
00112 divergence = 0.0;
00113 }
00114
00115 double
00116 Kimura80::K (void)
00123 {
00124 if (!isfinite(divergence))
00125 return (999.0);
00126 return (divergence);
00127 }
00128
00129 size_t
00130 Kimura80::sites (void)
00134 {
00135 return (sites_compared);
00136 }
00137 }