mxlpy 0.24.0__py3-none-any.whl → 0.25.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 -2
- mxlpy/fit/__init__.py +9 -0
- mxlpy/fit/common.py +298 -0
- mxlpy/fit/global_.py +534 -0
- mxlpy/{fit.py → fit/local_.py} +98 -320
- mxlpy/identify.py +5 -4
- mxlpy/model.py +33 -9
- mxlpy/types.py +171 -0
- {mxlpy-0.24.0.dist-info → mxlpy-0.25.0.dist-info}/METADATA +8 -1
- {mxlpy-0.24.0.dist-info → mxlpy-0.25.0.dist-info}/RECORD +12 -9
- {mxlpy-0.24.0.dist-info → mxlpy-0.25.0.dist-info}/WHEEL +0 -0
- {mxlpy-0.24.0.dist-info → mxlpy-0.25.0.dist-info}/licenses/LICENSE +0 -0
mxlpy/{fit.py → fit/local_.py}
RENAMED
@@ -1,28 +1,39 @@
|
|
1
|
-
"""Parameter
|
1
|
+
"""Parameter local fitting Module for Metabolic Models.
|
2
2
|
|
3
|
-
This module provides functions
|
4
|
-
including both steadyd-state and time-series data fitting capabilities.
|
5
|
-
|
6
|
-
Functions:
|
7
|
-
fit_steady_state: Fits parameters to steady-state experimental data
|
8
|
-
fit_time_course: Fits parameters to time-series experimental data
|
3
|
+
This module provides functions for fitting model parameters to experimental data,
|
4
|
+
including both steadyd-state and time-series data fitting capabilities.
|
9
5
|
"""
|
10
6
|
|
11
7
|
from __future__ import annotations
|
12
8
|
|
13
9
|
import logging
|
10
|
+
from collections.abc import Callable
|
14
11
|
from copy import deepcopy
|
15
12
|
from dataclasses import dataclass
|
16
13
|
from functools import partial
|
17
|
-
from typing import TYPE_CHECKING,
|
14
|
+
from typing import TYPE_CHECKING, Literal
|
18
15
|
|
19
|
-
import numpy as np
|
20
16
|
from scipy.optimize import minimize
|
21
|
-
from wadler_lindig import pformat
|
22
17
|
|
23
18
|
from mxlpy import parallel
|
24
|
-
from mxlpy.
|
25
|
-
|
19
|
+
from mxlpy.types import IntegratorType, cast
|
20
|
+
|
21
|
+
from .common import (
|
22
|
+
Bounds,
|
23
|
+
CarouselFit,
|
24
|
+
FitResult,
|
25
|
+
InitialGuess,
|
26
|
+
LossFn,
|
27
|
+
MinResult,
|
28
|
+
ProtocolResidualFn,
|
29
|
+
ResidualFn,
|
30
|
+
SteadyStateResidualFn,
|
31
|
+
TimeSeriesResidualFn,
|
32
|
+
_protocol_time_course_residual,
|
33
|
+
_steady_state_residual,
|
34
|
+
_time_course_residual,
|
35
|
+
rmse,
|
36
|
+
)
|
26
37
|
|
27
38
|
if TYPE_CHECKING:
|
28
39
|
import pandas as pd
|
@@ -33,72 +44,19 @@ if TYPE_CHECKING:
|
|
33
44
|
LOGGER = logging.getLogger(__name__)
|
34
45
|
|
35
46
|
__all__ = [
|
36
|
-
"Bounds",
|
37
|
-
"CarouselFit",
|
38
|
-
"FitResult",
|
39
|
-
"InitialGuess",
|
40
47
|
"LOGGER",
|
41
|
-
"
|
42
|
-
"
|
43
|
-
"MinimizeFn",
|
44
|
-
"ProtocolResidualFn",
|
45
|
-
"ResidualFn",
|
46
|
-
"SteadyStateResidualFn",
|
47
|
-
"TimeSeriesResidualFn",
|
48
|
+
"Minimizer",
|
49
|
+
"ScipyMinimizer",
|
48
50
|
"carousel_protocol_time_course",
|
49
51
|
"carousel_steady_state",
|
50
52
|
"carousel_time_course",
|
51
53
|
"protocol_time_course",
|
52
|
-
"rmse",
|
53
54
|
"steady_state",
|
54
55
|
"time_course",
|
55
56
|
]
|
56
57
|
|
57
58
|
|
58
|
-
|
59
|
-
class MinResult:
|
60
|
-
"""Result of a minimization operation."""
|
61
|
-
|
62
|
-
parameters: dict[str, float]
|
63
|
-
residual: float
|
64
|
-
|
65
|
-
def __repr__(self) -> str:
|
66
|
-
"""Return default representation."""
|
67
|
-
return pformat(self)
|
68
|
-
|
69
|
-
|
70
|
-
@dataclass
|
71
|
-
class FitResult:
|
72
|
-
"""Result of a fit operation."""
|
73
|
-
|
74
|
-
model: Model
|
75
|
-
best_pars: dict[str, float]
|
76
|
-
loss: float
|
77
|
-
|
78
|
-
def __repr__(self) -> str:
|
79
|
-
"""Return default representation."""
|
80
|
-
return pformat(self)
|
81
|
-
|
82
|
-
|
83
|
-
@dataclass
|
84
|
-
class CarouselFit:
|
85
|
-
"""Result of a carousel fit operation."""
|
86
|
-
|
87
|
-
fits: list[FitResult]
|
88
|
-
|
89
|
-
def __repr__(self) -> str:
|
90
|
-
"""Return default representation."""
|
91
|
-
return pformat(self)
|
92
|
-
|
93
|
-
def get_best_fit(self) -> FitResult:
|
94
|
-
"""Get the best fit from the carousel."""
|
95
|
-
return min(self.fits, key=lambda x: x.loss)
|
96
|
-
|
97
|
-
|
98
|
-
type InitialGuess = dict[str, float]
|
99
|
-
type ResidualFn = Callable[[Array], float]
|
100
|
-
type Bounds = dict[str, tuple[float | None, float | None]]
|
101
|
-
type MinimizeFn = Callable[
|
59
|
+
type Minimizer = Callable[
|
102
60
|
[
|
103
61
|
ResidualFn,
|
104
62
|
InitialGuess,
|
@@ -106,248 +64,68 @@ type MinimizeFn = Callable[
|
|
106
64
|
],
|
107
65
|
MinResult | None,
|
108
66
|
]
|
109
|
-
type LossFn = Callable[
|
110
|
-
[
|
111
|
-
pd.DataFrame | pd.Series,
|
112
|
-
pd.DataFrame | pd.Series,
|
113
|
-
],
|
114
|
-
float,
|
115
|
-
]
|
116
|
-
|
117
67
|
|
118
|
-
def rmse(
|
119
|
-
y_pred: pd.DataFrame | pd.Series,
|
120
|
-
y_true: pd.DataFrame | pd.Series,
|
121
|
-
) -> float:
|
122
|
-
"""Calculate root mean square error between model and data."""
|
123
|
-
return cast(float, np.sqrt(np.mean(np.square(y_pred - y_true))))
|
124
68
|
|
69
|
+
@dataclass
|
70
|
+
class ScipyMinimizer:
|
71
|
+
"""Local multivariate minimization using scipy.optimize.
|
125
72
|
|
126
|
-
|
127
|
-
|
73
|
+
See Also
|
74
|
+
--------
|
75
|
+
https://docs.scipy.org/doc/scipy/reference/optimize.html#local-multivariate-optimization
|
128
76
|
|
129
|
-
|
130
|
-
self,
|
131
|
-
par_values: Array,
|
132
|
-
# This will be filled out by partial
|
133
|
-
par_names: list[str],
|
134
|
-
data: pd.Series,
|
135
|
-
model: Model,
|
136
|
-
y0: dict[str, float] | None,
|
137
|
-
integrator: IntegratorType,
|
138
|
-
loss_fn: LossFn,
|
139
|
-
) -> float:
|
140
|
-
"""Calculate residual error between model steady state and experimental data."""
|
141
|
-
...
|
142
|
-
|
143
|
-
|
144
|
-
class TimeSeriesResidualFn(Protocol):
|
145
|
-
"""Protocol for time series residual functions."""
|
77
|
+
"""
|
146
78
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
""
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
79
|
+
tol: float = 1e-6
|
80
|
+
method: Literal[
|
81
|
+
"Nelder-Mead",
|
82
|
+
"Powell",
|
83
|
+
"CG",
|
84
|
+
"BFGS",
|
85
|
+
"Newton-CG",
|
86
|
+
"L-BFGS-B",
|
87
|
+
"TNC",
|
88
|
+
"COBYLA",
|
89
|
+
"COBYQA",
|
90
|
+
"SLSQP",
|
91
|
+
"trust-constr",
|
92
|
+
"dogleg",
|
93
|
+
"trust-ncg",
|
94
|
+
"trust-exact",
|
95
|
+
"trust-krylov",
|
96
|
+
] = "L-BFGS-B"
|
164
97
|
|
165
98
|
def __call__(
|
166
99
|
self,
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
...
|
179
|
-
|
180
|
-
|
181
|
-
def _default_minimize_fn(
|
182
|
-
residual_fn: ResidualFn,
|
183
|
-
p0: dict[str, float],
|
184
|
-
bounds: Bounds,
|
185
|
-
) -> MinResult | None:
|
186
|
-
res = minimize(
|
187
|
-
residual_fn,
|
188
|
-
x0=list(p0.values()),
|
189
|
-
bounds=[bounds.get(name, (1e-6, 1e6)) for name in p0],
|
190
|
-
method="L-BFGS-B",
|
191
|
-
)
|
192
|
-
if res.success:
|
193
|
-
return MinResult(
|
194
|
-
parameters=dict(
|
195
|
-
zip(
|
196
|
-
p0,
|
197
|
-
res.x,
|
198
|
-
strict=True,
|
199
|
-
),
|
200
|
-
),
|
201
|
-
residual=res.fun,
|
100
|
+
residual_fn: ResidualFn,
|
101
|
+
p0: dict[str, float],
|
102
|
+
bounds: Bounds,
|
103
|
+
) -> MinResult | None:
|
104
|
+
"""Call minimzer."""
|
105
|
+
res = minimize(
|
106
|
+
residual_fn,
|
107
|
+
x0=list(p0.values()),
|
108
|
+
bounds=[bounds.get(name, (1e-6, 1e6)) for name in p0],
|
109
|
+
method=self.method,
|
110
|
+
tol=self.tol,
|
202
111
|
)
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
def _steady_state_residual(
|
209
|
-
par_values: Array,
|
210
|
-
# This will be filled out by partial
|
211
|
-
par_names: list[str],
|
212
|
-
data: pd.Series,
|
213
|
-
model: Model,
|
214
|
-
y0: dict[str, float] | None,
|
215
|
-
integrator: IntegratorType,
|
216
|
-
loss_fn: LossFn,
|
217
|
-
) -> float:
|
218
|
-
"""Calculate residual error between model steady state and experimental data.
|
219
|
-
|
220
|
-
Args:
|
221
|
-
par_values: Parameter values to test
|
222
|
-
data: Experimental steady state data
|
223
|
-
model: Model instance to simulate
|
224
|
-
y0: Initial conditions
|
225
|
-
par_names: Names of parameters being fit
|
226
|
-
integrator: ODE integrator class to use
|
227
|
-
loss_fn: Loss function to use for residual calculation
|
228
|
-
|
229
|
-
Returns:
|
230
|
-
float: Root mean square error between model and data
|
231
|
-
|
232
|
-
"""
|
233
|
-
res = (
|
234
|
-
Simulator(
|
235
|
-
model.update_parameters(
|
236
|
-
dict(
|
112
|
+
if res.success:
|
113
|
+
return MinResult(
|
114
|
+
parameters=dict(
|
237
115
|
zip(
|
238
|
-
|
239
|
-
|
116
|
+
p0,
|
117
|
+
res.x,
|
240
118
|
strict=True,
|
241
|
-
)
|
242
|
-
)
|
243
|
-
|
244
|
-
|
245
|
-
integrator=integrator,
|
246
|
-
)
|
247
|
-
.simulate_to_steady_state()
|
248
|
-
.get_result()
|
249
|
-
)
|
250
|
-
if res is None:
|
251
|
-
return cast(float, np.inf)
|
252
|
-
|
253
|
-
return loss_fn(
|
254
|
-
res.get_combined().loc[:, cast(list, data.index)],
|
255
|
-
data,
|
256
|
-
)
|
257
|
-
|
258
|
-
|
259
|
-
def _time_course_residual(
|
260
|
-
par_values: ArrayLike,
|
261
|
-
# This will be filled out by partial
|
262
|
-
par_names: list[str],
|
263
|
-
data: pd.DataFrame,
|
264
|
-
model: Model,
|
265
|
-
y0: dict[str, float] | None,
|
266
|
-
integrator: IntegratorType,
|
267
|
-
loss_fn: LossFn,
|
268
|
-
) -> float:
|
269
|
-
"""Calculate residual error between model time course and experimental data.
|
270
|
-
|
271
|
-
Args:
|
272
|
-
par_values: Parameter values to test
|
273
|
-
data: Experimental time course data
|
274
|
-
model: Model instance to simulate
|
275
|
-
y0: Initial conditions
|
276
|
-
par_names: Names of parameters being fit
|
277
|
-
integrator: ODE integrator class to use
|
278
|
-
loss_fn: Loss function to use for residual calculation
|
279
|
-
|
280
|
-
Returns:
|
281
|
-
float: Root mean square error between model and data
|
282
|
-
|
283
|
-
"""
|
284
|
-
res = (
|
285
|
-
Simulator(
|
286
|
-
model.update_parameters(dict(zip(par_names, par_values, strict=True))),
|
287
|
-
y0=y0,
|
288
|
-
integrator=integrator,
|
289
|
-
)
|
290
|
-
.simulate_time_course(cast(list, data.index))
|
291
|
-
.get_result()
|
292
|
-
)
|
293
|
-
if res is None:
|
294
|
-
return cast(float, np.inf)
|
295
|
-
results_ss = res.get_combined()
|
296
|
-
|
297
|
-
return loss_fn(
|
298
|
-
results_ss.loc[:, cast(list, data.columns)],
|
299
|
-
data,
|
300
|
-
)
|
301
|
-
|
302
|
-
|
303
|
-
def _protocol_time_course_residual(
|
304
|
-
par_values: ArrayLike,
|
305
|
-
# This will be filled out by partial
|
306
|
-
par_names: list[str],
|
307
|
-
data: pd.DataFrame,
|
308
|
-
model: Model,
|
309
|
-
y0: dict[str, float] | None,
|
310
|
-
integrator: IntegratorType,
|
311
|
-
loss_fn: LossFn,
|
312
|
-
protocol: pd.DataFrame,
|
313
|
-
) -> float:
|
314
|
-
"""Calculate residual error between model time course and experimental data.
|
315
|
-
|
316
|
-
Args:
|
317
|
-
par_values: Parameter values to test
|
318
|
-
data: Experimental time course data
|
319
|
-
model: Model instance to simulate
|
320
|
-
y0: Initial conditions
|
321
|
-
par_names: Names of parameters being fit
|
322
|
-
integrator: ODE integrator class to use
|
323
|
-
loss_fn: Loss function to use for residual calculation
|
324
|
-
protocol: Experimental protocol
|
325
|
-
time_points_per_step: Number of time points per step in the protocol
|
119
|
+
),
|
120
|
+
),
|
121
|
+
residual=res.fun,
|
122
|
+
)
|
326
123
|
|
327
|
-
|
328
|
-
|
124
|
+
LOGGER.warning("Minimisation failed due to %s", res.message)
|
125
|
+
return None
|
329
126
|
|
330
|
-
"""
|
331
|
-
res = (
|
332
|
-
Simulator(
|
333
|
-
model.update_parameters(dict(zip(par_names, par_values, strict=True))),
|
334
|
-
y0=y0,
|
335
|
-
integrator=integrator,
|
336
|
-
)
|
337
|
-
.simulate_protocol_time_course(
|
338
|
-
protocol=protocol,
|
339
|
-
time_points=data.index,
|
340
|
-
)
|
341
|
-
.get_result()
|
342
|
-
)
|
343
|
-
if res is None:
|
344
|
-
return cast(float, np.inf)
|
345
|
-
results_ss = res.get_combined()
|
346
127
|
|
347
|
-
|
348
|
-
results_ss.loc[:, cast(list, data.columns)],
|
349
|
-
data,
|
350
|
-
)
|
128
|
+
_default_minimizer = ScipyMinimizer()
|
351
129
|
|
352
130
|
|
353
131
|
def _carousel_steady_state_worker(
|
@@ -357,7 +135,7 @@ def _carousel_steady_state_worker(
|
|
357
135
|
y0: dict[str, float] | None,
|
358
136
|
integrator: IntegratorType | None,
|
359
137
|
loss_fn: LossFn,
|
360
|
-
|
138
|
+
minimizer: Minimizer,
|
361
139
|
residual_fn: SteadyStateResidualFn,
|
362
140
|
bounds: Bounds | None,
|
363
141
|
) -> FitResult | None:
|
@@ -368,7 +146,7 @@ def _carousel_steady_state_worker(
|
|
368
146
|
p0={k: v for k, v in p0.items() if k in model_pars},
|
369
147
|
y0=y0,
|
370
148
|
data=data,
|
371
|
-
|
149
|
+
minimizer=minimizer,
|
372
150
|
residual_fn=residual_fn,
|
373
151
|
integrator=integrator,
|
374
152
|
loss_fn=loss_fn,
|
@@ -383,7 +161,7 @@ def _carousel_time_course_worker(
|
|
383
161
|
y0: dict[str, float] | None,
|
384
162
|
integrator: IntegratorType | None,
|
385
163
|
loss_fn: LossFn,
|
386
|
-
|
164
|
+
minimizer: Minimizer,
|
387
165
|
residual_fn: TimeSeriesResidualFn,
|
388
166
|
bounds: Bounds | None,
|
389
167
|
) -> FitResult | None:
|
@@ -393,7 +171,7 @@ def _carousel_time_course_worker(
|
|
393
171
|
p0={k: v for k, v in p0.items() if k in model_pars},
|
394
172
|
y0=y0,
|
395
173
|
data=data,
|
396
|
-
|
174
|
+
minimizer=minimizer,
|
397
175
|
residual_fn=residual_fn,
|
398
176
|
integrator=integrator,
|
399
177
|
loss_fn=loss_fn,
|
@@ -409,7 +187,7 @@ def _carousel_protocol_worker(
|
|
409
187
|
y0: dict[str, float] | None,
|
410
188
|
integrator: IntegratorType | None,
|
411
189
|
loss_fn: LossFn,
|
412
|
-
|
190
|
+
minimizer: Minimizer,
|
413
191
|
residual_fn: ProtocolResidualFn,
|
414
192
|
bounds: Bounds | None,
|
415
193
|
) -> FitResult | None:
|
@@ -420,7 +198,7 @@ def _carousel_protocol_worker(
|
|
420
198
|
y0=y0,
|
421
199
|
protocol=protocol,
|
422
200
|
data=data,
|
423
|
-
|
201
|
+
minimizer=minimizer,
|
424
202
|
residual_fn=residual_fn,
|
425
203
|
integrator=integrator,
|
426
204
|
loss_fn=loss_fn,
|
@@ -434,7 +212,7 @@ def steady_state(
|
|
434
212
|
p0: dict[str, float],
|
435
213
|
data: pd.Series,
|
436
214
|
y0: dict[str, float] | None = None,
|
437
|
-
|
215
|
+
minimizer: Minimizer = _default_minimizer,
|
438
216
|
residual_fn: SteadyStateResidualFn = _steady_state_residual,
|
439
217
|
integrator: IntegratorType | None = None,
|
440
218
|
loss_fn: LossFn = rmse,
|
@@ -451,7 +229,7 @@ def steady_state(
|
|
451
229
|
data: Experimental steady state data as pandas Series
|
452
230
|
p0: Initial parameter guesses as {parameter_name: value}
|
453
231
|
y0: Initial conditions as {species_name: value}
|
454
|
-
|
232
|
+
minimizer: Function to minimize fitting error
|
455
233
|
residual_fn: Function to calculate fitting error
|
456
234
|
integrator: ODE integrator class
|
457
235
|
loss_fn: Loss function to use for residual calculation
|
@@ -481,7 +259,7 @@ def steady_state(
|
|
481
259
|
loss_fn=loss_fn,
|
482
260
|
),
|
483
261
|
)
|
484
|
-
min_result =
|
262
|
+
min_result = minimizer(fn, p0, {} if bounds is None else bounds)
|
485
263
|
# Restore original model
|
486
264
|
model.update_parameters(p_orig)
|
487
265
|
if min_result is None:
|
@@ -500,7 +278,7 @@ def time_course(
|
|
500
278
|
p0: dict[str, float],
|
501
279
|
data: pd.DataFrame,
|
502
280
|
y0: dict[str, float] | None = None,
|
503
|
-
|
281
|
+
minimizer: Minimizer = _default_minimizer,
|
504
282
|
residual_fn: TimeSeriesResidualFn = _time_course_residual,
|
505
283
|
integrator: IntegratorType | None = None,
|
506
284
|
loss_fn: LossFn = rmse,
|
@@ -517,7 +295,7 @@ def time_course(
|
|
517
295
|
data: Experimental time course data
|
518
296
|
p0: Initial parameter guesses as {parameter_name: value}
|
519
297
|
y0: Initial conditions as {species_name: value}
|
520
|
-
|
298
|
+
minimizer: Function to minimize fitting error
|
521
299
|
residual_fn: Function to calculate fitting error
|
522
300
|
integrator: ODE integrator class
|
523
301
|
loss_fn: Loss function to use for residual calculation
|
@@ -546,7 +324,7 @@ def time_course(
|
|
546
324
|
),
|
547
325
|
)
|
548
326
|
|
549
|
-
min_result =
|
327
|
+
min_result = minimizer(fn, p0, {} if bounds is None else bounds)
|
550
328
|
# Restore original model
|
551
329
|
model.update_parameters(p_orig)
|
552
330
|
if min_result is None:
|
@@ -566,7 +344,7 @@ def protocol_time_course(
|
|
566
344
|
data: pd.DataFrame,
|
567
345
|
protocol: pd.DataFrame,
|
568
346
|
y0: dict[str, float] | None = None,
|
569
|
-
|
347
|
+
minimizer: Minimizer = _default_minimizer,
|
570
348
|
residual_fn: ProtocolResidualFn = _protocol_time_course_residual,
|
571
349
|
integrator: IntegratorType | None = None,
|
572
350
|
loss_fn: LossFn = rmse,
|
@@ -586,7 +364,7 @@ def protocol_time_course(
|
|
586
364
|
data: Experimental time course data
|
587
365
|
protocol: Experimental protocol
|
588
366
|
y0: Initial conditions as {species_name: value}
|
589
|
-
|
367
|
+
minimizer: Function to minimize fitting error
|
590
368
|
residual_fn: Function to calculate fitting error
|
591
369
|
integrator: ODE integrator class
|
592
370
|
loss_fn: Loss function to use for residual calculation
|
@@ -617,7 +395,7 @@ def protocol_time_course(
|
|
617
395
|
),
|
618
396
|
)
|
619
397
|
|
620
|
-
min_result =
|
398
|
+
min_result = minimizer(fn, p0, {} if bounds is None else bounds)
|
621
399
|
# Restore original model
|
622
400
|
model.update_parameters(p_orig)
|
623
401
|
if min_result is None:
|
@@ -636,7 +414,7 @@ def carousel_steady_state(
|
|
636
414
|
p0: dict[str, float],
|
637
415
|
data: pd.Series,
|
638
416
|
y0: dict[str, float] | None = None,
|
639
|
-
|
417
|
+
minimizer: Minimizer = _default_minimizer,
|
640
418
|
residual_fn: SteadyStateResidualFn = _steady_state_residual,
|
641
419
|
integrator: IntegratorType | None = None,
|
642
420
|
loss_fn: LossFn = rmse,
|
@@ -653,7 +431,7 @@ def carousel_steady_state(
|
|
653
431
|
data: Experimental time course data
|
654
432
|
protocol: Experimental protocol
|
655
433
|
y0: Initial conditions as {species_name: value}
|
656
|
-
|
434
|
+
minimizer: Function to minimize fitting error
|
657
435
|
residual_fn: Function to calculate fitting error
|
658
436
|
integrator: ODE integrator class
|
659
437
|
loss_fn: Loss function to use for residual calculation
|
@@ -678,7 +456,7 @@ def carousel_steady_state(
|
|
678
456
|
y0=y0,
|
679
457
|
integrator=integrator,
|
680
458
|
loss_fn=loss_fn,
|
681
|
-
|
459
|
+
minimizer=minimizer,
|
682
460
|
residual_fn=residual_fn,
|
683
461
|
bounds=bounds,
|
684
462
|
),
|
@@ -695,7 +473,7 @@ def carousel_time_course(
|
|
695
473
|
p0: dict[str, float],
|
696
474
|
data: pd.DataFrame,
|
697
475
|
y0: dict[str, float] | None = None,
|
698
|
-
|
476
|
+
minimizer: Minimizer = _default_minimizer,
|
699
477
|
residual_fn: TimeSeriesResidualFn = _time_course_residual,
|
700
478
|
integrator: IntegratorType | None = None,
|
701
479
|
loss_fn: LossFn = rmse,
|
@@ -714,7 +492,7 @@ def carousel_time_course(
|
|
714
492
|
data: Experimental time course data
|
715
493
|
protocol: Experimental protocol
|
716
494
|
y0: Initial conditions as {species_name: value}
|
717
|
-
|
495
|
+
minimizer: Function to minimize fitting error
|
718
496
|
residual_fn: Function to calculate fitting error
|
719
497
|
integrator: ODE integrator class
|
720
498
|
loss_fn: Loss function to use for residual calculation
|
@@ -739,7 +517,7 @@ def carousel_time_course(
|
|
739
517
|
y0=y0,
|
740
518
|
integrator=integrator,
|
741
519
|
loss_fn=loss_fn,
|
742
|
-
|
520
|
+
minimizer=minimizer,
|
743
521
|
residual_fn=residual_fn,
|
744
522
|
bounds=bounds,
|
745
523
|
),
|
@@ -757,7 +535,7 @@ def carousel_protocol_time_course(
|
|
757
535
|
data: pd.DataFrame,
|
758
536
|
protocol: pd.DataFrame,
|
759
537
|
y0: dict[str, float] | None = None,
|
760
|
-
|
538
|
+
minimizer: Minimizer = _default_minimizer,
|
761
539
|
residual_fn: ProtocolResidualFn = _protocol_time_course_residual,
|
762
540
|
integrator: IntegratorType | None = None,
|
763
541
|
loss_fn: LossFn = rmse,
|
@@ -776,7 +554,7 @@ def carousel_protocol_time_course(
|
|
776
554
|
data: Experimental time course data
|
777
555
|
protocol: Experimental protocol
|
778
556
|
y0: Initial conditions as {species_name: value}
|
779
|
-
|
557
|
+
minimizer: Function to minimize fitting error
|
780
558
|
residual_fn: Function to calculate fitting error
|
781
559
|
integrator: ODE integrator class
|
782
560
|
loss_fn: Loss function to use for residual calculation
|
@@ -802,7 +580,7 @@ def carousel_protocol_time_course(
|
|
802
580
|
y0=y0,
|
803
581
|
integrator=integrator,
|
804
582
|
loss_fn=loss_fn,
|
805
|
-
|
583
|
+
minimizer=minimizer,
|
806
584
|
residual_fn=residual_fn,
|
807
585
|
bounds=bounds,
|
808
586
|
),
|
mxlpy/identify.py
CHANGED
@@ -9,8 +9,9 @@ import numpy as np
|
|
9
9
|
import pandas as pd
|
10
10
|
from tqdm import tqdm
|
11
11
|
|
12
|
-
from mxlpy import
|
12
|
+
from mxlpy import fit_local
|
13
13
|
from mxlpy.distributions import LogNormal, sample
|
14
|
+
from mxlpy.fit.common import LossFn, rmse
|
14
15
|
from mxlpy.parallel import parallelise
|
15
16
|
|
16
17
|
if TYPE_CHECKING:
|
@@ -26,9 +27,9 @@ def _mc_fit_time_course_worker(
|
|
26
27
|
p0: pd.Series,
|
27
28
|
model: Model,
|
28
29
|
data: pd.DataFrame,
|
29
|
-
loss_fn:
|
30
|
+
loss_fn: fit_local.LossFn,
|
30
31
|
) -> float:
|
31
|
-
fit_result =
|
32
|
+
fit_result = fit_local.time_course(
|
32
33
|
model=model,
|
33
34
|
p0=p0.to_dict(),
|
34
35
|
data=data,
|
@@ -45,7 +46,7 @@ def profile_likelihood(
|
|
45
46
|
parameter_name: str,
|
46
47
|
parameter_values: Array,
|
47
48
|
n_random: int = 10,
|
48
|
-
loss_fn:
|
49
|
+
loss_fn: LossFn = rmse,
|
49
50
|
) -> pd.Series:
|
50
51
|
"""Estimate the profile likelihood of model parameters given data.
|
51
52
|
|