Skip to content

Commit e94ea6f

Browse files
FFroehlichclaude
andauthored
Fix JAXProblem.save()/load() round-trip against current petab.v2 API (#3204)
petab.v2.Problem.to_files() was simplified from a many-keyword-argument signature to to_files(base_path), which relies on each table/model already having rel_path/base_path set (normally done by Problem.from_yaml). JAXProblem.save() still called the old signature (prefix_path=..., model_file=..., condition_file=..., ...), raising TypeError. Fixed to set config.filepath = "problem.yaml" (so the written YAML has the name JAXProblem.load() expects) and call to_files(base_path=directory). This was masked by a broader skip-guard in test_serialisation; getting past that guard also required fixing a prerequisite bug in import_petab_problem(..., jax=True): it passed the original PEtab v1 problem straight into JAXProblem(), which rejects v1 problems outright. Upgrade v1->v2 via to_files_generic/from_yaml first, mirroring the conversion used elsewhere in the codebase. Removed the now-unneeded try/except skip-guard from test_serialisation so it actually asserts the round trip. Left the equivalent guard on test_preequilibration_failure alone, since that covers a separate, already-known bug in the preequilibration-condition heuristic. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
1 parent 6d10d6f commit e94ea6f

3 files changed

Lines changed: 34 additions & 30 deletions

File tree

python/sdist/amici/importers/petab/v1/_petab_import.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ def import_petab_problem(
255255
)
256256

257257
if jax:
258+
import tempfile
259+
260+
import petab.v2 as petabv2
261+
258262
from amici.sim.jax import JAXProblem
259263

260264
model = model_module.Model()
@@ -263,9 +267,17 @@ def import_petab_problem(
263267
f"Successfully loaded jax model {model_name} from {output_dir}."
264268
)
265269

270+
# JAXProblem requires a PEtab v2 problem; upgrade the v1 problem by
271+
# serializing it to a temporary PEtab v1 problem on disk and letting
272+
# petab auto-upgrade it (``petab.v2.Problem.from_yaml`` upgrades v1
273+
# YAML files via ``petab1to2``).
274+
with tempfile.TemporaryDirectory() as tmp_dir:
275+
yaml_path = petab_problem.to_files_generic(prefix_path=tmp_dir)
276+
petab_problem_v2 = petabv2.Problem.from_yaml(yaml_path)
277+
266278
# Create and return JAXProblem
267279
logger.info(f"Successfully created JAXProblem for {model_name}.")
268-
return JAXProblem(model, petab_problem)
280+
return JAXProblem(model, petab_problem_v2)
269281

270282
model = model_module.get_model()
271283
check_model(amici_model=model, petab_problem=petab_problem)

python/sdist/amici/sim/jax/petab.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,12 @@ def save(self, directory: Path):
183183
:param directory:
184184
Directory to save the problem to.
185185
"""
186-
self._petab_problem.to_files(
187-
prefix_path=directory,
188-
model_file="model",
189-
condition_file="conditions.tsv",
190-
measurement_file="measurements.tsv",
191-
parameter_file="parameters.tsv",
192-
observable_file="observables.tsv",
193-
yaml_file="problem.yaml",
194-
)
186+
if self._petab_problem.config is None:
187+
self._petab_problem.config = petabv2.ProblemConfig(
188+
format_version="2.0.0"
189+
)
190+
self._petab_problem.config.filepath = "problem.yaml"
191+
self._petab_problem.to_files(base_path=directory)
195192
shutil.copy(self.model.jax_py_file, directory / "jax_py_file.py")
196193
with open(directory / "parameters.pkl", "wb") as f:
197194
eqx.tree_serialise_leaves(f, self)

python/tests/test_jax.py

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -313,27 +313,22 @@ def test_serialisation(lotka_volterra): # noqa: F811
313313
with TemporaryDirectoryWinSafe(
314314
prefix=petab_problem.model.model_id
315315
) as model_dir:
316-
try:
317-
jax_problem = import_petab_problem(
318-
petab_problem, jax=True, output_dir=model_dir
319-
)
320-
# change parameters to random values to test serialisation
321-
jax_problem.update_parameters(
322-
jax_problem.parameters
323-
+ jr.normal(jr.PRNGKey(0), jax_problem.parameters.shape)
324-
)
316+
jax_problem = import_petab_problem(
317+
petab_problem, jax=True, output_dir=model_dir
318+
)
319+
# change parameters to random values to test serialisation
320+
jax_problem.update_parameters(
321+
jax_problem.parameters
322+
+ jr.normal(jr.PRNGKey(0), jax_problem.parameters.shape)
323+
)
325324

326-
with TemporaryDirectoryWinSafe() as outdir:
327-
outdir = Path(outdir)
328-
jax_problem.save(outdir)
329-
jax_problem_loaded = JAXProblem.load(outdir)
330-
assert_allclose(
331-
jax_problem.parameters, jax_problem_loaded.parameters
332-
)
333-
except (TypeError, NotImplementedError) as err:
334-
if "JAXProblem does not support PEtab v1 problems" in str(err):
335-
pytest.skip(str(err))
336-
raise err
325+
with TemporaryDirectoryWinSafe() as outdir:
326+
outdir = Path(outdir)
327+
jax_problem.save(outdir)
328+
jax_problem_loaded = JAXProblem.load(outdir)
329+
assert_allclose(
330+
jax_problem.parameters, jax_problem_loaded.parameters
331+
)
337332

338333

339334
@skip_on_valgrind

0 commit comments

Comments
 (0)