diff --git a/openenergyid/__init__.py b/openenergyid/__init__.py index 9d1e309..354c4d3 100644 --- a/openenergyid/__init__.py +++ b/openenergyid/__init__.py @@ -1,6 +1,6 @@ """Open Energy ID Python SDK.""" -__version__ = "0.1.1" +__version__ = "0.1.3" from .enums import Granularity from .models import TimeSeries diff --git a/openenergyid/mvlr/helpers.py b/openenergyid/mvlr/helpers.py index 52f7104..db32a38 100644 --- a/openenergyid/mvlr/helpers.py +++ b/openenergyid/mvlr/helpers.py @@ -28,3 +28,20 @@ def resample_input_data( return data.resample(rule=pandas_granularity_map[granularity]).agg( aggregation_methods, ) + + +def temperature_equivalent_to_degree_days( + temperature_equivalent: pd.Series, base_temperature: float, cooling: bool = False +) -> pd.Series: + """ + Convert temperature equivalent to degree days. + + Use cooling=True to convert cooling degree days. + """ + + if cooling: + result = temperature_equivalent - base_temperature + else: + result = base_temperature - temperature_equivalent + + return result.clip(lower=0) diff --git a/openenergyid/mvlr/models.py b/openenergyid/mvlr/models.py index dc31aa3..36b8603 100644 --- a/openenergyid/mvlr/models.py +++ b/openenergyid/mvlr/models.py @@ -1,7 +1,7 @@ """Models for multivariable linear regression.""" from typing import Optional -from pydantic import BaseModel +from pydantic import BaseModel, Field, ConfigDict import statsmodels.formula.api as fm from openenergyid.enums import Granularity @@ -13,9 +13,9 @@ class ConfidenceInterval(BaseModel): """Confidence interval for a coefficient.""" - confidence: float - lower: float - upper: float + confidence: float = Field(ge=0, le=1) + lower: float = Field(ge=0, le=1) + upper: float = Field(ge=0, le=1) class IndependentVariable(BaseModel): @@ -23,10 +23,14 @@ class IndependentVariable(BaseModel): name: str coef: float - t_stat: Optional[float] = None - p_value: Optional[float] = None - std_err: Optional[float] = None - confidence_interval: Optional[ConfidenceInterval] = None + t_stat: Optional[float] = Field(ge=0, le=1, default=None, alias="tStat") + p_value: Optional[float] = Field(ge=0, le=1, default=None, alias="pValue") + std_err: Optional[float] = Field(ge=0, le=1, default=None, alias="stdErr") + confidence_interval: Optional[ConfidenceInterval] = Field( + default=None, alias="confidenceInterval" + ) + + model_config = ConfigDict(populate_by_name=True) @classmethod def from_fit(cls, fit: fm.ols, name: str) -> "IndependentVariable": @@ -48,12 +52,12 @@ def from_fit(cls, fit: fm.ols, name: str) -> "IndependentVariable": class MultiVariableRegressionResult(BaseModel): """Result of a multivariable regression model.""" - dependent_variable: str - independent_variables: list[IndependentVariable] - r2: float - r2_adj: float - f_stat: float - prob_f_stat: float + dependent_variable: str = Field(alias="dependentVariable") + independent_variables: list[IndependentVariable] = Field(alias="independentVariables") + r2: float = Field(ge=0, le=1, alias="rSquared") + r2_adj: float = Field(ge=0, le=1, alias="rSquaredAdjusted") + f_stat: float = Field(ge=0, alias="fStat") + prob_f_stat: float = Field(ge=0, le=1, alias="probFStat") intercept: IndependentVariable granularity: Granularity frame: TimeSeries