Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Persefone.jl
Manage
Activity
Members
Plan
Wiki
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Deploy
Package registry
Model registry
Operate
Terraform modules
Analyze
Contributor analytics
Repository analytics
Insights
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Persefone
Persefone.jl
Commits
79f4da42
Commit
79f4da42
authored
1 year ago
by
xo30xoqa
Browse files
Options
Downloads
Patches
Plain Diff
Implemented a basic skylark species
Major commit - not yet quite functional
parent
36f8a06f
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/nature/species/skylark.jl
+174
-26
174 additions, 26 deletions
src/nature/species/skylark.jl
with
174 additions
and
26 deletions
src/nature/species/skylark.jl
+
174
−
26
View file @
79f4da42
...
...
@@ -11,54 +11,195 @@ At the moment, this implementation is still in development.
**Sources:**
- Bauer, H.-G., Bezzel, E., & Fiedler, W. (Eds.). (2012).
Das Kompendium der Vögel Mitteleuropas: Ein umfassendes
Handbuch zu Biologie, Gefährdung und Schutz (Einbändige
Sonderausg. der 2., vollständig überarb. und erw. Aufl. 2005).
AULA-Verlag
Das Kompendium der Vögel Mitteleuropas: Ein umfassendes
Handbuch zu Biologie, Gefährdung und Schutz (Einbändige
Sonderausg. der 2., vollständig überarb. und erw. Aufl. 2005).
AULA-Verlag
- Glutz von Blotzheim, Urs N. (Ed.). (1985). Handbuch der
Vögel Mitteleuropas. Bd. 10. Passeriformes (Teil 1)
1. Alaudidae - Hirundidae. AULA-Verlag, Wiesbaden.
ISBN 3-89104-019-9
"""
@species
Skylark
begin
egg
maturationtime
=
11
egg
harvest
mortality
=
0.
9
#???
eggpredation
mortality
=
0.
1
#
???
egg
time
=
11
# 11 days from laying to hatching
egg
predation
mortality
=
0.
03
# per-day egg mortality from predation
nestharvest
mortality
=
0.
9
#
egg mortality after a harvest event (XXX guess)
migrationdates
=
()
nestlingtime
=
7
:
11
# 7-11 days from hatching to leaving nest
nestlingpredationmortality
=
0.03
# per-day nestling mortality from predation
habitats
=
@habitat
((
@landcover
()
==
grass
||
fledglingtime
=
25
:
30
# 25-30 days from hatching to independence
fledglingharvestmortality
=
0.5
# fledgling mortality after harvest
fledglingpredationmortality
=
0.01
# per-day fledgling mortality from predation
firstyearmortality
=
0.38
# total mortality in the first year after independence
migrationdates
=
()
# is defined by each individual in `initskylark()`
migrationmortality
=
0.33
# chance of dying during the winter
mate
=
-
1
# the agent ID of the mate (-1 if none)
nest
=
()
# coordinates of current nest
nestingbegin
=
(
4
,
10
)
# begin nesting in the middle of April
nestbuildingtime
=
4
:
5
# 4-5 days needed to build a nest (doubled for first nest)
nestcompletion
=
0
# days left until the nest is built
eggsperclutch
=
2
:
5
# 2-5 eggs laid per clutch
clutch
=
[]
# IDs of offspring in current clutch
breedingdelay
=
18
# wait 18 days after hatching to start a new brood
habitats
=
@habitat
((
@landcover
()
==
grass
||
# settle on grass or arable land (but not maize)
(
@landcover
()
==
agriculture
&&
@cropname
()
!=
"maize"
))
&&
@distanceto
(
forest
)
>
5
)
@distancetoedge
()
>
5
)
# at least 50m from other habitats
#XXX this ought to check for distance to forest and builtup,
# but that's very expensive (see below)
# @distanceto(forest) > 5 && # at least 50m from forest edges
# @distanceto(builtup) > 5) # and from anthropogenic structures
@initialise
(
habitats
,
pairs
=
true
,
initfunction
=
initskylark
)
@initialise
(
habitats
,
popdensity
=
300
,
pairs
=
true
,
initfunction
=
initskylark
)
"""
As an egg, simply check for mortality and hatching.
"""
@phase
egg
begin
@kill
(
@trait
(
eggpredationmortality
),
"predation"
)
@respond
harvest
@kill
(
@trait
(
eggharvestmortality
),
"harvest"
)
#TODO dies if parents die (due to starvation?)
@respond
(
harvesting
,
@kill
(
@trait
(
nestharvestmortality
),
"harvest"
))
if
@trait
(
age
)
==
14
if
@trait
(
age
)
==
@trait
(
eggtime
)
@setphase
(
nestling
)
end
end
"""
As a nestling, simply check for mortality and fledging.
"""
@phase
nestling
begin
#TODO
#TODO add feeding & growth
@kill
(
@trait
(
nestlingpredationmortality
),
"predation"
)
@respond
(
harvesting
,
@kill
(
@trait
(
nestharvestmortality
),
"harvest"
))
if
@trait
(
age
)
==
@trait
(
nestlingtime
)
+
@trait
(
eggtime
)
@setphase
(
fledgling
)
end
end
@phase
breeding
begin
#TODO
"""
As a fledgling, move around a little, but mainly wait for maturity and
check mortality.
"""
@phase
fledgling
begin
#TODO add feeding & growth
@kill
(
@trait
(
fledglingpredationmortality
),
"predation"
)
@randomwalk
(
1
)
#TODO add movement following the parents
if
@trait
(
age
)
==
@trait
(
fledglingtime
)
+
@trait
(
eggtime
)
@kill
(
@trait
(
firstyearmortality
),
"first year mortality"
)
#XXX mechanistic?
@setphase
(
nonbreeding
)
end
end
"""
As a non-breeding adult, move around with other individuals and check for migration.
"""
@phase
nonbreeding
begin
#TODO
# flocking behaviour - follow a random neighbour or move randomly
#TODO add feeding and mortality, respect habitat when moving
neighbours
=
map
(
a
->
a
.
id
,
@neighbours
(
10
))
#isempty(neighbours) ? @randomwalk(5) : @follow(@rand(neighbours), 2)
if
isempty
(
neighbours
)
@randomwalk
(
5
)
else
@follow
(
model
[
@rand
(
neighbours
)],
2
)
end
# check if the bird migrates
leave
,
arrive
=
animal
.
migrationdates
m
,
d
=
monthday
(
model
.
date
)
migrate
=
(((
m
<
arrive
[
1
])
||
(
m
==
arrive
[
1
]
&&
d
<
arrive
[
2
]))
||
((
m
>
leave
[
1
])
||
(
m
==
leave
[
1
]
&&
d
>=
leave
[
2
])))
if
migrate
@kill
(
@trait
(
migrationmortality
),
"migration"
)
returndate
=
Date
(
year
(
model
.
date
),
arrive
[
1
],
arrive
[
2
])
model
.
date
!=
@param
(
core
.
startdate
)
&&
(
returndate
+=
Year
(
1
))
@setphase
(
mating
)
@migrate
(
returndate
)
end
end
@phase
migration
begin
#TODO
"""
Move around until a mate is found.
"""
@phase
mating
begin
# if we've found a mate, wait for nesting begin and then go to the next phase
if
@trait
(
mate
)
!=
-
1
if
!
@isalive
(
@trait
(
mate
))
@trait
(
mate
)
=
-
1
return
end
m
,
d
=
monthday
(
model
.
date
)
nest
=
((
m
==
@trait
(
nestingbegin
)[
1
]
&&
d
>
@trait
(
nestingbegin
)[
2
]
&&
@chance
(
0.05
))
||
(
m
>
@trait
(
nestingbegin
)[
1
]))
nest
&&
@setphase
(
nestbuilding
)
return
end
# look for a mate among the neighbouring birds, or move randomly
for
n
in
@neighbours
(
50
)
if
n
.
sex
!=
@trait
(
sex
)
&&
n
.
mate
==
-
1
@trait
(
mate
)
=
n
.
id
n
.
mate
=
@trait
(
id
)
@debug
"
$
(animalid(@trait(id))) and
$
(animalid(n.id)) have mated."
return
end
end
@randomwalk
(
10
)
end
@phase
mating
begin
#TODO
"""
Females select a location and build a nest. Males do nothing. (Sound familiar?)
"""
@phase
nestbuilding
begin
if
@trait
(
sex
)
==
female
if
isempty
(
@trait
(
nest
))
# try to find a nest in the neighbourhood, or move on
nest
=
@randompixel
(
10
,
@trait
(
habitats
))
if
isnothing
(
nest
)
nest
=
()
@randomwalk
(
20
)
else
# if we've found a location, start the clock on the building time
# (building time doubles for the first nest of the year)
@trait
(
nestcompletion
)
=
@rand
(
nestbuildingtime
)
month
(
model
.
date
)
==
4
&&
(
@trait
(
nestcompletion
)
*=
2
)
end
else
# wait while nest is being built, then lay eggs and go to next phase
if
@trait
(
nestcompletion
)
>
0
@trait
(
nestcompletion
)
-=
1
else
@trait
(
clutch
)
=
@reproduce
(
@trait
(
mate
),
@rand
(
eggsperclutch
))
@animal
(
@trait
(
mate
))
.
clutch
=
@trait
(
clutch
)
@setphase
(
breeding
)
end
end
else
# males stay near the female
@follow
(
model
[
@trait
(
mate
)],
5
)
@animal
(
@trait
(
mate
))
.
phase
==
"breeding"
&&
@setphase
(
breeding
)
end
end
"""
Do lots of foraging (not yet implemented).
"""
@phase
breeding
begin
#TODO forage (move random)
for
offspring
in
@trait
(
clutch
)
# check if offspring are still alive and juvenile, else remove from clutch
if
!
@isalive
(
offspring
)
||
@animal
(
offspring
)
.
phase
==
"nonbreeding"
deleteat!
(
@trait
(
clutch
),
findfirst
(
x
->
x
==
offspring
,
@trait
(
clutch
)))
end
end
# if all young have fledged, move to nonbreeding (if it's July) or breed again
if
isempty
(
@trait
(
clutch
))
@trait
(
nest
)
=
()
month
(
model
.
date
)
>=
7
?
@setphase
(
nonbreeding
)
:
@setphase
(
nestbuilding
)
end
end
end
...
...
@@ -66,13 +207,14 @@ end
initskylark(skylark, model)
Initialise a skylark individual. Selects migration dates and checks if the
bird should currently be on migration.
bird should currently be on migration. Also sets other individual-specific
variables. Called at model initialisation and when an egg is laid.
"""
function
initskylark
(
animal
::
Animal
,
model
::
AgentBasedModel
)
@debug
"Added
$
(animalid(animal)) at
$
(animal.pos)"
# calculate migration dates for this individual
animal
.
migrationdates
=
migrationdates
(
animal
,
model
)
leave
=
animal
.
migrationdates
[
1
]
arrive
=
animal
.
migrationdates
[
2
]
leave
,
arrive
=
animal
.
migrationdates
m
,
d
=
monthday
(
model
.
date
)
migrate
=
(((
m
<
arrive
[
1
])
||
(
m
==
arrive
[
1
]
&&
d
<
arrive
[
2
]))
||
((
m
>
leave
[
1
])
||
(
m
==
leave
[
1
]
&&
d
>=
leave
[
2
])))
...
...
@@ -81,6 +223,9 @@ function initskylark(animal::Animal, model::AgentBasedModel)
model
.
date
!=
@param
(
core
.
startdate
)
&&
(
returndate
+=
Year
(
1
))
@migrate
(
returndate
)
end
# set individual life-history parameters that are defined as ranges for the species
@trait
(
nestlingtime
)
=
@rand
(
@trait
(
nestlingtime
))
@trait
(
fledglingtime
)
=
@rand
(
@trait
(
fledglingtime
))
#TODO other stuff?
end
...
...
@@ -91,6 +236,8 @@ Select the dates on which this skylark will leave for / return from its migratio
based on observed migration patterns.
"""
function
migrationdates
(
skylark
::
Animal
,
model
::
AgentBasedModel
)
#TODO this ought to be temperature-dependent and dynamic
#XXX magic numbers!
minleave
=
skylark
.
sex
==
female
?
(
9
,
15
)
:
(
10
,
1
)
minarrive
=
skylark
.
sex
==
male
?
(
2
,
15
)
:
(
3
,
1
)
deltaleave
=
@rand
(
0
:
45
)
#XXX ought to be normally distributed
...
...
@@ -99,3 +246,4 @@ function migrationdates(skylark::Animal, model::AgentBasedModel)
arrive
=
monthday
(
Date
(
2001
,
minarrive
[
1
],
minarrive
[
2
])
+
Day
(
deltaarrive
))
(
leave
,
arrive
)
end
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment