Skip to content
Snippets Groups Projects
Commit 49f84fc0 authored by xo30xoqa's avatar xo30xoqa
Browse files

Wrote code to read in crop data files

parent b505ae4f
No related branches found
No related tags found
No related merge requests found
......@@ -3,85 +3,117 @@
### This file is responsible for managing the crop growth modules.
###
@enum GrowthPhase janfirst sow marchfirst harvest1 harvest2 vegphase
#TODO write tests for input functions
#TODO write actual growth function
"""
CropType
GrowthPhase
The type struct for all crops. Currently follows the crop
growth model as implemented in ALMaSS.
ALMaSS crop growth curves are split into five phases, triggered by
seasonal dates or agricultural events.
"""
@kwdef struct CropType
name::String
sowdate::Date
harvestdate::Date
mingrowthtemp::Float64
inflectionpoints::Dict{GrowthPhase,Vector{Float64}}
slopes::Dict{GrowthPhase,Vector{Float64}}
#issowable::Union{Function,Bool}=true
@enum GrowthPhase janfirst sow marchfirst harvest1 harvest2
"""
CropCurveParams
The values in this struct define one crop growth curve.
"""
struct CropCurveParams
curveID::Int
highnutrients::Bool
GDD::Dict{GrowthPhase,Vector{Float64}}
LAItotal::Dict{GrowthPhase,Vector{Float64}}
LAIgreen::Dict{GrowthPhase,Vector{Float64}}
height::Dict{GrowthPhase,Vector{Float64}}
end
let croptypes = Dict{String,CropType}()
global function registercrop(ct::CropType)
croptypes[ct.name] = ct
end
"""
CropType
global function getcrop(name::String)
croptypes[name]
end
The type struct for all crops. Currently follows the crop growth model as
implemented in ALMaSS.
"""
struct CropType
name::String
minsowdate::Union{Missing,Date}
maxsowdate::Union{Missing,Date}
minharvestdate::Union{Missing,Date}
maxharvestdate::Union{Missing,Date}
mingrowthtemp::Union{Missing,Float64}
highnutrientgrowth::Union{Missing,CropCurveParams}
lownutrientgrowth::Union{Missing,CropCurveParams}
#issowable::Union{Function,Bool}
end
"""
@dday(datestring)
Base.tryparse(type, str)
A utility macro to make it quicker to create dates in the
format "21 August".
Extend `tryparse` to allow parsing GrowthPhase values.
(Needed to read in the CSV parameter file.)
"""
macro dday(date::String)
:(Date($(date), dateformat"d U"))
function Base.tryparse(type::Type{GrowthPhase}, str::String)
str == "janfirst" ? janfirst :
str == "sow" ? sow :
str == "marchfirst" ? marchfirst :
str == "harvest1" ? harvest1 :
str == "harvest2" ? harvest2 :
nothing
end
let croplist = Dict{String,CropType}()
global function newcrop(;kwargs...)
crop = CropType(;kwargs...)
croplist[crop.name] = crop
end
"""
buildgrowthcurve(data)
global function cropdefinition(name)
croplist[name]
Convert a list of rows from the crop growth data into a CropCurveParams object.
"""
function buildgrowthcurve(data::Vector{CSV.Row})
isempty(data) && return missing
GDD = Dict(janfirst=>Vector{Float64}(), sow=>Vector{Float64}(),
marchfirst=>Vector{Float64}(), harvest1=>Vector{Float64}(),
harvest2=>Vector{Float64}())
LAItotal = Dict(janfirst=>Vector{Float64}(), sow=>Vector{Float64}(),
marchfirst=>Vector{Float64}(), harvest1=>Vector{Float64}(),
harvest2=>Vector{Float64}())
LAIgreen = Dict(janfirst=>Vector{Float64}(), sow=>Vector{Float64}(),
marchfirst=>Vector{Float64}(), harvest1=>Vector{Float64}(),
harvest2=>Vector{Float64}())
height = Dict(janfirst=>Vector{Float64}(), sow=>Vector{Float64}(),
marchfirst=>Vector{Float64}(), harvest1=>Vector{Float64}(),
harvest2=>Vector{Float64}())
for e in data
append!(GDD[e.growth_phase], e.GDD)
append!(LAItotal[e.growth_phase], e.LAI_total)
append!(LAIgreen[e.growth_phase], e.LAI_green)
append!(height[e.growth_phase], e.height)
end
CropCurveParams(data[1].curve_id, data[1].nutrient_status=="high",
GDD, LAItotal, LAIgreen, height)
end
#
# XXX It would be nicer to be able to define crops with a macro
# (like @species), but since macros are so tricky to get right,
# I'll leave that for later.
#
# """
# @crop
#
# A macro to create and register a new crop type. Pass a list
# of keyword arguments to instantiate each field of the
# [`CropType`](@ref) struct.
# """
# macro crop(;kwargs...) # macros don't take kwargs
# quote
# registercrop(CropType($(esc(kwargs))))
# end
# end
#
# @crop "winter wheat" begin
# minsowdate = @dday("1 November")
# maxsowdate = @dday("31 November")
# growthparameter = 1.0
# issowable = true
# end
newcrop(name="winter wheat",
sowdate = @dday("1 November"),
harvestdate = @dday("1 July"),
mingrowthtemp = 5.0,
growthparameter = 1.0,
issowable = true)
"""
readcropparameters(generalcropfile, cropgrowthfile)
Parse a CSV file containing the required parameter values for each crop
(as produced from the original ALMaSS file by `convert_almass_data.py`).
"""
function readcropparameters(generalcropfile::String, cropgrowthfile::String)
@debug "Reading crop parameters"
cropdata = CSV.File(generalcropfile, missingstring="NA", dateformat="d U",
types=[String,Date,Date,Date,Date,Float64])
growthdata = CSV.File(cropgrowthfile, missingstring="NA",
types=[Int,String,String,GrowthPhase,String,
Float64,Float64,Float64,Float64])
croptypes = Vector{CropType}()
for crop in cropdata
cropgrowthdata = growthdata |> filter(x -> !ismissing(x.crop_name) &&
x.crop_name == crop.name)
highnuts = buildgrowthcurve(cropgrowthdata |>
filter(x -> x.nutrient_status=="high"))
lownuts = buildgrowthcurve(cropgrowthdata |>
filter(x -> x.nutrient_status=="low"))
append!(croptypes, [CropType(crop.name, crop.minsowdate, crop.maxsowdate,
crop.minharvestdate, crop.maxharvestdate,
crop.mingrowthtemp, highnuts, lownuts)])
end
croptypes
end
......@@ -30,8 +30,10 @@ farmmodel = "FieldManager" # which version of the farm model to use (not yet imp
targetspecies = ["Wolpertinger", "Wyvern"] # list of target species to simulate
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"] # which factors affect insect growth ("weather" is not yet implemented)
insectmodel = ["season", "habitat", "pesticides", "weather"] # factors affecting insect growth
[crop]
cropmodel = "linear" # crop growth model to use, "linear" or "aquacrop" (not yet implemented)
cropmodel = "almass" # crop growth model to use, "almass" or "aquacrop"
cropfile = "data/crop_data_general.csv" # file with general crop parameters
cropgrowthfile = "data/almass_crop_growth_curves.csv" # file with crop growth parameters
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment