diff --git a/src/nature/nature.jl b/src/nature/nature.jl index 726d6f7f59847e38d7151cfb5fd5766f454cf18d..30370f7832d9fb41ebaa32a84617a98dbf01a817 100644 --- a/src/nature/nature.jl +++ b/src/nature/nature.jl @@ -70,9 +70,11 @@ custom syntax to describe species' biology: ```julia @species name begin - initialise! = initpopulation() - phase = "phase1" + + @initialise!(phase1, @habitat(...)) + speciesvar1 = 3.14 ... + @phase phase1 begin ... end @@ -80,23 +82,14 @@ end ``` The definition body (enclosed in the begin/end block) has two sections. -First comes a list of species-specific parameters, which are assigned -just like normal variables. Second come one or more phase definitions, -that describe the behaviour of the species during various parts of its -life cycle (see the documentation to `@phase` for details). - -There are two parameters that all species must define: -- `initialise!` should specify a function that will be used to create - the starting population for this species. This function must take - two arguments, a species dict and an `AgentBasedModel` object. - 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 - that individuals of this species will be assigned to on birth. - -Access to the rest of the model is given by the `model` variable (an object -of type `AgentBasedModel`). +First comes a call to `@initialise!()`, and optionally a list of +species-specific parameters, which are assigned just like normal variables. +Second come one or more phase definitions, that describe the behaviour +of the species during various parts of its life cycle. (See the documentation +to `@initialise!` and `@phase` for details). + +Code in a species definition block can access the rest of the model using +the `model` variable (an object of type `AgentBasedModel`). """ macro species(name, body) quote @@ -114,13 +107,20 @@ macro species(name, body) end """ - @initialise!(habitatdescriptor; kwargs...) + @initialise!(phase, 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. +Call this macro within the body of `@species`. It sets the phase that each individual +of this species will be assigned at birth, and passes the given habitat descriptor +function and keyword arguments on to `initpopulation()` when setting up the simulation. + +Note: if this macro is not used, `phase` and `initialise!` must be set manually in +the species definition. """ -macro initialise!(habitatdescriptor, kwargs...) - :($(esc(:initialise!)) = initpopulation($habitatdescriptor, $(kwargs...))) +macro initialise!(phase, habitatdescriptor, kwargs...) + quote + $(esc(:phase)) = String($phase) + $(esc(:initialise!)) = initpopulation($habitatdescriptor, $(kwargs...)) + end end """ diff --git a/src/nature/populations.jl b/src/nature/populations.jl index 8a58529489c1ff91ce0e1e3d7e907fd0380c830d..fb66d1c21fcca455af56b7ede45773edbc123528 100644 --- a/src/nature/populations.jl +++ b/src/nature/populations.jl @@ -13,6 +13,10 @@ This can be used to create the `initialise!` variable in a species definition bl - `habitatdescriptor` is a function that determines whether a given location is suitable or not (create this using `@habitat`). +- `phase` determines which life phase individuals will be assigned to. If this is `nothing`, + the species' default post-natal life stage will be used (although note that this is + probably not what you want). + - `popsize` determines the number of individuals that will be created. If this is zero or negative, one individual will be created in every suitable location in the landscape. If `popsize` is greater than the number of suitable locations, multiple individuals @@ -26,12 +30,13 @@ This can be used to create the `initialise!` variable in a species definition bl otherwise, they are randomly assigned male of female. (If `pairs` is true, `asexual` is ignored.) """ -function initpopulation(habitatdescriptor::Function; - popsize::Int64=-1, pairs::Bool=false, asexual=false) +function initpopulation(habitatdescriptor::Function; phase::Union{String,Nothing}=nothing, + popsize::Int64=-1, pairs::Bool=false, asexual::Bool=false) function(species::Dict{String,Any}, model::AgentBasedModel) n = 0 lastn = 0 specname = species["name"] + (!isnothing(phase)) && (species["phase"] = phase) width, height = size(model.landscape) while n == 0 || n < popsize for x in shuffle!(Vector(1:width))