1+ from cProfile import label
2+ import pystorms
3+ import pyswmm
4+ import numpy as np
5+ import matplotlib .pyplot as plt
6+ import pandas as pd
7+ import dill as pickle
8+ import datetime
9+ import networkx as nx
10+ import matplotlib .patches as mpatches
11+ from matplotlib .gridspec import GridSpec
12+ import os
13+
14+ # DELTA SCENARIO
15+ version = "2"
16+ level = "1"
17+ # set the working directory to the directory of this script
18+ os .chdir (os .path .dirname (os .path .abspath (__file__ )))
19+ print (os .getcwd ())
20+ env = pystorms .scenarios .delta (version = version ,level = level )
21+ env .env .sim .start ()
22+
23+
24+ # choose parameters for the plot
25+ static_plus_rule_param = "0.0"
26+ prop_outflow_param = "0.0"
27+
28+ static_plus_rule_data_log = pd .read_pickle (str ("./v" + version + "/lev" + level + "/results/static-plus-rule_param=" + str (static_plus_rule_param ) + "_data_log.pkl" ))
29+ prop_outflow_data_log = pd .read_pickle (str ("./v" + version + "/lev" + level + "/results/prop-outflow_param=" + str (prop_outflow_param ) + "_data_log.pkl" ))
30+ uncontrolled_data_log = pd .read_pickle (str ("./v" + version + "/results/uncontrolled_data_log.pkl" ))
31+
32+ # print the costs
33+ print ("Costs" )
34+ print ("uncontrolled: " , "{:.2E}" .format (sum (uncontrolled_data_log ['performance_measure' ])))
35+ print ("Static+Rule: " , "{:.2E}" .format (sum (static_plus_rule_data_log ['performance_measure' ])))
36+ print ("Prop Outflow: " , "{:.2E}" .format (sum (prop_outflow_data_log ['performance_measure' ])))
37+
38+ # load the actions and states
39+ uncontrolled_actions = pd .read_csv ("./v" + version + "/results/actions_uncontrolled.csv" ,index_col = 0 ,parse_dates = True )
40+ uncontrolled_states = pd .read_csv ("./v" + version + "/results/states_uncontrolled.csv" ,index_col = 0 ,parse_dates = True )
41+ static_plus_rule_actions = pd .read_csv (str ("./v" + version + "/lev" + level + "/results/actions_static-plus-rule_param=" + static_plus_rule_param + ".csv" ),index_col = 0 ,parse_dates = True )
42+ static_plus_rule_states = pd .read_csv (str ("./v" + version + "/lev" + level + "/results/states_static-plus-rule_param=" + static_plus_rule_param + ".csv" ),index_col = 0 ,parse_dates = True )
43+ prop_outflow_actions = pd .read_csv (str ("./v" + version + "/lev" + level + "/results/actions_prop-outflow_param=" + prop_outflow_param + ".csv" ),index_col = 0 ,parse_dates = True )
44+ prop_outflow_states = pd .read_csv (str ("./v" + version + "/lev" + level + "/results/states_prop-outflow_param=" + prop_outflow_param + ".csv" ),index_col = 0 ,parse_dates = True )
45+
46+ operational_bounds_data = {
47+ "Lower Limit" : [5.32 , 4.44 , 5.20 , 3.28 , None ],
48+ "Upper Limit" : [5.92 , 5.04 , 5.80 , 3.80 , 6.55 ]
49+ }
50+
51+ operational_bounds_df = pd .DataFrame (operational_bounds_data , index = ["N3" , "N2" , "N1" , "C" , "S" ])
52+
53+ exceedance_bounds_data = {
54+ "Lower Limit" : [5.28 , 4.04 , 2.11 , 2.21 , None ],
55+ "Upper Limit" : [11.99 , 6.59 , 5.92 , 5.70 , 9.55 ]
56+ }
57+
58+ exceedance_bounds_df = pd .DataFrame (exceedance_bounds_data , index = ["N3" , "N2" , "N1" , "C" , "S" ])
59+
60+
61+ # record total outflows under each control scenario
62+ static_plus_rule_total_outflows = sum (static_plus_rule_data_log ['flow' ]['conduit_Eout' ])
63+ prop_outflow_total_outflows = sum (prop_outflow_data_log ['flow' ]['conduit_Eout' ])
64+ uncontrolled_total_outflows = sum (uncontrolled_data_log ['flow' ]['conduit_Eout' ])
65+ # print those total outflows
66+ print ("Total outflows from system through Eout" )
67+ print ("Static+Rule: " , "{:.2E}" .format (static_plus_rule_total_outflows ))
68+ print ("Prop Outflow: " , "{:.2E}" .format (prop_outflow_total_outflows ))
69+ print ("Uncontrolled: " , "{:.2E}" .format (uncontrolled_total_outflows ))
70+
71+ # print the final depths in each storage asset under each control scenario
72+ print ("final depths in storage basins" )
73+ print ("Static+Rule: \n " , static_plus_rule_states .iloc [- 1 ,:])
74+ print ("Prop Outflow: \n " , prop_outflow_states .iloc [- 1 ,:])
75+ print ("Uncontrolled: \n " , uncontrolled_states .iloc [- 1 ,:])
76+
77+ # print the last date
78+ print ("last timestep" )
79+ print ("static+rule: " , static_plus_rule_data_log ['simulation_time' ][- 1 ])
80+ print ("prop outflow: " , prop_outflow_data_log ['simulation_time' ][- 1 ])
81+ print ("uncontrolled: " , uncontrolled_data_log ['simulation_time' ][- 1 ])
82+ print ("number of timesteps" )
83+ print ("static+rule: " , len (static_plus_rule_data_log ['simulation_time' ]))
84+ print ("prop outflow: " , len (prop_outflow_data_log ['simulation_time' ]))
85+ print ("uncontrolled: " , len (uncontrolled_data_log ['simulation_time' ]))
86+
87+ plots_high = max (len (env .config ['action_space' ]) , len (env .config ['states' ]))
88+ fig , axes = plt .subplots (plots_high , 2 , figsize = (10 ,2 * plots_high ))
89+
90+ axes [0 ,0 ].set_title ("actions" )
91+ axes [0 ,1 ].set_title ("states" )
92+ # plot the actions
93+ for idx in range (len (env .config ['action_space' ])):
94+ #axes[idx,0].plot(weir_heads32.iloc[:,idx])
95+ #axes[idx,0].set_ylabel("(weir head [ft])^(3/2)")
96+ axes [idx ,0 ].plot (static_plus_rule_actions .index , static_plus_rule_actions [env .config ['action_space' ][idx ]], label = 'Static+Rule' ,color = 'blue' ,alpha = 0.6 )
97+ axes [idx ,0 ].plot (prop_outflow_actions .index , prop_outflow_actions [env .config ['action_space' ][idx ]], label = 'Prop Outflow' ,color = 'red' ,alpha = 0.6 )
98+ axes [idx ,0 ].plot (uncontrolled_actions .index , uncontrolled_actions [env .config ['action_space' ][idx ]], label = 'Uncontrolled' ,color = 'black' ,alpha = 0.6 )
99+ axes [idx ,0 ].set_ylabel ("fraction open" )
100+ if idx == len (env .config ['action_space' ]) - 1 :
101+ axes [idx ,0 ].set_xlabel ("time" )
102+ # plot only the first, middle, and last x-ticks
103+ xticks = axes [idx ,0 ].get_xticks ()
104+ xticks = [xticks [0 ],xticks [int (len (xticks )/ 2 )],xticks [- 1 ]]
105+ axes [idx ,0 ].set_xticks (xticks )
106+ if idx != len (env .config ['action_space' ]) - 1 : # not the last row
107+ axes [idx ,0 ].set_xticklabels ([])
108+ 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' )
109+ # plot flows through Eout
110+ #axes[-1,0].plot(env.data_log['flow']['conduit_Eout'])
111+ axes [- 1 ,0 ].plot (uncontrolled_data_log ['simulation_time' ],uncontrolled_data_log ['flow' ]['conduit_Eout' ],label = "uncontrolled" ,color = 'black' ,alpha = 0.6 )
112+ axes [- 1 ,0 ].plot (static_plus_rule_data_log ['simulation_time' ],static_plus_rule_data_log ['flow' ]['conduit_Eout' ],label = "static+rule" ,color = 'blue' ,alpha = 0.6 )
113+ axes [- 1 ,0 ].plot (prop_outflow_data_log ['simulation_time' ],prop_outflow_data_log ['flow' ]['conduit_Eout' ],label = "prop outflow" ,color = 'red' ,alpha = 0.6 )
114+ axes [- 1 ,0 ].set_ylabel ("flow" )
115+ axes [- 1 ,0 ].set_xlabel ("time" )
116+ # add a dotted red line at threshold
117+ axes [- 1 ,0 ].axhline (y = env .threshold , color = 'r' , linestyle = 'dotted' )
118+
119+
120+ # plot the states
121+ for idx , state in enumerate (env .config ['states' ]):
122+ axes [idx ,1 ].plot (uncontrolled_states .index , uncontrolled_states [str (env .config ['states' ][idx ])], label = 'Uncontrolled' ,color = 'black' ,alpha = 0.6 )
123+ axes [idx ,1 ].plot (static_plus_rule_states .index , static_plus_rule_states [str (env .config ['states' ][idx ])], label = 'Static+Rule' ,color = 'blue' ,alpha = 0.6 )
124+ axes [idx ,1 ].plot (prop_outflow_states .index , prop_outflow_states [str (env .config ['states' ][idx ])], label = 'Prop Outflow' ,color = 'red' ,alpha = 0.6 )
125+
126+ # add bound lines (dotted blue operational, solid red exceedance)
127+ if '4' not in state [0 ]: # basin N4 isn't controlled and doesn't have bounds
128+ if "S" not in state [0 ]: # basin S doesn't have lower bounds defined
129+ axes [idx ,1 ].axhline (y = operational_bounds_df .loc [state [0 ][6 :],'Lower Limit' ] , color = 'b' , linestyle = 'dotted' )
130+ axes [idx ,1 ].axhline (y = exceedance_bounds_df .loc [state [0 ][6 :],'Lower Limit' ] , color = 'r' )
131+
132+ axes [idx ,1 ].axhline (y = operational_bounds_df .loc [state [0 ][6 :],'Upper Limit' ] , color = 'b' , linestyle = 'dotted' )
133+ axes [idx ,1 ].axhline (y = exceedance_bounds_df .loc [state [0 ][6 :],'Upper Limit' ] , color = 'r' )
134+
135+ if idx == len (env .config ['states' ]) - 1 :
136+ axes [idx ,1 ].set_xlabel ("time" )
137+ axes [idx ,1 ].annotate (str (env .config ['states' ][idx ]), xy = (0.5 , 0.4 ), xycoords = 'axes fraction' , ha = 'center' , va = 'center' ,fontsize = 'xx-large' )
138+
139+ # plot only the first, middle, and last x-ticks
140+ xticks = axes [idx ,1 ].get_xticks ()
141+ xticks = [xticks [0 ],xticks [int (len (xticks )/ 2 )],xticks [- 1 ]]
142+ axes [idx ,1 ].set_xticks (xticks )
143+
144+ if idx == 2 :
145+ # put the legend in middle of axes
146+ axes [idx ,1 ].legend ()
147+
148+ if idx != len (env .config ['states' ]) - 1 :
149+ axes [idx ,1 ].set_xticklabels ([])
150+ axes [idx ,1 ].annotate (str (env .config ['states' ][idx ]), xy = (0.5 , 0.8 ), xycoords = 'axes fraction' , ha = 'center' , va = 'center' ,fontsize = 'xx-large' )
151+
152+
153+ unc_perf = sum (uncontrolled_data_log ['performance_measure' ])
154+ prop_perf = sum (prop_outflow_data_log ['performance_measure' ])
155+ static_perf = sum (static_plus_rule_data_log ['performance_measure' ])
156+
157+ perfstr = "Cost Difference from Uncontrolled\n Static+Rule = {:+.1%}\n Prop-Outflow = {:+.1%}" .format ((static_perf - unc_perf )/ unc_perf , (prop_perf - unc_perf )/ unc_perf )
158+ axes [- 2 ,1 ].annotate (perfstr , xy = (0.5 , 0.45 ), xycoords = 'axes fraction' , ha = 'center' , va = 'center' ,fontsize = 'large' )
159+
160+
161+ plt .tight_layout ()
162+ # only going to use one plot for level (at most) so don't worry about tracking parameters
163+ plt .savefig (str ("./v" + version + "/lev" + level + "/actions_states.png" ))
164+ plt .savefig (str ("./v" + version + "/lev" + level + "/actions_states.svg" ))
165+ #plt.show()
166+ plt .close ('all' )
0 commit comments