1 #ifndef GENESIS_POPULATION_FUNCTION_FST_POOL_KOFLER_H_
2 #define GENESIS_POPULATION_FUNCTION_FST_POOL_KOFLER_H_
48 namespace population {
79 : p1_poolsize_( static_cast<double>( p1_poolsize ))
80 , p2_poolsize_( static_cast<double>( p2_poolsize ))
97 void reset_()
override
105 void process_( SampleCounts
const& p1, SampleCounts
const& p2 )
override
109 if( p1_poolsize_ <= 1.0 || p2_poolsize_ <= 1.0 ) {
119 std::isfinite( std::get<0>( pi_snps )) &&
120 std::isfinite( std::get<1>( pi_snps )) &&
121 std::isfinite( std::get<2>( pi_snps ))
124 assert( p1.a_count + p1.c_count + p1.g_count + p1.t_count > 0 );
125 assert( p2.a_count + p2.c_count + p2.g_count + p2.t_count > 0 );
128 p1_pi_sum_ += std::get<0>( pi_snps );
129 p2_pi_sum_ += std::get<1>( pi_snps );
130 pp_pi_sum_ += std::get<2>( pi_snps );
135 ( p1.a_count + p1.c_count + p1.g_count + p1.t_count <= 1 ) ||
136 ( p2.a_count + p2.c_count + p2.g_count + p2.t_count <= 1 )
141 double get_result_()
const override
144 if( p1_poolsize_ <= 1.0 || p2_poolsize_ <= 1.0 ) {
145 return std::numeric_limits<double>::quiet_NaN();
150 assert( p1_poolsize_ > 1.0 && p2_poolsize_ > 1.0 );
151 double const pp_poolsizem = std::min( p1_poolsize_, p2_poolsize_ );
152 auto const p1 =
static_cast<double>( p1_pi_sum_ ) * p1_poolsize_ / ( p1_poolsize_ - 1.0 );
153 auto const p2 =
static_cast<double>( p2_pi_sum_ ) * p2_poolsize_ / ( p2_poolsize_ - 1.0 );
154 auto const pp =
static_cast<double>( pp_pi_sum_ ) * pp_poolsizem / ( pp_poolsizem - 1.0 );
157 double const pp_avg = ( p1 + p2 ) / 2.0;
158 return ( pp - pp_avg ) / pp;
181 double freq_a,
double freq_c,
double freq_g,
double freq_t,
double nt_cnt
188 result *= nt_cnt / ( nt_cnt - 1.0 );
197 double const p1_nt_cnt =
static_cast<double>(
nucleotide_sum( p1 ));
198 double const p1_freq_a =
static_cast<double>( p1.
a_count ) / p1_nt_cnt;
199 double const p1_freq_c =
static_cast<double>( p1.
c_count ) / p1_nt_cnt;
200 double const p1_freq_g =
static_cast<double>( p1.
g_count ) / p1_nt_cnt;
201 double const p1_freq_t =
static_cast<double>( p1.
t_count ) / p1_nt_cnt;
204 double const p2_nt_cnt =
static_cast<double>(
nucleotide_sum( p2 ));
205 double const p2_freq_a =
static_cast<double>( p2.
a_count ) / p2_nt_cnt;
206 double const p2_freq_c =
static_cast<double>( p2.
c_count ) / p2_nt_cnt;
207 double const p2_freq_g =
static_cast<double>( p2.
g_count ) / p2_nt_cnt;
208 double const p2_freq_t =
static_cast<double>( p2.
t_count ) / p2_nt_cnt;
211 double const min_cnt = std::min( p1_nt_cnt, p2_nt_cnt );
212 double const avg_a = ( p1_freq_a + p2_freq_a ) / 2.0;
213 double const avg_c = ( p1_freq_c + p2_freq_c ) / 2.0;
214 double const avg_g = ( p1_freq_g + p2_freq_g ) / 2.0;
215 double const avg_t = ( p1_freq_t + p2_freq_t ) / 2.0;
218 auto const p1_pi = pi_snp_( p1_freq_a, p1_freq_c, p1_freq_g, p1_freq_t, p1_nt_cnt );
219 auto const p2_pi = pi_snp_( p2_freq_a, p2_freq_c, p2_freq_g, p2_freq_t, p2_nt_cnt );
220 auto const pp_pi = pi_snp_( avg_a, avg_c, avg_g, avg_t, min_cnt );
222 return std::tuple<double, double, double>{ p1_pi, p2_pi, pp_pi };
232 double p1_poolsize_ = 0;
233 double p2_poolsize_ = 0;
245 #endif // include guard