You can run a single simulation using main-sweep.jl
, with a single argument giving the location of the parameters file in JSON format, like this:
julia /simulation/src/main-sweep.jl parameters.json
An example parameters file is in simulation/src/parameters.json
.
To sweep across many parameter values, you'll want to write a script to generate a working directory for each simulation, containing a parameters file for that simulation and perhaps also a script that submits the simulation to the cluster.
An example of this script is /simulation/generate-sweep.jl
, which calls a JSON file designating the parameter intervals (sweep-parameters.json
). This script is written for a cluster operating with SLURM. Number of processes, cores and jobs can be customized. Run
julia /simulation/generate-sweep.jl
Working directories for each simulation and sbatch script will be generated, along with a shell script that submits jobs.
The model is a stochastic, continuous-time, discrete-event simulation (Gillespie-style) that steps from event to event, with a random amount of time, real-valued, between events.
Model state is represented by the State
struct, which contains two fields, bstrains
, of type BStrains
, and vstrains
, of type VStrains
.
The BStrains
and VStrains
structs are very similar.
Conceptually, they represent a collection of bacterial/viral strains, and although it would make conceptual sense to just have bstrains::Vector{BStrain}
, for efficiency of memory layout they are implemented using parallel arrays.
Each step follows this algorithm:
- The time to the next event is computed by drawing a waiting time from a Poisson process whose rate is the total rate of all possible events in the system.
- The type of event is chosen proportional to the total rate of all events of that type (e.g., all possible bacterial growth events).
- For each event type, the specific event is chosen by sampling proportional to the rates of the individual events. For example, for bacterial growth events, since bacterial cells grow at the same rate, the growth rate of particular strain is proportional to the abundance of that strain, and therefore a strain is chosen proportional to its abundance.
- The event is executed.
There are four events:
- Microbial growth:
const MICROBIAL_GROWTH = 1
- Microbial death:
const MICROBIAL_DEATH = 2
- Viral decay:
const VIRAL_DECAY = 3
- Contact:
const CONTACT = 4
- Bacterial immigration:
const MICROBIAL_IMMIGRATION = 5
- Randomly select a bacterial strain and a viral strain proportional to population size
- If immune, infect with probability p_crispr_failure_prob
- If not immune, defend successfully & acquire spacer with prob q_spacer_acquisition_prob
Infect:
- Draw the number of mutations for each of
beta
newly created virus particles; the number isBinomial(n_pspacers, mu)
. - Unmutated virus particles just increase the abundance of the existing viral strain.
- Mutated virus particles acquire newly created protospacers at randomly selected loci.
Please download analysis data (DOI 10.6084/m9.figshare.25254565), and put contents of the folder into a directory named generated-data
. This directory should be in the same containing directory as isolated-runs
, simulation
, etc.
Run the following
python /isolated-runs/tree-figure.py
Run the following
python /isolated-runs/analyses-figures.py host-strain-collapses
Run the following
python /isolated-runs/analyses-figures.py protospacer-div
Run the following
python /isolated-runs/triartitegraph.py
Run the following
python /isolated-runs/analyses-figures.py R
Run the following
python /isolated-runs/make-phase-diagrams.py
Run the following
python /isolated-runs/analyses-figures.py diversity
Run the following
python /isolated-runs/analyses-figures.py viralheatmap
Run the following
python /isolated-runs/analyses-figures.py escapeheatmap
Run the following
python /isolated-runs/analyses-figures.py escapeheatmap