modelbase2 0.1.79__py3-none-any.whl → 0.3.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.
- modelbase2/__init__.py +148 -25
- modelbase2/distributions.py +336 -0
- modelbase2/experimental/__init__.py +17 -0
- modelbase2/experimental/codegen.py +239 -0
- modelbase2/experimental/diff.py +227 -0
- modelbase2/experimental/notes.md +4 -0
- modelbase2/experimental/tex.py +521 -0
- modelbase2/fit.py +284 -0
- modelbase2/fns.py +185 -0
- modelbase2/integrators/__init__.py +19 -0
- modelbase2/integrators/int_assimulo.py +146 -0
- modelbase2/integrators/int_scipy.py +147 -0
- modelbase2/label_map.py +610 -0
- modelbase2/linear_label_map.py +301 -0
- modelbase2/mc.py +548 -0
- modelbase2/mca.py +280 -0
- modelbase2/model.py +1621 -0
- modelbase2/nnarchitectures.py +128 -0
- modelbase2/npe.py +271 -0
- modelbase2/parallel.py +171 -0
- modelbase2/parameterise.py +28 -0
- modelbase2/paths.py +36 -0
- modelbase2/plot.py +832 -0
- modelbase2/sbml/__init__.py +14 -0
- modelbase2/sbml/_data.py +77 -0
- modelbase2/sbml/_export.py +656 -0
- modelbase2/sbml/_import.py +585 -0
- modelbase2/sbml/_mathml.py +691 -0
- modelbase2/sbml/_name_conversion.py +52 -0
- modelbase2/sbml/_unit_conversion.py +74 -0
- modelbase2/scan.py +616 -0
- modelbase2/scope.py +96 -0
- modelbase2/simulator.py +635 -0
- modelbase2/surrogates/__init__.py +31 -0
- modelbase2/surrogates/_poly.py +91 -0
- modelbase2/surrogates/_torch.py +191 -0
- modelbase2/surrogates.py +316 -0
- modelbase2/types.py +352 -11
- modelbase2-0.3.0.dist-info/METADATA +93 -0
- modelbase2-0.3.0.dist-info/RECORD +43 -0
- {modelbase2-0.1.79.dist-info → modelbase2-0.3.0.dist-info}/WHEEL +1 -1
- modelbase2/core/__init__.py +0 -29
- modelbase2/core/algebraic_module_container.py +0 -130
- modelbase2/core/constant_container.py +0 -113
- modelbase2/core/data.py +0 -109
- modelbase2/core/name_container.py +0 -29
- modelbase2/core/reaction_container.py +0 -115
- modelbase2/core/utils.py +0 -28
- modelbase2/core/variable_container.py +0 -24
- modelbase2/ode/__init__.py +0 -13
- modelbase2/ode/integrator.py +0 -80
- modelbase2/ode/mca.py +0 -270
- modelbase2/ode/model.py +0 -470
- modelbase2/ode/simulator.py +0 -153
- modelbase2/utils/__init__.py +0 -0
- modelbase2/utils/plotting.py +0 -372
- modelbase2-0.1.79.dist-info/METADATA +0 -44
- modelbase2-0.1.79.dist-info/RECORD +0 -22
- {modelbase2-0.1.79.dist-info → modelbase2-0.3.0.dist-info/licenses}/LICENSE +0 -0
modelbase2/mca.py
ADDED
@@ -0,0 +1,280 @@
|
|
1
|
+
"""Metabolic Control Analysis (MCA) Module.
|
2
|
+
|
3
|
+
Provides functions for analyzing control and regulation in metabolic networks through:
|
4
|
+
- Elasticity coefficients (variable and parameter)
|
5
|
+
- Response coefficients
|
6
|
+
|
7
|
+
Main Functions:
|
8
|
+
variable_elasticities: Calculate non-steady state variable elasticities
|
9
|
+
parameter_elasticities: Calculate non-steady state parameter elasticities
|
10
|
+
response_coefficients: Calculate response coefficients for steady state
|
11
|
+
|
12
|
+
Mathematical Background:
|
13
|
+
MCA quantifies how changes in system parameters affect metabolic variables
|
14
|
+
through elasticity and control coefficients. These describe the sensitivity
|
15
|
+
of reaction rates and steady state variables to perturbations.
|
16
|
+
"""
|
17
|
+
|
18
|
+
from __future__ import annotations
|
19
|
+
|
20
|
+
from functools import partial
|
21
|
+
from typing import TYPE_CHECKING
|
22
|
+
|
23
|
+
import pandas as pd
|
24
|
+
|
25
|
+
from modelbase2.parallel import parallelise
|
26
|
+
from modelbase2.scan import _steady_state_worker
|
27
|
+
from modelbase2.types import ResponseCoefficients
|
28
|
+
|
29
|
+
__all__ = [
|
30
|
+
"parameter_elasticities",
|
31
|
+
"response_coefficients",
|
32
|
+
"variable_elasticities",
|
33
|
+
]
|
34
|
+
|
35
|
+
if TYPE_CHECKING:
|
36
|
+
from modelbase2.model import Model
|
37
|
+
|
38
|
+
|
39
|
+
###############################################################################
|
40
|
+
# Non-steady state
|
41
|
+
###############################################################################
|
42
|
+
|
43
|
+
|
44
|
+
def variable_elasticities(
|
45
|
+
model: Model,
|
46
|
+
*,
|
47
|
+
concs: dict[str, float] | None = None,
|
48
|
+
variables: list[str] | None = None,
|
49
|
+
time: float = 0,
|
50
|
+
normalized: bool = True,
|
51
|
+
displacement: float = 1e-4,
|
52
|
+
) -> pd.DataFrame:
|
53
|
+
"""Calculate non-steady state elasticity coefficients.
|
54
|
+
|
55
|
+
Computes the sensitivity of reaction rates to changes in metabolite
|
56
|
+
concentrations (ε-elasticities).
|
57
|
+
|
58
|
+
Examples:
|
59
|
+
>>> variable_elasticities(model, concs={"A": 1.0, "B": 2.0})
|
60
|
+
Rxn A B
|
61
|
+
v1 0.0 0.0
|
62
|
+
v2 1.0 0.0
|
63
|
+
v3 0.0 5.0
|
64
|
+
|
65
|
+
|
66
|
+
Args:
|
67
|
+
model: Metabolic model instance
|
68
|
+
concs: Initial concentrations {metabolite: value}. Uses model defaults if None
|
69
|
+
variables: List of variables to analyze. Uses all if None
|
70
|
+
time: Time point for evaluation
|
71
|
+
normalized: Whether to normalize coefficients
|
72
|
+
displacement: Relative perturbation size
|
73
|
+
|
74
|
+
Returns:
|
75
|
+
DataFrame with elasticity coefficients (reactions x metabolites)
|
76
|
+
|
77
|
+
"""
|
78
|
+
concs = model.get_initial_conditions() if concs is None else concs
|
79
|
+
variables = model.get_variable_names() if variables is None else variables
|
80
|
+
elasticities = {}
|
81
|
+
|
82
|
+
for var in variables:
|
83
|
+
old = concs[var]
|
84
|
+
|
85
|
+
upper = model.get_fluxes(
|
86
|
+
concs=concs | {var: old * (1 + displacement)}, time=time
|
87
|
+
)
|
88
|
+
lower = model.get_fluxes(
|
89
|
+
concs=concs | {var: old * (1 - displacement)}, time=time
|
90
|
+
)
|
91
|
+
|
92
|
+
elasticity_coef = (upper - lower) / (2 * displacement * old)
|
93
|
+
if normalized:
|
94
|
+
elasticity_coef *= old / model.get_fluxes(concs=concs, time=time)
|
95
|
+
elasticities[var] = elasticity_coef
|
96
|
+
|
97
|
+
return pd.DataFrame(data=elasticities)
|
98
|
+
|
99
|
+
|
100
|
+
def parameter_elasticities(
|
101
|
+
model: Model,
|
102
|
+
parameters: list[str] | None = None,
|
103
|
+
concs: dict[str, float] | None = None,
|
104
|
+
time: float = 0,
|
105
|
+
*,
|
106
|
+
normalized: bool = True,
|
107
|
+
displacement: float = 1e-4,
|
108
|
+
) -> pd.DataFrame:
|
109
|
+
"""Calculate parameter elasticity coefficients.
|
110
|
+
|
111
|
+
Examples:
|
112
|
+
>>> parameter_elasticities(model)
|
113
|
+
Rxn k1 k2
|
114
|
+
v1 1.0 0.0
|
115
|
+
v2 0.0 1.0
|
116
|
+
v3 0.0 0.0
|
117
|
+
|
118
|
+
Args:
|
119
|
+
model: Metabolic model instance
|
120
|
+
parameters: List of parameters to analyze. Uses all if None
|
121
|
+
concs: Initial concentrations {metabolite: value}. Uses model defaults if None
|
122
|
+
time: Time point for evaluation
|
123
|
+
normalized: Whether to normalize coefficients
|
124
|
+
displacement: Relative perturbation size
|
125
|
+
|
126
|
+
Returns:
|
127
|
+
DataFrame with parameter elasticities (reactions x parameters)
|
128
|
+
|
129
|
+
"""
|
130
|
+
concs = model.get_initial_conditions() if concs is None else concs
|
131
|
+
parameters = model.get_parameter_names() if parameters is None else parameters
|
132
|
+
|
133
|
+
elasticities = {}
|
134
|
+
|
135
|
+
concs = model.get_initial_conditions() if concs is None else concs
|
136
|
+
for par in parameters:
|
137
|
+
old = model.parameters[par]
|
138
|
+
|
139
|
+
model.update_parameters({par: old * (1 + displacement)})
|
140
|
+
upper = model.get_fluxes(concs=concs, time=time)
|
141
|
+
|
142
|
+
model.update_parameters({par: old * (1 - displacement)})
|
143
|
+
lower = model.get_fluxes(concs=concs, time=time)
|
144
|
+
|
145
|
+
# Reset
|
146
|
+
model.update_parameters({par: old})
|
147
|
+
elasticity_coef = (upper - lower) / (2 * displacement * old)
|
148
|
+
if normalized:
|
149
|
+
elasticity_coef *= old / model.get_fluxes(concs=concs, time=time)
|
150
|
+
elasticities[par] = elasticity_coef
|
151
|
+
|
152
|
+
return pd.DataFrame(data=elasticities)
|
153
|
+
|
154
|
+
|
155
|
+
# ###############################################################################
|
156
|
+
# # Steady state
|
157
|
+
# ###############################################################################
|
158
|
+
|
159
|
+
|
160
|
+
def _response_coefficient_worker(
|
161
|
+
parameter: str,
|
162
|
+
*,
|
163
|
+
model: Model,
|
164
|
+
y0: dict[str, float] | None,
|
165
|
+
normalized: bool,
|
166
|
+
rel_norm: bool,
|
167
|
+
displacement: float = 1e-4,
|
168
|
+
) -> tuple[pd.Series, pd.Series]:
|
169
|
+
"""Calculate response coefficients for a single parameter.
|
170
|
+
|
171
|
+
Internal helper function that computes concentration and flux response
|
172
|
+
coefficients using finite differences. The function:
|
173
|
+
1. Perturbs the parameter up and down by a small displacement
|
174
|
+
2. Calculates steady states for each perturbation
|
175
|
+
3. Computes response coefficients from the differences
|
176
|
+
4. Optionally normalizes the results
|
177
|
+
|
178
|
+
Args:
|
179
|
+
parameter: Name of the parameter to analyze
|
180
|
+
model: Metabolic model instance
|
181
|
+
y0: Initial conditions as a dictionary {species: value}
|
182
|
+
normalized: Whether to normalize the coefficients
|
183
|
+
rel_norm: Whether to use relative normalization
|
184
|
+
displacement: Relative perturbation size (default: 1e-4)
|
185
|
+
|
186
|
+
Returns:
|
187
|
+
tuple[pd.Series, pd.Series]: Tuple containing:
|
188
|
+
- Series of concentration response coefficients
|
189
|
+
- Series of flux response coefficients
|
190
|
+
|
191
|
+
"""
|
192
|
+
old = model.parameters[parameter]
|
193
|
+
|
194
|
+
model.update_parameters({parameter: old * (1 + displacement)})
|
195
|
+
upper = _steady_state_worker(
|
196
|
+
model,
|
197
|
+
y0=y0,
|
198
|
+
rel_norm=rel_norm,
|
199
|
+
)
|
200
|
+
|
201
|
+
model.update_parameters({parameter: old * (1 - displacement)})
|
202
|
+
lower = _steady_state_worker(
|
203
|
+
model,
|
204
|
+
y0=y0,
|
205
|
+
rel_norm=rel_norm,
|
206
|
+
)
|
207
|
+
|
208
|
+
conc_resp = (upper.concs - lower.concs) / (2 * displacement * old)
|
209
|
+
flux_resp = (upper.fluxes - lower.fluxes) / (2 * displacement * old)
|
210
|
+
# Reset
|
211
|
+
model.update_parameters({parameter: old})
|
212
|
+
if normalized:
|
213
|
+
norm = _steady_state_worker(
|
214
|
+
model,
|
215
|
+
y0=y0,
|
216
|
+
rel_norm=rel_norm,
|
217
|
+
)
|
218
|
+
conc_resp *= old / norm.concs
|
219
|
+
flux_resp *= old / norm.fluxes
|
220
|
+
return conc_resp, flux_resp
|
221
|
+
|
222
|
+
|
223
|
+
def response_coefficients(
|
224
|
+
model: Model,
|
225
|
+
parameters: list[str] | None = None,
|
226
|
+
*,
|
227
|
+
y0: dict[str, float] | None = None,
|
228
|
+
normalized: bool = True,
|
229
|
+
displacement: float = 1e-4,
|
230
|
+
disable_tqdm: bool = False,
|
231
|
+
parallel: bool = True,
|
232
|
+
max_workers: int | None = None,
|
233
|
+
rel_norm: bool = False,
|
234
|
+
) -> ResponseCoefficients:
|
235
|
+
"""Calculate response coefficients.
|
236
|
+
|
237
|
+
Examples:
|
238
|
+
>>> response_coefficients(model, parameters=["k1", "k2"]).concs
|
239
|
+
p x1 x2
|
240
|
+
k1 1.4 1.31
|
241
|
+
k2 -1.0 -2.49
|
242
|
+
|
243
|
+
Args:
|
244
|
+
model: Metabolic model instance
|
245
|
+
parameters: Parameters to analyze. Uses all if None
|
246
|
+
y0: Initial conditions as a dictionary {species: value}
|
247
|
+
normalized: Whether to normalize coefficients
|
248
|
+
displacement: Relative perturbation size
|
249
|
+
disable_tqdm: Disable progress bar
|
250
|
+
parallel: Whether to parallelize the computation
|
251
|
+
max_workers: Maximum number of workers
|
252
|
+
rel_norm: Whether to use relative normalization
|
253
|
+
|
254
|
+
Returns:
|
255
|
+
ResponseCoefficients object containing:
|
256
|
+
- Flux response coefficients
|
257
|
+
- Concentration response coefficients
|
258
|
+
|
259
|
+
"""
|
260
|
+
parameters = model.get_parameter_names() if parameters is None else parameters
|
261
|
+
|
262
|
+
res = parallelise(
|
263
|
+
partial(
|
264
|
+
_response_coefficient_worker,
|
265
|
+
model=model,
|
266
|
+
y0=y0,
|
267
|
+
normalized=normalized,
|
268
|
+
displacement=displacement,
|
269
|
+
rel_norm=rel_norm,
|
270
|
+
),
|
271
|
+
inputs=list(zip(parameters, parameters, strict=True)),
|
272
|
+
cache=None,
|
273
|
+
disable_tqdm=disable_tqdm,
|
274
|
+
parallel=parallel,
|
275
|
+
max_workers=max_workers,
|
276
|
+
)
|
277
|
+
return ResponseCoefficients(
|
278
|
+
concs=pd.DataFrame({k: v[0] for k, v in res.items()}),
|
279
|
+
fluxes=pd.DataFrame({k: v[1] for k, v in res.items()}),
|
280
|
+
)
|