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
74d43c05
Commit
74d43c05
authored
11 months ago
by
xo30xoqa
Browse files
Options
Downloads
Patches
Plain Diff
Moved some functions from populations.jl to new file individuals.jl
parent
2db97204
Branches
Branches containing commit
Tags
Tags containing commit
Loading
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/Persefone.jl
+1
-0
1 addition, 0 deletions
src/Persefone.jl
src/nature/individuals.jl
+194
-0
194 additions, 0 deletions
src/nature/individuals.jl
src/nature/populations.jl
+2
-193
2 additions, 193 deletions
src/nature/populations.jl
with
197 additions
and
193 deletions
src/Persefone.jl
+
1
−
0
View file @
74d43c05
...
...
@@ -141,6 +141,7 @@ include("nature/energy.jl")
include
(
"nature/nature.jl"
)
include
(
"nature/macros.jl"
)
include
(
"nature/populations.jl"
)
include
(
"nature/individuals.jl"
)
include
(
"nature/ecologicaldata.jl"
)
include
(
"nature/species/skylark.jl"
)
include
(
"nature/species/wolpertinger.jl"
)
...
...
This diff is collapsed.
Click to expand it.
src/nature/individuals.jl
0 → 100644
+
194
−
0
View file @
74d43c05
### Persefone.jl - a model of agricultural landscapes and ecosystems in Europe.
###
### This file contains life-history and other ecological functions that apply to
### all animal individuals, such reproduction, death, and movement.
###
"""
reproduce!(animal, model, mate, n=1)
Produce one or more offspring for the given animal at its current location.
The `mate` argument gives the ID of the reproductive partner.
"""
function
reproduce!
(
animal
::
Animal
,
model
::
SimulationModel
,
n
::
Int64
=
1
,
mate
::
Int64
=-
1
)
(
animal
.
sex
==
male
)
&&
@warn
"Male
$
(animalid(animal)) is reproducing."
for
i
in
1
:
n
if
animal
.
sex
==
hermaphrodite
sex
=
hermaphrodite
else
sex
=
@rand
([
male
,
female
])
end
bphase
=
populationparameters
(
typeof
(
animal
))
.
birthphase
#TODO add DEB?
child
=
typeof
(
animal
)(
length
(
model
.
animals
)
+
1
,
sex
,
(
animal
.
id
,
mate
),
animal
.
pos
,
bphase
)
push!
(
model
.
animals
,
child
)
push!
(
animal
.
offspring
,
child
.
id
)
mate
>
0
&&
push!
(
model
.
animals
[
mate
]
.
offspring
,
child
.
id
)
push!
(
model
.
landscape
[
child
.
pos
...
]
.
animals
,
child
.
id
)
create!
(
child
,
model
)
end
@debug
"
$
(animalid(animal)) has reproduced."
end
"""
kill!(animal, model, probability=1.0, cause="")
Kill this animal, optionally with a given percentage probability.
Returns true if the animal dies, false if not.
"""
function
kill!
(
animal
::
Animal
,
model
::
SimulationModel
,
probability
::
Float64
=
1.0
,
cause
::
String
=
""
)
if
@rand
()
<
probability
# remove the animal's location and territory pointers from the landscape
filter!
(
x
->
x!
=
animal
.
id
,
model
.
landscape
[
animal
.
pos
...
]
.
animals
)
for
pos
in
animal
.
territory
filter!
(
x
->
x!
=
animal
.
id
,
model
.
landscape
[
pos
...
]
.
territories
)
end
# print the epitaph and remove the animal from the model
postfix
=
isempty
(
cause
)
?
"."
:
" from
$
cause."
@debug
"
$
(animalid(animal)) has died
$(postfix)
"
model
.
animals
[
animal
.
id
]
=
nothing
return
true
end
return
false
end
"""
migrate!(animal, model, arrival)
Remove this animal from the map and add it to the migrant species pool.
It will be returned to its current location at the specified `arrival` date.
"""
function
migrate!
(
animal
::
Animal
,
model
::
SimulationModel
,
arrival
::
Date
)
# keep model.migrants sorted by inserting the new migrant after migrants
# that will return earlier than it
i
=
findfirst
(
m
->
m
.
second
>=
arrival
,
model
.
migrants
)
if
isnothing
(
i
)
push!
(
model
.
migrants
,
Pair
(
animal
,
arrival
))
else
insert!
(
model
.
migrants
,
i
,
Pair
(
animal
,
arrival
))
end
filter!
(
x
->
x!
=
animal
.
id
,
model
.
landscape
[
animal
.
pos
...
]
.
animals
)
model
.
animals
[
animal
.
id
]
=
nothing
@debug
"
$
(animalid(animal)) has migrated."
end
"""
occupy!(animal, model, position)
Add the given location to the animal's territory.
"""
function
occupy!
(
animal
::
Animal
,
model
::
SimulationModel
,
position
::
Tuple
{
Int64
,
Int64
})
if
isoccupied
(
model
,
speciesof
(
animal
),
position
)
#XXX should this be an error?
@warn
"Position
$
position is already occupied by a
$
(speciesof(animal))."
end
push!
(
animal
.
territories
,
position
)
push!
(
model
.
landscape
[
position
...
],
animal
.
id
)
end
"""
vacate!(animal, model, position)
Remove this position from the animal's territory.
"""
function
vacate!
(
animal
::
Animal
,
model
::
SimulationModel
,
position
::
Tuple
{
Int64
,
Int64
})
filter!
(
x
->
x!
=
position
,
animal
.
territory
)
filter!
(
x
->
x!
=
animal
.
id
,
model
.
landscape
[
position
...
]
.
territories
)
end
"""
vacate!(animal, model)
Remove the animal's complete territory.
"""
function
vacate!
(
animal
::
Animal
,
model
::
SimulationModel
)
for
pos
in
animal
.
territory
filter!
(
x
->
x!
=
animal
.
id
,
model
.
landscape
[
pos
...
]
.
territories
)
end
animal
.
territory
=
Vector
{
Tuple
{
Int64
,
Int64
}}()
end
"""
followanimal!(follower, leader, model, distance=0)
Move the follower animal to a location near the leading animal.
"""
function
followanimal!
(
follower
::
Animal
,
leader
::
Animal
,
model
::
SimulationModel
,
distance
::
Length
=
0
m
)
#TODO test function
dist
=
Int
(
floor
(
distance
/
@param
(
world
.
mapresolution
)))
spacing
=
Tuple
(
@rand
(
-
dist
:
dist
,
2
))
targetposition
=
safebounds
(
spacing
.+
leader
.
pos
,
model
)
move!
(
follower
,
model
,
targetposition
)
end
"""
move!(animal, model, position)
Move the animal to the given position, making sure that this is in-bounds.
If the position is out of bounds, the animal stops at the map edge.
"""
function
move!
(
animal
::
Animal
,
model
::
SimulationModel
,
position
::
Tuple
{
Int64
,
Int64
})
#XXX should this function give some sort of warning (e.g. return false)
# if the original position is not reachable?
filter!
(
x
->
x
!=
animal
.
id
,
model
.
landscape
[
animal
.
pos
...
]
.
animals
)
animal
.
pos
=
safebounds
(
position
,
model
)
push!
(
model
.
landscape
[
animal
.
pos
...
]
.
animals
,
animal
.
id
)
end
"""
walk!(animal, model, direction, distance=1pixel)
Let the animal move a given number of steps in the given direction ("
north
", "
northeast
",
"
east
", "
southeast
", "
south
", "
southwest
", "
west
", "
northwest
", "
random
").
"""
function
walk!
(
animal
::
Animal
,
model
::
SimulationModel
,
direction
::
String
,
distance
::
Length
=-
1
m
)
distance
<
0
m
?
steps
=
1
:
steps
=
Int
(
floor
(
distance
/
@param
(
world
.
mapresolution
)))
if
direction
==
"north"
shift
=
(
0
,
-
steps
)
elseif
direction
==
"northeast"
shift
=
(
steps
,
-
steps
)
elseif
direction
==
"east"
shift
=
(
steps
,
0
)
elseif
direction
==
"southeast"
shift
=
(
steps
,
steps
)
elseif
direction
==
"south"
shift
=
(
0
,
steps
)
elseif
direction
==
"southwest"
shift
=
(
-
steps
,
steps
)
elseif
direction
==
"west"
shift
=
(
-
steps
,
0
)
elseif
direction
==
"northwest"
shift
=
(
-
steps
,
-
steps
)
elseif
direction
==
"random"
shift
=
Tuple
(
@rand
([
-
steps
,
0
,
steps
],
2
))
else
@error
"Invalid direction in @walk: "
*
direction
end
walk!
(
animal
,
model
,
shift
)
end
"""
walk!(animal, model, direction, distance=-1)
Let the animal move in the given direction, where the direction is
defined by an (x, y) tuple to specify the shift in coordinates.
If maxdist >= 0, move no further than the specified distance.
"""
function
walk!
(
animal
::
Animal
,
model
::
SimulationModel
,
direction
::
Tuple
{
Int64
,
Int64
},
maxdist
::
Length
=-
1
m
)
#TODO test
distance
=
Int
(
floor
(
maxdist
/
@param
(
world
.
mapresolution
)))
if
distance
>=
0
direction
[
1
]
>
distance
&&
(
direction
[
1
]
=
distance
)
direction
[
2
]
>
distance
&&
(
direction
[
2
]
=
distance
)
direction
[
1
]
<
-
distance
&&
(
direction
[
1
]
=
-
distance
)
direction
[
2
]
<
-
distance
&&
(
direction
[
2
]
=
-
distance
)
end
newpos
=
animal
.
pos
.+
direction
move!
(
animal
,
model
,
newpos
)
end
#TODO add a walk function with a habitat descriptor
##TODO add walktoward or similar function (incl. pathfinding?)
This diff is collapsed.
Click to expand it.
src/nature/populations.jl
+
2
−
193
View file @
74d43c05
### Persefone.jl - a model of agricultural landscapes and ecosystems in Europe.
###
### This file contains
a set of utility functions for species, including initialisation,
###
reproduction, and mortality
.
### This file contains
functions that apply to all animal populations, such as for
###
initialisation, or querying for neighbours
.
###
##TODO move the life-history functions into a new file `individuals.jl`
"""
PopInitParams
...
...
@@ -141,89 +139,6 @@ end
#XXX initpopulation with dispersal from an original source?
#XXX initpopulation based on known occurences in real-life?
"""
reproduce!(animal, model, mate, n=1)
Produce one or more offspring for the given animal at its current location.
The `mate` argument gives the ID of the reproductive partner.
"""
function
reproduce!
(
animal
::
Animal
,
model
::
SimulationModel
,
n
::
Int64
=
1
,
mate
::
Int64
=-
1
)
(
animal
.
sex
==
male
)
&&
@warn
"Male
$
(animalid(animal)) is reproducing."
for
i
in
1
:
n
if
animal
.
sex
==
hermaphrodite
sex
=
hermaphrodite
else
sex
=
@rand
([
male
,
female
])
end
bphase
=
populationparameters
(
typeof
(
animal
))
.
birthphase
#TODO add DEB?
child
=
typeof
(
animal
)(
length
(
model
.
animals
)
+
1
,
sex
,
(
animal
.
id
,
mate
),
animal
.
pos
,
bphase
)
push!
(
model
.
animals
,
child
)
push!
(
animal
.
offspring
,
child
.
id
)
mate
>
0
&&
push!
(
model
.
animals
[
mate
]
.
offspring
,
child
.
id
)
push!
(
model
.
landscape
[
child
.
pos
...
]
.
animals
,
child
.
id
)
create!
(
child
,
model
)
end
@debug
"
$
(animalid(animal)) has reproduced."
end
"""
kill!(animal, model, probability=1.0, cause="")
Kill this animal, optionally with a given percentage probability.
Returns true if the animal dies, false if not.
"""
function
kill!
(
animal
::
Animal
,
model
::
SimulationModel
,
probability
::
Float64
=
1.0
,
cause
::
String
=
""
)
if
@rand
()
<
probability
# remove the animal's location and territory pointers from the landscape
filter!
(
x
->
x!
=
animal
.
id
,
model
.
landscape
[
animal
.
pos
...
]
.
animals
)
for
pos
in
animal
.
territory
filter!
(
x
->
x!
=
animal
.
id
,
model
.
landscape
[
pos
...
]
.
territories
)
end
# print the epitaph and remove the animal from the model
postfix
=
isempty
(
cause
)
?
"."
:
" from
$
cause."
@debug
"
$
(animalid(animal)) has died
$(postfix)
"
model
.
animals
[
animal
.
id
]
=
nothing
return
true
end
return
false
end
"""
migrate!(animal, model, arrival)
Remove this animal from the map and add it to the migrant species pool.
It will be returned to its current location at the specified `arrival` date.
"""
function
migrate!
(
animal
::
Animal
,
model
::
SimulationModel
,
arrival
::
Date
)
# keep model.migrants sorted by inserting the new migrant after migrants
# that will return earlier than it
i
=
findfirst
(
m
->
m
.
second
>=
arrival
,
model
.
migrants
)
if
isnothing
(
i
)
push!
(
model
.
migrants
,
Pair
(
animal
,
arrival
))
else
insert!
(
model
.
migrants
,
i
,
Pair
(
animal
,
arrival
))
end
filter!
(
x
->
x!
=
animal
.
id
,
model
.
landscape
[
animal
.
pos
...
]
.
animals
)
model
.
animals
[
animal
.
id
]
=
nothing
@debug
"
$
(animalid(animal)) has migrated."
end
"""
occupy!(animal, model, position)
Add the given location to the animal's territory.
"""
function
occupy!
(
animal
::
Animal
,
model
::
SimulationModel
,
position
::
Tuple
{
Int64
,
Int64
})
if
isoccupied
(
model
,
speciesof
(
animal
),
position
)
#XXX should this be an error?
@warn
"Position
$
position is already occupied by a
$
(speciesof(animal))."
end
push!
(
animal
.
territories
,
position
)
push!
(
model
.
landscape
[
position
...
],
animal
.
id
)
end
"""
isoccupied(model, position, species)
...
...
@@ -236,28 +151,6 @@ function isoccupied(model::SimulationModel, species::String, position::Tuple{Int
return
false
end
"""
vacate!(animal, model, position)
Remove this position from the animal's territory.
"""
function
vacate!
(
animal
::
Animal
,
model
::
SimulationModel
,
position
::
Tuple
{
Int64
,
Int64
})
filter!
(
x
->
x!
=
position
,
animal
.
territory
)
filter!
(
x
->
x!
=
animal
.
id
,
model
.
landscape
[
position
...
]
.
territories
)
end
"""
vacate!(animal, model)
Remove the animal's complete territory.
"""
function
vacate!
(
animal
::
Animal
,
model
::
SimulationModel
)
for
pos
in
animal
.
territory
filter!
(
x
->
x!
=
animal
.
id
,
model
.
landscape
[
pos
...
]
.
territories
)
end
animal
.
territory
=
Vector
{
Tuple
{
Int64
,
Int64
}}()
end
"""
isalive(id, model)
...
...
@@ -346,87 +239,3 @@ function distanceto(pos::Tuple{Int64,Int64}, model::SimulationModel, animal::Ani
#XXX this is very imprecise because diagonal distances are not calculated trigonometrically
maximum
(
abs
.
(
animal
.
pos
.-
pos
))
*
@param
(
world
.
mapresolution
)
end
"""
followanimal!(follower, leader, model, distance=0)
Move the follower animal to a location near the leading animal.
"""
function
followanimal!
(
follower
::
Animal
,
leader
::
Animal
,
model
::
SimulationModel
,
distance
::
Length
=
0
m
)
#TODO test function
dist
=
Int
(
floor
(
distance
/
@param
(
world
.
mapresolution
)))
spacing
=
Tuple
(
@rand
(
-
dist
:
dist
,
2
))
targetposition
=
safebounds
(
spacing
.+
leader
.
pos
,
model
)
move!
(
follower
,
model
,
targetposition
)
end
"""
move!(animal, model, position)
Move the animal to the given position, making sure that this is in-bounds.
If the position is out of bounds, the animal stops at the map edge.
"""
function
move!
(
animal
::
Animal
,
model
::
SimulationModel
,
position
::
Tuple
{
Int64
,
Int64
})
#XXX should this function give some sort of warning (e.g. return false)
# if the original position is not reachable?
filter!
(
x
->
x
!=
animal
.
id
,
model
.
landscape
[
animal
.
pos
...
]
.
animals
)
animal
.
pos
=
safebounds
(
position
,
model
)
push!
(
model
.
landscape
[
animal
.
pos
...
]
.
animals
,
animal
.
id
)
end
"""
walk!(animal, model, direction, distance=1pixel)
Let the animal move a given number of steps in the given direction ("
north
", "
northeast
",
"
east
", "
southeast
", "
south
", "
southwest
", "
west
", "
northwest
", "
random
").
"""
function
walk!
(
animal
::
Animal
,
model
::
SimulationModel
,
direction
::
String
,
distance
::
Length
=-
1
m
)
distance
<
0
m
?
steps
=
1
:
steps
=
Int
(
floor
(
distance
/
@param
(
world
.
mapresolution
)))
if
direction
==
"north"
shift
=
(
0
,
-
steps
)
elseif
direction
==
"northeast"
shift
=
(
steps
,
-
steps
)
elseif
direction
==
"east"
shift
=
(
steps
,
0
)
elseif
direction
==
"southeast"
shift
=
(
steps
,
steps
)
elseif
direction
==
"south"
shift
=
(
0
,
steps
)
elseif
direction
==
"southwest"
shift
=
(
-
steps
,
steps
)
elseif
direction
==
"west"
shift
=
(
-
steps
,
0
)
elseif
direction
==
"northwest"
shift
=
(
-
steps
,
-
steps
)
elseif
direction
==
"random"
shift
=
Tuple
(
@rand
([
-
steps
,
0
,
steps
],
2
))
else
@error
"Invalid direction in @walk: "
*
direction
end
walk!
(
animal
,
model
,
shift
)
end
"""
walk!(animal, model, direction, distance=-1)
Let the animal move in the given direction, where the direction is
defined by an (x, y) tuple to specify the shift in coordinates.
If maxdist >= 0, move no further than the specified distance.
"""
function
walk!
(
animal
::
Animal
,
model
::
SimulationModel
,
direction
::
Tuple
{
Int64
,
Int64
},
maxdist
::
Length
=-
1
m
)
#TODO test
distance
=
Int
(
floor
(
maxdist
/
@param
(
world
.
mapresolution
)))
if
distance
>=
0
direction
[
1
]
>
distance
&&
(
direction
[
1
]
=
distance
)
direction
[
2
]
>
distance
&&
(
direction
[
2
]
=
distance
)
direction
[
1
]
<
-
distance
&&
(
direction
[
1
]
=
-
distance
)
direction
[
2
]
<
-
distance
&&
(
direction
[
2
]
=
-
distance
)
end
newpos
=
animal
.
pos
.+
direction
move!
(
animal
,
model
,
newpos
)
end
#TODO add a walk function with a habitat descriptor
##TODO add walktoward or similar function (incl. pathfinding?)
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