Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding testing and validation #188

Merged
merged 8 commits into from
Apr 21, 2020
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Note that the user-supplied configuration file is used to provide

### Usage examples:
- Using the default emodl template: `python runScenarios.py
--running_location Local --region IL --experiment_config sample_experiment.yaml`
--running_location Local --region IL --experiment_config ./experiment_configs/sample_experiment.yaml`
- Using a different emodl template: `python runScenarios.py
--running_location Local --region IL --experiment_config sample_experiment.yaml --emodl_template simplemodel_testing.emodl`
- Specifying experiment name suffix and changing running_location : `python runScenarios.py
Expand Down
1 change: 1 addition & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pytest>=5
8 changes: 4 additions & 4 deletions extendedcobey.yaml → experiment_configs/extendedcobey.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,16 @@ sampled_parameters:
function_kwargs: {'low':0.95, 'high':1}
'socialDistance_time1':
custom_function: DateToTimestep
function_kwargs: {'dates': 2020-03-12}
function_kwargs: {'dates': 2020-03-12, 'startdate_col': 'startdate'}
'socialDistance_time2':
custom_function: DateToTimestep
function_kwargs: {'dates': 2020-03-17}
function_kwargs: {'dates': 2020-03-17, 'startdate_col': 'startdate'}
'socialDistance_time3':
custom_function: DateToTimestep
function_kwargs: {'dates': 2020-03-21}
function_kwargs: {'dates': 2020-03-21, 'startdate_col': 'startdate'}
'socialDistanceSTOP_time':
custom_function: DateToTimestep
function_kwargs: {'dates': 2020-04-24}
function_kwargs: {'dates': 2020-04-24, 'startdate_col': 'startdate'}
fitted_parameters:
# Note IL, NMH, Chicago and EMS_3 were fitted, the other EMS area Kis need updating/checking
Kis:
Expand Down
File renamed without changes.
15 changes: 11 additions & 4 deletions runScenarios.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
log = logging.getLogger(__name__)

mpl.rcParams['pdf.fonttype'] = 42

today = datetime.today()
DEFAULT_CONFIG = './extendedcobey.yaml'

Expand All @@ -34,8 +35,9 @@ def _parse_config_parameter(df, parameter, parameter_function):
function_name = parameter_function['custom_function']
function_kwargs = parameter_function['function_kwargs']
if function_name == 'DateToTimestep':
function_kwargs['startdate'] = first_day
return [DateToTimestep(**function_kwargs) for i in range(len(df))]
startdate_col = function_kwargs['startdate_col']
return [DateToTimestep(function_kwargs['dates'], df[startdate_col][i])
for i in range(len(df))]
elif function_name == 'subtract':
return df[function_kwargs['x1']] - df[function_kwargs['x2']]
else:
Expand Down Expand Up @@ -76,7 +78,7 @@ def add_config_parameter_column(df, parameter, parameter_function, age_bins=None
df: pd.DataFrame
dataframe with the additional column(s) added
"""
if parameter_function.get('expand_by_age'):
if isinstance(parameter_function, dict) and parameter_function.get('expand_by_age'):
if not age_bins:
raise ValueError("Ages bins must be specified if using an age expansion")
if 'list' in parameter_function:
Expand All @@ -97,7 +99,7 @@ def add_config_parameter_column(df, parameter, parameter_function, age_bins=None
else:
raise ValueError(f"Unknown type of parameter {parameter} for expand_by_age")
else:
if 'matrix' in parameter_function:
if isinstance(parameter_function, dict) and 'matrix' in parameter_function:
m = parameter_function['matrix']
for i, row in enumerate(m):
for j, item in enumerate(row):
Expand Down Expand Up @@ -138,6 +140,7 @@ def generateParameterSamples(samples, pop, first_day, config, age_bins):
df['sample_num'] = range(samples)
df['speciesS'] = pop
df['initialAs'] = config['experiment_setup_parameters']['initialAs']
df['startdate'] = experiment_config['fixed_parameters_region_specific']['startdate'][region]

for parameter, parameter_function in config['sampled_parameters'].items():
df = add_config_parameter_column(df, parameter, parameter_function, age_bins)
Expand Down Expand Up @@ -176,6 +179,10 @@ def replaceParameters(df, Ki_i, sample_nr, emodl_template, scen_num):
raise ValueError("Not all placeholders have been replaced in the template emodl file. "
f"Remaining placeholders: {remaining_placeholders}")
fin.close()
remaining_placeholders = re.findall(r'@\w+@', data)
if remaining_placeholders:
raise ValueError("Not all placeholders have been replaced in the template emodl file. "
f"Remaining placeholders: {remaining_placeholders}")
fin = open(os.path.join(temp_dir, f"simulation_{scen_num}.emodl"), "wt")
fin.write(data)
fin.close()
Expand Down
2 changes: 2 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
To run unit tests, run the following on the command line:
```python -m pytest tests```
69 changes: 69 additions & 0 deletions tests/test_runScenarios.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from datetime import datetime

import pandas as pd
import pytest

from runScenarios import add_config_parameter_column


@pytest.fixture
def original_df():
return pd.DataFrame({'sample_number': [1, 2, 3, 4, 5]})


def test_add_config_parameter_column__int(original_df):
new_df = add_config_parameter_column(original_df, "new_column", 10)
assert new_df.shape == (5, 2)
assert "new_column" in new_df.columns
assert set(new_df["new_column"]) == set([10])


def test_add_config_parameter_column__matrix(original_df):
f = {'matrix': [[9, 8], [7, 6]]}
new_df = add_config_parameter_column(original_df, "new_column", f)
assert new_df.shape == (5, 5)
assert all(new_cols in new_df.columns
for new_cols in ["new_column1_1", "new_column1_2", "new_column2_1", "new_column2_2"])
assert set(new_df["new_column1_1"]) == set([9])
assert set(new_df["new_column1_2"]) == set([8])
assert set(new_df["new_column2_1"]) == set([7])
assert set(new_df["new_column2_2"]) == set([6])


def test_add_config_parameter_column__random_uniform(original_df):
f = {'np.random': 'uniform', 'function_kwargs': {'low': 5, 'high': 6}}
new_df = add_config_parameter_column(original_df, "new_column", f)
assert new_df.shape == (5, 2)
assert "new_column" in new_df.columns
assert all((new_df["new_column"] >= 5) & (new_df["new_column"] <= 6))


def test_add_config_parameter_column__datetotimestep():
df = pd.DataFrame({'sample_number': [1, 2, 3, 4, 5],
'startdate': [datetime(2020, 2, 20)]*5})
f = {'custom_function': 'DateToTimestep',
'function_kwargs': {'dates': datetime(2020, 3, 1), 'startdate_col': 'startdate'}}
new_df = add_config_parameter_column(df, "new_column", f)
assert new_df.shape == (5, 3)
assert "new_column" in new_df.columns
print(new_df)
assert set(new_df["new_column"]) == set([10])


def test_add_config_parameter_column__subtract():
df = pd.DataFrame({'sample_number': [1, 2, 3, 4, 5],
'col1': [2, 4, 6, 8, 10],
'col2': [1, 3, 5, 7, 9]})
f = {'custom_function': 'subtract',
'function_kwargs': {'x1': 'col1', 'x2': 'col2'}}
new_df = add_config_parameter_column(df, "new_column", f)
assert new_df.shape == (5, 4)
assert "new_column" in new_df.columns
assert set(new_df["new_column"]) == set([1])


def test_add_config_parameter_column__error():
f = {'weird_function': {}}
with pytest.raises(ValueError) as e:
add_config_parameter_column(pd.DataFrame, "new_column", f)
assert "Unknown type of parameter" in str(e.value)