Skip to content

Commit

Permalink
Merge pull request #690 from Breakthrough-Energy/jen/delegate
Browse files Browse the repository at this point in the history
Replace case.mat with grid.pkl
  • Loading branch information
jenhagg authored Oct 6, 2022
2 parents a6a3760 + 823667c commit b89668c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 164 deletions.
143 changes: 12 additions & 131 deletions powersimdata/input/exporter/export_to_reise.py
Original file line number Diff line number Diff line change
@@ -1,139 +1,20 @@
import copy

import numpy as np
from scipy.io import savemat
import pickle

from powersimdata.input.transform_profile import TransformProfile


def export_case_mat(grid, filepath=None, storage_filepath=None):
"""Export a grid to a format suitable for loading into simulation engine.
If optional filepath arguments are used, the results will also be saved to
the filepaths provided
def export_grid(grid, file_path):
"""Save a grid object locally.
:param powersimdata.input.grid.Grid grid: Grid instance.
:param str filepath: path where main grid file will be saved, if present
:param str storage_filepath: path where storage data file will be saved, if present.
:return: (*tuple*) -- the mpc data as a dictionary and the mpc storage data
as a dictionary, if present. The storage data will be None if not present.
:param powersimdata.input.grid.Grid grid: a Grid object
:param str file_path: path to save the result, including the filename
"""
grid = copy.deepcopy(grid)

mpc = {"mpc": {"version": "2", "baseMVA": 100.0}}

# zone
mpc["mpc"]["zone"] = np.array(list(grid.id2zone.items()), dtype=object)

# sub
sub = grid.sub.copy()
subid = sub.index.values[np.newaxis].T
mpc["mpc"]["sub"] = sub.values
mpc["mpc"]["subid"] = subid

# bus
bus = grid.bus.copy()
busid = bus.index.values[np.newaxis].T
bus.reset_index(level=0, inplace=True)
bus.drop(columns=["interconnect", "lat", "lon"], inplace=True)
mpc["mpc"]["bus"] = bus.values
mpc["mpc"]["busid"] = busid

# bus2sub
bus2sub = grid.bus2sub.copy()
mpc["mpc"]["bus2sub"] = bus2sub.values

# plant
gen = grid.plant.copy()
genid = gen.index.values[np.newaxis].T
genfuel = gen.type.values[np.newaxis].T
genfuelcost = gen.GenFuelCost.values[np.newaxis].T
heatratecurve = gen[["GenIOB", "GenIOC", "GenIOD"]].values
gen.reset_index(inplace=True, drop=True)
gen.drop(
columns=[
"type",
"interconnect",
"lat",
"lon",
"zone_id",
"zone_name",
"GenFuelCost",
"GenIOB",
"GenIOC",
"GenIOD",
],
inplace=True,
)
mpc["mpc"]["gen"] = gen.values
mpc["mpc"]["genid"] = genid
mpc["mpc"]["genfuel"] = genfuel
mpc["mpc"]["genfuelcost"] = genfuelcost
mpc["mpc"]["heatratecurve"] = heatratecurve
# branch
branch = grid.branch.copy()
branchid = branch.index.values[np.newaxis].T
branchdevicetype = branch.branch_device_type.values[np.newaxis].T
branch.reset_index(inplace=True, drop=True)
branch.drop(
columns=[
"interconnect",
"from_lat",
"from_lon",
"to_lat",
"to_lon",
"from_zone_id",
"to_zone_id",
"from_zone_name",
"to_zone_name",
"branch_device_type",
],
inplace=True,
)
mpc["mpc"]["branch"] = branch.values
mpc["mpc"]["branchid"] = branchid
mpc["mpc"]["branchdevicetype"] = branchdevicetype

# generation cost
gencost = grid.gencost.copy()
gencost["before"].reset_index(inplace=True, drop=True)
gencost["before"].drop(columns=["interconnect"], inplace=True)
mpc["mpc"]["gencost"] = gencost["before"].values

# DC line
if len(grid.dcline) > 0:
dcline = grid.dcline.copy()
dclineid = dcline.index.values[np.newaxis].T
dcline.reset_index(inplace=True, drop=True)
dcline.drop(columns=["from_interconnect", "to_interconnect"], inplace=True)
mpc["mpc"]["dcline"] = dcline.values
mpc["mpc"]["dclineid"] = dclineid

# energy storage
mpc_storage = None

if len(grid.storage["gen"]) > 0:
storage = grid.storage.copy()

mpc_storage = {
"storage": {
"xgd_table": np.array([]),
"gen": np.array(storage["gen"].values, dtype=np.float64),
"sd_table": {
"colnames": storage["StorageData"].columns.values[np.newaxis],
"data": storage["StorageData"].values,
},
}
}

if filepath is not None:
savemat(filepath, mpc, appendmat=False)
if mpc_storage is not None:
savemat(storage_filepath, mpc_storage, appendmat=False)

return mpc, mpc_storage
print(f"Writing grid object to {file_path} on local machine")
with open(file_path, "a") as f:
pickle.dump(grid, f)


def export_transformed_profile(kind, scenario_info, grid, ct, filepath, slice=True):
def export_transformed_profile(kind, scenario_info, grid, ct, file_path, slice=True):
"""Apply transformation to the given kind of profile and save the result locally.
:param str kind: which profile to export. This parameter is passed to
Expand All @@ -143,10 +24,10 @@ def export_transformed_profile(kind, scenario_info, grid, ct, filepath, slice=Tr
:param powersimdata.input.grid.Grid grid: a Grid object previously
transformed.
:param dict ct: change table.
:param str filepath: path to save the result, including the filename
:param str file_path: path to save the result, including the filename
:param bool slice: whether to slice the profiles by the Scenario's time range.
"""
tp = TransformProfile(scenario_info, grid, ct, slice)
profile = tp.get_profile(kind)
print(f"Writing scaled {kind} profile to {filepath} on local machine")
profile.to_csv(filepath)
print(f"Writing scaled {kind} profile to {file_path} on local machine")
profile.to_csv(file_path)
8 changes: 4 additions & 4 deletions powersimdata/input/transform_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def _add_branch(self):
new_branch["to_lon"] = to_lon
new_branch["to_lat"] = to_lat
new_branch["x"] = x
new_index = [self.grid.branch.index[-1] + 1]
new_index = pd.Index([self.grid.branch.index[-1] + 1], name="branch_id")
self.grid.branch = pd.concat(
[self.grid.branch, pd.DataFrame(new_branch, index=new_index)]
)
Expand Down Expand Up @@ -330,7 +330,7 @@ def _add_dcline(self):
new_dcline["Pmax"] = entry["Pmax"]
new_dcline["from_interconnect"] = from_interconnect
new_dcline["to_interconnect"] = to_interconnect
new_index = [self.grid.dcline.index[-1] + 1]
new_index = pd.Index([self.grid.dcline.index[-1] + 1], name="dcline_id")
self.grid.dcline = pd.concat(
[self.grid.dcline, pd.DataFrame(new_dcline, index=new_index)]
)
Expand Down Expand Up @@ -361,7 +361,7 @@ def _add_plant(self):
new_plant["zone_name"] = zone_name
new_plant["lon"] = lon
new_plant["lat"] = lat
new_index = [self.grid.plant.index[-1] + 1]
new_index = pd.Index([self.grid.plant.index[-1] + 1], name="plant_id")
self.grid.plant = pd.concat(
[self.grid.plant, pd.DataFrame(new_plant, index=new_index)]
)
Expand All @@ -379,7 +379,7 @@ def _add_gencost(self):
new_gencost["c0"] = entry["c0"]
new_gencost["c1"] = entry["c1"]
new_gencost["c2"] = entry["c2"]
new_index = [gencost["before"].index[-1] + 1]
new_index = pd.Index([gencost["before"].index[-1] + 1], name="plant_id")
gencost["before"] = pd.concat(
[gencost["before"], pd.DataFrame(new_gencost, index=new_index)]
)
Expand Down
43 changes: 14 additions & 29 deletions powersimdata/scenario/execute.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import pickle

import pandas as pd
from scipy.io import savemat

from powersimdata.data_access.context import Context
from powersimdata.input.exporter.export_to_reise import export_case_mat
from powersimdata.input.grid import Grid
from powersimdata.input.input_data import InputData
from powersimdata.input.transform_grid import TransformGrid
Expand Down Expand Up @@ -107,16 +107,15 @@ def prepare_simulation_input(self, profiles_as=None):
for p in ["demand", "hydro", "solar", "wind"]:
si.prepare_profile(p, profiles_as)

si.prepare_mpc_file()
si.prepare_grid()

if "demand_flexibility" in self.ct:
# Prepare all specified demand flexibility profiles
for p in list(self.ct["demand_flexibility"]):
if p != "demand_flexibility_duration":
si.prepare_profile(p, profiles_as)

# Create the demand_flexibility_parameters file
si.prepare_demand_flexibility_parameters_file()
si.prepare_demand_flexibility_parameters()

prepared = "prepared"
self._execute_list_manager.set_status(self.scenario_id, prepared)
Expand Down Expand Up @@ -204,20 +203,12 @@ def __init__(self, data_access, scenario_info, grid, ct):

self.REL_TMP_DIR = self._data_access.tmp_folder(self.scenario_id)

def prepare_mpc_file(self):
"""Creates MATPOWER case file."""
file_path = "/".join([self.REL_TMP_DIR, "case.mat"])
storage_file_path = "/".join([self.REL_TMP_DIR, "case_storage.mat"])

print("Building MPC file")
mpc, mpc_storage = export_case_mat(self.grid)

with self._data_access.write(file_path, save_local=False) as f:
savemat(f, mpc, appendmat=False)

if mpc_storage is not None:
with self._data_access.write(storage_file_path, save_local=False) as f:
savemat(f, mpc_storage, appendmat=False)
def prepare_grid(self):
"""Prepare grid for simulation."""
print("--> Preparing grid data")
dest_path = "/".join([self.REL_TMP_DIR, "grid.pkl"])
with self._data_access.write(dest_path, save_local=False) as f:
pickle.dump(self.grid, f)

def prepare_profile(self, kind, profile_as=None, slice=False):
"""Prepares profile for simulation.
Expand All @@ -233,18 +224,15 @@ def prepare_profile(self, kind, profile_as=None, slice=False):
if profile_as is None:
tp = TransformProfile(self._scenario_info, self.grid, self.ct, slice)
profile = tp.get_profile(kind)
print(f"Writing scaled {kind} profile to {dest_path}")
with self._data_access.write(dest_path, save_local=False) as f:
profile.to_csv(f)
else:
from_dir = self._data_access.tmp_folder(profile_as)
src = "/".join([from_dir, file_name])
self._data_access.fs.copy(src, dest_path)

def prepare_demand_flexibility_parameters_file(self):
"""Creates the demand_flexibility_parameters file."""
# Construct a dictionary of the necessary parameters
print("Building demand flexibility parameters file")
def prepare_demand_flexibility_parameters(self):
"""Prepares demand_flexibility parameters file for simulation."""
params = {}
params["enabled"] = [True]
params["interval_balance"] = [True]
Expand All @@ -258,11 +246,8 @@ def prepare_demand_flexibility_parameters_file(self):
if "demand_flexibility_duration" in self.ct["demand_flexibility"]
else 0
]

# Convert the dictionary to a DataFrame to more easily save as a .csv file
params = pd.DataFrame.from_dict(params)

# Save the parameters as a .csv file and move the file to the correct location
file_path = "/".join([self.REL_TMP_DIR, "demand_flexibility_parameters.csv"])
with self._data_access.write(file_path, save_local=False) as f:
dest_path = "/".join([self.REL_TMP_DIR, "demand_flexibility_parameters.csv"])
with self._data_access.write(dest_path, save_local=False) as f:
params.to_csv(f)

0 comments on commit b89668c

Please sign in to comment.