diff --git a/CHANGELOG.md b/CHANGELOG.md index 83e12b936bec4a2582675551b2d56c38c2c58a9b..02f4db6a62c29aed709a41a5f1fb5ae4922486db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 *Plan: decouple CairoMakie (#81), fix & test ALMaSS, set up first experiments* +### Added + +### Changed + +- `preprocessparameters()` checks whether the map directory is 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. + +### Deprecated + +### Removed + +### Fixed + --- ## [0.5.5] - 09-08-2024 diff --git a/src/Persefone.jl b/src/Persefone.jl index f5aa7b43f3baebe84b6d0b7b38548b558522f12a..2b519088adf0df6e06f3679f77756462df875393 100644 --- a/src/Persefone.jl +++ b/src/Persefone.jl @@ -22,7 +22,7 @@ using DataFramesMeta, Distributed, FileIO, - GeoArrays, #XXX this is another big dependency + GeoArrays, #XXX this is another big dependency - replace with Rasters.jl? Logging, LoggingExtras, Random, diff --git a/src/analysis/makieplots.jl b/src/analysis/makieplots.jl index 70ba8ce93fbeab50d95d77cec4c3be01d910ebe5..d03c32eb2d7db33d1074f136e3d53581cf871033 100644 --- a/src/analysis/makieplots.jl +++ b/src/analysis/makieplots.jl @@ -25,7 +25,7 @@ function visualisemap(model::SimulationModel,date=nothing,landcover=nothing) image!(f[1,1], landcover) ax.aspect = DataAspect() # check if there are individuals and plot them - inds = @subset(@data("individuals"), :X .== -1) #remove migrants + inds = @subset(@data("individuals"), :X .!= -1) #remove migrants if iszero(size(inds)[1]) @debug "No individual data to map" return f diff --git a/src/core/input.jl b/src/core/input.jl index e233382ea20a48e69be50e639c5cb5f617733270..26478351958dfaa3729f337ea9bc008a64034762 100644 --- a/src/core/input.jl +++ b/src/core/input.jl @@ -93,8 +93,17 @@ function preprocessparameters(settings::Dict{String,Any}, defaultoutdir::String) if settings["core.startdate"] > settings["core.enddate"] Base.error("Enddate is earlier than startdate.") #TODO replace with exception end + if !isdir(settings["world.mapdirectory"]) + #TODO do equivalent check for crop directory, once this is implemented + # check if it's relative to the package directory + if isdir(abspath(pkgdir(@__MODULE__), settings["world.mapdirectory"])) + settings["world.mapdirectory"] = abspath(pkgdir(@__MODULE__), settings["world.mapdirectory"]) + else + Base.error("Couldn't find map directory $(settings["world.mapdirectory"]).") + end + end settings["world.mapresolution"] = settings["world.mapresolution"] * 1m - if ! (settings["crop.cropmodel"] in AVAILABLE_CROPMODELS) + if !(settings["crop.cropmodel"] in AVAILABLE_CROPMODELS) error("crop.cropmodel = \"$(settings["crop.cropmodel"])\", but has to be one of: $AVAILABLE_CROPMODELS") end #FIXME enable parallelisation diff --git a/src/core/output.jl b/src/core/output.jl index 4b3fd9712dba0b15a4d3bc97c324446368522479..4144d8f0fd2cdded464fc73761bf2e799b03f233 100644 --- a/src/core/output.jl +++ b/src/core/output.jl @@ -245,6 +245,25 @@ function record!(model::SimulationModel, outputname::String, data::Vector) !(outputname in keys(model.dataoutputs)) && return #XXX should this be a warning? push!(model.dataoutputs[outputname].databuffer, data) end + +""" + @record(outputname, data) + +Record an observation / data point. Only use in scopes where `model` is available. +""" +macro record(args...) + :(record!($(esc(:model)), $(map(esc, args)...))) +end + +""" + @data(outputname) + +Return the data stored in the given output (assumes `core.storedata` is true). +Only use in scopes where `model` is available. +""" +macro data(outputname) + :(data($(esc(:model)).dataoutputs[$(esc(outputname))])) +end """ visualiseoutput(model) diff --git a/src/core/utils.jl b/src/core/utils.jl index 607cafd909b4756c8e41c20058c0c9725798f73e..25d1b1d69f1b21cf1a2035d459f64f2272435518 100644 --- a/src/core/utils.jl +++ b/src/core/utils.jl @@ -53,10 +53,6 @@ AnnualDate(ad::String) = AnnualDate(Date(ad, dateformat"d U")) Base.convert(::Type{AnnualDate}, ad::String) = AnnualDate(ad) Base.tryparse(::Type{AnnualDate}, ad::String) = AnnualDate(ad) -# allow creating AnnualDates from a string of the format "8 August" -AnnualDate(ad::String) = AnnualDate(Date(ad, dateformat"d U")) -Base.convert(::Type{AnnualDate}, ad::String) = AnnualDate(ad) - # Interface with Dates AnnualDate(date::Date) = AnnualDate(month(date), day(date)) Base.convert(::Type{AnnualDate}, ad::Date) = AnnualDate(ad) diff --git a/src/crop/farmplot.jl b/src/crop/farmplot.jl index ecd4baf5a26aa927bc836dedffdf27f09af0b152..c44d6ad85d2c56f37784ae7df9c9cab89f3d361d 100644 --- a/src/crop/farmplot.jl +++ b/src/crop/farmplot.jl @@ -84,7 +84,7 @@ function isgrassland(farmplot::FarmPlot, model::SimulationModel) if proportiongrass > 0.8 return true elseif proportiongrass > 0.2 - @warn "Unclear classification: farm plot $(farmplot.id) has $(proportiongrass*100)% grass." + @debug "Unclear classification: farm plot $(farmplot.id) has $(proportiongrass*100)% grass." proportiongrass >= 0.5 && return true end return false diff --git a/src/nature/macros.jl b/src/nature/macros.jl index 53da2a60dc8b58a431c50ba6e7c149e44d1fc388..eb7f25cd119587a66e4cd994cd0aa3f5161dea19 100644 --- a/src/nature/macros.jl +++ b/src/nature/macros.jl @@ -522,25 +522,6 @@ macro lastyear(annualdate) :(lastyear($(esc(annualdate)), $(esc(:model)))) end -""" - @record(outputname, data) - -Record an observation / data point. Only use in scopes where `model` is available. -""" -macro record(args...) - :(record!($(esc(:model)), $(map(esc, args)...))) -end - -""" - @data(outputname) - -Return the data stored in the given output (assumes `core.storedata` is true). -Only use in scopes where `model` is available. -""" -macro data(outputname) - :(data($(esc(:model)).dataoutputs[$(esc(outputname))])) -end - """ @destroynest(reason) diff --git a/src/parameters.toml b/src/parameters.toml index 484c1a9b02d4245f7e48b40ccfdf9de1f5221895..5b742db393bc02a17f13f33895adf18443b11cc0 100644 --- a/src/parameters.toml +++ b/src/parameters.toml @@ -5,7 +5,7 @@ ### ### DO NOT MODIFY THIS FILE FOR SIMULATION EXPERIMENTS! ### Instead, copy it to another directory and modify the copy. - + [core] configfile = "src/parameters.toml" # location of the configuration file outdir = "results" # location and name of the output folder @@ -36,12 +36,12 @@ fieldoutfreq = "daily" # output frequency for crop/field data, daily/monthly/yea [nature] #targetspecies = ["Wolpertinger", "Wyvern"] # list of target species to simulate - example species -targetspecies = [] # XXX disable all species for farm model testing -#targetspecies = ["Skylark"] # list of target species to simulate -popoutfreq = "never" # output frequency population-level data, daily/monthly/yearly/end/never -indoutfreq = "never" # output frequency individual-level data, daily/monthly/yearly/end/never -#popoutfreq = "daily" # output frequency population-level data, daily/monthly/yearly/end/never -#indoutfreq = "end" # output frequency individual-level data, daily/monthly/yearly/end/never +#targetspecies = [] # XXX disable all species for farm model testing +targetspecies = ["Skylark"] # list of target species to simulate +#popoutfreq = "never" # output frequency population-level data, daily/monthly/yearly/end/never +#indoutfreq = "never" # output frequency individual-level data, daily/monthly/yearly/end/never +popoutfreq = "daily" # output frequency population-level data, daily/monthly/yearly/end/never +indoutfreq = "end" # output frequency individual-level data, daily/monthly/yearly/end/never insectmodel = ["season", "habitat", "pesticides", "weather"] # factors affecting insect growth [crop] diff --git a/src/world/landscape.jl b/src/world/landscape.jl index afbc6d7a8e416588627ee42236625f66a7fda827..a9d04549a6eb67bc18fcbe0a3a81cd56db152014 100644 --- a/src/world/landscape.jl +++ b/src/world/landscape.jl @@ -54,7 +54,6 @@ function initlandscape(directory::String, landcovermap::String, farmfieldsmap::S #TODO replace errors with exception !(isfile(landcovermap)) && Base.error("Landcover map $(landcovermap) doesn't exist.") !(isfile(farmfieldsmap)) && Base.error("Field map $(farmfieldsmap) doesn't exist.") - #XXX can I read the files in using FileIO, to avoid the GeoArrays dependency? # read in TIFFs, replacing missing values with 0 landcover = coalesce(GeoArrays.read(landcovermap), 0) farmfields = coalesce(GeoArrays.read(farmfieldsmap), 0) diff --git a/test/nature_tests.jl b/test/nature_tests.jl index b0d7e3cde16ebc6cfee39735454bb6cc8cfc1a90..d4b723e5716c7128786213340a6e20c84978ff23 100644 --- a/test/nature_tests.jl +++ b/test/nature_tests.jl @@ -39,7 +39,7 @@ end habitat = @habitat(@landcover() == water) pairs=true end - + end) # end eval ## Test sets