aquacropos / aquacrop

AquaCrop-OSPy: Python implementation of AquaCrop-OS
https://aquacropos.github.io/aquacrop/
Apache License 2.0
95 stars 68 forks source link

KeyError when updating season_counter #77

Closed samaranin closed 1 year ago

samaranin commented 2 years ago

I've got KeyError when trying to run a simulation on my data.
Simulation code and weather data can be found here -> WeTransfer <- and below.

My code and initial parameters for simulation:

from aquacrop import AquaCropModel, Soil, Crop, InitialWaterContent, IrrigationManagement
import pandas as pd

if __name__ == "__main__":
    weather_data = pd.read_csv("./key_error_example_data.csv")
    weather_data["Date"] = pd.to_datetime(weather_data["Date"])
    model_os = AquaCropModel(
                sim_start_time=f"2015/05/15",
                sim_end_time=f"2016/03/10",
                weather_df=weather_data,
                soil=Soil(soil_type='SiltClayLoam'),
                crop=Crop('Wheat', planting_date='05/15'),
                initial_water_content=InitialWaterContent(),
                irrigation_management=IrrigationManagement(irrigation_method=1, SMT=[70] * 4)
            )
    model_os.run_model(till_termination=True)
    model_results = model_os.get_simulation_results().head()
    print(model_results)

And the error (just the main part of it)

File "/home/boiko/Projects/original-aquacrop/aquacrop/timestep/update_time.py", line 58, in update_time
    clock_struct.time_step_counter = clock_struct.time_span.get_loc(
  File "/home/boiko/Projects/original-aquacrop/venv/lib/python3.10/site-packages/pandas/core/indexes/datetimes.py", line 698, in get_loc
    raise KeyError(orig_key) from err
KeyError: Timestamp('2016-05-15 00:00:00')

I assume that this error appears when the simulation tries to switch to another season but clock_struct.time_span does not contain dates for this period (the next planting date is after the last available date in clock_struct.time_span). I've fixed this with a quick fix inside aquacrop/timestep/update_time.py from line 58:

# ***********************************************************************
# Added this code to avoid the situation when left no weather data but simulation is trying to run further
# there was just commented code below
# clock_struct.time_step_counter = clock_struct.time_span.get_loc(
#     clock_struct.planting_dates[clock_struct.season_counter]
# )

# if the last date in available dates in time span is less than the planting date in next season
# we will finish the model and stop the simulation
if clock_struct.time_span[-1] < clock_struct.planting_dates[clock_struct.season_counter]:
    clock_struct.model_is_finished = True
    return clock_struct, init_cond, param_struct
# otherwise we are using original code and extracting data for the new planting date
else:
    clock_struct.time_step_counter = clock_struct.time_span.get_loc(
        clock_struct.planting_dates[clock_struct.season_counter]
    )
# ***********************************************************************

But I think that it needs to be fixed on a higher level. Maybe someone will have an idea of how or where this can be fixed.

UPDATE: I think this should be fixed in aquacrop/initialize/read_model_parameters.py from line 130, where the number of planting years is calculated because the number of seasons depends on this value. In cases similar to my should be only 1 planting year.

samaranin commented 2 years ago

I've fixed this by changing the method of clock_struct.n_seasons calculation in aquacrop/initialize/read_model_parameters.py from line 189:

diff_between_dates = (sim_end_date - sim_start_date).days
total_number_of_years = diff_between_dates // 365
clock_struct.n_seasons = total_number_of_years + 1
thomasdkelly commented 2 years ago

Hi @samaranin

Thanks for creating the pull request. Ill try and take a look at your example today but I will be on holiday for the next two weeks so the PR will likely not be merged before then, apologies.

Tom

samaranin commented 2 years ago

Thanks a lot for the answer!
Of course, no problems, this is not a critical bug and doesn't need any immediate answer.
Have a good holiday!