-
Notifications
You must be signed in to change notification settings - Fork 1
/
20120909b.py
121 lines (109 loc) · 3.8 KB
/
20120909b.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
"""
Check W-F generations per population for compensatory substitution pathways.
Do not use forward simulation.
Presumably the exact solutions have been checked against forward simulation
in other web scripts.
Two different compensatory substitution pathways are considered.
The model is of two alleles at two loci, so a four-haplotype model.
Mutation, recombination, and selection+drift occur between each generation
in that order.
Selection acts directly on the haploid population,
in a way that corresponds to multiplicative selection in diploids.
The two different compensatory substitution pathways
from the high-fitness state AB to the high-fitness state ab are distinguished
by whether the most recently fixed haplotype before first reaching state ab
is AB or is a low-fitness haplotype.
Haploid selection for this compensatory model
gives fitness 1 to AA and ab and fitness 1-s to Ab and aB.
"""
from StringIO import StringIO
import math
import numpy as np
from scipy import linalg
import Form
import FormOut
import RUtil
from RUtil import mk_call_str
import MatrixUtil
import wfengine
import wfcompens
import multinomstate
import wfbckcompens
import combobreaker
def get_form():
"""
@return: the body of a form
"""
return [
Form.Float('theta', 'mutation rate 4*N*mu', '1.0',
low_inclusive=0.001),
Form.Float('Nr', 'recombination rate N*r', '5.0',
low_inclusive=0),
Form.Float('Ns', 'selection N*s', '1.0',
low_inclusive=0),
]
def get_form_out():
return FormOut.Report()
def get_backward_info(N_diploid, theta, Nr, Ns):
"""
Compute expectations and variances for the two substitution pathways.
Here backward is somewhat of a misnomer; it is meant as a contrast
to forward simulation.
@param N_diploid: diploid population size
@param theta: a mutation rate
@param Nr: a recombination rate
@param Ns: a selection value
@return: (t1, v1), (t2, v2)
"""
# set up the state space
k = 4
M = multinomstate.get_sorted_states(2*N_diploid, k)
T = multinomstate.get_inverse_map(M)
nstates = M.shape[0]
lmcs = wfengine.get_lmcs(M)
# compute rate matrices
R_rate = wfcompens.create_recomb(M, T)
M_rate = wfcompens.create_mutation(M, T)
# compute a recombination probability matrix
R_prob = linalg.expm(Nr * R_rate / float((2*N_diploid)**2))
# compute the expected number of mutation events per generation
mu = theta / 2
# compute the mutation matrix
# and the product of mutation and recombination.
M_prob = linalg.expm(mu * M_rate / float(2*2*N_diploid))
MR_prob = np.dot(M_prob, R_prob)
# compute the selection coefficient
s = Ns / float(N_diploid)
lps = wfcompens.create_selection(s, M)
S_prob = np.exp(wfengine.create_genic(lmcs, lps, M))
P = np.dot(MR_prob, S_prob)
#
t1, v1 = wfbckcompens.get_type_1_info(P)
t2, v2 = wfbckcompens.get_type_2_info(P)
return (t1, v1), (t2, v2)
def get_response_content(fs):
out = StringIO()
print >> out, 'theta:', fs.theta
print >> out, 'Nr:', fs.Nr
print >> out, 'Ns:', fs.Ns
print >> out
for N_diploid in (3, 4, 5, 6, 7, 8, 9, 10, 11, 12):
N_hap = N_diploid * 2
# TODO check s vs N_diploid so that selection is not too big
# as to make fitnesses negative or zero
#
(t1, v1), (t2, v2) = get_backward_info(
N_diploid, fs.theta, fs.Nr, fs.Ns)
#
print >> out, '2N:', N_hap
print >> out, 'Type 1 (generations / 2N) expectation:', t1 / N_hap
print >> out, 'Type 2 (generations / 2N) expectation:', t2 / N_hap
print >> out
return out.getvalue()
def main():
"""
Check some stuff that takes longer to compute.
"""
pass
if __name__ == '__main__':
main()