diff --git a/data/crops/almass/crop_data_general.csv b/data/crops/almass/crop_data_general.csv index 806fdd7a87078e676dad57951561db6a6d45a7a8..c779dec5fa35c5777bb5363b88a81dbd8556bddc 100644 --- a/data/crops/almass/crop_data_general.csv +++ b/data/crops/almass/crop_data_general.csv @@ -6,7 +6,7 @@ name,minsowdate,maxsowdate,minharvestdate,maxharvestdate,mingrowthtemp,group "winter barley","15 September","30 September",NA,NA,0,"grain" "spring barley","1 March","10 April",NA,NA,0,"grain" "undersown spring barley",NA,NA,NA,NA,0,"grain" -"winter rye","23 September","15 October",NA,NA,NA,NA,"grain" +"winter rye","23 September","15 October",NA,NA,NA,"grain" "triticale","25 September","10 October",NA,NA,NA,"grain" "oats",NA,NA,NA,NA,NA,"grain" "maize","15 April","30 April",NA,NA,8,"grain" diff --git a/src/crop/almass.jl b/src/crop/almass.jl index 4e5bfe7a2a0341454f78fa4c140a93aff87cdaea..570305a4e4a3cc9c44724305ca359bd859d39197 100644 --- a/src/crop/almass.jl +++ b/src/crop/almass.jl @@ -22,7 +22,10 @@ import Persefone: cropname, cropheight, cropcover, - cropyield + cropyield, + sow!, + harvest!, + isharvestable using Dates: Date, month, monthday using CSV: CSV @@ -86,6 +89,7 @@ mutable struct CropState LAItotal::Float64 LAIgreen::Float64 #biomass::Float64 #XXX I need to figure out how to calculate this + mature::Bool #TODO how do we determine this? events::Vector{Management} end @@ -94,7 +98,7 @@ cropname(cs::CropState) = cropname(croptype(cs)) cropheight(cs::CropState) = cs.height cropcover(cs::CropState) = 0.0 # TODO: related to LAItotal, LAIgreen? cropyield(cs::CropState) = 0.0 # TODO: units? needs biomass? -isharvestable(cs::CropState) = false #FIXME how do we do this? +isharvestable(cs::CropState) = cs.mature """ Base.tryparse(type, str) @@ -233,6 +237,7 @@ function growcrop!(cs::CropState, model::SimulationModel) points = curve.GDD[cs.phase] for p in 1:length(points) if points[p] == 99999 + cs.mature = true #FIXME is this correct? return # the marker that there is no further growth this phase elseif points[p] == -1 # the marker to set all variables to specified values cs.height = curve.height[cs.phase][p] diff --git a/src/crop/cropmodels.jl b/src/crop/cropmodels.jl index d94725414df7fb9a941032681be9d468e43edee9..aef409f0f531326deaa706dcb58b8303bf713c71 100644 --- a/src/crop/cropmodels.jl +++ b/src/crop/cropmodels.jl @@ -66,7 +66,7 @@ function makecropstate(model::SimulationModel) cs = ALMaSS.CropState( model.crops["natural grass"], phase, - 0.0, 0.0m, 0.0, 0.0, Vector{Management}() + 0.0, 0.0m, 0.0, 0.0, false, Vector{Management}() ) elseif @param(crop.cropmodel) == "simple" cs = SimpleCrop.CropState( diff --git a/src/farm/farm.jl b/src/farm/farm.jl index 108f2efeb8e31133b9cf47b8a171d4b48e5e4418..32a4d7f68a9894d9023f6d407e97e6b10fd6164c 100644 --- a/src/farm/farm.jl +++ b/src/farm/farm.jl @@ -3,6 +3,8 @@ ### This file is responsible for managing the farm module(s). ### +##TODO what data do we need to gather from the farm submodel? + """ Farmer @@ -12,6 +14,7 @@ mutable struct Farmer <: ModelAgent #XXX make this into an abstract type and create subtypes for different farm submodels? (#69) const id::Int64 fields::Vector{Int64} # IDs of the farmplots this farmer owns + croprotation::Vector{String} #TODO figure this out totalincome::Float64 end @@ -24,7 +27,7 @@ function stepagent!(farmer::Farmer, model::SimulationModel) for f in farmer.fields field = model.farmplots[f] ctype = croptype(field) - if ctype.group != "semi-natural" && isharvestable(field) #TODO implement + if ctype.group != "semi-natural" && isharvestable(field) harvest!(field, model) #XXX later: calculate income based on yield and annual price (ctype.group != "grass") && @sow("no growth") @@ -41,11 +44,11 @@ Initialise the model with a set of farm agents. """ function initfarms!(model::SimulationModel) #XXX initially, we only have one farmer controlling all fields in the region - farmer = Farmer(1, collect(1:length(model.farmplots)), 0) + farmer = Farmer(1, collect(1:length(model.farmplots)), [], 0) model.farmers = [farmer] - setasides = findsetasides(farmer, model) #TODO implement + setasides = findsetasides(farmer, model) for field in model.farmplots - if isgrassland(field) + if isgrassland(field, model) @sow("permanent grassland (seeded)") elseif field.id in setasides @sow("permanent set-aside") @@ -63,36 +66,18 @@ set-aside rules. """ function findsetasides(farmer::Farmer, model::SimulationModel) @param(farm.setaside) == 0 && return [] - croparea = reduce(f -> isgrassland(f) ? 0 : length(f.pixels), model.farmplots[farmer.fields]) * - @param(world.mapresolution)^2 + croparea = @areaof(sum(f -> isgrassland(f, model) ? 0 : length(f.pixels), + model.farmplots[farmer.fields])) setasidearea = 0m² setasides = [] for f in farmer.fields #XXX should be sorted smallest-largest for highest efficiency field = model.farmplots[f] - isgrassland(f) && continue + isgrassland(field, model) && continue push!(setasides, f) - setasidearea += length(field.pixels)*@param(world.mapresolution)^2 + setasidearea += @areaof(length(field.pixels)) if setasidearea >= croparea*@param(farm.setaside) @debug "Farmer $(farmer.id) has set aside $(setasidearea |> ha)." return setasides end end end - -""" - @sow(cropname) - -Sow the named crop on the current field. Requires the variables `field` and `model`. -""" -macro sow(cropname) - :(sow!($(esc(:field)), $(esc(:model)), $(esc(cropname)))) -end - -""" - @harvest() - -Harvest the current field. Requires the variables `field` and `model`. -""" -macro harvest() - :(harvest!($(esc(:field)), $(esc(:model)))) -end