ContDisease
— Contagious Diseases#
This is a simple model of a contagious disease on a 2D grid.
Fundamentals#
We model a “forest” on a two-dimensional square grid of cells. Each cell can be in one of five different states: empty, tree, infected, source, or stone.
Implementation#
Update Rules#
In each time step, the cells update their respective states according to the following rules:
An
infected
cell turns into anempty
cell.An
empty
cell can become atree
cell with probabilityp_growth
.A
tree
cell can become infected in the following ways:from a neighboring infected cell with probability 1-
p_immunity
per neighbor,via a random point infection with probability
p_infect
,via a constantly infected cell, an infection
source
.
For the neighborhood, both the von Neumann neighborhood (5-neighborhood) and the Moore neighborhood (9-neighborhood) are supported (see model configuration).
Heterogeneities#
As in the Forest Fire model, there is the possibility to introduce heterogeneities into the grid, which are implemented as two additional possible cell states:
source
: these are constant infection sources. They spread infection like normal infected trees, but don not revert back to the empty state. If activated, they are per default on the lower boundary of the grid, though this can be changed in the configuration.stone
: stones are cells that can not be infected nor turn into trees. They are used to represent barriers in the forest. If enabled, the default mode isclustered_simple
, which leads to randomly distributed stones whose neighbours have a certain probability to also be a stone.
Both make use of the entity selection interface.
Infection Control#
Via the infection_control
parameter in the model configuration, additional infections can be introduced at desired times. The infections are introduced before the update rule above is carried out.
Data Output#
The following data is stored alongside the simulation:
kind
: the state of each cell. Possible values:0
:empty
1
:tree
2
:infected
3
:source
, is constantly ignited4
:stone
, does not take part in any interaction
age
: the age of each tree, reset after lightning strikescluster_id
: a number identifying to which cluster a cell belongs;0
for non-tree cellsdensities
: the densities of each of the kind of cells over time; this is a labeled 2D array with the dimensionstime
andkind
.
Default configuration parameters#
Below are the default configuration parameters for the ContDisease
model.
# --- Space parameters --------------------------------------------------------
# The physical space this model is embedded in
space:
periodic: false
# --- CellManager and cell initialization -------------------------------------
cell_manager:
grid:
structure: square
resolution: 64 # in cells per unit length of physical space
neighborhood:
mode: vonNeumann
# Cell initialization parameters
cell_params:
# Initial tree density, value in [0, 1]
# With this probability, a cell is initialized as tree (instead of empty)
p_tree: !is-probability 0
# --- Model Dynamics ----------------------------------------------------------
# Probability per site and time step to transition from state empty to tree
p_growth: !is-probability 7.5e-3
# Probability per site and time step for a tree cell to not become infected if
# an infected cell is in the neighborhood. This probability applies per event
# so it does _not_ mean that an immune cell is also immune in the next
# iteration step
p_immunity: !is-probability 0.
# Probability per site and time step for a random point infection of a tree
p_infect: !is-probability 0.
# NOTE This is affected by the infection control, see below.
# --- Infection Control -------------------------------------------------------
# Infection control to investigate the time-dependent influence of the
# disease driving force. Note that infection control is applied at the
# beginning of an iteration step. It's effect is seen in the following
# time step
infection_control:
enabled: !is-bool false
# The number of additional infections to be placed on the grid
num_additional_infections: !is-unsigned 10
# Add the additional infections at the given times
# Note the the !listgen tag creates a list from the parameters
# (start, stop, step_size)
# To disable, pass an empty sequence.
at_times: !listgen [0, 100, 20]
# Change the probability of a random infection.
# The expected value is a list of [iteration_step, new_value] pairs, e.g.
# - [10, .5]
# - [42, 0.]
# ... will set p_infect from the default value to .5 at time 10 and set it
# back to 0. at time 42.
# To disable, pass an empty sequence.
change_p_infect: []
# --- Heterogeneities ---------------------------------------------------------
# Some cells can be permanently infected or turned into stones.
# Both these features are using the `select_entities` interface; consult the
# documentation regarding information on available selection modes.
# Turn some cells into stones: these do not take part in any of the processes
stones:
enabled: !is-bool false
mode: clustered_simple
# Clustering parameters
# Probability with which a cell is a cluster seed
p_seed: !is-probability .02
# Attachment probability (per neighbor)
p_attach: !is-probability .1
num_passes: !is-unsigned 5 # How many attachment procedures to perform
# Set some cells to be permanently infected (invoked after stones are set)
infection_source:
enabled: !is-bool true
mode: boundary
# Boundary selection parameters (requires space to be set to NON-periodic!)
boundary: bottom
# --- Output Configuration ----------------------------------------------------
# Whether to only write out the densities; useful for runs on large grids
# where spatial information is not needed.
write_only_densities: !is-bool false
Available plots#
The following plot configurations are available for the ContDisease
model:
Default Plot Configuration#
# --- Densities time series ---------------------------------------------------
densities:
enabled: false
based_on: densities.universe
densities_facet_grid:
based_on: densities.multiverse
# --- Phase plot of two densities ---------------------------------------------
phase_diagram:
based_on: phase_diagram
# Select from what densities to create the phase diagram
x: tree
y: infected
hue: time
helpers:
set_labels:
x: Tree Density [1/A]
y: Infected Density [1/A]
set_title:
title: Phase Diagram
cmap: viridis_r
# Parameters that are passed on to plt.scatter
s: 10
# --- Snapshots and animations of the spatial grid ----------------------------
# The snapshot plots show the final state of the CA or, more precisely, the
# last written time step. To adjust these, set the `frames_isel` parameter.
# ... The forest ..............................................................
ca/forest:
based_on: ca/forest
enabled: false
ca/forest_snapshot:
based_on:
- ca/forest
- .plot.ca.snapshot
# ... The forest age ..........................................................
ca/forest_age:
based_on: ca/forest_age
enabled: false
ca/forest_age_snapshot:
based_on:
- ca/forest_age
- .plot.ca.snapshot
# ... The clusters ............................................................
ca/clusters:
based_on: ca/clusters
enabled: false
ca/clusters_snapshot:
based_on:
- ca/clusters
- .plot.ca.snapshot
# ... Combined plot of forest states and clusters .............................
ca/combined:
based_on: ca/combined
ca/combined_snapshot:
based_on:
- ca/combined
- .plot.ca.snapshot
Base Plot Configuration#
.variables:
base_path: &base_path data/ContDisease
colors: &cmap # state value
# NOTE Order is very important here!
empty: &color_empty darkkhaki # 0
tree: &color_tree forestgreen # 1
infected: &color_infected firebrick # 2
source: &color_source orange # 3
stone: &color_stone slategray # 4
cycler: &cycler !format
fstr: "cycler('color', ['{cmap[empty]:}', '{cmap[tree]:}', '{cmap[infected]:}', '{cmap[source]:}', '{cmap[stone]:}'])"
cmap:
<<: *cmap
# =============================================================================
# ╔╦╗╔═╗╔╦╗╔═╗╦ ╔═╗╔╦╗╔═╗╔═╗
# ║ ║╣ ║║║╠═╝║ ╠═╣ ║ ║╣ ╚═╗
# ╩ ╚═╝╩ ╩╩ ╩═╝╩ ╩ ╩ ╚═╝╚═╝
# =============================================================================
# -- Overloads ----------------------------------------------------------------
# Overload some configs to insert model-specific settings
# Model-specific defaults
.defaults:
based_on: .defaults
# Can define something here ...
# .. Creators .................................................................
.creator.universe:
based_on:
- .creator.universe
- .defaults
dag_options:
select_path_prefix: *base_path
.creator.multiverse:
based_on:
- .creator.multiverse
- .defaults
select_and_combine:
base_path: *base_path
# =============================================================================
# ╔═╗╦ ╔═╗╔╦╗╔═╗
# ╠═╝║ ║ ║ ║ ╚═╗
# ╩ ╩═╝╚═╝ ╩ ╚═╝
# =============================================================================
# -- Any kind of phase plot ---------------------------------------------------
phase_diagram:
based_on:
- .creator.universe
- .plot.facet_grid.scatter
select:
kind:
path: densities
transform:
- .sel: [ !dag_tag kind, { kind: tree } ]
kwargs: { drop: true }
tag: tree
- .sel: [ !dag_tag kind, { kind: infected } ]
kwargs: { drop: true }
tag: infected
- xr.Dataset:
data_vars:
tree: !dag_tag tree
infected: !dag_tag infected
tag: data
# -- Densities plot -----------------------------------------------------------
densities.base:
based_on:
- .plot.facet_grid.line
- .hlpr.kind.time_series
x: time
hue: kind
style:
axes.prop_cycle: *cycler
helpers:
set_limits:
y: [0., 1.]
set_labels:
y: Density [1/A]
only_label_outer: true
set_suptitle:
title: Densities
set_legend:
loc: best
densities.universe:
based_on:
- .creator.universe
- densities.base
select:
data:
path: densities
transform:
- .data
densities.multiverse:
based_on:
- .creator.multiverse
- .skip.if_more_than_3D
- densities.base
- .plot.facet_grid.with_auto_encoding
- .plot.facet_grid.errorbands
- .hlpr.legend.hide
- .animation.disabled
select_and_combine:
fields:
_data:
path: densities
transform:
- .data
transform:
- xr.full_like: [!dag_tag _data, !expr nan]
tag: nans
# Try to compute mean and std over ceratain dimensions, falling back to
# a NaN array if that dimension is not available
- .mean: [!dag_tag _data, seed]
allow_failure: silent
fallback: !dag_tag _data
tag: mean
- .std: [!dag_tag _data, seed]
allow_failure: silent
fallback: !dag_tag nans # use NaN instead
tag: std
# Combine into a dataset
- xr.Dataset:
data_vars:
mean: !dag_tag mean
std: !dag_tag std
tag: data
y: mean
yerr: std
x: time
hue: kind
# --- Grid Snapshots ----------------------------------------------------------
# NOTE These can also be used as basis for grid animations.
# ... The forest ..............................................................
ca/forest:
based_on:
- .creator.universe
- .plot.ca
select:
kind: kind
to_plot:
kind:
title: Forest State
cmap: *cmap
# ... The forest age ..........................................................
ca/forest_age:
based_on:
- .creator.universe
- .plot.ca
select:
age: age
to_plot:
age:
title: Forest Age
cmap: YlGn
vmin: 0
vmax: max
# ... The clusters ............................................................
ca/clusters:
based_on:
- .creator.universe
- .plot.ca
select:
cluster_id:
path: cluster_id
transform:
- where: [!dag_prev , "!=", 0] # not part of the cluster
- np.fmod: [!dag_prev , 20] # matching the size of the tab20 cmap
# NOTE Important to use np.fmod here because it carries through the
# container attributes, which are needed for determining the
# grid structure. The `mod` operation itself does not do that.
to_plot:
cluster_id:
title: Clusters
cmap: tab20
vmin: 0
vmax: 20
no_cbar_markings: true
# ... Combined plot of forest states and clusters .............................
ca/combined:
based_on:
- ca/forest
- ca/forest_age
- ca/clusters
# col_wrap: false
For available base plots, see Base Plot Configuration Pool.
References#
Kurt Roth: Chaotic, Complex, and Evolving Environmental Systems. Unpublished lecture notes, University of Heidelberg, 2018.