Skip to content

Commit

Permalink
Merge pull request #927 from amath-idm/variants-dev
Browse files Browse the repository at this point in the history
Variants dev
  • Loading branch information
cliffckerr authored Apr 13, 2021
2 parents 8898686 + ac8e34e commit 9e94ccd
Show file tree
Hide file tree
Showing 68 changed files with 4,674 additions and 2,567 deletions.
83 changes: 77 additions & 6 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,86 @@ Coming soon

These are the major improvements we are currently working on. If there is a specific bugfix or feature you would like to see, please `create an issue <https://github.com/InstituteforDiseaseModeling/covasim/issues/new/choose>`__.

- Mechanistic handling of different strains, and improved handling of vaccination, including more detailed targeting options, waning immunity, etc. This will be Covasim 3.0, which is slated for release early April.
- Expanded tutorials (health care workers, vaccination, calibration, exercises, etc.)
- Multi-region and geospatial support
- Expanded tutorials (health care workers, calibration, exercises, etc.)
- Multi-region and geographical support
- Economics and costing analysis


~~~~~~~~~~~~~~~~~~~~~
Latest versions (2.x)
~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
Latest versions (3.0.x)
~~~~~~~~~~~~~~~~~~~~~~~

Version 3.0.0 (2021-04-13)
--------------------------
This version introduces fully featured vaccines, variants, and immunity. **Note:** These new features are still under development; please use with caution and email us at [email protected] if you have any questions or issues. We expect there to be several more releases over the next few weeks as we refine these new features.

Highlights
^^^^^^^^^^
- **Model structure**: The model now follows an "SEIS"-type structure, instead of the previous "SEIR" structure. This means that after recovering from an infection, agents return to the "susceptible" compartment. Each agent in the simulation has properties ``sus_imm``, ``trans_imm`` and ``prog_imm``, which respectively determine their immunity to acquiring an infection, transmitting an infection, or developing a more severe case of COVID-19. All these immunity levels are initially zero. They can be boosted by either natural infection or vaccination, and thereafter they can wane over time or remain permanently elevated.
- **Multi-strain modeling**: Model functionality has been extended to allow for modeling of multiple different co-circulating strains with different properties. This means you can now do e.g. ``b117 = cv.strain('b117', days=1, n_imports=20)`` followed by ``sim = cv.Sim(strains=b117)`` to import strain B117. Further examples are contained in ``tests/test_immunity.py`` and in Tutorial 8.
- **New methods for vaccine modeling**: A new ``cv.vaccinate()`` intervention has been added, which allows more flexible modeling of vaccinations. Vaccines, like natural infections, are assumed to boost agents' immunity.
- **Consistency**: By default, results from Covasim 3.0.0 should exactly match Covasim 2.1.2. To use the new features, you will need to manually specify ``cv.Sim(use_waning=True)``.

Immunity-related parameter changes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- A new control parameter, ``use_waning``, has been added that controls whether to use new waning immunity dynamics ("SEIS" structure) or the old dynamics where post-infection immunity was perfect and did not wane ("SEIR" structure). By default, ``use_waning=False``.
- A subset of existing parameters have been made strain-specific, meaning that they are allowed to differ by strain. These include: ``rel_beta``, which specifies the relative transmissibility of a new strain compared to the wild strain; ``rel_symp_prob``, ``rel_severe_prob``, ``rel_crit_prob``, and the newly-added immunity parameters ``rel_imm`` (see next point). The list of parameters that can vary by strain is specified in ``defaults.py``.
- The parameter ``n_strains`` is an integer that specifies how many strains will be in circulation at some point during the course of the simulation.
- Seven new parameters have been added to characterize agents' immunity levels:
- The parameter ``nab_init`` specifies a distribution for the level of neutralizing antibodies that agents have following an infection. These values are on log2 scale, and by default they follow a normal distribution.
- The parameter ``nab_decay`` is a dictionary specifying the kinetics of decay for neutralizing antibodies over time.
- The parameter ``nab_kin`` is constructed during sim initialization, and contains pre-computed evaluations of the nab decay functions described above over time.
- The parameter ``nab_boost`` is a multiplicative factor applied to a person's nab levels if they get reinfected.
- The parameter ``cross_immunity``. By default, infection with one strain of SARS-CoV-2 is assumed to grant 50% immunity to infection with a different strain. This default assumption of 50% cross-immunity can be modified via this parameter (which will then apply to all strains in the simulation), or it can be modified on a per-strain basis using the ``immunity`` parameter described below.
- The parameter ``immunity`` is a matrix of size ``total_strains`` by ``total_strains``. Row ``i`` specifies the immunity levels that people who have been infected with strain ``i`` have to other strains.
- The parameter ``rel_imm`` is a dictionary with keys ``asymp``, ``mild`` and ``severe``. These contain scalars specifying the relative immunity levels for someone who had an asymptomatic, mild, or severe infection. By default, values of 0.98, 0.99, and 1.0 are used.
- The parameter ``strains`` contains information about any circulating strains that have been specified as additional to the default strain. This is initialized as an empty list and then populated by the user.

Other parameter changes
^^^^^^^^^^^^^^^^^^^^^^^
- The parameter ``frac_susceptible`` will initialize the simulation with less than 100% of the population to be susceptible to COVID (to represent, for example, a baseline level of population immunity). Note that this is intended for quick explorations only, since people are selected at random, whereas in reality higher-risk people will typically be infected first and preferentially be immune. This is primarily designed for use with ``use_waning=False``.
- The parameter ``scaled_pop``, if supplied, can be used in place of ``pop_scale`` or ``pop_size``. For example, if you specify ``cv.Sim(pop_size=100e3, scaled_pop=550e3)``, it will automatically calculate ``pop_scale=5.5``.
- Aliases have been added for several parameters: ``pop_size`` can also be supplied as ``n_agents``, and ``pop_infected`` can also be supplied as ``init_infected``. This only applies when creating a sim; otherwise, the default names will be used for these parameters.

Changes to states and results
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Several new states have been added, such as ``people.naive``, which stores whether or not a person has ever been exposed to COVID before.
- New results have been added to store information by strain, as well as population immunity levels. In addition to new entries in ``sim.results``, such as ``pop_nabs`` (population level neutralizing antibodies) and ``new_reinfections``, there is a new set of results ``sim.results.strain``: ``cum_infections_by_strain``, ``cum_infectious_by_strain``, ``new_infections_by_strain``, ``new_infectious_by_strain``, ``prevalence_by_strain``, ``incidence_by_strain``.

New functions, methods and classes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- The newly-added file ``immunity.py`` contains functions, methods, and classes related to calculating immunity. This includes the ``strain`` class (which uses lowercase convention like Covasim interventions, which are also technically classes).
- A new ``cv.vaccinate()`` intervention has been added. Compared to the previous ``vaccine`` intervention (now renamed ``cv.simple_vaccine()``), this new intervention allows vaccination to boost agents' immunity against infection, transmission, and progression.
- There is a new ``sim.people.make_nonnaive()`` method, as the opposite of ``sim.people.make_naive()``.
- New functions ``cv.iundefined()`` and ``cv.iundefinedi()`` have been added for completeness.
- A new function ``cv.demo()`` has been added as a shortcut to ``cv.Sim().run().plot()``.
- There are now additional shortcut plotting methods, including ``sim.plot('strain')`` and ``sim.plot('all')``.

Renamed functions and methods
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- ``cv.vaccine()`` is now called ``cv.simple_vaccine()``.
- ``cv.get_sim_plots()`` is now called ``cv.get_default_plots()``; ``cv.get_scen_plots()`` is now ``cv.get_default_plots(kind='scen')``.
- ``sim.people.make_susceptible()`` is now called ``sim.people.make_naive()``.

Bugfixes
^^^^^^^^
- ``n_imports`` now scales correctly with population scale (previously they were unscaled).
- ``cv.ifalse()`` and related functions now work correctly with non-boolean arrays (previously they used the ``~`` operator instead of ``np.logical_not()``, which gave incorrect results for int or float arrays).
- Interventions and analyzers are now deep-copied when supplied to a sim; this means that the same ones can be created and then used in multiple sims. Scenarios also now deep-copy their inputs.

Regression information
^^^^^^^^^^^^^^^^^^^^^^
- As noted above, with ``cv.Sim(use_waning=False)`` (the default), results should be the same as Covasim 2.1.2, except for new results keys mentioned above (which will mostly be zeros, since they are only populated with immunity turned on).
- Scripts using ``cv.vaccine()`` should be updated to use ``cv.simple_vaccine()``.
- Scripts calling ``sim.people.make_susceptible()`` should now call ``sim.people.make_naive()``.
- *GitHub info*: PR `927 <https://github.com/amath-idm/covasim/pull/927>`__



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Versions 2.x (2.0.0 – 2.1.2)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Version 2.1.2 (2021-03-31)
--------------------------
Expand Down
7 changes: 4 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ Covasim has been used for analyses in over a dozen countries, both to inform pol

4. **Lessons learned from Vietnam's COVID-19 response: the role of adaptive behaviour change and testing in epidemic control**. Pham QD, Stuart RM, Nguyen TV, Luong QC, Tran DQ, Phan LT, Dang TQ, Tran DN, Mistry D, Klein DJ, Abeysuriya RG, Oron AP, Kerr CC (in press; accepted 2021-02-25). *Lancet Global Health*; doi: https://doi.org/10.1101/2020.12.18.20248454.

5. **The role of masks, testing and contact tracing in preventing COVID-19 resurgences: a case study from New South Wales, Australia**. Stuart RM, Abeysuriya RG, Kerr CC, Mistry D, Klein DJ, Gray R, Hellard M, Scott N (under review; posted 2020-09-03). *medRxiv* 2020.09.02.20186742; doi: https://doi.org/10.1101/2020.09.02.20186742.
5. **The role of masks, testing and contact tracing in preventing COVID-19 resurgences: a case study from New South Wales, Australia**. Stuart RM, Abeysuriya RG, Kerr CC, Mistry D, Klein DJ, Gray R, Hellard M, Scott N (in press; accepted 2021-03-19). *BMJ Open* doi: https://doi.org/10.1101/2020.09.02.20186742.

6. **Schools are not islands: Balancing COVID-19 risk and educational benefits using structural and temporal countermeasures**. Cohen JA, Mistry D, Kerr CC, Klein DJ (under review; posted 2020-09-10). *medRxiv* 2020.09.08.20190942; doi: https://doi.org/10.1101/2020.09.08.20190942.
6. **The potential contribution of face coverings to the control of SARS-CoV-2 transmission in schools and broader society in the UK: a modelling study**. Panovska-Griffiths J, Kerr CC, Waites W, Stuart RM, Mistry D, Foster D, Klein DJ, Viner R, Bonnell C (in press; accepted 2021-04-08). *Nature Scientific Reports* doi: https://doi.org/10.1101/2020.09.28.20202937.

7. **The potential contribution of face coverings to the control of SARS-CoV-2 transmission in schools and broader society in the UK: a modelling study**. Panovska-Griffiths J, Kerr CC, Waites W, Stuart RM, Mistry D, Foster D, Klein DJ, Viner R, Bonnell C (under review; posted 2020-10-08). *medRxiv* 2020.09.28.20202937; doi: https://doi.org/10.1101/2020.09.28.20202937.
7. **Schools are not islands: Balancing COVID-19 risk and educational benefits using structural and temporal countermeasures**. Cohen JA, Mistry D, Kerr CC, Klein DJ (under review; posted 2020-09-10). *medRxiv* 2020.09.08.20190942; doi: https://doi.org/10.1101/2020.09.08.20190942.

8. **COVID-19 reopening strategies at the county level in the face of uncertainty: Multiple Models for Outbreak Decision Support**. Shea K, Borchering RK, Probert WJM, et al. (under review; posted 2020-11-05). *medRxiv* 2020.11.03.20225409; doi: https://doi.org/10.1101/2020.11.03.20225409.

Expand Down Expand Up @@ -139,6 +139,7 @@ The structure of the ``covasim`` folder is as follows, roughly in the order in w
* ``people.py``: The ``People`` class, for handling updates of state for each person.
* ``population.py``: Functions for creating populations of people, including age, contacts, etc.
* ``interventions.py``: The ``Intervention`` class, for adding interventions and dynamically modifying parameters, and classes for each of the specific interventions derived from it.
* ``immunity.py``: The ``strain`` class, and functions for computing waning immunity and neutralizing antibodies.
* ``sim.py``: The ``Sim`` class, which performs most of the heavy lifting: initializing the model, running, and plotting.
* ``run.py``: Functions for running simulations (e.g. parallel runs and the ``Scenarios`` and ``MultiSim`` classes).
* ``analysis.py``: The ``Analyzers`` class (for performing analyses on the sim while it's running), the ``Fit`` class (for calculating the fit between the model and the data), the ``TransTree`` class, and other classes and functions for analyzing simulations.
Expand Down
1 change: 1 addition & 0 deletions covasim/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from .people import * # Depends on utils, defaults, base, plotting
from .population import * # Depends on people et al.
from .interventions import * # Depends on defaults, utils, base
from .immunity import * # Depends on utils, parameters, defaults
from .analysis import * # Depends on utils, misc, interventions
from .sim import * # Depends on almost everything
from .run import * # Depends on sim
10 changes: 5 additions & 5 deletions covasim/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def finalize(self, sim=None):
final operations after the simulation is complete (e.g. rescaling)
'''
if self.finalized:
raise Exception('Analyzer already finalized') # Raise an error because finalizing multiple times has a high probability of producing incorrect results e.g. applying rescale factors twice
raise RuntimeError('Analyzer already finalized') # Raise an error because finalizing multiple times has a high probability of producing incorrect results e.g. applying rescale factors twice
self.finalized = True
return

Expand Down Expand Up @@ -251,6 +251,7 @@ def from_sim(self, sim):


def initialize(self, sim):
super().initialize()

# Handle days
self.start_day = sc.date(sim['start_day'], as_date=False) # Get the start day, as a string
Expand Down Expand Up @@ -284,8 +285,6 @@ def initialize(self, sim):
self.data = self.datafile # Use it directly
self.datafile = None

self.initialized = True

return


Expand Down Expand Up @@ -434,6 +433,7 @@ def __init__(self, states=None, edges=None, **kwargs):


def initialize(self, sim):
super().initialize()

if self.states is None:
self.states = ['exposed', 'severe', 'dead', 'tested', 'diagnosed']
Expand All @@ -444,7 +444,7 @@ def initialize(self, sim):
self.bins = self.edges[:-1] # Don't include the last edge in the bins

self.start_day = sim['start_day']
self.initialized = True

return


Expand Down Expand Up @@ -591,6 +591,7 @@ def __init__(self, days=None, verbose=True, reporter=None, save_inds=False, **kw


def initialize(self, sim):
super().initialize()
if self.days is None:
self.days = sc.dcp(sim.tvec)
else:
Expand All @@ -599,7 +600,6 @@ def initialize(self, sim):
self.keys = ['exposed', 'infectious', 'symptomatic', 'severe', 'critical', 'known_contact', 'quarantined', 'diagnosed', 'recovered', 'dead']
self.basekeys = ['stocks', 'trans', 'source', 'test', 'quar'] # Categories of things to plot
self.extrakeys = ['layer_counts', 'extra']
self.initialized = True
return


Expand Down
Loading

0 comments on commit 9e94ccd

Please sign in to comment.