diff --git a/.gitignore b/.gitignore index 8b22ff275..2427012b1 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,7 @@ share/python-wheels/ .installed.cfg *.egg build/ +_build/ build_dir/ MANIFEST diff --git a/README.md b/README.md index 679a6a5cc..10a8b406e 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,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. diff --git a/cEpiabm/README.rst b/cEpiabm/README.rst new file mode 100644 index 000000000..3732bfa20 --- /dev/null +++ b/cEpiabm/README.rst @@ -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``. diff --git a/cEpiabm/docs/.readthedocs.yaml b/cEpiabm/docs/.readthedocs.yaml new file mode 100644 index 000000000..1e10de6d0 --- /dev/null +++ b/cEpiabm/docs/.readthedocs.yaml @@ -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 diff --git a/cEpiabm/docs/conf.py b/cEpiabm/docs/conf.py index 0abda9182..3f8ae162e 100644 --- a/cEpiabm/docs/conf.py +++ b/cEpiabm/docs/conf.py @@ -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, diff --git a/cEpiabm/docs/index.rst b/cEpiabm/docs/index.rst index 1e761e90b..d5757bb82 100644 --- a/cEpiabm/docs/index.rst +++ b/cEpiabm/docs/index.rst @@ -6,8 +6,7 @@ Welcome to C++ Epiabm's documentation! ====================================== -This is the C++ Backend for the EpiAbm Package. - +.. include:: ../README.rst Contents ======== diff --git a/pyEpiabm/README.md b/pyEpiabm/README.md deleted file mode 100644 index bfedcece1..000000000 --- a/pyEpiabm/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# pyEpiabm - -This is the python backend for epiabm. diff --git a/pyEpiabm/README.rst b/pyEpiabm/README.rst new file mode 100644 index 000000000..f9cbf6fe7 --- /dev/null +++ b/pyEpiabm/README.rst @@ -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 `__, 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). diff --git a/.readthedocs.yml b/pyEpiabm/docs/.readthedocs.yaml similarity index 100% rename from .readthedocs.yml rename to pyEpiabm/docs/.readthedocs.yaml diff --git a/pyEpiabm/docs/source/index.rst b/pyEpiabm/docs/source/index.rst index 14360d76d..4882444c1 100644 --- a/pyEpiabm/docs/source/index.rst +++ b/pyEpiabm/docs/source/index.rst @@ -1,13 +1,12 @@ .. 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 ======== @@ -15,7 +14,6 @@ Contents .. module:: pyEpiabm .. toctree:: - core interventions outputs diff --git a/pyEpiabm/pyEpiabm/version_info.py b/pyEpiabm/pyEpiabm/version_info.py index f6ad75892..8ea984176 100644 --- a/pyEpiabm/pyEpiabm/version_info.py +++ b/pyEpiabm/pyEpiabm/version_info.py @@ -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]) diff --git a/pyEpiabm/setup.py b/pyEpiabm/setup.py index ff1118caf..97d9988a1 100644 --- a/pyEpiabm/setup.py +++ b/pyEpiabm/setup.py @@ -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()