Skip to content

Commit

Permalink
Merge branch 'waning-immunity' of github.com:SABS-R3-Epidemiology/epi…
Browse files Browse the repository at this point in the history
…abm into waning-immunity
  • Loading branch information
tomcodewizard committed Feb 14, 2024
2 parents 2381fad + 46c41bb commit 2252eaa
Show file tree
Hide file tree
Showing 32 changed files with 250 additions and 20 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ share/python-wheels/
.installed.cfg
*.egg
build/
_build/
build_dir/
MANIFEST

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ Note that cmake must be installed on your system. The following command can be u
sudo apt-get install cmake cmake-data
```

We recommend the use of the G++ compiler (version 9 or higher) with cEpiabm. If other compilers are used, users should ensure they include the filesystem library, or include this explicitly by inserting `link_libraries(stdc++fs)` in [CMakeLists.txt](cEpiabm/CMakeLists.txt).

### Compiling cEpiabm Python Bindings

Pybind11 is required for compiling cEpiabm with Python bindings. Pybind11 is added as a git submodule, make sure this submodule is cloned along with the main epiabm repository.
Expand Down
58 changes: 58 additions & 0 deletions cEpiabm/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
cEpiabm
=======

We provide an efficient and scalable backend in C++, which can run
simulations for populations comparable to the UK in a reasonable
timeframe. This code may be harder than pyEpiabm for new users to
understand, but the parallels with the python code should be
sufficiently informative for those who wish to look deeper into the
code.

Set up
------

Installation of cEpiabm
~~~~~~~~~~~~~~~~~~~~~~~

Cmake is used for installation of the cEpiabm software. The following
procedure will compile the code and run all unit tests:

.. code:: console
mkdir build_dir
cd build_dir
cmake ../cEpiabm/. -DCMAKE_BUILD_TYPE=Debug
cmake --build . --parallel 2 --target unit_tests
ctest -j2 --output-on-failure
Note that cmake must be installed on your system. The following command
can be used on ubuntu systems:

.. code:: console
sudo apt-get install cmake cmake-data
We recommend the use of the G++ compiler (version 9 or higher) with
cEpiabm. If other compilers are used, users should ensure they include
the filesystem library, or include this explicitly by inserting
``link_libraries(stdc++fs)`` in the ``cEpiabm/CMakeLists.txt`` file.

Compiling cEpiabm Python Bindings
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Pybind11 is required for compiling cEpiabm with Python bindings.
Pybind11 is added as a git submodule, make sure this submodule is cloned
along with the main epiabm repository.

Compiling Python bindings follows similar procedure to compiling the
cEpiabm tests:

.. code:: console
mkdir build_dir
cd build_dir
cmake ../cEpiabm/. -DCMAKE_BUILD_TYPE=Release -DENABLE_COVERAGE=OFF
cmake --build . --parallel 6 --target epiabm
cEpiabm’s python bindings will be compiled to a python module named
epiabm, located in ``build_dir/src/epiabm.cpython-(version info).so``.
20 changes: 20 additions & 0 deletions cEpiabm/docs/.readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# Required
version: 2

# Set the required OS and Python version
build:
os: ubuntu-22.04
tools:
python: "3.10"

# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: cEpiabm/docs/conf.py

python:
install:
- requirements: cEpiabm/docs/requirements.txt
2 changes: 1 addition & 1 deletion cEpiabm/docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def configure_doxyfile(_input_dir, _output_dir):
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
html_theme = 'alabaster'

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
Expand Down
3 changes: 1 addition & 2 deletions cEpiabm/docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
Welcome to C++ Epiabm's documentation!
======================================

This is the C++ Backend for the EpiAbm Package.

.. include:: ../README.rst

Contents
========
Expand Down
3 changes: 0 additions & 3 deletions pyEpiabm/README.md

This file was deleted.

134 changes: 134 additions & 0 deletions pyEpiabm/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
pyEpiabm
========

The pyEpiabm backend is written in python, chosen for its readability
and user-friendliness. It is not able to cope with large population
sizes, but can configure a toy population to explore the functionality
of the model and better understand the underlying code. Additionally,
toy models may be quicker for model comparison and parameter inference,
though care should obviously be taken when scaling up to a full
population. We provide a variety of workflows to show the utility of
code.

Installation of pyEpiabm
------------------------

pyEpiabm is not yet available on `PyPI <https://pypi.org/>`__, but the
module can be pip installed locally. The directory should first be
downloaded to your local machine, and can then be installed using the
command:

.. code:: console
pip install -e .
from the ``pyEpiabm`` directory. If you also wish to build the docs
locally, this requires additional dependencies, which must be specified:

.. code:: console
pip install -e .[docs]
Running a simulation
--------------------

A number of example simulations are included the in the
``python_examples`` directory. The simplest complete workflow for
running a simulation is provided in
``python_examples/basic_example/simulation_flow.py``, but all others
follow a similar format. Other example simulations include an
``age_stratified_example``, and ``spatial_example`` which demonstrate
these aspects of the module. ``gilbraltar_example`` combines age and
spatial stratification using census data from Gibraltar, and can be used
to benchmark against CovidSIM.

There are a number of steps to any simulation:

Set Random Seed *(Optional)*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This allows the random seed to be set for all random modules used in the
simulation, to enable reproducible simulations. The recommended approach
here is to set one seed at the start of the script (before configuring
the population or the simulation objects), so that both are generated
according to this seed. It is also possible to set a separate seed for
one or other object, by passing ``population_seed`` or
``simulation_seed`` into their respective parameter dictionaries,
however care should be exercised to ensure the two objects are
configured sequentially. For example, generating a second population
after setting the simulation seed would be done according to
``simulation_seed`` not ``population_seed``. Setting the seed is not
currently compatible with multi-threaded execution.

Configure Population
~~~~~~~~~~~~~~~~~~~~

Create a population based on the parameters given, from the following
list:

- ``population_size``: Number of people in population
- ``cell_number``: Number of cells in population
- ``microcell_number``: Number of microcells in each cell
- ``household_number``: Number of households in each microcell
*(Optional)*
- ``place_number``: Number of places in each microcell *(Optional)*
- ``population_seed``: Random seed for reproducible populations - see
above *(Optional)*

Import Population
~~~~~~~~~~~~~~~~~

Alternatively, it is possible to import a population from a ``.csv``
file, with the following headings:

- ``cell``: ID code for cell
- ``microcell``: ID code for microcell
- ``location_x``: The x coordinate of the parent cell location
- ``location_y``: The y coordinate of the parent cell location
- ``household_number``: Number of households in that microcell
- Any number of columns with titles from the ``InfectionStatus`` enum
(such as ``InfectionStatus.Susceptible``), giving the number of
people with that status in that cell

File of this format can also be exported using the
``pyEpiabm.routine.FilePopulationConfig.print_population()`` method,
i.e. for reproducibility or use in further simulations.

Configure Simulation
~~~~~~~~~~~~~~~~~~~~

Configure a simulation with a number of parameters. These are split into
three categories:

sim_params
""""""""""

- ``simulation_start_time``: The initial time at the start of the simulation
- ``simulation_end_time``: The final time at which to stop the simulation
- ``initial_infected_number``: The initial number of infected individuals in the population
- ``initial_infect_cell``: Whether to choose initial infected individuals from a single cell
- ``simulation_seed``: Random seed for reproducible simulations - see above *(Optional)*

file_params
"""""""""""
*(For controlling output location)*

- ``output_file``: String for the name of the output .csv file
- ``output_dir``: String for the location of the output file, as a relative path
- ``spatial_output``: Boolean to determine whether a spatial output should be used *(Default false)*
- ``age_stratified``: Boolean to determine whether the output will be age stratified *(Default false)*

inf_history_params
""""""""""""""""""
*(For controlling the infection history output - Default None)*

- ``output_dir``: String for the location for the output files, as a relative path
- ``status_output``: Boolean to determine whether we need a csv file containing infection status values (Default false)
- ``infectiousness_output``: Boolean to determine whether we need a csv file containing infectiousness (viral load) values (Default false)
- ``compress``: Boolean to determine whether we compress a csv file containing infection status values and/or a csv file containing infectiousness (viral load) values if they are written (Default false)

Two lists of sweeps must also be passed to this function - the first
will be executed once at the start of the simulation (i.e. to determine
the initial infections in the population), while the second list will be
ran at every timestep (i.e. to propagate the infection through the
population).
File renamed without changes.
10 changes: 4 additions & 6 deletions pyEpiabm/docs/source/index.rst
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
.. pyEpiabm documentation master file, created by
sphinx-quickstart on Wed Oct 28 05:13:22 2020.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
sphinx-quickstart on Wed Oct 28 05:13:22 2020.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to pyEpiabm's documentation!
====================================

This is a python backend for the EpiAbm package.

.. include:: ../../README.rst

Contents
========

.. module:: pyEpiabm

.. toctree::

core
interventions
outputs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ def test__get_waning_weights_no_age(self):
def test__get_waning_weights(self):
"""Tests the _get_waning_weights() function with ages
"""
with (mock.patch('pyEpiabm.Parameters.instance') as mock_param):
with mock.patch('pyEpiabm.Parameters.instance') as mock_param:
mock_param.return_value.use_ages = 1.0
mock_param.return_value.use_waning_immunity = 1.0
mock_param.return_value.asympt_infect_period = 14
Expand Down
3 changes: 2 additions & 1 deletion pyEpiabm/pyEpiabm/utility/rate_multiplier.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#

import math
import typing


class RateMultiplier:
Expand Down Expand Up @@ -47,7 +48,7 @@ def __init__(self, p_1: float, p_2: float,
self.t_2 = t_2
self.a, self.b = self._calculate_parameters()

def _calculate_parameters(self) -> tuple[float, float]:
def _calculate_parameters(self) -> typing.Tuple:
"""Given the initial data points p(t_1) = p_1 and p(t_2) = p_2, this
method determines the parameters a and b of the function.
Note that p(t) = 1 - be^(-at).
Expand Down
2 changes: 1 addition & 1 deletion pyEpiabm/pyEpiabm/version_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# - Changes to minor indicate new features, possible slight backwards
# incompatibility
# - Changes to revision indicate bugfixes, tiny new features
VERSION_INT = 0, 0, 3
VERSION_INT = 1, 1, 0

# String version of the version number
VERSION = '.'.join([str(x) for x in VERSION_INT])
4 changes: 2 additions & 2 deletions pyEpiabm/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ def get_version():

def get_readme():
"""
Load README.md text for use as description.
Load README.rst text for use as description.
"""
with open('README.md') as f:
with open('README.rst') as f:
return f.read()


Expand Down
1 change: 1 addition & 0 deletions python_examples/NZ_example/NZ_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
plt.savefig(os.path.join(os.path.dirname(__file__),
"simulation_outputs/SIR.png"))
plt.close()
# Default file format is .png, but can be changed to .pdf, .svg, etc.

# Create plot to show new cases and new deaths against time
newdf = pd.DataFrame()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
plt.xlabel('Age')
plt.title('Histogram of toy population')
plt.savefig('images/Histograms/Withoutsim.png')
# Default file format is .png, but can be changed to .pdf, .svg, etc.

# Set simulation parameters
sim_params = {"simulation_start_time": 0, "simulation_end_time": 90,
Expand Down
8 changes: 6 additions & 2 deletions python_examples/age_stratified_example/age_stratified_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,11 @@ def barchart(self, outfile: str,
param_file=None):
"""Function which creates a bar chart from csv data, with
capability to stratify by age if required. Plot is automatically
saved to a png file.
saved to a file of the specified format.
Parameters
----------
outfile : str
Path to the .png file where the bar chart will be saved
Path to the file where the bar chart will be saved
infection_category : str
Category to be plotted, defaults to Total Infectious
write_Df_toFile : str
Expand Down Expand Up @@ -242,9 +242,13 @@ def barchart(self, outfile: str,

if __name__ == '__main__':
dirname = os.path.dirname(os.path.abspath(__file__))
savename = os.path.join("simulation_outputs", "age_stratify.png")
# Default file format is .png, but can be changed to .pdf, .svg, etc.

p = Plotter(os.path.join(os.path.dirname(__file__),
"simulation_outputs/output_with_age.csv"),
start_date='01-01-2020', sum_weekly=False)

p.barchart(os.path.join(os.path.dirname(__file__),
"simulation_outputs/age_stratify.png"),
write_Df_toFile=os.path.join(os.path.dirname(__file__),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"InfectionStatus.Recovered"])
plt.savefig(os.path.join(os.path.dirname(__file__),
"simulation_outputs/simulation_flow_SIR_plot.png"))
# Default file format is .png, but can be changed to .pdf, .svg, etc.

# Creation of a plot of results with age stratification
p = Plotter(os.path.join(os.path.dirname(__file__),
Expand Down
1 change: 1 addition & 0 deletions python_examples/basic_simulation/simulation_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,4 @@
"simulation_outputs",
"simulation_flow_SIR_plot.png")
)
# Default file format is .png, but can be changed to .pdf, .svg, etc.
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,4 @@
"covidsim_daily_cases.csv"),
param_file=os.path.join(os.path.dirname(__file__),
os.path.pardir, "./gibraltar_parameters.json"))
# Default file format is .png, but can be changed to .pdf, .svg, etc.
1 change: 1 addition & 0 deletions python_examples/gibraltar_example/gibraltar_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
SIRdf.plot(y=["Susceptible", "Infected", "Recovered"])
plt.savefig(os.path.join(os.path.dirname(__file__),
"simulation_outputs/simulation_flow_SIR_plot.png"))
# Default file format is .png, but can be changed to .pdf, .svg, etc.

# Creation of a plot of results with age stratification
# if file_params["age_stratified"]:
Expand Down
Loading

0 comments on commit 2252eaa

Please sign in to comment.