Skip to content

Daily Model Settings

opendsm.eemeter.models.daily.utilities.settings

Copyright 2014-2025 OpenDSM contributors

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

DailySettings

Settings for creating the daily model.

These settings should be converted to a dictionary before being passed to the DailyModel class. Be advised that any changes to the default settings deviates from OpenEEmeter standard methods and should be used with caution.

Attributes:

Name Type Description
developer_mode bool

Allows changing of developer settings

algorithm_choice str

Optimization algorithm choice. Developer mode only.

initial_guess_algorithm_choice str

Initial guess optimization algorithm choice. Developer mode only.

full_model str

The largest model allowed. Developer mode only.

smoothed_model bool

Allow smoothed models.

allow_separate_summer bool

Allow summer to be modeled separately.

allow_separate_shoulder bool

Allow shoulder to be modeled separately.

allow_separate_winter bool

Allow winter to be modeled separately.

allow_separate_weekday_weekend bool

Allow weekdays and weekends to be modeled separately.

reduce_splits_by_gaussian bool

Reduces splits by fitting with multivariate Gaussians and testing for overlap.

reduce_splits_num_std list[float]

Number of standard deviations to use with Gaussians.

alpha_minimum float

Alpha where adaptive robust loss function is Welsch loss.

alpha_selection float

Specified alpha to evaluate which is the best model type.

alpha_final_type str

When to use 'alpha_final: 'all': on every model, 'last': on final model, 'None': don't use.

alpha_final float | str | None

Specified alpha or 'adaptive' for adaptive loss in model evaluation.

final_bounds_scalar float | None

Scalar for calculating bounds of 'alpha_final'.

regularization_alpha float

Alpha for elastic net regularization.

regularization_percent_lasso float

Percent lasso vs (1 - perc) ridge regularization.

segment_minimum_count int

Minimum number of data points for HDD/CDD.

maximum_slope_OoM_scalar float

Scaler for initial slope to calculate bounds based on order of magnitude.

initial_smoothing_parameter float | None

Initial guess for the smoothing parameter.

initial_step_percentage float | None

Initial step-size for relevant algorithms.

split_selection_criteria str

What selection criteria is used to select data splits of models.

split_selection_penalty_multiplier float

Penalty multiplier for split selection criteria.

split_selection_penalty_power float

What power should the penalty of the selection criteria be raised to.

season Dict[int, str]

Dictionary of months and their associated season (January is 1).

is_weekday Dict[int, bool]

Dictionary of days (1 = Monday) and if that day is a weekday (True/False).

uncertainty_alpha float

Significance level used for uncertainty calculations (0 < float < 1).

cvrmse_threshold float

Threshold for the CVRMSE to disqualify a model.

model_config = pydantic.ConfigDict(frozen=True, arbitrary_types_allowed=True, str_to_lower=True, str_strip_whitespace=True) class-attribute instance-attribute

Make all property keys lowercase and strip whitespace

developer_mode: bool = CustomField(default=False, developer=False, description='Developer mode flag') class-attribute instance-attribute

silent_developer_mode: bool = CustomField(default=False, developer=False, exclude=True, repr=False) class-attribute instance-attribute

algorithm_choice: Optional[AlgorithmChoice] = CustomField(default=AlgorithmChoice.NLOPT_SBPLX, developer=True, description='Optimization algorithm choice') class-attribute instance-attribute

initial_guess_algorithm_choice: Optional[AlgorithmChoice] = CustomField(default=AlgorithmChoice.NLOPT_DIRECT, developer=True, description='Initial guess optimization algorithm choice') class-attribute instance-attribute

full_model: Optional[FullModelSelection] = CustomField(default=FullModelSelection.HDD_TIDD_CDD, developer=True, description='The largest model allowed') class-attribute instance-attribute

allow_smooth_model: bool = CustomField(default=True, developer=True, description='Allow smoothed models') class-attribute instance-attribute

alpha_minimum: float = CustomField(default=-100, le=-10, developer=True, description='Alpha where adaptive robust loss function is Welsch loss') class-attribute instance-attribute

alpha_selection: float = CustomField(default=2, ge=-10, le=2, developer=True, description='Specified alpha to evaluate which is the best model type') class-attribute instance-attribute

alpha_final_type: Optional[AlphaFinalType] = CustomField(default=AlphaFinalType.LAST, developer=True, description="When to use 'alpha_final: 'all': on every model, 'last': on final model, 'None': don't use") class-attribute instance-attribute

alpha_final: Optional[Union[float, Literal['adaptive']]] = CustomField(default='adaptive', developer=True, description="Specified alpha or 'adaptive' for adaptive loss in model evaluation") class-attribute instance-attribute

final_bounds_scalar: Optional[float] = CustomField(default=1, developer=True, description="Scalar for calculating bounds of 'alpha_final'") class-attribute instance-attribute

regularization_alpha: float = CustomField(default=0.001, ge=0, developer=True, description='Alpha for elastic net regularization') class-attribute instance-attribute

regularization_percent_lasso: float = CustomField(default=1, ge=0, le=1, developer=True, description='Percent lasso vs (1 - perc) ridge regularization') class-attribute instance-attribute

segment_minimum_count: int = CustomField(default=6, ge=3, developer=True, description='Minimum number of data points for HDD/CDD') class-attribute instance-attribute

maximum_slope_oom_scalar: float = CustomField(default=2, ge=1, developer=True, description='Scaler for initial slope to calculate bounds based on order of magnitude') class-attribute instance-attribute

initial_step_percentage: Optional[float] = CustomField(default=0.1, developer=True, description='Initial step-size for relevant algorithms') class-attribute instance-attribute

split_selection: Split_Selection_Definition = CustomField(default_factory=Split_Selection_Definition, developer=True, description='Settings for split selection') class-attribute instance-attribute

season: Season_Definition = CustomField(default_factory=Season_Definition, developer=False, description='Dictionary of months and their associated season (January is 1)') class-attribute instance-attribute

weekday_weekend: Weekday_Weekend_Definition = CustomField(default_factory=Weekday_Weekend_Definition, developer=False, description='Dictionary of days (1 = Monday) and if that day is a weekday (True/False)') class-attribute instance-attribute

uncertainty_alpha: float = CustomField(default=0.1, ge=0, le=1, developer=False, description='Significance level used for uncertainty calculations') class-attribute instance-attribute

cvrmse_threshold: float = CustomField(default=1, ge=0, developer=True, description='Threshold for the CVRMSE to disqualify a model') class-attribute instance-attribute

__lowercase_property_keys__(values)

Source code in opendsm/common/base_settings.py
@pydantic.model_validator(mode="before")
def __lowercase_property_keys__(cls, values: Any) -> Any:
    def __lower__(value: Any) -> Any:
        if isinstance(value, dict):
            return {k.lower().strip() if isinstance(k, str) else k: __lower__(v) for k, v in value.items()}
        return value

    return __lower__(values)

lowercase_values(v)

Source code in opendsm/common/base_settings.py
@pydantic.field_validator("*", mode="before")
def lowercase_values(cls, v):
    if isinstance(v, str):
        return v.lower().strip()
    return v

_check_developer_mode()

Source code in opendsm/eemeter/models/daily/utilities/settings.py
@pydantic.model_validator(mode="after")
def _check_developer_mode(self):
    if self.developer_mode:
        if not self.silent_developer_mode:
            print("Warning: Daily model is nonstandard and should be explicitly stated in any derived work")

        return self

    _check_developer_mode(self)

    return self

_check_alpha_final()

Source code in opendsm/eemeter/models/daily/utilities/settings.py
@pydantic.model_validator(mode="after")
def _check_alpha_final(self):
    if self.alpha_final is None:
        if self.alpha_final_type != None:
            raise ValueError("`ALPHA_FINAL` must be set if `ALPHA_FINAL_TYPE` is not None")

    elif isinstance(self.alpha_final, float):
        if (self.alpha_minimum > self.alpha_final) or (self.alpha_final > 2.0):
            raise ValueError(
                f"`ALPHA_FINAL` must be `adaptive` or `ALPHA_MINIMUM` <= float <= 2"
            )

    elif isinstance(self.alpha_final, str):
        if self.alpha_final != "adaptive":
            raise ValueError(
                f"ALPHA_FINAL must be `adaptive` or `ALPHA_MINIMUM` <= float <= 2"
        )

    return self

_check_final_bounds_scalar()

Source code in opendsm/eemeter/models/daily/utilities/settings.py
@pydantic.model_validator(mode="after")
def _check_final_bounds_scalar(self):
    if self.final_bounds_scalar is not None:
        if self.final_bounds_scalar <= 0:
            raise ValueError("`FINAL_BOUNDS_SCALAR` must be > 0")

        if self.alpha_final_type is None:
            raise ValueError("`FINAL_BOUNDS_SCALAR` must be None if `ALPHA_FINAL` is None")

    else:
        if self.alpha_final_type is not None:
            raise ValueError("`FINAL_BOUNDS_SCALAR` must be > 0 if `ALPHA_FINAL` is not None")

    return self

_check_initial_step_percentage()

Source code in opendsm/eemeter/models/daily/utilities/settings.py
@pydantic.model_validator(mode="after")
def _check_initial_step_percentage(self):
    if self.initial_step_percentage is not None:
        if self.initial_step_percentage <= 0 or self.initial_step_percentage > 0.5:
            raise ValueError("`INITIAL_STEP_PERCENTAGE` must be None or 0 < float <= 0.5")

    else:
        if self.algorithm_choice[:5] in ["nlopt"]:
            raise ValueError("`INITIAL_STEP_PERCENTAGE` must be specified if `ALGORITHM_CHOICE` is from Nlopt")

    return self