Skip to content

Commit d3d6e9e

Browse files
committed
fix serialization / validation
1 parent d54a003 commit d3d6e9e

File tree

1 file changed

+29
-14
lines changed

1 file changed

+29
-14
lines changed

petab/v2/core.py

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -503,9 +503,13 @@ class ExperimentPeriod(BaseModel):
503503
@field_validator("condition_ids", mode="before")
504504
@classmethod
505505
def _validate_ids(cls, condition_ids):
506+
if condition_ids is None:
507+
return []
508+
506509
for condition_id in condition_ids:
507-
if not is_valid_identifier(condition_id):
508-
raise ValueError(f"Invalid ID: {condition_id}")
510+
# condition_id may be empty
511+
if condition_id and not is_valid_identifier(condition_id):
512+
raise ValueError(f"Invalid ID: `{condition_id}'")
509513
return condition_ids
510514

511515

@@ -854,17 +858,23 @@ class Parameter(BaseModel):
854858
#: Parameter ID.
855859
id: str = Field(alias=C.PARAMETER_ID)
856860
#: Lower bound.
857-
lb: float | None = Field(alias=C.LOWER_BOUND, default=None)
861+
lb: Annotated[float | None, BeforeValidator(_convert_nan_to_none)] = Field(
862+
alias=C.LOWER_BOUND, default=None
863+
)
858864
#: Upper bound.
859-
ub: float | None = Field(alias=C.UPPER_BOUND, default=None)
865+
ub: Annotated[float | None, BeforeValidator(_convert_nan_to_none)] = Field(
866+
alias=C.UPPER_BOUND, default=None
867+
)
860868
#: Nominal value.
861-
nominal_value: float | None = Field(alias=C.NOMINAL_VALUE, default=None)
869+
nominal_value: Annotated[
870+
float | None, BeforeValidator(_convert_nan_to_none)
871+
] = Field(alias=C.NOMINAL_VALUE, default=None)
862872
#: Is the parameter to be estimated?
863873
estimate: bool = Field(alias=C.ESTIMATE, default=True)
864874
#: Type of parameter prior distribution.
865-
prior_distribution: PriorDistribution | None = Field(
866-
alias=C.PRIOR_DISTRIBUTION, default=None
867-
)
875+
prior_distribution: Annotated[
876+
PriorDistribution | None, BeforeValidator(_convert_nan_to_none)
877+
] = Field(alias=C.PRIOR_DISTRIBUTION, default=None)
868878
#: Prior distribution parameters.
869879
prior_parameters: list[float] = Field(
870880
alias=C.PRIOR_PARAMETERS, default_factory=list
@@ -921,12 +931,17 @@ def _validate_estimate_before(cls, v):
921931
def _serialize_estimate(self, estimate: bool, _info):
922932
return str(estimate).lower()
923933

924-
@field_validator("lb", "ub", "nominal_value")
925-
@classmethod
926-
def _convert_nan_to_none(cls, v):
927-
if isinstance(v, float) and np.isnan(v):
928-
return None
929-
return v
934+
@field_serializer("prior_distribution")
935+
def _serialize_prior_distribution(
936+
self, prior_distribution: PriorDistribution | None, _info
937+
):
938+
if prior_distribution is None:
939+
return ""
940+
return str(prior_distribution)
941+
942+
@field_serializer("prior_parameters")
943+
def _serialize_prior_parameters(self, prior_parameters: list[str], _info):
944+
return C.PARAMETER_SEPARATOR.join(prior_parameters)
930945

931946
@model_validator(mode="after")
932947
def _validate(self) -> Self:

0 commit comments

Comments
 (0)