Giter Club home page Giter Club logo

epispot's Introduction

epispot


epispot v3

A Python package for the mathematical modeling of infectious diseases via compartmental models. Originally designed for epidemiologists, epispot can be adapted for almost any type of modeling scenario.

Features

The epispot package currently only supports compartmental models, though we plan to expand the package to work for stochastic agent-based and spatial models as well. Currently, epispot offers the following:

  • Quick compilation of compartmental models with the following compartments:
    • Susceptible
    • Infected
    • Recovered
    • Removed
    • Exposed
    • Dead
    • Critical
    • Hospitalized
  • Custom-defined compartments for research
  • Built-in graphing and visualization engine
    • Plots model predictions interactively
    • Creates comparisons between models

Due to its diverse range of features, epispot can be used for both research and experimental modeling. If you would like to add more modeling support, please see the contributing section.

Installation

Notice: The epispot nightly package is now officially deprecated.

The epispot package can be installed from PyPI, Anaconda, or be built from the source. Below are the steps for each installation process:

PyPI

This is the easiest way to install epispot. From a terminal, enter:

pip install epispot

Anaconda

The standard version of epispot is published to conda using the conda-forge channel. To install, please use:

conda config --add channels conda-forge
conda install -c conda-forge epispot

Building from the source

This is the hardest way to install epispot and it is recommended that you use either PyPI or Anaconda to install it instead. However, if you would like to contribute to the repository, this will be particularly useful.

Clone the repository and install the dependencies with:

git clone https://github.com/epispot/epispot
cd epispot
pip install -r requirements.txt
pip install -r bin/requirements.txt

Then, build the latest version with:

python setup.py install

For older releases, first checkout a version tag before installing; e.g.:

git checkout v2.1.1
python setup.py install

Quick Demo

Using epispot in a Python REPL to create the well-known SIR model (in less than three lines of code):

Demo showing how to create an SEIR model in less than 20 lines of code

Documentation

Right now, documentation for some of the latest releases is quite shaky. The official docs are located at https://epispot.github.io/epispot/ but may be incomplete in many areas.

Examples

The GitHub repository has a vast array of samples using epispot. We are currently working on a tutorial, but for now the documentation is the best place to start.

Badges

PyPI: latest-release Downloads

LGTM: Language grade: Python Total alerts

Codecov: codecov

Feedback

If you have any feedback, please

  • Create a discussion on GitHub
  • Create an issue if you've found a bug
  • Submit a PR if you want to add a new feature
  • Contact a CODEOWNER

Contributing

Contributions are always welcome! See CONTRIBUTING.md for instructions on how to get started, including environment setup and instructions to build from the source. Please note also that epispot has many guides dedicated to certain types of contributions. Please see

Citation

GPLv3 License

If you plan on using epispot in your project, please abide by the GPLv3 license. This requires that any changes you make to epispot are open-sourced under the GPLv3 license as well and that you give credit to the author, which you can do by citing the project in your research, linking back to the original repository, or mentioning the author @quantum9innovation.

For research, you can also use epispot's DOI to reference the project:

DOI

The recommended citation for epispot is:

quantum9innovation (2022, August 20). epispot/epispot: (Version 3.0.0-rc-1). Zenodo. http://doi.org/10.5281/zenodo.5136721

Related Work

There are many related projects to epispot, although we believe that epispot has greater extensibility than many of these other projects. Additionally, epispot is quite portable (graphs can be used as web components, displayed as images, etc.). However, below we would like to acknowledge a few projects that may be better suited to certain use cases:

  • EpiJS by @Quantalabs contains the same functionality of epispot but in pure JavaScript, making it more suitable for use in a web browser
  • covasim by the Institute for Disease Modeling offers agent-based stochastic models as opposed to epispot's compartmental modeling structure
  • CovsirPhy by @lisphilar offers greater support for loading and analyzing real COVID-19 data instead of running simulations

Authors

Please see our CODEOWNERS file for authors. Because epispot is an open-source project, different pieces of our code have different authors. However, if citing epispot or using it in another project, you can cite @quantum9innovation as the lead author.

Acknowledgements

Idea & Inspiration

The original idea for epispot came from a 3Blue1Brown video on basic infectious disease dynamics and an interactive article in the Washington Post. This in turn inspired the very basic infectious disease dynamics simulated here. However, what finally set the package into motion was a series of articles by Henry Froese, available on Medium here, along with their corresponding interactive notebooks.

Code Development & Maintenance

The epispot project is built on open source code and is itself open-source. The initial core development was fueled by @quantum9innovation and much of the codebase was maintained by @Quantalabs. Additionally, thank you to all of epispot's open-source contributors!

epispot's open-source contributors

epispot's People

Contributors

dependabot[bot] avatar quantum9innovation avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

epispot's Issues

[Stub] Issue status test

This issue is a stub: do not comment.
It is intended to test the new claim.yml and mod.yml workflows that aim to provide automatic issue labeling based on issue comments. See commit 5eb8ce1 for more information.

Decreased legend visibility on `massive-plots`

Describe the bug
The newly-added support for native stacked area charts in massive-plots (epi.plots.native.stacked()) lacks good legend visibility. This is due to the fact that for some reason, matplotlib fails to enforce the default white background for graphical elements on plots, resulting in no contrast between the graph itself and the legend.

To Reproduce
See tests/plotting::test_full_native_stack

Expected behavior
All legends should have a white background, thus standing out from the rest of the plot.

Screenshots
epispot-issue-screenshot-3
As shown in the plot above, legend colors blend in with the actual graphics.

Python

  • Python Version: 3.9.4
  • Operating System: Linux Mint 20 (Cinnamon)
  • Epispot Version: massive-plots @ 4068117
  • Nightly (yes/no): yes: pre-alpha

Anaconda

  • Anaconda Version: 4.10.1
  • Matplotlib Version: 3.3.4

Additional context
This issue was mentioned in commit 4068117

Get testing with pytest

Is your feature request related to a problem? Please describe.
No.

Describe the solution you'd like
Testing with pytest makes everything quicker, more efficient, and faster.

Describe alternatives you've considered
Running each command manually, which is less efficient, and reports aren't given, unlike pytest, which files error and warning reports in the summary.

Error in `basic-sir-model.py`

This error happened when running in GitHub actions, and only happened in the Python version 3.6. It says that there is an extra seed parameter on line 43 of basic-sir-model.py.

Incorrect codecov reporting on PRs

Describe the bug
@codecov officially does not recognize a base report from the master branch even though reports are being uploaded to codecov every commit via Travis CI, and can be seen here. Instead, codecov compares each PR to older commits with higher overall code coverage and fails because of this incorrect comparison.

To Reproduce
See #49, #50

Expected behavior
Codecov should instead find the latest reports from the master branch and compare those to the PR reports. Codecov should also provide detailed merge information on their website, which currently it does not do due to incorrect base reporting.

Pre-configured parameter and model sanity checks

Models should automatically run sanity checks to ensure that parameter values are reasonable, implemented correctly, and that all layer combinations are proper. If any of these conditions is not met, epispot should either give a warning or stop the program with a ValueError.

Speed up re-integration

Store a fully-integrated model every epoch of the gradient descent process and then access the values later to avoid re-integration. Potential speedup: 2x

Automatically switch to log scale for large models

Larger models can create nearly imperceivable differences in the non-susceptible population because such a small fraction of the population is infected. By automatically deploying log scaling, this visualization would capture the small changes in each class.

Create a new fitter for exact gradient calculations in basic models

The current \fitters\gradient-descent.py bypasses direct gradient calculation by sampling at multiple points to get an estimation of the gradient. Getting an exact value would speed up convergence, solve numerical issues, and would be twice as efficient as the current algorithm.

Add stricter tests with bounds checking, etc.

Before the launch of v3 (stable), we should implement greater testing capabilities to limit the number of bugs and implementation errors that arise in production. The most obvious way of doing this is to check that model estimates seem reasonable after they go through testing. This will require some minor changes to our testing suite, which we hope @Quantalabs will lead.

Add Dependabot

Is your feature request related to a problem? Please describe.
This feature is unrelated to any current issues in epispot. However, using Dependabot will not only make epispot's code more secure, but it allow epispot to support the latest versions of each of our dependencies. Previously, this was not a problem—however, as new versions of epispot add more and more external dependencies, it is critical that we monitor security vulnerabilities and release notes constantly.

Describe the solution you'd like
Solving this problem will require the following steps:

Describe alternatives you've considered
No alternative solutions have been considered. Dependabot is usually the norm for dependency management, especially since it integrates nicely with GitHub.

Update guides for compatibility with epispot v3

With the release of epispot v3, we must ensure that all guides are updated to reflect the changes made in the update. Additionally, we must provide a transition guide to help ease the difficulties of switching (possibly even creating an epispot-6 package to automatically convert code). This issue is currently a long (or short?) way off as it's planned for the official release of v3 as opposed to v3b which is due to come out a week sooner.

Code coverage metrics may be inaccurate

After adding testing files, code coverage actually went down which may signal that

  1. coverage.py is set up wrong
  2. coverage.py is wrong
  3. We should not use coverage.py
  4. Workflow is wrong

[op:spaghetti] Standardize parameters

Parameters for all compartments other than the Susceptible compartment should include a rate and probability, organized into an easily-understandable matrix which is then parsed by the Model class. The reason for this is to eliminate the double-parameter chaos created in epispot v2.

The double-parameter issue

Currently, epispot v2 requires parameters to be specified twice. First to the compartment from which people are leaving and second to the compartment which people are entering. This is because each compartment does not have access to the other compartments' derivatives. However, there is a simple fix for this; every compartment needs to be able to change the derivative of every other compartment. This means that all the derivatives need to be stored at the Model level and distributed to all the compartments. Each compartment should not make a direct assignment to the derivative but rather add or subtract some value from the derivative. Using this system, every compartment can change the derivative of every other compartment, avoiding the complication of having to enter parameters in twice.

An example solution

The model first learns what compartments are going to be compiled. For this example, we'll use the following compartment codes: A, B, C. Here's a diagram of how they all connect:

  ┌───────────────────┐
  │                   ▼
┌───┐     ┌───┐     ┌───┐
│ A │ ──▶ │ C │ ──▶ │ B │
└───┘     └───┘     └───┘

Now we examine how we can represent this as a parameter matrix. We will refer as the compartments from which an arrow extends as the from compartments. On the other hand, compartments which receive an arrow will be referred to as to compartments.

In code

Each from compartment gets its own subarray. Each element of this subarray corresponds to its respective to compartment. This in turn contains a tuple with the structure ({probability}, {rate}). For our diagram, the matrix looks like this in Python:

matrix = [
    [(1/2, 1/3), (1/5, 1/2)],       # A: [B, C]
    [(1/2, 1/6)],                   # C: [B]
]

Sidenote

Notice how the matrix simply does not include elements or subarrays that aren't necessary; B has no subarray of its own and C lacks a tuple describing rates and probabilities for A. We can do this because of how we describe connections between compartments:

Describing connections

This won't change much from epispot v2. Here's how connections are described, using our example with A, B, and C. The following graph:

  ┌───────────────────┐
  │                   ▼
┌───┐     ┌───┐     ┌───┐
│ A │ ──▶ │ C │ ──▶ │ B │
└───┘     └───┘     └───┘

becomes the following matrix in Python:

connections = [
    ['B', 'C'],     # A
    [],             # B
    ['B']           # C
]

Sidenote

Notice how, even despite having any connections, B must be included in this matrix. This matrix differs from the rate and probability matrix because here epispot does not yet know what the connections are. After epispot receives this matrix, the Model class can then parse following parameter matrices by assuming that non-connections are skipped.

Development

For now, development of this feature will not interfere with the package itself. Rather, the development will be done in a separate module and tested with dummy compartments (as we did above), before it is transitioned into the actual Model class.

[Stub] Issue Review Process Demo

Describe the bug
This is a test of the new issue tracking workflows mod.yml and claim.yml

To Reproduce
See this issue

Expected behavior
This issue should be automatically labeled as status:review-needed. Upon review, a reviewer will mark this issue with either the high-priority or low-priority tags and then add the /available message which will trigger mod.yml to add status:available, eliminating the previous tag. Finally, someone may claim the issue with /claim which will trigger claim.yml to add the status:claimed label.

Gradient Descent fitter doesn't converge for most cases

In many cases, the gradient descent fitter fails to converge, often ending up with extremely large parameters that make no sense for a specific problem. It seems that early stopping (limiting the number of epochs) helps to a certain extent, but the model still fails to capture most of the data.

Triage on Hospitalized layer does not work

Describe the bug
Triage on the Hospitalized layer is not properly put into effect--the compartment continues to take in more incoming patients even when maximum capacity has been reached.

To Reproduce
Steps to reproduce the behavior:

  1. See test_critical.py on the super-coverage branch

Expected behavior
There should be a sharp cut-off as soon as the Hospitalized compartment crosses the threshold.

Screenshots
epispot-issue-screenshot-2

Python

  • Python Version: 3.7
  • Operating System: Linux
  • Epispot Version: super-coverage latest
  • Nightly (yes/no): yes

[Bug] Fix the codebase

Describe the bug
Several syntax errors/untested code creating problems for pytest (hence all the failing PRs)

To Reproduce
(locally)

  1. Pull the latest version of the master branch:
    git checkout master; git pull
  2. python -m pytest

Expected behavior
All builds should be passing and most code should undergo testing to prevent any unforeseen bugs like this from reoccuring.

Python

  • Python Version: First observed on Python 3.8
  • Operating System: Linux
  • Epispot Version: latest @ 3b63032
  • Nightly (yes/no): unreleased

Additional context
@Quantalabs will head the management of this issue, necessary for continuing any release plans we may have.

Adding an en/ folder?

Right now both pdoc docs and translations are stored on the root folder in gh-pages. There are two problems with this:

  1. Modules with the same names as language codes will cause improper translations
  2. Sub-modules are not being deleted
    a) The command that is being run in docs.yml is rm * which only deletes root files
    b) Files inside sub-modules will not be deleted

Possible fix:
Create an en/ folder for English documentation solving (1) and then delete all documentation inside en/ including sub-modules
every time docs.yml is run solving (2).

Travis CI Setup

Describe the solution you'd like
Travis CI provides a quick and easy CI/CD setup perfect for testing. Work has already started on the travis-ci-setup branch.

Additional context
Work has started on the travis-ci-setup branch already.

Deprecate support for Python 3.7 (With #137)

NumPy has officially dropped support for Python 3.7, though Python won't end-of-life it for more than 9 months. This of course brings up the question of whether we, as epispot, should follow suit, considering that NumPy is one of our core dependencies and also that most of our other dependencies are in one way or another dependent on NumPy.

Originally posted by @quantum9Innovation in #137 (comment)

It has been decided that support for 3.7 should be deprecated. the following are the steps for what needs to be done:

[Feat] Save/load models to/from file

Is your feature request related to a problem? Please describe.
There is no problem directly related to this feature request, though it would solve issues relating to model reproduciblity, which will prove especially useful in research.

Describe the solution you'd like
Two functions, each of which compile an epispot model object into a file (JSON would probably be best, though any object-oriented file type like YAML/TOML could theoretically work). For certain abstract elements related to the models, (e.g. parameters defined as functions) values could be linked to names or special codes which could be interpreted later with the help of a dictionary. With this dictionary, the reader function would be able to read from the file and recreate the model in its original form, solving the problem of reproducibility and drastically lowering the file size required to do so.

Describe alternatives you've considered
There are, of course, multiple alternatives to solving the reproducibility issue, outlined below:

(1) Copying code: While this works, it's inefficient, occasionally hard to read (as it can be clouded with unnecessary functions and scripts), and involves large file sizes for a problem that can be solved more cleanly by other means.

(2) Saving model outputs: This is perhaps the most obvious solution, but it prevents researchers from actually inspecting the models producing the results and only shows part of the larger picture.

(3) Compiling the model to lower-level code ⁉️: Very efficient, but almost certainly unreadable. Why would we ever want to do this??

Additional context
It would be nice to ship this with epispot v3b, but the current situation makes that look unlikely. Regardless, @Quantalabs will head development until this enters nightly (or, if we're lucky, beta) testing.

Add marker support to both web and native graphing

Is your feature request related to a problem? Please describe.
This feature request is not related to any problems in this repository. However, this does address a potential deprecation concern with epispot v3. In older v2 versions of epispot, there was the option of customizing graphs by adding 'markers,' which was taken away with the new plots submodule, introduced in #67 (of v3a1). The reason for this was that markers were not supported by plotly, which would mean that if implemented, this feature would cause an incompatibility between the web and native modules. However, plotly's latest update (v5.2.1)—discussed in #104—now supports adding markers to line graphs, eliminating any need for discussion about this problem.

Original discussion (pulled from #104)

  • plotly/plotly.py#2719
    • We can now add markers to epispot web graphs with Plotly! This is actually something that older versions of epispot have supported for quite a while with matplotlib, but being able to bring this functionality back into both plotly and matplotlib is a huge plus. This will be worked on in a separate issue.

Describe the solution you'd like
The new feature will add a markers parameter to all supported functions in the native and web modules. This parameter will accept various kinds of graphical markers (and ideally maintain compatibility with the standards established in epispot v2). The end result should allow for various graphical annotations wherever possible.

Describe alternatives you've considered
No alternatives have been considered as this was an already-implemented feature.

Additional context
No screenshots as of yet (subject to change in the future).

Importing and Exporting epispot models

Importing and exporting epispot models with .yml and/or .json files created from a CLI or function would be extremely easy. I've already started to work on this.

Related PR's and Issues:

[Feat] Built-in parameter distributions and estimates from literature

Is your feature request related to a problem? Please describe.
This feature is not related to any problem, but it is inspired by epiforcasts/EpiNow2

Describe the solution you'd like
Epispot should include a handful of parameter estimates from literature to aid with the creation of new models. Additionally, epispot should come with built in random modeling of various parameter distributions which can either be selected manually or automatically in the case that the user has not passed in a function for a specific parameter.

Describe alternatives you've considered
The alternative of not including this would complicate model creation greatly as there are often many, many parameters (exponentially many so as more compartments are added). Therefore, it would be helpful to have some kind of "filler" parameter distribution for unlabeled parameters. Additionally, by adding literature estimates, we can fit COVID-19 trends better using vetted sources rather than tweaking parameters to find an exact match for the data.

Additional context
No testing is expected to happen before this code is pushed to production

Current progress:

  • Parameter distributions
    • Gamma (γ)
    • R Naught ($$ R_0 $$)
    • Total population (N)
  • #135
  • #134

Code Coverage Gaps on `massive-plots` Branch

New commits in the massive-plots branch have caused a new gap in code coverage from previous commits in that branch. The first commit in which this gap was exposed is 02253f05a0747f136b983c313093be57e554c570. The CodeCov diff and coverage analytics for that commit can be seen here. The commit in question resulted in the code coverage drop partly due to new file additions that were not properly covered for in tests. Additionally, there is a missing # pragma: no cover annotation that should be made for the new ImportError warnings introduced with the new files. This should be fixed in a matter of commits.

Convert to package-ready form

Currently, all hyperparameter adjustments take place within the code. To avoid this troublesome interface, the code should be put in package-ready form so that models can be tested from an entirely different script.

New Issue Found in super-coverage Branch with Circular-Type Models

Describe the bug
Models with a probability of resusceptability do not change the derivative of the Susceptible compartment which means that the Susceptible compartment continues to shrink and never grows. This is because self.first_layer is always true, even if a probability of resusceptability is provided.

To Reproduce
Steps to reproduce the behavior:

  1. Create a recurrent S --> I --> R --> S Model
  2. Plot all compartments
  3. Notice how the Infected and Recovered compartments shrink to 0 while the Susceptible compartment never grows

Expected behavior
The Susceptible compartment should grow to keep the population the same.

Screenshots
epispot-issue-screenshot-1

Python

  • Python Version: 3.7
  • Operating System: Linux
  • Epispot Version: super-coverage latest
  • Nightly (yes/no): yes

Additional context
This problem is currently being solved in the super-coverage branch.

[Bug] Pytest failing on params.py

Describe the bug
From GitHub Actions Runner (source):

Couldn't parse '/home/runner/work/epispot/epispot/epispot/params.py' as Python source: 'invalid syntax' at line 90

To Reproduce
Running pytest should give the same error.

Expected behavior
Pytest should exit with 0.

Python

  • Python Version: 3.7 (also 3.8)
  • Operating System: Linux/Ubuntu
  • Epispot Version: 2fd255e (also 3b63032)
  • Nightly: yes (unreleased as of yet)

Additional context
This is unrelated to the removal of Python 3.7 and has to do with some type of syntax error in the newly-added params module (see #136 for more)

Improper handling of `compartments` parameter in `massive-plots`

Describe the bug
The compartments parameter in the module epi.plots.web of the massive-plots branch is not being used. This has led to 2 "unused import" alerts on LGTM, which can be observed here.

To Reproduce
See LGTM error or examine tests/plotting::test_full_web.

Expected behavior
The compartments parameter should be used to hide compartments that should not be plotted. The official definition of the parameter is the list of compartments to be plotted, although for technical reasons, it might be easier to implement the reverse, specifically: the list of compartments to not be plotted. However, this will require changing the functions in the epi.plots.native module as well.

Screenshots
Screenshots will be posted at a later date.

Python

  • Python Version: irrelevant
  • Operating System: irrelevant
  • Epispot Version: massive-plots @ a485fedb26887a1985ee759cc0f44f51d2ad5a11
  • Nightly: yes: pre-alpha (in review on PR #67)

Additional context
We are still seeking out more details on this issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.