@@ -46,7 +46,8 @@ def debug(type, value, tb):
4646 parser = _ArgumentParser (allow_abbrev = False , add_help = False )
4747 add_module_args (parser )
4848 module_options = parser .parse_known_args (args = args )[0 ]
49- if do_inputs_need_upgrade (module_options .inputs_dir ):
49+ if (os .path .exists (module_options .inputs_dir ) and
50+ do_inputs_need_upgrade (module_options .inputs_dir )):
5051 do_upgrade = query_yes_no (
5152 ("Warning! Your inputs directory needs to be upgraded. "
5253 "Do you want to auto-upgrade now? We'll keep a backup of "
@@ -76,6 +77,10 @@ def debug(type, value, tb):
7677 if return_model and not return_instance :
7778 return model
7879
80+ if model .options .reload_prior_solution :
81+ if not os .path .isdir (model .options .outputs_dir ):
82+ raise IOError ("Specified outputs directory for solution exploration does not exist." )
83+
7984 # get a list of modules to iterate through
8085 iterate_modules = get_iteration_list (model )
8186
@@ -93,9 +98,9 @@ def debug(type, value, tb):
9398 # create an instance
9499 instance = model .load_inputs ()
95100 instance .pre_solve ()
101+ instantiation_time = time .time ()
96102 if model .options .verbose :
97- instantiation_time = time .time ()
98- print "Inputs loaded in {:.2f} s." .format (instantiation_time - creation_time )
103+ print "Inputs loaded in {:.2f} s.\n " .format (instantiation_time - creation_time )
99104
100105 # return the instance as-is if requested
101106 if return_instance :
@@ -104,49 +109,73 @@ def debug(type, value, tb):
104109 else :
105110 return instance
106111
107- # make sure the outputs_dir exists (used by some modules during iterate)
108- # use a race-safe approach in case this code is run in parallel
109- try :
110- os .makedirs (instance .options .outputs_dir )
111- except OSError :
112- # directory probably exists already, but double-check
113- if not os .path .isdir (instance .options .outputs_dir ):
114- raise
115-
116- # solve the model
117- if iterate_modules :
118- if instance .options .verbose :
119- print "iterating model..."
120- iterate (instance , iterate_modules )
112+ if model .options .reload_prior_solution :
113+ # read variable values from previously solved model
114+ import csv
115+ var_objects = [c for c in instance .component_objects ()
116+ if isinstance (c ,pyomo .core .base .Var )]
117+ def _convert_if_numeric (s ):
118+ try :
119+ return float (s )
120+ except ValueError :
121+ return s
122+ for var in var_objects :
123+ if '{}.tab' .format (var .name ) not in os .listdir (model .options .outputs_dir ):
124+ raise RuntimeError ("Tab output file for variable {} cannot be found in outputs directory. Exiting." .format (var .name ))
125+ with open (os .path .join (model .options .outputs_dir , '{}.tab' .format (var .name )),'r' ) as f :
126+ reader = csv .reader (f , delimiter = '\t ' )
127+ # skip headers
128+ next (reader )
129+ for row in reader :
130+ index = (_convert_if_numeric (i ) for i in row [:- 1 ])
131+ var [index ].value = float (row [- 1 ])
132+ print 'Loaded variable {} values into instance.' .format (var .name )
133+ output_loading_time = time .time ()
134+ print 'Finished loading previous results into model instance in {:.2f} s.' .format (output_loading_time - instantiation_time )
121135 else :
122- results = solve (instance )
123- if instance .options .verbose :
124- print "Optimization termination condition was {}.\n " .format (
125- results .solver .termination_condition )
126-
127- # report/save results
128- if instance .options .verbose :
129- post_solve_start_time = time .time ()
130- print "Executing post solve functions..."
131- instance .post_solve ()
132- if instance .options .verbose :
133- post_solve_end_time = time .time ()
134- print "Post solve processing completed in {:.2f} s." .format (
135- post_solve_end_time - post_solve_start_time )
136+ # make sure the outputs_dir exists (used by some modules during iterate)
137+ # use a race-safe approach in case this code is run in parallel
138+ try :
139+ os .makedirs (model .options .outputs_dir )
140+ except OSError :
141+ # directory probably exists already, but double-check
142+ if not os .path .isdir (model .options .outputs_dir ):
143+ raise
144+
145+ # solve the model
146+ if iterate_modules :
147+ if model .options .verbose :
148+ print "Iterating model..."
149+ iterate (instance , iterate_modules )
150+ else :
151+ results = solve (instance )
152+ if model .options .verbose :
153+ print "Optimization termination condition was {}.\n " .format (
154+ results .solver .termination_condition )
155+
156+ # report/save results
157+ if model .options .verbose :
158+ post_solve_start_time = time .time ()
159+ print "Executing post solve functions..."
160+ instance .post_solve ()
161+ if model .options .verbose :
162+ post_solve_end_time = time .time ()
163+ print "Post solve processing completed in {:.2f} s." .format (
164+ post_solve_end_time - post_solve_start_time )
136165
137166 # return stdout to original
138167 sys .stdout = stdout_copy
139168
140- if pre_module_options . interact :
169+ if model . options . interact or model . options . reload_prior_solution :
141170 m = instance # present the solved model as 'm' for convenience
142171 banner = (
143172 "\n "
144- "================================================================================= \n "
173+ "=======================================================================\n "
145174 "Entering interactive Python shell.\n "
146175 "Abstract model is in 'model' variable; \n "
147176 "Solved instance is in 'instance' and 'm' variables.\n "
148177 "Type ctrl-d or exit() to exit shell.\n "
149- "================================================================================= \n "
178+ "=======================================================================\n "
150179 )
151180 import code
152181 code .interact (banner = banner , local = dict (globals ().items () + locals ().items ()))
@@ -331,6 +360,12 @@ def define_arguments(argparser):
331360 argparser .add_argument (
332361 '--verbose' , '-v' , default = False , action = 'store_true' ,
333362 help = 'Show information about model preparation and solution' )
363+ argparser .add_argument (
364+ '--interact' , default = False , action = 'store_true' ,
365+ help = 'Enter interactive shell after solving the instance to enable inspection of the solved model.' )
366+ argparser .add_argument (
367+ '--reload-prior-solution' , default = False , action = 'store_true' ,
368+ help = 'Load outputs from a previously solved instance into variable values to allow interactive exploration of model components without having to solve the instance again.' )
334369
335370
336371def add_module_args (parser ):
@@ -362,8 +397,7 @@ def add_pre_module_args(parser):
362397 help = 'Directory containing log files (default is "logs"' )
363398 parser .add_argument ("--debug" , action = "store_true" , default = False ,
364399 help = 'Automatically start pdb debugger on exceptions' )
365- parser .add_argument ("--interact" , action = "store_true" , default = False ,
366- help = 'Enter interactive shell after solving model (to inspect finished model).' )
400+
367401
368402def parse_pre_module_options (args ):
369403 """
@@ -612,7 +646,6 @@ def query_yes_no(question, default="yes"):
612646 "(or 'y' or 'n').\n " )
613647
614648
615-
616649###############
617650
618651if __name__ == "__main__" :
0 commit comments