gaia / docs /compute.py
AliceTt's picture
addded some docs for indicators
98a2104
import numpy as np
import pandas as pd
from pvlib.solarposition import sun_rise_set_transit_spa
from agroclimatic_indicators import (
agro_indicators,
animal_indicators,
climatic_indicators,
)
## Compute Agronomics
def compute_vpd(df: pd.DataFrame):
"""
Compute VPD.
Parameters
----------
df : DataFrame
The input dataframe containing sensor data.
Returns
-------
arraylike
VPD at df's timestep
"""
return agro_indicators.vpd(df.air_temperature, df.relative_humidity)
def compute_et0(
df: pd.DataFrame,
latitude: float,
longitude: float
):
"""
Compute reference evapotranspiration.
Parameters
----------
df : DataFrame
The input dataframe containing sensor data.
latitude : float
Latitude of the location.
longitude : float
Longitude of the location
Returns
-------
arraylike
Daily reference evapotranspiration.
"""
irradiance = (
(df.photon_flux_density.resample("1h").mean() / 2.1).resample("1d").sum()
)
T = df.air_temperature.resample("1d").mean()
Tmin = df.air_temperature.resample("1d").min()
Tmax = df.air_temperature.resample("1d").max()
RHmin = df.relative_humidity.resample("1d").min()
RHmax = df.relative_humidity.resample("1d").max()
WS = df.wind_speed.resample("1d").mean()
JJulien = np.unique(df.index.day_of_year)
l = [
agro_indicators.et0(
irradiance.iloc[i],
T.iloc[i],
Tmax.iloc[i],
Tmin.iloc[i],
RHmin.iloc[i],
RHmax.iloc[i],
WS.iloc[i],
JJulien[i],
latitude,
np.array([longitude]),
)
for i in range(len(JJulien))
]
if len(JJulien) == 1:
et0 = l[0]
else:
et0 = l
return et0
## Compute Climatics
def compute_frostday(df: pd.DataFrame):
"""
Define if day is a frost day (min temperature below 0°C).
Parameters
----------
df : DataFrame
Air sensors data.
Returns
-------
bool
True if day is a frost day, else False.
"""
T = df.air_temperature.resample("1d").min()
ind = climatic_indicators.frost_bool(T, 0)
if ind.shape[0] == 1:
ind = ind.iloc[0]
return ind
def compute_strongfrostday(df: pd.DataFrame):
"""
Define if day is a strong frost day (min temperature below -3°C).
Parameters
----------
df : DataFrame
The input dataframe containing temperature data.
Returns
-------
bool
True if day is a strong frost day, else False.
"""
T = df.air_temperature.resample("1d").min()
ind = climatic_indicators.frost_bool(T, -3)
if ind.shape[0] == 1:
ind = ind.iloc[0]
return ind
def compute_thermalstressday(df: pd.DataFrame, stress_threshold: float = 35):
"""
Define if daily temperature is a source of thermal stress (max temperature above stress threshold).
Parameters
----------
df : DataFrame
The input dataframe containing air temperature data.
stress_threshold : float
Threshold temperature of stress (degrees Celsius).
Returns
-------
bool
True if day is a day with thermal stress, else False.
"""
T = df.air_temperature.resample("1d").max()
ind = climatic_indicators.thermalstress_bool(T, stress_threshold)
if ind.shape[0] == 1:
ind = ind.iloc[0]
return ind
def compute_summerday(df: pd.DataFrame):
"""
Define if day is a summer day (max temperature above 25°C).
Parameters
----------
df : DataFrame
The input dataframe containing air temperature data.
Returns
-------
bool
True if day is a summer day, else False.
"""
T = df.air_temperature.resample("1d").max()
ind = climatic_indicators.summerday_bool(T)
if ind.shape[0] == 1:
ind = ind.iloc[0]
return ind
def compute_scorchday(df: pd.DataFrame, scorch_threshold: float = 25):
"""
Define if day is a scorching day (jour échaudant) (max temperature above scorch threshold).
Parameters
----------
df : DataFrame
The input dataframe containing air temperature data.
scorch_threshold : float
Temperature threshold above which the day is considered scorching (degrees Celsius).
Returns
-------
bool
True if day is a scorching day, else False.
"""
T = df.air_temperature.resample("1d").max()
ind = climatic_indicators.scorch_bool(T, scorch_threshold)
if ind.shape[0] == 1:
ind = ind.iloc[0]
return ind
def compute_tropicalnight(df: pd.DataFrame, latitude: float, longitude: float):
"""
Define if night is a tropical night (min temperature above 20°C).
Parameters
----------
df : DataFrame
The input dataframe containing air temperature data.
latitude : float
Latitude of the location.
longitude : float
Longitude of the location.
Returns
-------
bool
True if night is a tropical night, else False.
"""
if len(df) == 0:
return None
df = sun_rise_set_transit_spa(
times=df.index, latitude=latitude, longitude=longitude
).merge(df["air_temperature"], left_index=True, right_index=True)
df = df.loc[(df.index < df["sunrise"]) | (df.index > df["sunset"])]
df_minnight = df.resample("24h", offset="12h")["air_temperature"].min()
tropicalnight = climatic_indicators.tropicalnight_bool(df_minnight)
if tropicalnight.shape[0] == 1:
tropicalnight = tropicalnight.iloc[0]
return tropicalnight
def compute_mintempnight(df: pd.DataFrame, latitude: float, longitude: float):
"""
Return minimal night temperature.
Parameters
----------
df : DataFrame
The input dataframe containing air temperature data.
latitude : float
Latitude of the location.
longitude : float
Longitude of the location.
Returns
-------
float
Min night temperature (degrees Celsius).
"""
if len(df) == 0:
return None
df = sun_rise_set_transit_spa(df.index, latitude, longitude).merge(
df["air_temperature"], left_index=True, right_index=True
)
df = df.loc[(df.index < df["sunrise"]) | (df.index > df["sunset"])]
df_minnight = df.resample("24h", offset="12h")["air_temperature"].min()
if df_minnight.shape[0] == 1:
df_minnight = df_minnight.iloc[0]
return df_minnight
def compute_hli(
df: pd.DataFrame,
):
"""
Computes HLI (heat load index).
Parameters
----------
df : DataFrame
The input dataframe containing air temperature data.
Returns
-------
float
HLI value.
"""
ind = animal_indicators.hli(
irradiance=df.photon_flux_density,
air_temperature=df.air_temperature,
RH=df.relative_humidity,
wind_speed=df.wind_speed,
)
if ind.size == 1:
df_ind = float(ind)
else:
df_ind = pd.Series(ind, index=df.index)
return df_ind