diff --git a/.circleci/config.yml b/.circleci/config.yml index 263f8b48..8d16cb4f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -35,6 +35,12 @@ jobs: - run: command: python testing/tests/run1psub0.py name: Run Starts at 1 for PSUB 0 + - run: + command: python testing/tests/append_mod_test.py + name: Auto Append Model ID + - run: + command: python testing/tests/cadCAD_exp.py + name: Package Root Experiment and configs object # - run: # command: python -m unittest discover -s testing/tests -p "*_test.py" # name: Test Suite diff --git a/CHANGELOG.md b/CHANGELOG.md index 5500ea72..2ad665dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,22 +1,50 @@ # Changelog: +### September 28, 2021 +#### New Features: +* **ver. ≥ `0.4.28`:** + * ##### [Experiments](documentation#experiments) + * ##### System Model Configuration + * Configurations (`cadCAD.utils.Configuration`'s) are now accessed via the `configs` member of `cadCAD.configuration.Experiment`. + [Example:](documentation#experiments) `cadCAD.configuration.Experiment().configs` + * `cadCAD.configs` has been re-included for backwards compatibility and has been assigned `cadCAD.experiment.configs` + * ##### Experiments + * `cadCAD.configuration.Experiment()` is unique representation of an experiment of one or more configured System + Models. + * The `cadCAD` module now contains a default Experiment object `cadCAD.experiment` as an instantiation of + `cadCAD.configuration.Experiment()` + * An `Experiment`'s `append_model` method stores multiple system model `Configuration`'s for simulation + execution within `cadCAD.configuration.Experiment().configs`. + `cadCAD.configuration.Experiment().model_ids` contains system model labels and/or indexes for + `cadCAD.configuration.Experiment().configs` + * The `Experiment`'s `append_model` method is defined with `model_id` parameter that accepts a system model + label. + * If duplicate `model_id`'s are specified, an index is appended to the label after the `@` symbol. + (Example: `cadCAD.configuration.Experiment().model_ids = ['sys_model', 'sys_model@1', 'sys_model@2', ...]`) + * If `model_id`'s are not specified or duplicate, the label is auto-generated as a string indicating the + system model index within `cadCAD.configuration.Experiment().configs`. + (Example of unspecified system models at indexes 1, 3, and 4: + `cadCAD.configuration.Experiment().model_ids = ['sys_model', '1', 'sys_model@2', '3', '4', ...]`) + * ##### [Upgrade Guide:](https://github.com/cadCAD-org/cadCAD/blob/master/documentation/cadCAD-v0.4.28-Model-Upgrade-Guide.md) specific to feature changes / additions + ### August 25, 2021 #### New Features: * **ver. ≥ `0.4.27`:** * ##### [Experiments](documentation#experiments) - * ##### [System Model Configurations] + * ##### System Model Configurations * Configurations (`cadCAD.utils.Configuration`'s) as are no longer a part of the `cadCAD` module (as `cadCAD.configs`) and are now accessed via the `configs` member of `cadCAD.configuration.Experiment`. [Example:](documentation#experiments) `cadCAD.configuration.Experiment().configs` - * `cadCAD.configuration.Experiment` is unique representation of an experiment of one or more configured System - Models. An `Experiment`'s `append_model` method stores multiple system model `Configuration`'s for simulation - execution. - * The `Experiment`'s `append_model` method requires a `model_id` parameter that is auto-created as `'sys_model_#'`. - * **Requirements:** - * Users must use different `model_id`'s when appending multiple System Model Configurations. - * Users can no longer use the `config_list` method of `cadCAD.configuration.Experiment` - * **Backwards Compatibility:** The `append_model` method of `cadCAD.configuration.Experiment` can also be used as - the `append_configs` method. + * ##### Experiments + * `cadCAD.configuration.Experiment` is unique representation of an experiment of one or more configured System + Models. An `Experiment`'s `append_model` method stores multiple system model `Configuration`'s for simulation + execution. + * The `Experiment`'s `append_model` method requires a `model_id` parameter that is auto-created as `'sys_model_#'`. + * **Requirements:** + * Users must use different `model_id`'s when appending multiple System Model Configurations. + * Users can no longer use the `config_list` method of `cadCAD.configuration.Experiment` + * **Backwards Compatibility:** The `append_model` method of `cadCAD.configuration.Experiment` can also be used as + the `append_configs` method. * Removed [Nix](https://nixos.org/) * ##### [Upgrade Guide:](https://github.com/cadCAD-org/cadCAD/blob/master/documentation/cadCAD-v0.4.27-Model-Upgrade-Guide.md) specific to feature changes / additions * **Fixes:** diff --git a/README.md b/README.md index bb77351c..122565cb 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ / ___/ __` / __ / / / /| | / / / / / /__/ /_/ / /_/ / /___/ ___ |/ /_/ / \___/\__,_/\__,_/\____/_/ |_/_____/ -by cadCAD ver. 0.4.27 +by cadCAD ver. 0.4.28 ====================================== Complex Adaptive Dynamics o i e @@ -20,7 +20,7 @@ through simulation, with support for Monte Carlo methods, A/B testing and parame # Getting Started -#### Change Log: [ver. 0.4.27](CHANGELOG.md) +#### Change Log: [ver. 0.4.28](CHANGELOG.md) [Previous Stable Release (No Longer Supported)](https://github.com/cadCAD-org/cadCAD/tree/b9cc6b2e4af15d6361d60d6ec059246ab8fbf6da) @@ -47,7 +47,7 @@ $ ## 1. Installation: Requires [>= Python 3.6.13](https://www.python.org/downloads/) -**Option A: Install Using **[pip](https://pypi.org/project/cadCAD/0.4.27/)** +**Option A: Install Using **[pip](https://pypi.org/project/cadCAD/0.4.28/)** ```bash pip3 install cadCAD ``` diff --git a/cadCAD/__init__.py b/cadCAD/__init__.py index 9cb5946c..fbfbaf52 100644 --- a/cadCAD/__init__.py +++ b/cadCAD/__init__.py @@ -1,7 +1,10 @@ import os, dill +from cadCAD.configuration import Experiment name = "cadCAD" -version = "0.4.27" +version = "0.4.28" +experiment = Experiment() +configs = experiment.configs if os.name == 'nt': dill.settings['recurse'] = True diff --git a/cadCAD/configuration/__init__.py b/cadCAD/configuration/__init__.py index 08c0ac7c..b7e191f8 100644 --- a/cadCAD/configuration/__init__.py +++ b/cadCAD/configuration/__init__.py @@ -59,11 +59,10 @@ def __init__(self): self.exp_window = deque([self.exp_id, None], 2) self.subset_window = deque([self.subset_id, None], 2) - def append_model( self, user_id='cadCAD_user', - model_id='sys_model_#', + model_id=None, sim_configs={}, initial_state={}, seeds={}, raw_exogenous_states={}, env_processes={}, partial_state_update_blocks={}, policy_ops=[lambda a, b: a + b], _exo_update_per_ts: bool = True, **kwargs # config_list=deepcopy(global_configs) @@ -106,6 +105,18 @@ def append_model( sim_cnt_local += 1 + if model_id == None: + new_model_id = str(len(self.model_ids)) + if new_model_id in self.model_ids: + model_id = f"model@{len(self.model_ids)}" + else: + model_id = str(new_model_id) + elif model_id != None: + if model_id in self.model_ids: + model_id = f"{model_id}@{len(self.model_ids)}" + else: + model_id = str(model_id) + run_id = 0 new_model_ids, new_configs = [], [] for sim_config in new_sim_configs: @@ -161,8 +172,8 @@ def append_model( self.model_ids.append(model_id) else: except_str = f""" - Error: Duplicate model_id in Experiment - \'{model_id}\' in {self.model_ids} - -- Specify unique model_id for each use of `.append_config` per `Experiment()` + Error: Duplicate model_id in Experiment - \'{model_id}\' in {self.model_ids} + -- Specify unique model_id for each use of `.append_model` per `Experiment()` """ raise Exception(except_str) @@ -264,4 +275,4 @@ def only_ep_handler(state_dict): sdf_values, bdf_values = only_ep_handler(initial_state) zipped_list = list(zip(sdf_values, bdf_values)) - return list(map(lambda x: (x[0] + exo_proc, x[1]), zipped_list)) + return list(map(lambda x: (x[0] + exo_proc, x[1]), zipped_list)) \ No newline at end of file diff --git a/dist/cadCAD-0.4.27.tar.gz b/dist/cadCAD-0.4.27.tar.gz deleted file mode 100644 index e8d329fc..00000000 Binary files a/dist/cadCAD-0.4.27.tar.gz and /dev/null differ diff --git a/dist/cadCAD-0.4.27-py3-none-any.whl b/dist/cadCAD-0.4.28-py3-none-any.whl similarity index 67% rename from dist/cadCAD-0.4.27-py3-none-any.whl rename to dist/cadCAD-0.4.28-py3-none-any.whl index 5fd34b59..db314a31 100644 Binary files a/dist/cadCAD-0.4.27-py3-none-any.whl and b/dist/cadCAD-0.4.28-py3-none-any.whl differ diff --git a/dist/cadCAD-0.4.28.tar.gz b/dist/cadCAD-0.4.28.tar.gz new file mode 100644 index 00000000..84524405 Binary files /dev/null and b/dist/cadCAD-0.4.28.tar.gz differ diff --git a/documentation/README.md b/documentation/README.md index 616fb437..1c8ca8c4 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -12,7 +12,7 @@ cadCAD according to the definitions set by the user in [Partial State Update Blo A Simulation Configuration is comprised of a [System Model](#System-Model) and a set of [Simulation Properties](#Simulation-Properties). ### Experiments -`cadCAD.configuration.Experiment` is a unique representation of an experiment of one or more configured System Models. +`cadCAD.configuration.Experiment` is a unique representation of an experiment of one or more configured System Models. The `append_model` method of `Experiment` appends a System Model configurations, each representing a single `run`. ```python @@ -20,7 +20,7 @@ from cadCAD.configuration import Experiment exp = Experiment() exp.append_model( - model_id = ..., # System Model + model_id = ..., # OPTIONAL: System Model label initial_state = ..., # System Model partial_state_update_blocks = ..., # System Model policy_ops = ..., # System Model @@ -29,7 +29,7 @@ exp.append_model( ) ``` Parameters: `append_model` -* **model_id** : str - System Model Identification +* **model_id** : str - OPTIONAL: System Model label * **initial_state** : _dict_ - [State Variables](#State-Variables) and their initial values * **partial_state_update_blocks** : List[dict[dict]] - List of [Partial State Update Blocks](#Partial-State-Update-Blocks) * **policy_ops** : List[functions] - See [Policy Aggregation](Policy_Aggregation.md) diff --git a/documentation/cadCAD-v0.4.28-Model-Upgrade-Guide.md b/documentation/cadCAD-v0.4.28-Model-Upgrade-Guide.md new file mode 100644 index 00000000..ded5adf5 --- /dev/null +++ b/documentation/cadCAD-v0.4.28-Model-Upgrade-Guide.md @@ -0,0 +1,88 @@ +
+ Feature + | ++ ver. 0.4.28 + | ++ ver. 0.4.23 + | +
---|---|---|
+ + Experiments & System Model Configurations ++ |
+
+
+from cadCAD.configuration import Experiment
+
+exp = Experiment()
+exp.append_model(
+ model_id = 'sys_model_1', # System Model - OPTIONAL
+ initial_state = ..., # System Model
+ partial_state_update_blocks = ..., # System Model
+ policy_ops = ..., # System Model
+ sim_configs = ..., # Simulation Properties
+)
+exp.append_model(...)
+
+configs = exp.configs
+
+ |
+
+
+from cadCAD import configs
+from cadCAD.configuration import Experiment
+exp = Experiment()
+exp.append_configs(...)
+
+ |
+
+ + cadCAD Post-Processing Modifications ++ |
+
+
+import pandas as pd
+from tabulate import tabulate
+from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
+from simulations.regression_tests.experiments import multi_exp
+from simulations.regression_tests.models import config_multi_1, config_multi_2
+
+exec_mode = ExecutionMode()
+
+local_proc_ctx = ExecutionContext(context=exec_mode.local_mode)
+run = Executor(exec_context=local_proc_ctx, configs=multi_exp.configs)
+
+raw_result, tensor_fields, _ = run.execute()
+result = pd.DataFrame(raw_result)
+print(tabulate(tensor_fields[0], headers='keys', tablefmt='psql'))
+print(tabulate(result, headers='keys', tablefmt='psql'))
+
+ |
+
+
+import pandas as pd
+from tabulate import tabulate
+from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
+import system_model_A, system_model_B
+
+from cadCAD import configs
+exec_mode = ExecutionMode()
+
+local_ctx = ExecutionContext(context=exec_mode.local_mode)
+simulation = Executor(exec_context=local_ctx, configs=configs)
+raw_result, sys_model, _ = simulation.execute()
+result = pd.DataFrame(raw_result)
+print(tabulate(result, headers='keys', tablefmt='psql'))
+
+ |
+