Skip to content

Commit

Permalink
Merge pull request #300 from cadCAD-org/staging
Browse files Browse the repository at this point in the history
ver. 0.4.28
  • Loading branch information
JEJodesty authored Sep 28, 2021
2 parents a5dc002 + fdc0ad9 commit 4b69169
Show file tree
Hide file tree
Showing 15 changed files with 271 additions and 23 deletions.
6 changes: 6 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
48 changes: 38 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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:**
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/ ___/ __` / __ / / / /| | / / / /
/ /__/ /_/ / /_/ / /___/ ___ |/ /_/ /
\___/\__,_/\__,_/\____/_/ |_/_____/
by cadCAD ver. 0.4.27
by cadCAD ver. 0.4.28
======================================
Complex Adaptive Dynamics
o i e
Expand All @@ -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)

Expand All @@ -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
```
Expand Down
5 changes: 4 additions & 1 deletion cadCAD/__init__.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
21 changes: 16 additions & 5 deletions cadCAD/configuration/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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))
Binary file removed dist/cadCAD-0.4.27.tar.gz
Binary file not shown.
Binary file not shown.
Binary file added dist/cadCAD-0.4.28.tar.gz
Binary file not shown.
6 changes: 3 additions & 3 deletions documentation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ 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
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
Expand All @@ -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)
Expand Down
88 changes: 88 additions & 0 deletions documentation/cadCAD-v0.4.28-Model-Upgrade-Guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<table>
<tr>
<th>
Feature
</th>
<th>
ver. 0.4.28
</th>
<th>
ver. 0.4.23
</th>
</tr>
<tr>
<td>
<h5>
Experiments & System Model Configurations
</h5>
</td>
<td>
<pre lang="python">
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
</pre>
</td>
<td>
<pre lang="python">
from cadCAD import configs
from cadCAD.configuration import Experiment
exp = Experiment()
exp.append_configs(...)
</pre>
</td>
</tr>
<tr>
<td>
<h5>
cadCAD Post-Processing Modifications
</h5>
</td>
<td>
<pre lang="python">
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'))
</pre>
</td>
<td>
<pre lang="python">
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'))
</pre>
</td>
</tr>
</table>
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"""

name = "cadCAD"
version = "0.4.27"
version = "0.4.28"

setup(name=name,
version=version,
Expand Down
3 changes: 3 additions & 0 deletions testing/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from cadCAD.configuration import Experiment

exp = Experiment()
7 changes: 7 additions & 0 deletions testing/models/param_sweep.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pprint
from typing import Dict, List

from cadCAD import experiment
from cadCAD.configuration import Experiment
from cadCAD.configuration.utils import env_trigger, var_substep_trigger, config_sim, psub_list

Expand Down Expand Up @@ -93,3 +94,9 @@ def sweeped(_g, step, sL, s, _input, **kwargs):
env_processes=env_process,
partial_state_update_blocks=partial_state_update_blocks
)
experiment.append_model(
sim_configs=sim_config,
initial_state=genesis_states,
env_processes=env_process,
partial_state_update_blocks=partial_state_update_blocks
)
78 changes: 78 additions & 0 deletions testing/tests/append_mod_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import unittest
from copy import deepcopy

from testing.models import exp
from testing.models.param_sweep import sim_config as sim_config_a
from testing.models.param_sweep import genesis_states as genesis_states_a
from testing.models.param_sweep import env_process as env_process_a
from testing.models.param_sweep import partial_state_update_blocks as psubs_a


def append_model_id(model_ids, sim_config, genesis_states, env_process, psubs):
exp_copy = deepcopy(exp)
for mod_id in model_ids:
exp_copy.append_model(
model_id=mod_id,
sim_configs=sim_config,
initial_state=genesis_states,
env_processes=env_process,
partial_state_update_blocks=psubs,
policy_ops=[lambda a, b: a + b]
)
return exp_copy


class AppendModelTest(unittest.TestCase):
def test_index_model_ids(self):
no_id_exp = append_model_id(
model_ids=[None] * 10,
sim_config=sim_config_a,
genesis_states=genesis_states_a,
env_process=env_process_a,
psubs=psubs_a
)
expected = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
self.assertEqual(no_id_exp.model_ids == expected, True, "Incorrect Indexing of System Model IDs")

def test_same_model_ids(self):
same_id_exp = append_model_id(
model_ids=['sys_model'] * 10,
sim_config=sim_config_a,
genesis_states=genesis_states_a,
env_process=env_process_a,
psubs=psubs_a
)
expected = [
'sys_model', 'sys_model@1', 'sys_model@2', 'sys_model@3', 'sys_model@4', 'sys_model@5',
'sys_model@6', 'sys_model@7', 'sys_model@8', 'sys_model@9'
]
self.assertEqual(same_id_exp.model_ids == expected, True, "Incorrect Duplicate Indexing of System Model IDs")

def test_different_model_ids(self):
diff_id_exp = append_model_id(
model_ids=[f'sys_model_{i}' for i in list(range(10))],
sim_config=sim_config_a,
genesis_states=genesis_states_a,
env_process=env_process_a,
psubs=psubs_a
)
expected = [
'sys_model_0', 'sys_model_1', 'sys_model_2', 'sys_model_3', 'sys_model_4', 'sys_model_5',
'sys_model_6', 'sys_model_7', 'sys_model_8', 'sys_model_9'
]
self.assertEqual(diff_id_exp.model_ids == expected, True, "Incorrect Unique System Model IDs")

def test_mix_model_ids(self):
mix_exp = append_model_id(
model_ids=[None, 'sys_model_A', None, 'sys_model_B', 'model@3', 'model@3'],
sim_config=sim_config_a,
genesis_states=genesis_states_a,
env_process=env_process_a,
psubs=psubs_a
)
expected = ['0', 'sys_model_A', '2', 'sys_model_B', 'model@3', 'model@3@5']
self.assertEqual(mix_exp.model_ids == expected, True, "Incorrect System Model ID Mix")


if __name__ == '__main__':
unittest.main()
Loading

0 comments on commit 4b69169

Please sign in to comment.