Skip to content

Commit

Permalink
Merge branch 'main' into geo_messaging
Browse files Browse the repository at this point in the history
  • Loading branch information
TJohnsonAZ authored Feb 19, 2024
2 parents e612775 + 8afbe52 commit 5815ea9
Show file tree
Hide file tree
Showing 12 changed files with 1,213 additions and 9 deletions.
10 changes: 7 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
},
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true,


"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
},
"editor.defaultFormatter": null,
"editor.formatOnSave": true,
"notebook.formatOnSave.enabled": true,
"notebook.codeActionsOnSave": {
"source.organizeImports": "explicit"
},

"autopep8.importStrategy": "fromEnvironment",
"isort.importStrategy": "fromEnvironment",
Expand All @@ -36,6 +39,7 @@
"*_test.py"
],

"editor.defaultFormatter": null,
"[python]": {
"editor.detectIndentation": false,
"editor.insertSpaces": true,
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ python3.11 -m venv .venv
# activate it (after which `python` should be bound to the venv python)
source .venv/bin/activate

# then install the project in "editable" mode
python -m pip install --editable .[dev]
# then install the project in editable mode
python -m pip install --editable ".[dev]"
```

(The quotes in the last command are necessary on some platforms, but if the quotes give you issues you can also try without them.)

## Running from the command line

The most basic task epymorph can perform is to run a spatial, compartmental disease simulation and output the time-series data of compartment populations (prevalence) as well as new events (incidence).
Expand Down
304 changes: 304 additions & 0 deletions doc/devlog/2023-11-08-age-ipm.ipynb

Large diffs are not rendered by default.

432 changes: 432 additions & 0 deletions doc/devlog/2024-02-06.ipynb

Large diffs are not rendered by default.

418 changes: 418 additions & 0 deletions doc/devlog/2024-02-12.ipynb

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions doc/devlog/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,15 @@ This folder is a handy place to put Jupyter notebooks or other documents which h
| 2023-10-26.ipynb | Tyler | | Describes a major Geo system refactor and introduces new systems. |
| 2023-11-03-seirs-example.ipynb | Ajay | | Demonstrates the building and running of an SEIRS model. |
| 2023-11-08.ipynb | Ajay | | Demonstration of using proxy geo to access data in parameter functions. |
| 2023-11-08-age-ipm.ipynb | Jarom | | Initial prototyping of age-class IPMs. |
| 2023-11-15.ipynb | Ajay | | Detailed description of parameter functions functionality. |
| 2023-11-20-adrio-phase-2-demo.ipynb | Trevor | | Demonstrates the refactor work on DynamicGeos and the ADRIO system, and geo cache handling. |
| 2023-11-22-ipm-probs.ipynb | Tyler | | Analyzing statistical correctness of our IPM processing algorithms. |
| 2023-12-05.ipynb | Tyler | | A brief tour of changes to epymorph due to the refactor effort. |
| 2024-01-08.ipynb | Tyler | | Another functional parameters demonstration, revisiting the Bonus Example from 2023-10-10. |
| 2024-02-06-adrio-demo.ipynb | Trevor | | Demonstrates the ADRIO system using code updated for latest changes. |
| 2024-02-06.ipynb | Tyler | | Revisiting age-class IPMs, and thinking about modularity of approach. |
| 2024-02-12.ipynb | Tyler | | Continued age-class IPM work, this time in more than one geo node. |

## Contributing

Expand Down
21 changes: 21 additions & 0 deletions epymorph/data/mm/flat.movement
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# This model evenly weights the probability of movement to all other nodes.
# It uses parameter 'commuter_proportion' to determine how many people should
# be moving, based on the total normal population of each node.

[move-steps: per-day=2; duration=[1/3, 2/3]]

[predef: function=
def flat_predef():
ones = np.ones((dim.nodes, dim.nodes))
np.fill_diagonal(ones, 0)
dispersal_kernel = row_normalize(ones)
return { 'dispersal_kernel': dispersal_kernel }
]

# Assume a percentage of the population move around,
# evenly weighted to all other locations.
[mtype: days=all; leave=1; duration=0d; return=2; function=
def flat_movement(t):
n_commuters = np.floor(geo['population'] * params['commuter_proportion']).astype(SimDType)
return np.multinomial(n_commuters, predef['dispersal_kernel'])
]
2 changes: 1 addition & 1 deletion epymorph/engine/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def _create_attribute_getter(attr: AttributeDef) -> AttributeGetter:
data_raw = self._get_attribute_value(attr)
data = attr.shape.adapt(self.dim, data_raw, True)
if data is None:
msg = f"Attribute '{attr.name}' could not be adpated to the required shape."
msg = f"Attribute '{attr.name}' could not be adapted to the required shape."
raise AttributeException(msg)
return attr.shape.accessor(data)

Expand Down
6 changes: 3 additions & 3 deletions epymorph/initializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def _default_compartments(ctx: InitContext) -> NDArray[SimDType]:

def _check_population(ctx: InitContext) -> None:
try:
check_ndarray(ctx.geo['population'], dtype=np.integer, shape=(ctx.dim.nodes,))
check_ndarray(ctx.geo['population'], dtype=[np.int64], shape=(ctx.dim.nodes,))
except KeyError as e:
raise InitException.for_arg('population', 'No such value in the geo.') from e
except NumpyTypeError as e:
Expand All @@ -95,7 +95,7 @@ def explicit(ctx: InitContext, initials: NDArray[SimDType]) -> NDArray[SimDType]
return initials.copy()


def proportional(ctx: InitContext, ratios: NDArray[np.integer | np.floating]) -> NDArray[SimDType]:
def proportional(ctx: InitContext, ratios: NDArray[np.int64 | np.float64]) -> NDArray[SimDType]:
"""
Set all compartments as a proportion of their population according to the geo.
The parameter array provided to this initializer will be normalized, then multiplied
Expand All @@ -107,7 +107,7 @@ def proportional(ctx: InitContext, ratios: NDArray[np.integer | np.floating]) ->

_, N, C, _ = ctx.dim.TNCE
try:
check_ndarray(ratios, dtype=[np.integer, np.floating], shape=[(C,), (N, C)])
check_ndarray(ratios, dtype=[np.int64, np.float64], shape=[(C,), (N, C)])
except NumpyTypeError as e:
raise InitException.for_arg('ratios') from e

Expand Down
12 changes: 12 additions & 0 deletions epymorph/movement/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,18 @@ def visit_Subscript(self, node: ast.Subscript) -> Any:
return node
return self.generic_visit(node)

def visit_Attribute(self, node: ast.Attribute) -> Any:
"""Modify references to objects that should be in context."""
if isinstance(node.value, ast.Name):
if node.value.id in ['dim']:
node.value = ast.Attribute(
value=ast.Name(id='ctx', ctx=ast.Load()),
attr=node.value.id,
ctx=ast.Load(),
)
return node
return self.generic_visit(node)

def visit_FunctionDef(self, node: ast.FunctionDef) -> Any:
"""Modify function parameters."""
new_node = self.generic_visit(node)
Expand Down
1 change: 1 addition & 0 deletions epymorph/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ def epymorph_namespace() -> dict[str, Any]:
'concatenate': partial(np.concatenate, dtype=SimDType),
'sum': partial(np.sum, dtype=SimDType),
'newaxis': np.newaxis,
'fill_diagonal': np.fill_diagonal,
# numpy math functions
'radians': np.radians,
'degrees': np.degrees,
Expand Down
7 changes: 7 additions & 0 deletions epymorph/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ def call_all(*fs: Callable[[], Any]) -> None:
f()


def or_raise(value: T | None, message: str) -> T:
"""Enforce that the given value is not None, or else raise an exception."""
if value is None:
raise Exception(message)
return value


# collection utilities


Expand Down

0 comments on commit 5815ea9

Please sign in to comment.