Source code for powersimdata.design.transmission.mwmiles
from powersimdata.input.transform_grid import TransformGrid
from powersimdata.utility.distance import haversine
[docs]def calculate_mw_miles(scenario, exclude_branches=None):
"""Given a Scenario object, calculate the number of upgraded lines and
transformers, and the total upgrade quantity (in MW and MW-miles).
Currently only supports change tables that specify branches' id, not
zone name. Currently lumps Transformer and TransformerWinding upgrades
together.
:param powersimdata.scenario.scenario.Scenario scenario: scenario instance.
:param list/tuple/set/None exclude_branches: branches to exclude.
:return: (*dict*) -- Upgrades to the branches.
"""
original_grid = scenario.get_base_grid()
ct = scenario.get_ct()
upgrades = _calculate_mw_miles(original_grid, ct, exclude_branches)
return upgrades
def _calculate_mw_miles(original_grid, ct, exclude_branches=None):
"""Given a base grid and a change table, calculate the number of upgraded
lines and transformers, and the total upgrade quantity (in MW & MW-miles).
This function is separate from calculate_mw_miles() for testing purposes.
Currently only supports change_tables that specify branches, not zone_name.
Currently lumps Transformer and TransformerWinding upgrades together.
:param powersimdata.input.grid.Grid original_grid: grid instance.
:param dict ct: change table instance.
:param list/tuple/set/None exclude_branches: branches to exclude.
:raises ValueError: if not all values in exclude_branches are in the grid.
:raises TypeError: if exclude_branches gets the wrong type.
:return: (*dict*) -- Upgrades to the branches.
"""
upgrade_categories = ("mw_miles", "transformer_mw", "num_lines", "num_transformers")
upgrades = {u: 0 for u in upgrade_categories}
if "branch" not in ct or "branch_id" not in ct["branch"]:
return upgrades
if exclude_branches is None:
exclude_branches = {}
elif isinstance(exclude_branches, (list, set, tuple)):
good_branch_indices = original_grid.branch.index
if not all([e in good_branch_indices for e in exclude_branches]):
raise ValueError("not all branches are present in grid!")
exclude_branches = set(exclude_branches)
else:
raise TypeError("exclude_branches must be None, list, tuple, or set")
base_branch_ids = set(original_grid.branch.index)
upgraded_branch_ids = set(ct["branch"]["branch_id"].keys())
transformed_branch = TransformGrid(original_grid, ct).get_grid().branch
if "new_branch" in ct:
upgraded_branch_ids |= set(transformed_branch.index) - base_branch_ids
for b in upgraded_branch_ids:
if b in exclude_branches:
continue
if b in base_branch_ids:
# 'upgraded' capacity is (scale - 1) because a scale of 1 = an upgrade of 0
scale = ct["branch"]["branch_id"][b]
upgraded_capacity = transformed_branch.loc[b, "rateA"] / scale * (scale - 1)
else:
upgraded_capacity = transformed_branch.loc[b, "rateA"]
device_type = transformed_branch.loc[b, "branch_device_type"]
if device_type == "Line":
from_coords = (
transformed_branch.loc[b, "from_lat"],
transformed_branch.loc[b, "from_lon"],
)
to_coords = (
transformed_branch.loc[b, "to_lat"],
transformed_branch.loc[b, "to_lon"],
)
addtl_mw_miles = upgraded_capacity * haversine(from_coords, to_coords)
upgrades["mw_miles"] += addtl_mw_miles
upgrades["num_lines"] += 1
elif device_type == "Transformer":
upgrades["transformer_mw"] += upgraded_capacity
upgrades["num_transformers"] += 1
elif device_type == "TransformerWinding":
upgrades["transformer_mw"] += upgraded_capacity
upgrades["num_transformers"] += 1
else:
raise Exception("Unknown branch type: " + str(b))
return upgrades