Source code for corrai.base.parameter

from dataclasses import dataclass

TYPES = ["Integer", "Real", "Choice", "Binary"]
RELABS = ["Absolute", "Relative"]


[docs] @dataclass class Parameter: name: str interval: tuple[int | float, int | float] | None = None values: tuple[str | int | float, ...] | None = None ptype: str = "Real" relabs: str = "Absolute" init_value: str | int | float | tuple[str | int | float] | None = None min_max_interval: ( tuple[int | float, int | float] | list[tuple[int | float, int | float]] | None ) = None model_property: str | tuple[str, ...] = None """ A parameter definition for models. Can Affect a single model property or a list of properties The parameter can be either defined over a continuous interval (e.g., for real or integer parameters) or as a discrete set of possible values (e.g., for categorical or binary parameters). Exactly one of `interval` or `values` must be provided. The `Parameter` class also supports specifying metadata such as type, relative/absolute scaling, an initial value, and optional min/max constraints. Parameters ---------- name : str The name of the parameter. model_property : str or list of str The model property (or list of property) that this parameter is associated with. Usually, a property is a "path" to a value in a model. (eg : building.wall.insulation.conductivity) interval : tuple of int or float, optional A tuple representing the lower and upper bounds of the parameter's domain, used for continuous or integer parameters. Must not be provided if `values` is specified. values : list of str, int, or float, optional A list of discrete candidate values the parameter can take. Must not be provided if `interval` is specified. ptype : str, default="Real" The type of parameter. Must be one of `"Integer"`, `"Real"`, `"Choice"`, or `"Binary"`. relabs : str, default="Absolute" Specifies whether the parameter should be treated in `"Relative"` or `"Absolute"` terms. Use Relative if the parameter values or interval are specified as a percentage of the model property values init_value : str, int, or float, optional The initial value of the parameter. If `interval` is used, must fall within the interval. If `values` is used, must be one of the listed values. min_max_interval : tuple of int or float, optional Optional min and max bounds used for some checking operations. Raises ------ ValueError If both `interval` and `values` are specified, or if neither is specified. If `init_value` is outside the specified domain. If `ptype` or `relabs` are not in the allowed sets. Examples -------- >>> # Example using an interval >>> p = Parameter( ... name="Conductivity", ... model_property=( ... "building.wall.insulation.conductivity", ... "building.roof.insulation.conductivity", ... ), ... interval=(0.032, 0.040), ... ptype="Real", ... init_value=(0.035, 0.039) ... ) >>> # Example using discrete values >>> p = Parameter( ... name="ThermalCapacity", ... model_property="simulation.algorithm", ... values=("TARP", "DOE"), ... ptype="Choice", ... init_value="TARP" ... ) """ def __post_init__(self): if self.interval is not None and self.values is not None: raise ValueError("Only one of 'interval' or 'values' may be specified.") if self.interval is None and self.values is None and self.ptype != "Binary": raise ValueError("One of 'interval' or 'values' must be specified.") if self.ptype not in TYPES: raise ValueError(f"Invalid type: {self.ptype!r}. Must be one of {TYPES}.") if isinstance(self.relabs, str) and self.relabs not in RELABS: raise ValueError( f"Invalid relabs: {self.relabs!r}. " f"Must be one of {RELABS} or a bool." ) if self.init_value is not None: list_to_test = ( self.init_value if isinstance(self.init_value, list) else [self.init_value] ) if self.interval is not None and self.relabs != "Relative": lo, hi = self.interval if not all(lo <= i_value <= hi for i_value in list_to_test): raise ValueError( f"init_value {self.init_value} " f"not in interval {self.interval}" ) elif self.values is not None and self.relabs != "Relative": if not all(i_value in self.values for i_value in list_to_test): raise ValueError( f"init_value {self.init_value} " f"not in values {self.values}" ) self.init_value = list_to_test