mxlpy 0.19.0__py3-none-any.whl → 0.20.0__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.
- mxlpy/__init__.py +4 -10
- mxlpy/compare.py +240 -0
- mxlpy/experimental/diff.py +15 -3
- mxlpy/fit.py +6 -11
- mxlpy/fns.py +37 -42
- mxlpy/identify.py +10 -3
- mxlpy/integrators/__init__.py +4 -3
- mxlpy/integrators/int_assimulo.py +6 -6
- mxlpy/integrators/int_scipy.py +6 -6
- mxlpy/label_map.py +4 -2
- mxlpy/linear_label_map.py +4 -2
- mxlpy/mc.py +5 -14
- mxlpy/mca.py +4 -4
- mxlpy/meta/__init__.py +6 -4
- mxlpy/meta/codegen_latex.py +179 -86
- mxlpy/meta/codegen_modebase.py +3 -1
- mxlpy/meta/codegen_py.py +11 -3
- mxlpy/meta/source_tools.py +8 -4
- mxlpy/model.py +42 -14
- mxlpy/nn/_keras.py +10 -3
- mxlpy/nn/_torch.py +7 -1
- mxlpy/parallel.py +5 -2
- mxlpy/parameterise.py +11 -3
- mxlpy/plot.py +203 -50
- mxlpy/report.py +33 -8
- mxlpy/sbml/__init__.py +3 -3
- mxlpy/sbml/_data.py +7 -6
- mxlpy/sbml/_mathml.py +8 -7
- mxlpy/sbml/_name_conversion.py +5 -1
- mxlpy/scan.py +14 -19
- mxlpy/simulator.py +34 -31
- mxlpy/surrogates/_keras.py +2 -0
- mxlpy/surrogates/_poly.py +6 -2
- mxlpy/surrogates/_qss.py +4 -1
- mxlpy/surrogates/_torch.py +6 -2
- mxlpy/symbolic/__init__.py +5 -3
- mxlpy/symbolic/strikepy.py +5 -2
- mxlpy/symbolic/symbolic_model.py +12 -3
- mxlpy/types.py +5 -10
- {mxlpy-0.19.0.dist-info → mxlpy-0.20.0.dist-info}/METADATA +6 -4
- mxlpy-0.20.0.dist-info/RECORD +55 -0
- mxlpy-0.19.0.dist-info/RECORD +0 -54
- {mxlpy-0.19.0.dist-info → mxlpy-0.20.0.dist-info}/WHEEL +0 -0
- {mxlpy-0.19.0.dist-info → mxlpy-0.20.0.dist-info}/licenses/LICENSE +0 -0
mxlpy/__init__.py
CHANGED
@@ -42,6 +42,7 @@ from typing import TYPE_CHECKING
|
|
42
42
|
import pandas as pd
|
43
43
|
|
44
44
|
from . import (
|
45
|
+
compare,
|
45
46
|
distributions,
|
46
47
|
experimental,
|
47
48
|
fit,
|
@@ -57,11 +58,7 @@ from .label_map import LabelMapper
|
|
57
58
|
from .linear_label_map import LinearLabelMapper
|
58
59
|
from .mc import Cache
|
59
60
|
from .model import Model
|
60
|
-
from .scan import
|
61
|
-
steady_state,
|
62
|
-
time_course,
|
63
|
-
time_course_over_protocol,
|
64
|
-
)
|
61
|
+
from .scan import steady_state, time_course, time_course_over_protocol
|
65
62
|
from .simulator import Simulator
|
66
63
|
from .symbolic import SymbolicModel, to_symbolic_model
|
67
64
|
from .types import Derived, IntegratorProtocol, unwrap
|
@@ -72,11 +69,7 @@ with contextlib.suppress(ImportError):
|
|
72
69
|
if TYPE_CHECKING:
|
73
70
|
from mxlpy.types import ArrayLike
|
74
71
|
|
75
|
-
from . import
|
76
|
-
nn,
|
77
|
-
npe,
|
78
|
-
surrogates,
|
79
|
-
)
|
72
|
+
from . import nn, npe, surrogates
|
80
73
|
else:
|
81
74
|
from lazy_import import lazy_module
|
82
75
|
|
@@ -98,6 +91,7 @@ __all__ = [
|
|
98
91
|
"Simulator",
|
99
92
|
"SymbolicModel",
|
100
93
|
"cartesian_product",
|
94
|
+
"compare",
|
101
95
|
"distributions",
|
102
96
|
"experimental",
|
103
97
|
"fit",
|
mxlpy/compare.py
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
"""Docstring."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
from dataclasses import dataclass
|
6
|
+
from typing import TYPE_CHECKING, cast
|
7
|
+
|
8
|
+
import pandas as pd
|
9
|
+
|
10
|
+
from mxlpy import plot
|
11
|
+
from mxlpy.simulator import Result, Simulator
|
12
|
+
from mxlpy.types import unwrap
|
13
|
+
|
14
|
+
if TYPE_CHECKING:
|
15
|
+
from mxlpy.model import Model
|
16
|
+
from mxlpy.types import ArrayLike
|
17
|
+
|
18
|
+
__all__ = [
|
19
|
+
"ProtocolComparison",
|
20
|
+
"SteadyStateComparison",
|
21
|
+
"TimeCourseComparison",
|
22
|
+
"protocol_time_courses",
|
23
|
+
"steady_states",
|
24
|
+
"time_courses",
|
25
|
+
]
|
26
|
+
|
27
|
+
|
28
|
+
@dataclass
|
29
|
+
class SteadyStateComparison:
|
30
|
+
"""Compare two steady states."""
|
31
|
+
|
32
|
+
res1: Result
|
33
|
+
res2: Result
|
34
|
+
|
35
|
+
@property
|
36
|
+
def variables(self) -> pd.DataFrame:
|
37
|
+
"""Compare the steady state variables."""
|
38
|
+
ss1 = self.res1.get_variables().iloc[-1]
|
39
|
+
ss2 = self.res2.get_variables().iloc[-1]
|
40
|
+
diff = ss2 - ss1
|
41
|
+
return pd.DataFrame(
|
42
|
+
{"m1": ss1, "m2": ss2, "diff": diff, "rel_diff": diff / ss1}
|
43
|
+
)
|
44
|
+
|
45
|
+
@property
|
46
|
+
def fluxes(self) -> pd.DataFrame:
|
47
|
+
"""Compare the steady state fluxes."""
|
48
|
+
ss1 = self.res1.get_fluxes().iloc[-1]
|
49
|
+
ss2 = self.res2.get_fluxes().iloc[-1]
|
50
|
+
diff = ss2 - ss1
|
51
|
+
return pd.DataFrame(
|
52
|
+
{"m1": ss1, "m2": ss2, "diff": diff, "rel_diff": diff / ss1}
|
53
|
+
)
|
54
|
+
|
55
|
+
@property
|
56
|
+
def all(self) -> pd.DataFrame:
|
57
|
+
"""Compare both steady-state variables and fluxes."""
|
58
|
+
ss1 = self.res1.get_combined().iloc[-1]
|
59
|
+
ss2 = self.res2.get_combined().iloc[-1]
|
60
|
+
diff = ss2 - ss1
|
61
|
+
return pd.DataFrame(
|
62
|
+
{"m1": ss1, "m2": ss2, "diff": diff, "rel_diff": diff / ss1}
|
63
|
+
)
|
64
|
+
|
65
|
+
def plot_variables(self, title: str = "Variables") -> plot.FigAxs:
|
66
|
+
"""Plot the relative difference of steady-state variables."""
|
67
|
+
fig, axs = plot.bars_autogrouped(self.variables["rel_diff"], ylabel="")
|
68
|
+
plot.grid_labels(axs, ylabel="Relative difference")
|
69
|
+
fig.suptitle(title)
|
70
|
+
return fig, axs
|
71
|
+
|
72
|
+
def plot_fluxes(self, title: str = "Fluxes") -> plot.FigAxs:
|
73
|
+
"""Plot the relative difference of steady-state fluxes."""
|
74
|
+
fig, axs = plot.bars_autogrouped(self.fluxes["rel_diff"], ylabel="")
|
75
|
+
plot.grid_labels(axs, ylabel="Relative difference")
|
76
|
+
fig.suptitle(title)
|
77
|
+
return fig, axs
|
78
|
+
|
79
|
+
def plot_all(self, title: str = "Variables and Fluxes") -> plot.FigAxs:
|
80
|
+
"""Plot the relative difference of steady-state variables and fluxes."""
|
81
|
+
combined = self.all
|
82
|
+
|
83
|
+
fig, axs = plot.bars_autogrouped(combined["rel_diff"], ylabel="")
|
84
|
+
plot.grid_labels(axs, ylabel="Relative difference")
|
85
|
+
fig.suptitle(title)
|
86
|
+
return fig, axs
|
87
|
+
|
88
|
+
|
89
|
+
@dataclass
|
90
|
+
class TimeCourseComparison:
|
91
|
+
"""Compare two time courses."""
|
92
|
+
|
93
|
+
res1: Result
|
94
|
+
res2: Result
|
95
|
+
|
96
|
+
# @property
|
97
|
+
# def variables(self) -> pd.DataFrame:
|
98
|
+
# """Compare the steady state variables."""
|
99
|
+
# ss1 = self.res1.get_variables()
|
100
|
+
# ss2 = self.res2.get_variables()
|
101
|
+
# diff = ss2 - ss1
|
102
|
+
# return pd.DataFrame(
|
103
|
+
# {"m1": ss1, "m2": ss2, "diff": diff, "rel_diff": diff / ss1}
|
104
|
+
# )
|
105
|
+
|
106
|
+
# @property
|
107
|
+
# def fluxes(self) -> pd.DataFrame:
|
108
|
+
# """Compare the steady state fluxes."""
|
109
|
+
# ss1 = self.res1.get_fluxes()
|
110
|
+
# ss2 = self.res2.get_fluxes()
|
111
|
+
# diff = ss2 - ss1
|
112
|
+
# return pd.DataFrame(
|
113
|
+
# {"m1": ss1, "m2": ss2, "diff": diff, "rel_diff": diff / ss1}
|
114
|
+
# )
|
115
|
+
|
116
|
+
def plot_variables_relative_difference(self) -> plot.FigAxs:
|
117
|
+
"""Plot the relative difference of time course variables."""
|
118
|
+
c1 = self.res1.variables
|
119
|
+
c2 = self.res2.variables
|
120
|
+
|
121
|
+
rel_diff = ((c2.loc[:, cast(list[str], c1.columns)] - c1) / c1).fillna(0)
|
122
|
+
fig, axs = plot.line_autogrouped(rel_diff, ylabel="")
|
123
|
+
plot.grid_labels(axs, ylabel="Relative difference")
|
124
|
+
fig.suptitle("Variables")
|
125
|
+
return fig, axs
|
126
|
+
|
127
|
+
def plot_fluxes_relative_difference(self) -> plot.FigAxs:
|
128
|
+
"""Plot the relative difference of time course fluxes."""
|
129
|
+
v1 = self.res1.fluxes
|
130
|
+
v2 = self.res2.fluxes
|
131
|
+
|
132
|
+
rel_diff = ((v2.loc[:, cast(list[str], v1.columns)] - v1) / v1).fillna(0)
|
133
|
+
fig, axs = plot.line_autogrouped(rel_diff, ylabel="")
|
134
|
+
plot.grid_labels(axs, ylabel="Relative difference")
|
135
|
+
fig.suptitle("Fluxes")
|
136
|
+
return fig, axs
|
137
|
+
|
138
|
+
|
139
|
+
@dataclass
|
140
|
+
class ProtocolComparison:
|
141
|
+
"""Compare two protocol time courses."""
|
142
|
+
|
143
|
+
res1: Result
|
144
|
+
res2: Result
|
145
|
+
protocol: pd.DataFrame
|
146
|
+
|
147
|
+
# @property
|
148
|
+
# def variables(self) -> pd.DataFrame:
|
149
|
+
# """Compare the steady state variables."""
|
150
|
+
# ss1 = self.res1.get_variables()
|
151
|
+
# ss2 = self.res2.get_variables()
|
152
|
+
# diff = ss2 - ss1
|
153
|
+
# return pd.DataFrame(
|
154
|
+
# {"m1": ss1, "m2": ss2, "diff": diff, "rel_diff": diff / ss1}
|
155
|
+
# )
|
156
|
+
|
157
|
+
# @property
|
158
|
+
# def fluxes(self) -> pd.DataFrame:
|
159
|
+
# """Compare the steady state fluxes."""
|
160
|
+
# ss1 = self.res1.get_fluxes()
|
161
|
+
# ss2 = self.res2.get_fluxes()
|
162
|
+
# diff = ss2 - ss1
|
163
|
+
# return pd.DataFrame(
|
164
|
+
# {"m1": ss1, "m2": ss2, "diff": diff, "rel_diff": diff / ss1}
|
165
|
+
# )
|
166
|
+
|
167
|
+
def plot_variables_relative_difference(
|
168
|
+
self,
|
169
|
+
shade_protocol_variable: str | None = None,
|
170
|
+
) -> plot.FigAxs:
|
171
|
+
"""Plot the relative difference of time course variables."""
|
172
|
+
c1 = self.res1.variables
|
173
|
+
c2 = self.res2.variables
|
174
|
+
|
175
|
+
rel_diff = ((c2.loc[:, cast(list[str], c1.columns)] - c1) / c1).fillna(0)
|
176
|
+
fig, axs = plot.line_autogrouped(rel_diff, ylabel="")
|
177
|
+
plot.grid_labels(axs, ylabel="Relative difference")
|
178
|
+
fig.suptitle("Variables")
|
179
|
+
|
180
|
+
if shade_protocol_variable is not None:
|
181
|
+
protocol = self.protocol[shade_protocol_variable]
|
182
|
+
for ax in axs:
|
183
|
+
plot.shade_protocol(protocol=protocol, ax=ax)
|
184
|
+
return fig, axs
|
185
|
+
|
186
|
+
def plot_fluxes_relative_difference(
|
187
|
+
self,
|
188
|
+
shade_protocol_variable: str | None = None,
|
189
|
+
) -> plot.FigAxs:
|
190
|
+
"""Plot the relative difference of time course fluxes."""
|
191
|
+
v1 = self.res1.fluxes
|
192
|
+
v2 = self.res2.fluxes
|
193
|
+
|
194
|
+
rel_diff = ((v2.loc[:, cast(list[str], v1.columns)] - v1) / v1).fillna(0)
|
195
|
+
fig, axs = plot.line_autogrouped(rel_diff, ylabel="")
|
196
|
+
plot.grid_labels(axs, ylabel="Relative difference")
|
197
|
+
fig.suptitle("Fluxes")
|
198
|
+
|
199
|
+
if shade_protocol_variable is not None:
|
200
|
+
protocol = self.protocol[shade_protocol_variable]
|
201
|
+
for ax in axs:
|
202
|
+
plot.shade_protocol(protocol=protocol, ax=ax)
|
203
|
+
return fig, axs
|
204
|
+
|
205
|
+
|
206
|
+
def steady_states(m1: Model, m2: Model) -> SteadyStateComparison:
|
207
|
+
"""Compare the steady states of two models."""
|
208
|
+
return SteadyStateComparison(
|
209
|
+
res1=unwrap(Simulator(m1).simulate_to_steady_state().get_result()),
|
210
|
+
res2=unwrap(Simulator(m2).simulate_to_steady_state().get_result()),
|
211
|
+
)
|
212
|
+
|
213
|
+
|
214
|
+
def time_courses(m1: Model, m2: Model, time_points: ArrayLike) -> TimeCourseComparison:
|
215
|
+
"""Compare the time courses of two models."""
|
216
|
+
return TimeCourseComparison(
|
217
|
+
res1=unwrap(
|
218
|
+
Simulator(m1).simulate_time_course(time_points=time_points).get_result()
|
219
|
+
),
|
220
|
+
res2=unwrap(
|
221
|
+
Simulator(m2).simulate_time_course(time_points=time_points).get_result()
|
222
|
+
),
|
223
|
+
)
|
224
|
+
|
225
|
+
|
226
|
+
def protocol_time_courses(
|
227
|
+
m1: Model,
|
228
|
+
m2: Model,
|
229
|
+
protocol: pd.DataFrame,
|
230
|
+
) -> ProtocolComparison:
|
231
|
+
"""Compare the time courses of two models."""
|
232
|
+
return ProtocolComparison(
|
233
|
+
res1=unwrap(
|
234
|
+
Simulator(m1).simulate_over_protocol(protocol=protocol).get_result()
|
235
|
+
),
|
236
|
+
res2=unwrap(
|
237
|
+
Simulator(m2).simulate_over_protocol(protocol=protocol).get_result()
|
238
|
+
),
|
239
|
+
protocol=protocol,
|
240
|
+
)
|
mxlpy/experimental/diff.py
CHANGED
@@ -1,12 +1,24 @@
|
|
1
1
|
"""Diffing utilities for comparing models."""
|
2
2
|
|
3
|
-
from
|
3
|
+
from __future__ import annotations
|
4
|
+
|
4
5
|
from dataclasses import dataclass, field
|
6
|
+
from typing import TYPE_CHECKING
|
5
7
|
|
6
|
-
from mxlpy.model import Model
|
7
8
|
from mxlpy.types import Derived
|
8
9
|
|
9
|
-
|
10
|
+
if TYPE_CHECKING:
|
11
|
+
from collections.abc import Mapping
|
12
|
+
|
13
|
+
from mxlpy.model import Model
|
14
|
+
|
15
|
+
__all__ = [
|
16
|
+
"DerivedDiff",
|
17
|
+
"ModelDiff",
|
18
|
+
"ReactionDiff",
|
19
|
+
"model_diff",
|
20
|
+
"soft_eq",
|
21
|
+
]
|
10
22
|
|
11
23
|
|
12
24
|
@dataclass
|
mxlpy/fit.py
CHANGED
@@ -18,13 +18,12 @@ from scipy.optimize import minimize
|
|
18
18
|
|
19
19
|
from mxlpy.integrators import DefaultIntegrator
|
20
20
|
from mxlpy.simulator import Simulator
|
21
|
-
from mxlpy.types import
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
)
|
21
|
+
from mxlpy.types import Array, ArrayLike, Callable, IntegratorType, cast
|
22
|
+
|
23
|
+
if TYPE_CHECKING:
|
24
|
+
import pandas as pd
|
25
|
+
|
26
|
+
from mxlpy.model import Model
|
28
27
|
|
29
28
|
__all__ = [
|
30
29
|
"InitialGuess",
|
@@ -40,10 +39,6 @@ __all__ = [
|
|
40
39
|
"time_course_over_protocol",
|
41
40
|
]
|
42
41
|
|
43
|
-
if TYPE_CHECKING:
|
44
|
-
import pandas as pd
|
45
|
-
|
46
|
-
from mxlpy.model import Model
|
47
42
|
|
48
43
|
type InitialGuess = dict[str, float]
|
49
44
|
type ResidualFn = Callable[[Array], float]
|
mxlpy/fns.py
CHANGED
@@ -2,11 +2,6 @@
|
|
2
2
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
-
from typing import TYPE_CHECKING
|
6
|
-
|
7
|
-
if TYPE_CHECKING:
|
8
|
-
from mxlpy.types import Float
|
9
|
-
|
10
5
|
__all__ = [
|
11
6
|
"add",
|
12
7
|
"constant",
|
@@ -36,7 +31,7 @@ __all__ = [
|
|
36
31
|
###############################################################################
|
37
32
|
|
38
33
|
|
39
|
-
def constant(x:
|
34
|
+
def constant(x: float) -> float:
|
40
35
|
"""Return a constant value regardless of other model components.
|
41
36
|
|
42
37
|
Parameters
|
@@ -58,7 +53,7 @@ def constant(x: Float) -> Float:
|
|
58
53
|
return x
|
59
54
|
|
60
55
|
|
61
|
-
def neg(x:
|
56
|
+
def neg(x: float) -> float:
|
62
57
|
"""Calculate the negation of a value.
|
63
58
|
|
64
59
|
Parameters
|
@@ -82,7 +77,7 @@ def neg(x: Float) -> Float:
|
|
82
77
|
return -x
|
83
78
|
|
84
79
|
|
85
|
-
def minus(x:
|
80
|
+
def minus(x: float, y: float) -> float:
|
86
81
|
"""Calculate the difference between two values.
|
87
82
|
|
88
83
|
Parameters
|
@@ -108,7 +103,7 @@ def minus(x: Float, y: Float) -> Float:
|
|
108
103
|
return x - y
|
109
104
|
|
110
105
|
|
111
|
-
def mul(x:
|
106
|
+
def mul(x: float, y: float) -> float:
|
112
107
|
"""Calculate the product of two values.
|
113
108
|
|
114
109
|
Parameters
|
@@ -134,7 +129,7 @@ def mul(x: Float, y: Float) -> Float:
|
|
134
129
|
return x * y
|
135
130
|
|
136
131
|
|
137
|
-
def div(x:
|
132
|
+
def div(x: float, y: float) -> float:
|
138
133
|
"""Calculate the quotient of two values.
|
139
134
|
|
140
135
|
Parameters
|
@@ -160,7 +155,7 @@ def div(x: Float, y: Float) -> Float:
|
|
160
155
|
return x / y
|
161
156
|
|
162
157
|
|
163
|
-
def one_div(x:
|
158
|
+
def one_div(x: float) -> float:
|
164
159
|
"""Calculate the reciprocal of a value.
|
165
160
|
|
166
161
|
Parameters
|
@@ -184,7 +179,7 @@ def one_div(x: Float) -> Float:
|
|
184
179
|
return 1.0 / x
|
185
180
|
|
186
181
|
|
187
|
-
def neg_div(x:
|
182
|
+
def neg_div(x: float, y: float) -> float:
|
188
183
|
"""Calculate the negative quotient of two values.
|
189
184
|
|
190
185
|
Parameters
|
@@ -210,7 +205,7 @@ def neg_div(x: Float, y: Float) -> Float:
|
|
210
205
|
return -x / y
|
211
206
|
|
212
207
|
|
213
|
-
def twice(x:
|
208
|
+
def twice(x: float) -> float:
|
214
209
|
"""Calculate twice the value.
|
215
210
|
|
216
211
|
Parameters
|
@@ -234,7 +229,7 @@ def twice(x: Float) -> Float:
|
|
234
229
|
return x * 2
|
235
230
|
|
236
231
|
|
237
|
-
def add(x:
|
232
|
+
def add(x: float, y: float) -> float:
|
238
233
|
"""Calculate the sum of two values.
|
239
234
|
|
240
235
|
Parameters
|
@@ -260,7 +255,7 @@ def add(x: Float, y: Float) -> Float:
|
|
260
255
|
return x + y
|
261
256
|
|
262
257
|
|
263
|
-
def proportional(x:
|
258
|
+
def proportional(x: float, y: float) -> float:
|
264
259
|
"""Calculate the product of two values.
|
265
260
|
|
266
261
|
Common in mass-action kinetics where x represents a rate constant
|
@@ -295,9 +290,9 @@ def proportional(x: Float, y: Float) -> Float:
|
|
295
290
|
|
296
291
|
|
297
292
|
def moiety_1s(
|
298
|
-
x:
|
299
|
-
x_total:
|
300
|
-
) ->
|
293
|
+
x: float,
|
294
|
+
x_total: float,
|
295
|
+
) -> float:
|
301
296
|
"""Calculate conservation relationship for one substrate.
|
302
297
|
|
303
298
|
Used for creating derived variables that represent moiety conservation,
|
@@ -328,10 +323,10 @@ def moiety_1s(
|
|
328
323
|
|
329
324
|
|
330
325
|
def moiety_2s(
|
331
|
-
x1:
|
332
|
-
x2:
|
333
|
-
x_total:
|
334
|
-
) ->
|
326
|
+
x1: float,
|
327
|
+
x2: float,
|
328
|
+
x_total: float,
|
329
|
+
) -> float:
|
335
330
|
"""Calculate conservation relationship for two substrates.
|
336
331
|
|
337
332
|
Used for creating derived variables that represent moiety conservation
|
@@ -369,7 +364,7 @@ def moiety_2s(
|
|
369
364
|
###############################################################################
|
370
365
|
|
371
366
|
|
372
|
-
def mass_action_1s(s1:
|
367
|
+
def mass_action_1s(s1: float, k: float) -> float:
|
373
368
|
"""Calculate irreversible mass action reaction rate with one substrate.
|
374
369
|
|
375
370
|
Rate = k * [S]
|
@@ -398,7 +393,7 @@ def mass_action_1s(s1: Float, k: Float) -> Float:
|
|
398
393
|
return k * s1
|
399
394
|
|
400
395
|
|
401
|
-
def mass_action_1s_1p(s1:
|
396
|
+
def mass_action_1s_1p(s1: float, p1: float, kf: float, kr: float) -> float:
|
402
397
|
"""Calculate reversible mass action reaction rate with one substrate and one product.
|
403
398
|
|
404
399
|
Rate = kf * [S] - kr * [P]
|
@@ -432,7 +427,7 @@ def mass_action_1s_1p(s1: Float, p1: Float, kf: Float, kr: Float) -> Float:
|
|
432
427
|
return kf * s1 - kr * p1
|
433
428
|
|
434
429
|
|
435
|
-
def mass_action_2s(s1:
|
430
|
+
def mass_action_2s(s1: float, s2: float, k: float) -> float:
|
436
431
|
"""Calculate irreversible mass action reaction rate with two substrates.
|
437
432
|
|
438
433
|
Rate = k * [S1] * [S2]
|
@@ -463,7 +458,7 @@ def mass_action_2s(s1: Float, s2: Float, k: Float) -> Float:
|
|
463
458
|
return k * s1 * s2
|
464
459
|
|
465
460
|
|
466
|
-
def mass_action_2s_1p(s1:
|
461
|
+
def mass_action_2s_1p(s1: float, s2: float, p1: float, kf: float, kr: float) -> float:
|
467
462
|
"""Calculate reversible mass action reaction rate with two substrates and one product.
|
468
463
|
|
469
464
|
Rate = kf * [S1] * [S2] - kr * [P]
|
@@ -505,7 +500,7 @@ def mass_action_2s_1p(s1: Float, s2: Float, p1: Float, kf: Float, kr: Float) ->
|
|
505
500
|
###############################################################################
|
506
501
|
|
507
502
|
|
508
|
-
def michaelis_menten_1s(s1:
|
503
|
+
def michaelis_menten_1s(s1: float, vmax: float, km1: float) -> float:
|
509
504
|
"""Calculate irreversible Michaelis-Menten reaction rate for one substrate.
|
510
505
|
|
511
506
|
Rate = Vmax * [S] / (Km + [S])
|
@@ -549,12 +544,12 @@ def michaelis_menten_1s(s1: Float, vmax: Float, km1: Float) -> Float:
|
|
549
544
|
|
550
545
|
|
551
546
|
def michaelis_menten_2s(
|
552
|
-
s1:
|
553
|
-
s2:
|
554
|
-
vmax:
|
555
|
-
km1:
|
556
|
-
km2:
|
557
|
-
) ->
|
547
|
+
s1: float,
|
548
|
+
s2: float,
|
549
|
+
vmax: float,
|
550
|
+
km1: float,
|
551
|
+
km2: float,
|
552
|
+
) -> float:
|
558
553
|
"""Calculate Michaelis-Menten reaction rate (ping-pong) for two substrates.
|
559
554
|
|
560
555
|
Rate = Vmax * [S1] * [S2] / ([S1]*[S2] + km1*[S2] + km2*[S1])
|
@@ -594,14 +589,14 @@ def michaelis_menten_2s(
|
|
594
589
|
|
595
590
|
|
596
591
|
def michaelis_menten_3s(
|
597
|
-
s1:
|
598
|
-
s2:
|
599
|
-
s3:
|
600
|
-
vmax:
|
601
|
-
km1:
|
602
|
-
km2:
|
603
|
-
km3:
|
604
|
-
) ->
|
592
|
+
s1: float,
|
593
|
+
s2: float,
|
594
|
+
s3: float,
|
595
|
+
vmax: float,
|
596
|
+
km1: float,
|
597
|
+
km2: float,
|
598
|
+
km3: float,
|
599
|
+
) -> float:
|
605
600
|
"""Calculate Michaelis-Menten reaction rate (ping-pong) for three substrates.
|
606
601
|
|
607
602
|
Rate = Vmax * [S1] * [S2] * [S3] / ([S1]*[S2] + km1*[S2]*[S3] + km2*[S1]*[S3] + km3*[S1]*[S2])
|
@@ -649,7 +644,7 @@ def michaelis_menten_3s(
|
|
649
644
|
###############################################################################
|
650
645
|
|
651
646
|
|
652
|
-
def diffusion_1s_1p(inside:
|
647
|
+
def diffusion_1s_1p(inside: float, outside: float, k: float) -> float:
|
653
648
|
"""Calculate diffusion rate between two compartments.
|
654
649
|
|
655
650
|
Rate = k * ([outside] - [inside])
|
mxlpy/identify.py
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
"""Numerical parameter identification estimations."""
|
2
2
|
|
3
|
+
from __future__ import annotations
|
4
|
+
|
3
5
|
from functools import partial
|
6
|
+
from typing import TYPE_CHECKING
|
4
7
|
|
5
8
|
import numpy as np
|
6
9
|
import pandas as pd
|
@@ -8,11 +11,15 @@ from tqdm import tqdm
|
|
8
11
|
|
9
12
|
from mxlpy import fit
|
10
13
|
from mxlpy.distributions import LogNormal, sample
|
11
|
-
from mxlpy.model import Model
|
12
14
|
from mxlpy.parallel import parallelise
|
13
|
-
from mxlpy.types import Array
|
14
15
|
|
15
|
-
|
16
|
+
if TYPE_CHECKING:
|
17
|
+
from mxlpy.model import Model
|
18
|
+
from mxlpy.types import Array
|
19
|
+
|
20
|
+
__all__ = [
|
21
|
+
"profile_likelihood",
|
22
|
+
]
|
16
23
|
|
17
24
|
|
18
25
|
def _mc_fit_time_course_worker(
|
mxlpy/integrators/__init__.py
CHANGED
@@ -6,9 +6,6 @@ It includes support for both Assimulo and Scipy integrators, with Assimulo being
|
|
6
6
|
|
7
7
|
from __future__ import annotations
|
8
8
|
|
9
|
-
__all__ = ["DefaultIntegrator"]
|
10
|
-
|
11
|
-
|
12
9
|
from .int_scipy import Scipy
|
13
10
|
|
14
11
|
try:
|
@@ -17,3 +14,7 @@ try:
|
|
17
14
|
DefaultIntegrator = Assimulo
|
18
15
|
except ImportError:
|
19
16
|
DefaultIntegrator = Scipy
|
17
|
+
|
18
|
+
__all__ = [
|
19
|
+
"DefaultIntegrator",
|
20
|
+
]
|
@@ -2,14 +2,9 @@
|
|
2
2
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
-
from dataclasses import dataclass
|
6
|
-
|
7
|
-
__all__ = [
|
8
|
-
"Assimulo",
|
9
|
-
]
|
10
|
-
|
11
5
|
import contextlib
|
12
6
|
import os
|
7
|
+
from dataclasses import dataclass
|
13
8
|
from typing import TYPE_CHECKING, Literal
|
14
9
|
|
15
10
|
import numpy as np
|
@@ -25,6 +20,11 @@ if TYPE_CHECKING:
|
|
25
20
|
from mxlpy.types import Array, ArrayLike
|
26
21
|
|
27
22
|
|
23
|
+
__all__ = [
|
24
|
+
"Assimulo",
|
25
|
+
]
|
26
|
+
|
27
|
+
|
28
28
|
@dataclass
|
29
29
|
class Assimulo:
|
30
30
|
"""Assimulo integrator for solving ODEs.
|
mxlpy/integrators/int_scipy.py
CHANGED
@@ -2,13 +2,8 @@
|
|
2
2
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
-
from dataclasses import dataclass, field
|
6
|
-
|
7
|
-
__all__ = [
|
8
|
-
"Scipy",
|
9
|
-
]
|
10
|
-
|
11
5
|
import copy
|
6
|
+
from dataclasses import dataclass, field
|
12
7
|
from typing import TYPE_CHECKING, cast
|
13
8
|
|
14
9
|
import numpy as np
|
@@ -20,6 +15,11 @@ if TYPE_CHECKING:
|
|
20
15
|
from collections.abc import Callable
|
21
16
|
|
22
17
|
|
18
|
+
__all__ = [
|
19
|
+
"Scipy",
|
20
|
+
]
|
21
|
+
|
22
|
+
|
23
23
|
@dataclass
|
24
24
|
class Scipy:
|
25
25
|
"""Scipy integrator for solving ODEs.
|
mxlpy/label_map.py
CHANGED
@@ -24,13 +24,15 @@ import numpy as np
|
|
24
24
|
|
25
25
|
from mxlpy.model import Model
|
26
26
|
|
27
|
-
__all__ = ["LabelMapper"]
|
28
|
-
|
29
27
|
if TYPE_CHECKING:
|
30
28
|
from collections.abc import Callable, Mapping
|
31
29
|
|
32
30
|
from mxlpy.types import Derived
|
33
31
|
|
32
|
+
__all__ = [
|
33
|
+
"LabelMapper",
|
34
|
+
]
|
35
|
+
|
34
36
|
|
35
37
|
def _total_concentration(*args: float) -> float:
|
36
38
|
"""Calculate sum of isotopomer concentrations.
|
mxlpy/linear_label_map.py
CHANGED
@@ -16,13 +16,15 @@ from typing import TYPE_CHECKING
|
|
16
16
|
|
17
17
|
from mxlpy.model import Derived, Model
|
18
18
|
|
19
|
-
__all__ = ["LinearLabelMapper"]
|
20
|
-
|
21
19
|
if TYPE_CHECKING:
|
22
20
|
from collections.abc import Mapping
|
23
21
|
|
24
22
|
import pandas as pd
|
25
23
|
|
24
|
+
__all__ = [
|
25
|
+
"LinearLabelMapper",
|
26
|
+
]
|
27
|
+
|
26
28
|
|
27
29
|
def _generate_isotope_labels(base_name: str, num_labels: int) -> list[str]:
|
28
30
|
"""Generate list of isotopomer names for a compound.
|