pypharm 1.4.2__py3-none-any.whl → 1.5.1__py3-none-any.whl
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/constants.py +56 -31
- PyPharm/models/compartment_models.py +5 -4
- PyPharm/models/pbpk.py +396 -93
- {pypharm-1.4.2.dist-info → pypharm-1.5.1.dist-info}/METADATA +3 -2
- {pypharm-1.4.2.dist-info → pypharm-1.5.1.dist-info}/RECORD +7 -7
- {pypharm-1.4.2.dist-info → pypharm-1.5.1.dist-info}/WHEEL +0 -0
- {pypharm-1.4.2.dist-info → pypharm-1.5.1.dist-info}/top_level.txt +0 -0
PyPharm/constants.py
CHANGED
|
@@ -1,40 +1,60 @@
|
|
|
1
1
|
MODEL_CONST = {
|
|
2
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},
|
|
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
17
|
'arterial_blood': {'V':25.7} ,
|
|
18
18
|
'venous_blood': {'V':51.4}
|
|
19
19
|
},
|
|
20
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
|
|
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} ,
|
|
36
37
|
'venous_blood': {'V':45.2}
|
|
37
|
-
}
|
|
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
|
+
}
|
|
38
58
|
}
|
|
39
59
|
|
|
40
60
|
class ORGAN_NAMES:
|
|
@@ -53,4 +73,9 @@ class ORGAN_NAMES:
|
|
|
53
73
|
STOMACH = 'stomach'
|
|
54
74
|
PANCREAS = 'pancreas'
|
|
55
75
|
VENOUS = 'venous_blood'
|
|
56
|
-
ARTERIAL = 'arterial_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
|
|
PyPharm/models/pbpk.py
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
1
|
+
import inspect
|
|
2
|
+
from numbalsoda import lsoda_sig, lsoda
|
|
3
3
|
import numpy as np
|
|
4
|
-
from scipy.integrate import solve_ivp,
|
|
5
|
-
from scipy.integrate import simps
|
|
4
|
+
from scipy.integrate import solve_ivp, LSODA
|
|
6
5
|
from scipy.optimize import minimize
|
|
7
6
|
from PyPharm.algorithms.country_optimization import CountriesAlgorithm
|
|
8
7
|
from PyPharm.algorithms.country_optimization_v2 import CountriesAlgorithm_v2
|
|
9
8
|
from PyPharm.algorithms.genetic_optimization import GeneticAlgorithm
|
|
10
|
-
from PyPharm.constants import MODEL_CONST, ORGAN_NAMES
|
|
11
|
-
from numba import njit, types
|
|
9
|
+
from PyPharm.constants import MODEL_CONST, ORGAN_NAMES, ANIMALS
|
|
10
|
+
from numba import njit, types, cfunc
|
|
12
11
|
from numba.typed import Dict
|
|
13
12
|
import matplotlib.pyplot as plt
|
|
14
13
|
|
|
15
|
-
cnst_rat = MODEL_CONST['rat']
|
|
16
|
-
cnst_human = MODEL_CONST['human']
|
|
17
14
|
|
|
18
15
|
|
|
19
16
|
class PBPKmod:
|
|
@@ -22,50 +19,48 @@ class PBPKmod:
|
|
|
22
19
|
'liver', 'gut', 'spleen', 'stomach', 'pancreas', 'venous_blood', 'arterial_blood']
|
|
23
20
|
_cl_organs = ['kidney', 'liver']
|
|
24
21
|
|
|
25
|
-
def __init__(self, know_k=
|
|
26
|
-
|
|
27
|
-
self.
|
|
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 {}
|
|
28
26
|
self._optim = False
|
|
29
27
|
self.numba_option = numba_option
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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']
|
|
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
|
|
57
49
|
|
|
58
|
-
def load_optimization_data(self, time_exp, dict_c_exp, start_c_in_venous,
|
|
50
|
+
def load_optimization_data(self, time_exp, dict_c_exp, start_c_in_venous, animal=ANIMALS.MOUSE):
|
|
59
51
|
self.time_exp = time_exp
|
|
60
52
|
self.dict_c_exp = dict_c_exp
|
|
61
53
|
self.start_c_in_venous = start_c_in_venous
|
|
62
|
-
self.
|
|
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)
|
|
63
58
|
|
|
64
59
|
def fitness(self, k_cl):
|
|
65
60
|
|
|
66
61
|
self.k_cl = k_cl
|
|
67
62
|
|
|
68
|
-
sol_difurs = self(
|
|
63
|
+
sol_difurs = self._get_sol_difurs()
|
|
69
64
|
# Список для хранения результатов
|
|
70
65
|
present_organs_indices = []
|
|
71
66
|
|
|
@@ -77,8 +72,8 @@ class PBPKmod:
|
|
|
77
72
|
|
|
78
73
|
rez_err = 0
|
|
79
74
|
for organ, index in present_organs_indices:
|
|
80
|
-
mean_y = sum(sol_difurs[
|
|
81
|
-
a = [(sol_difurs[
|
|
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]))]
|
|
82
77
|
a = sum(a)
|
|
83
78
|
b = [(mean_y - self.dict_c_exp[organ][i]) ** 2 for i in
|
|
84
79
|
range(len(self.dict_c_exp[organ]))]
|
|
@@ -88,12 +83,46 @@ class PBPKmod:
|
|
|
88
83
|
# range(len(self.dict_c_exp[organ]))])
|
|
89
84
|
|
|
90
85
|
return rez_err
|
|
91
|
-
|
|
92
|
-
|
|
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):
|
|
93
122
|
self.y0 = [0 for _ in range(15)] # всего в модели 15 органов
|
|
94
123
|
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
|
-
|
|
124
|
+
t = np.linspace(0, max_time, max_time + 1 if self._optim else int(1 / step * max_time) + 1) / 60
|
|
125
|
+
|
|
97
126
|
if not hasattr(self, 'k_cl'):
|
|
98
127
|
self.k_cl = []
|
|
99
128
|
|
|
@@ -115,43 +144,44 @@ class PBPKmod:
|
|
|
115
144
|
else:
|
|
116
145
|
full_cl.append(self.k_cl[i])
|
|
117
146
|
i += 1
|
|
118
|
-
if not self.numba_option:
|
|
119
|
-
|
|
120
|
-
self.fullPBPKmodel,
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
|
124
164
|
)
|
|
125
165
|
else:
|
|
126
166
|
k_cl = np.array([*full_k, *full_cl])
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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(
|
|
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(
|
|
134
170
|
y=c,
|
|
135
|
-
t=
|
|
171
|
+
t=time,
|
|
136
172
|
K_CL=k_cl.astype(np.float64),
|
|
137
173
|
cnst_q=cnst_q,
|
|
138
174
|
cnst_v=cnst_v
|
|
139
175
|
)
|
|
140
|
-
|
|
141
|
-
function,
|
|
142
|
-
|
|
143
|
-
|
|
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
|
|
144
182
|
)
|
|
145
|
-
|
|
146
|
-
|
|
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
|
|
183
|
+
self._prepare_result(t, res)
|
|
184
|
+
return self._res
|
|
155
185
|
|
|
156
186
|
def plot_last_result(self, organ_names=[], left=None, right=None, user_names={}, theoretic_data={}, y_lims={}):
|
|
157
187
|
if hasattr(self, 'last_result'):
|
|
@@ -222,18 +252,19 @@ class PBPKmod:
|
|
|
222
252
|
self._optim = False
|
|
223
253
|
return x
|
|
224
254
|
|
|
225
|
-
def update_know_params(self, k_cl):
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
255
|
+
def update_know_params(self, k_cl=None):
|
|
256
|
+
if k_cl is not None:
|
|
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
|
|
237
268
|
|
|
238
269
|
def get_unknown_params(self):
|
|
239
270
|
result = []
|
|
@@ -247,12 +278,9 @@ class PBPKmod:
|
|
|
247
278
|
result.append(f"cl_{name}")
|
|
248
279
|
return result
|
|
249
280
|
|
|
250
|
-
def fullPBPKmodel(self, y, t, K_CL,
|
|
281
|
+
def fullPBPKmodel(self, y, t, K_CL, animal=ANIMALS.MOUSE): # V, Q, K, CL):
|
|
251
282
|
# 15 органов
|
|
252
|
-
|
|
253
|
-
cnst = cnst_human
|
|
254
|
-
else:
|
|
255
|
-
cnst = cnst_rat
|
|
283
|
+
cnst = MODEL_CONST[animal]
|
|
256
284
|
C_lung, C_heart, C_brain, C_muscle, C_fat, C_skin, C_bone, \
|
|
257
285
|
C_kidney, C_liver, C_gut, C_spleen, C_stomach, C_pancreas, C_V, C_A = y
|
|
258
286
|
|
|
@@ -366,4 +394,279 @@ class PBPKmod:
|
|
|
366
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, \
|
|
367
395
|
dC_kidney_dt, dC_liver_dt, dC_gut_dt, dC_spleen_dt, dC_stomach_dt, dC_pancreas_dt, dC_venouse_dt,
|
|
368
396
|
dC_arterial_dt]).astype(np.float64)
|
|
369
|
-
return y_new
|
|
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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pypharm
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.1
|
|
4
4
|
Summary: Module for solving pharmacokinetic problems
|
|
5
5
|
Home-page: https://github.com/Krash13/PyPharm
|
|
6
6
|
Author: Krash13
|
|
@@ -14,10 +14,11 @@ Classifier: Operating System :: OS Independent
|
|
|
14
14
|
Requires-Python: >=3.9
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
Requires-Dist: numpy (>=1.22.1)
|
|
17
|
-
Requires-Dist: scipy (
|
|
17
|
+
Requires-Dist: scipy (<=1.13.0)
|
|
18
18
|
Requires-Dist: numba (>=0.58.1)
|
|
19
19
|
Requires-Dist: matplotlib (>=3.5.1)
|
|
20
20
|
Requires-Dist: graycode (>=1.0.5)
|
|
21
|
+
Requires-Dist: numbalsoda (>=0.3.4)
|
|
21
22
|
|
|
22
23
|
PyPharm
|
|
23
24
|
----------
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
PyPharm/__init__.py,sha256=W3NIi--fjBbpS9ODzq8lZ4L0trgqvXda7GO2dxpscXg,103
|
|
2
|
-
PyPharm/constants.py,sha256=
|
|
2
|
+
PyPharm/constants.py,sha256=KovwTSSkiGh9o0Hf-yoqw3H7GxC_YmawunlWMHtSK98,3869
|
|
3
3
|
PyPharm/country_optimization.py,sha256=3fnnAJfdLgD0RP8qyJzHBuPDHcPljcLPQM9oqNip1r8,19664
|
|
4
4
|
PyPharm/country_optimization_v2.py,sha256=3d2mt15DXdr1V3soIJS51xuCv6uzH8pirah1RnI5--8,13156
|
|
5
5
|
PyPharm/country_optimization_v3.py,sha256=-3slM5MwSmiG6rD7p9ycbUQPdt4hd5bcEwpSxjb3A7U,17034
|
|
@@ -13,9 +13,9 @@ PyPharm/algorithms/country_optimization_v3.py,sha256=btPF1_aNfk9TNWf9oi-POGTU_2v
|
|
|
13
13
|
PyPharm/algorithms/genetic_optimization.py,sha256=EC_pEWwL-ufCQd71zBhCeAB6-Sh1fijv7F3L0bWCz3I,5036
|
|
14
14
|
PyPharm/algorithms/gold_digger_optimization.py,sha256=mln67sAYxkwzFqZ9Ylild1F25VuaruXRPaUMOGT5gIM,4449
|
|
15
15
|
PyPharm/models/__init__.py,sha256=NMJcXMq0gCXgGLyB62j3qIzz3tbxqe6AOLPsJnfcjM0,129
|
|
16
|
-
PyPharm/models/compartment_models.py,sha256=
|
|
17
|
-
PyPharm/models/pbpk.py,sha256=
|
|
18
|
-
pypharm-1.
|
|
19
|
-
pypharm-1.
|
|
20
|
-
pypharm-1.
|
|
21
|
-
pypharm-1.
|
|
16
|
+
PyPharm/models/compartment_models.py,sha256=qptmcVUVHmVL_00w5iPg590dNQnsirtywnk2arfAwTI,33149
|
|
17
|
+
PyPharm/models/pbpk.py,sha256=Wm-z3M2Pc2XQ5IP37kSu6OUC8cbRa4Bzzwpl-eHsaEk,30381
|
|
18
|
+
pypharm-1.5.1.dist-info/METADATA,sha256=qdXIw-u8ZsQI7Oa6v4MPCGbbJh1ZwcLxGeem3iNT7xs,22976
|
|
19
|
+
pypharm-1.5.1.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92
|
|
20
|
+
pypharm-1.5.1.dist-info/top_level.txt,sha256=yybfSkKw8q1G3aEcnlfVL7_L9ufGFSAYZnpc7q6oYJk,8
|
|
21
|
+
pypharm-1.5.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|