Skip to content
Snippets Groups Projects
Commit 4954227d authored by xo30xoqa's avatar xo30xoqa
Browse files

Fixed the (hopefully) remaining bugs in the species macros

This seems to work as intended now! :D
parent f7d339d5
Branches
Tags
No related merge requests found
......@@ -48,14 +48,12 @@ Execute one update of the model.
function stepsimulation!(model::AgentBasedModel)
@info "Simulating day $(model.date)."
for a in Schedulers.ByType((Farmer,FarmPlot,Animal), true)(model)
#The animal may have been killed, so we need a try/catch
# try
# stepagent!(model[a], model)
# catch exc
# #FIXME check if the KeyError comes from the model[a] or the function call
# isa(exc, KeyError) ? continue : throw(exc)
# end
stepagent!(model[a], model)
try #The animal may have been killed
stepagent!(model[a], model)
catch exc
# check if the KeyError comes from the `model[a]` or the function call
isa(exc, KeyError) && isa(exc.key, Int) ? continue : throw(exc)
end
end
updateevents!(model)
outputdata(model)
......
......@@ -62,6 +62,11 @@ end
### MACROS IMPLEMENTING THE DOMAIN-SPECIFIC LANGUAGE FOR DEFINING SPECIES
## Note that this DSL consists of lots of deeply nested macro calls, which is a
## known tricky issue in Julia (https://github.com/JuliaLang/julia/issues/23221,
## https://github.com/p-i-/MetaGuideJulia/wiki#example-swap-macro-to-illustrate-esc).
## Hence all the `esc`apes in the following code - be careful when modifying!
"""
@species(name, body)
......@@ -125,8 +130,7 @@ Note: if this macro is not used, the variable `initialise!` must be set manually
species definition.
"""
macro initialise(habitatdescriptor, kwargs...)
#FIXME does the habitatdescriptor need to be `esc`aped due to scoping issues?
:($(esc(:initialise!)) = initpopulation($habitatdescriptor, $(kwargs...)))
:($(esc(:initialise!)) = initpopulation($(esc(habitatdescriptor)); $(map(esc, kwargs)...)))
end
"""
......@@ -159,6 +163,7 @@ the phase that animals are assigned at birth, unless the variable `phase` is
explicitly defined by the user in the species definition block.
"""
macro phase(name, body)
#TODO the docstrings give a lot of warnings in the log - can I fix that?
quote
Core.@__doc__ function $(esc(name))($(esc(:animal))::Animal, $(esc(:model))::AgentBasedModel)
$(esc(:pos)) = $(esc(:animal)).pos
......@@ -251,7 +256,7 @@ This can only be used nested within `@phase`.
"""
macro neighbours(radius)
#TODO enable filtering by species
:(nearby_animals($(esc(:animal)), $(esc(:model)), $radius))
:(nearby_animals($(esc(:animal)), $(esc(:model)), $(esc(radius))))
end
"""
......@@ -336,7 +341,7 @@ Calculate the distance to the closest habitat of the specified type or descripto
This is a utility wrapper that can only be used nested within `@phase` or `@habitat`.
"""
macro distanceto(habitat)
:(distanceto($(esc(:pos)), $(esc(:model)), $habitat))
:(distanceto($(esc(:pos)), $(esc(:model)), $(esc(habitat))))
end
"""
......
......@@ -18,7 +18,7 @@ legs, but that doesn't make it any less dangerous...
aggression = 0.2
huntsuccess = 0.8
initialise! = initrandompopulation(popsize)
@initialise(@habitat(@landcover() in (grass, soil, agriculture, builtup)), popsize=popsize)
phase = "winter"
"""
......@@ -26,7 +26,7 @@ legs, but that doesn't make it any less dangerous...
prey: wolpertingers...
"""
@phase summer begin
for a in nearby_agents(animal, model, @trait(speed))
for a in @neighbours(@trait(speed))
# check if a wolpertinger is in pouncing distance
if a.traits["name"] == "Wolpertinger"
move_agent!(animal, a.pos, model)
......@@ -50,7 +50,7 @@ legs, but that doesn't make it any less dangerous...
end
# check if a wolpertinger is in seeing distance, or walk in a random direction
direction = Tuple(rand([-1,1], 2))
for a in nearby_agents(animal, model, @trait(vision))
for a in @neighbours(@trait(vision))
if a.traits["name"] == "Wolpertinger"
direction = get_direction(animal.pos, a.pos, model)
break
......
......@@ -16,8 +16,8 @@ loglevel = "debug" # verbosity level: "debug", "info", "quiet"
seed = 0 # seed value for the RNG (0 -> random value)
# dates to start and end the simulation
startdate = 2022-01-01
enddate = 2022-01-02
#enddate = 2022-12-31
#enddate = 2022-01-02
enddate = 2022-12-31
[farm]
farmmodel = "FieldManager" # which version of the farm model to use (not yet implemented)
......
......@@ -15,7 +15,7 @@
h1 = @habitat(@landcover() == Ps.water)
h2 = @habitat(@croptype() == Ps.wheat &&
@cropheight() < 2)
h3 = @habitat(@distanceto(water) > 2 &&
h3 = @habitat(@distanceto(Ps.water) > 2 &&
@distancetoedge() <= 2)
h4 = @habitat(@countanimals(species="test_animal", radius=1) == 1)
# test the descriptors
......@@ -67,18 +67,13 @@ end
end
@testset "Species macros" begin
#FIXME I am having tons of trouble here with module scoping and macro expansion,
# a known tricky issue in Julia (https://github.com/JuliaLang/julia/issues/23221,
# https://github.com/p-i-/MetaGuideJulia/wiki#example-swap-macro-to-illustrate-esc).
# Basically, one needs to avoid nesting modules too deeply (i.e. more than one nesting level)
# -- is that so?? --
# create a model landscape and a test species
model = smalltestlandscape(Union{Animal,Farmer,FarmPlot})
@species Mermaid begin
ageofmaturity = 2
pesticidemortality = 1.0
#@initialise!(@habitat(@landcover() == Persephone.water), pairs=true) #FIXME
initialise! = Persephone.initpopulation(@habitat(@landcover() == Persephone.water), pairs=true)
@initialise(@habitat(@landcover() == Persephone.water), pairs=true)
@phase life begin
@debug "$(Persephone.animalid(animal)) is swimming happily in its pond."
@respond Persephone.pesticide @kill(@trait(pesticidemortality))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment