Skip to content

Commit e8f3ba9

Browse files
committed
initial work on beta. going to delete that folder
1 parent b3e3b1f commit e8f3ba9

File tree

76 files changed

+233769
-194030
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+233769
-194030
lines changed
Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
7.488126440622215441e+00
2-
8.172848160415529861e+00
3-
2.148182569563456656e+00
4-
8.679829797198499008e+00
5-
7.181258470602148059e+00
6-
4.809828910248568068e-01
7-
6.308617524913902042e-01
8-
2.971008847979095258e-01
9-
7.840639433804419411e-01
10-
4.938764385059879469e-01
11-
6.535373310348524534e-01
1+
1.151034005982485287e+00
2+
8.720377953466526222e+00
3+
3.324757115099834515e+00
4+
4.273230858049058334e+00
5+
3.816021942505130937e+00
6+
2.222091609177368199e-01
7+
5.894422923650146640e-01
8+
2.224365545894931018e-01
9+
5.277255289653753900e-01
10+
5.644022280526826973e-01
11+
1.795594579108001021e+00
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.429250628441912340e+03
1+
2.190236573167535425e+03
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import pystorms
2+
import pyswmm
3+
import numpy as np
4+
import matplotlib.pyplot as plt
5+
import pandas as pd
6+
import dill as pickle
7+
import datetime
8+
import networkx as nx
9+
import matplotlib.patches as mpatches
10+
from matplotlib.gridspec import GridSpec
11+
import os
12+
13+
# BETA SCENARIO
14+
version = "1"
15+
level = "1"
16+
# set the working directory to the directory of this script
17+
os.chdir(os.path.dirname(os.path.abspath(__file__)))
18+
print(os.getcwd())
19+
#env = pystorms.scenarios.beta(version=version,level=level)
20+
env = pystorms.scenarios.beta()
21+
env.env.sim.start()
22+
23+
24+
mpc_data_log = pd.read_pickle(str("./v" + version + "/lev" + level + "/results/mpc_data_log.pkl"))
25+
uncontrolled_data_log = pd.read_pickle(str("./v" + version + "/results/uncontrolled_data_log.pkl"))
26+
27+
# print the costs
28+
print("uncontrolled: ", "{:.2E}".format(sum(uncontrolled_data_log['performance_measure'])))
29+
print("mpc: ", "{:.2E}".format(sum(mpc_data_log['performance_measure'])))
30+
31+
# load the actions and states
32+
uncontrolled_actions = pd.read_csv("./v" + version + "/results/actions_uncontrolled.csv",index_col=0,parse_dates=True)
33+
uncontrolled_states = pd.read_csv("./v" + version + "/results/states_uncontrolled.csv",index_col=0,parse_dates=True)
34+
mpc_actions = pd.read_csv("./v" + version + "/lev" + level + "/results/actions_mpc.csv",index_col=0,parse_dates=True)
35+
mpc_states = pd.read_csv("./v" + version + "/lev" + level + "/results/states_mpc.csv",index_col=0,parse_dates=True)
36+
37+
38+
plots_high = max(len(env.config['action_space']) , len(env.config['states']))
39+
40+
fig = plt.figure(figsize=(10,2*plots_high))
41+
gs = GridSpec(plots_high,2,figure=fig)
42+
43+
# plot the actions
44+
for idx, name in enumerate(env.config['action_space']):
45+
ax = fig.add_subplot(gs[idx,0] )
46+
ax.plot(uncontrolled_actions.index, uncontrolled_actions[env.config['action_space'][idx]], label='Uncontrolled',color='black',alpha=0.6)
47+
ax.plot(mpc_actions.index, mpc_actions[env.config['action_space'][idx]], label='MPC',color='green',alpha=0.6)
48+
49+
if idx == len(env.config['action_space']) - 1:
50+
ax.set_xlabel("time")
51+
# just add ticks in the beginning, middle, and end of the index
52+
ax.set_xticks([mpc_actions.index[0],mpc_actions.index[int(len(mpc_actions.index)/2)],mpc_actions.index[-1]])
53+
54+
if idx == 0:
55+
ax.set_title("Controls")
56+
if idx != len(env.config['action_space']) - 1: # not the last row
57+
ax.set_xticks([])
58+
ax.set_xticklabels([])
59+
60+
ax.annotate(str(env.config['action_space'][idx]), xy=(0.5, 0.8), xycoords='axes fraction', ha='center', va='center',fontsize='xx-large')
61+
62+
ax = fig.add_subplot(gs[idx+1,0])
63+
ax.legend(fontsize='x-large')
64+
65+
# plot the states
66+
for idx, name in enumerate(env.config['states']):
67+
ax = fig.add_subplot(gs[idx,1] )
68+
ax.plot(uncontrolled_states.index, uncontrolled_states[str(env.config['states'][idx])], label='Uncontrolled',color='black',alpha=0.6)
69+
ax.plot(mpc_states.index, mpc_states[str(env.config['states'][idx])], label='MPC',color='green',alpha=0.6)
70+
71+
ax.annotate(str(env.config['states'][idx]), xy=(0.5, 0.8), xycoords='axes fraction', ha='center', va='center',fontsize='xx-large')
72+
ax.axhline(y = pyswmm.Nodes(env.env.sim)[name[0]].full_depth, color='r', linestyle='--')
73+
74+
75+
if idx == len(env.config['states']) - 1:
76+
ax.set_xlabel("time")
77+
# just add ticks in the beginning, middle, and end of the index
78+
ax.set_xticks([mpc_actions.index[0],mpc_actions.index[int(len(mpc_actions.index)/2)],mpc_actions.index[-1]])
79+
80+
if idx == 0:
81+
ax.set_title("States")
82+
if idx != len(env.config['states']) - 1: # not the last row
83+
ax.set_xticks([])
84+
ax.set_xticklabels([])
85+
86+
87+
unc_perf = sum(uncontrolled_data_log['performance_measure'])
88+
mpc_perf = sum(mpc_data_log['performance_measure'])
89+
perfstr = "Cost Difference from Uncontrolled\nModel Predictive Control = {:+.1%}".format((mpc_perf - unc_perf)/unc_perf)
90+
ax = fig.add_subplot(gs[-1,0])
91+
ax.annotate(perfstr, xy=(0.55, 0.4), xycoords='axes fraction', ha='center', va='center',fontsize='x-large')
92+
ax.axis('off')
93+
94+
plt.tight_layout()
95+
plt.savefig(str("./v" + version + "/lev" + level + "/actions_states.png"))
96+
plt.savefig(str("./v" + version + "/lev" + level + "/actions_states.svg"))
97+
#plt.show()
98+
plt.close('all')
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
'''
2+
# install pystorms from the current directory (this should be commented out in final version once pystorms source code isn't changing all the time)
3+
import subprocess
4+
import sys
5+
subprocess.check_call([sys.executable, '-m', 'pip', 'uninstall', '-y', 'pystorms'])
6+
subprocess.check_call([sys.executable, '-m', 'pip', 'cache', 'purge'])
7+
subprocess.check_call([sys.executable, '-m', 'pip', 'install', '.'])
8+
'''
9+
import pystorms # this will be the first line of the program when dev is done
10+
11+
import pyswmm
12+
import numpy as np
13+
import matplotlib.pyplot as plt
14+
import pandas as pd
15+
import dill as pickle
16+
import datetime
17+
import os
18+
import swmmio
19+
20+
np.set_printoptions(precision=3,suppress=True)
21+
22+
# BETA
23+
# options are: 'mpc' (per sadler 2020) or 'uncontrolled'
24+
evaluating = 'uncontrolled'
25+
verbose = True
26+
version = "1" # options are "1" and "2"
27+
level = "1" # options are "1" , "2", and "3"
28+
plot = True # plot True significantly increases the memory usage.
29+
# set the working directory to the directory of this script
30+
os.chdir(os.path.dirname(os.path.abspath(__file__)))
31+
print(os.getcwd())
32+
# set the random seed
33+
rand_seed = 42
34+
np.random.seed(rand_seed)
35+
36+
37+
print("evaluating ", evaluating, " for beta scenario")
38+
39+
if evaluating == "mpc":
40+
folder_path = str("./v" + version + "/lev" + level + "/results")
41+
elif evaluating == "uncontrolled":
42+
folder_path = str("./v" + version + "/results")
43+
44+
if not os.path.exists(folder_path):
45+
os.makedirs(folder_path)
46+
47+
48+
# project file is in english units
49+
cfs2cms = 35.315
50+
ft2meters = 3.281
51+
52+
53+
54+
mpc_df = pd.read_csv("mpc_rules_beta.csv")
55+
mpc_df['datetime'] = pd.to_datetime(mpc_df['datetime'])
56+
57+
# convert the dataframe of rules to an easily readable dictionary
58+
mpc_df['P0'].replace({"ON":1.0, "OFF":0.0}, inplace=True)
59+
mpc_df.drop(columns=["simtime (hr)"], inplace=True)
60+
mpc_datetimes = mpc_df['datetime'].to_list()
61+
mpc_controller = mpc_df.set_index('datetime').to_dict()
62+
63+
# initialize the scenario, and obtain the initial controller settings
64+
#env = pystorms.scenarios.beta(level=level)
65+
env = pystorms.scenarios.beta()
66+
controller_datetime = env.env.sim.start_time
67+
actions = np.array([mpc_controller['R2'][controller_datetime],
68+
mpc_controller['P0'][controller_datetime],
69+
mpc_controller['W0'][controller_datetime]])
70+
done = False
71+
72+
last_eval = env.env.sim.start_time - datetime.timedelta(days=1) # initto a time before the simulation starts
73+
last_read = env.env.sim.start_time - datetime.timedelta(days=1) # initto a time before the simulation starts
74+
75+
states = pd.DataFrame(columns = env.config['states'])
76+
actions_log = pd.DataFrame(columns = env.config['action_space'])
77+
78+
79+
# Run the simulation
80+
while not done:
81+
82+
if evaluating == "mpc" and (env.env.sim.current_time >= controller_datetime) and (controller_datetime in mpc_datetimes):
83+
actions = np.array([mpc_controller['R2'][controller_datetime],
84+
mpc_controller['P0'][controller_datetime],
85+
mpc_controller['W0'][controller_datetime]])
86+
controller_datetime += datetime.timedelta(minutes=15)
87+
elif evaluating == "uncontrolled":
88+
actions = np.array([1.0, 0.0, 1.0]) # orifice and weir open, pump off.
89+
else:
90+
exit(1)
91+
if (not done) and verbose and env.env.sim.current_time.minute == 0 and env.env.sim.current_time.hour % 4 == 0:
92+
u_print = actions.flatten()
93+
y_measured = env.state(level=level).reshape(-1,1)
94+
# print the names of the states and their current values side-by-side
95+
print("state, value")
96+
for idx in range(len(env.config['states'])):
97+
print(env.config['states'][idx], y_measured[idx])
98+
print("actuator, setting")
99+
for idx in range(len(env.config['action_space'])):
100+
print(env.config['action_space'][idx], u_print[idx])
101+
102+
print("current time, end time")
103+
print(env.env.sim.current_time, env.env.sim.end_time)
104+
print("\n")
105+
106+
if (not done) and (env.env.sim.current_time > (last_read + datetime.timedelta(minutes=1))) and plot: # log data
107+
last_read = env.env.sim.current_time
108+
state = env.state(level="1").reshape(1,len(env.config['states']))
109+
current_state = pd.DataFrame(data=state, columns = env.config['states'], index = [env.env.sim.current_time] )
110+
states = pd.concat((states,current_state))
111+
action = actions.reshape(1,len(env.config['action_space']))
112+
current_actions = pd.DataFrame(data = action, columns = env.config['action_space'], index=[env.env.sim.current_time])
113+
actions_log = pd.concat((actions_log, current_actions))
114+
115+
116+
if (not done) and env.env.sim.current_time > env.env.sim.end_time - datetime.timedelta(hours=1):
117+
final_depths = env.state(level="1")
118+
119+
#done = env.step(actions.flatten(),level=level)
120+
done = env.step(actions.flatten())
121+
# note that noise won't affect the controller as it's predetermined
122+
# but actuator faults such as getting stuck will still affect the controller
123+
perf = sum(env.data_log["performance_measure"])
124+
print("flooding")
125+
for key,value in env.data_log['flooding'].items():
126+
# flooded nodes
127+
if sum(value) > 0:
128+
print(key, sum(value))
129+
130+
131+
# save the cost and ending dpeths to a csv
132+
perf_summary = pd.DataFrame(data = {"cost": perf, "final_depths": final_depths})
133+
if evaluating == "uncontrolled":
134+
perf_summary.to_csv(str(folder_path + "/costs_" + evaluating + ".csv"))
135+
else:
136+
perf_summary.to_csv(str(folder_path + "/costs_" + evaluating + ".csv"))
137+
138+
if plot:
139+
140+
if evaluating == "uncontrolled":
141+
states.to_csv(str(folder_path + "/states_" + str(evaluating) + ".csv"))
142+
actions_log.to_csv(str(folder_path + "/actions_" + str(evaluating) + ".csv"))
143+
# and the data log
144+
with open(f'./v{version}/results/{evaluating}_data_log.pkl', 'wb') as f:
145+
pickle.dump(env.data_log, f)
146+
else:
147+
# save the flows and depths
148+
states.to_csv(str(folder_path + "/states_" + str(evaluating) + ".csv"))
149+
actions_log.to_csv(str(folder_path + "/actions_" + str(evaluating) + ".csv"))
150+
# and the data log
151+
with open(f'./v{version}/lev{level}/results/{str(evaluating )}_data_log.pkl', 'wb') as f:
152+
pickle.dump(env.data_log, f)
153+
154+
155+
# if there are any na values in states or weir_heads32, linearly interpolate over them
156+
states.interpolate(method='time',axis='index',inplace=True)
157+
#weir_heads32.interpolate(method='time',axis='index',inplace=True)
158+
actions_log.interpolate(method='time',axis='index',inplace=True)
159+
#flows.interpolate(method='time',axis='index',inplace=True)
160+
161+
plots_high = max(len(env.config['action_space']) , len(env.config['states']))
162+
fig, axes = plt.subplots(plots_high, 2, figsize=(10,2*plots_high))
163+
164+
axes[0,0].set_title("actions")
165+
axes[0,1].set_title("states")
166+
# plot the actions
167+
for idx in range(len(env.config['action_space'])):
168+
axes[idx,0].plot(actions_log.iloc[:,idx])
169+
axes[idx,0].set_ylabel("setting")
170+
if idx == len(env.config['action_space']) - 1:
171+
axes[idx,0].set_xlabel("time")
172+
# plot only the first, middle, and last x-ticks
173+
xticks = axes[idx,0].get_xticks()
174+
xticks = [xticks[0],xticks[int(len(xticks)/2)],xticks[-1]]
175+
axes[idx,0].set_xticks(xticks)
176+
if idx != len(env.config['action_space']) - 1: # not the last row
177+
axes[idx,0].set_xticklabels([])
178+
axes[idx,0].annotate(str(env.config['action_space'][idx]), xy=(0.5, 0.8), xycoords='axes fraction', ha='center', va='center',fontsize='xx-large')
179+
180+
181+
# plot the states
182+
for idx in range(len(env.config['states'])):
183+
axes[idx,1].plot(states.iloc[:,idx])
184+
185+
if idx == len(env.config['states']) - 1:
186+
axes[idx,1].set_xlabel("time")
187+
axes[idx,1].annotate(str(env.config['states'][idx]), xy=(0.5, 0.4), xycoords='axes fraction', ha='center', va='center',fontsize='xx-large')
188+
# plot only the first, middle, and last x-ticks
189+
xticks = axes[idx,1].get_xticks()
190+
xticks = [xticks[0],xticks[int(len(xticks)/2)],xticks[-1]]
191+
axes[idx,1].set_xticks(xticks)
192+
193+
if idx != len(env.config['states']) - 1:
194+
axes[idx,1].set_xticklabels([])
195+
axes[idx,1].annotate(str(env.config['states'][idx]), xy=(0.5, 0.8), xycoords='axes fraction', ha='center', va='center',fontsize='xx-large')
196+
197+
198+
plt.tight_layout()
199+
if evaluating == "uncontrolled":
200+
plt.savefig(str(folder_path + "/evaluate_" + str(evaluating) + ".png"),dpi=450)
201+
plt.savefig(str(folder_path + "/evaluate_" + str(evaluating) + ".svg"),dpi=450)
202+
else:
203+
plt.savefig(str(folder_path + "/evaluate_" + str(evaluating) + ".png"),dpi=450)
204+
plt.savefig(str(folder_path + "/evaluate_" + str(evaluating) + ".svg"),dpi=450)
205+
#plt.show()
206+
plt.close('all')

0 commit comments

Comments
 (0)