Skip to content

Commit

Permalink
Update the docs
Browse files Browse the repository at this point in the history
  • Loading branch information
kavir1698 committed Sep 1, 2022
1 parent 3dc1e0f commit 30a0515
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 105 deletions.
14 changes: 8 additions & 6 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# EvoDynamics.jl Documentation

EvoDynamics.jl tries to bridge the gap in studying biological systems at small and large scales. Some studies only focus on single genes affecting single phenotypes, some studies only analyze gene interactions, some focus on populations, and some on species interactions. EvoDynamics.jl is a framework to study the effect of interactions between all these levels. It includes explicit pleiotropy, epistasis, selection acting on multiple phenotypes, different phenotypes affecting fitness at different amounts, arbitrary spatial structure, migration, and interacting species.
EvoDynamics.jl is a framework to bridge the gap in studying biological systems at small and large scales. Specifically, it allows modeling biological dynamics at evolutionary and ecological scale. Genotypes affect phenotypes, and they interact with ecology (i.e. environment and other species). The flow of causal effect runs in both directions. Such changes affect adaptation, population demography, and species coexistence. Such eco-evolutionary feedbacks occur when the speed of evolution is fast; populations need to constantly adapt to changing conditions. This happens in antagonistic interactions between species (e.g. predator-prey or parasitism), competitive interactions, and mutualistic interactions.

Some studies only focus on single genes affecting single phenotypes, some studies only analyze gene interactions, some focus on populations, and some on species interactions. EvoDynamics.jl is a framework to study the effect of interactions between all these levels. It includes an explicit genotype-phenotype architecture (pleiotropy and epistasis), selection acting on multiple phenotypes, different phenotypes affecting fitness at different amounts, arbitrary spatial structure, migration, and interacting species.

Figure below shows different biological levels controlled by the model.

Expand All @@ -11,13 +13,13 @@ See [Tutorial](@ref) for running the model, and [Model description](@ref) for a
## Features

* Possibility to model complex food webs with various asymmetrical interactions.
* Individuals interact given their phenotypes.
* Individuals interact with one another and with the environment given their phenotypes.
* Connecting genome structure to phenotypes to populations.
* Space is a grid on which individuals can migrate.
* Possibility to model a complex environment with various amounts of resources at each site.
* Allows time varying optimal phenotypic value per site.
* Possibility of killing specific individuals at certain times and sites.
* Can model both haploid and diploid species.
* Possibility to model a complex environment with spatio-temporally varying resources.
* Allows time varying optimal phenotypic value per site per species.
* Possibility of killing individuals at certain times and sites.
* Modeling both haploid and diploid species.
* Includes mutation and recombination.
* Easy data collection.
* Runs replicates and collects data in a table automatically.
Expand Down
57 changes: 33 additions & 24 deletions docs/src/model_description.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/example1.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ using EvoDynamics
# :N => [100],
# :environmental_noise => 0.01,
# :optimal_phenotypes => [fill([1.5 for p in 1:1], space...) for t in 0:generations],
# :bottleneck_function => [fill(0.0, space...) for t in 0:generations],
# :bottlenecks => [fill(0.0, space...) for t in 0:generations],
# :age => 2,
# :recombination => 0,
# :initial_energy => 0,
Expand Down
138 changes: 80 additions & 58 deletions examples/example2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,15 @@
# Here we create a predator prey model of two species, one haploid and one diploid.

using EvoDynamics
using Plots

# Model parameters are in a .jl file as follows:

# ```julia
# ## 1. Functions

# function bn(agent::AbstractAgent, model::ABM)
# return false
# end

# function optphens2(site::Tuple{Int,Int}, model::ABM)
# opt1 = [0.8214794136627462, 0.49335401288317304, 0.3435556249656141, 0.25050033180075226]
# opt2 = opt1 .+ 0.1
# ss = EvoDynamics.coord2vertex(site, model)
# if model.step[1] > 6
# return [opt1[ss]]
# else
# return [opt2[ss]]
# end
# end

# function optphens3(site::Tuple{Int,Int}, model::ABM)
# phenotypic_values = [[0.7614758101208934 2.3911353663016586; 2.2091361414343313 1.7858661540288683; 0.7920974352892358 0.7630236717263839; 2.587205421882114 2.311211631439866],
# [0.6437641305315445 2.097629262577973; 0.9954545836033715 1.1314248848669466; 2.469792530385348 1.490299526620522; 1.6158867433451882 0.2566056477862022]]
# agent_site = (site[2] - 1) * size(model.space)[2] + (site[1])
# if model.step[1] > 7
# return phenotypic_values[1][agent_site, :]
# else
# return phenotypic_values[2][agent_site, :]
# end
# end

# env_resources2(time::Int) = [200 220; 183 190]

# ## 2. Species parameters
# generations = 14
# space = (2, 2)

# ## 1. Species parameters

# species1 = Dict(
# :name => "a",
Expand All @@ -47,26 +21,47 @@ using EvoDynamics
# :abiotic_phenotypes => [1],
# :biotic_phenotypes => [2, 3],
# :migration_phenotype => 4,
# :migration_threshold => 3.5,
# :migration_threshold => 1.5,
# :vision_radius => 1,
# :check_fraction => 0.5,
# :ploidy => 2,
# :epistasis_matrix => [1.0 0.43 -0.41 0.38 0.48 -0.43 -0.1 -0.08 -0.09 -0.5 0.41 0.44 -0.21 -0.12; 0.34 1.0 -0.19 -0.36 0.38 -0.28 0.24 -0.22 0.12 0.12 -0.12 -0.39 0.21 0.26; 0.05 0.27 1.0 0.04 0.01 -0.14 0.3 -0.28 0.43 -0.13 0.2 -0.02 0.25 -0.39; -0.12 0.33 -0.48 1.0 -0.4 -0.48 -0.22 -0.36 -0.24 -0.07 -0.12 -0.49 -0.37 0.27; 0.25 0.25 -0.14 0.49 1.0 0.28 -0.34 -0.49 0.45 -0.14 0.26 -0.13 -0.44 -0.17; -0.47 0.19 -0.24 0.41 0.08 1.0 0.11 0.03 0.15 0.49 0.04 0.41 -0.19 0.13; 0.37 0.09 -0.11 0.4 0.42 0.45 1.0 -0.01 -0.47 0.07 0.5 0.44 -0.18 -0.2; -0.32 0.15 0.4 -0.24 -0.21 0.5 0.22 1.0 -0.33 0.48 -0.49 0.07 0.5 -0.07; 0.02 -0.16 0.33 0.48 -0.42 0.39 0.2 -0.11 1.0 0.46 -0.06 0.22 -0.3 0.31; 0.41 -0.18 -0.16 -0.4 0.01 0.04 0.07 0.2 -0.37 1.0 -0.33 0.49 0.05 -0.42; 0.03 0.25 0.14 -0.36 0.28 -0.18 0.09 -0.2 0.46 -0.48 1.0 -0.21 0.41 -0.46; 0.0 0.44 -0.34 -0.42 0.37 -0.04 0.43 -0.25 0.21 0.19 0.29 1.0 -0.02 0.06; 0.46 -0.1 0.14 -0.22 -0.26 0.13 -0.5 -0.41 -0.31 0.0 -0.15 0.29 1.0 0.17; -0.22 0.21 0.46 -0.01 -0.35 -0.11 0.25 -0.03 0.18 -0.38 -0.4 -0.28 0.05 1.0],
# :pleiotropy_matrix => Bool[1 1 0 0 0 0 0 1 0 1 0 1 0 1; 1 0 1 1 1 0 1 1 1 0 0 1 1 0; 1 0 1 0 1 0 0 0 0 0 1 0 1 0; 0 0 0 0 1 0 0 1 1 1 1 0 1 0],
# :growth_rate => 0.8,
# :epistasis_matrix => [
# 1.0 0.43 -0.41 0.38 0.48 -0.43 -0.1 -0.08 -0.09 -0.5 0.41 0.44 -0.21 -0.12
# 0.34 1.0 -0.19 -0.36 0.38 -0.28 0.24 -0.22 0.12 0.12 -0.12 -0.39 0.21 0.26
# 0.05 0.27 1.0 0.04 0.01 -0.14 0.3 -0.28 0.43 -0.13 0.2 -0.02 0.25 -0.39
# -0.12 0.33 -0.48 1.0 -0.4 -0.48 -0.22 -0.36 -0.24 -0.07 -0.12 -0.49 -0.37 0.27
# 0.25 0.25 -0.14 0.49 1.0 0.28 -0.34 -0.49 0.45 -0.14 0.26 -0.13 -0.44 -0.17
# -0.47 0.19 -0.24 0.41 0.08 1.0 0.11 0.03 0.15 0.49 0.04 0.41 -0.19 0.13
# 0.37 0.09 -0.11 0.4 0.42 0.45 1.0 -0.01 -0.47 0.07 0.5 0.44 -0.18 -0.2
# -0.32 0.15 0.4 -0.24 -0.21 0.5 0.22 1.0 -0.33 0.48 -0.49 0.07 0.5 -0.07
# 0.02 -0.16 0.33 0.48 -0.42 0.39 0.2 -0.11 1.0 0.46 -0.06 0.22 -0.3 0.31
# 0.41 -0.18 -0.16 -0.4 0.01 0.04 0.07 0.2 -0.37 1.0 -0.33 0.49 0.05 -0.42
# 0.03 0.25 0.14 -0.36 0.28 -0.18 0.09 -0.2 0.46 -0.48 1.0 -0.21 0.41 -0.46
# 0.0 0.44 -0.34 -0.42 0.37 -0.04 0.43 -0.25 0.21 0.19 0.29 1.0 -0.02 0.06
# 0.46 -0.1 0.14 -0.22 -0.26 0.13 -0.5 -0.41 -0.31 0.0 -0.15 0.29 1.0 0.17
# -0.22 0.21 0.46 -0.01 -0.35 -0.11 0.25 -0.03 0.18 -0.38 -0.4 -0.28 0.05 1.0],
# :pleiotropy_matrix => Bool[
# 1 1 0 0 0 0 0 1 0 1 0 1 0 1
# 1 0 1 1 1 0 1 1 1 0 0 1 1 0
# 1 0 1 0 1 0 0 0 0 0 1 0 1 0
# 0 0 0 0 1 0 0 1 1 1 1 0 1 0],
# :growth_rate => 2.8,
# :expression_array => [0.28878032859775615, 0.4629421231828499, 0.26092147517051467, 0.952859489607121, 0.9638502824424, 0.05038142018016245, 0.05930756376654234, 0.033459292878885716, 0.32421526342800044, 0.9029235877297073, 0.7670060809312949, 0.12766808941531993, 0.8656895869985795, 0.342191940658253],
# :selection_coefficient => 0.5,
# :selection_coefficient => 0.1,
# :mutation_probabilities => [0.9, 0.0, 0.0],
# :mutation_magnitudes => [0.05, 0.0, 0.01],
# :N => [1000, 0, 0, 0],
# :environmental_noise => 0.01,
# :optimal_phenotypes => optphens2,
# :bottleneck_function => bn,
# :optimal_phenotypes => [fill([1.4 for p in 1:1], space...) for t in 0:generations],
# :bottlenecks => [fill(0.0, space...) for t in 0:generations],
# :age => 5,
# :recombination => 1,
# :initial_energy => 0,
# :reproduction_start_age => 1,
# :initial_energy => 1,
# :reproduction_start_age => 2,
# :reproduction_end_age => 5,
# :abiotic_variance => 1.0,
# :biotic_variance => 1.0,
# :mating_scheme => 0
# )

# species2 = Dict(
Expand All @@ -76,45 +71,72 @@ using EvoDynamics
# :abiotic_phenotypes => [1, 2],
# :biotic_phenotypes => [3, 4],
# :migration_phenotype => 5,
# :migration_threshold => 3.4,
# :migration_threshold => 1.4,
# :vision_radius => 1,
# :check_fraction => 0.5,
# :ploidy => 1,
# :epistasis_matrix => [1.0 -0.01 -0.01 -0.34 -0.42 0.18 -0.09 0.13; 0.28 1.0 -0.21 -0.11 0.12 -0.46 0.21 -0.39; 0.0 0.28 1.0 0.1 0.09 0.3 0.1 0.17; 0.0 -0.42 0.05 1.0 -0.11 -0.07 -0.27 0.43; 0.31 0.47 -0.42 -0.34 1.0 -0.4 0.16 0.11; -0.19 0.29 -0.33 -0.49 0.17 1.0 -0.1 -0.28; -0.43 0.38 -0.06 0.39 0.21 -0.5 1.0 -0.08; 0.26 0.27 -0.44 -0.08 0.47 -0.27 -0.27 1.0],
# :pleiotropy_matrix => Bool[1 0 0 0 1 1 0 0; 1 0 0 1 1 0 1 1; 0 1 1 1 1 1 0 1; 1 0 1 0 0 1 0 1; 1 1 0 1 1 1 1 1],
# :growth_rate => 1.2,
# :epistasis_matrix => [
# 1.0 -0.01 -0.01 -0.34 -0.42 0.18 -0.09 0.13
# 0.28 1.0 -0.21 -0.11 0.12 -0.46 0.21 -0.39
# 0.0 0.28 1.0 0.1 0.09 0.3 0.1 0.17
# 0.0 -0.42 0.05 1.0 -0.11 -0.07 -0.27 0.43
# 0.31 0.47 -0.42 -0.34 1.0 -0.4 0.16 0.11
# -0.19 0.29 -0.33 -0.49 0.17 1.0 -0.1 -0.28
# -0.43 0.38 -0.06 0.39 0.21 -0.5 1.0 -0.08
# 0.26 0.27 -0.44 -0.08 0.47 -0.27 -0.27 1.0],
# :pleiotropy_matrix => Bool[
# 1 0 0 0 1 1 0 0
# 1 0 0 1 1 0 1 1
# 0 1 1 1 1 1 0 1
# 1 0 1 0 0 1 0 1
# 1 1 0 1 1 1 1 1],
# :growth_rate => 1.5,
# :expression_array => [0.24923147816626035, 0.7155732641738595, 0.9655184311211502, 0.8638149724268844, 0.5075272565823061, 0.9189652626508431, 0.7897640036022151, 0.17091233765481717],
# :selection_coefficient => 0.5,
# :selection_coefficient => 0.1,
# :mutation_probabilities => [0.9, 0.0, 0.0],
# :mutation_magnitudes => [0.05, 0.0, 0.01],
# :N => [1000, 0, 0, 0],
# :N => [100, 0, 0, 0],
# :environmental_noise => 0.01,
# :optimal_phenotypes => optphens3,
# :bottleneck_function => bn,
# :optimal_phenotypes => [fill([1.4, 1.6], space...) for t in 0:generations],
# :bottlenecks => [fill(0.0, space...) for t in 0:generations],
# :age => 3,
# :recombination => 1,
# :recombination => 0,
# :initial_energy => 0,
# :reproduction_start_age => 1,
# :reproduction_end_age => 3,
# :abiotic_variance => 1.0,
# :biotic_variance => 2.0,
# :mating_scheme => 0
# )

# ## 3. Model parameters
# ## 2. Model parameters

# #NB this dict should be called model_parameters
# #NB this dictionary should be called model_parameters
# model_parameters = Dict(
# :species => [species1, species2],
# :generations => 14,
# :space => (2, 2),
# :generations => generations,
# :space => space,
# :metric => "chebyshev",
# :periodic => false,
# :resources => env_resources2,
# :interactions => [0.1 0.0; 0.0 -1.0],
# :food_sources => [1.0 0.5; 0.0 0.0],
# :seed => nothing

# :resources => [
# [2000 2200
# 1830 1900] for i in 0:generations],

# :interactions => [0.0 1.0
# 1.0 0.0],

# :food_sources => [1.0 0.0
# 1.0 0.0],

# :seed => 32
# )
# ```

param_file = "../../examples/paramfile2.jl" #hide
agentdata, modeldata, model = runmodel(param_file);

modeldata
modeldata

plot(1:size(modeldata, 1), getindex.(modeldata[:, 3], 1), xlabel="Time", ylabel="N", label="Prey")
plot!(1:size(modeldata, 1), getindex.(modeldata[:, 3], 2), label="Predator")
2 changes: 1 addition & 1 deletion examples/paramfile1.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ species1 = Dict(
:N => [100],
:environmental_noise => 0.01,
:optimal_phenotypes => [fill([1.5 for p in 1:1], space...) for t in 0:generations],
:bottleneck_function => [fill(0.0, space...) for t in 0:generations],
:bottlenecks => [fill(0.0, space...) for t in 0:generations],
:age => 2,
:recombination => 0,
:initial_energy => 0,
Expand Down
12 changes: 6 additions & 6 deletions examples/paramfile2.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
generations = 14
generations = 30
space = (2, 2)

## 1. Species parameters
Expand Down Expand Up @@ -44,7 +44,7 @@ species1 = Dict(
:N => [1000, 0, 0, 0],
:environmental_noise => 0.01,
:optimal_phenotypes => [fill([1.4 for p in 1:1], space...) for t in 0:generations],
:bottleneck_function => [fill(0.0, space...) for t in 0:generations],
:bottlenecks => [fill(0.0, space...) for t in 0:generations],
:age => 5,
:recombination => 1,
:initial_energy => 1,
Expand Down Expand Up @@ -91,14 +91,14 @@ species2 = Dict(
:N => [100, 0, 0, 0],
:environmental_noise => 0.01,
:optimal_phenotypes => [fill([1.4, 1.6], space...) for t in 0:generations],
:bottleneck_function => [fill(0.0, space...) for t in 0:generations],
:bottlenecks => [fill(0.0, space...) for t in 0:generations],
:age => 3,
:recombination => 0,
:initial_energy => 0,
:reproduction_start_age => 1,
:reproduction_end_age => 3,
:abiotic_variance => 1.0,
:biotic_variance => 1.0,
:biotic_variance => 2.0,
:mating_scheme => 0
)

Expand All @@ -119,7 +119,7 @@ model_parameters = Dict(
1.0 0.0],

:food_sources => [1.0 0.0;
2.5 0.0],
1.0 0.0],

:seed => nothing
:seed => 32
)
4 changes: 2 additions & 2 deletions src/check_params.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function check_param_names(d)
species_keys = [:name, :number_of_genes, :number_of_phenotypes, :abiotic_phenotypes, :biotic_phenotypes, :migration_phenotype, :migration_threshold, :ploidy, :epistasis_matrix, :pleiotropy_matrix, :growth_rate, :expression_array, :selection_coefficient, :mutation_probabilities, :mutation_magnitudes, :N, :vision_radius, :check_fraction, :environmental_noise, :optimal_phenotypes, :age, :recombination, :initial_energy, :bottleneck_function, :reproduction_start_age, :reproduction_end_age, :abiotic_variance, :biotic_variance, :mating_scheme]
species_keys = [:name, :number_of_genes, :number_of_phenotypes, :abiotic_phenotypes, :biotic_phenotypes, :migration_phenotype, :migration_threshold, :ploidy, :epistasis_matrix, :pleiotropy_matrix, :growth_rate, :expression_array, :selection_coefficient, :mutation_probabilities, :mutation_magnitudes, :N, :vision_radius, :check_fraction, :environmental_noise, :optimal_phenotypes, :age, :recombination, :initial_energy, :bottlenecks, :reproduction_start_age, :reproduction_end_age, :abiotic_variance, :biotic_variance, :mating_scheme]
model_keys = [:species, :generations, :space, :metric, :periodic, :resources, :interactions, :food_sources, :seed]
species = d[:species]
for sp in species
Expand Down Expand Up @@ -41,7 +41,7 @@ function check_param_shapes(d)
@assert typeof(dd[:recombination]) <: Real "recombination of species $spname should be type numeric"
@assert typeof(dd[:initial_energy]) <: Real "Initial energy should be a number"
# bottleneck should be nothing or array/string
@assert typeof(dd[:bottleneck_function]) <: AbstractArray || isnothing(dd[:bottleneck_function]) "bottleneck function for species $spname is not an `Array` or `nothing`"
@assert typeof(dd[:bottlenecks]) <: AbstractArray || isnothing(dd[:bottlenecks]) "bottleneck function for species $spname is not an `Array` or `nothing`"
@assert typeof(dd[:selection_coefficient]) <: AbstractFloat "selection coefficient of species $spname should be floating point number"
@assert typeof(dd[:migration_threshold]) <: AbstractFloat "migration_threshold of species $spname should be floating point number"
@assert typeof(dd[:abiotic_variance]) <: AbstractFloat "Species $spname: abiotic variance should be a floating number"
Expand Down
2 changes: 1 addition & 1 deletion src/reproduction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ end

"""
Sexual reproduction for diploid individuals.
Whether it is assortative or dissortative depends on the sign of the corresponding element in the interaction matrix.
Whether it is assortative or disassortative depends on the sign of the corresponding element in the interaction matrix.
"""
function reproduce!(ag1::Ind, ag2::Ind, model::ABM)
if model.mating_schemes[ag1.species] == 0.0
Expand Down
2 changes: 1 addition & 1 deletion src/simulation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ function create_properties(dd)
names = Dict(i => allspecies[i][:name] for i in 1:nspecies)
recombination = [Poisson(allspecies[i][:recombination]) for i in 1:nspecies]
initial_energy = [AbstractFloat(allspecies[i][:initial_energy]) for i in 1:nspecies]
bottlenecks = [allspecies[i][:bottleneck_function] for i in 1:nspecies]
bottlenecks = [allspecies[i][:bottlenecks] for i in 1:nspecies]
repro_start = [allspecies[i][:reproduction_start_age] for i in 1:nspecies]
repro_end = [allspecies[i][:reproduction_end_age] for i in 1:nspecies]
resources = dd[:resources][1]
Expand Down
Loading

0 comments on commit 30a0515

Please sign in to comment.