Wrapper Utility Tools#

Utility tools for to ease model wrapping.

Overview Information Here: boa.wrappers

boa.wrappers.wrapper_utils.cd_and_cd_back(path: PathLike = None)[source]#

Context manager that will return to the starting directory when the context manager exits, regardless of what directory changes happen between start and end.

Parameters:

path (PathLike) – If supplied, will change directory to this path at the start of the context manager (it will “cd” to this path before “cd” back to the original directory)

Examples

>>> starting_dir = os.getcwd()
... with cd_and_cd_back():
...     # with do some things that change the directory
...     os.chdir("..")
... # When we exit the context manager (dedent) we go back to the starting directory
... ending_dir = os.getcwd()
... assert starting_dir == ending_dir
>>> starting_dir = os.getcwd()
... path_to_change_to = ".."
... with cd_and_cd_back(path=path_to_change_to):
...     # with do some things inside the context manager
...     ...
... # When we exit the context manager (dedent) we go back to the starting directory
... ending_dir = os.getcwd()
... assert starting_dir == ending_dir
boa.wrappers.wrapper_utils.cd_and_cd_back_dec(path: Optional[PathLike] = None)[source]#

Same as cd_and_cd_back() except as a function decorator instead of a context manager.

Parameters:

path (Optional[PathLike]) – If supplied, will change directory to this path at the start of the function run (it will “cd” to this path before “cd” back to the original directory)

Examples

>>> @cd_and_cd_back_dec
... def foo():
...     os.chdir("..")
...
... starting_dir = os.getcwd()
... foo()
... ending_dir = os.getcwd()
... assert starting_dir == ending_dir
>>> @cd_and_cd_back_dec(path="..")
... def bar():
...     os.chdir("..")
...
... starting_dir = os.getcwd()
... bar()
... ending_dir = os.getcwd()
... assert starting_dir == ending_dir
boa.wrappers.wrapper_utils.initialize_wrapper(wrapper: Type[BaseWrapper] | PathLike, append_timestamp: bool = None, experiment_dir: PathLike = None, wrapper_name: str = 'Wrapper', post_init_attrs: dict = None, **kwargs)[source]#
Parameters:
  • wrapper (Type[BaseWrapper] | PathLike) –

  • append_timestamp (bool) –

  • experiment_dir (PathLike) –

  • wrapper_name (str) –

  • post_init_attrs (dict) –

boa.wrappers.wrapper_utils.split_shell_command(cmd: str)[source]#

split shell command for passing to python subproccess. This should correctly split commands like “echo ‘Hello, World!’” to [‘echo’, ‘Hello, World!’] (2 items) and not [‘echo’, “‘Hello,”, “World!’”] (3 items)

It also works for posix and windows systems appropriately

Parameters:

cmd (str) –

boa.wrappers.wrapper_utils.load_json(file: PathLike, normalize: bool = True, *args, **kwargs) dict[source]#

Read experiment configuration file for setting up the optimization. The configuration file contains the list of parameters, and whether each parameter is a fixed parameter or a range parameter. Fixed parameters have a value specified, and range parameters have a range specified.

Parameters:
  • file (PathLike) – File path for the experiment configuration file

  • normalize (bool) – Whether to run normalize_config() after loading config to run certain predictable configuration normalization. (default true)

  • parameter_keys – Alternative keys or paths to keys to parse as parameters to optimize, for more information, see wpr_params_to_boa()

Return type:

dict

Examples

config_path = Path(“path/to/your/config.json_or_yaml”) config = load_jsonlike(config_path)

Returns:

  • loaded_configs (dict)

  • See Also

  • ——– jmn nmn

  • normalize_config() for information on parameter_keys option

Parameters:
  • file (PathLike) –

  • normalize (bool) –

Return type:

dict

boa.wrappers.wrapper_utils.load_yaml(file: PathLike, normalize: bool = True, *args, **kwargs) dict[source]#

Read experiment configuration file for setting up the optimization. The configuration file contains the list of parameters, and whether each parameter is a fixed parameter or a range parameter. Fixed parameters have a value specified, and range parameters have a range specified.

Parameters:
  • file (PathLike) – File path for the experiment configuration file

  • normalize (bool) – Whether to run normalize_config() after loading config to run certain predictable configuration normalization. (default true)

  • parameter_keys – Alternative keys or paths to keys to parse as parameters to optimize, for more information, see wpr_params_to_boa()

Return type:

dict

Examples

config_path = Path(“path/to/your/config.json_or_yaml”) config = load_jsonlike(config_path)

Returns:

  • loaded_configs (dict)

  • See Also

  • ——– jmn nmn

  • normalize_config() for information on parameter_keys option

Parameters:
  • file (PathLike) –

  • normalize (bool) –

Return type:

dict

boa.wrappers.wrapper_utils.load_jsonlike(file: PathLike, *args, **kwargs)[source]#

Read experiment configuration file for setting up the optimization. The configuration file contains the list of parameters, and whether each parameter is a fixed parameter or a range parameter. Fixed parameters have a value specified, and range parameters have a range specified.

Parameters:
  • file (PathLike) – File path for the experiment configuration file

  • normalize – Whether to run normalize_config() after loading config to run certain predictable configuration normalization. (default true)

  • parameter_keys – Alternative keys or paths to keys to parse as parameters to optimize, for more information, see wpr_params_to_boa()

Examples

config_path = Path(“path/to/your/config.json_or_yaml”) config = load_jsonlike(config_path)

Returns:

  • loaded_configs (dict)

  • See Also

  • ——– jmn nmn

  • normalize_config() for information on parameter_keys option

Parameters:

file (PathLike) –

boa.wrappers.wrapper_utils.normalize_config(config: dict, parameter_keys: Optional[Union[str, list[Union[str, list[str], list[Union[str, int]]]]]] = None) dict[source]#

Normalize config dictionary passed in.

Perform a series of minor convenience normalizations to your configuration dictionary. These include adding empty sections for certain optional sections you don’t include. Defaulting you experiment name to boa_runs if you don’t include it. And any pathing you include under the parameter_keys section, will get prepended with its path, and will get added to your parameters section.

Instead of putting all of your parameters under the parameters key, You can put them under different keys, and then pass a list of lists where each list is the json/yaml pathing to the additional parameters key section.

Useful for if you have multiple sections of parameters that you want to keep logically separated but you are still optimizing over them all, such as different plant species in a multi-species plant model.

Parameters:
  • config (dict) – your configuration dictionary (jsonlike)

  • parameter_keys (str | list[Union[str, list[str], list[Union[str, int]]]]) – This needs to be a json path to a key or keys where parameters or stored. So either a single string (the key) or a list of strings and ints (the keys and list indices), or a list of those lists for multiple paths.

Returns:

config – normalized configuration

Return type:

dict

Examples

optimization_options:
    parameter_keys: [
        ["params", "a"],
    ]

    # Alternatively, these keys can be expressed in more traditional YAML
    # syntax, but the above more traditional json like syntax might be easier
    # to understand. They both mean the same thing, a list of lists
    #    -
    #        - "params"
    #        - "a"

params:
    a:
        x1:
            type: range
            bounds: [0, 1]
        x2:
            type: fixed
            value: 0.5

# This would get normalized to

parameters:
    params_a_x2:
        type: range
        bounds: [0, 1]
    params_a_x1:
        type: fixed
        value: 0.5
# A more complicated working example
>>> from boa import normalize_config
>>> from pprint import pprint
>>> config = {
...     "params": {
...         "a": {"x1": {"bounds": [0, 1], "type": "range"}, "x2": {"type": "fixed", "value": 0.5}},
...         "b": {"x1": {"bounds": [0, 1], "type": "range"}, "x2": {"type": "fixed", "value": 0.5}},
...     },
...     "params2": [
...         {0: {"x1": {"bounds": [0, 1], "type": "range"}, "x2": {"type": "fixed", "value": 0.5}}},
...         {0: {"x1": {"bounds": [0, 1], "type": "range"}, "x2": {"type": "fixed", "value": 0.5}}},
...     ],
...     "params_a": {"x1": {"bounds": [0, 1], "type": "range"}, "x2": {"type": "fixed", "value": 0.5}},
... }
>>> parameter_keys = [
...     ["params", "a"],
...     ["params", "b"],
...     ["params_a"],
...     ["params2", 0, 0],
...     ["params2", 1, 0],
... ]
>>> config = normalize_config(config, parameter_keys)
>>> pprint(config["parameters"])
[{'bounds': [0, 1], 'name': 'params_a_x1', 'type': 'range'},
 {'name': 'params_a_x2', 'type': 'fixed', 'value': 0.5},
 {'bounds': [0, 1], 'name': 'params_b_x1', 'type': 'range'},
 {'name': 'params_b_x2', 'type': 'fixed', 'value': 0.5},
 {'bounds': [0, 1], 'name': 'params_a_x1_0', 'type': 'range'},
 {'name': 'params_a_x2_0', 'type': 'fixed', 'value': 0.5},
 {'bounds': [0, 1], 'name': 'params2_0_0_x1', 'type': 'range'},
 {'name': 'params2_0_0_x2', 'type': 'fixed', 'value': 0.5},
 {'bounds': [0, 1], 'name': 'params2_1_0_x1', 'type': 'range'},
 {'name': 'params2_1_0_x2', 'type': 'fixed', 'value': 0.5}]
boa.wrappers.wrapper_utils.wpr_params_to_boa(params: dict, parameter_keys: str | list[Union[str, list[str], list[Union[str, int]]]]) tuple[dict, dict][source]#
Parameters:
Return type:

tuple[dict, dict]

boa.wrappers.wrapper_utils.boa_params_to_wpr(params: list[dict], mapping, from_trial=True)[source]#
Parameters:

params (list[dict]) –

boa.wrappers.wrapper_utils.get_dt_now_as_str(fmt: str = '%Y%m%dT%H%M%S') str[source]#

get the datetime as now as a str.

fmtstr

Default format is file friendly. See strftime documentation for more information on choices.

Parameters:

fmt (str) –

Return type:

str

boa.wrappers.wrapper_utils.make_experiment_dir(output_dir: Optional[PathLike] = None, experiment_dir: Optional[PathLike] = None, experiment_name: str = '', append_timestamp: bool = True, exist_ok: bool = False, **kwargs)[source]#

Creates directory for the experiment and returns the path. The directory is named with the experiment name and the current datetime.

Parameters:
  • output_dir (Optional[PathLike]) – Output directory, the parent directory where the experiment directory will be written. Specify either an output directory and an experiment name or an experiment_dir

  • experiment_dir (Optional[PathLike]) – The exact dir the experiment directory boa will use to write the runs to. Specify either a output directory and an experiment name or an experiment_dir

  • experiment_name (str) – Name of the experiment

  • append_timestamp (bool) – Whether to append a timestamp to the end of the experiment directory to ensure uniqueness

  • exist_ok (bool) – Whether it is ok if the directory already exists or not (will throw an error if set to False and it already exists)

Returns:

Path to the directory for the experiment

Return type:

pathlib.Path

boa.wrappers.wrapper_utils.zfilled_trial_index(trial_index: int, fill_size: int = 6) str[source]#

Return trial index left passed with zeros of length fill_size

Parameters:
  • trial_index (int) –

  • fill_size (int) –

Return type:

str

boa.wrappers.wrapper_utils.get_trial_dir(experiment_dir: PathLike, trial_index: int, **kwargs)[source]#

Return a directory for a trial, Trial directory is named with the trial index (0 padded to 6 decimal)

Parameters:
  • experiment_dir (PathLike) – Directory for the experiment

  • trial_index (int) – Trial index from the Ax client

  • **kwargs – keyword args passed to zfilled_trial_index

Returns:

Directory for the trial

Return type:

pathlib.Path

boa.wrappers.wrapper_utils.make_trial_dir(experiment_dir: PathLike, trial_index: int, exist_ok=True, **kwargs)[source]#

Create a directory for a trial, and return the path to the directory. Trial directory is created inside the experiment directory, and named with the trial index (0 padded to 6 decimal). Model configs and outputs for each trial will be written here.

Parameters:
  • experiment_dir (PathLike) – Directory for the experiment

  • trial_index (int) – Trial index from the Ax client

  • exist_ok – Whether it is ok if the directory already exists. Errors if set to False and the directory already exists. Sometimes the directory already exists if reusing experiment directory of continueing stopped experiments that were interrupted and have to restart trials

  • **kwargs – keyword args passed to get_trial_dir

Returns:

Directory for the trial

Return type:

pathlib.Path

boa.wrappers.wrapper_utils.save_trial_data(trial: BaseTrial, trial_dir: Optional[Path] = None, experiment_dir: Optional[PathLike] = None, **kwargs)[source]#

Save trial data (trial.json, parameters.json and data.json) to either: supplied trial_dir or supplied experiment_dir / trial.index

Parameters: