|
7 | 7 |
|
8 | 8 | from datetime import datetime |
9 | 9 |
|
10 | | -from .parameters import modify_params |
| 10 | +from .parameters import modify_params, Parameters |
| 11 | +from .data import Data |
| 12 | +from .util import load_statvar |
11 | 13 | from .simulation import Simulation |
12 | 14 |
|
13 | 15 |
|
@@ -90,6 +92,43 @@ def __init__(self, base_dir, scenarios_dir, title=None, description=None): |
90 | 92 | uuid_title_map={}) |
91 | 93 | self.scenarios = [] |
92 | 94 |
|
| 95 | + self.outputs = None |
| 96 | + |
| 97 | + @classmethod |
| 98 | + def from_parameters_iter(cls, base_directory, parameters_iter, |
| 99 | + title=None, description=None): |
| 100 | + ''' |
| 101 | + Create a ScenarioSeries from a list of parameters and the path to a |
| 102 | + directory in which scenarios should be saved and a data and control |
| 103 | + file can be found. |
| 104 | + ''' |
| 105 | + series = cls(base_directory, base_directory, |
| 106 | + title=title, description=description) |
| 107 | + |
| 108 | + for parameters in parameters_iter: |
| 109 | + |
| 110 | + title = parameters['title'] if 'title' in parameters else None |
| 111 | + |
| 112 | + uu = str(uuid.uuid4()) |
| 113 | + |
| 114 | + series.metadata['uuid_title_map'].update({uu: title}) |
| 115 | + |
| 116 | + scenario_dir = os.path.join(series.scenarios_dir, uu) |
| 117 | + |
| 118 | + scenario = Scenario(series.base_dir, scenario_dir, title=title) |
| 119 | + |
| 120 | + scenario.build() |
| 121 | + |
| 122 | + series.scenarios.append(scenario) |
| 123 | + |
| 124 | + with open( |
| 125 | + os.path.join(series.scenarios_dir, 'series_metadata.json'), 'w' |
| 126 | + ) as f: |
| 127 | + f.write(json.dumps(series.metadata, indent=2)) |
| 128 | + |
| 129 | + def __len__(self): |
| 130 | + return len(self.scenarios) |
| 131 | + |
93 | 132 | def build(self, scenarios_list): |
94 | 133 | """ |
95 | 134 | Build the scenarios from a list of scenario definitions in dicitonary |
@@ -154,6 +193,11 @@ def run(self, prms_exec='prms', nproc=None): |
154 | 193 | pool = mp.Pool(processes=nproc) |
155 | 194 | pool.map(_scenario_runner, self.scenarios) |
156 | 195 |
|
| 196 | + # self.outputs = [ |
| 197 | + # ScenarioOutput(uu, os.path.join(os.curdir(), d)) |
| 198 | + # for uu, d in self.metadata['uuid_title_map'].items() |
| 199 | + # ] |
| 200 | + |
157 | 201 |
|
158 | 202 | # multiprocessing req the function be def'd at root scope so it's picklable |
159 | 203 | def _scenario_runner(scenario, prms_exec='prms'): |
@@ -183,36 +227,38 @@ def __init__(self, base_dir, scenario_dir, |
183 | 227 |
|
184 | 228 | def build(self, param_mod_funs=None): |
185 | 229 |
|
186 | | - if not isinstance(param_mod_funs, dict): |
187 | | - raise TypeError('param_mod_funs must be a dictionary') |
188 | | - |
189 | | - # create scenario_dir that will be used as Simulation input dir |
190 | | - if os.path.isdir(self.scenario_dir): |
191 | | - shutil.rmtree(self.scenario_dir) |
192 | | - |
193 | | - os.makedirs(self.scenario_dir) |
194 | | - shutil.copy( |
195 | | - os.path.join(self.base_dir, 'control'), self.scenario_dir |
196 | | - ) |
197 | | - shutil.copy( |
198 | | - os.path.join(self.base_dir, 'data'), self.scenario_dir |
199 | | - ) |
200 | | - |
201 | | - old_params_path = os.path.join(self.base_dir, 'parameters') |
202 | | - new_params_path = os.path.join(self.scenario_dir, 'parameters') |
203 | | - if not param_mod_funs: |
204 | | - shutil.copy(old_params_path, self.scenario_dir) |
205 | | - else: |
206 | | - modify_params(old_params_path, new_params_path, param_mod_funs) |
| 230 | + if isinstance(param_mod_funs, dict): |
| 231 | + |
| 232 | + # create scenario_dir that will be used as Simulation input dir |
| 233 | + if os.path.isdir(self.scenario_dir): |
| 234 | + shutil.rmtree(self.scenario_dir) |
| 235 | + |
| 236 | + os.makedirs(self.scenario_dir) |
| 237 | + shutil.copy( |
| 238 | + os.path.join(self.base_dir, 'control'), self.scenario_dir |
| 239 | + ) |
| 240 | + shutil.copy( |
| 241 | + os.path.join(self.base_dir, 'data'), self.scenario_dir |
| 242 | + ) |
207 | 243 |
|
208 | | - param_mod_funs_metadata = { |
209 | | - param_name: inspect.getsource(param_mod_fun) |
210 | | - for param_name, param_mod_fun in param_mod_funs.items() |
211 | | - } |
| 244 | + old_params_path = os.path.join(self.base_dir, 'parameters') |
| 245 | + new_params_path = os.path.join(self.scenario_dir, 'parameters') |
| 246 | + if not param_mod_funs: |
| 247 | + shutil.copy(old_params_path, self.scenario_dir) |
| 248 | + else: |
| 249 | + modify_params(old_params_path, new_params_path, param_mod_funs) |
212 | 250 |
|
213 | | - self.metadata['mod_funs_dict'] = param_mod_funs_metadata |
| 251 | + param_mod_funs_metadata = { |
| 252 | + param_name: inspect.getsource(param_mod_fun) |
| 253 | + for param_name, param_mod_fun in param_mod_funs.items() |
| 254 | + } |
214 | 255 |
|
215 | | - self.simulation = Simulation(self.scenario_dir, self.scenario_dir) |
| 256 | + self.metadata['mod_funs_dict'] = param_mod_funs_metadata |
| 257 | + |
| 258 | + self.simulation = Simulation(self.scenario_dir, self.scenario_dir) |
| 259 | + |
| 260 | + else: |
| 261 | + self.simulation = Simulation(self.scenario_dir) |
216 | 262 |
|
217 | 263 | self.__simulation_ready = True |
218 | 264 |
|
@@ -250,3 +296,16 @@ def __setitem__(self, key, value): |
250 | 296 | def write(self, output_path): |
251 | 297 | with open(output_path, 'w') as f: |
252 | 298 | f.write(json.dumps(self.metadata_dict)) |
| 299 | + |
| 300 | + |
| 301 | +class ScenarioOutput: |
| 302 | + |
| 303 | + def __init__(self, scenario_uu, scenario_directory, title=None): |
| 304 | + opj = os.path.join |
| 305 | + self.uuid = scenario_uu |
| 306 | + self.scenario_directory = scenario_directory |
| 307 | + self.title = title |
| 308 | + self.data = Data(opj(scenario_directory, 'data')) |
| 309 | + self.parameters = Parameters(opj(scenario_directory, 'parameters')) |
| 310 | + self.statvar = load_statvar(opj(scenario_directory, 'statvar.dat')) |
| 311 | + self.control = open(opj(scenario_directory, 'control')).read() |
0 commit comments