diff --git a/Makefile b/Makefile index 6ef66c43114fc977d5235100e836e76a6907ca46..91edc67485a55575d77fac94f4b49a0d8b6abf53 100644 --- a/Makefile +++ b/Makefile @@ -11,12 +11,14 @@ test: # running test suite cd test; julia runtests.jl -commit = $(shell git log --format="%cd (commit %h)" --date=short -1) +date = $(shell date +%F) +commit = $(shell git log --format="%h" -1) +version = $(shell grep "version" Project.toml | sed 's/[[:alpha:]|=|"|[:space:]]//g') docs: # building documentation - # include a date stamp with the latest commit - sed -i -e "s/\*Last updated:.*/\*Last updated: ${commit}\*/" docs/src/index.md + # include the version, date, and latest commit in the footer of the index page + sed -i -e "s/\*This documentation was last updated.*/\*This documentation was last updated on ${date} for \*\*Persefone.jl v${version}\*\* (commit [${commit}](https\:\/\/git\.idiv\.de\/persefone\/persefone\-model\/\-\/commit\/${commit})).\*/" docs/src/index.md cd docs; julia builddocs.jl profile: diff --git a/docs/builddocs.jl b/docs/builddocs.jl index 8494b6c139f3a0b145bf265ee9f920c11658af68..17c42ae840117ec145d5dca3928292d545b5a950 100644 --- a/docs/builddocs.jl +++ b/docs/builddocs.jl @@ -14,7 +14,7 @@ using Documenter, Persefone #TODO add a changelog: https://keepachangelog.com/en/1.0.0/ -makedocs(sitename="Persefone", +makedocs(sitename="Persefone.jl", modules = [Persefone], repo = Remotes.GitLab("git.idiv.de", "persefone", "persefone-model"), format = Documenter.HTML(prettyurls = false), diff --git a/docs/src/adapting.md b/docs/src/adapting.md index 66dc380b1d517fda493dc5f50614b9e90f98afe1..681d1b6e6d26dd05bd364e012850c647d6d56f1d 100644 --- a/docs/src/adapting.md +++ b/docs/src/adapting.md @@ -43,13 +43,8 @@ In particular, you need to understand how initialisation and scheduling works in [`src/core/simulation.jl`](https://git.idiv.de/xo30xoqa/persephone/-/blob/master/src/core/simulation.jl), and what information is stored in the `model` object. -If you want to add a new agent type, use Agents.jl's -[`@agent`](https://juliadynamics.github.io/Agents.jl/stable/tutorial/#Agents.@agent) -macro. (But be aware that Persefone already has three agent types and you may encounter -[performance problems](https://juliadynamics.github.io/Agents.jl/stable/performance_tips/#Avoid-Unions-of-many-different-agent-types-(temporary!)-1).) -Having implemented the new agent type, add it to the `model` objects type definition -and scheduler, and write an initialisation function and a `stepagent!` function. -(See [`Persefone.initmodel`](@ref) and [`stepsimulation!`](@ref) for details.) +If you want to add a new agent type, create a subtype of [`ModelAgent`](@ref), +implement a [`stepagent!`](@ref) function for it and add it to [`Persefone.initmodel`](@ref). ### Linking to another model diff --git a/docs/src/architecture.md b/docs/src/architecture.md index 1712124a2e15628dfec9361eb1e5a059f5d63cf0..f0464bc4e5d433a1b288ee1e7ec0b2c907d87591 100644 --- a/docs/src/architecture.md +++ b/docs/src/architecture.md @@ -6,9 +6,9 @@ Persefone is divided into four components, three of which are semi-independent submodels: -1. `core`: This is the foundation of the model software, which sets up and executes - simulation runs. It also reads in the configuration file and landscape maps, and - provides data output functionality. (Eventually, it will also provide weather data.) +1. `core` and `world`: These two directories provide the foundation of the model software, + which sets up and executes simulation runs. It also reads all input files (the configuration + file, landscape maps, and weather data), and provides data output functionality. 2. `nature`: This is an individual-based model of species in agricultural landscapes. It defines the [`Animal`](@ref) agent type, and a set of macros that can be used to rapidly @@ -33,19 +33,15 @@ the `Animal`s in the model landscape. ### The `model` object A cursory reading of the source code will quickly show that most functions take an -`SimulationModel` object as one of their arguments. This is the key data structure -of [Agents.jl](https://juliadynamics.github.io/Agents.jl/stable/tutorial/#.-The-model-1), -and holds all state that is in any way relevant to a simulation run. (Persefone has -a strict "no global state" policy to avoid state-dependent bugs and allow parallelisation.) -The model object gives access to all agent instances (via `model[id]`, where `id` is the -unique identifier of this agent). It also stores the configuration (`model.settings`), +`SimulationModel` object as one of their arguments. The concrete type for this is +[`AgricultureModel`](@ref), a struct that holds all state that is in any way relevant +to a simulation run. (Persefone has a strict "no global state" policy to avoid +state-dependent bugs and allow parallelisation.) The model object gives access to all +agent instances. It also stores the configuration (`model.settings`), the landscape (`model.landscape`, a matrix of [`Pixel`](@ref) objects that store the local land cover, amongst other things), and the current simulation date (`model.date`). (See [`Persefone.initmodel`](@ref) for details.) -For more information about working with agent objects, see the -[Agents.jl API](https://juliadynamics.github.io/Agents.jl/stable/api/). - ### Model configuration/the `@param` macro The model is configured via a [TOML](https://toml.io/en/) file, the default version of which is at diff --git a/docs/src/assets/architecture.png b/docs/src/assets/architecture.png index bf109d5137a8f8f832e6ffb12df40bf2fc5ec91e..ead154a03211bf85238b8108ff9ee66b1940ce9e 100644 Binary files a/docs/src/assets/architecture.png and b/docs/src/assets/architecture.png differ diff --git a/docs/src/assets/architecture.svg b/docs/src/assets/architecture.svg index be710384808f4ef0788aa55ca442dcacb13d02a6..5bca77162436a231811599578b1aa94b7a7a01d3 100644 --- a/docs/src/assets/architecture.svg +++ b/docs/src/assets/architecture.svg @@ -7,9 +7,9 @@ viewBox="0 0 100 80" version="1.1" id="svg5" - inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)" + inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)" sodipodi:docname="architecture.svg" - inkscape:export-filename="/home/xo30xoqa/Documents/Promotion/Persephone/docs/src/assets/architecture.png" + inkscape:export-filename="architecture.png" inkscape:export-xdpi="300" inkscape:export-ydpi="300" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" @@ -27,17 +27,19 @@ inkscape:document-units="mm" showgrid="false" inkscape:zoom="1.8" - inkscape:cx="195.83333" - inkscape:cy="143.61111" + inkscape:cx="196.11111" + inkscape:cy="143.88889" inkscape:window-width="1920" inkscape:window-height="1016" inkscape:window-x="0" - inkscape:window-y="27" + inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="layer1" width="100mm" height="160px" - units="px" /> + units="px" + inkscape:showpageshadow="2" + inkscape:deskcolor="#d1d1d1" /> <defs id="defs2"> <clipPath @@ -131,7 +133,7 @@ y="30.08935">Farmer</tspan></text> <g id="g20748" - transform="translate(33.763864,-9.8749511)"> + transform="translate(19.055834,6.3281353)"> <path d="m 21.677551,59.233303 -2.098905,-0.66097 -0.360479,-0.90155 -0.06369,0.46667 -0.839494,-0.53621 0.327341,-0.37702 -0.488348,-1.21654 1.896754,1.47761 0.09433,0.75622 z m -10.380146,-0.99456 -0.02956,0.0295 -0.06769,-0.0377 z m 11.003754,2.62282 c -1.012697,-0.081 -2.045257,-0.39522 -3.118963,-0.99918 -0.992493,-0.55831 -2.047012,-0.9591 -3.128447,-1.20237 l 0.957754,-0.67304 -0.981868,-1.52118 0.663797,-0.80202 -0.414896,-0.99569 -1.880678,0.88504 1.901435,-1.81847 6.365701,5.31045 -0.09202,0.45942 0.296667,-0.0775 -0.337812,0.28281 -0.09917,0.49506 -0.04687,0.23415 0.350777,-0.12005 -0.409692,0.41407 z m 1.02212,-0.0641 -0.337812,-0.18804 0.369256,0.031 z M 9.1668722,59.590103 c 7.6798988,-1.92007 7.7635428,4.80676 13.6361228,3.33857 -5.668766,2.62662 -6.305185,-4.17874 -13.6361228,-3.33857 m 16.1832158,-0.80774 -4.950611,-4.50147 -1.382876,1.24456 -2.682723,-2.32323 -3.813033,3.81307 -0.01398,-0.0698 -0.375169,-0.14431 0.346897,0.019 -0.09935,-0.51182 -0.247546,-0.0906 h 0.229407 l -0.229407,-1.14518 -0.178376,0.8907 0.178376,-0.0472 -0.193497,0.12264 -0.103139,0.51486 0.296636,-0.0774 -0.33775,0.28278 -0.0992,0.49506 -0.0469,0.23415 0.350809,-0.12005 -0.409692,0.41416 -0.03825,0.19091 -0.02947,-0.14718 -0.06181,-0.30849 -0.375169,-0.14435 0.346897,0.019 -0.09935,-0.51181 -0.247546,-0.0906 h 0.229376 l -0.229376,-1.14518 -0.178407,0.89071 0.178407,-0.0472 -0.193528,0.12263 -0.103108,0.51486 0.296636,-0.0774 -0.337781,0.28272 -0.09917,0.49506 -0.0469,0.23418 0.350808,-0.12005 -0.409723,0.41413 -0.0874,0.43633 c -0.049,0.0135 -0.09793,0.0274 -0.14681,0.0415 l -0.4313108,-0.24012 0.4089528,0.0343 -0.08786,-0.43883 -0.06184,-0.30852 -0.3751378,-0.14432 0.3468658,0.019 -0.09932,-0.51181 -0.2475458,-0.0906 h 0.229407 l -0.229407,-1.14516 -0.178407,0.89071 0.178407,-0.0472 -0.193497,0.12266 -0.103139,0.51487 0.296636,-0.0775 -0.337781,0.28278 -0.09913,0.49506 -0.0469,0.23418 0.350777,-0.12008 -0.409692,0.41419 -0.107142,0.53476 c -0.429495,0.17702 -0.85092,0.38081 -1.2616899,0.61187 1.9391609,-0.60944 3.5902477,-0.96862 5.1902727,-0.89862 l 0.03813,-0.19048 0.204861,-0.20708 -0.175419,0.06 0.02347,-0.11705 0.04958,-0.24752 0.16889,-0.14139 -0.148318,0.0387 0.05155,-0.2574 0.09676,-0.0614 -0.08919,0.0236 0.08919,-0.44536 0.114688,0.57258 h -0.114688 l 0.123773,0.0453 0.04968,0.25589 -0.173449,-0.009 0.187554,0.0721 0.03092,0.15427 0.04395,0.21942 -0.204491,-0.0172 0.226296,0.12599 0.03536,0.17656 c 0.15306,0.0178 0.305906,0.04 0.458751,0.0664 l 0.40963,-0.41404 -0.350746,0.11999 0.04687,-0.23415 0.09917,-0.49506 0.337781,-0.28275 -0.296667,0.0775 0.103139,-0.51487 0.193528,-0.12263 -0.178407,0.0471 0.178407,-0.89071 0.229376,1.14518 h -0.229376 l 0.247546,0.0906 0.09932,0.51181 -0.346866,-0.019 0.375138,0.14429 0.06178,0.30852 0.08793,0.43886 -0.409015,-0.0343 0.452623,0.25198 0.03027,0.15106 c 0.979651,0.31108 1.981445,0.81316 3.059462,1.54764 2.787864,1.89965 7.202947,1.18072 9.286146,-1.49541 -0.892188,0.50193 -1.770456,0.89961 -2.649401,1.15427 l -0.01528,-0.0762 -0.226327,-0.12599 0.204553,0.0171 -0.04401,-0.2194 -0.03089,-0.15423 -0.187553,-0.0722 0.173448,0.01 -0.04971,-0.25598 -0.123742,-0.0453 h 0.114718 l -0.114718,-0.57254 -0.08922,0.44538 0.08922,-0.0236 -0.09676,0.0613 -0.05156,0.25755 0.148319,-0.0388 -0.168922,0.14139 -0.04955,0.24751 -0.02344,0.11703 0.175388,-0.06 -0.204892,0.20708 -0.05962,0.29784 h 3.08e-4 c -0.01799,0.004 -0.03603,0.007 -0.05402,0.0111 l -0.02063,-0.10326 -0.3594,-0.20015 0.324754,0.0272 -0.06982,-0.34844 -0.04906,-0.24502 -0.297929,-0.1146 0.275478,0.0151 -0.0789,-0.40649 -0.196577,-0.0719 h 0.182133 l -0.182133,-0.90937 -0.141666,0.70735 0.141666,-0.0374 -0.153708,0.0974 -0.08186,0.40886 0.235566,-0.0615 -0.268211,0.22455 -0.07878,0.39318 -0.0372,0.18592 0.278589,-0.0953 -0.325401,0.32884 -0.0027,0.0132 -0.06766,-0.33803 -0.06184,-0.30853 -0.375107,-0.14431 0.346866,0.019 -0.09935,-0.51178 -0.247515,-0.0906 h 0.229375 l -0.229375,-1.14521 -0.178407,0.89071 0.178407,-0.0472 -0.193559,0.12266 -0.01004,0.05 -1.648099,-1.56032 2.161145,0.25872 -2.005128,-1.13394 0.117521,0.4909 -1.085531,-0.94725 -0.554099,0.0383 -0.303319,-0.28718 1.770055,0.2351 -0.138278,-0.77439 z" style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.031;stroke-miterlimit:4;stroke-dasharray:none" @@ -151,31 +153,26 @@ </g> <g id="g20758" - transform="translate(-17.191961,-9.9021151)"> + transform="translate(-17.191961,-11.392119)"> <g id="g1709" transform="matrix(0.03759233,0,0,0.03759233,20.02845,40.979859)"> - <path - d="M 575.833,400 H 424.167 C 411.067,400 400,411.066 400,424.167 v 151.667 c 0,13.1 11.067,24.166 24.167,24.166 H 575.833 C 588.933,600 600,588.934 600,575.842 V 424.167 C 600,411.067 588.933,400 575.833,400 Z m -151.666,8.333 h 151.666 c 8.584,0 15.834,7.25 15.834,15.833 V 450 H 408.333 v -25.833 c 0,-8.584 7.25,-15.834 15.834,-15.834 z M 575.833,591.667 H 424.167 c -8.583,0 -15.833,-7.25 -15.833,-15.834 v -117.5 h 183.333 v 117.5 c 0,8.584 -7.25,15.834 -15.834,15.834 z" - id="path1699" /> - - <path - d="m 462.5,434.167 h 0.833 c 2.3,0 4.167,-1.867 4.167,-4.167 0,-2.3 -1.867,-4.167 -4.167,-4.167 H 462.5 c -2.3,0 -4.167,1.858 -4.167,4.167 0,2.308 1.867,4.167 4.167,4.167 z" - id="path1701" /> - - <path - d="m 537.5,434.167 c 2.3,0 4.167,-1.867 4.167,-4.167 0,-2.3 -1.867,-4.167 -4.167,-4.167 h -0.833 c -2.3,0 -3.75,1.867 -3.75,4.167 0,2.3 2.283,4.167 4.583,4.167 z" - id="path1703" /> - - <path - d="m 536.016,483.6 -17.5,6.667 c -2.158,0.825 -3.233,3.225 -2.408,5.383 0.816,2.15 3.233,3.225 5.375,2.408 l 11.85,-4.517 v 68.125 c 0,2.3 1.867,4.166 4.167,4.166 2.3,0 4.167,-1.866 4.167,-4.166 V 487.5 c 0,-1.375 -0.675,-2.65 -1.809,-3.434 -1.125,-0.783 -2.566,-0.941 -3.842,-0.466 z" - id="path1705" /> - - <path - d="m 479.366,519.45 23.867,-29.325 c 1.017,-1.242 1.217,-2.967 0.533,-4.417 -0.691,-1.45 -2.158,-2.375 -3.767,-2.375 h -44.167 c -2.3,0 -4.167,1.867 -4.167,4.167 0,2.3 1.866,4.167 4.167,4.167 h 35.4 L 467.6,520.7 c -1.05,1.291 -1.233,3.083 -0.458,4.558 0.767,1.483 2.342,2.467 4.008,2.226 4.175,-0.275 16.15,0.149 21.725,6.066 2.684,2.842 3.667,6.684 2.992,11.733 -1.208,9.066 -7.458,12.108 -12.483,13.059 -10.2,1.934 -23.167,-3.009 -27.25,-10.367 -1.117,-2 -3.65,-2.725 -5.667,-1.616 -2.017,1.125 -2.742,3.649 -1.617,5.675 4.958,8.925 17.708,15.075 29.875,15.075 2.1,-0.009 4.183,-0.184 6.208,-0.566 10.767,-2.042 17.75,-9.384 19.191,-20.142 1.017,-7.608 -0.733,-13.851 -5.2,-18.575 -5.291,-5.618 -13.357,-7.668 -19.558,-8.376 z" - id="path1707" /> - -</g> + <path + d="M 575.833,400 H 424.167 C 411.067,400 400,411.066 400,424.167 v 151.667 c 0,13.1 11.067,24.166 24.167,24.166 H 575.833 C 588.933,600 600,588.934 600,575.842 V 424.167 C 600,411.067 588.933,400 575.833,400 Z m -151.666,8.333 h 151.666 c 8.584,0 15.834,7.25 15.834,15.833 V 450 H 408.333 v -25.833 c 0,-8.584 7.25,-15.834 15.834,-15.834 z M 575.833,591.667 H 424.167 c -8.583,0 -15.833,-7.25 -15.833,-15.834 v -117.5 h 183.333 v 117.5 c 0,8.584 -7.25,15.834 -15.834,15.834 z" + id="path1699" /> + <path + d="m 462.5,434.167 h 0.833 c 2.3,0 4.167,-1.867 4.167,-4.167 0,-2.3 -1.867,-4.167 -4.167,-4.167 H 462.5 c -2.3,0 -4.167,1.858 -4.167,4.167 0,2.308 1.867,4.167 4.167,4.167 z" + id="path1701" /> + <path + d="m 537.5,434.167 c 2.3,0 4.167,-1.867 4.167,-4.167 0,-2.3 -1.867,-4.167 -4.167,-4.167 h -0.833 c -2.3,0 -3.75,1.867 -3.75,4.167 0,2.3 2.283,4.167 4.583,4.167 z" + id="path1703" /> + <path + d="m 536.016,483.6 -17.5,6.667 c -2.158,0.825 -3.233,3.225 -2.408,5.383 0.816,2.15 3.233,3.225 5.375,2.408 l 11.85,-4.517 v 68.125 c 0,2.3 1.867,4.166 4.167,4.166 2.3,0 4.167,-1.866 4.167,-4.166 V 487.5 c 0,-1.375 -0.675,-2.65 -1.809,-3.434 -1.125,-0.783 -2.566,-0.941 -3.842,-0.466 z" + id="path1705" /> + <path + d="m 479.366,519.45 23.867,-29.325 c 1.017,-1.242 1.217,-2.967 0.533,-4.417 -0.691,-1.45 -2.158,-2.375 -3.767,-2.375 h -44.167 c -2.3,0 -4.167,1.867 -4.167,4.167 0,2.3 1.866,4.167 4.167,4.167 h 35.4 L 467.6,520.7 c -1.05,1.291 -1.233,3.083 -0.458,4.558 0.767,1.483 2.342,2.467 4.008,2.226 4.175,-0.275 16.15,0.149 21.725,6.066 2.684,2.842 3.667,6.684 2.992,11.733 -1.208,9.066 -7.458,12.108 -12.483,13.059 -10.2,1.934 -23.167,-3.009 -27.25,-10.367 -1.117,-2 -3.65,-2.725 -5.667,-1.616 -2.017,1.125 -2.742,3.649 -1.617,5.675 4.958,8.925 17.708,15.075 29.875,15.075 2.1,-0.009 4.183,-0.184 6.208,-0.566 10.767,-2.042 17.75,-9.384 19.191,-20.142 1.017,-7.608 -0.733,-13.851 -5.2,-18.575 -5.291,-5.618 -13.357,-7.668 -19.558,-8.376 z" + id="path1707" /> + </g> <text xml:space="preserve" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;line-height:25%;font-family:'Latin Modern Mono Caps';-inkscape-font-specification:'Latin Modern Mono Caps, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" @@ -190,7 +187,7 @@ </g> <g id="g20772" - transform="translate(24.875916,-9.0367501)"> + transform="translate(9.611018,6.3048519)"> <g id="g2810" transform="matrix(1.2503212,0,0,1.2503212,-11.47161,-11.896543)"> @@ -254,7 +251,7 @@ </g> <g id="g20786" - transform="translate(-37.205577,5.1853828)"> + transform="translate(-22.497547,-11.368835)"> <g id="g2298" transform="matrix(0.04783691,0,0,0.04783691,40.809767,46.207054)"> @@ -317,7 +314,8 @@ y="66.894287">output</tspan></text> </g> <g - id="g65798"> + id="g65798" + transform="translate(15.264898,-16.550337)"> <g id="g2299" transform="matrix(0.74874537,0,0,0.74874537,30.945366,-5.3407431)"> @@ -356,7 +354,7 @@ id="tspan26337" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.29167px;font-family:'Latin Modern Mono';-inkscape-font-specification:'Latin Modern Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583" x="6.9151421" - y="41.859329">core</tspan></text> + y="41.859329">core+world</tspan></text> <text xml:space="preserve" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93889px;line-height:25%;font-family:'Latin Modern Mono Caps';-inkscape-font-specification:'Latin Modern Mono Caps, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" diff --git a/docs/src/assets/model_object.png b/docs/src/assets/model_object.png index d7d84bf9964495dd987ca937bc11fd8776a664cb..846bada21ddde03c725ed72f488a0183fb19d103 100644 Binary files a/docs/src/assets/model_object.png and b/docs/src/assets/model_object.png differ diff --git a/docs/src/assets/model_object.svg b/docs/src/assets/model_object.svg index 9379036a7a9689b47900fc44f9aaaff99d54e3c4..91038a823a0b9c0bf69822ded0e7df5b286e148b 100644 --- a/docs/src/assets/model_object.svg +++ b/docs/src/assets/model_object.svg @@ -7,9 +7,9 @@ viewBox="0 0 100 80" version="1.1" id="svg5" - inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)" + inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)" sodipodi:docname="model_object.svg" - inkscape:export-filename="/home/xo30xoqa/Documents/Promotion/Persephone/docs/src/assets/model_object.png" + inkscape:export-filename="model_object.png" inkscape:export-xdpi="300" inkscape:export-ydpi="300" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" @@ -27,17 +27,19 @@ inkscape:document-units="mm" showgrid="false" inkscape:zoom="1.8" - inkscape:cx="163.61111" - inkscape:cy="143.61111" + inkscape:cx="163.88889" + inkscape:cy="143.88889" inkscape:window-width="1920" inkscape:window-height="1016" inkscape:window-x="0" - inkscape:window-y="27" + inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="layer1" width="100mm" height="160px" - units="px" /> + units="px" + inkscape:showpageshadow="2" + inkscape:deskcolor="#d1d1d1" /> <defs id="defs2"> <clipPath @@ -125,31 +127,26 @@ </g> <g id="g67104" - transform="translate(26.537875,21.497315)"> + transform="translate(26.537875,20.476418)"> <g id="g1709" transform="matrix(0.03759233,0,0,0.03759233,-30.306482,-10.182581)"> - <path - d="M 575.833,400 H 424.167 C 411.067,400 400,411.066 400,424.167 v 151.667 c 0,13.1 11.067,24.166 24.167,24.166 H 575.833 C 588.933,600 600,588.934 600,575.842 V 424.167 C 600,411.067 588.933,400 575.833,400 Z m -151.666,8.333 h 151.666 c 8.584,0 15.834,7.25 15.834,15.833 V 450 H 408.333 v -25.833 c 0,-8.584 7.25,-15.834 15.834,-15.834 z M 575.833,591.667 H 424.167 c -8.583,0 -15.833,-7.25 -15.833,-15.834 v -117.5 h 183.333 v 117.5 c 0,8.584 -7.25,15.834 -15.834,15.834 z" - id="path1699" /> - - <path - d="m 462.5,434.167 h 0.833 c 2.3,0 4.167,-1.867 4.167,-4.167 0,-2.3 -1.867,-4.167 -4.167,-4.167 H 462.5 c -2.3,0 -4.167,1.858 -4.167,4.167 0,2.308 1.867,4.167 4.167,4.167 z" - id="path1701" /> - - <path - d="m 537.5,434.167 c 2.3,0 4.167,-1.867 4.167,-4.167 0,-2.3 -1.867,-4.167 -4.167,-4.167 h -0.833 c -2.3,0 -3.75,1.867 -3.75,4.167 0,2.3 2.283,4.167 4.583,4.167 z" - id="path1703" /> - - <path - d="m 536.016,483.6 -17.5,6.667 c -2.158,0.825 -3.233,3.225 -2.408,5.383 0.816,2.15 3.233,3.225 5.375,2.408 l 11.85,-4.517 v 68.125 c 0,2.3 1.867,4.166 4.167,4.166 2.3,0 4.167,-1.866 4.167,-4.166 V 487.5 c 0,-1.375 -0.675,-2.65 -1.809,-3.434 -1.125,-0.783 -2.566,-0.941 -3.842,-0.466 z" - id="path1705" /> - - <path - d="m 479.366,519.45 23.867,-29.325 c 1.017,-1.242 1.217,-2.967 0.533,-4.417 -0.691,-1.45 -2.158,-2.375 -3.767,-2.375 h -44.167 c -2.3,0 -4.167,1.867 -4.167,4.167 0,2.3 1.866,4.167 4.167,4.167 h 35.4 L 467.6,520.7 c -1.05,1.291 -1.233,3.083 -0.458,4.558 0.767,1.483 2.342,2.467 4.008,2.226 4.175,-0.275 16.15,0.149 21.725,6.066 2.684,2.842 3.667,6.684 2.992,11.733 -1.208,9.066 -7.458,12.108 -12.483,13.059 -10.2,1.934 -23.167,-3.009 -27.25,-10.367 -1.117,-2 -3.65,-2.725 -5.667,-1.616 -2.017,1.125 -2.742,3.649 -1.617,5.675 4.958,8.925 17.708,15.075 29.875,15.075 2.1,-0.009 4.183,-0.184 6.208,-0.566 10.767,-2.042 17.75,-9.384 19.191,-20.142 1.017,-7.608 -0.733,-13.851 -5.2,-18.575 -5.291,-5.618 -13.357,-7.668 -19.558,-8.376 z" - id="path1707" /> - -</g> + <path + d="M 575.833,400 H 424.167 C 411.067,400 400,411.066 400,424.167 v 151.667 c 0,13.1 11.067,24.166 24.167,24.166 H 575.833 C 588.933,600 600,588.934 600,575.842 V 424.167 C 600,411.067 588.933,400 575.833,400 Z m -151.666,8.333 h 151.666 c 8.584,0 15.834,7.25 15.834,15.833 V 450 H 408.333 v -25.833 c 0,-8.584 7.25,-15.834 15.834,-15.834 z M 575.833,591.667 H 424.167 c -8.583,0 -15.833,-7.25 -15.833,-15.834 v -117.5 h 183.333 v 117.5 c 0,8.584 -7.25,15.834 -15.834,15.834 z" + id="path1699" /> + <path + d="m 462.5,434.167 h 0.833 c 2.3,0 4.167,-1.867 4.167,-4.167 0,-2.3 -1.867,-4.167 -4.167,-4.167 H 462.5 c -2.3,0 -4.167,1.858 -4.167,4.167 0,2.308 1.867,4.167 4.167,4.167 z" + id="path1701" /> + <path + d="m 537.5,434.167 c 2.3,0 4.167,-1.867 4.167,-4.167 0,-2.3 -1.867,-4.167 -4.167,-4.167 h -0.833 c -2.3,0 -3.75,1.867 -3.75,4.167 0,2.3 2.283,4.167 4.583,4.167 z" + id="path1703" /> + <path + d="m 536.016,483.6 -17.5,6.667 c -2.158,0.825 -3.233,3.225 -2.408,5.383 0.816,2.15 3.233,3.225 5.375,2.408 l 11.85,-4.517 v 68.125 c 0,2.3 1.867,4.166 4.167,4.166 2.3,0 4.167,-1.866 4.167,-4.166 V 487.5 c 0,-1.375 -0.675,-2.65 -1.809,-3.434 -1.125,-0.783 -2.566,-0.941 -3.842,-0.466 z" + id="path1705" /> + <path + d="m 479.366,519.45 23.867,-29.325 c 1.017,-1.242 1.217,-2.967 0.533,-4.417 -0.691,-1.45 -2.158,-2.375 -3.767,-2.375 h -44.167 c -2.3,0 -4.167,1.867 -4.167,4.167 0,2.3 1.866,4.167 4.167,4.167 h 35.4 L 467.6,520.7 c -1.05,1.291 -1.233,3.083 -0.458,4.558 0.767,1.483 2.342,2.467 4.008,2.226 4.175,-0.275 16.15,0.149 21.725,6.066 2.684,2.842 3.667,6.684 2.992,11.733 -1.208,9.066 -7.458,12.108 -12.483,13.059 -10.2,1.934 -23.167,-3.009 -27.25,-10.367 -1.117,-2 -3.65,-2.725 -5.667,-1.616 -2.017,1.125 -2.742,3.649 -1.617,5.675 4.958,8.925 17.708,15.075 29.875,15.075 2.1,-0.009 4.183,-0.184 6.208,-0.566 10.767,-2.042 17.75,-9.384 19.191,-20.142 1.017,-7.608 -0.733,-13.851 -5.2,-18.575 -5.291,-5.618 -13.357,-7.668 -19.558,-8.376 z" + id="path1707" /> + </g> <text xml:space="preserve" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;line-height:25%;font-family:'Latin Modern Mono Caps';-inkscape-font-specification:'Latin Modern Mono Caps, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" @@ -164,7 +161,7 @@ </g> <g id="g69618" - transform="translate(43.57738,24.136259)"> + transform="translate(84.842902,24.136258)"> <g id="g2298" transform="matrix(0.04783691,0,0,0.04783691,-43.576989,31.272012)"> @@ -228,34 +225,38 @@ </g> <g id="g76635" - transform="translate(43.162525,5.2861854)"> + transform="translate(-6.3959161,5.2861852)"> <g - id="g2299" - transform="matrix(0.74874537,0,0,0.74874537,-6.96828,-6.6072202)"> - <rect - style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="rect1783" - width="6.5330334" - height="6.5330334" - x="42.346821" - y="92.094666" /> - <path - style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="m 43.954613,94.209431 2.385742,2.385741 5.336779,-5.336779" - id="path1898" - sodipodi:nodetypes="ccc" /> - </g> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;line-height:25%;font-family:'Latin Modern Mono Caps';-inkscape-font-specification:'Latin Modern Mono Caps, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" - x="20.208107" - y="70.786034" - id="text17157"><tspan - sodipodi:role="line" - id="tspan17155" - style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.88056px;font-family:'Latin Modern Mono';-inkscape-font-specification:'Latin Modern Mono, Italic';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583" + id="g2" + transform="translate(4.9982594)"> + <g + id="g2299" + transform="matrix(0.74874537,0,0,0.74874537,-6.96828,-6.6072202)"> + <rect + style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect1783" + width="6.5330334" + height="6.5330334" + x="42.346821" + y="92.094666" /> + <path + style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 43.954613,94.209431 2.385742,2.385741 5.336779,-5.336779" + id="path1898" + sodipodi:nodetypes="ccc" /> + </g> + <text + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;line-height:25%;font-family:'Latin Modern Mono Caps';-inkscape-font-specification:'Latin Modern Mono Caps, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" x="20.208107" - y="70.786034">settings</tspan></text> + y="70.786034" + id="text17157"><tspan + sodipodi:role="line" + id="tspan17155" + style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.88056px;font-family:'Latin Modern Mono';-inkscape-font-specification:'Latin Modern Mono, Italic';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583" + x="20.208107" + y="70.786034">settings</tspan></text> + </g> </g> <g id="g72496" @@ -292,22 +293,21 @@ y="68.529076">agents</tspan></text> </g> <g - id="g81155" - transform="translate(0,-1.9848942)"> + id="g1"> <text xml:space="preserve" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93889px;line-height:25%;font-family:'Latin Modern Mono Caps';-inkscape-font-specification:'Latin Modern Mono Caps, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" x="43.218731" - y="55.738956" + y="53.754063" id="text26339"><tspan sodipodi:role="line" id="tspan26337" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.29167px;font-family:'Latin Modern Mono';-inkscape-font-specification:'Latin Modern Mono, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583" x="43.218731" - y="55.738956">model</tspan></text> + y="53.754063">model</tspan></text> <g id="g69652" - transform="matrix(0.03465928,0,0,0.03465928,36.829475,23.859814)"> + transform="matrix(0.03465928,0,0,0.03465928,36.829475,21.87492)"> <path d="m 760,380 a 380,380 0 1 1 -760,0 380,380 0 1 1 760,0 z" fill="url(#sea)" @@ -323,17 +323,17 @@ xml:space="preserve" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.93889px;line-height:25%;font-family:'Latin Modern Mono Caps';-inkscape-font-specification:'Latin Modern Mono Caps, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" x="32.382271" - y="60.07893" + y="58.094036" id="text75428"><tspan sodipodi:role="line" id="tspan75426" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.88056px;font-family:'Latin Modern Mono Caps';-inkscape-font-specification:'Latin Modern Mono Caps, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583" x="32.382271" - y="60.07893">::AgentBasedModel</tspan></text> + y="58.094036">::SimulationModel</tspan></text> </g> <g id="g81435" - transform="translate(0,2.6027248)"> + transform="translate(0,1.0202776)"> <g id="g5042" transform="matrix(0.03318832,0,0,0.03318832,80.941666,18.331834)"> @@ -361,7 +361,7 @@ </g> <g id="g80986" - transform="translate(21.330012,-37.850443)"> + transform="translate(21.330012,-38.87134)"> <g id="g2091" transform="matrix(0.28429111,0,0,0.28429111,53.631813,58.093451)"> @@ -401,7 +401,7 @@ </g> <g id="g82065" - transform="translate(3.3894536,-1.2489369)"> + transform="translate(3.3894536,-2.8313841)"> <path id="path3924" sodipodi:nodetypes="cccccccccccssssccssssccssssccccccccccccssssccssssccsssssccssssccccccccccccssssccsssssccsssssccsssssccsssssccsssssccssssc" @@ -419,5 +419,69 @@ x="8.1108866" y="60.572594">rng</tspan></text> </g> + <g + id="g20772" + transform="translate(-6.8151277,9.1779317)"> + <g + id="g2810" + transform="matrix(1.2503212,0,0,1.2503212,-11.47161,-11.896543)"> + <path + d="m 49.989548,60.329899 h 5.689704 c 0.110127,0 0.21638,-0.04023 0.29922,-0.112792 0.304778,-0.266968 0.497239,-0.659004 0.497239,-1.096007 0,-0.804415 -0.652109,-1.456524 -1.456524,-1.456524 -0.01952,0 -0.03894,4.34e-4 -0.05828,0.0012 1e-6,-3.26e-4 1.1e-5,-7.12e-4 1.1e-5,-0.0012 0,-0.804416 -0.652109,-1.456524 -1.456524,-1.456524 -0.265307,0 -0.514021,0.07097 -0.728263,0.194905 -0.214241,-0.123937 -0.462956,-0.194905 -0.728262,-0.194905 -0.804416,0 -1.456524,0.652108 -1.456524,1.456524 0,4.34e-4 1e-5,9.25e-4 1e-5,0.0013 -0.7774,0.03059 -1.398279,0.670364 -1.398279,1.455263 0,0.437003 0.192462,0.82904 0.497238,1.096007 0.08284,0.07256 0.189094,0.112792 0.299222,0.112792 z" + id="path1457" + style="stroke-width:0.00284477" /> + <circle + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="path2323" + cx="55.451946" + cy="57.113873" + r="1.9020891" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 55.451946,53.244022 v 1.416725" + id="path2438" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 57.663643,53.64691 -0.708362,1.226919" + id="path2771" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 59.276569,55.206144 -1.317334,0.521287" + id="path2773" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 59.503811,57.113872 -1.416724,10e-7" + id="path2775" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 53.431898,53.64691 0.708362,1.226919" + id="path2777" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 51.919701,55.206144 1.317334,0.521287" + id="path2779" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 57.807403,58.410821 1.317334,0.521287" + id="path2799" + sodipodi:nodetypes="cc" /> + </g> + <text + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;line-height:25%;font-family:'Latin Modern Mono Caps';-inkscape-font-specification:'Latin Modern Mono Caps, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" + x="49.393562" + y="66.894287" + id="text17149"><tspan + sodipodi:role="line" + id="tspan17147" + style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.88056px;font-family:'Latin Modern Mono';-inkscape-font-specification:'Latin Modern Mono, Italic';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583" + x="49.393562" + y="66.894287">weather</tspan></text> + </g> </g> </svg> diff --git a/docs/model_structure.pdf b/docs/src/assets/model_structure.pdf similarity index 100% rename from docs/model_structure.pdf rename to docs/src/assets/model_structure.pdf diff --git a/docs/model_structure.png b/docs/src/assets/model_structure.png similarity index 100% rename from docs/model_structure.png rename to docs/src/assets/model_structure.png diff --git a/docs/model_structure.svg b/docs/src/assets/model_structure.svg similarity index 100% rename from docs/model_structure.svg rename to docs/src/assets/model_structure.svg diff --git a/docs/src/config.md b/docs/src/config.md index 707609c364aac981b7873b498b2b2a42eb62d6b8..38b7cabe88bfd97827522b423cd6bb0f82790528 100644 --- a/docs/src/config.md +++ b/docs/src/config.md @@ -14,15 +14,15 @@ defines parameter values and looks like this (see `src/parameters.toml` for the configfile = "src/parameters.toml" # location of the configuration file outdir = "results" # location and name of the output folder overwrite = "ask" # overwrite the output directory? (true/false/"ask") +logoutput = "both" # log output to screen/file/both csvoutput = true # save collected data in CSV files visualise = true # generate result graphs storedata = true # keep collected data in memory loglevel = "debug" # verbosity level: "debug", "info", "warn" processors = 2 # number of processors to use on parallel runs seed = 2 # seed value for the RNG (0 -> random value) -# dates to start and end the simulation -startdate = 2022-01-01 -enddate = 2022-12-31 +startdate = 2022-01-01 # first day of the simulation +enddate = 2022-12-31 # last day of the simulation [world] landcovermap = "data/regions/jena/landcover.tif" # location of the landcover map diff --git a/docs/src/developing.md b/docs/src/developing.md index c0a31375bfc51cb5e7e04fea23110466eb111b2e..89ca256aa8135967573ce1e499c23af173f3ff96 100644 --- a/docs/src/developing.md +++ b/docs/src/developing.md @@ -100,16 +100,6 @@ milestones/releases. Once we have a first release, we will start using ## Important libraries -### Agents.jl - -Our model uses [Agents.jl](https://juliadynamics.github.io/Agents.jl/stable/) as a framework. -Their [repository](https://github.com/JuliaDynamics/Agents.jl) can be used to inspect the source -code or submit bug reports (the authors are quick to respond). Questions can be asked at the -[Julia Discourse forum](https://discourse.julialang.org/c/domain/models/21). - -*Tutorial on collaborating on Julia packages: -[https://www.matecdev.com/posts/julia-package-collaboration.html](https://www.matecdev.com/posts/julia-package-collaboration.html).* - ### Revise.jl [`Revise.jl`](https://timholy.github.io/Revise.jl/stable/) allows one to reload code diff --git a/docs/src/index.md b/docs/src/index.md index 11f106d08919dd6f777618db71b0971a95c02595..b148767c11533f509f3bfa3f81867213a010f143 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -14,4 +14,4 @@ changes in farm operations (e.g. through policy changes in the CAP) influence bi The model is open-source software available on [Gitlab](https://git.idiv.de/persefone/persefone-model). -*Last updated: 2023-10-27 (commit b27fb1b)* +*This documentation was last updated on 2024-06-07 for **Persefone.jl v0.4.1** (commit [4f3d4f4](https://git.idiv.de/persefone/persefone-model/-/commit/4f3d4f4)).* diff --git a/docs/src/simulation.md b/docs/src/simulation.md index 1468016e0d1494678b3b97e2adb5e6d3a209b7de..11ccea7c9ae9f5956f14fc0143f8741c410e170a 100644 --- a/docs/src/simulation.md +++ b/docs/src/simulation.md @@ -3,6 +3,15 @@ The `core` and `world` directories hold source files that are important for all submodels, including scheduling, landscape, weather, and input/output functions. +## Persefone.jl + +This file defines the module, including all exported symbols and two high-level types. + +```@autodocs +Modules = [Persefone] +Pages = ["Persefone.jl"] +``` + ## simulation.jl This file includes the basal functions for initialising and running simulations. diff --git a/docs/src/species-dsl.md b/docs/src/species-dsl.md index 1504d2194440ced71381c4308c7721584355fcaa..a355fd95700a57ac0467f8b895e6c87eeb1adcc5 100644 --- a/docs/src/species-dsl.md +++ b/docs/src/species-dsl.md @@ -1,7 +1,5 @@ # Defining new species -## The Persefone species DSL - In order to make implementing new species as easy as possible, Persefone includes a [domain-specific language](https://doi.org/10.1016/j.ecoinf.2015.02.005) (DSL) built from a collection of macros and functions. @@ -12,56 +10,69 @@ Here is an example of what this looks like, using a hypothetical mermaid species @species Mermaid begin ageofmaturity = 2 pesticidemortality = 1.0 - @initialise(@habitat(@landcover() == water), pairs=true) - - @phase life begin - @debug "$(animalid(animal)) is swimming happily in its pond." - @respond pesticide @kill(@trait(pesticidemortality), "poisoning") - @respond harvest @setphase(drought) - @debug "Animal: $animal" - if @trait(sex) == female && @countanimals() < 3 && - @trait(age) >= @trait(ageofmaturity) && @landcover() == water - @reproduce() - end - end - - @phase drought begin - n = sum(1 for a in @neighbours(0)) - @debug "$(animalid(animal)) is experiencing drought with $n neighbour(s)." - @respond sowing @setphase(life) +end + +@create Mermaid begin + @debug "Created $(animalid(self))." +end + +@phase Mermaid life begin + @debug "$(animalid(self)) is swimming happily in its pond." + @respond pesticide @kill(self.pesticidemortality, "poisoning") + @respond harvesting @setphase(drought) + if self.sex == female && length(@neighbours()) < 3 && + self.age >= self.ageofmaturity && @landcover() == water + @reproduce() end end + +@phase Mermaid drought begin + n = sum(1 for a in @neighbours()) + @debug "$(animalid(self)) is experiencing drought with $n neighbour(s)." + @respond sowing @setphase(life) +end + +@populate Mermaid begin + birthphase = life + initphase = life + habitat = @habitat(@landcover() == water) + pairs=true +end ``` -The two most important macros are [`@species`](@ref) and [`@phase`](@ref), -followed by [`@initialise`](@ref), [`@trait`](@ref), [`@respond`](@ref), -and [`@habitat`](@ref). Other macros provide convenience wrappers for common -functions. (See `src/nature/nature.jl` for details.) +A complete species definition consists of one call each to [`@species`](@ref), +[`@create`](@ref), [`@populate`](@ref), and one or more calls to [`@phase`](@ref). +Another important macro is [`@habitat`](@ref). Further macros are available to +provide convenience wrappers for common functions. +(See [`src/nature/nature.jl`](nature.md) for details.) -The top-level macro is [`@species`](@ref). This takes two arguments: a species -name and a definition block (enclosed in `begin` and `end` tags). At the start of the -definition block, species-specific variables can be defined that should be available -throughout a species' lifetime. Code in this section has access to the `model` -object and can thus reference the current model state. In this section, the user -also has to call the [`@initialise`](@ref) macro. This wraps the -[`Persefone.initpopulation`](@ref) function, and takes a habitat descriptor -(see [`@habitat`](@ref) below) and several options to specify how the species' -population should be distributed in the landscape during model initialisation. +The first macro to call is [`@species`](@ref). This takes two arguments: a species +name and a definition block (enclosed in `begin` and `end` tags). Within the block, +species-specific parameters and variables can be defined (and optionally given values) +that should be available throughout a species' lifetime. -Following this section, each species must define one or more [`@phase`](@ref) blocks. +Next, each species must define one or more [`@phase`](@ref) blocks. The concept behind this is that species show different behaviours at different phases of their lifecycle. Each `@phase` block defines the behaviour in one of these phases. (Technically, it defines a function that will be called daily, so -long as the species' `phase` variable is set to the name of this phase.) Code -in this section has access to the `model` object as well as an `animal` object, -which is the currently active animal agent. Properties of the `animal` agent, -regardless of whether they were defined by the user or by Persefone, can be -accessed using the [`@trait`](@ref) macro. Within a phase block, [`@respond`](@ref) +long as the species' `phase` variable is set to this phase.) Code in this section +has access to the `model` object as well as a `self` object, which is the +currently active [`Animal`](@ref) agent. Within a phase block, [`@respond`](@ref) can be used to define the species' response to a [`FarmEvent`](@ref) that affects the species' current location, while a variety of other macros provide wrappers to -ecological process functions from `src/nature/populations.jl`. +life history and movement functions from [`src/nature/populations.jl`](nature.md). + +The third macro to call is [`@create`](@ref). Like `@phase`, this defines a function +with access to the `world` and `self` objects. This function is called whenever a new +individual of this species is created (either at birth, or when the model is initialised). + +The last macro that must be called is [`@populate`]. Whereas `@create` regulates the +creation of individual animals, `@populate` determines how the population of a species +is initialised at the start of a simulation. It does this by defining values for the +parameters used by [`initpopulation!`](@ref). The full list of parameters that can be +used is documented under [`PopInitParams`](@ref). -Another important macro is [`@habitat`](@ref). This defines a "habitat descriptor", +The final important macro is [`@habitat`](@ref). This defines a "habitat descriptor", i.e. a predicate function that tests whether or not a given landscape pixel is suitable for a specified purpose. Such habitat descriptors are used as arguments to various functions, for example for population initialisation or movement. @@ -70,38 +81,4 @@ to the animal's current position (the `pos` tuple variable) and the `model`. Various macros are available to easily reference information about the current location, such as [`@landcover`](@ref) or [`@distancetoedge`](@ref). -## Implementation details - -Due to a known [performance problem](https://juliadynamics.github.io/Agents.jl/stable/performance_tips/#Avoid-Unions-of-many-different-agent-types-(temporary!)-1) -with multi-agent models, the underlying implementation of species is -rather complicated (see `src/nature/nature.jl` for details.) - -Rather than creating a new type/struct for each species, all [Animal](@ref) -agents have the same type. Instead, they are differentiated by a `traits` -dict, which stores both species-specific parameters and run-time variables. -Note that due to a redefinition of the `getproperty()/setproperty!()` -methods, variables from the trait dict can be accessed and modified just -like normal struct fields (i.e. although `phase` is defined in the dict, -not the struct, `animal.phase = "newphase"` works just fine - one does -not have to use `animal.traits["phase"] = "newphase"`.) - -Under the hood, the [`@species`](@ref) macro generates a function (with the -name of the species), which in turn creates the trait dict when called. Thus, -adding a new animal agent to the model involves instantiating an [`Animal`](@ref) -object, then calling the relevant species function and attaching the returned -dict to the agent object. - -Similarly, the [`@phase`](@ref) macro too works by defining a new function, which -is stored in the species' trait dict. These functions take an animal object -and the model object as input, and define what the species does during its -daily update. - -Once again, [`@habitat`](@ref) creates a function that takes `model` and `pos` -as input and returns a boolean response. Functions that require a habitat -descriptor thus take in this (anonymous) function and call it internally. - -Finally, the [`@initialise`](@ref) macro is a wrapper around -[`Persefone.initpopulation`](@ref), which (yet again) creates a function that -specifies how a species' population is to be initialised at the beginning of a -simulation run. This function is stored in the species trait dict and accessed -during model setup. +All of these macros are defined in [`src/nature/macros.jl`](https://git.idiv.de/persefone/persefone-model/-/blob/master/src/nature/macros.jl). diff --git a/docs/src/using.md b/docs/src/using.md index 4863ac849ff180c265f2ee6632401047c8953def..b5c4730b8772721a45309e38dc431a522ada65e2 100644 --- a/docs/src/using.md +++ b/docs/src/using.md @@ -8,7 +8,7 @@ which is the default mode. To use the model with a graphical user interface, see *For more detailed installation instructions, see [here](developing.md).* Install the latest version of the [Julia](https://julialang.org/downloads/) programming -language (1.9+). The recommended editors are [VSCode](https://www.julia-vscode.org/) or +language (1.10+). The recommended editors are [VSCode](https://www.julia-vscode.org/) or [Emacs](https://www.emacswiki.org/emacs/JuliaProgrammingLanguage). To install the package dependencies, open a Julia REPL in this folder and run: diff --git a/src/nature/macros.jl b/src/nature/macros.jl index 226f979295a3f579e4bc5f890d2593620fa690b0..237782a9794e884e6f002076690ebb75a5beb4db 100644 --- a/src/nature/macros.jl +++ b/src/nature/macros.jl @@ -6,44 +6,33 @@ ##XXX does it make sense to have all of the macros in one place, ## or shouldn't they rather be next to the functions they wrap? +##TODO -> rearrange files -## 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, +## Note that this DSL consists of 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 - take care when modifying! -##FIXME update documentation """ @species(name, body) -A macro used to create new species definitions for the nature model. -All species include the standard fields described for the [Animal](@ref) type. +A macro used to add new species types to the nature model. Use this to define +species-specific variables and parameters. -This is effectively a simple domain-specific language, establishing a -custom syntax to describe species' biology: +The macro works by creating a keyword-defined mutable struct that contains +the standard fields described for the [`Animal`](@ref) type, as well as any +new fields that the user adds: ```julia -@species name begin - - @initialise(@habitat(...)) - speciesvar1 = 3.14 +@species <name> begin + <var1> = <value> + <var2> = <value> ... - - @phase phase1 begin - ... - end end ``` -The definition body (enclosed in the begin/end block) has two sections. -First comes a call to [`@initialise`](@ref), and optionally a list of -species-specific parameters, which are assigned just like normal variables. -Second come one or more phase definitions, that describe the behaviour -of the species during various parts of its life cycle. (See the documentation -to [`@initialise`](@ref) and [`@phase`](@ref) for details). - -Code in a species definition block can access the rest of the model using -the `model` variable (an object of type `SimulationModel`). +To complete the species definition, the [`@phase`](@ref), [`@create`](@ref), +and [`@populate`](@ref) macros also need to be used. """ macro species(name, body) quote @@ -73,6 +62,13 @@ end Set the parameters that are used to initialise this species' population. For parameter options, see [`PopInitParams`](@ref). + +```julia +@populate <species> begin + <parameter> = <value> + ... +end +``` """ macro populate(species, params) quote @@ -87,38 +83,30 @@ macro populate(species, params) end end -#FIXME update documentation """ @phase(name, body) -This macro is designed to be used within a species definition block (i.e. within -the body of a call to [`@species`](@ref)). - -The idea behind this is that species show very different behaviour during different -phases of their lives. Therefore, `@phase` can be used define the behaviour for one +Use this macro to describe a species' behaviour during a given phase of its life. +The idea behind this is that species show very different behaviour at different +times of their lives. Therefore, `@phase` can be used define the behaviour for one such phase, and the conditions under which the animal transitions to another phase. `@phase` works by creating a function that will be called by the model if the animal is in the relevant phase. When it is called, it has access to the following variables: -- `self` a reference to the animal itself. This provides access to `animal.age`, - `self.sex`, and `animal.<trait>` (where <trait> is a variable that was defined - in the top part of the species definition body). +- `self` a reference to the animal itself. This provides access to all the variables + defined in the [`@species`](@ref) definition, as well as all standard [`Animal`](@ref) + variables (e.g. `self.age`, `self.sex`, `self.offspring`). - `pos` gives the animal's current position as a coordinate tuple. -- `model` a reference to the model world (an object of type `SimulationModel`). - This allows access to `model.date` (the current simulation date) and - `model.landscape` (a two-dimensional array of pixels containing geographic +- `model` a reference to the model world (an object of type [`SimulationModel`](@ref)). + This allows access, amongst others, to `model.date` (the current simulation date) + and `model.landscape` (a two-dimensional array of pixels containing geographic information). -Several utility macros can be used within the body of `@phase` as a -short-hand for common expressions: [`@setphase`](@ref), [`@respond`](@ref), -[`@kill`](@ref), [`@reproduce`](@ref), [`@neighbours`](@ref), -[`@rand`](@ref),[`@shuffle!`](@ref), [`@move`](@ref), [`@walk`](@ref), -[`@follow`](@ref). - -Note that the first phase that is defined in a species definition block will -be the phase that animals are assigned at birth, unless the variable `phase` -is explicitly defined by the user in the species definition block. +Many macros are available to make the code within the body of `@phase` more succinct. +Some of the most important of these are: [`@setphase`](@ref), [`@respond`](@ref), +[`@kill`](@ref), [`@reproduce`](@ref), [`@neighbours`](@ref), [`@migrate`](@ref), +[`@move`](@ref), [`@rand`](@ref). """ macro phase(species, phase, body) quote