@@ -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