From dc00b4a291a8b15b9b5b200f34118f0022b44318 Mon Sep 17 00:00:00 2001 From: Daniel Vedder <daniel.vedder@idiv.de> Date: Fri, 6 Sep 2024 11:44:35 +0200 Subject: [PATCH] Check package directory for input files --- CHANGELOG.md | 14 ++++++++++++++ src/Persefone.jl | 2 +- src/analysis/makieplots.jl | 2 +- src/core/input.jl | 11 ++++++++++- src/core/output.jl | 19 +++++++++++++++++++ src/core/utils.jl | 4 ---- src/crop/farmplot.jl | 2 +- src/nature/macros.jl | 19 ------------------- src/parameters.toml | 14 +++++++------- src/world/landscape.jl | 1 - test/nature_tests.jl | 2 +- 11 files changed, 54 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83e12b9..02f4db6 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 f5aa7b4..2b51908 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 70ba8ce..d03c32e 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 e233382..2647835 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 4b3fd97..4144d8f 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 607cafd..25d1b1d 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 ecd4baf..c44d6ad 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 53da2a6..eb7f25c 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 484c1a9..5b742db 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 afbc6d7..a9d0454 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 b0d7e3c..d4b723e 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 -- GitLab