From df23cc87bcd3823f1e4ad2f32c59b31c7d129b6b Mon Sep 17 00:00:00 2001 From: Marco Matthies <71844+marcom@users.noreply.github.com> Date: Tue, 11 Mar 2025 11:22:00 +0100 Subject: [PATCH] Fix AquaCrop cropfield setup when there are not enough data points --- src/crop/aquacrop.jl | 25 ++++++++++++++++++------- test/crop_tests.jl | 2 +- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/crop/aquacrop.jl b/src/crop/aquacrop.jl index d9c9f1c..ba18b48 100644 --- a/src/crop/aquacrop.jl +++ b/src/crop/aquacrop.jl @@ -108,6 +108,8 @@ end function make_aquacrop_cropfield(croptype::CropType, model::SimulationModel, soiltype::SoilType) + # TODO: put this constant somewhere else? + MIN_DATASET_LEN = 366 # TODO: get this mapping for soil types from a CSV file? soiltype_to_aquacrop = Dict(soiltype => replace(string(soiltype), "_" => " ") for soiltype in instances(SoilType)) @@ -118,10 +120,19 @@ function make_aquacrop_cropfield(croptype::CropType, start_daynum = daynumber(model.weather, start_date) end_daynum = daynumber(model.weather, end_date) dayrange = start_daynum:end_daynum - input_Tmin = @view model.weather.mintemp[dayrange] - input_Tmax = @view model.weather.maxtemp[dayrange] - input_ETo = @view model.weather.evapotranspiration[dayrange] - input_Rain = @view model.weather.precipitation[dayrange] + numdays = length(dayrange) + if numdays >= MIN_DATASET_LEN + input_Tmin = @view model.weather.mintemp[dayrange] + input_Tmax = @view model.weather.maxtemp[dayrange] + input_ETo = @view model.weather.evapotranspiration[dayrange] + input_Rain = @view model.weather.precipitation[dayrange] + else + # Append fake data so that there are always more than MIN_DATASET_LEN datapoints + input_Tmin = append!(model.weather.mintemp[dayrange], fill(10.0, MIN_DATASET_LEN - numdays)) + input_Tmax = append!(model.weather.maxtemp[dayrange], fill(16.0, MIN_DATASET_LEN - numdays)) + input_ETo = append!(model.weather.evapotranspiration[dayrange], fill(1.0, MIN_DATASET_LEN - numdays)) + input_Rain = append!(model.weather.precipitation[dayrange], fill(1.0, MIN_DATASET_LEN - numdays)) + end # Generate the keyword object for the AquaCrop simulation kwargs = ( @@ -163,8 +174,8 @@ mutable struct CropState <: AbstractCropState soiltype::SoilType cropstate::AquaCrop.AquaCropField - function CropState(croptype::CropType, soiltype::SoilType, - model::SimulationModel, height::Tlength=0.0cm) + function CropState(croptype::CropType, model::SimulationModel, + soiltype::SoilType, height::Tlength=0.0cm) aquacrop_cropfield = make_aquacrop_cropfield(croptype, model, soiltype) return new(croptype, height, soiltype, aquacrop_cropfield) end @@ -180,7 +191,7 @@ function isharvestable(cs::CropState) return !ismissing(stage) && stage == 0 end makecropstate(croptype::CropType, model::SimulationModel, soiltype::SoilType) = - CropState(croptype, soiltype, model) + CropState(croptype, model, soiltype) function setsoiltype!(cs::CropState, soiltype::SoilType) # TODO: this does not affect the actual soil type of the state of # the aquacrop simulation diff --git a/test/crop_tests.jl b/test/crop_tests.jl index 8b3a0d3..f35ec56 100644 --- a/test/crop_tests.jl +++ b/test/crop_tests.jl @@ -65,7 +65,7 @@ end pixels = [(0, 0)] farmer = 0 soiltype = Ps.sand - fp = FarmPlot(id, pixels, farmer, soiltype, PsAC.CropState(ct, soiltype, model)) + fp = FarmPlot(id, pixels, farmer, soiltype, PsAC.CropState(ct, model, soiltype)) @test fp isa FarmPlot @test fp.cropstate isa PsAC.CropState @test croptype(fp) isa PsAC.CropType -- GitLab