Skip to content

Commit

Permalink
first draft
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinBelthle committed Sep 20, 2024
1 parent c4f39f9 commit 7a6387e
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 44 deletions.
12 changes: 4 additions & 8 deletions src/antares/model/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,15 @@ class ClusterProperties(BaseModel, extra="forbid", populate_by_name=True, alias_
# Activity status:
# - True: the plant may generate.
# - False: not yet commissioned, moth-balled, etc.
enabled: Optional[bool] = None
enabled: bool = True

unit_count: Optional[int] = None
nominal_capacity: Optional[float] = None
unit_count: int = 1
nominal_capacity: float = 0

@property
def installed_capacity(self) -> Optional[float]:
if self.unit_count is None or self.nominal_capacity is None:
return None
def installed_capacity(self) -> float:
return self.unit_count * self.nominal_capacity

@property
def enabled_capacity(self) -> Optional[float]:
if self.enabled is None or self.installed_capacity is None:
return None
return self.enabled * self.installed_capacity
12 changes: 9 additions & 3 deletions src/antares/model/renewable.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from pydantic import BaseModel, computed_field

from antares.model.cluster import ClusterProperties
from antares.tools.all_optional_meta import all_optional_model
from antares.tools.contents_tool import transform_name_to_id


Expand Down Expand Up @@ -54,13 +55,18 @@ class TimeSeriesInterpretation(Enum):
PRODUCTION_FACTOR = "production-factor"


class RenewableClusterProperties(ClusterProperties):
class NonOptionalRenewableClusterProperties(ClusterProperties):
"""
Properties of a renewable cluster read from the configuration files.
"""

group: Optional[RenewableClusterGroup] = None
ts_interpretation: Optional[TimeSeriesInterpretation] = None
group: RenewableClusterGroup = RenewableClusterGroup.OTHER1
ts_interpretation: TimeSeriesInterpretation = TimeSeriesInterpretation.POWER_GENERATION


@all_optional_model
class RenewableClusterProperties(NonOptionalRenewableClusterProperties):
pass


# TODO update to use check_if_none
Expand Down
72 changes: 39 additions & 33 deletions src/antares/model/thermal.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from pydantic import BaseModel, computed_field

from antares.model.cluster import ClusterProperties
from antares.tools.all_optional_meta import all_optional_model
from antares.tools.contents_tool import transform_name_to_id
from antares.tools.ini_tool import check_if_none

Expand Down Expand Up @@ -65,46 +66,51 @@ class ThermalCostGeneration(Enum):
USE_COST_TIME_SERIES = "useCostTimeseries"


class ThermalClusterProperties(ClusterProperties):
class NonOptionalThermalProperties(ClusterProperties):
"""
Thermal cluster configuration model.
This model describes the configuration parameters for a thermal cluster.
"""

group: Optional[ThermalClusterGroup] = None
gen_ts: Optional[LocalTSGenerationBehavior] = None
min_stable_power: Optional[float] = None
min_up_time: Optional[int] = None
min_down_time: Optional[int] = None
must_run: Optional[bool] = None
spinning: Optional[float] = None
volatility_forced: Optional[float] = None
volatility_planned: Optional[float] = None
law_forced: Optional[LawOption] = None
law_planned: Optional[LawOption] = None
marginal_cost: Optional[float] = None
spread_cost: Optional[float] = None
fixed_cost: Optional[float] = None
startup_cost: Optional[float] = None
market_bid_cost: Optional[float] = None
co2: Optional[float] = None
group: ThermalClusterGroup = ThermalClusterGroup.OTHER1
gen_ts: LocalTSGenerationBehavior = LocalTSGenerationBehavior.USE_GLOBAL
min_stable_power: float = 0
min_up_time: int = 1
min_down_time: int = 1
must_run: bool = False
spinning: float = 0
volatility_forced: float = 0
volatility_planned: float = 0
law_forced: LawOption = LawOption.UNIFORM
law_planned: LawOption = LawOption.UNIFORM
marginal_cost: float = 0
spread_cost: float = 0
fixed_cost: float = 0
startup_cost: float = 0
market_bid_cost: float = 0
co2: float = 0
# version 860
nh3: Optional[float] = None
so2: Optional[float] = None
nox: Optional[float] = None
pm2_5: Optional[float] = None
pm5: Optional[float] = None
pm10: Optional[float] = None
nmvoc: Optional[float] = None
op1: Optional[float] = None
op2: Optional[float] = None
op3: Optional[float] = None
op4: Optional[float] = None
op5: Optional[float] = None
nh3: float = 0
so2: float = 0
nox: float = 0
pm2_5: float = 0
pm5: float = 0
pm10: float = 0
nmvoc: float = 0
op1: float = 0
op2: float = 0
op3: float = 0
op4: float = 0
op5: float = 0
# version 870
cost_generation: Optional[ThermalCostGeneration] = None
efficiency: Optional[float] = None
variable_o_m_cost: Optional[float] = None
cost_generation: ThermalCostGeneration = ThermalCostGeneration.SET_MANUALLY
efficiency: float = 100
variable_o_m_cost: float = 0


@all_optional_model
class ThermalClusterProperties(NonOptionalThermalProperties):
pass


class ThermalClusterPropertiesLocal(BaseModel):
Expand Down
25 changes: 25 additions & 0 deletions src/antares/tools/all_optional_meta.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import copy
import typing as t
from pydantic import BaseModel, create_model

ModelClass = t.TypeVar("ModelClass", bound=BaseModel)


def all_optional_model(model: t.Type[ModelClass]) -> t.Type[ModelClass]:
"""
This decorator can be used to make all fields of a pydantic model optionals.
Args:
model: The pydantic model to modify.
Returns:
The modified model.
"""
kwargs = {}
for field_name, field_info in model.model_fields.items():
new = copy.deepcopy(field_info)
new.default = None
new.annotation = t.Optional[field_info.annotation] # type: ignore
kwargs[field_name] = (new.annotation, new)

return create_model(f"Partial{model.__name__}", __base__=model, __module__=model.__module__, **kwargs) # type: ignore

0 comments on commit 7a6387e

Please sign in to comment.