Skip to content

Commit 004be14

Browse files
authored
Add id field to v2.ProblemConfig (#442)
* Update schema * v2.Problem.id * v2.ProblemConfig.id Related to PEtab-dev/PEtab#646. Closes #441.
1 parent f79bba5 commit 004be14

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

petab/schemas/petab_schema.v2.0.0.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ properties:
2323
- type: integer
2424
description: Version of the PEtab format
2525

26+
id:
27+
type: string
28+
description: |
29+
Identifier of the PEtab problem.
30+
31+
This is optional and has no effect on the PEtab problem itself.
32+
pattern: "^[a-zA-Z_]\\w*$"
33+
2634
parameter_files:
2735
type: array
2836
description: |

petab/v2/core.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,6 +1630,18 @@ def mappings(self) -> list[Mapping]:
16301630
chain.from_iterable(mt.mappings for mt in self.mapping_tables)
16311631
)
16321632

1633+
@property
1634+
def id(self) -> str | None:
1635+
"""The ID of the PEtab problem if set, ``None`` otherwise."""
1636+
return self.config.id
1637+
1638+
@id.setter
1639+
def id(self, value: str):
1640+
"""Set the ID of the PEtab problem."""
1641+
if self.config is None:
1642+
self.config = ProblemConfig(format_version="2.0.0")
1643+
self.config.id = value
1644+
16331645
def get_optimization_parameters(self) -> list[str]:
16341646
"""
16351647
Get the list of optimization parameter IDs from parameter table.
@@ -2327,6 +2339,10 @@ class ProblemConfig(BaseModel):
23272339
)
23282340
#: The PEtab format version.
23292341
format_version: str = "2.0.0"
2342+
2343+
#: The problem ID.
2344+
id: str | None = None
2345+
23302346
#: The path to the parameter file, relative to ``base_path``.
23312347
# TODO https://github.com/PEtab-dev/PEtab/pull/641:
23322348
# rename to parameter_files in yaml for consistency with other files?
@@ -2388,6 +2404,9 @@ def to_yaml(self, filename: str | Path):
23882404
data["model_files"][model_id][C.MODEL_LOCATION] = str(
23892405
data["model_files"][model_id]["location"]
23902406
)
2407+
if data["id"] is None:
2408+
# The schema requires a valid id or no id field at all.
2409+
del data["id"]
23912410

23922411
write_yaml(data, filename)
23932412

tests/v2/test_core.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,3 +707,35 @@ def test_petablint_v2(tmpdir):
707707

708708
result = subprocess.run(["petablint", str(Path(tmpdir, "problem.yaml"))]) # noqa: S603,S607
709709
assert result.returncode == 0
710+
711+
712+
def test_problem_id(tmpdir):
713+
"""Test that the problem ID works as expected."""
714+
from jsonschema import ValidationError
715+
716+
def make_yaml(id_line: str) -> str:
717+
return f"""
718+
format_version: 2.0.0
719+
{id_line}
720+
model_files: {{}}
721+
parameter_files: []
722+
observable_files: []
723+
condition_files: []
724+
measurement_files: []
725+
"""
726+
727+
filepath = Path(tmpdir, "problem.yaml")
728+
with open(filepath, "w") as f:
729+
f.write(make_yaml("id: my_problem_id"))
730+
problem = Problem.from_yaml(filepath)
731+
assert problem.id == "my_problem_id"
732+
733+
with open(filepath, "w") as f:
734+
f.write(make_yaml("id: "))
735+
with pytest.raises(ValidationError):
736+
Problem.from_yaml(filepath)
737+
738+
with open(filepath, "w") as f:
739+
f.write(make_yaml(""))
740+
problem = Problem.from_yaml(filepath)
741+
assert problem.id is None

0 commit comments

Comments
 (0)