diff --git a/src/core/output.jl b/src/core/output.jl index 830303f6f454e24c3aca08615c6469171dfe66e4..db3ce30049822823c1f7499f3069293aa1711528 100644 --- a/src/core/output.jl +++ b/src/core/output.jl @@ -42,7 +42,7 @@ function setupdatadir() simulationlogger = TeeLogger(ConsoleLogger(logfile, loglevel), ConsoleLogger(stdout, loglevel)) global_logger(simulationlogger) - @info "Setting up output directory $(param("core.outdir"))" + @debug "Setting up output directory $(param("core.outdir"))" # Export a copy of the current parameter settings to the output folder. # This can be used to replicate this exact run in future, and also # records the current time and git commit. diff --git a/src/core/simulation.jl b/src/core/simulation.jl index b94b8d69aea70865b0780830d664eaa5977f2eb5..f8c94f982c2e84cd546ec9b884e159474c98127c 100644 --- a/src/core/simulation.jl +++ b/src/core/simulation.jl @@ -10,7 +10,8 @@ Initialise the model: read in parameters, create the output data directory, and instantiate the AgentBasedModel object. """ function initialise(config::String=PARAMFILE) - #XXX add a seed parameter? + @info "Simulation run started at $(Dates.now())." + #TODO add a seed parameter - requires mutable parameters # do some housekeeping initsettings(config) Random.seed!(param("core.seed")) @@ -29,7 +30,6 @@ function initialise(config::String=PARAMFILE) initfarms!(model) initfields!(model) initnature!(model) - @info "Simulation initialised at $(Dates.now())." model end @@ -52,11 +52,11 @@ end """ finalise(model) -Wrap up the simulation. Output all remaining data and exit. +Wrap up the simulation. Currently doesn't do anything except print some information. """ function finalise(model::AgentBasedModel) - @info "Simulated $(model.date-param("core.startdate"))." - @info "Simulation completed at $(Dates.now()),\nwrote output to $(param("core.outdir"))." + @info "Simulated $(model.date-param("core.startdate")) days." + @info "Simulation run completed at $(Dates.now()),\nwrote output to $(param("core.outdir"))." #XXX is there anything to do here? #genocide!(model) end diff --git a/src/crop/crops.jl b/src/crop/crops.jl index c96c7c075cc68232410f7da0d5459efe4896a7df..c84c75d5d2621946eb5d64caf7033b46ae7c7c4f 100644 --- a/src/crop/crops.jl +++ b/src/crop/crops.jl @@ -59,7 +59,7 @@ function initfields!(model::AgentBasedModel) end end end - @debug "Initialised $n farm plots." + @info "Initialised $n farm plots." end #XXX only needed during development, can be deleted again? diff --git a/src/nature/nature.jl b/src/nature/nature.jl index bae14283b4809845a8caf4fd5e116f65991fd36c..186c47619576453b1d34dbd7977dc85a35958150 100644 --- a/src/nature/nature.jl +++ b/src/nature/nature.jl @@ -304,12 +304,11 @@ macro distancetoedge() end """ - @countanimals(speciesname) + @countanimals(speciesname, radius=0) Count the number of animals of the given species in this location. This is a utility wrapper that can only be used nested within `@phase` or `@habitat`. """ -macro countanimals(speciesname) - #XXX this also counts the enquiring agent - :(countanimals($(esc(:pos)), $(esc(:model)), $speciesname)) +macro countanimals(speciesname, radius=0) + :(countanimals($(esc(:pos)), $(esc(:model)), $speciesname, $radius)) end diff --git a/src/nature/populations.jl b/src/nature/populations.jl index 28b9528ba4ea486116a9d9dac99eb5c910749977..bd6577f465693f366c5a297c18299e0c706afb7b 100644 --- a/src/nature/populations.jl +++ b/src/nature/populations.jl @@ -4,6 +4,63 @@ ### reproduction, and mortality. ### +""" + initpopulation(habitatdescriptor; popsize=-1, pairs=false, asexual=false) + +Creates a function that initialises individuals at random locations across the landscape. +This can be used to create the `initialise!` variable in a species definition block. + +- `habitatdescriptor` is a function that determines whether a given location is suitable + or not (create this using `@habitat`). + +- `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 + will be created in one place. (Maximum population density can be set in the habitat + descriptor using the `@countanimals` macro.) + +- If `pairs` is true, a male and a female individual will be created in each selected + location, otherwise, only one individual will be created at a time. + +- If `asexual` is true, all created individuals are assigned the sex `hermaphrodite`, + 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(species::Dict{String,Any}, model::AgentBasedModel) + n = 0 + lastn = 0 + specname = species["name"] + width, height = size(model.landscape) + while n == 0 || n < popsize + for x in shuffle!(Vector(1:width)) + for y in shuffle!(Vector(1:height)) + if habitatdescriptor((x,y), model) + if pairs + add_agent!(Animal, (x,y), model, species, female, 0) + add_agent!(Animal, (x,y), model, species, male, 0) + n += 2 + else + sex = asexual ? hermaphrodite : rand([male, female]) + add_agent!(Animal, (x,y), model, species, sex, 0) + n += 1 + end + end + (n >= popsize) && break + end + (n >= popsize) && break + end + if lastn == n # prevent an infinite loop - we don't have a Cray... + @warn "There are not enough suitable locations for $(specname) in the landscape." + break + end + lastn = n + end + @info "Initialised $(n) $(specname)s." + end +end + """ initrandompopulation(popsize, asexual=true) @@ -12,7 +69,7 @@ A simplified version of `initpopulation()`. Creates a function that initialises 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) - initfunc = function(species::Dict{String,Any}, model::AgentBasedModel) + function(species::Dict{String,Any}, model::AgentBasedModel) if popsize < 1.0 x, y = size(model.landscape) popsize = Int(round(x*y*popsize)) @@ -21,12 +78,10 @@ function initrandompopulation(popsize::Union{Int64,Float64}, asexual::Bool=true) sex = asexual ? hermaphrodite : rand([male, female]) add_agent!(Animal, model, species, sex, 0) end - @debug "Initialised $(popsize) $(species["name"])s." + @info "Initialised $(popsize) $(species["name"])s." end - return initfunc end -#TODO initpopulation with habitat descriptor #XXX initpopulation with dispersal from an original source? #XXX initpopulation based on known occurences in real-life? diff --git a/src/nature/species/skylark.jl b/src/nature/species/skylark.jl index d29ab65d6515753f2d82e17c5bb38cf8ff5b30c6..0f877bd0910db60a95f54049a7a416e359d6d636 100644 --- a/src/nature/species/skylark.jl +++ b/src/nature/species/skylark.jl @@ -35,7 +35,7 @@ At the moment, this implementation is still in development. @respond harvest @kill(@trait(eggharvestmortality), "harvest") - if animal.age == 14 + if @trait(age) == 14 @trait(phase) = "nestling" end end