Skip to content

Commit

Permalink
Create standard/schema for Models (#131)
Browse files Browse the repository at this point in the history
* add schema

* rename path args to `filename`

* change `Models` to be a `RootModel`

* update doc links; bump mkstd req

---------

Co-authored-by: Daniel Weindl <dweindl@users.noreply.github.com>
  • Loading branch information
dilpath and dweindl authored Jan 6, 2025
1 parent f8d94d7 commit 8843834
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 68 deletions.
7 changes: 6 additions & 1 deletion doc/problem_definition.rst
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,12 @@ Brief format description
Schema
^^^^^^

The format is provided as `YAML-formatted JSON schema <_static/model.yaml>`_, which enables easy validation with various third-party tools.
The schema are provided as YAML-formatted JSON schema, which enables easy validation with various third-party tools. Schema are provided for:

- `a single model <_static/model.yaml>`_, and
- `a list of models <_static/models.yaml>`_, which is simply a YAML list of the single model format.

Below is the schema for a single model.

.. literalinclude:: standard/model.yaml
:language: yaml
2 changes: 2 additions & 0 deletions doc/standard/make_schemas.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from petab_select.model import ModelStandard
from petab_select.models import ModelsStandard

ModelStandard.save_schema("model.yaml")
ModelsStandard.save_schema("models.yaml")
86 changes: 86 additions & 0 deletions doc/standard/models.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
$defs:
Model:
description: "A model.\n\nSee :class:`ModelBase` for the standardized attributes.\
\ Additional\nattributes are available in ``Model`` to improve usability.\n\n\
Attributes:\n _model_subspace_petab_problem:\n The PEtab problem of\
\ the model subspace of this model.\n If not provided, this is reconstructed\
\ from\n :attr:`model_subspace_petab_yaml`."
properties:
model_subspace_id:
title: Model Subspace Id
type: string
model_subspace_indices:
items:
type: integer
title: Model Subspace Indices
type: array
criteria:
additionalProperties:
type: number
title: Criteria
type: object
model_hash:
$ref: '#/$defs/ModelHash'
default: null
model_subspace_petab_yaml:
anyOf:
- format: path
type: string
- type: 'null'
title: Model Subspace Petab Yaml
estimated_parameters:
anyOf:
- additionalProperties:
type: number
type: object
- type: 'null'
default: null
title: Estimated Parameters
iteration:
anyOf:
- type: integer
- type: 'null'
default: null
title: Iteration
model_id:
default: null
title: Model Id
type: string
parameters:
additionalProperties:
anyOf:
- type: number
- type: integer
- const: estimate
type: string
title: Parameters
type: object
predecessor_model_hash:
$ref: '#/$defs/ModelHash'
default: null
required:
- model_subspace_id
- model_subspace_indices
- model_subspace_petab_yaml
- parameters
title: Model
type: object
ModelHash:
type: string
description: 'A collection of models.
Provide a PEtab Select ``problem`` to the constructor or via
``set_problem``, to use add models by hashes. This means that all models
must belong to the same PEtab Select problem.
This permits both ``list`` and ``dict`` operations -- see
:class:``ListDict`` for further details.'
items:
$ref: '#/$defs/Model'
title: Models
type: array
20 changes: 10 additions & 10 deletions petab_select/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,21 +362,21 @@ def _fix_predecessor_model_hash(self: ModelBase) -> ModelBase:

def to_yaml(
self,
yaml_path: str | Path,
filename: str | Path,
) -> None:
"""Save a model to a YAML file.
All paths will be made relative to the ``yaml_path`` directory.
All paths will be made relative to the ``filename`` directory.
Args:
yaml_path:
The model YAML file location.
filename:
Location of the YAML file.
"""
root_path = Path(yaml_path).parent
root_path = Path(filename).parent

model = copy.deepcopy(self)
model.set_relative_paths(root_path=root_path)
ModelStandard.save_data(data=model, filename=yaml_path)
ModelStandard.save_data(data=model, filename=filename)

def set_relative_paths(self, root_path: str | Path) -> None:
"""Change all paths to be relative to ``root_path``."""
Expand Down Expand Up @@ -686,16 +686,16 @@ def get_parameter_values(

@staticmethod
def from_yaml(
yaml_path: str | Path,
filename: str | Path,
) -> Model:
"""Load a model from a YAML file.
Args:
yaml_path:
The model YAML file location.
filename:
Location of the YAML file.
"""
model = ModelStandard.load_data(
filename=yaml_path, root_path=yaml_path.parent
filename=filename, root_path=Path(filename).parent
)
return model

Expand Down
Loading

0 comments on commit 8843834

Please sign in to comment.