Senet
Energy Balance model approach for crop water demand estimation
Install / Use
/learn @rslab-ntua/SenetREADME
senet
Energy Balance model approach for irrigation (SEN-ET SNAP plugin).
Installation
Install ESA SNAP
For the installation of ESA SNAP run the automated script (install_snap.sh) for downloading and installing the official Linux installer from the official ESA repository. To install SNAP
run the following commands:
$chmod +x install_snap.sh
$./install_snap.sh
:warning: Do not install SNAP to default option (/home/USER/snap) and install it in a different folder (e.g /home/USER/esa-snap) to avoid facing problems with Ubuntu snap.
Install SEN-ET SNAP plugin
Since there is no official support of SNAP to install plugins through CLI, install_senet.sh script was developed for the installation of SEN-ET plugin. The script downloads SEN-ET plugin, and sets the enviroment for the installation of the netbeans (*.nbm) SEN-ET modules. To install SEN-ET a complete installation of ESA SNAP is required and user must provide a full SNAP installation path (e.g /home/USER/esa-snap) and also SNAP installation auxiliary path (e.g /home/USER/.snap). To install SEN-ET run the following commands:
$chmod +x install_senet.sh
$./install_senet.sh
SNAPPY permanent installation
To configure SNAPPY permanently in a Python enviroment use snappy_conf_perm.sh. The shell script input are the complete installation path of SNAP and the python path.
$chmod +x snappy_conf_perm.sh
$./snappy_conf_perm.sh
Install ESA CCI Land Cover Map
Download and install ESA CCI Land Cover Map to ESA-SNAP with install_CCI_LC.sh script. The shell script input is the complete installation path of SNAP.
$chmod +x install_CCI_LC.sh
$./install_CCI_LC.sh
Install Python GDAL
Use install_gdal.sh for a complete installation of GDAL python bindings.
$chmod +x install_gdal.sh
$./install_gdal.sh
Install ECMWF CDS API Key
The Climate Data Store Application Program Interface is a service providing programmatic access to CDS data. Use install_CDS_key.sh to install the CDS API key.
$chmod +x install_CDS_key.sh
$./install_CDS_key.sh
:warning: An CDS Copernicus climate account must be provided in order to have the API key. Create a new account here.
Update server SNAP
Since no UI is provided to update SNAP use update_snap_no_GUI.sh to get the latest version of ESA SNAP.
$chmod +x update_snap_no_GUI.sh
$./update_snap_no_GUI.sh
Python Pipeline
The following section analyses step by step the complete Python pipeline in order to acquire daily evapotranspiration.
| Python Method Index | Operation Type | ------------------------------------------------------------------------------------------------------------|--------------------| | Get Data | Python Method | | Sentinel-2 preprocessing graph | GPF SNAP Graph | | Add elevation graph | GPF SNAP Graph | | Add landcover graph | GPF SNAP Graph | | Estimate leaf reflectance and transmittance | Python Method | | Estimate fraction of green vegetation | Python Method | | Produce maps of vegetation structural parameters | Python Method | | Estimate aerodynamic roughness | Python Method | | Sentinel-3 pre-processing graph | GPF SNAP Graph | | Warp to template | Python Method | | Sharpen LST | Python Method | | Download ECMWF ERA5 reanalysis data | Python Method | | Prepare ERA5 reanalysis data | Python Method | | Estimate longwave irradiance | Python Method | | Estimate net shortwave radiation | Python Method | | Estimate land surface energy fluxes | Python Method | | Estimate daily evapotranspiration | Python Method |
Get data
At first a Sentinel-2 L2A multispectral image and a Sentinel-3 LST thermal image at the same date have to be selected. The images currently are found from Copernicus Open Access Hub, given an area of interest (AOI) and a date range.
:warning: Note that an ESA APIHUB account must be used for searching satellite data and also, user and password variables must be changed inside the code. Create a new account here.
See the example bellow:
import os
import getpass
import geopandas
import pyproj
from datetime import datetime, timedelta
from get_creodias import get_data, prepare_data_senet_S2 eodata_path_creator
from sentinels import sentinel2, sentinel3
# All ROI must be in WGS84
wgs_crs = pyproj.crs.CRS("epsg:4326")
USER = getpass.getuser()
meteo_datapath = "/home/eouser/uth/Cap_Bon/Meteo/"
AOI_path = "/home/eouser/uth/Cap_Bon/AOI/AOI_Cap_Bon.geojson"
AOI = geopandas.read_file(AOI_path)
CRS = AOI.crs
if CRS != wgs_crs:
AOI = AOI.to_crs(wgs_crs.to_epsg())
WKT_GEOM = AOI.geometry[0]
user = "guest"
password = "guest"
start_date = "20210810"
end_date = "20210820"
data = get_data(AOI_path, start_date, end_date, user, password, producttype = "S2MSI2A")
data = prepare_data_senet_S2(data)
creodias_paths = eodata_path_creator(data)
# From all available images select the first
s2_path, s2_name = os.path.split(creodias_paths[0])
print(s2_path, s2_name)
s2 = sentinel2(s2_path, s2_name)
s2.getmetadata()
# Now select an available S3 image
start_date = s2.date
end_date = s2.date + timedelta(days=1)
data = get_data(AOI_path, start_date, end_date, user, password, platform = "Sentinel-3", producttype = "SL_2_LST___")
creodias_paths = eodata_path_creator(data)
for path in creodias_paths:
# Again select the first image
s3_path, s3_name = os.path.split(path)
s3 = sentinel3(s3_path, s3_name)
s3.getmetadata()
if s3.date == s2.date:
break
# Because the user has no permission to write make a new directory inside the user with the selected image name
home = "/home/eouser/uth"
if not os.path.exists(os.path.join(home, "Sentinel-2")):
os.mkdir(os.path.join(home, "Sentinel-2"))
if not os.path.exists(os.path.join(home, "Sentinel-2", s2.tile_id)):
os.mkdir(os.path.join(home, "Sentinel-2", s2.tile_id))
if not os.path.exists(os.path.join(home, "Sentinel-2", s2.tile_id, s2.name)):
os.mkdir(os.path.join(home, "Sentinel-2", s2.tile_id, s2.name))
s2_savepath = os.path.join(home, "Sentinel-2", s2.tile_id)
if not os.path.exists(os.path.join(home, "Sentinel-3")):
os.mkdir(os.path.join(home, "Sentinel-3"))
if not os.path.exists(os.path.join(home, "Sentinel-3", s3.name)):
os.mkdir(os.path.join(home, "Sentinel-3", s3.name))
s3_savepath = os.path.join(home, "Sentinel-3")
Sentinel-2 preprocessing graph
This graph resamples the L2A Sentinel-2 scene to 20 m, subsets required bands and saves them as individual products and estimates biophysical parameters from the refectance bands. This step creates a product containing the 20 m reflectance bands (B2, B3, B4, B5, B6, B7, B8A, B11, B12), a product containing the scene's sun zenith angle band (sun_zenith), a product containing cloud mask derived from scene's quality flags and a product containing biophysical parameters (LAI, FAPAR, Fcover, Cab, Cw). See the example bellow:
import os
import subprocess
subprocess.run([f"/home/eouser/{USER}/esa-snap/bin/gpt", "./auxdata/sentinel_2_preprocessing.xml",
"-PINPUT_S2_L2A={}".format(os.path.join(s2_path, s2_name, "MTD_MSIL2A.xml")),
"-PAOI={}".format(WKT_GEOM),
"-POUTPUT_REFL={}".format(os.path.join(s2_savepath, s2_name, "{}_{}_REFL".format(s2.tile_id, s2.str_datetime))),
"-POUTPUT_SUN_ZEN_ANG={}".format(os.path.join(s2_savepath, s2_name, "{}_{}_SUN-ZEN-ANG".format(s2.tile_id, s2.str_datetime))),
"-POUTPUT_MASK={}".format(os.path.join(s2_savepath, s2_name, "{}_{}_MASK".format(s2.tile_id, s2.str_datetime))),
"-POUTPUT_BIO={}".format(os.path.join(s2_savepath, s2_name, "{}_{}_BIO".format(s2.tile_id, s2.str_datetime)))
])
Add elevation graph
This graph creates a high resolution digital elevation model (DEM) for the given L2A Sentinel-2 scene. See the example bellow:
import os
import subprocess
subprocess.run([f"/home/eouser/{USER}/esa-snap/bin/gpt", "./auxdata/add_elevation.xml",
"-PINPUT_S2_MASK={}".format(os.path.join(s2_savepath, s2_name, "{}_{}_REFL.dim".format(s2.tile_id, s2.str_datetime))),
"-POUTPUT_SRTM_ELEV={}".format(os.path.join(s2_savepath, s2_name, "{}_{}_ELEV".format(s2.tile_id, s2.str_datetime)))
])
Add landcover graph
This graph creates A land-cover map for the given Sentinel-2 scene using the ESA CCI Land Cover 2015 map. ESA CCI Land Cover 2015 map is already downloaded with SNAP. See the example bellow:
import o
