simulator.simple_models
A collection of trivial toy models.
1"""A collection of trivial toy models.""" 2# Imports 3import numpy as np # Misc. numerical tools 4import os # Misc. system tools 5import sys 6import scipy.stats as sc # Extended numerical tools 7from copy import copy, deepcopy 8from multiprocessing import Process, Pipe # To be able to run Python methods in background 9import time # To wait a bit before loading files 10 11import h5py # To load matlab .mat files 12from scipy import interpolate 13 14 15class lin_1d: 16 """ 17 linear 1x150 model (or whatever), just make observations of the state at given positions. 18 """ 19 20 def __init__(self, input_dict=None, m=None): 21 """ 22 Two inputs here. A dictionary of keys, or parameter directly. 23 24 Parameters 25 ---------- 26 input_dict : dict, optional 27 Dictionary containing all information required to run the simulator. It may come from, for example, an init file. 28 29 m : int, optional 30 Parameter to make predicted data. 31 32 Changelog 33 --------- 34 - ST 7/9-15 35 """ 36 self.input_dict = input_dict 37 38 assert 'reporttype' in self.input_dict, 'Reporttype is missing, please specify this' 39 assert 'reportpoint' in self.input_dict, 'Reportpoint is missing, please specify this' 40 41 self.true_prim = [self.input_dict['reporttype'], self.input_dict['reportpoint']] 42 43 self.true_order = [self.input_dict['reporttype'], self.input_dict['reportpoint']] 44 self.all_data_types = self.input_dict['datatype'] 45 self.l_prim = [int(i) for i in range(len(self.true_prim[1]))] 46 47 # Inputs 48 self.input_dict = input_dict 49 self.m = m 50 self.keys = {} 51 52 def setup_fwd_run(self, **kwargs): 53 self.__dict__.update(kwargs) # parse kwargs input into class attributes 54 assimIndex = [i for i in range(len(self.l_prim))] 55 trueOrder = self.true_order 56 57 self.pred_data = [deepcopy({}) for _ in range(len(assimIndex))] 58 for ind in self.l_prim: 59 for key in self.all_data_types: 60 self.pred_data[ind][key] = np.zeros((1, 1)) 61 62 if isinstance(trueOrder[1], list): # Check if true data prim. ind. is a list 63 self.true_prim = [trueOrder[0], [x for x in trueOrder[1]]] 64 else: # Float 65 self.true_prim = [trueOrder[0], [trueOrder[1]]] 66 67 def run_fwd_sim(self, state, member_i, del_folder=True): 68 inv_param = state.keys() 69 for prim_ind in self.l_prim: 70 for dat in self.all_data_types: 71 tmp_val = [] 72 for para in inv_param: 73 tmp_val.append(state[para][self.true_prim[1][prim_ind]]) 74 self.pred_data[prim_ind][dat] = np.array(tmp_val) 75 76 return self.pred_data 77 78 79class nonlin_onedimmodel: 80 """ 81 Class of simple 1D forward model for testing purposes. 82 """ 83 84 def __init__(self, input_dict=None): 85 """ 86 Two inputs here. A dictionary of keys, or parameter directly. 87 88 Parameters 89 ---------- 90 input_dict: dict, optional 91 contains all information the run the simulator (may come from, e.g., an init file) 92 """ 93 self.input_dict = input_dict 94 95 assert 'reporttype' in self.input_dict, 'Reporttype is missing, please specify this' 96 assert 'reportpoint' in self.input_dict, 'Reportpoint is missing, please specify this' 97 98 self.true_prim = [self.input_dict['reporttype'], self.input_dict['reportpoint']] 99 100 self.true_order = [self.input_dict['reporttype'], self.input_dict['reportpoint']] 101 self.all_data_types = self.input_dict['datatype'] 102 self.l_prim = [int(i) for i in range(len(self.true_prim[1]))] 103 104 def setup_fwd_run(self, **kwargs): 105 self.__dict__.update(kwargs) # parse kwargs input into class attributes 106 assimIndex = [i for i in range(len(self.l_prim))] 107 trueOrder = self.true_order 108 109 self.pred_data = [deepcopy({}) for _ in range(len(assimIndex))] 110 for ind in self.l_prim: 111 for key in self.all_data_types: 112 self.pred_data[ind][key] = np.zeros((1, 1)) 113 114 if isinstance(trueOrder[1], list): # Check if true data prim. ind. is a list 115 self.true_prim = [trueOrder[0], [x for x in trueOrder[1]]] 116 else: # Float 117 self.true_prim = [trueOrder[0], [trueOrder[1]]] 118 119 def run_fwd_sim(self, state, member_i, del_folder=True): 120 # Fwd. model given by Chen & Oliver, Computat. Geosci., 17(4), p. 689-703, 2013. 121 inv_param = state.keys() 122 for prim_ind in self.l_prim: 123 for dat in self.all_data_types: 124 tmp_val = [] 125 for para in inv_param: 126 tmp_val.append( 127 (7 / 12) * (state[para] ** 3) - (7 / 2) * (state[para] ** 2) + 8 * state[para]) 128 self.pred_data[prim_ind][dat] = np.array(tmp_val) 129 130 return self.pred_data 131 132 133class sevenmountains: 134 """ 135 The objective function is the elevations of the seven mountains around bergen, to test optimization algorithm 136 """ 137 138 def __init__(self, input_dict=None, state=None): 139 """ 140 Two inputs here. A dictionary of keys, or parameter directly. 141 142 Parameters 143 ---------- 144 input_dict: dict, optional 145 contains all information the run the simulator (may come from, e.g., an init file) 146 state: any, optional 147 Parameter to make predicted data 148 149 Changelog 150 --------- 151 - ST 9/5-18 152 """ 153 154 # Inputs 155 self.input_dict = input_dict 156 157 self._load_sevenmountains_data() 158 159 # If input option 1 is selected 160 if self.input_dict is not None: 161 self._extInfoInputDict() 162 163 self.state = state 164 165 # Within 166 self.m_inv = None 167 168 def _load_sevenmountains_data(self): 169 # load mountain coordinates from .mat file 170 with h5py.File('sevenMountains.mat', 'r') as f: 171 longitude = list(f['X']) 172 self.longitude = longitude[0] 173 latitude = list(f['Y']) 174 self.latitude = latitude[0] 175 elevation = list(f['Z']) 176 self.elevation = np.asarray(elevation) 177 # self.elevation = interpolate.interp2d(longitude, latitude, elevation) 178 179 def _extInfoInputDict(self): 180 """ 181 Extract the manditory and optional information from the input_dict dictionary. 182 183 184 Parameters 185 ---------- 186 input_dict : dict 187 Dictionary containing all information required to run the simulator. (Defined in self) 188 189 Returns 190 ------- 191 filename : str 192 Name of the .mako file utilized to generate the ecl input .DATA file. 193 194 Changelog 195 --------- 196 - KF 14/9-2015 197 """ 198 # In the ecl framework, all reference to the filename should be uppercase 199 # self.file = self.input_dict['runfile'].upper() 200 201 # SIMOPTIONS - simulator options 202 # TODO: Change this when more options are implemented 203 if 'simoption' in self.input_dict and self.input_dict['simoptions'][0] == 'sim_path': 204 self.options = {'sim_path': self.input_dict['simoptions'][1]} 205 else: 206 self.options = {'sim_path': ''} 207 208 if 'origbounds' in self.input_dict: 209 if isinstance(self.input_dict['origbounds'][0], list): 210 origbounds = np.array(self.input_dict['origbounds']) 211 elif self.input_dict['origbounds'] == 'auto': 212 origbounds = np.array([[np.min(self.longitude), np.max(self.longitude)], 213 [np.min(self.latitude), np.max(self.latitude)]]) 214 else: 215 origbounds = np.array([self.input_dict['origbounds']]) 216 self.orig_lb = origbounds[:, 0] 217 self.orig_ub = origbounds[:, 1] 218 219 if 'obj_const' in self.input_dict: 220 self.obj_scaling = self.input_dict['obj_const'][0][1] 221 222 # if 223 # # load mountain coordinates from .mat file and interpolate 224 # with h5py.File('sevenMountains.mat', 'r') as f: 225 # longitude = list(f['X']) 226 # longitude = longitude[0] 227 # latitude = list(f['Y']) 228 # latitude = latitude[0] 229 # elevation = list(f['Z']) 230 # elevation = asarray(elevation) 231 # self.elevation = interpolate.interp2d(longitude, latitude, elevation) 232 233 def setup_fwd_run(self, state, assim_ind=None, true_ind=None): 234 """ 235 Set input parameters from an fwd_sim in the simulation to get predicted data. Parameters can be an ensemble or 236 a single array. 237 238 Parameters 239 ---------- 240 state : dict 241 Dictionary of input parameter. It can be either a single 'state' or an ensemble of 'state'. 242 243 Other Parameters 244 ---------------- 245 true_ind : list 246 The list of observed data assimilation indices. 247 248 assim_ind : list 249 List with information on assimilation order for ensemble-based methods. 250 251 Changelog 252 --------- 253 - ST 3/6-16 254 """ 255 256 # Extract parameter 257 self.m_inv = state['coord'] 258 259 def run_fwd_sim(self, en_member=None, folder=os.getcwd(), wait_for_proc=False): 260 """ 261 Set up and run a forward simulation in an fwd_sim. The parameters for the forward simulation is set in 262 setup_fwd_run. All the steps to set up and run a forward simulation is done in this object. 263 264 Parameters 265 ---------- 266 en_member : int, optional 267 Index of the ensemble member to be run. 268 269 folder : str, optional 270 Folder where the forward simulation is run. 271 272 Changelog 273 --------- 274 - ST 3/6-16 275 """ 276 # Set free parameter to fixed 277 if self.m_inv.ndim > 1: # Ensemble matrix 278 self.state = self.m_inv[:, en_member].copy() 279 else: # Deterministic fwd_sim 280 self.state = copy(self.m_inv) 281 282 # Run forward model 283 # Use Process to run the scripts needed in the simulation 284 p = Process(target=self.call_sim, args=(folder,)) 285 p.start() 286 if wait_for_proc is True: # Use the join method of Process to wait for simulation to be finished 287 p.join() 288 else: 289 pass 290 291 return p 292 293 def call_sim(self, path=None): 294 """ 295 Run the simple 1D forward model 296 297 Parameters 298 ---------- 299 path : str, optional 300 Alternative folder where the MARE2DEM input files are located. 301 302 Returns 303 ------- 304 d : object 305 Predicted data. 306 307 Changelog 308 --------- 309 - ST 3/6-16 310 """ 311 # Save path 312 if path is not None: 313 filename = path 314 else: 315 filename = '' 316 317 func = interpolate.interp2d(self.longitude, self.latitude, self.elevation) 318 319 # Convert to original scale 320 # for i, key in enumerate(self.state): 321 control = self.orig_lb + self.state * (self.orig_ub - self.orig_lb) 322 323 if control.ndim == 1: 324 d = func(control[0], control[1]) 325 elif control.ndim == 2: 326 n = control.shape[1] 327 d = [] 328 for i in range(n): 329 d[i] = func(control[0][i], control[1][i]) 330 else: 331 print('\033[1;31mERROR: Input to objective function has wrong dimension.\033[1;m') 332 sys.exit(1) 333 # # Calc. data 334 # d = -self.m ** 2 335 336 # Save in a numpy zip file 337 np.savez(filename + 'pred_data.npz', d=[d]) 338 339 # Create static method since the following function does not use 'self' 340 @staticmethod 341 def get_sim_results(which_resp, ext_data_info=None, member=None): 342 """ 343 Get forward simulation results. Simply load the numpy array... 344 345 Parameters 346 ---------- 347 which_resp : str 348 Specifies which of the responses is to be outputted (just one data type in this case). 349 350 member : int, optional 351 Ensemble member that is finished. 352 353 Returns 354 ------- 355 y : numpy.ndarray 356 Array containing the predicted data (response). 357 358 Changelog 359 --------- 360 - ST 3/6-16 361 """ 362 363 # Ensemble runs 364 if member is not None: 365 filename = 'En_' + str(member) + os.sep 366 367 # Single run 368 else: 369 filename = '' 370 371 # Load file and get result 372 time.sleep(0.1) 373 load_file = np.load(filename + 'pred_data.npz') 374 y = np.squeeze(load_file['d']) 375 376 # Return predicted data 377 return y 378 379 # Create static method since the following function does not use 'self' 380 @staticmethod 381 def get_obj_func(obj_func_name, data_info=None, member=None): 382 # Ensemble runs 383 if member is not None: 384 filename = 'En_' + str(member) + os.sep 385 386 # Single run 387 else: 388 filename = '' 389 390 # Load file and get result 391 time.sleep(0.1) 392 load_file = np.load(filename + 'pred_data.npz') 393 y = np.squeeze(load_file['d']) 394 395 # Return predicted data 396 return y 397 398 # Create static method since the following function does not use 'self' 399 @staticmethod 400 def check_sim_end(current_run): 401 """ 402 Check if a simulation that has run in the background is finished. For ensemble-based methods, 403 there can possibly be several folders with simulations, and each folder must be checked for finished runs. To 404 check if simulation is done we search for .resp file which is the output in a successful run. 405 406 Parameters 407 ---------- 408 current_run : list 409 List of ensemble members currently running simulation. 410 411 Returns 412 ------- 413 member : int 414 Ensemble member that is finished. 415 416 Changelog 417 --------- 418 - ST 9/5-18 419 """ 420 421 # Initialize output 422 member = None 423 424 # Search for .resp file 425 if isinstance(current_run, list): 426 for i in range(len(current_run)): # Check all En_ folders 427 # Search with a specific En_folder 428 for file in os.listdir('En_' + str(current_run[i])): 429 if file == 'pred_data.npz': # If there is a output .npz file 430 member = current_run[i] 431 else: 432 member = current_run 433 434 return member 435 436 437class noSimulation: 438 439 def __init__(self, input_dict): 440 # parse information from the input. 441 # Needs to get datatype, reporttype and reportpoint 442 self.input_dict = input_dict 443 self.true_order = None 444 445 def setup_fwd_run(self, **kwargs): 446 # do whatever initialization you need. 447 # Useful to initialize the self.pred_data variable. 448 # self.pred_data is a list of dictionaries. Where each list element represents 449 # a reportpoint and the dictionary should have the datatypes as keys. 450 # Entries in the dictionary are numpy arrays. 451 self.__dict__.update(kwargs) # parse kwargs input into class attributes 452 453 def run_fwd_sim(self, state, member): 454 # run simulator. Called from the main function using p_map from p_tqdm package. 455 # Return pred_data if run is successfull, False if run failed. 456 return [state]
16class lin_1d: 17 """ 18 linear 1x150 model (or whatever), just make observations of the state at given positions. 19 """ 20 21 def __init__(self, input_dict=None, m=None): 22 """ 23 Two inputs here. A dictionary of keys, or parameter directly. 24 25 Parameters 26 ---------- 27 input_dict : dict, optional 28 Dictionary containing all information required to run the simulator. It may come from, for example, an init file. 29 30 m : int, optional 31 Parameter to make predicted data. 32 33 Changelog 34 --------- 35 - ST 7/9-15 36 """ 37 self.input_dict = input_dict 38 39 assert 'reporttype' in self.input_dict, 'Reporttype is missing, please specify this' 40 assert 'reportpoint' in self.input_dict, 'Reportpoint is missing, please specify this' 41 42 self.true_prim = [self.input_dict['reporttype'], self.input_dict['reportpoint']] 43 44 self.true_order = [self.input_dict['reporttype'], self.input_dict['reportpoint']] 45 self.all_data_types = self.input_dict['datatype'] 46 self.l_prim = [int(i) for i in range(len(self.true_prim[1]))] 47 48 # Inputs 49 self.input_dict = input_dict 50 self.m = m 51 self.keys = {} 52 53 def setup_fwd_run(self, **kwargs): 54 self.__dict__.update(kwargs) # parse kwargs input into class attributes 55 assimIndex = [i for i in range(len(self.l_prim))] 56 trueOrder = self.true_order 57 58 self.pred_data = [deepcopy({}) for _ in range(len(assimIndex))] 59 for ind in self.l_prim: 60 for key in self.all_data_types: 61 self.pred_data[ind][key] = np.zeros((1, 1)) 62 63 if isinstance(trueOrder[1], list): # Check if true data prim. ind. is a list 64 self.true_prim = [trueOrder[0], [x for x in trueOrder[1]]] 65 else: # Float 66 self.true_prim = [trueOrder[0], [trueOrder[1]]] 67 68 def run_fwd_sim(self, state, member_i, del_folder=True): 69 inv_param = state.keys() 70 for prim_ind in self.l_prim: 71 for dat in self.all_data_types: 72 tmp_val = [] 73 for para in inv_param: 74 tmp_val.append(state[para][self.true_prim[1][prim_ind]]) 75 self.pred_data[prim_ind][dat] = np.array(tmp_val) 76 77 return self.pred_data
linear 1x150 model (or whatever), just make observations of the state at given positions.
21 def __init__(self, input_dict=None, m=None): 22 """ 23 Two inputs here. A dictionary of keys, or parameter directly. 24 25 Parameters 26 ---------- 27 input_dict : dict, optional 28 Dictionary containing all information required to run the simulator. It may come from, for example, an init file. 29 30 m : int, optional 31 Parameter to make predicted data. 32 33 Changelog 34 --------- 35 - ST 7/9-15 36 """ 37 self.input_dict = input_dict 38 39 assert 'reporttype' in self.input_dict, 'Reporttype is missing, please specify this' 40 assert 'reportpoint' in self.input_dict, 'Reportpoint is missing, please specify this' 41 42 self.true_prim = [self.input_dict['reporttype'], self.input_dict['reportpoint']] 43 44 self.true_order = [self.input_dict['reporttype'], self.input_dict['reportpoint']] 45 self.all_data_types = self.input_dict['datatype'] 46 self.l_prim = [int(i) for i in range(len(self.true_prim[1]))] 47 48 # Inputs 49 self.input_dict = input_dict 50 self.m = m 51 self.keys = {}
Two inputs here. A dictionary of keys, or parameter directly.
Parameters
- input_dict (dict, optional): Dictionary containing all information required to run the simulator. It may come from, for example, an init file.
- m (int, optional): Parameter to make predicted data.
Changelog
- ST 7/9-15
53 def setup_fwd_run(self, **kwargs): 54 self.__dict__.update(kwargs) # parse kwargs input into class attributes 55 assimIndex = [i for i in range(len(self.l_prim))] 56 trueOrder = self.true_order 57 58 self.pred_data = [deepcopy({}) for _ in range(len(assimIndex))] 59 for ind in self.l_prim: 60 for key in self.all_data_types: 61 self.pred_data[ind][key] = np.zeros((1, 1)) 62 63 if isinstance(trueOrder[1], list): # Check if true data prim. ind. is a list 64 self.true_prim = [trueOrder[0], [x for x in trueOrder[1]]] 65 else: # Float 66 self.true_prim = [trueOrder[0], [trueOrder[1]]]
68 def run_fwd_sim(self, state, member_i, del_folder=True): 69 inv_param = state.keys() 70 for prim_ind in self.l_prim: 71 for dat in self.all_data_types: 72 tmp_val = [] 73 for para in inv_param: 74 tmp_val.append(state[para][self.true_prim[1][prim_ind]]) 75 self.pred_data[prim_ind][dat] = np.array(tmp_val) 76 77 return self.pred_data
80class nonlin_onedimmodel: 81 """ 82 Class of simple 1D forward model for testing purposes. 83 """ 84 85 def __init__(self, input_dict=None): 86 """ 87 Two inputs here. A dictionary of keys, or parameter directly. 88 89 Parameters 90 ---------- 91 input_dict: dict, optional 92 contains all information the run the simulator (may come from, e.g., an init file) 93 """ 94 self.input_dict = input_dict 95 96 assert 'reporttype' in self.input_dict, 'Reporttype is missing, please specify this' 97 assert 'reportpoint' in self.input_dict, 'Reportpoint is missing, please specify this' 98 99 self.true_prim = [self.input_dict['reporttype'], self.input_dict['reportpoint']] 100 101 self.true_order = [self.input_dict['reporttype'], self.input_dict['reportpoint']] 102 self.all_data_types = self.input_dict['datatype'] 103 self.l_prim = [int(i) for i in range(len(self.true_prim[1]))] 104 105 def setup_fwd_run(self, **kwargs): 106 self.__dict__.update(kwargs) # parse kwargs input into class attributes 107 assimIndex = [i for i in range(len(self.l_prim))] 108 trueOrder = self.true_order 109 110 self.pred_data = [deepcopy({}) for _ in range(len(assimIndex))] 111 for ind in self.l_prim: 112 for key in self.all_data_types: 113 self.pred_data[ind][key] = np.zeros((1, 1)) 114 115 if isinstance(trueOrder[1], list): # Check if true data prim. ind. is a list 116 self.true_prim = [trueOrder[0], [x for x in trueOrder[1]]] 117 else: # Float 118 self.true_prim = [trueOrder[0], [trueOrder[1]]] 119 120 def run_fwd_sim(self, state, member_i, del_folder=True): 121 # Fwd. model given by Chen & Oliver, Computat. Geosci., 17(4), p. 689-703, 2013. 122 inv_param = state.keys() 123 for prim_ind in self.l_prim: 124 for dat in self.all_data_types: 125 tmp_val = [] 126 for para in inv_param: 127 tmp_val.append( 128 (7 / 12) * (state[para] ** 3) - (7 / 2) * (state[para] ** 2) + 8 * state[para]) 129 self.pred_data[prim_ind][dat] = np.array(tmp_val) 130 131 return self.pred_data
Class of simple 1D forward model for testing purposes.
85 def __init__(self, input_dict=None): 86 """ 87 Two inputs here. A dictionary of keys, or parameter directly. 88 89 Parameters 90 ---------- 91 input_dict: dict, optional 92 contains all information the run the simulator (may come from, e.g., an init file) 93 """ 94 self.input_dict = input_dict 95 96 assert 'reporttype' in self.input_dict, 'Reporttype is missing, please specify this' 97 assert 'reportpoint' in self.input_dict, 'Reportpoint is missing, please specify this' 98 99 self.true_prim = [self.input_dict['reporttype'], self.input_dict['reportpoint']] 100 101 self.true_order = [self.input_dict['reporttype'], self.input_dict['reportpoint']] 102 self.all_data_types = self.input_dict['datatype'] 103 self.l_prim = [int(i) for i in range(len(self.true_prim[1]))]
Two inputs here. A dictionary of keys, or parameter directly.
Parameters
- input_dict (dict, optional): contains all information the run the simulator (may come from, e.g., an init file)
105 def setup_fwd_run(self, **kwargs): 106 self.__dict__.update(kwargs) # parse kwargs input into class attributes 107 assimIndex = [i for i in range(len(self.l_prim))] 108 trueOrder = self.true_order 109 110 self.pred_data = [deepcopy({}) for _ in range(len(assimIndex))] 111 for ind in self.l_prim: 112 for key in self.all_data_types: 113 self.pred_data[ind][key] = np.zeros((1, 1)) 114 115 if isinstance(trueOrder[1], list): # Check if true data prim. ind. is a list 116 self.true_prim = [trueOrder[0], [x for x in trueOrder[1]]] 117 else: # Float 118 self.true_prim = [trueOrder[0], [trueOrder[1]]]
120 def run_fwd_sim(self, state, member_i, del_folder=True): 121 # Fwd. model given by Chen & Oliver, Computat. Geosci., 17(4), p. 689-703, 2013. 122 inv_param = state.keys() 123 for prim_ind in self.l_prim: 124 for dat in self.all_data_types: 125 tmp_val = [] 126 for para in inv_param: 127 tmp_val.append( 128 (7 / 12) * (state[para] ** 3) - (7 / 2) * (state[para] ** 2) + 8 * state[para]) 129 self.pred_data[prim_ind][dat] = np.array(tmp_val) 130 131 return self.pred_data
134class sevenmountains: 135 """ 136 The objective function is the elevations of the seven mountains around bergen, to test optimization algorithm 137 """ 138 139 def __init__(self, input_dict=None, state=None): 140 """ 141 Two inputs here. A dictionary of keys, or parameter directly. 142 143 Parameters 144 ---------- 145 input_dict: dict, optional 146 contains all information the run the simulator (may come from, e.g., an init file) 147 state: any, optional 148 Parameter to make predicted data 149 150 Changelog 151 --------- 152 - ST 9/5-18 153 """ 154 155 # Inputs 156 self.input_dict = input_dict 157 158 self._load_sevenmountains_data() 159 160 # If input option 1 is selected 161 if self.input_dict is not None: 162 self._extInfoInputDict() 163 164 self.state = state 165 166 # Within 167 self.m_inv = None 168 169 def _load_sevenmountains_data(self): 170 # load mountain coordinates from .mat file 171 with h5py.File('sevenMountains.mat', 'r') as f: 172 longitude = list(f['X']) 173 self.longitude = longitude[0] 174 latitude = list(f['Y']) 175 self.latitude = latitude[0] 176 elevation = list(f['Z']) 177 self.elevation = np.asarray(elevation) 178 # self.elevation = interpolate.interp2d(longitude, latitude, elevation) 179 180 def _extInfoInputDict(self): 181 """ 182 Extract the manditory and optional information from the input_dict dictionary. 183 184 185 Parameters 186 ---------- 187 input_dict : dict 188 Dictionary containing all information required to run the simulator. (Defined in self) 189 190 Returns 191 ------- 192 filename : str 193 Name of the .mako file utilized to generate the ecl input .DATA file. 194 195 Changelog 196 --------- 197 - KF 14/9-2015 198 """ 199 # In the ecl framework, all reference to the filename should be uppercase 200 # self.file = self.input_dict['runfile'].upper() 201 202 # SIMOPTIONS - simulator options 203 # TODO: Change this when more options are implemented 204 if 'simoption' in self.input_dict and self.input_dict['simoptions'][0] == 'sim_path': 205 self.options = {'sim_path': self.input_dict['simoptions'][1]} 206 else: 207 self.options = {'sim_path': ''} 208 209 if 'origbounds' in self.input_dict: 210 if isinstance(self.input_dict['origbounds'][0], list): 211 origbounds = np.array(self.input_dict['origbounds']) 212 elif self.input_dict['origbounds'] == 'auto': 213 origbounds = np.array([[np.min(self.longitude), np.max(self.longitude)], 214 [np.min(self.latitude), np.max(self.latitude)]]) 215 else: 216 origbounds = np.array([self.input_dict['origbounds']]) 217 self.orig_lb = origbounds[:, 0] 218 self.orig_ub = origbounds[:, 1] 219 220 if 'obj_const' in self.input_dict: 221 self.obj_scaling = self.input_dict['obj_const'][0][1] 222 223 # if 224 # # load mountain coordinates from .mat file and interpolate 225 # with h5py.File('sevenMountains.mat', 'r') as f: 226 # longitude = list(f['X']) 227 # longitude = longitude[0] 228 # latitude = list(f['Y']) 229 # latitude = latitude[0] 230 # elevation = list(f['Z']) 231 # elevation = asarray(elevation) 232 # self.elevation = interpolate.interp2d(longitude, latitude, elevation) 233 234 def setup_fwd_run(self, state, assim_ind=None, true_ind=None): 235 """ 236 Set input parameters from an fwd_sim in the simulation to get predicted data. Parameters can be an ensemble or 237 a single array. 238 239 Parameters 240 ---------- 241 state : dict 242 Dictionary of input parameter. It can be either a single 'state' or an ensemble of 'state'. 243 244 Other Parameters 245 ---------------- 246 true_ind : list 247 The list of observed data assimilation indices. 248 249 assim_ind : list 250 List with information on assimilation order for ensemble-based methods. 251 252 Changelog 253 --------- 254 - ST 3/6-16 255 """ 256 257 # Extract parameter 258 self.m_inv = state['coord'] 259 260 def run_fwd_sim(self, en_member=None, folder=os.getcwd(), wait_for_proc=False): 261 """ 262 Set up and run a forward simulation in an fwd_sim. The parameters for the forward simulation is set in 263 setup_fwd_run. All the steps to set up and run a forward simulation is done in this object. 264 265 Parameters 266 ---------- 267 en_member : int, optional 268 Index of the ensemble member to be run. 269 270 folder : str, optional 271 Folder where the forward simulation is run. 272 273 Changelog 274 --------- 275 - ST 3/6-16 276 """ 277 # Set free parameter to fixed 278 if self.m_inv.ndim > 1: # Ensemble matrix 279 self.state = self.m_inv[:, en_member].copy() 280 else: # Deterministic fwd_sim 281 self.state = copy(self.m_inv) 282 283 # Run forward model 284 # Use Process to run the scripts needed in the simulation 285 p = Process(target=self.call_sim, args=(folder,)) 286 p.start() 287 if wait_for_proc is True: # Use the join method of Process to wait for simulation to be finished 288 p.join() 289 else: 290 pass 291 292 return p 293 294 def call_sim(self, path=None): 295 """ 296 Run the simple 1D forward model 297 298 Parameters 299 ---------- 300 path : str, optional 301 Alternative folder where the MARE2DEM input files are located. 302 303 Returns 304 ------- 305 d : object 306 Predicted data. 307 308 Changelog 309 --------- 310 - ST 3/6-16 311 """ 312 # Save path 313 if path is not None: 314 filename = path 315 else: 316 filename = '' 317 318 func = interpolate.interp2d(self.longitude, self.latitude, self.elevation) 319 320 # Convert to original scale 321 # for i, key in enumerate(self.state): 322 control = self.orig_lb + self.state * (self.orig_ub - self.orig_lb) 323 324 if control.ndim == 1: 325 d = func(control[0], control[1]) 326 elif control.ndim == 2: 327 n = control.shape[1] 328 d = [] 329 for i in range(n): 330 d[i] = func(control[0][i], control[1][i]) 331 else: 332 print('\033[1;31mERROR: Input to objective function has wrong dimension.\033[1;m') 333 sys.exit(1) 334 # # Calc. data 335 # d = -self.m ** 2 336 337 # Save in a numpy zip file 338 np.savez(filename + 'pred_data.npz', d=[d]) 339 340 # Create static method since the following function does not use 'self' 341 @staticmethod 342 def get_sim_results(which_resp, ext_data_info=None, member=None): 343 """ 344 Get forward simulation results. Simply load the numpy array... 345 346 Parameters 347 ---------- 348 which_resp : str 349 Specifies which of the responses is to be outputted (just one data type in this case). 350 351 member : int, optional 352 Ensemble member that is finished. 353 354 Returns 355 ------- 356 y : numpy.ndarray 357 Array containing the predicted data (response). 358 359 Changelog 360 --------- 361 - ST 3/6-16 362 """ 363 364 # Ensemble runs 365 if member is not None: 366 filename = 'En_' + str(member) + os.sep 367 368 # Single run 369 else: 370 filename = '' 371 372 # Load file and get result 373 time.sleep(0.1) 374 load_file = np.load(filename + 'pred_data.npz') 375 y = np.squeeze(load_file['d']) 376 377 # Return predicted data 378 return y 379 380 # Create static method since the following function does not use 'self' 381 @staticmethod 382 def get_obj_func(obj_func_name, data_info=None, member=None): 383 # Ensemble runs 384 if member is not None: 385 filename = 'En_' + str(member) + os.sep 386 387 # Single run 388 else: 389 filename = '' 390 391 # Load file and get result 392 time.sleep(0.1) 393 load_file = np.load(filename + 'pred_data.npz') 394 y = np.squeeze(load_file['d']) 395 396 # Return predicted data 397 return y 398 399 # Create static method since the following function does not use 'self' 400 @staticmethod 401 def check_sim_end(current_run): 402 """ 403 Check if a simulation that has run in the background is finished. For ensemble-based methods, 404 there can possibly be several folders with simulations, and each folder must be checked for finished runs. To 405 check if simulation is done we search for .resp file which is the output in a successful run. 406 407 Parameters 408 ---------- 409 current_run : list 410 List of ensemble members currently running simulation. 411 412 Returns 413 ------- 414 member : int 415 Ensemble member that is finished. 416 417 Changelog 418 --------- 419 - ST 9/5-18 420 """ 421 422 # Initialize output 423 member = None 424 425 # Search for .resp file 426 if isinstance(current_run, list): 427 for i in range(len(current_run)): # Check all En_ folders 428 # Search with a specific En_folder 429 for file in os.listdir('En_' + str(current_run[i])): 430 if file == 'pred_data.npz': # If there is a output .npz file 431 member = current_run[i] 432 else: 433 member = current_run 434 435 return member
The objective function is the elevations of the seven mountains around bergen, to test optimization algorithm
139 def __init__(self, input_dict=None, state=None): 140 """ 141 Two inputs here. A dictionary of keys, or parameter directly. 142 143 Parameters 144 ---------- 145 input_dict: dict, optional 146 contains all information the run the simulator (may come from, e.g., an init file) 147 state: any, optional 148 Parameter to make predicted data 149 150 Changelog 151 --------- 152 - ST 9/5-18 153 """ 154 155 # Inputs 156 self.input_dict = input_dict 157 158 self._load_sevenmountains_data() 159 160 # If input option 1 is selected 161 if self.input_dict is not None: 162 self._extInfoInputDict() 163 164 self.state = state 165 166 # Within 167 self.m_inv = None
Two inputs here. A dictionary of keys, or parameter directly.
Parameters
- input_dict (dict, optional): contains all information the run the simulator (may come from, e.g., an init file)
- state (any, optional): Parameter to make predicted data
Changelog
- ST 9/5-18
234 def setup_fwd_run(self, state, assim_ind=None, true_ind=None): 235 """ 236 Set input parameters from an fwd_sim in the simulation to get predicted data. Parameters can be an ensemble or 237 a single array. 238 239 Parameters 240 ---------- 241 state : dict 242 Dictionary of input parameter. It can be either a single 'state' or an ensemble of 'state'. 243 244 Other Parameters 245 ---------------- 246 true_ind : list 247 The list of observed data assimilation indices. 248 249 assim_ind : list 250 List with information on assimilation order for ensemble-based methods. 251 252 Changelog 253 --------- 254 - ST 3/6-16 255 """ 256 257 # Extract parameter 258 self.m_inv = state['coord']
Set input parameters from an fwd_sim in the simulation to get predicted data. Parameters can be an ensemble or a single array.
Parameters
- state (dict): Dictionary of input parameter. It can be either a single 'state' or an ensemble of 'state'.
Other Parameters
- true_ind (list): The list of observed data assimilation indices.
- assim_ind (list): List with information on assimilation order for ensemble-based methods.
Changelog
- ST 3/6-16
260 def run_fwd_sim(self, en_member=None, folder=os.getcwd(), wait_for_proc=False): 261 """ 262 Set up and run a forward simulation in an fwd_sim. The parameters for the forward simulation is set in 263 setup_fwd_run. All the steps to set up and run a forward simulation is done in this object. 264 265 Parameters 266 ---------- 267 en_member : int, optional 268 Index of the ensemble member to be run. 269 270 folder : str, optional 271 Folder where the forward simulation is run. 272 273 Changelog 274 --------- 275 - ST 3/6-16 276 """ 277 # Set free parameter to fixed 278 if self.m_inv.ndim > 1: # Ensemble matrix 279 self.state = self.m_inv[:, en_member].copy() 280 else: # Deterministic fwd_sim 281 self.state = copy(self.m_inv) 282 283 # Run forward model 284 # Use Process to run the scripts needed in the simulation 285 p = Process(target=self.call_sim, args=(folder,)) 286 p.start() 287 if wait_for_proc is True: # Use the join method of Process to wait for simulation to be finished 288 p.join() 289 else: 290 pass 291 292 return p
Set up and run a forward simulation in an fwd_sim. The parameters for the forward simulation is set in setup_fwd_run. All the steps to set up and run a forward simulation is done in this object.
Parameters
- en_member (int, optional): Index of the ensemble member to be run.
- folder (str, optional): Folder where the forward simulation is run.
Changelog
- ST 3/6-16
294 def call_sim(self, path=None): 295 """ 296 Run the simple 1D forward model 297 298 Parameters 299 ---------- 300 path : str, optional 301 Alternative folder where the MARE2DEM input files are located. 302 303 Returns 304 ------- 305 d : object 306 Predicted data. 307 308 Changelog 309 --------- 310 - ST 3/6-16 311 """ 312 # Save path 313 if path is not None: 314 filename = path 315 else: 316 filename = '' 317 318 func = interpolate.interp2d(self.longitude, self.latitude, self.elevation) 319 320 # Convert to original scale 321 # for i, key in enumerate(self.state): 322 control = self.orig_lb + self.state * (self.orig_ub - self.orig_lb) 323 324 if control.ndim == 1: 325 d = func(control[0], control[1]) 326 elif control.ndim == 2: 327 n = control.shape[1] 328 d = [] 329 for i in range(n): 330 d[i] = func(control[0][i], control[1][i]) 331 else: 332 print('\033[1;31mERROR: Input to objective function has wrong dimension.\033[1;m') 333 sys.exit(1) 334 # # Calc. data 335 # d = -self.m ** 2 336 337 # Save in a numpy zip file 338 np.savez(filename + 'pred_data.npz', d=[d])
Run the simple 1D forward model
Parameters
- path (str, optional): Alternative folder where the MARE2DEM input files are located.
Returns
- d (object): Predicted data.
Changelog
- ST 3/6-16
341 @staticmethod 342 def get_sim_results(which_resp, ext_data_info=None, member=None): 343 """ 344 Get forward simulation results. Simply load the numpy array... 345 346 Parameters 347 ---------- 348 which_resp : str 349 Specifies which of the responses is to be outputted (just one data type in this case). 350 351 member : int, optional 352 Ensemble member that is finished. 353 354 Returns 355 ------- 356 y : numpy.ndarray 357 Array containing the predicted data (response). 358 359 Changelog 360 --------- 361 - ST 3/6-16 362 """ 363 364 # Ensemble runs 365 if member is not None: 366 filename = 'En_' + str(member) + os.sep 367 368 # Single run 369 else: 370 filename = '' 371 372 # Load file and get result 373 time.sleep(0.1) 374 load_file = np.load(filename + 'pred_data.npz') 375 y = np.squeeze(load_file['d']) 376 377 # Return predicted data 378 return y
Get forward simulation results. Simply load the numpy array...
Parameters
- which_resp (str): Specifies which of the responses is to be outputted (just one data type in this case).
- member (int, optional): Ensemble member that is finished.
Returns
- y (numpy.ndarray): Array containing the predicted data (response).
Changelog
- ST 3/6-16
381 @staticmethod 382 def get_obj_func(obj_func_name, data_info=None, member=None): 383 # Ensemble runs 384 if member is not None: 385 filename = 'En_' + str(member) + os.sep 386 387 # Single run 388 else: 389 filename = '' 390 391 # Load file and get result 392 time.sleep(0.1) 393 load_file = np.load(filename + 'pred_data.npz') 394 y = np.squeeze(load_file['d']) 395 396 # Return predicted data 397 return y
400 @staticmethod 401 def check_sim_end(current_run): 402 """ 403 Check if a simulation that has run in the background is finished. For ensemble-based methods, 404 there can possibly be several folders with simulations, and each folder must be checked for finished runs. To 405 check if simulation is done we search for .resp file which is the output in a successful run. 406 407 Parameters 408 ---------- 409 current_run : list 410 List of ensemble members currently running simulation. 411 412 Returns 413 ------- 414 member : int 415 Ensemble member that is finished. 416 417 Changelog 418 --------- 419 - ST 9/5-18 420 """ 421 422 # Initialize output 423 member = None 424 425 # Search for .resp file 426 if isinstance(current_run, list): 427 for i in range(len(current_run)): # Check all En_ folders 428 # Search with a specific En_folder 429 for file in os.listdir('En_' + str(current_run[i])): 430 if file == 'pred_data.npz': # If there is a output .npz file 431 member = current_run[i] 432 else: 433 member = current_run 434 435 return member
Check if a simulation that has run in the background is finished. For ensemble-based methods, there can possibly be several folders with simulations, and each folder must be checked for finished runs. To check if simulation is done we search for .resp file which is the output in a successful run.
Parameters
- current_run (list): List of ensemble members currently running simulation.
Returns
- member (int): Ensemble member that is finished.
Changelog
- ST 9/5-18
438class noSimulation: 439 440 def __init__(self, input_dict): 441 # parse information from the input. 442 # Needs to get datatype, reporttype and reportpoint 443 self.input_dict = input_dict 444 self.true_order = None 445 446 def setup_fwd_run(self, **kwargs): 447 # do whatever initialization you need. 448 # Useful to initialize the self.pred_data variable. 449 # self.pred_data is a list of dictionaries. Where each list element represents 450 # a reportpoint and the dictionary should have the datatypes as keys. 451 # Entries in the dictionary are numpy arrays. 452 self.__dict__.update(kwargs) # parse kwargs input into class attributes 453 454 def run_fwd_sim(self, state, member): 455 # run simulator. Called from the main function using p_map from p_tqdm package. 456 # Return pred_data if run is successfull, False if run failed. 457 return [state]
446 def setup_fwd_run(self, **kwargs): 447 # do whatever initialization you need. 448 # Useful to initialize the self.pred_data variable. 449 # self.pred_data is a list of dictionaries. Where each list element represents 450 # a reportpoint and the dictionary should have the datatypes as keys. 451 # Entries in the dictionary are numpy arrays. 452 self.__dict__.update(kwargs) # parse kwargs input into class attributes