Spaces:
Runtime error
Runtime error
File size: 7,392 Bytes
399a98a 196cbb2 8ff070c 196cbb2 542edf7 196cbb2 542edf7 e8721da 8ff070c e8721da 8ff070c e8721da 399a98a 8ff070c e8721da ec9d9e0 e8721da ec9d9e0 e8721da 196cbb2 e8721da 196cbb2 e8721da 196cbb2 542edf7 196cbb2 ec9d9e0 542edf7 8ff070c ec9d9e0 e8721da 542edf7 8ff070c 542edf7 8ff070c 542edf7 e8721da 196cbb2 25d0ed1 d93b3a4 25d0ed1 d93b3a4 25d0ed1 d93b3a4 25d0ed1 d93b3a4 25d0ed1 196cbb2 d93b3a4 ba70fb9 d93b3a4 399a98a d93b3a4 399a98a d93b3a4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from forecast import get_forecast_data
from retrieve_coefs_max_yield import get_coefs_Kc_Ky_and_max_yield
from utils.soil_utils import get_soil_properties
def calculate_ETx(Kc, ETo):
"""
Calculate the maximum evapotranspiration (ETx) using the crop coefficient (Kc) and reference evapotranspiration (ETo).
Parameters:
Kc (float): Crop coefficient
ETo (float): Reference evapotranspiration (mm)
Returns:
float: Maximum evapotranspiration (ETx) in mm
"""
ETx = Kc * ETo
return ETx
def calculate_ETa(ETx, soil_moisture, field_capacity, wilting_point, water_deficit, ETo):
"""
Calculate the actual evapotranspiration (ETa) using the maximum evapotranspiration (ETx), soil moisture, field capacity, and wilting point.
Parameters:
ETx (float): Maximum evapotranspiration (mm)
soil_moisture (Series): Current soil moisture content (%)
field_capacity (float): Field capacity of the soil (%)
wilting_point (float): Wilting point of the soil (%)
Returns:
float: Actual evapotranspiration (ETa) in mm
"""
Ks = 1 - (water_deficit / ETo) # coef de stress hydrique = precipitation / et0
Ks = Ks.clip(lower=0, upper=1)
ETa = ETx * Ks
ETa.loc[soil_moisture > field_capacity] = ETx.loc[soil_moisture > field_capacity]
ETa.loc[soil_moisture < wilting_point] = 0
return ETa
def calculate_yield_projection(Yx, ETx, ETa, Ky):
"""
Calculate the agricultural yield projection using the FAO water production function.
Parameters:
Yx (float): Maximum yield (quintal/ha)
ETx (float): Maximum evapotranspiration (mm)
ETa (float): Actual evapotranspiration (mm)
Ky (float): Yield response factor
Returns:
float: Projected yield (quintal/ha)
"""
Ya = Yx * (1 - Ky * (1 - ETa / ETx))
Ya.loc[ETx == 0] = 0
return round(Ya, 2)
def add_cultural_coefs(monthly_forecast: pd.DataFrame, cultural_coefs: pd.DataFrame) -> pd.DataFrame:
monthly_forecast["Kc"] = 0
monthly_forecast["Ky"] = 0
for month in range(1, 13):
Kc = cultural_coefs["Kc"][cultural_coefs.Mois == month].iloc[0]
Ky = cultural_coefs["Ky"][cultural_coefs.Mois == month].iloc[0]
monthly_forecast.loc[(monthly_forecast.month==month).to_numpy(), "Kc"] = Kc
monthly_forecast.loc[(monthly_forecast.month==month).to_numpy(), "Ky"] = Ky
return monthly_forecast
def compute_yield_forecast(
latitude: float,
longitude: float,
culture: str = "Colza d'hiver",
region: str = "Bourgogne-Franche-Comté",
scenario: str = "pessimist",
shading_coef: float = 0.,
):
monthly_forecast = get_forecast_data(latitude, longitude, scenario=scenario, shading_coef=shading_coef)
cultural_coefs, max_yield = get_coefs_Kc_Ky_and_max_yield(culture, region)
monthly_forecast = add_cultural_coefs(monthly_forecast, cultural_coefs)
Kc = monthly_forecast["Kc"]
Ky = monthly_forecast["Ky"]
soil_properties = get_soil_properties(latitude, longitude)
ETo = monthly_forecast["Evaporation (mm/day)"]
ETx = calculate_ETx(Kc, ETo)
ETa = calculate_ETa(
ETx,
monthly_forecast["Moisture in Upper Portion of Soil Column (kg m-2)"],
soil_properties["field_capacity"],
soil_properties["wilting_point"],
water_deficit=monthly_forecast["Water Deficit (mm/day)"],
ETo=ETo,
)
projected_yield = calculate_yield_projection(
Yx=max_yield,
ETx=ETx,
ETa=ETa,
Ky=Ky)
monthly_forecast["Estimated yield (quintal/ha)"] = projected_yield
return monthly_forecast
def get_annual_yield(monthly_forecast: pd.DataFrame) -> pd.Series:
yield_forecast = pd.Series(
index=monthly_forecast["time"],
data=monthly_forecast["Estimated yield (quintal/ha)"].to_numpy(),
)
yield_forecast = yield_forecast.resample("1YE").mean()
return yield_forecast
def plot_yield(
latitude: float,
longitude: float,
culture: str = "Colza d'hiver",
region: str = "Bourgogne-Franche-Comté",
scenario: str = "pessimist",
shading_coef: float = 0.2,
) -> plt.Figure:
monthly_forecast = compute_yield_forecast(
latitude=latitude,
longitude=longitude,
culture=culture,
scenario=scenario,
shading_coef=0.,
)
yield_forecast = get_annual_yield(monthly_forecast)
n_years = 10
years = 2025 + np.arange(len(yield_forecast))
aggregated_years = years[years % n_years == 0]
aggregated_forecasts = yield_forecast.rolling(n_years).sum()[years % n_years == 0]
width = 3 # the width of the bars
fig, ax = plt.subplots(layout='constrained')
_ = ax.bar(aggregated_years, aggregated_forecasts, width, label="No shading")
if shading_coef > 0:
monthly_forecast_with_shading = compute_yield_forecast(
latitude=latitude,
longitude=longitude,
culture=culture,
scenario=scenario,
shading_coef=shading_coef,
)
yield_forecast_with_shading = get_annual_yield(monthly_forecast_with_shading)
aggregated_forecasts_with_shading = yield_forecast_with_shading.rolling(n_years).sum()[years % n_years == 0]
_ = ax.bar(aggregated_years + width, aggregated_forecasts_with_shading, width, label="20% shading")
ax.legend()
ax.set_xlabel("Année")
ax.set_ylabel(f"Production agricole de {culture} estimée (quintal / ha)")
ax.set_ylim(150)
return fig
if __name__ == '__main__':
latitude = 47
longitude = 5
cultures = ["Colza d'hiver", "Blé tendre d'hiver", "Orge d'hiver"]
dfs = []
for culture in cultures:
scenario = "pessimist"
shading_coef = 0.2
monthly_forecast = compute_yield_forecast(
latitude=47,
longitude=5,
culture=culture,
scenario=scenario,
shading_coef=0.,
)
monthly_forecast_with_shading = compute_yield_forecast(
latitude=47,
longitude=5,
culture=culture,
scenario=scenario,
shading_coef=shading_coef,
)
fig = plot_yield(latitude, longitude, culture, scenario="pessimist", shading_coef=shading_coef)
plt.show()
# yield_forecast = get_annual_yield(monthly_forecast)
# yield_forecast_df = yield_forecast.reset_index()
# yield_forecast_df.columns = ["time", "yield_simple_forecast"]
# yield_forecast_df["year"] = yield_forecast_df["time"].dt.year
# yield_forecast_with_shading = get_annual_yield(monthly_forecast_with_shading)
# yield_forecast_with_shading_df = yield_forecast_with_shading.reset_index()
# yield_forecast_with_shading_df.columns = ["time", "yield_with_shading_forecast"]
# yield_forecast_with_shading_df["year"] = yield_forecast_with_shading_df["time"].dt.year
# final_df = pd.merge(yield_forecast_df[["year", "yield_simple_forecast"]], yield_forecast_with_shading_df[["year", "yield_with_shading_forecast"]], on="year")
# final_df["culture"] = culture
# dfs.append(final_df)
# result = pd.concat(dfs, axis=0)
# result.to_csv("data/data_yield/rendement_forecast.csv", index=False)
|