Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Persefone.jl
Manage
Activity
Members
Plan
Wiki
Automate
Agent sessions
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
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Persefone
Persefone.jl
Commits
d529d60a
Commit
d529d60a
authored
3 months ago
by
xo30xoqa
Browse files
Options
Downloads
Patches
Plain Diff
Added stats recording for the marbled white
parent
2b25a290
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/nature/ecologicaldata.jl
+4
-5
4 additions, 5 deletions
src/nature/ecologicaldata.jl
src/nature/species/marbled_white.jl
+77
-13
77 additions, 13 deletions
src/nature/species/marbled_white.jl
with
81 additions
and
18 deletions
src/nature/ecologicaldata.jl
+
4
−
5
View file @
d529d60a
...
...
@@ -137,11 +137,10 @@ function initmarbledwhitedata(model::SimulationModel)
newdataoutput!
(
model
,
"marbledwhite_abundance"
,
[
"Date"
,
"TotalAbundance"
,
"Eggs"
,
"Larvae"
,
"Pupae"
,
"Adults"
],
@param
(
nature
.
popoutfreq
),
marbledwhiteabundance
,
marbledwhitepopulation
)
# newdataoutput!(model, "marbledwhite_territories", ["Date", "ID", "X", "Y"],
# marbledwhiteterritories, "monthly") #TODO add plotting function
# newdataoutput!(model, "marbledwhite_breeding",
# ["Date", "Female", "Male", "X", "Y", "Landcover", "Crop", "Territory"],
# @param(nature.popoutfreq), nothing, marbledwhitestats) #TODO add
newdataoutput!
(
model
,
"marbledwhite_lifestats"
,
[
"ID"
,
"Fecundity"
,
"Daily movement"
,
"Displacement"
,
"Unmanaged grassland"
,
"Extensive grassland"
,
"Fallow"
,
"Intensive grassland"
,
"Arable"
,
"Other"
],
@param
(
nature
.
popoutfreq
),
nothing
,
marbledwhitelifestats
)
#TODO add
end
"""
...
...
This diff is collapsed.
Click to expand it.
src/nature/species/marbled_white.jl
+
77
−
13
View file @
d529d60a
...
...
@@ -3,10 +3,6 @@
### This file holds the code for the Marbled White (Melanargia galathea).
###
##TODO
## - population initialisation
## - agglomeration?
"""
Marbled White
...
...
@@ -41,6 +37,8 @@
- Roy et al. (2001). Butterfly numbers and weather: Predicting historical
trends in abundance and the future effects of climate change. Journal of
Animal Ecology, 70(2), 201–217. https://doi.org/10.1111/j.1365-2656.2001.00480.x
- Schulte et al. (2007). Die Tagfalter der Pfalz—Band 2. Gesellschaft für
Naturschutz und Ornithologie Rheinland-Pfalz.
- Vandewoestijne et al. (2004). Dispersal, landscape occupancy and population
structure in the butterfly Melanargia galathea. Basic and Applied Ecology,
5(6), 581–591. https://doi.org/10.1016/j.baae.2004.07.004
...
...
@@ -62,26 +60,32 @@
const
selfavoidance
=
0.9
const
habitatpreference
=
0.9
const
perception
=
100
m
# perceptual range (cf. Cant et al. 2005)
const
socialdistancing
=
true
# avoid pixels already occupied by conspecifics
# lifecycle parameters
# (eggsperday and time parameters from Reinhardt et al. 2007)
const
maxeggsperday
=
15
# number of eggs laid under optimal conditions
const
maxeggsperday
=
8
# number of eggs laid under optimal conditions
#TODO recalculate
const
eggtime
=
18
:
22
# days as egg
const
larvatime
=
290
:
320
# days as larva
const
pupatime
=
16
:
29
# days as pupa
const
adulttime
=
17
:
34
# days as adult
const
maturationtime
=
5
:
8
# days from hatching to first oviposition
const
juvenilesurvival
=
0
:
25
# in percent (Wilson 1985, Dennis 1992)
const
maturationtime
=
5
:
8
# days from hatching to first oviposition #FIXME include
const
juvenilesurvival
=
0
:
5
#0:25 # in percent (Wilson 1985, Dennis 1992)
#TODO add mowing mortality
const
earliesteclosure
::
AnnualDate
=
(
June
,
15
)
# (Ebert & Rennwald 1991)
const
latesteclosure
::
AnnualDate
=
(
August
,
15
)
# (Ebert & Rennwald 1991)
const
enforceflyingperiod
=
true
# make sure all pupa eclose in the flying period?
## INDIVIDUAL VARIABLES
# life-history related
birthdate
::
Date
=
Date
(
2000
,
July
,
1
)
# is redefined in @create
# how many days this individual spends in each phase
daysinphase
::
Vector
{
Int64
}
=
[
20
,
300
,
19
,
25
]
# is redefined in @create
# following::Int64 = -1 # ID of the individual being followed #XXX include this?
# needed for statistics
birthplace
::
Tuple
{
Int64
,
Int64
}
=
(
0
,
0
)
# is redefined in @create
lifestats
::
Dict
{
String
,
Int64
}
=
Dict
(
"Fecundity"
=>
0
,
"Unmanaged grassland"
=>
0
,
"Extensive grassland"
=>
0
,
"Fallow"
=>
0
,
"Intensive grassland"
=>
0
,
"Arable"
=>
0
,
"Other"
=>
0
)
end
...
...
@@ -124,7 +128,8 @@ Adults move a given number of steps each day, depending on the temperature (see
Each step, an individual scans its surroundings in concentric circles, looking for
the closest spot that offers suitable habitat which it hasn't visited today. (Depending
on the `habitatpreference` and `selfavoidance` parameters, spots that are not suitable
habitat or have been visited before may also be selected.) After each step, if it
habitat or have been visited before may also be selected.) If `socialdistancing` is true,
spots that are already occupied by a conspecific are avoided. After each step, if it
is in a suitable habitat, the individual lays an egg, up to `maxeggsperday` (depending
on temperature, see below).
...
...
@@ -146,6 +151,7 @@ weather data.
opttemp
=
(
self
.
mintemp
+
self
.
maxtemp
)
/
2
optimality
=
bounds
(
1
-
(
abs
(
opttemp
-
@maxtemp
())
/
(
opttemp
-
self
.
mintemp
)))
stepsremaining
::
Int64
=
Int
(
round
(
self
.
maxstepsperday
*
optimality
))
#FIXME consider maturationtime
eggsremaining
::
Int64
=
self
.
maxeggsperday
if
@maxtemp
()
<
opttemp
||
@maxtemp
()
>
self
.
maxtemp
eggsremaining
=
Int
(
round
(
self
.
maxeggsperday
*
optimality
))
...
...
@@ -168,11 +174,15 @@ weather data.
push!
(
coords
,
(
y
,
xrange
[
2
]))
end
for
c
in
@shuffle
!
(
coords
)
# ignore undesirable habitats
(
c
[
1
]
<=
0
||
c
[
2
]
<=
0
||
c
[
1
]
>
width
||
c
[
2
]
>
height
)
&&
continue
(
self
.
socialdistancing
&&
countanimals
(
c
,
model
,
species
=
"MarbledWhite"
)
>
0
)
&&
continue
(
c
in
path
&&
@chance
(
self
.
selfavoidance
))
&&
continue
(
!
suitablehabitat
(
self
,
model
,
c
)
&&
@chance
(
self
.
habitatpreference
))
&&
continue
radius
=
self
.
perception
/
@param
(
world
.
mapresolution
)
# move to the new location and record habitat stats
radius
=
self
.
perception
/
@param
(
world
.
mapresolution
)
# end the outer loop
@move
(
c
)
recordmovementstats
(
self
,
model
)
break
end
radius
+=
1
...
...
@@ -182,13 +192,16 @@ weather data.
if
@chance
(
@randn
(
self
.
juvenilesurvival
)
/
100
)
@reproduce
()
# only create an individual that will survive to adulthood
end
self
.
lifestats
[
"Fecundity"
]
+=
1
eggsremaining
-=
1
end
push!
(
path
,
self
.
pos
)
stepsremaining
-=
1
end
#XXX record daily displacement?
# die once the lifespan has been reached
if
self
.
age
>=
sum
(
self
.
daysinphase
)
recordlifestats
(
self
,
model
)
@kill
()
end
end
...
...
@@ -210,6 +223,56 @@ function suitablehabitat(butterfly::MarbledWhite, model::SimulationModel, pos::T
@cropheight
()
<=
butterfly
.
maxheight
)))
end
"""
recordmovementstats(butterfly, model)
Record the habitat category of the butterfly's current location in its life stats.
"""
function
recordmovementstats
(
butterfly
::
MarbledWhite
,
model
::
SimulationModel
)
pos
=
butterfly
.
pos
if
@cropname
()
==
"permanent grassland (low yield)"
butterfly
.
lifestats
[
"Extensive grassland"
]
+=
1
elseif
@cropname
()
==
"permanent grassland (grazed)"
butterfly
.
lifestats
[
"Intensive grassland"
]
+=
1
elseif
@cropname
()
==
"set-aside"
butterfly
.
lifestats
[
"Fallow"
]
+=
1
elseif
@cropname
()
==
""
if
@landcover
()
==
"grass"
butterfly
.
lifestats
[
"Unmanaged grassland"
]
+=
1
else
butterfly
.
lifestats
[
"Other"
]
+=
1
end
else
butterfly
.
lifestats
[
"Arable"
]
+=
1
end
end
"""
recordlifestats(butterfly, model)
Save this butterfly's life stats to file.
"""
function
recordlifestats
(
butterfly
::
MarbledWhite
,
model
::
SimulationModel
)
stats
=
butterfly
.
lifestats
totalmovement
=
stats
[
"Unmanaged grassland"
]
+
stats
[
"Extensive grassland"
]
+
stats
[
"Fallow"
]
+
stats
[
"Intensive grassland"
]
+
stats
[
"Arable"
]
+
stats
[
"Other"
]
# use Pythagoras to calculate the lifetime displacement
displacement
=
round
(
sqrt
(
sum
(
abs
.
(
butterfly
.
birthplace
.-
butterfly
.
pos
)
.^
2
)))
record!
(
model
,
"marbledwhite_lifestats"
,
[
butterfly
.
id
,
stats
[
"Fecundity"
],
# save average daily movement and lifetime displacement distances (but strip out units)
Int
(
round
((
totalmovement
/
butterfly
.
daysinphase
[
4
]))
*
@param
(
world
.
mapresolution
)
/
1
m
),
Int
(
displacement
*
@param
(
world
.
mapresolution
)
/
1
m
),
# save percentage time spent in different habitats
Int
(
round
(
stats
[
"Unmanaged grassland"
]
/
totalmovement
*
100
)),
Int
(
round
(
stats
[
"Extensive grassland"
]
/
totalmovement
*
100
)),
Int
(
round
(
stats
[
"Fallow"
]
/
totalmovement
*
100
)),
Int
(
round
(
stats
[
"Intensive grassland"
]
/
totalmovement
*
100
)),
Int
(
round
(
stats
[
"Arable"
]
/
totalmovement
*
100
)),
Int
(
round
(
stats
[
"Other"
]
/
totalmovement
*
100
))])
end
## INITIALISATION
...
...
@@ -238,15 +301,16 @@ random, but I don't have data for that.)
if
self
.
enforceflyingperiod
eclose
=
self
.
birthdate
+
Day
(
self
.
daysinphase
[
1
]
+
self
.
daysinphase
[
2
]
+
self
.
daysinphase
[
3
])
if
eclose
<
self
.
earliesteclosure
diff
=
@
this
year
(
self
.
earliesteclosure
)
-
eclose
diff
=
@
next
year
(
self
.
earliesteclosure
)
-
eclose
self
.
daysinphase
[
2
]
+=
diff
.
value
@debug
(
"Increased larval time by
$(diff)
to stay in flying period."
)
elseif
eclose
>
self
.
latesteclosure
diff
=
eclose
-
@
this
year
(
self
.
latesteclosure
)
diff
=
eclose
-
@
next
year
(
self
.
latesteclosure
)
self
.
daysinphase
[
2
]
-=
diff
.
value
@debug
(
"Reduced larval time by
$(diff)
to stay in flying period."
)
end
end
self
.
birthplace
=
self
.
pos
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
sign in
to comment