Skip to content
Snippets Groups Projects
Commit 6af775fe authored by xo30xoqa's avatar xo30xoqa
Browse files

Wrote tests for `initpopulation()`

Still errors - looks like `@habitat` still needs fixing.
parent 3f71e954
No related branches found
No related tags found
No related merge requests found
...@@ -89,7 +89,9 @@ There are two parameters that all species must define: ...@@ -89,7 +89,9 @@ There are two parameters that all species must define:
- `initialise!` should specify a function that will be used to create - `initialise!` should specify a function that will be used to create
the starting population for this species. This function must take the starting population for this species. This function must take
two arguments, a species dict and an `AgentBasedModel` object. two arguments, a species dict and an `AgentBasedModel` object.
The easiest way to create this function is by using `initpopultion()`. The easiest way to create this function is by using `initpopulation()`.
(To save typing, `@initialise!()` can be called instead. It defines
this variable and calls `initpopulation()`, all in one go.)
- `phase` should be a string specifying the name of the first phase - `phase` should be a string specifying the name of the first phase
that individuals of this species will be assigned to on birth. that individuals of this species will be assigned to on birth.
...@@ -111,6 +113,16 @@ macro species(name, body) ...@@ -111,6 +113,16 @@ macro species(name, body)
end end
end end
"""
@initialise!(habitatdescriptor; kwargs...)
This is a wrapper around `initpopulation()` that can be called within the body of a `@species`
definition block. It saves the user having to define the required `initialise!` variable by hand.
"""
macro initialise!(habitatdescriptor, kwargs...)
:($(esc(:initialise!)) = initpopulation($habitatdescriptor, $(kwargs...)))
end
""" """
@phase(name, body) @phase(name, body)
...@@ -248,7 +260,11 @@ circumvented by directly creating an equivalent function. ...@@ -248,7 +260,11 @@ circumvented by directly creating an equivalent function.
macro habitat(body) macro habitat(body)
quote quote
function($(esc(:pos)), $(esc(:model))) function($(esc(:pos)), $(esc(:model)))
($(esc(body))) ? return true : return false if $(esc(body))
return true
else
return false
end
end end
end end
end end
......
...@@ -68,18 +68,12 @@ A simplified version of `initpopulation()`. Creates a function that initialises ...@@ -68,18 +68,12 @@ A simplified version of `initpopulation()`. Creates a function that initialises
`popsize` individuals, spread at random across the landscape. If `popsize` is less `popsize` individuals, spread at random across the landscape. If `popsize` is less
than 1, it is interpreted as a population density (i.e. 1 animal per `popsize` pixels). than 1, it is interpreted as a population density (i.e. 1 animal per `popsize` pixels).
""" """
function initrandompopulation(popsize::Union{Int64,Float64}, asexual::Bool=true) function initrandompopulation(popsize::Union{Int64,Float64}; kwargs...)
function(species::Dict{String,Any}, model::AgentBasedModel) if popsize < 1.0
if popsize < 1.0 x, y = size(model.landscape)
x, y = size(model.landscape) popsize = round(x*y*popsize)
popsize = Int(round(x*y*popsize))
end
for i in 1:popsize
sex = asexual ? hermaphrodite : rand([male, female])
add_agent!(Animal, model, species, sex, 0)
end
@info "Initialised $(popsize) $(species["name"])s."
end end
initpopulation(@habitat(true), popsize=Int(popsize), kwargs...)
end end
#XXX initpopulation with dispersal from an original source? #XXX initpopulation with dispersal from an original source?
......
...@@ -7,4 +7,42 @@ ...@@ -7,4 +7,42 @@
#TODO #TODO
end end
#TODO @testset "Habitat macros" begin
#TODO
end
@testset "Species initialisation" begin
model = smalltestlandscape()
specname = "test_animal"
species = Dict("name"=>specname)
# create a set of initialisation functions
initfun1 = Ps.initrandompopulation(10)
initfun2 = Ps.initrandompopulation(6*6*3, asexual=true)
initfun3 = Ps.initpopulation(@habitat(Ps.@landcover() == Ps.grass), pairs=true)
initfun4 = Ps.initpopulation(@habitat(Ps.@landcover() == Ps.water &&
Ps.@countanimals(specname, 0) <= 5),
popsize=10)
# apply and test the initialisation functions
@test_logs (:info, "Initialised 10 $(specname)s.") initfun1(species, model)
@test all(a -> a.sex in (Ps.male, Ps.female), allagents(model))
genocide!(model)
@test_logs (:info, "Initialised 108 $(specname)s.") initfun2(species, model)
@test countanimals((1,1), model, specname, 0) == countanimals((6,6), model, specname, 0) == 3
@test Vector(nearby_animals((1,1), model, 0))[1].sex == Ps.hermaphrodite
genocide!(model)
@test_logs (:info, "Initialised 16 $(specname)s.") initfun3(species, model)
@test countanimals((2,2), model, specname, 2) == countanimals((5,3), model, specname, 1) == 0
@test countanimals((5,5), model, specname, 0) == countanimals((6,6), model, specname, 0) == 2
a1, a2 = Vector(nearby_animals((6,6), model, 0))
@test a1.sex != a2.sex
genocide!(model)
@test_logs((:warn, "There are not enough suitable locations for $(specname) in the landscape."),
(:info, "Initialised 5 $(specname)s."),
initfun4(species, model))
@test countanimals((1,1), model, specname, 4) == 0
@test countanimals((6,4), model, specname, 0) == 5
end
@testset "Population functions" begin
#TODO
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment