I've been trying to solve a system of ODE's with scipys solve_ivp, which is a mean field approximation of a hierarchically organized tissue model, where I want to quantify the number of cells at level 'k' with 'm' number of mutations at a given time point. Here is the equation itself:
My goal is to calculate the number of cells which have 1,2,3... number of mutations, which can be obtained by knowing the number of cells in the entire system having at least 1,2,3... number of mutations which is: M(m) = \\sum_{k=0,n} \\sum_{l=m,inf} N_{k,l}, where n is the last hierarchical level. The problem is, that the resulting cell numbers of these equations include those cells also, which have not acquired a new mutation, but just inherited it from its mother cell. I want to count those cells which acquired a new mutation.
So my problem is that I having a hard time modifying the equations, all I want to do is setting a "counter" where I can add at every iteration a certain proportion of cells, while I do not modify my original equations which governing the system dynamics.
Here is my code:
#!/usr/bin/python
import os, shutil, time, sys, math
from sys import *
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
from mpmath import *
mp.dps = 30
n=3 # number of levels
g = 3.0 # a parameter of the tissue
deltas = [0]*(n+2) # differentiation rates
Nk = [1.0]*(n+2) # number of cells prescribed to a level
maxMut = 10
N = 1024*Nk[0] # number of cells generated over the lifetime of the tissue
tlife = N
sumNk = 0
for k in range(len(Nk)-1):
sumNk += Nk[k]
for l in range(0,n):
deltas[l] = (1./g)**(n-1-l)
deltas[n]=2.0
deltas[n+1] = 0
print(deltas)
Nkmt = np.zeros((maxMut,n+1)).flatten() # I store the equations here
def Nt(t,Nkmt):
retVec= []
for k in range(len(Nkmt)):
if k%maxMut==0 and k>0 and k<n*maxMut: # wild type non term
retVec.append(deltas[int(floor(k/float(maxMut)))-1] * (Nkmt[k-maxMut]/Nk[int(floor(k/float(maxMut)))-1] - Nkmt[k]/Nk[int(floor(k/float(maxMut)))]+ mu * ( (0-Nkmt[k-maxMut])/Nk[int(floor(k/float(maxMut)))-1] - 2*(0-Nkmt[k])/Nk[int(floor(k/float(maxMut)))] ) )+ deltas[int(floor(k/float(maxMut)))] * mu * (0-Nkmt[k])/Nk[int(floor(k/float(maxMut)))])
elif k<maxMut and k>0: # 0th level with mutation
retVec.append(deltas[int(floor(k/float(maxMut)))] * mu * (Nkmt[k-1]-Nkmt[k])/Nk[int(floor(k/float(maxMut)))])
elif k==0: # 0th level wild type
retVec.append(deltas[int(floor(k/float(maxMut)))] * mu * (0-Nkmt[k])/Nk[int(floor(k/float(maxMut)))])
elif k>n*maxMut: # term level with mutation
retVec.append( ((deltas[int(floor(k/float(maxMut)))-1]/Nk[int(floor(k/float(maxMut)))-1])*Nkmt[k-maxMut])+ mu*( (deltas[int(floor(k/float(maxMut)))-1]/Nk[int(floor(k/float(maxMut)))-1])*Nkmt[k-maxMut-1])- mu*( (deltas[int(floor(k/float(maxMut)))-1]/Nk[int(floor(k/float(maxMut)))-1])*Nkmt[k-maxMut]))
elif k==n*maxMut: # term level wild type
retVec.append( ((deltas[int(floor(k/float(maxMut)))-1]/Nk[int(floor(k/float(maxMut)))-1])*Nkmt[k-maxMut])- mu*( (deltas[int(floor(k/float(maxMut)))-1]/Nk[int(floor(k/float(maxMut)))-1])*Nkmt[k-maxMut]))
else: # everything else
retVec.append(deltas[int(floor(k/float(maxMut)))-1] * (Nkmt[k-maxMut]/Nk[int(floor(k/float(maxMut)))-1] - Nkmt[k]/Nk[int(floor(k/float(maxMut)))]+ mu * ( (Nkmt[k-maxMut-1]-Nkmt[k-maxMut])/Nk[int(floor(k/float(maxMut)))-1] - 2*(Nkmt[k-1]-Nkmt[k])/Nk[int(floor(k/float(maxMut)))] ) )+ deltas[int(floor(k/float(maxMut)))] * mu * (Nkmt[k-1]-Nkmt[k])/Nk[int(floor(k/float(maxMut)))])
return retVec
Nkmt = Nkmt.tolist()
initCond = [0]*(len(Nkmt))
M_Vec = [0]*maxMut
P_vec=[0]*maxMut
for k in range(len(Nkmt)):
if k%maxMut==0 and k<(n+1)*maxMut:
initCond[k] = Nk[int(floor(k/float(maxMut)))]
else:
initCond[k] = 0.0
file = open("Pmuem_Master_1.txt",'w+')
print(Nkmt,initCond)
for mut in range(0,20): # here I tune the mutation rate
mu = (1e-6)*(10**(1./4))**mut
#mu = 0
lspace = int(tlife/1.0)
res = solve_ivp(Nt,(0,tlife),initCond,t_eval=np.linspace(0,tlife,lspace))# here I solve the system
for m in range(len(M_Vec)):
M_Vec[m]=0
for m in range(0,len(Nkmt)):
M_Vec[0]+=res.y[m].T[lspace-1]
for n_mut in range(1,maxMut):
if m%maxMut<n_mut:
M_Vec[n_mut] += res.y[m].T[lspace-1] # here I sum all the mutants cells which have at least m mutations
file.write(str(mu)+'\t')
for m in range(1,maxMut):
P_vec[m] = 1.0-exp(-(M_Vec[0]-M_Vec[m])/Nk[0]) # here I calculate the probabilities
file.write(str(P_vec[m] )+'\t')
file.write('\n')
#print(M_Vec[0])
print(M_Vec[0], sumNk,P_vec[1]/(1.0-exp(-2*N*mu/Nk[0])),(M_Vec[0]-M_Vec[1])/(2*N*mu),P_vec[1],)
file.close()
So the question again is, how can I add a "counter" with which at every iteration I can add a particular value to it which is a proportion of cells, which gained a new mutation, eg:
...
def Nt(t,Nkmt):
retVec= []
retVecE = []
eq = 0
for k in range(len(Nkmt)):
...
elif k<maxMut and k>0: # 0th level with mutation
#print("0th level with mutation",k,int(floor(k/float(maxMut))),k%maxMut,k-maxMut)
retVec.append(deltas[int(floor(k/float(maxMut)))] * mu * (Nkmt[k-1]-Nkmt[k])/Nk[int(floor(k/float(maxMut)))])
counter+= deltas[int(floor(k/float(maxMut)))] * mu * (Nkmt[k-1])/Nk[int(floor(k/float(maxMut)))]
...
...
Thank you in advance, I am also open to completely start the implementation from scratch if there is a better way to do this with python or c++ or mathematica or anything...
I could solve it
#!/usr/bin/python
import os, shutil, time, sys, math
from sys import *
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp, odeint
from mpmath import *
mp.dps = 30
N0 = 1
rm = 2
nt = 1
mg2 = 1
inf = 25
threshold = 0.0000000001
porq = 'p'
pkqk = 1
def p(g):
if porq == "p":
return float(pkqk)
else:
return 2.0/(q(g)*g)
def q(g):
if porq == "q":
return float(pkqk)
else:
return 2.0/(p(g)*g)
def ddpd(m,g,s):
return 1/(1 + q(g)*(m*s*(g - 1) - 1))
def mc(g, s):
return ceil(1/(s*(g - 1)))
def Dtr(g,k):
return k*(g-1)
def Dli(g,k,n):
return NpN0/g**(n-1) + Dtr(g,k)
def Pmul(g,k,n):
if(k==n):
return 2.0/g
else:
return 1.0
def Dadd(g,k,n):
if(k==n):
return 0
else:
return (1-p(g))/2.0
def P(mu,m,g,k,n):
if(k-1>=0):
return (mu**m/math.gamma(m + 1))*((Dli(g, k, n) + Dadd(g, k, n) - 1.5)**
m - (Dtr(g, k) + Dadd(g, k, n) - 1.5)**m)*(g**k)*Pmul(g, k, n)
else:
return (mu**m/math.gamma(m + 1))*(Dli(g, 0, n))**m
fileError = open("Error.txt",'w+')
file = open("Pmuem_Master_"+sys.argv[1]+"_"+str(1e-5)+".txt",'w+')
for gammas in range(int(sys.argv[2]),int(sys.argv[3])):
print(gammas)
n=int(sys.argv[1])
g = 2.0+gammas*0.5
deltas = [0]*(n+2)
Nk = [1e20 ]*(n+2)
maxMut = 12
N = 1e7*Nk[0]
tlife = N
NpN0 = N
sumNk = 0
for k in range(len(Nk)-1):
sumNk += Nk[k]
for l in range(0,n):
deltas[l] = (1./g)**(n-1-l)
deltas[n]=2.0
deltas[n+1] = 0
p=1
#íp=(2.0/g)
print(deltas)
Nkmt = np.zeros((maxMut,n+1)).flatten() # Pre-allocate matrix
Ekmt = np.zeros((maxMut,n+1)).flatten() # Pre-allocate matrix
def Nt(t,Nkmt):
retVec= []
retVecE = []
for k in range(len(Ekmt)):
# top level differentiation off
if k%maxMut==0 and k>0 and k<n*maxMut: # wild type non term
#print("wild type non term.",k,int(floor(k/float(maxMut))),k%maxMut,k-maxMut)
retVec.append(deltas[int(floor(k/float(maxMut)))-1] * (Nkmt[k-maxMut]/Nk[int(floor(k/float(maxMut)))-1] - Nkmt[k]/Nk[int(floor(k/float(maxMut)))]+ mu * ( (0-Nkmt[k-maxMut])/Nk[int(floor(k/float(maxMut)))-1] - 2*(0-Nkmt[k])/Nk[int(floor(k/float(maxMut)))] ) )+ deltas[int(floor(k/float(maxMut)))] * mu * (0-Nkmt[k])/Nk[int(floor(k/float(maxMut)))])
elif k<maxMut and k>0: # 0th level with mutation
#print("0th level with mutation",k,int(floor(k/float(maxMut))),k%maxMut,k-maxMut)
retVec.append(deltas[int(floor(k/float(maxMut)))] * mu * (Nkmt[k-1]-Nkmt[k])/Nk[int(floor(k/float(maxMut)))])
elif k==0: # 0th level wild type
#print("0th level wild type",k,int(floor(k/float(maxMut))),k%maxMut,k-maxMut)
retVec.append(deltas[int(floor(k/float(maxMut)))] * mu * (0-Nkmt[k])/Nk[int(floor(k/float(maxMut)))])
elif k>n*maxMut: # term level with mutation
#print("term level with mutation",k,int(floor(k/float(maxMut))),k%maxMut,k-maxMut)
retVec.append( ((deltas[int(floor(k/float(maxMut)))-1]/Nk[int(floor(k/float(maxMut)))-1])*Nkmt[k-maxMut])+ mu*( (deltas[int(floor(k/float(maxMut)))-1]/Nk[int(floor(k/float(maxMut)))-1])*Nkmt[k-maxMut-1])- mu*( (deltas[int(floor(k/float(maxMut)))-1]/Nk[int(floor(k/float(maxMut)))-1])*Nkmt[k-maxMut]))
elif k==n*maxMut: # term level wild type
#print("term level wild type",k,int(floor(k/float(maxMut))),k%maxMut,k-maxMut)
retVec.append( ((deltas[int(floor(k/float(maxMut)))-1]/Nk[int(floor(k/float(maxMut)))-1])*Nkmt[k-maxMut])- mu*( (deltas[int(floor(k/float(maxMut)))-1]/Nk[int(floor(k/float(maxMut)))-1])*Nkmt[k-maxMut]))
else: # everything else
#print("everything else",k,int(floor(k/float(maxMut))),k%maxMut,k-maxMut)
retVec.append(deltas[int(floor(k/float(maxMut)))-1] * (Nkmt[k-maxMut]/Nk[int(floor(k/float(maxMut)))-1] - Nkmt[k]/Nk[int(floor(k/float(maxMut)))]+ mu * ( (Nkmt[k-maxMut-1]-Nkmt[k-maxMut])/Nk[int(floor(k/float(maxMut)))-1] - 2*(Nkmt[k-1]-Nkmt[k])/Nk[int(floor(k/float(maxMut)))] ) )+ deltas[int(floor(k/float(maxMut)))] * mu * (Nkmt[k-1]-Nkmt[k])/Nk[int(floor(k/float(maxMut)))])
if k%maxMut==0 and k>0 and k<n*maxMut: # wild type non term
#print("wild type non term.",k,int(floor(k/float(maxMut))),k%maxMut,k-maxMut)
retVecE.append(0)
elif k<maxMut and k>0: # 0th level with mutation
#print("0th level with mutation",k,int(floor(k/float(maxMut))),k%maxMut,k-maxMut)
retVecE.append(deltas[int(floor(k/float(maxMut)))-1] * (mu * ( (Nkmt[k-maxMut-1])/Nk[int(floor(k/float(maxMut)))-1] - 2*(Nkmt[k-1])/Nk[int(floor(k/float(maxMut)))] ) )+ deltas[int(floor(k/float(maxMut)))] * mu * (Nkmt[k-1])/Nk[int(floor(k/float(maxMut)))])
elif k==0: # 0th level wild type
#print("0th level wild type",k,int(floor(k/float(maxMut))),k%maxMut,k-maxMut)
retVecE.append(0)
elif k>n*maxMut: # term level with mutation
#print("term level with mutation",k,int(floor(k/float(maxMut))),k%maxMut,k-maxMut)
retVecE.append(deltas[int(floor(k/float(maxMut)))-1] * (mu * ( (Nkmt[k-maxMut-1])/Nk[int(floor(k/float(maxMut)))-1] - 2*(Nkmt[k-1])/Nk[int(floor(k/float(maxMut)))] ) )+ deltas[int(floor(k/float(maxMut)))] * mu * (Nkmt[k-1])/Nk[int(floor(k/float(maxMut)))])
elif k==n*maxMut: # term level wild type
#print("term level wild type",k,int(floor(k/float(maxMut))),k%maxMut,k-maxMut)
retVecE.append(0)
else: # everything else
#print("everything else",k,int(floor(k/float(maxMut))),k%maxMut,k-maxMut)
retVecE.append(deltas[int(floor(k/float(maxMut)))-1] * (mu * ( (Nkmt[k-maxMut-1])/Nk[int(floor(k/float(maxMut)))-1] - 2*(Nkmt[k-1])/Nk[int(floor(k/float(maxMut)))] ) )+ deltas[int(floor(k/float(maxMut)))] * mu * (Nkmt[k-1])/Nk[int(floor(k/float(maxMut)))])
return retVec+retVecE
#Nkmt = np.append(Nkmt,0)
Nkmt = Nkmt.tolist()
Ekmt = Ekmt.tolist()
Nkmt = Nkmt+Ekmt
initCond = [0]*(len(Nkmt))
M_Vec = [0]*maxMut
P_vec=[0]*maxMut
for k in range(len(Nkmt)):
if k%maxMut==0 and k<=n*maxMut :
initCond[k] = Nk[int(floor(k/float(maxMut)))]
else:
initCond[k] = 0.0
print(len(Nkmt),len(initCond) )
E = np.zeros((n+1,maxMut))
ErrorSum = 0
for mut in range(0,1):
mu = 1e-5
#mu = 0
lspace = 10000
print(np.linspace(0,tlife,lspace))
res = solve_ivp(Nt,(0,tlife),initCond,t_eval=np.linspace(0,tlife,lspace), method = 'LSODA')
#res = odeint(Nt,initCond,np.linspace(0,tlife,lspace))
'''
#plotting results
plt.ylim(0.01, N*10)
plt.yscale('log')
#plt.plot(res.t, res.y[1].T+res.y[maxMut+1].T+res.y[2*maxMut+1].T,color='green', label='mut1')
for k in range(len(Nkmt)):
labello = str(int(floor(k/maxMut)))+str(k%maxMut)
plt.plot(res.t, res.y[k].T, label=labello)
randpos = int(floor(k/maxMut))*800
plt.text(res.t[-1-randpos], res.y[k].T[-1-randpos], labello)
plt.plot(res.t,2*res.t*mu,color='yellow', label='2*N*mu')
#plt.legend()
plt.plot(res.t, res.y[1].T+res.y[maxMut+1].T+res.y[2*maxMut+1].T+res.y[3*maxMut+1].T, label="mutossz")
plt.show()
print(res.y[1].T[-1],res.y[3].T[-1],res.y[5].T[-1])
'''
for m in range(len(M_Vec)):
M_Vec[m]=0
for m in range(0,len(Nkmt)):
M_Vec[0]+=res.y[m].T[lspace-1]
for n_mut in range(1,maxMut):
if m%maxMut>=n_mut and m >= (n+1)*maxMut:
if M_Vec[n_mut]>=0:
M_Vec[n_mut] += res.y[m].T[lspace-1]
else:
continue
file.write(str(g)+'\t')
for m in range(1,maxMut):
P_vec[m] = 1.0-exp(-(M_Vec[m])/Nk[0])
file.write(str(P_vec[m] )+'\t')
file.write('\n')
#print(M_Vec[0])
#print(M_Vec[0], sumNk,P_vec[1]/(1.0-exp(-2*N*mu/Nk[0])),(M_Vec[0]-M_Vec[1])/(2*N*mu),P_vec[1],)
file.close()
fileError.close()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.