pypharm 1.4.2__tar.gz → 1.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pypharm-1.4.2 → pypharm-1.5.0}/PKG-INFO +1 -1
- pypharm-1.5.0/PyPharm/constants.py +81 -0
- {pypharm-1.4.2 → pypharm-1.5.0}/PyPharm/models/compartment_models.py +5 -4
- pypharm-1.5.0/PyPharm/models/pbpk.py +672 -0
- {pypharm-1.4.2 → pypharm-1.5.0}/pypharm.egg-info/PKG-INFO +1 -1
- {pypharm-1.4.2 → pypharm-1.5.0}/pypharm.egg-info/requires.txt +2 -1
- {pypharm-1.4.2 → pypharm-1.5.0}/setup.py +3 -2
- pypharm-1.4.2/PyPharm/constants.py +0 -56
- pypharm-1.4.2/PyPharm/models/pbpk.py +0 -369
- {pypharm-1.4.2 → pypharm-1.5.0}/PyPharm/__init__.py +0 -0
- {pypharm-1.4.2 → pypharm-1.5.0}/PyPharm/algorithms/__init__.py +0 -0
- {pypharm-1.4.2 → pypharm-1.5.0}/PyPharm/algorithms/country_optimization.py +0 -0
- {pypharm-1.4.2 → pypharm-1.5.0}/PyPharm/algorithms/country_optimization_v2.py +0 -0
- {pypharm-1.4.2 → pypharm-1.5.0}/PyPharm/algorithms/country_optimization_v3.py +0 -0
- {pypharm-1.4.2 → pypharm-1.5.0}/PyPharm/algorithms/genetic_optimization.py +0 -0
- {pypharm-1.4.2 → pypharm-1.5.0}/PyPharm/algorithms/gold_digger_optimization.py +0 -0
- {pypharm-1.4.2 → pypharm-1.5.0}/PyPharm/models/__init__.py +0 -0
- {pypharm-1.4.2 → pypharm-1.5.0}/README.md +0 -0
- {pypharm-1.4.2 → pypharm-1.5.0}/pypharm.egg-info/SOURCES.txt +0 -0
- {pypharm-1.4.2 → pypharm-1.5.0}/pypharm.egg-info/dependency_links.txt +0 -0
- {pypharm-1.4.2 → pypharm-1.5.0}/pypharm.egg-info/top_level.txt +0 -0
- {pypharm-1.4.2 → pypharm-1.5.0}/setup.cfg +0 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
MODEL_CONST = {
|
|
2
|
+
'human':{
|
|
3
|
+
'adipose': {'V':143, 'Q': 60 * 3.7},
|
|
4
|
+
'bone': {'V':124, 'Q': 60 * 3.6} ,
|
|
5
|
+
'brain': {'V':20.7, 'Q': 60 * 10} ,
|
|
6
|
+
'gut': {'V':23.6, 'Q': 60 * 13} ,
|
|
7
|
+
'heart': {'V':3.8, 'Q': 60 * 2.14},
|
|
8
|
+
'kidney': {'V':4.4, 'Q': 60 * 15.7} ,
|
|
9
|
+
'liver': {'V':24.1, 'Q': 60 * 21} ,
|
|
10
|
+
'lung': {'V':16.7, 'Q': 60 * 71} ,
|
|
11
|
+
'muscle': {'V':429, 'Q': 60 * 10.7} ,
|
|
12
|
+
'pancreas': {'V':1.2, 'Q': 60 * 1.9} ,
|
|
13
|
+
'skin': {'V':111, 'Q': 60 * 4.3} ,
|
|
14
|
+
'spleen': {'V':2.7, 'Q': 60 * 1.1},
|
|
15
|
+
'stomach': {'V':2.2, 'Q': 60 * 0.56},
|
|
16
|
+
'teaster': {'V':0.51, 'Q': 60 * 0.04},
|
|
17
|
+
'arterial_blood': {'V':25.7} ,
|
|
18
|
+
'venous_blood': {'V':51.4}
|
|
19
|
+
},
|
|
20
|
+
'rat':{
|
|
21
|
+
'adipose': {'V':40, 'Q': 60 * 1.6},
|
|
22
|
+
'bone': {'V':53.2, 'Q': 60 * 10.12},
|
|
23
|
+
'brain': {'V':6.8, 'Q': 60 * 5.32} ,
|
|
24
|
+
'gut': {'V':40, 'Q': 60 * 52} ,
|
|
25
|
+
'heart': {'V':3.2, 'Q': 60 * 15.68},
|
|
26
|
+
'kidney': {'V':9.2, 'Q': 60 * 36.92},
|
|
27
|
+
'liver': {'V':41.2, 'Q': 60 * 80} ,
|
|
28
|
+
'lung': {'V':4, 'Q': 60 * 203.2} ,
|
|
29
|
+
'muscle': {'V':487.6, 'Q': 60 * 30} ,
|
|
30
|
+
'pancreas': {'V':5.2, 'Q': 60 * 4} ,
|
|
31
|
+
'skin': {'V':160, 'Q': 60 * 20} ,
|
|
32
|
+
'spleen': {'V':2.4, 'Q': 60 * 5} ,
|
|
33
|
+
'stomach': {'V':4.4, 'Q': 60 * 8.2} ,
|
|
34
|
+
'teaster': {'V':10, 'Q': 60 * 1.8} ,
|
|
35
|
+
'arterial_blood': {'V':22.4} ,
|
|
36
|
+
# 'arterial_blood': {'V':22.4, 'Q': 60 * 10.8} ,
|
|
37
|
+
'venous_blood': {'V':45.2}
|
|
38
|
+
},
|
|
39
|
+
'mouse': {
|
|
40
|
+
'adipose': {'V': 1000 * 1e-3 / 0.02, 'Q': 60 * 4e-5 * 1000 / 0.02},
|
|
41
|
+
'bone': {'V': 1000 * 1.58e-3 / 0.02, 'Q': 60 * 2.53e-4 * 1000 / 0.02},
|
|
42
|
+
'brain': {'V': 1000 * 1.7e-4 / 0.02, 'Q': 60 * 1.3e-4 * 1000 / 0.02},
|
|
43
|
+
'gut': {'V': 1000 * 6.27e-4 / 0.02, 'Q': 60 * 5e-4 * 1000 / 0.02},
|
|
44
|
+
'heart': {'V': 1000 * 9.5e-5 / 0.02, 'Q': 60 * 2.8e-4 * 1000 / 0.02},
|
|
45
|
+
'kidney': {'V': 1000 * 3.4e-4 / 0.02, 'Q': 60 * 1.3e-3 * 1000 / 0.02},
|
|
46
|
+
'liver': {'V': 1000 * 1e-3/ 0.02, 'Q' : 60 * 3.5e-4 * 1000 / 0.02},
|
|
47
|
+
'lung': {'V': 1000 * 1e-4 / 0.02, 'Q': 60 * 5.47e-3 * 1000 / 0.02},
|
|
48
|
+
'muscle': {'V': 1000 * 0.01e-1 / 0.02, 'Q': 60 * 9.1e-4 * 1000 / 0.02},
|
|
49
|
+
'pancreas': {'V': 1000 * 1.3e-4 / 0.02, 'Q': 60 * 5.2e-5 * 1000 / 0.02},
|
|
50
|
+
'skin': {'V': 1000 * 2.9e-3 / 0.02, 'Q': 60 * 4.1e-4 * 1000 / 0.02},
|
|
51
|
+
'spleen': {'V': 1000 * 1e-4 / 0.02, 'Q': 60 * 9e-5 * 1000 / 0.02},
|
|
52
|
+
'stomach': {'V': 1000 * 1.1e-4 / 0.02, 'Q': 60 * 1.1e-4 * 1000 / 0.02},
|
|
53
|
+
'teaster': {'V': 1, 'Q': 1},
|
|
54
|
+
'arterial_blood': {'V': 1000 * 2.28e-4 / 0.02},
|
|
55
|
+
# 'arterial_blood': {'V':22.4, 'Q': 60 * 10.8} ,
|
|
56
|
+
'venous_blood': {'V': 1000 * 5.25e-4 / 0.02}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
class ORGAN_NAMES:
|
|
61
|
+
|
|
62
|
+
LUNG = 'lung'
|
|
63
|
+
HEART = 'heart'
|
|
64
|
+
BRAIN = 'brain'
|
|
65
|
+
MUSCLE = 'muscle'
|
|
66
|
+
ADIPOSE = 'adipose'
|
|
67
|
+
SKIN = 'skin'
|
|
68
|
+
BONE = 'bone'
|
|
69
|
+
KIDNEY = 'kidney'
|
|
70
|
+
LIVER = 'liver'
|
|
71
|
+
GUT = 'gut'
|
|
72
|
+
SPLEEN = 'spleen'
|
|
73
|
+
STOMACH = 'stomach'
|
|
74
|
+
PANCREAS = 'pancreas'
|
|
75
|
+
VENOUS = 'venous_blood'
|
|
76
|
+
ARTERIAL = 'arterial_blood'
|
|
77
|
+
|
|
78
|
+
class ANIMALS:
|
|
79
|
+
HUMAN = 'human'
|
|
80
|
+
RAT = 'rat'
|
|
81
|
+
MOUSE = 'mouse'
|
|
@@ -4,9 +4,9 @@ import numpy as np
|
|
|
4
4
|
from scipy.integrate import solve_ivp, RK45
|
|
5
5
|
from scipy.integrate import simps
|
|
6
6
|
from scipy.optimize import minimize
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
from
|
|
7
|
+
from PyPharm.algorithms.country_optimization import CountriesAlgorithm
|
|
8
|
+
from PyPharm.algorithms.country_optimization_v2 import CountriesAlgorithm_v2
|
|
9
|
+
from PyPharm.algorithms.genetic_optimization import GeneticAlgorithm
|
|
10
10
|
from numba import njit
|
|
11
11
|
import matplotlib.pyplot as plt
|
|
12
12
|
|
|
@@ -127,7 +127,8 @@ class BaseCompartmentModel:
|
|
|
127
127
|
t_span=ts,
|
|
128
128
|
y0=c0,
|
|
129
129
|
max_step=max_step,
|
|
130
|
-
t_eval=t_eval
|
|
130
|
+
t_eval=t_eval,
|
|
131
|
+
method='LSODA'
|
|
131
132
|
)
|
|
132
133
|
return self.last_result
|
|
133
134
|
|
|
@@ -0,0 +1,672 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
from numbalsoda import lsoda_sig, lsoda
|
|
3
|
+
import numpy as np
|
|
4
|
+
from scipy.integrate import solve_ivp, LSODA
|
|
5
|
+
from scipy.optimize import minimize
|
|
6
|
+
from PyPharm.algorithms.country_optimization import CountriesAlgorithm
|
|
7
|
+
from PyPharm.algorithms.country_optimization_v2 import CountriesAlgorithm_v2
|
|
8
|
+
from PyPharm.algorithms.genetic_optimization import GeneticAlgorithm
|
|
9
|
+
from PyPharm.constants import MODEL_CONST, ORGAN_NAMES, ANIMALS
|
|
10
|
+
from numba import njit, types, cfunc
|
|
11
|
+
from numba.typed import Dict
|
|
12
|
+
import matplotlib.pyplot as plt
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class PBPKmod:
|
|
17
|
+
|
|
18
|
+
_organs = ['lung', 'heart', 'brain', 'muscle', 'adipose', 'skin', 'bone', 'kidney',
|
|
19
|
+
'liver', 'gut', 'spleen', 'stomach', 'pancreas', 'venous_blood', 'arterial_blood']
|
|
20
|
+
_cl_organs = ['kidney', 'liver']
|
|
21
|
+
|
|
22
|
+
def __init__(self, know_k=None, know_cl=None, numba_option=False, lsoda_option=False):
|
|
23
|
+
|
|
24
|
+
self.know_k = know_k if know_k is not None else {}
|
|
25
|
+
self.know_cl = know_cl if know_cl is not None else {}
|
|
26
|
+
self._optim = False
|
|
27
|
+
self.numba_option = numba_option
|
|
28
|
+
self.lsoda_option = lsoda_option
|
|
29
|
+
if numba_option or lsoda_option:
|
|
30
|
+
self.cnst_v_dict = {}
|
|
31
|
+
for key in MODEL_CONST:
|
|
32
|
+
cnst_v = Dict.empty(
|
|
33
|
+
key_type=types.unicode_type,
|
|
34
|
+
value_type=types.float64
|
|
35
|
+
)
|
|
36
|
+
for k, v in MODEL_CONST[key].items():
|
|
37
|
+
cnst_v[k] = v['V']
|
|
38
|
+
self.cnst_v_dict[key] = cnst_v
|
|
39
|
+
self.cnst_q_dict = {}
|
|
40
|
+
for key in MODEL_CONST:
|
|
41
|
+
cnst_q = Dict.empty(
|
|
42
|
+
key_type=types.unicode_type,
|
|
43
|
+
value_type=types.float64
|
|
44
|
+
)
|
|
45
|
+
for k, v in MODEL_CONST[key].items():
|
|
46
|
+
if v.get('Q'):
|
|
47
|
+
cnst_q[k] = v['Q']
|
|
48
|
+
self.cnst_q_dict[key] = cnst_q
|
|
49
|
+
|
|
50
|
+
def load_optimization_data(self, time_exp, dict_c_exp, start_c_in_venous, animal=ANIMALS.MOUSE):
|
|
51
|
+
self.time_exp = time_exp
|
|
52
|
+
self.dict_c_exp = dict_c_exp
|
|
53
|
+
self.start_c_in_venous = start_c_in_venous
|
|
54
|
+
self.animal = animal
|
|
55
|
+
|
|
56
|
+
def _get_sol_difurs(self):
|
|
57
|
+
return self(max(self.time_exp), self.start_c_in_venous, self.animal)
|
|
58
|
+
|
|
59
|
+
def fitness(self, k_cl):
|
|
60
|
+
|
|
61
|
+
self.k_cl = k_cl
|
|
62
|
+
|
|
63
|
+
sol_difurs = self._get_sol_difurs()
|
|
64
|
+
# Список для хранения результатов
|
|
65
|
+
present_organs_indices = []
|
|
66
|
+
|
|
67
|
+
# Проверяем, какие ключи из 'organs' есть в 'dict_n'
|
|
68
|
+
for organ in self._organs:
|
|
69
|
+
if organ in self.dict_c_exp:
|
|
70
|
+
index = self._organs.index(organ) # Получаем индекс органа в списке organs
|
|
71
|
+
present_organs_indices.append((organ, index))
|
|
72
|
+
|
|
73
|
+
rez_err = 0
|
|
74
|
+
for organ, index in present_organs_indices:
|
|
75
|
+
mean_y = sum(sol_difurs[index]) / len(sol_difurs[index])
|
|
76
|
+
a = [(sol_difurs[index][self.time_exp[i]] - self.dict_c_exp[organ][i]) ** 2 for i in range(len(self.dict_c_exp[organ]))]
|
|
77
|
+
a = sum(a)
|
|
78
|
+
b = [(mean_y - self.dict_c_exp[organ][i]) ** 2 for i in
|
|
79
|
+
range(len(self.dict_c_exp[organ]))]
|
|
80
|
+
b = sum(b)
|
|
81
|
+
rez_err += a / b
|
|
82
|
+
# rez_err += sum([abs(sol_difurs[:, index][self.time_exp[i]] - self.dict_c_exp[organ][i]) for i in
|
|
83
|
+
# range(len(self.dict_c_exp[organ]))])
|
|
84
|
+
|
|
85
|
+
return rez_err
|
|
86
|
+
def _get_result(self, fun, t, max_time, K_CL, animal=ANIMALS.MOUSE):
|
|
87
|
+
if not self.lsoda_option:
|
|
88
|
+
return solve_ivp(
|
|
89
|
+
fun=fun,
|
|
90
|
+
t_span=[0, max_time],
|
|
91
|
+
y0=self.y0,
|
|
92
|
+
t_eval=t,
|
|
93
|
+
method=LSODA,
|
|
94
|
+
)
|
|
95
|
+
else:
|
|
96
|
+
return lsoda(
|
|
97
|
+
funcptr=fun,
|
|
98
|
+
u0=np.array(self.y0, dtype=np.float64),
|
|
99
|
+
t_eval=np.array(t, dtype=np.float64),
|
|
100
|
+
data=np.array(K_CL, dtype=np.float64),
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
def _prepare_result(self, t, res):
|
|
104
|
+
if not self.lsoda_option:
|
|
105
|
+
self._res = res.y
|
|
106
|
+
else:
|
|
107
|
+
res = res.T
|
|
108
|
+
self._res = res
|
|
109
|
+
self.last_result = {
|
|
110
|
+
't': t * 60
|
|
111
|
+
}
|
|
112
|
+
if not self.lsoda_option:
|
|
113
|
+
for organ in self._organs:
|
|
114
|
+
index = self._organs.index(organ)
|
|
115
|
+
self.last_result[organ] = res.y[index]
|
|
116
|
+
else:
|
|
117
|
+
for organ in self._organs:
|
|
118
|
+
index = self._organs.index(organ)
|
|
119
|
+
self.last_result[organ] = res[index]
|
|
120
|
+
|
|
121
|
+
def __call__(self, max_time, start_c_in_venous, animal=ANIMALS.MOUSE, step=1.0):
|
|
122
|
+
self.y0 = [0 for _ in range(15)] # всего в модели 15 органов
|
|
123
|
+
self.y0[-2] = start_c_in_venous
|
|
124
|
+
t = np.linspace(0, max_time, max_time + 1 if self._optim else int(1 / step * max_time) + 1) / 60
|
|
125
|
+
|
|
126
|
+
if not hasattr(self, 'k_cl'):
|
|
127
|
+
self.k_cl = []
|
|
128
|
+
|
|
129
|
+
full_k = []
|
|
130
|
+
i = 0
|
|
131
|
+
for name in self._organs:
|
|
132
|
+
know_k = self.know_k.get(name)
|
|
133
|
+
if know_k is not None:
|
|
134
|
+
full_k.append(know_k)
|
|
135
|
+
else:
|
|
136
|
+
full_k.append(self.k_cl[i])
|
|
137
|
+
i += 1
|
|
138
|
+
full_cl = []
|
|
139
|
+
|
|
140
|
+
for name in self._cl_organs:
|
|
141
|
+
know_k = self.know_cl.get(name)
|
|
142
|
+
if know_k is not None:
|
|
143
|
+
full_cl.append(know_k)
|
|
144
|
+
else:
|
|
145
|
+
full_cl.append(self.k_cl[i])
|
|
146
|
+
i += 1
|
|
147
|
+
if not self.numba_option and not self.lsoda_option:
|
|
148
|
+
res = self._get_result(
|
|
149
|
+
fun=lambda time, y: self.fullPBPKmodel(y, time, [*full_k, *full_cl], animal),
|
|
150
|
+
t=t,
|
|
151
|
+
max_time=max_time,
|
|
152
|
+
K_CL=[*full_k, *full_cl],
|
|
153
|
+
animal=animal
|
|
154
|
+
)
|
|
155
|
+
elif self.lsoda_option:
|
|
156
|
+
cnst_v = self.cnst_v_dict[animal]
|
|
157
|
+
cnst_q = self.cnst_q_dict[animal]
|
|
158
|
+
res, success = self._get_result(
|
|
159
|
+
fun=self.lsoda_fullPBPK_for_optimization.address,
|
|
160
|
+
t=t,
|
|
161
|
+
max_time=max_time,
|
|
162
|
+
K_CL=[*full_k, *full_cl, *[cnst_q[key] for key in cnst_q.keys()], *[cnst_v[key] for key in cnst_v.keys()]],
|
|
163
|
+
animal=animal
|
|
164
|
+
)
|
|
165
|
+
else:
|
|
166
|
+
k_cl = np.array([*full_k, *full_cl])
|
|
167
|
+
cnst_v = self.cnst_v_dict[animal]
|
|
168
|
+
cnst_q = self.cnst_q_dict[animal]
|
|
169
|
+
function = lambda time, c: self.numba_fullPBPK_for_optimization(
|
|
170
|
+
y=c,
|
|
171
|
+
t=time,
|
|
172
|
+
K_CL=k_cl.astype(np.float64),
|
|
173
|
+
cnst_q=cnst_q,
|
|
174
|
+
cnst_v=cnst_v
|
|
175
|
+
)
|
|
176
|
+
res = self._get_result(
|
|
177
|
+
fun=function,
|
|
178
|
+
t=t,
|
|
179
|
+
max_time=max_time,
|
|
180
|
+
K_CL=[*full_k, *full_cl],
|
|
181
|
+
animal=animal
|
|
182
|
+
)
|
|
183
|
+
self._prepare_result(t, res)
|
|
184
|
+
return self._res
|
|
185
|
+
|
|
186
|
+
def plot_last_result(self, organ_names=[], left=None, right=None, user_names={}, theoretic_data={}, y_lims={}):
|
|
187
|
+
if hasattr(self, 'last_result'):
|
|
188
|
+
for name in organ_names:
|
|
189
|
+
if theoretic_data.get(name):
|
|
190
|
+
plt.plot(theoretic_data[name]['x'], theoretic_data[name]['y'], '*r')
|
|
191
|
+
plt.plot(
|
|
192
|
+
self.last_result['t'],
|
|
193
|
+
self.last_result.get(name),
|
|
194
|
+
)
|
|
195
|
+
plt.title(user_names.get(name, name))
|
|
196
|
+
plt.xlim(left=left, right=right)
|
|
197
|
+
if y_lims.get(name):
|
|
198
|
+
plt.ylim(y_lims.get(name))
|
|
199
|
+
plt.grid()
|
|
200
|
+
plt.show()
|
|
201
|
+
|
|
202
|
+
def optimize(self, method=None, user_method=None, method_is_func=True,
|
|
203
|
+
optimization_func_name='__call__', **kwargs):
|
|
204
|
+
"""
|
|
205
|
+
Функция оптимизации модели
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
method: Метод оптимизации, любой доступный minimize + 'country_optimization' и 'country_optimization_v2'
|
|
209
|
+
max_step: Максимальный шаг при решении СДУ
|
|
210
|
+
**kwargs: Дополнительные именованные аргументы
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
None
|
|
214
|
+
"""
|
|
215
|
+
self._optim = True
|
|
216
|
+
f = lambda x: self.fitness(x)
|
|
217
|
+
if user_method is not None:
|
|
218
|
+
if method_is_func:
|
|
219
|
+
x = user_method(f, **kwargs)
|
|
220
|
+
else:
|
|
221
|
+
optimization_obj = user_method(f, **kwargs)
|
|
222
|
+
x = getattr(optimization_obj, optimization_func_name)()
|
|
223
|
+
else:
|
|
224
|
+
if method == 'country_optimization':
|
|
225
|
+
CA = CountriesAlgorithm(
|
|
226
|
+
f=f,
|
|
227
|
+
memory_list=getattr(self, 'memory', None),
|
|
228
|
+
**kwargs
|
|
229
|
+
)
|
|
230
|
+
CA.start()
|
|
231
|
+
x = CA.countries[0].population[0].x
|
|
232
|
+
elif method == 'country_optimization_v2':
|
|
233
|
+
CA = CountriesAlgorithm_v2(
|
|
234
|
+
f=f,
|
|
235
|
+
**kwargs
|
|
236
|
+
)
|
|
237
|
+
CA.start()
|
|
238
|
+
x = CA.countries[0].population[0].x
|
|
239
|
+
elif method == 'GA':
|
|
240
|
+
CA = GeneticAlgorithm(
|
|
241
|
+
f=f,
|
|
242
|
+
**kwargs
|
|
243
|
+
)
|
|
244
|
+
x = CA.start()
|
|
245
|
+
else:
|
|
246
|
+
res = minimize(
|
|
247
|
+
fun=f,
|
|
248
|
+
method=method,
|
|
249
|
+
**kwargs
|
|
250
|
+
)
|
|
251
|
+
x = res.x
|
|
252
|
+
self._optim = False
|
|
253
|
+
return x
|
|
254
|
+
|
|
255
|
+
def update_know_params(self, k_cl=None):
|
|
256
|
+
if k_cl:
|
|
257
|
+
i = 0
|
|
258
|
+
for name in self._organs:
|
|
259
|
+
know_k = self.know_k.get(name)
|
|
260
|
+
if know_k is None:
|
|
261
|
+
self.know_k[name] = k_cl[i]
|
|
262
|
+
i += 1
|
|
263
|
+
for name in self._cl_organs:
|
|
264
|
+
know_cl = self.know_cl.get(name)
|
|
265
|
+
if know_cl is None:
|
|
266
|
+
self.know_cl[name] = k_cl[i]
|
|
267
|
+
i += 1
|
|
268
|
+
|
|
269
|
+
def get_unknown_params(self):
|
|
270
|
+
result = []
|
|
271
|
+
for name in self._organs:
|
|
272
|
+
know_k = self.know_k.get(name)
|
|
273
|
+
if know_k is None:
|
|
274
|
+
result.append(f"k_{name}")
|
|
275
|
+
for name in self._cl_organs:
|
|
276
|
+
know_cl = self.know_cl.get(name)
|
|
277
|
+
if know_cl is None:
|
|
278
|
+
result.append(f"cl_{name}")
|
|
279
|
+
return result
|
|
280
|
+
|
|
281
|
+
def fullPBPKmodel(self, y, t, K_CL, animal=ANIMALS.MOUSE): # V, Q, K, CL):
|
|
282
|
+
# 15 органов
|
|
283
|
+
cnst = MODEL_CONST[animal]
|
|
284
|
+
C_lung, C_heart, C_brain, C_muscle, C_fat, C_skin, C_bone, \
|
|
285
|
+
C_kidney, C_liver, C_gut, C_spleen, C_stomach, C_pancreas, C_V, C_A = y
|
|
286
|
+
|
|
287
|
+
K_lung, K_heart, K_brain, K_muscle, K_fat, K_skin, K_bone, \
|
|
288
|
+
K_kidney, K_liver, K_gut, K_spleen, K_stomach, K_pancreas, K_liver_cl, K_kidney_cl = K_CL[:15]
|
|
289
|
+
CL_kidney, CL_liver = K_CL[15:]
|
|
290
|
+
|
|
291
|
+
dC_lung_dt = cnst['lung']['Q'] * (C_V - C_lung / K_lung) / cnst['lung']['V']
|
|
292
|
+
dC_heart_dt = cnst['heart']['Q'] * (C_A - C_heart / K_heart) / cnst['heart']['V']
|
|
293
|
+
dC_brain_dt = cnst['brain']['Q'] * (C_A - C_brain / K_brain) / cnst['brain']['V']
|
|
294
|
+
dC_muscle_dt = cnst['muscle']['Q'] * (C_A - C_muscle / K_muscle) / cnst['muscle']['V']
|
|
295
|
+
dC_fat_dt = cnst['adipose']['Q'] * (C_A - C_fat / K_fat) / cnst['adipose']['V']
|
|
296
|
+
dC_skin_dt = cnst['skin']['Q'] * (C_A - C_skin / K_skin) / cnst['skin']['V']
|
|
297
|
+
dC_bone_dt = cnst['bone']['Q'] * (C_A - C_bone / K_bone) / cnst['bone']['V']
|
|
298
|
+
# Kidney V(Kidney)*dC(Kidney)/dt = Q(Kidney)*C(A)-Q(Kidney)*CV(Kidney)-CL(Kidney,int)*CV(Kidney,int)?
|
|
299
|
+
dC_kidney_dt = (cnst['kidney']['Q'] * (C_A - C_kidney / K_kidney) - CL_kidney * C_kidney / K_kidney_cl) / \
|
|
300
|
+
cnst['kidney']['V'] # ???
|
|
301
|
+
|
|
302
|
+
# Liver V(Liver)*dC(Liver)/dt = (Q(Liver)-Q(Spleen)-Q(Gut)-Q(Pancreas)-Q(Stomach))*C(A) + Q(Spleen)*CV(Spleen) +
|
|
303
|
+
# + Q(Gut)*CV(Gut) + Q(Pancreas)*CV(Pancreas) + Q(Stomach)*CV(Stomach) -
|
|
304
|
+
# - Q(Liver)*CV(Liver) - CL(Liver,int)*CV(Liver,int)? # тут скорее всего нужно вычитать потоки из друг друга дополнительно по крови что бы сохранить массовый баланс
|
|
305
|
+
Q_liver_in_from_art = cnst['liver']['Q'] - cnst['gut']['Q'] - cnst['spleen']['Q'] - \
|
|
306
|
+
cnst['pancreas']['Q'] - cnst['stomach']['Q']
|
|
307
|
+
dC_liver_dt = (
|
|
308
|
+
Q_liver_in_from_art * C_A + cnst['gut']['Q'] * C_gut / K_gut
|
|
309
|
+
+ cnst['spleen']['Q'] * C_spleen / K_spleen
|
|
310
|
+
+ cnst['stomach']['Q'] * C_stomach / K_stomach
|
|
311
|
+
+ cnst['pancreas']['Q'] * C_pancreas / K_pancreas
|
|
312
|
+
- cnst['liver']['Q'] * C_liver / K_liver
|
|
313
|
+
- CL_liver * C_liver / K_liver_cl # ???
|
|
314
|
+
) / cnst['liver']['V']
|
|
315
|
+
|
|
316
|
+
dC_gut_dt = cnst['gut']['Q'] * (C_A - C_gut / K_gut) / cnst['gut']['V']
|
|
317
|
+
dC_spleen_dt = cnst['spleen']['Q'] * (C_A - C_spleen / K_spleen) / cnst['spleen']['V']
|
|
318
|
+
dC_stomach_dt = cnst['stomach']['Q'] * (C_A - C_stomach / K_stomach) / cnst['stomach']['V']
|
|
319
|
+
dC_pancreas_dt = cnst['pancreas']['Q'] * (C_A - C_pancreas / K_pancreas) / cnst['pancreas']['V']
|
|
320
|
+
|
|
321
|
+
dC_venouse_dt = (
|
|
322
|
+
cnst['heart']['Q'] * C_heart / K_heart
|
|
323
|
+
+ cnst['brain']['Q'] * C_brain / K_brain
|
|
324
|
+
+ cnst['muscle']['Q'] * C_muscle / K_muscle
|
|
325
|
+
+ cnst['skin']['Q'] * C_skin / K_skin
|
|
326
|
+
+ cnst['adipose']['Q'] * C_fat / K_fat
|
|
327
|
+
+ cnst['bone']['Q'] * C_bone / K_bone
|
|
328
|
+
+ cnst['kidney']['Q'] * C_kidney / K_kidney
|
|
329
|
+
+ cnst['liver']['Q'] * C_liver / K_liver
|
|
330
|
+
- cnst['lung']['Q'] * C_V
|
|
331
|
+
) / cnst['venous_blood']['V']
|
|
332
|
+
|
|
333
|
+
dC_arterial_dt = cnst['lung']['Q'] * (C_lung / K_lung - C_A) / cnst['arterial_blood']['V']
|
|
334
|
+
|
|
335
|
+
y_new = [dC_lung_dt, dC_heart_dt, dC_brain_dt, dC_muscle_dt, dC_fat_dt, dC_skin_dt, dC_bone_dt, \
|
|
336
|
+
dC_kidney_dt, dC_liver_dt, dC_gut_dt, dC_spleen_dt, dC_stomach_dt, dC_pancreas_dt, dC_venouse_dt,
|
|
337
|
+
dC_arterial_dt]
|
|
338
|
+
return y_new
|
|
339
|
+
|
|
340
|
+
@staticmethod
|
|
341
|
+
@njit
|
|
342
|
+
def numba_fullPBPK_for_optimization(y, t, K_CL, cnst_q, cnst_v):
|
|
343
|
+
C_lung, C_heart, C_brain, C_muscle, C_fat, C_skin, C_bone, \
|
|
344
|
+
C_kidney, C_liver, C_gut, C_spleen, C_stomach, C_pancreas, C_V, C_A = y
|
|
345
|
+
|
|
346
|
+
K_lung, K_heart, K_brain, K_muscle, K_fat, K_skin, K_bone, \
|
|
347
|
+
K_kidney, K_liver, K_gut, K_spleen, K_stomach, K_pancreas, K_liver_cl, K_kidney_cl = K_CL[:15]
|
|
348
|
+
CL_kidney, CL_liver = K_CL[15:]
|
|
349
|
+
|
|
350
|
+
dC_lung_dt = cnst_q['lung'] * (C_V - C_lung / K_lung) / cnst_v['lung']
|
|
351
|
+
dC_heart_dt = cnst_q['heart'] * (C_A - C_heart / K_heart) / cnst_v['heart']
|
|
352
|
+
dC_brain_dt = cnst_q['brain'] * (C_A - C_brain / K_brain) / cnst_v['brain']
|
|
353
|
+
dC_muscle_dt = cnst_q['muscle'] * (C_A - C_muscle / K_muscle) / cnst_v['muscle']
|
|
354
|
+
dC_fat_dt = cnst_q['adipose'] * (C_A - C_fat / K_fat) / cnst_v['adipose']
|
|
355
|
+
dC_skin_dt = cnst_q['skin'] * (C_A - C_skin / K_skin) / cnst_v['skin']
|
|
356
|
+
dC_bone_dt = cnst_q['bone'] * (C_A - C_bone / K_bone) / cnst_v['bone']
|
|
357
|
+
# Kidney V(Kidney)*dC(Kidney)/dt = Q(Kidney)*C(A)-Q(Kidney)*CV(Kidney)-CL(Kidney,int)*CV(Kidney,int)?
|
|
358
|
+
dC_kidney_dt = (cnst_q['kidney'] * (C_A - C_kidney / K_kidney) - CL_kidney * C_kidney / K_kidney_cl) / \
|
|
359
|
+
cnst_v['kidney'] # ???
|
|
360
|
+
|
|
361
|
+
# Liver V(Liver)*dC(Liver)/dt = (Q(Liver)-Q(Spleen)-Q(Gut)-Q(Pancreas)-Q(Stomach))*C(A) + Q(Spleen)*CV(Spleen) +
|
|
362
|
+
# + Q(Gut)*CV(Gut) + Q(Pancreas)*CV(Pancreas) + Q(Stomach)*CV(Stomach) -
|
|
363
|
+
# - Q(Liver)*CV(Liver) - CL(Liver,int)*CV(Liver,int)? # тут скорее всего нужно вычитать потоки из друг друга дополнительно по крови что бы сохранить массовый баланс
|
|
364
|
+
Q_liver_in_from_art = cnst_q['liver'] - cnst_q['gut'] - cnst_q['spleen'] - \
|
|
365
|
+
cnst_q['pancreas'] - cnst_q['stomach']
|
|
366
|
+
dC_liver_dt = (
|
|
367
|
+
Q_liver_in_from_art * C_A + cnst_q['gut'] * C_gut / K_gut
|
|
368
|
+
+ cnst_q['spleen'] * C_spleen / K_spleen
|
|
369
|
+
+ cnst_q['stomach'] * C_stomach / K_stomach
|
|
370
|
+
+ cnst_q['pancreas'] * C_pancreas / K_pancreas
|
|
371
|
+
- cnst_q['liver'] * C_liver / K_liver
|
|
372
|
+
- CL_liver * C_liver / K_liver_cl # ???
|
|
373
|
+
) / cnst_v['liver']
|
|
374
|
+
|
|
375
|
+
dC_gut_dt = cnst_q['gut'] * (C_A - C_gut / K_gut) / cnst_v['gut']
|
|
376
|
+
dC_spleen_dt = cnst_q['spleen'] * (C_A - C_spleen / K_spleen) / cnst_v['spleen']
|
|
377
|
+
dC_stomach_dt = cnst_q['stomach'] * (C_A - C_stomach / K_stomach) / cnst_v['stomach']
|
|
378
|
+
dC_pancreas_dt = cnst_q['pancreas'] * (C_A - C_pancreas / K_pancreas) / cnst_v['pancreas']
|
|
379
|
+
|
|
380
|
+
dC_venouse_dt = (
|
|
381
|
+
cnst_q['heart'] * C_heart / K_heart
|
|
382
|
+
+ cnst_q['brain'] * C_brain / K_brain
|
|
383
|
+
+ cnst_q['muscle'] * C_muscle / K_muscle
|
|
384
|
+
+ cnst_q['skin'] * C_skin / K_skin
|
|
385
|
+
+ cnst_q['adipose'] * C_fat / K_fat
|
|
386
|
+
+ cnst_q['bone'] * C_bone / K_bone
|
|
387
|
+
+ cnst_q['kidney'] * C_kidney / K_kidney
|
|
388
|
+
+ cnst_q['liver'] * C_liver / K_liver
|
|
389
|
+
- cnst_q['lung'] * C_V
|
|
390
|
+
) / cnst_v['venous_blood']
|
|
391
|
+
|
|
392
|
+
dC_arterial_dt = cnst_q['lung'] * (C_lung / K_lung - C_A) / cnst_v['arterial_blood']
|
|
393
|
+
|
|
394
|
+
y_new = np.array([dC_lung_dt, dC_heart_dt, dC_brain_dt, dC_muscle_dt, dC_fat_dt, dC_skin_dt, dC_bone_dt, \
|
|
395
|
+
dC_kidney_dt, dC_liver_dt, dC_gut_dt, dC_spleen_dt, dC_stomach_dt, dC_pancreas_dt, dC_venouse_dt,
|
|
396
|
+
dC_arterial_dt]).astype(np.float64)
|
|
397
|
+
return y_new
|
|
398
|
+
|
|
399
|
+
@staticmethod
|
|
400
|
+
@cfunc(lsoda_sig)
|
|
401
|
+
def lsoda_fullPBPK_for_optimization(t, y, y_new, data):
|
|
402
|
+
|
|
403
|
+
C_lung = y[0]
|
|
404
|
+
C_heart = y[1]
|
|
405
|
+
C_brain = y[2]
|
|
406
|
+
C_muscle = y[3]
|
|
407
|
+
C_fat = y[4]
|
|
408
|
+
C_skin = y[5]
|
|
409
|
+
C_bone = y[6]
|
|
410
|
+
C_kidney = y[7]
|
|
411
|
+
C_liver = y[8]
|
|
412
|
+
C_gut = y[9]
|
|
413
|
+
C_spleen = y[10]
|
|
414
|
+
C_stomach = y[11]
|
|
415
|
+
C_pancreas = y[12]
|
|
416
|
+
C_V = y[13]
|
|
417
|
+
C_A = y[14]
|
|
418
|
+
|
|
419
|
+
K_lung = data[0]
|
|
420
|
+
K_heart = data[1]
|
|
421
|
+
K_brain = data[2]
|
|
422
|
+
K_muscle = data[3]
|
|
423
|
+
K_fat = data[4]
|
|
424
|
+
K_skin = data[5]
|
|
425
|
+
K_bone = data[6]
|
|
426
|
+
K_kidney = data[7]
|
|
427
|
+
K_liver = data[8]
|
|
428
|
+
K_gut = data[9]
|
|
429
|
+
K_spleen = data[10]
|
|
430
|
+
K_stomach = data[11]
|
|
431
|
+
K_pancreas = data[12]
|
|
432
|
+
K_liver_cl = data[13]
|
|
433
|
+
K_kidney_cl = data[14]
|
|
434
|
+
CL_kidney = data[15]
|
|
435
|
+
CL_liver = data[16]
|
|
436
|
+
|
|
437
|
+
cnst_q_adipose = data[17]
|
|
438
|
+
cnst_q_bone = data[18]
|
|
439
|
+
cnst_q_brain = data[19]
|
|
440
|
+
cnst_q_gut = data[20]
|
|
441
|
+
cnst_q_heart = data[21]
|
|
442
|
+
cnst_q_kidney = data[22]
|
|
443
|
+
cnst_q_liver = data[23]
|
|
444
|
+
cnst_q_lung = data[24]
|
|
445
|
+
cnst_q_muscle = data[25]
|
|
446
|
+
cnst_q_pancreas = data[26]
|
|
447
|
+
cnst_q_skin = data[27]
|
|
448
|
+
cnst_q_spleen = data[28]
|
|
449
|
+
cnst_q_stomach = data[29]
|
|
450
|
+
cnst_q_teaster = data[30]
|
|
451
|
+
|
|
452
|
+
cnst_v_adipose = data[31]
|
|
453
|
+
cnst_v_bone = data[32]
|
|
454
|
+
cnst_v_brain = data[33]
|
|
455
|
+
cnst_v_gut = data[34]
|
|
456
|
+
cnst_v_heart = data[35]
|
|
457
|
+
cnst_v_kidney = data[36]
|
|
458
|
+
cnst_v_liver = data[37]
|
|
459
|
+
cnst_v_lung = data[38]
|
|
460
|
+
cnst_v_muscle = data[39]
|
|
461
|
+
cnst_v_pancreas = data[40]
|
|
462
|
+
cnst_v_skin = data[41]
|
|
463
|
+
cnst_v_spleen = data[42]
|
|
464
|
+
cnst_v_stomach = data[43]
|
|
465
|
+
cnst_v_teaster = data[44]
|
|
466
|
+
cnst_v_arterial_blood = data[45]
|
|
467
|
+
cnst_v_venous_blood = data[46]
|
|
468
|
+
|
|
469
|
+
dC_lung_dt = cnst_q_lung * (C_V - C_lung / K_lung) / cnst_v_lung
|
|
470
|
+
dC_heart_dt = cnst_q_heart * (C_A - C_heart / K_heart) / cnst_v_heart
|
|
471
|
+
dC_brain_dt = cnst_q_brain * (C_A - C_brain / K_brain) / cnst_v_brain
|
|
472
|
+
dC_muscle_dt = cnst_q_muscle * (C_A - C_muscle / K_muscle) / cnst_v_muscle
|
|
473
|
+
dC_fat_dt = cnst_q_adipose * (C_A - C_fat / K_fat) / cnst_v_adipose
|
|
474
|
+
dC_skin_dt = cnst_q_skin * (C_A - C_skin / K_skin) / cnst_v_skin
|
|
475
|
+
dC_bone_dt = cnst_q_bone * (C_A - C_bone / K_bone) / cnst_v_bone
|
|
476
|
+
# Kidney V(Kidney)*dC(Kidney)/dt = Q(Kidney)*C(A)-Q(Kidney)*CV(Kidney)-CL(Kidney,int)*CV(Kidney,int)?
|
|
477
|
+
dC_kidney_dt = (cnst_q_kidney * (C_A - C_kidney / K_kidney) - CL_kidney * C_kidney / K_kidney_cl) / \
|
|
478
|
+
cnst_v_kidney # ???
|
|
479
|
+
|
|
480
|
+
# Liver V(Liver)*dC(Liver)/dt = (Q(Liver)-Q(Spleen)-Q(Gut)-Q(Pancreas)-Q(Stomach))*C(A) + Q(Spleen)*CV(Spleen) +
|
|
481
|
+
# + Q(Gut)*CV(Gut) + Q(Pancreas)*CV(Pancreas) + Q(Stomach)*CV(Stomach) -
|
|
482
|
+
# - Q(Liver)*CV(Liver) - CL(Liver,int)*CV(Liver,int)? # тут скорее всего нужно вычитать потоки из друг друга дополнительно по крови что бы сохранить массовый баланс
|
|
483
|
+
Q_liver_in_from_art = cnst_q_liver - cnst_q_gut - cnst_q_spleen - \
|
|
484
|
+
cnst_q_pancreas - cnst_q_stomach
|
|
485
|
+
dC_liver_dt = (
|
|
486
|
+
Q_liver_in_from_art * C_A + cnst_q_gut * C_gut / K_gut
|
|
487
|
+
+ cnst_q_spleen * C_spleen / K_spleen
|
|
488
|
+
+ cnst_q_stomach * C_stomach / K_stomach
|
|
489
|
+
+ cnst_q_pancreas * C_pancreas / K_pancreas
|
|
490
|
+
- cnst_q_liver * C_liver / K_liver
|
|
491
|
+
- CL_liver * C_liver / K_liver_cl # ???
|
|
492
|
+
) / cnst_v_liver
|
|
493
|
+
|
|
494
|
+
dC_gut_dt = cnst_q_gut * (C_A - C_gut / K_gut) / cnst_v_gut
|
|
495
|
+
dC_spleen_dt = cnst_q_spleen * (C_A - C_spleen / K_spleen) / cnst_v_spleen
|
|
496
|
+
dC_stomach_dt = cnst_q_stomach * (C_A - C_stomach / K_stomach) / cnst_v_stomach
|
|
497
|
+
dC_pancreas_dt = cnst_q_pancreas * (C_A - C_pancreas / K_pancreas) / cnst_v_pancreas
|
|
498
|
+
|
|
499
|
+
dC_venouse_dt = (
|
|
500
|
+
cnst_q_heart * C_heart / K_heart
|
|
501
|
+
+ cnst_q_brain * C_brain / K_brain
|
|
502
|
+
+ cnst_q_muscle * C_muscle / K_muscle
|
|
503
|
+
+ cnst_q_skin * C_skin / K_skin
|
|
504
|
+
+ cnst_q_adipose * C_fat / K_fat
|
|
505
|
+
+ cnst_q_bone * C_bone / K_bone
|
|
506
|
+
+ cnst_q_kidney * C_kidney / K_kidney
|
|
507
|
+
+ cnst_q_liver * C_liver / K_liver
|
|
508
|
+
- cnst_q_lung * C_V
|
|
509
|
+
) / cnst_v_venous_blood
|
|
510
|
+
|
|
511
|
+
dC_arterial_dt = cnst_q_lung * (C_lung / K_lung - C_A) / cnst_v_arterial_blood
|
|
512
|
+
y_new[0] = dC_lung_dt
|
|
513
|
+
y_new[1] = dC_heart_dt
|
|
514
|
+
y_new[2] = dC_brain_dt
|
|
515
|
+
y_new[3] = dC_muscle_dt
|
|
516
|
+
y_new[4] = dC_fat_dt
|
|
517
|
+
y_new[5] = dC_skin_dt
|
|
518
|
+
y_new[6] = dC_bone_dt
|
|
519
|
+
y_new[7] = dC_kidney_dt
|
|
520
|
+
y_new[8] = dC_liver_dt
|
|
521
|
+
y_new[9] = dC_gut_dt
|
|
522
|
+
y_new[10] = dC_spleen_dt
|
|
523
|
+
y_new[11] = dC_stomach_dt
|
|
524
|
+
y_new[12] = dC_pancreas_dt
|
|
525
|
+
y_new[13] = dC_venouse_dt
|
|
526
|
+
y_new[14] = dC_arterial_dt
|
|
527
|
+
|
|
528
|
+
# y_new = [dC_lung_dt, dC_heart_dt, dC_brain_dt, dC_muscle_dt, dC_fat_dt, dC_skin_dt, dC_bone_dt, \
|
|
529
|
+
# dC_kidney_dt, dC_liver_dt, dC_gut_dt, dC_spleen_dt, dC_stomach_dt, dC_pancreas_dt, dC_venouse_dt,
|
|
530
|
+
# dC_arterial_dt]
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
class ReleasePBPKmod(PBPKmod):
|
|
534
|
+
|
|
535
|
+
@staticmethod
|
|
536
|
+
def ode_release(solver, t, y0, release_function, d, v, is_lsoda=False):
|
|
537
|
+
result = []
|
|
538
|
+
new_y0 = y0
|
|
539
|
+
old_release_correction = 0
|
|
540
|
+
for i in range(1, len(t)):
|
|
541
|
+
if is_lsoda:
|
|
542
|
+
res, _ = solver(new_y0, t[i - 1], t[i])
|
|
543
|
+
y = res.T
|
|
544
|
+
else:
|
|
545
|
+
res = solver(new_y0, t[i - 1], t[i])
|
|
546
|
+
y = res.y
|
|
547
|
+
release_correction = release_function(t[i], d)
|
|
548
|
+
plus_release = release_correction - old_release_correction
|
|
549
|
+
all_corrections = plus_release
|
|
550
|
+
y[-2][1] += all_corrections / v
|
|
551
|
+
old_release_correction = release_correction
|
|
552
|
+
if i == 1:
|
|
553
|
+
result.append([y[i][0] for i in range(y.shape[0])])
|
|
554
|
+
new_y0 = np.array([y[i][1] for i in range(y.shape[0])])
|
|
555
|
+
result.append(new_y0)
|
|
556
|
+
return np.array(result).T
|
|
557
|
+
|
|
558
|
+
def __init__(self, release_parameters: dict=None, release_function: callable=None, know_k=None, know_cl=None, numba_option=False, lsoda_option=False):
|
|
559
|
+
super().__init__(
|
|
560
|
+
know_k=know_k, know_cl=know_cl, numba_option=numba_option, lsoda_option=lsoda_option
|
|
561
|
+
)
|
|
562
|
+
self.release_function = release_function
|
|
563
|
+
if release_parameters is None:
|
|
564
|
+
self.release_parameters = {}
|
|
565
|
+
else:
|
|
566
|
+
self.release_parameters = release_parameters
|
|
567
|
+
self.know_release_parameters = set(self.release_parameters.keys())
|
|
568
|
+
|
|
569
|
+
@staticmethod
|
|
570
|
+
def _default_release_function(t, d, m, b, c):
|
|
571
|
+
"""
|
|
572
|
+
Функция для поправки на высвобождение
|
|
573
|
+
"""
|
|
574
|
+
return d * c * t ** b / (t ** b + m)
|
|
575
|
+
|
|
576
|
+
def get_release_function(self):
|
|
577
|
+
return lambda t, d: self._get_release_function()(t, d, **self.release_parameters)
|
|
578
|
+
|
|
579
|
+
def _get_release_function(self):
|
|
580
|
+
if self.release_function is not None:
|
|
581
|
+
return self.release_function
|
|
582
|
+
else:
|
|
583
|
+
return self._default_release_function
|
|
584
|
+
|
|
585
|
+
@property
|
|
586
|
+
def _release_parameters_list(self) -> list[str]:
|
|
587
|
+
method = self._get_release_function()
|
|
588
|
+
arguments = inspect.getfullargspec(method).args
|
|
589
|
+
return [arg for arg in arguments if arg not in {'t', 'd'}]
|
|
590
|
+
|
|
591
|
+
def get_unknown_params(self):
|
|
592
|
+
result = super().get_unknown_params()
|
|
593
|
+
arguments = self._release_parameters_list
|
|
594
|
+
for arg in arguments:
|
|
595
|
+
know_arg = self.release_parameters.get(arg)
|
|
596
|
+
if know_arg is None:
|
|
597
|
+
result.append(f"release_{arg}")
|
|
598
|
+
return result
|
|
599
|
+
|
|
600
|
+
def update_know_params(self, k_cl=None, release_parameters=None):
|
|
601
|
+
super().update_know_params(k_cl)
|
|
602
|
+
if release_parameters is not None:
|
|
603
|
+
self.release_parameters = release_parameters
|
|
604
|
+
self.know_release_parameters = set(self.release_parameters.keys())
|
|
605
|
+
|
|
606
|
+
def _get_sol_difurs(self):
|
|
607
|
+
return self(max(self.time_exp), self.d, self.animal)
|
|
608
|
+
|
|
609
|
+
def fitness(self, x):
|
|
610
|
+
|
|
611
|
+
n = len(self._organs) + len(self._cl_organs) - len(self.know_cl) - len(self.know_k)
|
|
612
|
+
self.k_cl = x[:n]
|
|
613
|
+
i = 0
|
|
614
|
+
for arg in self._release_parameters_list:
|
|
615
|
+
if not arg in self.know_release_parameters:
|
|
616
|
+
self.release_parameters[arg] = x[n + i]
|
|
617
|
+
i += 1
|
|
618
|
+
return super().fitness(self.k_cl)
|
|
619
|
+
|
|
620
|
+
def _get_result(self, fun, t, max_time, K_CL, animal):
|
|
621
|
+
if not self.lsoda_option:
|
|
622
|
+
solver = lambda y0, t_left, t_right: solve_ivp(
|
|
623
|
+
fun=fun,
|
|
624
|
+
t_span=[t_left, t_right],
|
|
625
|
+
y0=y0,
|
|
626
|
+
t_eval=np.array([t_left, t_right]),
|
|
627
|
+
method=LSODA
|
|
628
|
+
)
|
|
629
|
+
return self.ode_release(solver, t, self.y0, d=self.d, v=self.v, release_function=self.get_release_function())
|
|
630
|
+
else:
|
|
631
|
+
solver = lambda y0, t_left, t_right: lsoda(
|
|
632
|
+
funcptr=fun,
|
|
633
|
+
u0=np.array(y0, dtype=np.float64),
|
|
634
|
+
t_eval=np.array([t_left, t_right], dtype=np.float64),
|
|
635
|
+
data=np.array(K_CL, dtype=np.float64),
|
|
636
|
+
)
|
|
637
|
+
return self.ode_release(solver, t, self.y0, d=self.d, v=self.v,
|
|
638
|
+
release_function=self.get_release_function(), is_lsoda=True), True
|
|
639
|
+
|
|
640
|
+
def _prepare_result(self, t, res):
|
|
641
|
+
self._res = res
|
|
642
|
+
self.last_result = {
|
|
643
|
+
't': t * 60
|
|
644
|
+
}
|
|
645
|
+
for organ in self._organs:
|
|
646
|
+
index = self._organs.index(organ)
|
|
647
|
+
self.last_result[organ] = res[index]
|
|
648
|
+
|
|
649
|
+
def __call__(self, max_time, d, animal=ANIMALS.MOUSE, step=1.0):
|
|
650
|
+
self.d = d
|
|
651
|
+
const = MODEL_CONST[animal]
|
|
652
|
+
self.v = const['venous_blood']['V']
|
|
653
|
+
return super().__call__(
|
|
654
|
+
max_time=max_time,
|
|
655
|
+
start_c_in_venous=0,
|
|
656
|
+
animal=animal,
|
|
657
|
+
step=step
|
|
658
|
+
)
|
|
659
|
+
|
|
660
|
+
def optimize(self, method=None, user_method=None, method_is_func=True,
|
|
661
|
+
optimization_func_name='__call__', **kwargs):
|
|
662
|
+
|
|
663
|
+
return super().optimize(
|
|
664
|
+
method=method, user_method=user_method, method_is_func=method_is_func,
|
|
665
|
+
optimization_func_name=optimization_func_name, **kwargs
|
|
666
|
+
)
|
|
667
|
+
|
|
668
|
+
def load_optimization_data(self, time_exp, dict_c_exp, d, animal=ANIMALS.MOUSE):
|
|
669
|
+
self.time_exp = time_exp
|
|
670
|
+
self.dict_c_exp = dict_c_exp
|
|
671
|
+
self.d = d
|
|
672
|
+
self.animal = animal
|
|
@@ -6,7 +6,7 @@ def readme():
|
|
|
6
6
|
|
|
7
7
|
setup(
|
|
8
8
|
name='pypharm',
|
|
9
|
-
version='1.
|
|
9
|
+
version='1.5.0',
|
|
10
10
|
author='Krash13',
|
|
11
11
|
author_email='krasheninnikov.r.s@muctr.ru',
|
|
12
12
|
description='Module for solving pharmacokinetic problems',
|
|
@@ -14,7 +14,8 @@ setup(
|
|
|
14
14
|
long_description_content_type='text/markdown',
|
|
15
15
|
url='https://github.com/Krash13/PyPharm',
|
|
16
16
|
packages=find_packages(),
|
|
17
|
-
install_requires=['numpy>=1.22.1', 'scipy
|
|
17
|
+
install_requires=['numpy>=1.22.1', 'scipy<=1.13.0', 'numba>=0.58.1',
|
|
18
|
+
'matplotlib>=3.5.1', 'graycode>=1.0.5', 'numbalsoda>=0.3.4'],
|
|
18
19
|
classifiers=[
|
|
19
20
|
'Programming Language :: Python :: 3.9',
|
|
20
21
|
'License :: OSI Approved :: BSD License',
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
MODEL_CONST = {
|
|
2
|
-
'human':{
|
|
3
|
-
'adipose': {'V':143, 'Q':3.7},
|
|
4
|
-
'bone': {'V':124, 'Q': 3.6} ,
|
|
5
|
-
'brain': {'V':20.7, 'Q': 10} ,
|
|
6
|
-
'gut': {'V':23.6, 'Q': 13} ,
|
|
7
|
-
'heart': {'V':3.8, 'Q': 2.14},
|
|
8
|
-
'kidney': {'V':4.4, 'Q': 15.7} ,
|
|
9
|
-
'liver': {'V':24.1, 'Q': 21} ,
|
|
10
|
-
'lung': {'V':16.7, 'Q': 71} ,
|
|
11
|
-
'muscle': {'V':429, 'Q': 10.7} ,
|
|
12
|
-
'pancreas': {'V':1.2, 'Q': 1.9} ,
|
|
13
|
-
'skin': {'V':111, 'Q': 4.3} ,
|
|
14
|
-
'spleen': {'V':2.7, 'Q': 1.1},
|
|
15
|
-
'stomach': {'V':2.2, 'Q':0.56},
|
|
16
|
-
'teaster': {'V':0.51, 'Q':0.04},
|
|
17
|
-
'arterial_blood': {'V':25.7} ,
|
|
18
|
-
'venous_blood': {'V':51.4}
|
|
19
|
-
},
|
|
20
|
-
'rat':{
|
|
21
|
-
'adipose': {'V':40, 'Q':1.6},
|
|
22
|
-
'bone': {'V':53.2, 'Q': 10.12},
|
|
23
|
-
'brain': {'V':6.8, 'Q': 5.32} ,
|
|
24
|
-
'gut': {'V':40, 'Q': 52} ,
|
|
25
|
-
'heart': {'V':3.2, 'Q': 15.68},
|
|
26
|
-
'kidney': {'V':9.2, 'Q': 36.92},
|
|
27
|
-
'liver': {'V':41.2, 'Q': 80} ,
|
|
28
|
-
'lung': {'V':4, 'Q': 203.2} ,
|
|
29
|
-
'muscle': {'V':487.6, 'Q': 30} ,
|
|
30
|
-
'pancreas': {'V':5.2, 'Q': 4} ,
|
|
31
|
-
'skin': {'V':160, 'Q': 20} ,
|
|
32
|
-
'spleen': {'V':2.4, 'Q': 5} ,
|
|
33
|
-
'stomach': {'V':4.4, 'Q':8.2} ,
|
|
34
|
-
'teaster': {'V':10, 'Q':1.8} ,
|
|
35
|
-
'arterial_blood': {'V':22.4, 'Q':10.8} ,
|
|
36
|
-
'venous_blood': {'V':45.2}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
class ORGAN_NAMES:
|
|
41
|
-
|
|
42
|
-
LUNG = 'lung'
|
|
43
|
-
HEART = 'heart'
|
|
44
|
-
BRAIN = 'brain'
|
|
45
|
-
MUSCLE = 'muscle'
|
|
46
|
-
ADIPOSE = 'adipose'
|
|
47
|
-
SKIN = 'skin'
|
|
48
|
-
BONE = 'bone'
|
|
49
|
-
KIDNEY = 'kidney'
|
|
50
|
-
LIVER = 'liver'
|
|
51
|
-
GUT = 'gut'
|
|
52
|
-
SPLEEN = 'spleen'
|
|
53
|
-
STOMACH = 'stomach'
|
|
54
|
-
PANCREAS = 'pancreas'
|
|
55
|
-
VENOUS = 'venous_blood'
|
|
56
|
-
ARTERIAL = 'arterial_blood'
|
|
@@ -1,369 +0,0 @@
|
|
|
1
|
-
from multiprocessing import shared_memory
|
|
2
|
-
import datetime
|
|
3
|
-
import numpy as np
|
|
4
|
-
from scipy.integrate import solve_ivp, RK45, odeint
|
|
5
|
-
from scipy.integrate import simps
|
|
6
|
-
from scipy.optimize import minimize
|
|
7
|
-
from PyPharm.algorithms.country_optimization import CountriesAlgorithm
|
|
8
|
-
from PyPharm.algorithms.country_optimization_v2 import CountriesAlgorithm_v2
|
|
9
|
-
from PyPharm.algorithms.genetic_optimization import GeneticAlgorithm
|
|
10
|
-
from PyPharm.constants import MODEL_CONST, ORGAN_NAMES
|
|
11
|
-
from numba import njit, types
|
|
12
|
-
from numba.typed import Dict
|
|
13
|
-
import matplotlib.pyplot as plt
|
|
14
|
-
|
|
15
|
-
cnst_rat = MODEL_CONST['rat']
|
|
16
|
-
cnst_human = MODEL_CONST['human']
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class PBPKmod:
|
|
20
|
-
|
|
21
|
-
_organs = ['lung', 'heart', 'brain', 'muscle', 'adipose', 'skin', 'bone', 'kidney',
|
|
22
|
-
'liver', 'gut', 'spleen', 'stomach', 'pancreas', 'venous_blood', 'arterial_blood']
|
|
23
|
-
_cl_organs = ['kidney', 'liver']
|
|
24
|
-
|
|
25
|
-
def __init__(self, know_k={}, know_cl={}, numba_option=False):
|
|
26
|
-
self.know_k = know_k
|
|
27
|
-
self.know_cl = know_cl
|
|
28
|
-
self._optim = False
|
|
29
|
-
self.numba_option = numba_option
|
|
30
|
-
if numba_option:
|
|
31
|
-
self.cnst_v_rat = Dict.empty(
|
|
32
|
-
key_type=types.unicode_type,
|
|
33
|
-
value_type=types.float64
|
|
34
|
-
)
|
|
35
|
-
for k, v in cnst_rat.items():
|
|
36
|
-
self.cnst_v_rat[k] = v['V']
|
|
37
|
-
self.cnst_v_human = Dict.empty(
|
|
38
|
-
key_type=types.unicode_type,
|
|
39
|
-
value_type=types.float64
|
|
40
|
-
)
|
|
41
|
-
for k, v in cnst_human.items():
|
|
42
|
-
self.cnst_v_human[k] = v['V']
|
|
43
|
-
self.cnst_q_rat = Dict.empty(
|
|
44
|
-
key_type=types.unicode_type,
|
|
45
|
-
value_type=types.float64
|
|
46
|
-
)
|
|
47
|
-
for k, v in cnst_rat.items():
|
|
48
|
-
if v.get('Q'):
|
|
49
|
-
self.cnst_q_rat[k] = v['Q']
|
|
50
|
-
self.cnst_q_human = Dict.empty(
|
|
51
|
-
key_type=types.unicode_type,
|
|
52
|
-
value_type=types.float64
|
|
53
|
-
)
|
|
54
|
-
for k, v in cnst_human.items():
|
|
55
|
-
if v.get('Q'):
|
|
56
|
-
self.cnst_q_human[k] = v['Q']
|
|
57
|
-
|
|
58
|
-
def load_optimization_data(self, time_exp, dict_c_exp, start_c_in_venous, is_human=False):
|
|
59
|
-
self.time_exp = time_exp
|
|
60
|
-
self.dict_c_exp = dict_c_exp
|
|
61
|
-
self.start_c_in_venous = start_c_in_venous
|
|
62
|
-
self.is_human = is_human
|
|
63
|
-
|
|
64
|
-
def fitness(self, k_cl):
|
|
65
|
-
|
|
66
|
-
self.k_cl = k_cl
|
|
67
|
-
|
|
68
|
-
sol_difurs = self(max(self.time_exp), self.start_c_in_venous, self.is_human)
|
|
69
|
-
# Список для хранения результатов
|
|
70
|
-
present_organs_indices = []
|
|
71
|
-
|
|
72
|
-
# Проверяем, какие ключи из 'organs' есть в 'dict_n'
|
|
73
|
-
for organ in self._organs:
|
|
74
|
-
if organ in self.dict_c_exp:
|
|
75
|
-
index = self._organs.index(organ) # Получаем индекс органа в списке organs
|
|
76
|
-
present_organs_indices.append((organ, index))
|
|
77
|
-
|
|
78
|
-
rez_err = 0
|
|
79
|
-
for organ, index in present_organs_indices:
|
|
80
|
-
mean_y = sum(sol_difurs[:, index]) / len(sol_difurs[:, index])
|
|
81
|
-
a = [(sol_difurs[:, index][self.time_exp[i]] - self.dict_c_exp[organ][i]) ** 2 for i in range(len(self.dict_c_exp[organ]))]
|
|
82
|
-
a = sum(a)
|
|
83
|
-
b = [(mean_y - self.dict_c_exp[organ][i]) ** 2 for i in
|
|
84
|
-
range(len(self.dict_c_exp[organ]))]
|
|
85
|
-
b = sum(b)
|
|
86
|
-
rez_err += a / b
|
|
87
|
-
# rez_err += sum([abs(sol_difurs[:, index][self.time_exp[i]] - self.dict_c_exp[organ][i]) for i in
|
|
88
|
-
# range(len(self.dict_c_exp[organ]))])
|
|
89
|
-
|
|
90
|
-
return rez_err
|
|
91
|
-
|
|
92
|
-
def __call__(self, max_time, start_c_in_venous, is_human=False, step=1):
|
|
93
|
-
self.y0 = [0 for _ in range(15)] # всего в модели 15 органов
|
|
94
|
-
self.y0[-2] = start_c_in_venous
|
|
95
|
-
t = np.linspace(0, max_time, max_time + 1 if self._optim else int(1 / step * max_time) + 1)
|
|
96
|
-
|
|
97
|
-
if not hasattr(self, 'k_cl'):
|
|
98
|
-
self.k_cl = []
|
|
99
|
-
|
|
100
|
-
full_k = []
|
|
101
|
-
i = 0
|
|
102
|
-
for name in self._organs:
|
|
103
|
-
know_k = self.know_k.get(name)
|
|
104
|
-
if know_k is not None:
|
|
105
|
-
full_k.append(know_k)
|
|
106
|
-
else:
|
|
107
|
-
full_k.append(self.k_cl[i])
|
|
108
|
-
i += 1
|
|
109
|
-
full_cl = []
|
|
110
|
-
|
|
111
|
-
for name in self._cl_organs:
|
|
112
|
-
know_k = self.know_cl.get(name)
|
|
113
|
-
if know_k is not None:
|
|
114
|
-
full_cl.append(know_k)
|
|
115
|
-
else:
|
|
116
|
-
full_cl.append(self.k_cl[i])
|
|
117
|
-
i += 1
|
|
118
|
-
if not self.numba_option:
|
|
119
|
-
sol_difurs = odeint(
|
|
120
|
-
self.fullPBPKmodel,
|
|
121
|
-
self.y0,
|
|
122
|
-
t,
|
|
123
|
-
args=([*full_k, *full_cl], is_human)
|
|
124
|
-
)
|
|
125
|
-
else:
|
|
126
|
-
k_cl = np.array([*full_k, *full_cl])
|
|
127
|
-
if is_human:
|
|
128
|
-
cnst_v = self.cnst_v_human
|
|
129
|
-
cnst_q = self.cnst_q_human
|
|
130
|
-
else:
|
|
131
|
-
cnst_v = self.cnst_v_rat
|
|
132
|
-
cnst_q = self.cnst_q_rat
|
|
133
|
-
function = lambda c, t: self.numba_fullPBPK_for_optimization(
|
|
134
|
-
y=c,
|
|
135
|
-
t=t,
|
|
136
|
-
K_CL=k_cl.astype(np.float64),
|
|
137
|
-
cnst_q=cnst_q,
|
|
138
|
-
cnst_v=cnst_v
|
|
139
|
-
)
|
|
140
|
-
sol_difurs = odeint(
|
|
141
|
-
function,
|
|
142
|
-
self.y0,
|
|
143
|
-
t
|
|
144
|
-
)
|
|
145
|
-
if self._optim:
|
|
146
|
-
return sol_difurs
|
|
147
|
-
|
|
148
|
-
self.last_result = {
|
|
149
|
-
't': t
|
|
150
|
-
}
|
|
151
|
-
for organ in self._organs:
|
|
152
|
-
index = self._organs.index(organ)
|
|
153
|
-
self.last_result[organ] = np.array([sol_difurs[i][index] for i in range(t.size)])
|
|
154
|
-
return self.last_result
|
|
155
|
-
|
|
156
|
-
def plot_last_result(self, organ_names=[], left=None, right=None, user_names={}, theoretic_data={}, y_lims={}):
|
|
157
|
-
if hasattr(self, 'last_result'):
|
|
158
|
-
for name in organ_names:
|
|
159
|
-
if theoretic_data.get(name):
|
|
160
|
-
plt.plot(theoretic_data[name]['x'], theoretic_data[name]['y'], '*r')
|
|
161
|
-
plt.plot(
|
|
162
|
-
self.last_result['t'],
|
|
163
|
-
self.last_result.get(name),
|
|
164
|
-
)
|
|
165
|
-
plt.title(user_names.get(name, name))
|
|
166
|
-
plt.xlim(left=left, right=right)
|
|
167
|
-
if y_lims.get(name):
|
|
168
|
-
plt.ylim(y_lims.get(name))
|
|
169
|
-
plt.grid()
|
|
170
|
-
plt.show()
|
|
171
|
-
|
|
172
|
-
def optimize(self, method=None, user_method=None, method_is_func=True,
|
|
173
|
-
optimization_func_name='__call__', **kwargs):
|
|
174
|
-
"""
|
|
175
|
-
Функция оптимизации модели
|
|
176
|
-
|
|
177
|
-
Args:
|
|
178
|
-
method: Метод оптимизации, любой доступный minimize + 'country_optimization' и 'country_optimization_v2'
|
|
179
|
-
max_step: Максимальный шаг при решении СДУ
|
|
180
|
-
**kwargs: Дополнительные именованные аргументы
|
|
181
|
-
|
|
182
|
-
Returns:
|
|
183
|
-
None
|
|
184
|
-
"""
|
|
185
|
-
self._optim = True
|
|
186
|
-
f = lambda x: self.fitness(x)
|
|
187
|
-
if user_method is not None:
|
|
188
|
-
if method_is_func:
|
|
189
|
-
x = user_method(f, **kwargs)
|
|
190
|
-
else:
|
|
191
|
-
optimization_obj = user_method(f, **kwargs)
|
|
192
|
-
x = getattr(optimization_obj, optimization_func_name)()
|
|
193
|
-
else:
|
|
194
|
-
if method == 'country_optimization':
|
|
195
|
-
CA = CountriesAlgorithm(
|
|
196
|
-
f=f,
|
|
197
|
-
memory_list=getattr(self, 'memory', None),
|
|
198
|
-
**kwargs
|
|
199
|
-
)
|
|
200
|
-
CA.start()
|
|
201
|
-
x = CA.countries[0].population[0].x
|
|
202
|
-
elif method == 'country_optimization_v2':
|
|
203
|
-
CA = CountriesAlgorithm_v2(
|
|
204
|
-
f=f,
|
|
205
|
-
**kwargs
|
|
206
|
-
)
|
|
207
|
-
CA.start()
|
|
208
|
-
x = CA.countries[0].population[0].x
|
|
209
|
-
elif method == 'GA':
|
|
210
|
-
CA = GeneticAlgorithm(
|
|
211
|
-
f=f,
|
|
212
|
-
**kwargs
|
|
213
|
-
)
|
|
214
|
-
x = CA.start()
|
|
215
|
-
else:
|
|
216
|
-
res = minimize(
|
|
217
|
-
fun=f,
|
|
218
|
-
method=method,
|
|
219
|
-
**kwargs
|
|
220
|
-
)
|
|
221
|
-
x = res.x
|
|
222
|
-
self._optim = False
|
|
223
|
-
return x
|
|
224
|
-
|
|
225
|
-
def update_know_params(self, k_cl):
|
|
226
|
-
i = 0
|
|
227
|
-
for name in self._organs:
|
|
228
|
-
know_k = self.know_k.get(name)
|
|
229
|
-
if know_k is None:
|
|
230
|
-
self.know_k[name] = k_cl[i]
|
|
231
|
-
i += 1
|
|
232
|
-
for name in self._cl_organs:
|
|
233
|
-
know_cl = self.know_cl.get(name)
|
|
234
|
-
if know_cl is None:
|
|
235
|
-
self.know_cl[name] = k_cl[i]
|
|
236
|
-
i += 1
|
|
237
|
-
|
|
238
|
-
def get_unknown_params(self):
|
|
239
|
-
result = []
|
|
240
|
-
for name in self._organs:
|
|
241
|
-
know_k = self.know_k.get(name)
|
|
242
|
-
if know_k is None:
|
|
243
|
-
result.append(f"k_{name}")
|
|
244
|
-
for name in self._cl_organs:
|
|
245
|
-
know_cl = self.know_cl.get(name)
|
|
246
|
-
if know_cl is None:
|
|
247
|
-
result.append(f"cl_{name}")
|
|
248
|
-
return result
|
|
249
|
-
|
|
250
|
-
def fullPBPKmodel(self, y, t, K_CL, is_human=False): # V, Q, K, CL):
|
|
251
|
-
# 15 органов
|
|
252
|
-
if is_human:
|
|
253
|
-
cnst = cnst_human
|
|
254
|
-
else:
|
|
255
|
-
cnst = cnst_rat
|
|
256
|
-
C_lung, C_heart, C_brain, C_muscle, C_fat, C_skin, C_bone, \
|
|
257
|
-
C_kidney, C_liver, C_gut, C_spleen, C_stomach, C_pancreas, C_V, C_A = y
|
|
258
|
-
|
|
259
|
-
K_lung, K_heart, K_brain, K_muscle, K_fat, K_skin, K_bone, \
|
|
260
|
-
K_kidney, K_liver, K_gut, K_spleen, K_stomach, K_pancreas, K_liver_cl, K_kidney_cl = K_CL[:15]
|
|
261
|
-
CL_kidney, CL_liver = K_CL[15:]
|
|
262
|
-
|
|
263
|
-
dC_lung_dt = cnst['lung']['Q'] * (C_V - C_lung / K_lung) / cnst['lung']['V']
|
|
264
|
-
dC_heart_dt = cnst['heart']['Q'] * (C_A - C_heart / K_heart) / cnst['heart']['V']
|
|
265
|
-
dC_brain_dt = cnst['brain']['Q'] * (C_A - C_brain / K_brain) / cnst['brain']['V']
|
|
266
|
-
dC_muscle_dt = cnst['muscle']['Q'] * (C_A - C_muscle / K_muscle) / cnst['muscle']['V']
|
|
267
|
-
dC_fat_dt = cnst['adipose']['Q'] * (C_A - C_fat / K_fat) / cnst['adipose']['V']
|
|
268
|
-
dC_skin_dt = cnst['skin']['Q'] * (C_A - C_skin / K_skin) / cnst['skin']['V']
|
|
269
|
-
dC_bone_dt = cnst['bone']['Q'] * (C_A - C_bone / K_bone) / cnst['bone']['V']
|
|
270
|
-
# Kidney V(Kidney)*dC(Kidney)/dt = Q(Kidney)*C(A)-Q(Kidney)*CV(Kidney)-CL(Kidney,int)*CV(Kidney,int)?
|
|
271
|
-
dC_kidney_dt = (cnst['kidney']['Q'] * (C_A - C_kidney / K_kidney) - CL_kidney * C_kidney / K_kidney_cl) / \
|
|
272
|
-
cnst['kidney']['V'] # ???
|
|
273
|
-
|
|
274
|
-
# Liver V(Liver)*dC(Liver)/dt = (Q(Liver)-Q(Spleen)-Q(Gut)-Q(Pancreas)-Q(Stomach))*C(A) + Q(Spleen)*CV(Spleen) +
|
|
275
|
-
# + Q(Gut)*CV(Gut) + Q(Pancreas)*CV(Pancreas) + Q(Stomach)*CV(Stomach) -
|
|
276
|
-
# - Q(Liver)*CV(Liver) - CL(Liver,int)*CV(Liver,int)? # тут скорее всего нужно вычитать потоки из друг друга дополнительно по крови что бы сохранить массовый баланс
|
|
277
|
-
Q_liver_in_from_art = cnst['liver']['Q'] - cnst['gut']['Q'] - cnst['spleen']['Q'] - \
|
|
278
|
-
cnst['pancreas']['Q'] - cnst['stomach']['Q']
|
|
279
|
-
dC_liver_dt = (
|
|
280
|
-
Q_liver_in_from_art * C_A + cnst['gut']['Q'] * C_gut / K_gut
|
|
281
|
-
+ cnst['spleen']['Q'] * C_spleen / K_spleen
|
|
282
|
-
+ cnst['stomach']['Q'] * C_stomach / K_stomach
|
|
283
|
-
+ cnst['pancreas']['Q'] * C_pancreas / K_pancreas
|
|
284
|
-
- cnst['liver']['Q'] * C_liver / K_liver
|
|
285
|
-
- CL_liver * C_liver / K_liver_cl # ???
|
|
286
|
-
) / cnst['liver']['V']
|
|
287
|
-
|
|
288
|
-
dC_gut_dt = cnst['gut']['Q'] * (C_A - C_gut / K_gut) / cnst['gut']['V']
|
|
289
|
-
dC_spleen_dt = cnst['spleen']['Q'] * (C_A - C_spleen / K_spleen) / cnst['spleen']['V']
|
|
290
|
-
dC_stomach_dt = cnst['stomach']['Q'] * (C_A - C_stomach / K_stomach) / cnst['stomach']['V']
|
|
291
|
-
dC_pancreas_dt = cnst['pancreas']['Q'] * (C_A - C_pancreas / K_pancreas) / cnst['pancreas']['V']
|
|
292
|
-
|
|
293
|
-
dC_venouse_dt = (
|
|
294
|
-
cnst['heart']['Q'] * C_heart / K_heart
|
|
295
|
-
+ cnst['brain']['Q'] * C_brain / K_brain
|
|
296
|
-
+ cnst['muscle']['Q'] * C_muscle / K_muscle
|
|
297
|
-
+ cnst['skin']['Q'] * C_skin / K_skin
|
|
298
|
-
+ cnst['adipose']['Q'] * C_fat / K_fat
|
|
299
|
-
+ cnst['bone']['Q'] * C_bone / K_bone
|
|
300
|
-
+ cnst['kidney']['Q'] * C_kidney / K_kidney
|
|
301
|
-
+ cnst['liver']['Q'] * C_liver / K_liver
|
|
302
|
-
- cnst['lung']['Q'] * C_V
|
|
303
|
-
) / cnst['venous_blood']['V']
|
|
304
|
-
|
|
305
|
-
dC_arterial_dt = cnst['lung']['Q'] * (C_lung / K_lung - C_A) / cnst['arterial_blood']['V']
|
|
306
|
-
|
|
307
|
-
y_new = [dC_lung_dt, dC_heart_dt, dC_brain_dt, dC_muscle_dt, dC_fat_dt, dC_skin_dt, dC_bone_dt, \
|
|
308
|
-
dC_kidney_dt, dC_liver_dt, dC_gut_dt, dC_spleen_dt, dC_stomach_dt, dC_pancreas_dt, dC_venouse_dt,
|
|
309
|
-
dC_arterial_dt]
|
|
310
|
-
return y_new
|
|
311
|
-
|
|
312
|
-
@staticmethod
|
|
313
|
-
@njit
|
|
314
|
-
def numba_fullPBPK_for_optimization(y, t, K_CL, cnst_q, cnst_v):
|
|
315
|
-
C_lung, C_heart, C_brain, C_muscle, C_fat, C_skin, C_bone, \
|
|
316
|
-
C_kidney, C_liver, C_gut, C_spleen, C_stomach, C_pancreas, C_V, C_A = y
|
|
317
|
-
|
|
318
|
-
K_lung, K_heart, K_brain, K_muscle, K_fat, K_skin, K_bone, \
|
|
319
|
-
K_kidney, K_liver, K_gut, K_spleen, K_stomach, K_pancreas, K_liver_cl, K_kidney_cl = K_CL[:15]
|
|
320
|
-
CL_kidney, CL_liver = K_CL[15:]
|
|
321
|
-
|
|
322
|
-
dC_lung_dt = cnst_q['lung'] * (C_V - C_lung / K_lung) / cnst_v['lung']
|
|
323
|
-
dC_heart_dt = cnst_q['heart'] * (C_A - C_heart / K_heart) / cnst_v['heart']
|
|
324
|
-
dC_brain_dt = cnst_q['brain'] * (C_A - C_brain / K_brain) / cnst_v['brain']
|
|
325
|
-
dC_muscle_dt = cnst_q['muscle'] * (C_A - C_muscle / K_muscle) / cnst_v['muscle']
|
|
326
|
-
dC_fat_dt = cnst_q['adipose'] * (C_A - C_fat / K_fat) / cnst_v['adipose']
|
|
327
|
-
dC_skin_dt = cnst_q['skin'] * (C_A - C_skin / K_skin) / cnst_v['skin']
|
|
328
|
-
dC_bone_dt = cnst_q['bone'] * (C_A - C_bone / K_bone) / cnst_v['bone']
|
|
329
|
-
# Kidney V(Kidney)*dC(Kidney)/dt = Q(Kidney)*C(A)-Q(Kidney)*CV(Kidney)-CL(Kidney,int)*CV(Kidney,int)?
|
|
330
|
-
dC_kidney_dt = (cnst_q['kidney'] * (C_A - C_kidney / K_kidney) - CL_kidney * C_kidney / K_kidney_cl) / \
|
|
331
|
-
cnst_v['kidney'] # ???
|
|
332
|
-
|
|
333
|
-
# Liver V(Liver)*dC(Liver)/dt = (Q(Liver)-Q(Spleen)-Q(Gut)-Q(Pancreas)-Q(Stomach))*C(A) + Q(Spleen)*CV(Spleen) +
|
|
334
|
-
# + Q(Gut)*CV(Gut) + Q(Pancreas)*CV(Pancreas) + Q(Stomach)*CV(Stomach) -
|
|
335
|
-
# - Q(Liver)*CV(Liver) - CL(Liver,int)*CV(Liver,int)? # тут скорее всего нужно вычитать потоки из друг друга дополнительно по крови что бы сохранить массовый баланс
|
|
336
|
-
Q_liver_in_from_art = cnst_q['liver'] - cnst_q['gut'] - cnst_q['spleen'] - \
|
|
337
|
-
cnst_q['pancreas'] - cnst_q['stomach']
|
|
338
|
-
dC_liver_dt = (
|
|
339
|
-
Q_liver_in_from_art * C_A + cnst_q['gut'] * C_gut / K_gut
|
|
340
|
-
+ cnst_q['spleen'] * C_spleen / K_spleen
|
|
341
|
-
+ cnst_q['stomach'] * C_stomach / K_stomach
|
|
342
|
-
+ cnst_q['pancreas'] * C_pancreas / K_pancreas
|
|
343
|
-
- cnst_q['liver'] * C_liver / K_liver
|
|
344
|
-
- CL_liver * C_liver / K_liver_cl # ???
|
|
345
|
-
) / cnst_v['liver']
|
|
346
|
-
|
|
347
|
-
dC_gut_dt = cnst_q['gut'] * (C_A - C_gut / K_gut) / cnst_v['gut']
|
|
348
|
-
dC_spleen_dt = cnst_q['spleen'] * (C_A - C_spleen / K_spleen) / cnst_v['spleen']
|
|
349
|
-
dC_stomach_dt = cnst_q['stomach'] * (C_A - C_stomach / K_stomach) / cnst_v['stomach']
|
|
350
|
-
dC_pancreas_dt = cnst_q['pancreas'] * (C_A - C_pancreas / K_pancreas) / cnst_v['pancreas']
|
|
351
|
-
|
|
352
|
-
dC_venouse_dt = (
|
|
353
|
-
cnst_q['heart'] * C_heart / K_heart
|
|
354
|
-
+ cnst_q['brain'] * C_brain / K_brain
|
|
355
|
-
+ cnst_q['muscle'] * C_muscle / K_muscle
|
|
356
|
-
+ cnst_q['skin'] * C_skin / K_skin
|
|
357
|
-
+ cnst_q['adipose'] * C_fat / K_fat
|
|
358
|
-
+ cnst_q['bone'] * C_bone / K_bone
|
|
359
|
-
+ cnst_q['kidney'] * C_kidney / K_kidney
|
|
360
|
-
+ cnst_q['liver'] * C_liver / K_liver
|
|
361
|
-
- cnst_q['lung'] * C_V
|
|
362
|
-
) / cnst_v['venous_blood']
|
|
363
|
-
|
|
364
|
-
dC_arterial_dt = cnst_q['lung'] * (C_lung / K_lung - C_A) / cnst_v['arterial_blood']
|
|
365
|
-
|
|
366
|
-
y_new = np.array([dC_lung_dt, dC_heart_dt, dC_brain_dt, dC_muscle_dt, dC_fat_dt, dC_skin_dt, dC_bone_dt, \
|
|
367
|
-
dC_kidney_dt, dC_liver_dt, dC_gut_dt, dC_spleen_dt, dC_stomach_dt, dC_pancreas_dt, dC_venouse_dt,
|
|
368
|
-
dC_arterial_dt]).astype(np.float64)
|
|
369
|
-
return y_new
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|