def __init__(self, params_name: str = None, params: Dict = None, eco_in: np.ndarray = None, t_in: np.ndarray = None, details_str: str = None): """Initialize SinglePlotter Parameters ---------- params_name Name of parameter set to load details_str for loading specific files eco_in Ecosystem we're passing to plotter t_in Times saved in ecosystem params We can also pass params to init and use this to load other things """ if params is None: # use this if we're loading params from directory self.params_name = params_name self.eco_in = helpers.load(self.params_name, 'data', 'single', data_label='time_series', details_str=details_str) self.t_in = helpers.load(self.params_name, 'data', 'single', data_label='time', details_str=details_str) self.params = helpers.load(self.params_name, 'params', 'single', details_str=details_str) # pass directly else: self.eco_in = eco_in self.t_in = t_in self.params = params # establish common parameter values self.num_phy = self.params['bio']['num_phy'] self.num_compartments = self.params['bio']['num_compartments'] self.num_days = self.params['num_days'] self.num_years = self.num_days / c.NUM_DAYS_PER_YEAR
def run(params_name: str, params_orig: Dict = None, method: str = 'odeint', cluster_kw: Dict = None, functions: List[Tuple[str, Callable, Dict]] = None, data_ext: str = c.DATA_EXT_DEFAULT, odeint_kw: Dict = None, details_str: str = None): """Execute a sweep of runs of the model for the parameter set specified Parameters ---------- params_name Identifier for param set to run. Used to load params if `params` is None. params_orig Dict of parameters. details_str Extra bit to add to filenames method What method to use? Either 'odeint' or 'ode' for now (with the faster 'odeint' as default) data_ext What kind of file are we saving the data to? functions The functions we'd like to apply to our output after each run cluster_kw 'cluster' (int): cluster index 'num_clusters' (int): total number of clusters in sweep If we're not loading for a specific cluster, then 'cluster' kwarg not included odeint_kw Arguments to ODEINT integrator """ ######################################################################## # load params if params_orig is None: params_orig = helpers.load(params_name, 'params', 'sweep', cluster_kw=cluster_kw, details_str=details_str) ######################################################################## # INITIAL CONDITIONS / PREPARATION # Set up initial condition vector eco_0 = helpers.initial_conditions(params_orig) ############################################################################ sweeps = params_orig['sweep']['pp'] name_list = tuple(sweep[0] for sweep in sweeps) entry_list = tuple(sweep[1] for sweep in sweeps) val_list = tuple(sweep[-1] for sweep in sweeps) val_length = len(val_list[0]) output = np.zeros( (val_length, len(functions)), dtype=object) if functions is not None else None time_saved = False # make deep copy of params_orig (because we will modify values as we sweep) for j in range(val_length): params = copy.deepcopy(params_orig) for i in range(len(val_list)): name = name_list[i] entries = entry_list[i] val = val_list[i][j] # does name end with _scale? Then scale entries by value if name.endswith('_scale'): actual_name = '_'.join(name.split('_')[:-1]) orig_key = '{}_orig'.format(actual_name) if orig_key not in params['bio']: params['bio'][orig_key] = copy.deepcopy( params['bio'][actual_name]) if entries is None: params['bio'][actual_name] = val * params['bio'][orig_key] else: for entry in entries: if isinstance(entry, (np.ndarray, tuple, list)): params['bio'][actual_name][tuple( entry )] = val * params['bio'][orig_key][tuple(entry)] else: params['bio'][actual_name][ entry] = val * params['bio'][orig_key][entry] print('{}: {}'.format(actual_name, val)) print(params['bio'][actual_name]) else: print('{}: {}'.format(name, val)) if entries is None: params['bio'][name] = val else: for entry in entries: if isinstance(entry, (np.ndarray, tuple, list)): params['bio'][name][tuple(entry)] = val else: params['bio'][name][entry] = val print(params['bio'][name]) # Update params popped_vals = helpers.additional_bio_setup(params, pop_values=True) # Run (eco, t_save) = model_int.integrate(eco_0, params, method=method, odeint_kw=odeint_kw, raise_errors=False) # put keys back for key in popped_vals: params['bio'][key] = popped_vals[key] fn_count = 0 if not time_saved: helpers.save(params_name, 'data', 'sweep', output=t_save, data_label='time', data_ext=data_ext, details_str=details_str) time_saved = True for i, f in enumerate(functions if functions is not None else []): output_name = f[0] output_fn = f[1] output_kw = f[2] if np.isnan(eco).any(): print('NaN values encountered for {}!'.format(output_name)) if fn_count == 0: print( 'Problem integrating! System likely too stiff for sweep params below:' ) # store as nans with same dimensions as output should be fake_output = helpers.build_mock_eco_output(t_save, params) output[j, i] = np.full( np.shape( output_fn(fake_output, copy.deepcopy(t_save), params, output_kw)), c.NAN_VALUE).tolist() else: # ensure params aren't modified by any changes output[j, i] = output_fn(copy.deepcopy(eco), copy.deepcopy(t_save), copy.deepcopy(params), copy.deepcopy(output_kw)) # save if this is our last go if j == val_length - 1: helpers.save(params_name, 'data', 'sweep', output=output[:, i], data_ext=data_ext, data_label=output_name, functions=functions, cluster_kw=cluster_kw, details_str=details_str) fn_count += 1
######################################################################## params_name = 'example' num_clusters = 2 data_label = 'avg_phy_total' sweep_label = 'zoo_mort_rate' kwargs = { 'data_label': data_label, 'cluster_kw': { 'num_clusters': num_clusters } } params = helpers.load(params_name, 'params', 'sweep', **kwargs) data_kw = {'in_labels': [sweep_label], 'out_label': data_label} kwargs.update(**{'pd_kw': data_kw}) data = helpers.load(params_name, 'data', 'sweep', **kwargs) data[data_label] = data[data_label].map(lambda x: x[0]) print(data.head()) fig, ax = plt.subplots(1, 1) data.plot.scatter(sweep_label, data_label, ax=ax, legend=False) ax.set_title('Average Total P Biomass vs. Z Mortality Rate') ax.set_xlabel('Z Mortality Rate') ax.set_ylabel('Avg P')
######################################################################## params_name = 'example' ################################################################################################ # DEBUG out_list = list() out_keys = list() xaxis = None num_years_plot = 3 params = helpers.load(params_name, 'params', 'single') res_phy_stoich_ratio = params.get('bio').get('res_phy_stoich_ratio') num_phy = params.get('bio').get('num_phy') num_zoo = params.get('bio').get('num_zoo') debug = helpers.load(params_name, 'debug', 'single') eco = helpers.load(params_name, 'data', 'single') phy = eco[helpers.eco_indices('phy', params=params), :] zoo = eco[helpers.eco_indices('zoo', params=params), :] zoo_prey_pref = params.get('bio').get('zoo_prey_pref') # we can compute res_zoo_makeup_ratio prey = np.zeros((num_phy + 1, num_zoo)) t, ind = np.unique(debug['t'][0], return_index=True) t_y = helpers.get_last_n_years(t, num_years_plot) / c.NUM_DAYS_PER_YEAR
######################################################################## params_name = 'example_noise' ######################################################################## plotting_threshold = 0 num_years = 5 # SINGLE PLOT plotter = SinglePlotter(params_name=params_name) num_years_simulation = plotter.num_years data = helpers.load(params_name, 'data', 'single', data_label='time_series') params = helpers.load(params_name, 'params', 'single') sns.set_context('paper') sns.set_style('white') legend_kw = { 'fontsize': 12, 'loc': 'upper center', 'bbox_to_anchor': (0.5, -0.2), 'ncol': 3 } color_kw = {'cmap': 'tab20b'} ################################################################################################
num_clusters = 2 params_name = 'example' ######################################################################## num_years = 3 # plot last three years data_label = 'time_series' sweep_label = 'zoo_mort_rate' # pick second cluster (i.e. index 1) cluster = 1 kwargs = {'data_label': data_label, 'cluster_kw': {'num_clusters': num_clusters, 'cluster': cluster}} params = helpers.load(params_name, 'params', 'sweep', **kwargs) num_years_simulation = params.get('num_years') num_phy = params['bio']['num_phy'] # get vals sweep = params['sweep']['pp'] data_kw = {'in_labels': ('zoo_mort_rate',)} kwargs.update(**{'pd_kw': data_kw}) data_2d = helpers.load(params_name, 'data', 'sweep', **kwargs) output = np.squeeze(data_2d['output'][0]) # output stored as a list of lists, so extract values color_kw = {'cmap': 'tab20b'}
plt.switch_backend('Qt5Agg') ######################################################################## params_name = 'example' ####################################################################### num_years_ts = 3 # Number of years to display in time series # Set up plotter class plotter = SinglePlotter(params_name=params_name) num_years_simulation = plotter.num_years # 50 years total in simulation data = helpers.load(params_name, 'data', 'single') params = helpers.load(params_name, 'params', 'single') sns.set_context('paper') sns.set_style('white') ################################################################################################ # TIME SERIES # PHYTO phy_indiv_alpha = 0.8 phy_total_alpha = 0.8 phy_total_lw = 1.0
def run(params_name: str = None, params: Dict = None, method: str = 'odeint', ts_label: str = 'time_series', details_str: str = None, return_eco: bool = False, save_eco: bool = True, data_ext: str = c.DATA_EXT_DEFAULT, functions: List[Tuple[str, Callable, Dict]] = None, debug: bool = False, odeint_kw: Dict = None) -> Optional[Union[np.ndarray, tuple]]: """Execute a single run of the model for the parameter set specified Parameters ---------- params_name Identifier for param set to run. Used to load params if `params` is None. data_ext When we run, in what format should we save the data? params Dict of parameters. details_str Extra bits for filename ts_label Time series label. By default "time_series" functions The functions we'd like to apply to our output after each run method What method to use? Either 'odeint' or 'ode' for now debug Are we debugging? save_eco Are we saving ecosystem (and time vector?) return_eco Are we returning ecosystem? odeint_kw Arguments to ODEINT integrator """ ######################################################################## # load params if params is None: params = helpers.load(params_name, 'params', 'single', details_str=details_str) ######################################################################## # INITIAL CONDITIONS / PREPARATION # Set up initial condition vector eco_0 = helpers.initial_conditions(params) ######################################################################## # DEBUGGING bio = params.get('bio') if debug: params['bio']['debug_dict'] = helpers.debug_dict_setup(bio) ######################################################################## # SOLVE # pop values we won't use popped_vals = helpers.additional_bio_setup(params, pop_values=True) dd = None (eco, t_save) = model_int.integrate(eco_0, params, method=method, odeint_kw=odeint_kw) # put keys back for key in popped_vals: if popped_vals[key] is not None: if key.endswith('_TEMP'): actual_name = '_'.join(key.split('_')[:-1]) params['bio'][actual_name] = copy.deepcopy(popped_vals[key]) else: params['bio'][key] = popped_vals[key] if debug: dd = params.get('bio').get('debug_dict') # convert lists to numpy arrays for key in dd: dd[key] = np.transpose(dd[key]) # save helpers.save(params_name, 'debug', 'single', output=dd) if np.isnan(eco).any(): print('NaN values encountered!') print( 'Problem integrating! System likely too stiff. Check your bio parameters.' ) else: if functions is not None: fn_count = 0 for output in functions: output_name = output[0] output_fn = output[1] output_kw = output[2] if np.isnan(eco).any(): if fn_count == 0: print('NaN values encountered!') print( 'Problem integrating! System likely too stiff for sweep params below:' ) # store as nans with same dimensions as output should be fake_output = helpers.build_mock_eco_output(t_save, params) out = np.full( np.shape( output_fn(fake_output, t_save, params, output_kw)), c.NAN_VALUE).tolist() else: out = output_fn(eco, t_save, params, output_kw) helpers.save(params_name, 'data', 'single', output=out, data_ext=data_ext, data_label=output_name, functions=functions, details_str=details_str) fn_count += 1 # save time series and time as well if save_eco: helpers.save(params_name, 'data', 'single', data_label=ts_label, output=eco, data_ext=data_ext, details_str=details_str) helpers.save(params_name, 'data', 'single', data_label='time', output=t_save, data_ext=data_ext, details_str=details_str) if return_eco: if debug: return eco, dd return eco