77 lines
2.5 KiB
Python
77 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from enum import Enum
|
|
from typing import TYPE_CHECKING
|
|
|
|
from sqlalchemy import (
|
|
JSON,
|
|
DateTime,
|
|
Enum as SQLEnum,
|
|
ForeignKey,
|
|
Integer,
|
|
Numeric,
|
|
String,
|
|
)
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
from sqlalchemy.sql import func
|
|
|
|
from config.database import Base
|
|
from .metadata import ResourceType, StochasticVariable
|
|
|
|
if TYPE_CHECKING: # pragma: no cover
|
|
from .scenario import Scenario
|
|
|
|
|
|
class DistributionType(str, Enum):
|
|
"""Supported stochastic distribution families for simulations."""
|
|
|
|
NORMAL = "normal"
|
|
TRIANGULAR = "triangular"
|
|
UNIFORM = "uniform"
|
|
LOGNORMAL = "lognormal"
|
|
CUSTOM = "custom"
|
|
|
|
|
|
class SimulationParameter(Base):
|
|
"""Probability distribution settings for scenario simulations."""
|
|
|
|
__tablename__ = "simulation_parameters"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
scenario_id: Mapped[int] = mapped_column(
|
|
ForeignKey("scenarios.id", ondelete="CASCADE"), nullable=False, index=True
|
|
)
|
|
name: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
distribution: Mapped[DistributionType] = mapped_column(
|
|
SQLEnum(DistributionType), nullable=False
|
|
)
|
|
variable: Mapped[StochasticVariable | None] = mapped_column(
|
|
SQLEnum(StochasticVariable), nullable=True
|
|
)
|
|
resource_type: Mapped[ResourceType | None] = mapped_column(
|
|
SQLEnum(ResourceType), nullable=True
|
|
)
|
|
mean_value: Mapped[float | None] = mapped_column(Numeric(18, 4), nullable=True)
|
|
standard_deviation: Mapped[float | None] = mapped_column(Numeric(18, 4), nullable=True)
|
|
minimum_value: Mapped[float | None] = mapped_column(Numeric(18, 4), nullable=True)
|
|
maximum_value: Mapped[float | None] = mapped_column(Numeric(18, 4), nullable=True)
|
|
unit: Mapped[str | None] = mapped_column(String(32), nullable=True)
|
|
metadata: Mapped[dict | None] = mapped_column(JSON, nullable=True)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), nullable=False, server_default=func.now()
|
|
)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()
|
|
)
|
|
|
|
scenario: Mapped["Scenario"] = relationship(
|
|
"Scenario", back_populates="simulation_parameters"
|
|
)
|
|
|
|
def __repr__(self) -> str: # pragma: no cover
|
|
return (
|
|
f"SimulationParameter(id={self.id!r}, scenario_id={self.scenario_id!r}, "
|
|
f"name={self.name!r})"
|
|
)
|