Public documentation
Documentation for EcologicalNetworksDynamics.jl public interface.
Index
EcologicalNetworksDynamics.Foodweb
EcologicalNetworksDynamics.Model
EcologicalNetworksDynamics.Species
EcologicalNetworksDynamics.default_model
EcologicalNetworksDynamics.persistence
EcologicalNetworksDynamics.persistence
EcologicalNetworksDynamics.richness
EcologicalNetworksDynamics.richness
EcologicalNetworksDynamics.shannon_diversity
EcologicalNetworksDynamics.shannon_diversity
EcologicalNetworksDynamics.total_biomass
EcologicalNetworksDynamics.total_biomass
Public Interface
Functions
EcologicalNetworksDynamics.default_model
— Methoddefault_model(
foodweb::Foodweb;
kwargs...
)
Generate a model from a food web with parameters set to default values.
Let's first illustrate the use of default_model
with a simple example.
foodweb = Foodweb([1 => 2])
default_model(foodweb)
In this example, all parameters are set to default values, however for your needs, you can override any of the default parameters. For instance, if you want to override the default metabolic rate, you can do it as follows:
my_x = [0.0, 1.2] # One value per species.
default_model(foodweb, Metabolism(my_x))
EcologicalNetworksDynamics.persistence
— Methodpersistence(vec::AbstractVector; threshold = 0)
Fraction of alive species given a biomass vector vec
. See richness
for details.
EcologicalNetworksDynamics.persistence
— Methodpersistence(solution::AbstractODESolution; threshold = 0)
Fraction of alive species at each timestep of the simulation. See richness
for details.
Examples
julia> S = 20 # Initial number of species.
foodweb = Foodweb(:niche; S = 20, C = 0.1)
m = default_model(foodweb)
B0 = rand(S)
sol = simulate(m, B0)
all(persistence(sol) .== richness(sol) / S)
true
EcologicalNetworksDynamics.richness
— Methodrichness(vec::AbstractVector; threshold = 0)
Return the number of alive species given a biomass vector vec
. By default, species are considered extinct if their biomass is 0. But, this threshold
can be changed using the corresponding keyword argument.
Examples
julia> foodweb = Foodweb([0 0; 1 0])
m = default_model(foodweb)
B0 = [0.5, 0.5]
sol = simulate(m, B0)
richness(sol[end]) # Richness at the end of the simulation.
2.0
EcologicalNetworksDynamics.richness
— Methodrichness(solution::Solution; threshold = 0)
Return the number of alive species at each timestep of the simulation. solution
is the output of simulate
. By default, species are considered extinct if their biomass is 0. But, this threshold
can be changed using the corresponding keyword argument.
Examples
Let's start with a simple example where the richness remains constant:
julia> foodweb = Foodweb([0 0; 1 0])
m = default_model(foodweb)
B0 = [0.5, 0.5]
sol = simulate(m, B0)
richness_trajectory = richness(sol)
all(richness_trajectory .== 2) # At each timestep, there are 2 alive species.
true
Now let's assume that the producer is extinct at the beginning of the simulation, while its consumer is not. We expect to observe a decrease in richness from 1 to 0 over time.
julia> B0 = [0, 0.5] # The producer is extinct at the beginning.
sol = simulate(m, B0)
richness_trajectory = richness(sol)
richness_trajectory[1] == 1 && richness_trajectory[end] == 0
true
EcologicalNetworksDynamics.shannon_diversity
— Methodshannon_diversity(vec::AbstractVector; threshold = 0)
Shannon diversitty index given a biomass vector `vec Shannon diversity is a measure of species diversity based on the entropy. According to the Shannon index, for a same number of species, the more evenly the biomass is distributed among them, the higher the diversity.
Example
We consider a simple example with 3 species, but different shannon diversity.
julia> s1 = shannon_diversity([1, 1, 1])
s2 = shannon_diversity([1, 1, 0.1])
s3 = shannon_diversity([1, 1, 0.01])
s1 > s2 > s3
true
We observe as we decrease the biomass of the third species, the shannon diversity tends to 2, as we tend towards an effective two-species community.
EcologicalNetworksDynamics.shannon_diversity
— Methodshannon_diversity(solution::AbstractODESolution; threshold = 0)
Shannon diversity index at each timestep of the simulation. solution
is the output of simulate
. Shannon diversity is a measure of species diversity based on the entropy. According to the Shannon index, for a same number of species, the more evenly the biomass is distributed among them, the higher the diversity.
Example
We start a simple simulation with even biomass distribution, therefore we expect the Shannon diversity to decrease over time as the biomass of the species diverge from each other.
julia> foodweb = Foodweb([0 0; 1 0])
m = default_model(foodweb)
B0 = [0.5, 0.5] # Even biomass, maximal shannon diversity.
sol = simulate(m, B0)
shannon_trajectory = shannon_diversity(sol)
biomass_trajectory[1] > biomass_trajectory[end]
true
EcologicalNetworksDynamics.total_biomass
— Methodtotal_biomass(vec::AbstractVector)
Total biomass of a community given a biomass vector vec
.
Examples
julia> total_biomass([0.5, 1.5]) # 0.5 + 1.5 = 2.0
2.0
EcologicalNetworksDynamics.total_biomass
— Methodtotal_biomass(solution::AbstractODESolution)
Total biomass of a community at each timestep of the simulation. solution
is the output of simulate
.
Example
Let's consider a consumer feeding on a producer, and let's start the simulation with the producer extinction so we can observe the consumer's biomass decrease over time.
julia> foodweb = Foodweb([0 0; 1 0])
m = default_model(foodweb)
B0 = [0, 0.5] # The producer is extinct at the beginning.
sol = simulate(m, B0)
biomass_trajectory = total_biomass(sol)
biomass_trajectory[1] == 0.5 && biomass_trajectory[end] == 0
true
Types
EcologicalNetworksDynamics.Foodweb
— TypeThe Foodweb component, aka. "Trophic layer", adds a set of trophic links connecting species in the model. This is one of the most structuring components.
Blueprint Creation from Raw Links.
From an adjacency list:
julia> fw = Foodweb([:a => :b, :b => [:c, :d]])
blueprint for Foodweb with 2 trophic links:
A:
:a eats :b
:b eats :c and :d
julia> Model(fw) # Automatically brings a 'Species' component.
Model with 2 components:
- Species: 4 (:a, :b, :c, :d)
- Foodweb: 3 links
julia> Model(Foodweb([4 => [2, 1], 2 => 1])) # From species indices.
Model with 2 components:
- Species: 4 (:s1, :s2, :s3, :s4)
- Foodweb: 3 links
From a matrix:
julia> fw = Foodweb([0 0 1; 1 0 1; 0 0 0])
blueprint for Foodweb with 3 trophic links:
A: 3×3 SparseArrays.SparseMatrixCSC{Bool, Int64} with 3 stored entries:
⋅ ⋅ 1
1 ⋅ 1
⋅ ⋅
julia> Model(fw)
Model with 2 components:
- Species: 3 (:s1, :s2, :s3)
- Foodweb: 3 links
Blueprint Creation from Random Models.
Cascade model: specify the desired number of species S
and connectance C
.
julia> using Random
Random.seed!(12)
fw = Foodweb(:cascade; S = 5, C = 0.2)
blueprint for Foodweb with 5 trophic links:
A: 5×5 SparseArrays.SparseMatrixCSC{Bool, Int64} with 5 stored entries:
⋅ 1 ⋅ 1 1
⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ 1 ⋅
⋅ ⋅ ⋅ ⋅ 1
⋅ ⋅ ⋅ ⋅ ⋅
Random foodwebs are drawn until the desired connectance is obtained, within a tolerance level defaulted to tol_C = 0.1 * C
, modifiable as a keyword argument.
Niche model: either specify the connectance C
or number of links L
.
julia> fw = Foodweb(:niche; S = 5, C = 0.2) # From connectance.
blueprint for Foodweb with 5 trophic links:
A: 5×5 SparseArrays.SparseMatrixCSC{Bool, Int64} with 5 stored entries:
⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅
1 1 ⋅ ⋅ ⋅
⋅ ⋅ 1 ⋅ ⋅
1 1 ⋅ ⋅ ⋅
julia> fw = Foodweb(:niche; S = 5, L = 4) # From number of links.
blueprint for Foodweb with 4 trophic links:
A: 5×5 SparseArrays.SparseMatrixCSC{Bool, Int64} with 4 stored entries:
⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅ ⋅
1 ⋅ ⋅ ⋅ ⋅
1 1 1 ⋅ ⋅
The default tolerance levels for the niche model are tol_C = 0.1 * C
and tol_L = 0.1 * L
, modifiable as keyword arguments.
For either random model, the following keyword arguments can also be specified:
reject_cycles = false
(default): raise to forbid trophic cycles.reject_if_disconnected = true
(default): lower to allow disconnected trophic networks.max_iterations = 10^5
(default): give up if no satisfying network can be found after this number of random trials.
Properties.
A model m
with a Foodweb
has the following properties.
m.A
orm.trophic_links
: a view into the matrix of trophic links.m.n_trophic_links
: the number of trophic links in the model.m.trophic_levels
: calculate the trophic level of every species in the model.- Distinguishing between
producers
(species without outgoing trophic links) andconsumers
(species with outgoing trophic links):m.{producers,consumers}_mask
: a boolean vector to select either kind of species.m.n_{producers,consumers}
: count number of species of either kind.is_{producer,consumer}(m, i)
: check whether speciesi
(name or index) is of either kind.m.{producers,consumer}_indices
: iterate over either species kind indices.m.{producers,consumer}_{sparse,dense}_index
: obtain a $species\_name \mapsto species\_index$ mapping:- the
sparse
index yields indices valid within the whole collection of species. - the
dense
index yields indices only valid within the restricted collection of species of either kind.
- the
- Distinguishing betwen
preys
(species with incoming trophic links) andtops
predators (species without incoming trophic links) works the same way. m.producers_links
: boolean matrix highlighting potential links between producers.m.herbivorous_links
: highlight only consumer-to-producer trophic links.m.carnivorous_links
: highlight only consumer-to-consumer trophic links.
julia> m = Model(Foodweb([:a => :b, :b => [:c, :d], :d => :e]));
julia> m.n_trophic_links
4
julia> m.A
5×5 EcologicalNetworksDynamics.TrophicLinks:
0 1 0 0 0
0 0 1 1 0
0 0 0 0 0
0 0 0 0 1
0 0 0 0 0
julia> m.trophic_levels
5-element EcologicalNetworksDynamics.TrophicLevels:
3.5
2.5
1.0
2.0
1.0
julia> m.producers_mask
5-element EcologicalNetworksDynamics.ProducersMask:
0
0
1
0
1
julia> m.preys_mask
5-element EcologicalNetworksDynamics.PreysMask:
0
1
1
1
1
julia> m.n_producers, m.n_consumers
(2, 3)
julia> m.n_tops, m.n_preys
(1, 4)
julia> is_top(m, 1), is_top(m, 2)
(true, false)
julia> collect(m.consumers_indices)
3-element Vector{Int64}:
1
2
4
julia> m.producers_sparse_index
OrderedCollections.OrderedDict{Symbol, Int64} with 2 entries:
:c => 3
:e => 5
julia> m.producers_dense_index
OrderedCollections.OrderedDict{Symbol, Int64} with 2 entries:
:c => 1
:e => 2
julia> m.producers_links
5×5 EcologicalNetworksDynamics.ProducersLinks:
0 0 0 0 0
0 0 0 0 0
0 0 1 0 1
0 0 0 0 0
0 0 1 0 1
julia> m.herbivorous_links
5×5 EcologicalNetworksDynamics.HerbivorousLinks:
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 1
0 0 0 0 0
julia> m.carnivorous_links
5×5 EcologicalNetworksDynamics.CarnivorousLinks:
0 1 0 0 0
0 0 0 1 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
EcologicalNetworksDynamics.Model
— TypeModel is the main object that we hand out to user which contains all the information about the underlying ecological model.
Create a Model
The most straightforward way to create a model is to use default_model
. This function only requires you to specify the trophic network.
fw = [1 => 2, 2 => 3]
model = default_model(fw)
This function will help you to create a model with ease, however it relies on default values for the parameters, which are not always suitable for your specific case, even though extracted from the literature.
To create a model with custom parameters, you can pass other arguments to default_model
.
model = default_model(fw, BodyMass(; Z = 100))
For instance, the above example creates a model with a body mass distribution with a predator-prey mass ratio of 100.
It is also possible to create a model manually by adding the components one by one. First, create an empty model:
m = Model()
Then add your components one by one. Note that you have to add the components in the right order, as some components depend on others. Moreover, some components are mandatory. Specifically, you need to provide a food web, species body masses, a functional response, metabolic rates and a producer growth function.
m = Model()
m += Foodweb([3 => 2, 2 => 1])
m += ClassicResponse(; h = 2, M = BodyMass([0.1, 2, 3]))
m += LogisticGrowth(; r = 1, K = 10)
m += Metabolism(:Miele2019)
m += Mortality(0)
Read and write properties of the model
First all properties contained in the model can be listed with:
properties(m) # Where m is a Model.
Then, the value of a property can be read with get_<X>
where X
is the name of the property. For instance, to read mortality rates:
get_mortality(m) # Equivalent to: m.mortality.
You can also re-write properties of the model using set_<X>!
. However, not all properties can be re-written, because some of them are derived from the others. For instance, many parameters are derived from species body masses, therefore changing body masses would make the model inconsistent. However, terminal properties can be re-written, as the species metabolic rate.
EcologicalNetworksDynamics.Species
— TypeThe Species component adds the most basic nodes compartment into the model: species. There is one node per species, and every species is given a unique name and index. The species ordering specified in this compartment is the reference species ordering.
julia> sp = Species(["hen", "fox", "snake"])
blueprint for Species:
names: 3-element Vector{Symbol}:
:hen
:fox
:snake
julia> m = Model(sp)
Model with 1 component:
- Species: 3 (:hen, :fox, :snake)
julia> Model(Species(5)) # Default names generated.
Model with 1 component:
- Species: 5 (:s1, :s2, :s3, :s4, :s5)
Typically, the species component is implicitly brought by other blueprints.
julia> Model(Foodweb([:a => :b]))
Model with 2 components:
- Species: 2 (:a, :b)
- Foodweb: 1 link
julia> Model(BodyMass([4, 5, 6]))
Model with 2 components:
- Species: 3 (:s1, :s2, :s3)
- Body masses: [4.0, 5.0, 6.0]
The species component makes the following properties available to a model m
:
m.S
orm.richness
orm.species_richness
orm.n_species
: number of species in the model.m.species_names
: list of species name in reference order.m.species_index
: get a $species\_name \mapsto species\_index$ mapping.
julia> (m.S, m.richness, m.species_richness, m.n_species) # All aliases for the same thing.
(3, 3, 3, 3)
julia> m.species_names
3-element EcologicalNetworksDynamics.SpeciesNames:
:hen
:fox
:snake
julia> m.species_index
OrderedCollections.OrderedDict{Symbol, Int64} with 3 entries:
:hen => 1
:fox => 2
:snake => 3