Skip to content
Merged

Dev #67

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions physiofit/base/fitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,9 @@ def aic_test(self):
k = len(self.model.parameters) + 1 # +1 for the cost parameter
logger.debug(f"Number of measurements: {n}")
logger.debug(f"Number of parameters: {k}")
if n - k - 1 <= 0:
self.aic = self.aic_c = "NA"
raise ValueError("Not enough measurements to calculate AIC")
cost = self._calculate_cost(
self.optimize_results.x,
self.model.simulate,
Expand All @@ -516,8 +519,6 @@ def aic_test(self):
self.aic = 2 * k + n * np.log(cost)
logger.debug(f"AIC: {self.aic}")
# Correct AIC for small sample sizes
if n - k - 1 <= 0:
raise ValueError("Not enough measurements to calculate AIC")
self.aic_c = self.aic + ((2 * k * (k + 1)) / (n - k - 1))

self.aic_res = pd.DataFrame.from_dict(
Expand Down
4 changes: 4 additions & 0 deletions physiofit/base/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ def select_model(
for model in self.models:
if model.name == name:
return model
available = ", ".join(sorted({model.name for model in self.models}))
raise ValueError(
f"Unknown model '{name}'. Available models: {available}"
)

@staticmethod
def read_model(
Expand Down
37 changes: 37 additions & 0 deletions physiofit/tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import pandas as pd
import pytest
import physiofit
import physiofit.base.io

logging.getLogger("physiofit").setLevel(logging.ERROR)

Expand Down Expand Up @@ -118,3 +119,39 @@ def test_that_simulated_and_experimental_matrices_are_close(base_test_data):
rtol=1e-3,
equal_nan=True
)


def test_aic_with_too_few_measurements():
"""
With fewer measurements than the small-sample correction needs, the AIC
test raises and both AIC values are set to "NA"
"""

data = pd.DataFrame(
{
"time": [0.0, 1.0, 2.0],
"X": [0.1, 0.2, 0.4],
"Glucose": [10.0, 9.0, 7.0],
}
)
io = physiofit.base.io.IoHandler()
model = io.select_model("Steady-state batch model", data)
model.get_params()
fitter = io.initialize_fitter(
model.data,
model=model,
sd=0.2,
debug_mode=False
)
fitter.optimize()
with pytest.raises(ValueError, match="Not enough measurements"):
fitter.aic_test()
assert fitter.aic == "NA"
assert fitter.aic_c == "NA"
assert fitter.aic_res is None


def test_select_unknown_model(base_test_data):
io = physiofit.base.io.IoHandler()
with pytest.raises(ValueError, match="Steady-state batch model"):
io.select_model("Unknown model", base_test_data)
1 change: 0 additions & 1 deletion physiofit/ui/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ def run(data, args, experiments):
logger.warning(
"Not enough measurements to calculate AIC"
)
fitter.aic, fitter.aic_c = "NA"
df = pd.DataFrame.from_dict(
fitter.parameter_stats,
orient="columns"
Expand Down
1 change: 0 additions & 1 deletion physiofit/ui/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ def _run(self):
logger.warning(
"Not enough measurements to calculate AIC"
)
fitter.aic, fitter.aic_c = "NA"
df = pd.DataFrame.from_dict(
fitter.parameter_stats,
orient="columns"
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "physiofit"
version = "3.4.0"
version = "3.4.1"
description = "Calculate extracellular fluxes from metabolite concentrations and biomass data"
authors = ["llegregam <legregam@insa-toulouse.fr>"]
license = "GNU General Public License (GPL)"
Expand Down
Loading