Skip to content

Commit

Permalink
Merge pull request #144 from NREL/dt/check-cost-db
Browse files Browse the repository at this point in the history
Add early checking of cost database and catalog
  • Loading branch information
daniel-thom authored Jul 1, 2022
2 parents ab14f0e + 662735c commit 790338a
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 143 deletions.
2 changes: 1 addition & 1 deletion disco/cli/upgrade_cost_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from disco.exceptions import DiscoBaseException, get_error_code_from_exception
from disco.models.base import OpenDssDeploymentModel
from disco.models.upgrade_cost_analysis_generic_input_model import (
UpgradeCostAnalysisSimulationModel,
UpgradeCostAnalysisSimulationModel
)
from disco.models.upgrade_cost_analysis_generic_output_model import (
UpgradeViolationResultModel,
Expand Down
22 changes: 8 additions & 14 deletions disco/extensions/upgrade_simulation/upgrades/cost_computation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from .common_functions import create_overall_output_file
from disco import timer_stats_collector
from disco.models.upgrade_cost_analysis_generic_input_model import UpgradeCostDatabaseModel
from disco.models.upgrade_cost_analysis_generic_input_model import load_cost_database
from disco.models.upgrade_cost_analysis_generic_output_model import AllUpgradesTechnicalResultModel, \
AllEquipmentUpgradeCostsResultModel, EquipmentTypeUpgradeCostsResultModel, CapacitorControllerResultType, \
VoltageRegulatorResultType, TotalUpgradeCostsResultModel, AllUpgradesCostResultSummaryModel
Expand Down Expand Up @@ -46,19 +46,13 @@ def compute_all_costs(
line_upgrades_df = pd.DataFrame(m.dict(by_alias=True)["line"])
voltage_upgrades_df = pd.DataFrame(m.dict(by_alias=True)["voltage"])

# unit cost database files
xfmr_cost_database = pd.read_excel(cost_database_filepath, "transformers")
line_cost_database = pd.read_excel(cost_database_filepath, "lines")
controls_cost_database = pd.read_excel(cost_database_filepath, "control_changes")
voltage_regulators_cost_database = pd.read_excel(cost_database_filepath, "voltage_regulators")
misc_database = pd.read_excel(cost_database_filepath, "misc")

# perform validation of input cost database using pydantic models
input_cost_model = UpgradeCostDatabaseModel(transformers=xfmr_cost_database.to_dict(orient="records"),
lines=line_cost_database.to_dict(orient="records"),
control_changes=controls_cost_database.to_dict(orient="records"),
voltage_regulators=voltage_regulators_cost_database.to_dict(orient="records"),
misc=misc_database.to_dict(orient="records"))
(
xfmr_cost_database,
line_cost_database,
controls_cost_database,
voltage_regulators_cost_database,
misc_database,
) = load_cost_database(cost_database_filepath)
output_columns = list(EquipmentTypeUpgradeCostsResultModel.schema(True).get("properties").keys())

# reformat data
Expand Down
275 changes: 147 additions & 128 deletions disco/models/upgrade_cost_analysis_generic_input_model.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import enum
from typing import List, Optional, Set, Dict
from pydantic import BaseModel, Field, root_validator, validator

import pandas as pd

from PyDSS.controllers import PvControllerModel

from disco.models.base import BaseAnalysisModel
Expand Down Expand Up @@ -31,6 +32,126 @@ def get_default_voltage_upgrade_params():
return _get_default_upgrade_params()["voltage_upgrade_params"]


class OpenDSSLineModel(OpenDSSLineParams):
bus1: str = Field(
title="bus1",
description="bus1",
)
bus2: str = Field(
title="bus2",
description="bus2",
)
length: float = Field(
title="length",
description="length",
)
enabled: Any = Field(
title="enabled",
description="enabled",
)


class LineModel(OpenDSSLineModel, ExtraLineParams):
name: str = Field(
title="name",
description="name. This is not a direct OpenDSS object property.",
)


class LineCatalogModel(OpenDSSLineParams, ExtraLineParams):
"""Contains Line information needed for thermal upgrade analysis. Most fields can be directly obtained from the opendss models"""
name: str = Field(
title="name",
description="name. This is not a direct OpenDSS object property.",
)


class LineCodeCatalogModel(CommonLineParameters):
"""Contains LineCode information needed for thermal upgrade analysis. Most fields can be directly obtained from the opendss models"""
name: str = Field(
title="name",
description="name",
)
nphases: int = Field(
title="nphases",
description="nphases",
determine_upgrade_option=True,
)
Kron: Optional[Any] = Field(
title="Kron",
description="Kron",
default="N",
determine_upgrade_option=True,
)
neutral: float = Field(
title="neutral",
description="neutral",
determine_upgrade_option=True,
)
like: Optional[Any] = Field(
title="like",
description="like",
default=None,
)
baseFreq: float = Field(
title="basefreq",
description="basefreq",
determine_upgrade_option=True,
)


class OpenDSSTransformerModel(CommonTransformerParameters):
bus: str = Field(
title="bus",
description="bus",
)
buses: Any = Field(
title="buses",
description="buses",
)
enabled: Any = Field(
title="enabled",
description="enabled",
)


class TransformerModel(OpenDSSTransformerModel, ExtraTransformerParams):
name: str = Field(
title="name",
description="name. This is not a direct OpenDSS object property.",
)


class TransformerCatalogModel(CommonTransformerParameters, ExtraTransformerParams):
"""Contains Transformer information needed for thermal upgrade analysis. Most fields can be directly obtained from the opendss models"""
name: str = Field(
title="name",
description="name",
)
class UpgradeTechnicalCatalogModel(UpgradeParamsBaseModel):
"""Contains Upgrades Technical Catalog needed for thermal upgrade analysis"""
line: Optional[List[LineCatalogModel]] = Field(
title="line",
description="line catalog",
default=[]
)
transformer: Optional[List[TransformerCatalogModel]] = Field(
title="transformer",
description="transformer catalog",
default=[]
)
linecode: Optional[List[LineCodeCatalogModel]] = Field(
title="linecode",
description="linecode catalog",
default=[]
)
# TODO not implemented yet. Can be added if lines are defined through linegeometry
# geometry: Optional[List[LineGeometryCatalogModel]] = Field(
# title="linegeometry",
# description="linegeometry catalog",
# default=[]
# )


class ThermalUpgradeParamsModel(UpgradeParamsBaseModel):
"""Thermal Upgrade Parameters for all jobs in a simulation"""
Expand Down Expand Up @@ -98,8 +219,11 @@ def check_voltage_lower_limits(cls, voltage_lower_limit, values):

@validator("external_catalog")
def check_catalog(cls, external_catalog, values):
if values["read_external_catalog"] and not Path(external_catalog).exists():
raise ValueError(f"{external_catalog} does not exist")
if values["read_external_catalog"]:
if not Path(external_catalog).exists():
raise ValueError(f"{external_catalog} does not exist")
# Just verify that it constructs the model.
UpgradeTechnicalCatalogModel(**load_data(external_catalog))
return external_catalog

@validator("timepoint_multipliers")
Expand Down Expand Up @@ -302,6 +426,8 @@ def check_database(cls, calculate_costs, values):
if calculate_costs:
if not Path(values["upgrade_cost_database"]).exists():
raise ValueError(f"{values['upgrade_cost_database']} does not exist")
# Just verify that it constructs the model.
load_cost_database(values["upgrade_cost_database"])
return calculate_costs

@validator("upgrade_order")
Expand Down Expand Up @@ -524,130 +650,23 @@ class UpgradeCostDatabaseModel(UpgradeParamsBaseModel):
)


class upgrade_cost_types(enum.Enum):
"""Possible values for upgrade costs"""
TRANSFORMER = "Transformer"
LINE = "Line"


class OpenDSSLineModel(OpenDSSLineParams):
bus1: str = Field(
title="bus1",
description="bus1",
)
bus2: str = Field(
title="bus2",
description="bus2",
)
length: float = Field(
title="length",
description="length",
)
enabled: Any = Field(
title="enabled",
description="enabled",
)


class LineModel(OpenDSSLineModel, ExtraLineParams):
name: str = Field(
title="name",
description="name. This is not a direct OpenDSS object property.",
)


class LineCatalogModel(OpenDSSLineParams, ExtraLineParams):
"""Contains Line information needed for thermal upgrade analysis. Most fields can be directly obtained from the opendss models"""
name: str = Field(
title="name",
description="name. This is not a direct OpenDSS object property.",
)
def load_cost_database(filepath):
xfmr_cost_database = pd.read_excel(filepath, "transformers")
line_cost_database = pd.read_excel(filepath, "lines")
controls_cost_database = pd.read_excel(filepath, "control_changes")
voltage_regulators_cost_database = pd.read_excel(filepath, "voltage_regulators")
misc_database = pd.read_excel(filepath, "misc")


class LineCodeCatalogModel(CommonLineParameters):
"""Contains LineCode information needed for thermal upgrade analysis. Most fields can be directly obtained from the opendss models"""
name: str = Field(
title="name",
description="name",
)
nphases: int = Field(
title="nphases",
description="nphases",
determine_upgrade_option=True,
# perform validation of input cost database using pydantic models
input_cost_model = UpgradeCostDatabaseModel(transformers=xfmr_cost_database.to_dict(orient="records"),
lines=line_cost_database.to_dict(orient="records"),
control_changes=controls_cost_database.to_dict(orient="records"),
voltage_regulators=voltage_regulators_cost_database.to_dict(orient="records"),
misc=misc_database.to_dict(orient="records"))
return (
xfmr_cost_database,
line_cost_database,
controls_cost_database,
voltage_regulators_cost_database,
misc_database,
)
Kron: Optional[Any] = Field(
title="Kron",
description="Kron",
default="N",
determine_upgrade_option=True,
)
neutral: float = Field(
title="neutral",
description="neutral",
determine_upgrade_option=True,
)
like: Optional[Any] = Field(
title="like",
description="like",
default=None,
)
baseFreq: float = Field(
title="basefreq",
description="basefreq",
determine_upgrade_option=True,
)


class OpenDSSTransformerModel(CommonTransformerParameters):
bus: str = Field(
title="bus",
description="bus",
)
buses: Any = Field(
title="buses",
description="buses",
)
enabled: Any = Field(
title="enabled",
description="enabled",
)


class TransformerModel(OpenDSSTransformerModel, ExtraTransformerParams):
name: str = Field(
title="name",
description="name. This is not a direct OpenDSS object property.",
)


class TransformerCatalogModel(CommonTransformerParameters, ExtraTransformerParams):
"""Contains Transformer information needed for thermal upgrade analysis. Most fields can be directly obtained from the opendss models"""
name: str = Field(
title="name",
description="name",
)


class UpgradeTechnicalCatalogModel(UpgradeParamsBaseModel):
"""Contains Upgrades Technical Catalog needed for thermal upgrade analysis"""
line: Optional[List[LineCatalogModel]] = Field(
title="line",
description="line catalog",
default=[]
)
transformer: Optional[List[TransformerCatalogModel]] = Field(
title="transformer",
description="transformer catalog",
default=[]
)
linecode: Optional[List[LineCodeCatalogModel]] = Field(
title="linecode",
description="linecode catalog",
default=[]
)
# TODO not implemented yet. Can be added if lines are defined through linegeometry
# geometry: Optional[List[LineGeometryCatalogModel]] = Field(
# title="linegeometry",
# description="linegeometry catalog",
# default=[]
# )

0 comments on commit 790338a

Please sign in to comment.