Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
########################################################################

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')
Ejemplo n.º 4
0
########################################################################

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
Ejemplo n.º 5
0
########################################################################

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'}

################################################################################################
Ejemplo n.º 6
0
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
Ejemplo n.º 8
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