Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[1.0.0] - 05-03-2026

This is the first official release, used to run the experiments in the first revision of the model presentation paper. In terms of the source code, it represents a polishing up of v0.11.

Added

  • studies subdirectory to store configuration files and analysis scripts for simulation experiments

Changed

  • name of landscape input file can now be changed with world.landscapemap

  • recreated regional maps and weather data files

  • updated documentation and rewrote map-related docs

Removed

  • removed world.landcovermap, world.farmfieldsmap, world.soiltypemap parameters

  • input data files are no longer copied to the output directory, as they are too big

  • cleaned up ALMaSS input data, removed crops that aren't needed

  • deleted old binary files

Fixed

  • several bugs in vector_maps.jl

  • minor bug in extract_weather_data.R

  • various bugs in the animal models

[0.11.0] - 25-01-2026

This version changes the landscape map to a vector format. This entails wide-ranging changes in the code structure and geometric operations to deal with continuous space.

Added

  • src/core/geometry.jl with:

    • Coord, Extent2D, and Geom types
    • pointfrombearing(), bearingfrompoint(), fuzzyposition(), and randompoint()
    • circle(), rectangle(), square()
  • in src/world/landscape.jl:

    • LandscapeElement, HomeRange, and Landscape types
    • add_land!(), get_land_elems_in_extent(), get_land_elem_at_coord()
    • add_homerange!(), remove_homerange!(), get_homeranges_in_extent(), get_homeranges_at_coord()
  • HabitatExpression and @h_str macro to specify habitat properties using strings (replaces @habitat)

  • tests for the new landscape functionality

  • utility functions for dealing with string case (e.g. snakecase(), camelcase())

  • visualisemap() can now plot animal home ranges

Changed

  • moved model-wide type definitions to src/core/types.jl

  • adapted spatial functions (e.g. landcover(), directionto()) to vector maps and continuous space

  • integrated standardised CropNames into the model (so we no longer have to work with crop model-specific strings)

  • functions that formerly worked on FarmPlots now work with LandscapeElements

  • adapted ATKIS conversion script to output (vector) Geopackage files rather than (raster) TIFFs, as well as adding a spatial index and diagnostics

  • initlandscape() now reads in Geopackage files

  • animals are now stored in a dict instead of a vector, and all model entities (animals, farmers, farmplots) are identified using custom ID types (AnimalID, FarmerID, LandElemID)

  • updated documentation of the animal submodel

Deprecated

Removed

  • Pixel and FarmPlot types - their functionality is taken over by LandscapePolygon

  • @habitat macro - replaced by habitat descriptor strings

  • @here, @randomdirection - weren't needed

  • crop.use_region_specific_params removed from configuration files and crop init APIs; AquaCrop now always uses the regional, then Germany-wide, then default parameters

Fixed

  • bugs in the animal species models

[0.10.0] - 25-11-2025

This minor version restructures the animal submodel for easier species parameterisation and simpler initialisation routines.

Added

  • species parameters are read in from configuration files stored in data/animals (configured using the animal.animaldirectory setting)

  • SpeciesParameter, addspeciesparam!(), requireparams!(), and checkspeciesdicts() to document all parameters required by the animal code and ensure that they are present and correct in the animal configuration files

  • CropName enum to provide a standardised name for crops

  • region jena-small for testing purposes

Changed

  • @phase now refers to taxa, not species (it is assumed that species of the same taxon share similar behaviour, and that differences can be represented using different species-specific parameter values)

  • @create is now used instead of @species to define and initialise lifetime variables on a taxon level (works by adding a "create" phase for the taxon)

  • animal.targetspecies now defines which files from the animal.animaldirectory are to be used (this allows testing multiple versions of the same species)

  • code from src/animal/species/skylark.jl and src/animal/species/marbled_white.jl moved to src/animal/birds.jl and src/animal/butterflies.jl, respectively, and adapted to the new structure

  • upgraded to Julia 1.12

Deprecated

Removed

  • @species macro (use @create instead to define taxon initialisation)

  • @populate macro, PopInitParams, and associated functions (parameters formerly passed via these are now part of the species config files)

  • species-specific parameters from src/parameters.toml

  • Wolpertinger and Wyvern test species (alas, the mythological species are extinct :-( )

Fixed

  • removed pos from @phase (#142)

[0.9.0] - 24-10-2025

This minor release changes the map to ATKIS.

Added

  • data/regions/auxiliary/rasterise_maps.jl to create input raster maps from ATKIS and soil atlas vector maps (#150)

  • data/regions/auxiliary/createinputs.sh to automate the creation of input data for the regions (includes downloading and processing of weather and map data, #89)

  • LandCoverCategory enum to provide "supertypes" for LandCover

  • data/regions/auxiliary/extract_weather_data.R script now automatically interpolates missing weather data

  • started using git LFS

Changed

  • Land cover map source changed from Mundialis to ATKIS, spatial resolution increased to 3m (#150)

  • LandCover enum expanded from 6 to 32 land cover classes

  • nature submodel renamed to animal (#125)

  • using Rasters.jl instead of GeoArrays.jl to read in maps (#152)

  • world.mapresolution parameter is now the constant MAPRESOLUTION

  • improved runprofile.jl script

Removed

  • world.fixlandcover parameter

Fixed

  • improved type stability in landscape.jl

  • fixed logic in createdatadir() when overwrite="no"


[0.8.0] - 29-8-2025

This minor release adds the first butterfly model (marbled white), and expands the farm model.

Added

  • Marbled white (Melanargia galathea) species model with associated data outputs

  • implemented management of extensive and intensive grassland in the farm model (new parameters: farm.extensivegrassland, farm.mowingthreshold, farm.mowingperiod)

  • management scenarios can now be implemented using functions in the farm model and activated using the farm.scenarios parameter

  • added cropgroup() functions

  • added macros for weather functions (@humidity(), @maxtemp(), etc.)

  • added runparallel.jl and slurm.sh to allow parallel processing of parameter scans on an HPC

  • region-specific modified crop parameters for use with AquaCrop will now be loaded automatically from the data/crops/aquacrop/regions/ directory, e.g. the file data/crops/aquacrop/regions/jena/winter_wheat.toml can be used to overload the parameters for "winter wheat" in the "jena" region. Use of the modified crop parameters can be controlled with the crop.use_region_specific_params configuration file parameter.

Changed

  • Skylark model parameters can be set via configuration file

  • added Skylark parameters limitterritory and offfieldnesting

  • Setasides (fallows) are now reassigned to new fields every year

  • ALMaSS grassland data expanded to allow continued growth after mowing

  • crop rotation on all fields can now be set via parameter farm.croprotation

  • the model now attempts to fix misclassifications in the land cover map if the world.fixlandcover parameter is true

  • DataOutputs can now be passed a string with an AnnualDate instead of a frequency to specify on which date they should be run

  • the world.mapdirectory parameter has been split up into world.mapdirectory and world.region

  • updated and expanded documentation

Deprecated

Removed

Fixed

  • fixed post-mowing grass growth in ALMaSS

  • fixed isvalidstart() bug in almass.jl

  • fixed a bug in initpopulations!()

  • interpolated missing weather data

  • crop cover is now given as percent by both crop models

[0.7.1] - 17-6-2025

Added

  • AquaCrop can now estimate crop height from dry biomass using the rational function regression y = a * (x/x0)^b / (c + (x/x0)^b) with parameters fitted for maize, winter wheat, winter barley, and winter rapeseed. AquaCrop by itself does not model plant height.

[0.7.0] - 14-03-2025

This minor release adds support for the AquaCrop crop model.

Added

  • Add AquaCrop crop model

  • Simple linear crop height estimation for AquaCrop plants from biomass (AquaCrop does not model plant height)

  • Read soil type map, controlled with the setting "world.soiltypesmap"

  • Landscape Pixels store their soil type (enum SoilType)

  • FarmPlots store the most common soil type of their landscape Pixels (AquaCrop needs the soil type as an input parameter).

Changed

  • Allow multiple crop models to be used in one simulation. The settings "crop.cropmodel" and "crop.cropdirectory" are now comma-separated lists of crop models and their data directories.

Deprecated

Removed

Fixed

[0.6.1] - 14-03-2025

Added

  • user manual: documentation is now compiled to PDF (#91)

  • added soil maps to region data, but not used yet

  • added mean_cloud_cover and potential_evapotranspiration fields to weather data csv files

Changed

  • added soil map section to GIS docs

  • Changed weather internal representation to struct-of-arrays (previously a dict-of-struct representation). The Weather type now stores all weather information for the whole simulation, with a function interface, e.g. sunshine(weather, date).

  • When reading weather data, we now throw an error when there are missing days or any missing values for the fields min_temperature, max_temperature, mean_temperature, precipitation, and potential_evapotranspiration. In the future missing values could also be imputed.

  • The script for weather data extraction at data/regions/auxiliary/extract_weather_data.R has been reworked to always return an output row for each day in the date range, even if the day is missing in the original data source. It now also accepts the stations to download as command-line arguments. The renv lockfile for the R environment used to run the script can be found at data/regions/auxiliary/renv.lock.

Deprecated

Removed

Fixed

[0.6.0] - 13-01-2025

This minor release re-implements the ALMaSS crop model

Added

  • crop.cropdirectory parameter specifies folder in which all crop data files for the selected crop model can be found.

Changed

  • preprocessparameters() checks whether the map and crop directories are reachable from the current working directory. If not, it checks whether it can be reached from the package directory. This makes running simulations easier when Persefone has been installed as a package.

  • simulate() and initialise() now take a params keyword argument that can be used to override parameters from other input sources

  • The ALMaSS crop data config file data/crops/almass/crop_data_general.csv now has extra columns for is_c4_plant, sowingdensity, and phase_before_harvest

Deprecated

Removed

  • crop.cropfile and crop.growthfile parameters -> user configuration is now done via crop.cropdirectory, names of ALMaSS input files are specified as constants in almass.jl

Fixed

  • The implementation of the ALMaSS vegetation model in Persefone has been completely rewritten, hopefully more faithfully reproducing the logic in ALMaSS. The resulting plant heights are now more realistic and do not produce the extreme plant heights seen previously (which was due to an erroneous interpretation of the ALMaSS growth curves).

[0.5.5] - 09-08-2024

This point release implements the first basic farm model

Added

  • basic farm model that assigns a crop rotation to each field, sowing and harvesting when appropriate

  • new parameters: farm.farmmodel, farm.setaside, farm.fieldoutfreq

  • visualisation of cropped area and crop growth over time

  • farm.setaside setting to configure what proportion of land farmers let lie fallow

  • isharvestable() function for FarmPlots

  • @areaof macro to calculate the area of a given number of landscape pixels

  • data/farm/standard_gross_margins.csv from KTBL data

Changed

  • expanded & adapted general crop data and crop growth curve tables

Fixed

  • bug fixes in the ALMaSS crop model

[0.5.4] - 08-08-2024

Skylark data analysis and new internal utility functions

Added

  • AnnualDate type and associated functions for working with recurring dates (#101)

    • can be constructed from two Int64, a Date, or a Tuple{Int64,Int64}
    • automatic conversion from Date or Tuple{Int64,Int64}
    • can use operators: ==, <, +, -, :
    • thisyear(), lastyear(), nextyear() functions and macros
  • new file core/utils.jl for utility functions that fit in no other file

  • irregular data logging using record!()/@record() (#103)

  • data outputs & visualisation for the skylark model (#97)

  • randn() function and macro to sample from a vector using a normal distribution

  • make install to download and install Julia and package dependencies (on Linux, #67)

  • weather file for the Thüringer Becken

Changed

  • moved random number functions and macros from input.jl to utils.jl

  • expanded weather data for Jena to 1990-2023

  • Non-breeding skylarks only search for neighbours to follow once (-> huge performance improvement!)

Fixed

  • bug fixes in the skylark model

[0.5.3] - 31-07-2024

Switchable crop models

Added

  • Support for switchable crop models (#70), crop models can be set with the cropmodel setting in the [crop] section of parameters.toml.

  • New submodules ALMaSS for the ALMaSS crop model, and SimpleCrop for testing switchable crop models.

Changed

  • All functionality specific to the ALMaSS crop model has been moved to the submodule ALMaSS.

  • Due to switchable crop models, some types are now parametric: AgricultureModel{Tcroptype,Tcropstate} and FarmPlot{Tcropstate}.

  • FarmPlot{Tcropstate} now only stores basic information about which pixels are part of the farm plot, all crop-specific information is now stored in the field cropstate. Many functions acting on a FarmPlot now mostly forward to functions of the same name acting on the cropstate field of a FarmPlot.

  • The type of height in ALMaSS.CropState and ALMaSS.CropCurveParams is now a unitful number ::Length{Float64}.

  • Both crop models ALMaSS and SimpleCrop now also support the functions cropcover and cropyield in addition to croptype, cropname, cropheight.

  • cropheight now returns a unitful number ::Length{Float64}, and returns height 0cm if the landscape at that position is not a FarmPlot.

[0.5.2] - 30-07-2024

Rewrote the skylark model

Added

  • Skylark model is largely rewritten to follow a new phase structure (#9)

  • animals can occupy territories (see @occupy, @isoccupied, @vacate macros/functions) (#94)

  • @cropcover macro and function

  • ODD documentation for Skylark

Changed

  • input files that are now copied to a separate inputs directory within the output directory

  • EventType renamed to Management for clarity

  • documentation website now has a "Scientific Documentation" section

Removed

  • old skylark model (has been rewritten, see above)

Fixed

  • all skylarks now migrate (#90)

  • insectbiomass() uses units

[0.5.1] - 13-06-2024

Added Unitful.jl

Added

  • Unitful.jl now used to add units to quantities

  • world.mapdirectory parameter specifies the path to the directory in which

landcovermap, farmfieldsmap, and weatherfile are located

  • world.mapresolution parameter specifies the input maps' spatial resolution in meters

Changed

  • spatial functions now work with explicit distances (using Unitful.jl) rather than using the number of pixels

  • all species definitions and tests updated to use units


[0.5.0] - 07-06-2024

This release doesn't add much new functionality, but represents a major restructuring of the code base. Specifically, it removes the Agents.jl dependency and changes the way the species definition macros work and are used.

Added

  • SimulationModel type, extended by AgricultureModel struct

  • @create macro defines a special phase function that is called when an individual animal is created (at birth or on model initialisation)

  • functions (and associated macros) to replace Agents.jl functionality:

    • move!() and walk!()
    • nearby_ids(), nearby_animals(), countanimals(), neighbours()
    • directionto(), distanceto(), randomdirection()
    • nagents(), killallanimals!()
  • @here macro to return the pixel currently occupied by the active animal

  • core.logoutput parameter to define whether logs are printed to screen, file, none, or both

  • large logo and model structure diagram

  • Changelog

Changed

  • SimulationModel replaces AgentBasedModel

  • Species definition macros revamped:

    • @species now only defines parameters and variables and creates a mutable struct
    • @phase must now be defined in the top-level code and creates a global function
    • @initialise renamed to @populate, must also be called in the top-level code
    • initindividual() renamed to create!()
  • Skylark, Wolpertinger, and Wyvern updated to match the new macros

  • requires Julia 1.10

Removed

  • Agents.jl dependency (including AgentBasedModel and functions for adding/moving/removing agents)

[0.4.1] - 2023-11-14

Initial version of the skylark model

Added

  • initial version of the Skylark species

  • small Jena map

  • animal individuals keep track of their parents' IDs

  • several new functions and macros for animals

  • installation instructions for Windows

Changed

  • graphics output is more configurable

[0.4.0] - 2023-10-28

Functions for animal populations

Added

  • initialisation functions for individuals (not just species)

  • migration function / migrant pool for animals that disappear from the landscape during winter

  • skylark migration

Changed

  • online documentation was expanded and restructured

  • nature macros moved to a separate file

Started changelog at this point, earlier versions are not included.

<!– Template

[version] - unreleased

<comments>

Added

Changed

Deprecated

Removed

Fixed

-->