/
20120824a.py
155 lines (144 loc) · 4.52 KB
/
20120824a.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
"""
Check continuous approximations of sojourn density.
Show the proportion of dimorphic time spent at each
allele frequency after a preferred
(or unpreferred if selection is negative)
mutation has occurred in a population fixed for the non-mutant allele
and before the mutant has gone to fixation or has been lost.
"""
from StringIO import StringIO
import time
import math
import numpy as np
from scipy import integrate
from scipy import special
import Form
import FormOut
import MatrixUtil
import StatsUtil
import kaizeng
import wrightfisher
import Util
import RUtil
from RUtil import mk_call_str
import wfengine
def get_form():
"""
@return: the body of a form
"""
return [
Form.Integer('N_diploid', 'diploid population size',
5, low=3, high=40),
Form.Float('gamma', 'scaled genic selection value', 1.5),
Form.ImageFormat(),
]
def get_form_out():
return FormOut.Image('plot')
def sojourn_indefinite(x, g):
"""
Integral of equation (9) of McVean and Charlesworth 1999.
integral of 2*expm1(-a*(1-x)) / (expm1(-a)*x*(1-x))
limit x -> 1 of (-2/expm1(a))*(-exp(a)*Ei(a*(x-1)) + Ei(a*x) + exp(a)*log((1-x)/x))
"""
if not 0 < x <= 1:
raise ValueError('x should be in the half open interval (0, 1]')
if g:
prefix = 2 / math.expm1(g)
suffix = -special.expi(g*x)
if x == 1:
eulergamma = -special.digamma(1)
suffix += math.exp(g)*(math.log(g) + eulergamma)
else:
suffix += math.exp(g)*(special.expi(g*(x-1)) - math.log((1-x)/x))
return prefix * suffix
else:
return 2*math.log(x)
def sojourn_definite(x0, x1, g):
return sojourn_indefinite(x1, g) - sojourn_indefinite(x0, g)
def sojourn_kernel(x, g):
return 2 * math.expm1(-g*(1-x)) / (math.expm1(-g) * x * (1-x))
def get_response_content(fs):
N_diploid = fs.N_diploid
N = N_diploid * 2
k = 2
gamma = fs.gamma
# define the fitnesses and the selection value
f0 = 1.0
f1 = 1.0 - gamma / N
s = 1 - f1 / f0
if f1 <= 0:
raise ValueError('the extreme selection caused a non-positive fitness')
# get a wright fisher transition matrix
P = np.exp(wfengine.create_genic_diallelic(N_diploid, s))
"""
# condition on no fixation
for i in range(N):
P[i] /= 1 - P[i, N]
# remove the fixed state from the transition matrix
P = P[:N, :N]
"""
# add mutations
P[0, 0] = 0
P[0, 1] = 1
P[N, N] = 0
P[N, 1] = 1
# compute the stationary distribution
v = MatrixUtil.get_stationary_distribution(P)
# get the distribution over dimorphic states
h = v[1:-1]
h /= np.sum(h)
# look at continuous approximations
w = np.zeros(N+1)
for i in range(1, N):
x = i / float(N)
#x0 = i / float(N)
#x1 = (i + 1) / float(N)
#value = sojourn_definite(x0, x1, gamma)
value = sojourn_kernel(x, gamma)
w[i] = value
w = w[1:-1]
w /= np.sum(w)
# get the array for the R plot
arr = [h.tolist(), w.tolist()]
# define the r script
out = StringIO()
print >> out, 'title.string <- "allele 1 vs allele 2"'
print >> out, 'mdat <-', RUtil.matrix_to_R_string(arr)
print >> out, mk_call_str(
'barplot',
'mdat',
'legend.text=' + mk_call_str(
'c',
'"exact discrete distribution"',
'"continuous approximation"',
#'"two-allele large N limit"',
#'"two-allele"',
#'"four-allele without mutational bias"',
#'"four-allele with mutational bias (kappa_{1,2}=2)"',
#'"four-allele with mutational bias, large N limit"',
),
'args.legend = list(x="topright", bty="n")',
'names.arg = 1:%s' % (N-1),
main='title.string',
xlab='"frequency of allele 1"',
ylab='"frequency"',
col=mk_call_str(
'c',
#'"red"',
#'"white"',
'"black"',
#'"gray"',
'"red"',
),
beside='TRUE',
border='NA',
)
#print >> out, 'box()'
script = out.getvalue().rstrip()
# create the R plot image
device_name = Form.g_imageformat_to_r_function[fs.imageformat]
retcode, r_out, r_err, image_data = RUtil.run_plotter_no_table(
script, device_name)
if retcode:
raise RUtil.RError(r_err)
return image_data