In this notebook we will setup a TSEB model to run a time series data at point scale.
The main input data consists on an ASCII table with tab separators and with the first row containing the names of the variables. The table should at least contain the following field names (case sensitive):
- TSEB-PT :
Year, DOY, Time, Trad, VZA, Ta, u, ea, Sdn, LAI & hc
- DTD :
Year, DOY, Time, Trad_0, Trad, VZA, Ta_0, Ta, u, ea, Sdn, LAI & hc
- TSEB-2T :
Year, DOY, Time, Tc, Ts, Ta, u, ea, Sdn, LAI & hc
Year is not really used in the model but is kept in case several years were processed, DOY is the day of the year (1-366), Time is the local-solar measurement time in decimal hours (0-24). Trad is the radiometric composite temperature; Trad_0, the same for time 0 (close to sunrise) for DTD model; Ts and Tc are the component soil and canopy temperatures for TSEB-2T; Ta is the air temperature: all temperatures expressed in Kelvin. u is the wind speed measurement (m s$^{-1}$), ea is the atmospheric vapour pressure (mb), Sdn is the shortwave irradiance (W m$^{-2}$), LAI is the effective leaf area index, and hc is the canopy height (m).
Additional input variables that can be included in the table are: SAA solar azimuth angle, SZA solar zenith angle, Ldn incoming longwave radiation (W m$^{-2}$), fc vegetation fractional cover, fg vegetation green fraction, wc canopy width-to-height ratio, and G soil heat flux (W m$^{-2}$).
If any of those additional variables are not found in the table they will be internally estimated by TSEB (in case of SAA, SZA, Ldn, fc, and G) or default values will be used (in case of other variables). The order of the columns is not relevant, and neither whether there are additional columns in the table (they will be ignored if their names do not match any of the possible input variables).
For more information about the inputs and outputs of pyTSEB click here
You can press the Load Configuration File button to load a configuration text file which will upload all its information to the corresponding cells.
You can also press the Save Configuration File button to save the configuration in a text file which can be used in future runs.
In [ ]:
from pyTSEB.TSEBIPythonInterface import TSEBIPythonInterface # import the PyTSEB class object in the pyTSEB.py module
setup = TSEBIPythonInterface() # Create the setup instance from the PyTSEB class object
setup.point_time_series_widget() # Load the TSEB configuration Widget
Once TSEB is configured we parsed all the information in the widgets and run the selected model.
After the processing is done an ASCII table with the following variables will be written in the output txt file:
Year, DOY, Time, LAI, f_g, skyl, VZA, SZA, SAA, Ldn, Rn_model, Rn_sw_veg, Rn_sw_soil, Rn_lw_veg, Rn_lw_soil, Tc, Ts, Tac, LE_model, H_model, LE_c, H_c, LE_s, H_s, flag, zo, d, G_model, R_s, R_x, R_a, u_friction, L, n_iterations
where variables with the same name as input variables have the same meaning, and for the others: skyl is the ratio of diffuse radiation, Rn_model is net radiation (W m-2; sw and lw subscripts stand for shortwave and longwave, veg and soil for canopy and soil), Tc, Ts and Tac are canopy, soil and inter-canopy-air temperatures (K), LE_model is latent heat flux and H_model is sensible heat flux (W m-2; subscripts c and s stand for canopy and soil respectively), flag is a quality flag (255==BAD), zo and d are roughness length and zero-plane displacement height (m), R_s, R_x and R_a are resistances to heat and momentum transport (s m-1), u_friction is friction velocity (m s-1), L is the Monin-Obukhov length (m) and n_iterations is the number of iterations of TSEB needed to achieve model convergence.
Now we can open the output and plot the TSEB outputs:
In [ ]:
import numpy as np
from bokeh.plotting import figure, output_file, show
from bokeh.io import output_notebook
from bokeh.models import *
from bokeh.resources import INLINE
output_notebook(resources=INLINE)
# get the data
output=np.genfromtxt(setup.outputFile,names=True,dtype=None)
# create a datetime variable
timestamp=np.array(output['Year'].astype(int).astype(str),dtype='datetime64')
timestamp=timestamp+np.array(output['DOY'],dtype='timedelta64[D]')
timestamp=np.array(timestamp.astype(str))
# Add time to the time
for i,string in enumerate(timestamp):
timestamp[i]=string+'T00:00'
timestamp=np.array(timestamp,dtype='datetime64')
delta=np.array(output['Time'].astype(int),dtype='timedelta64[h]')
timestamp=timestamp+delta
timestamp=timestamp+np.array(np.array((output['Time']-output['Time'].astype(int))*60,dtype='timedelta64[m]'))
# Create Figure
source=ColumnDataSource(data=dict(timestamp=timestamp,Year=output['Year'],DOY=output['DOY'],Time=np.round(output['Time'],2),
H=np.round(output['H_model'],0),LE=np.round(output['LE_model'],0),Rn=np.round(output['Rn_model'],0),
G=np.round(output['G_model'],0),flag=output['flag']))
p = figure(title="Time Series", plot_width=600, plot_height=400,x_axis_type="datetime")
# Plot all the points as dashed lines
p.line('timestamp','H',source=source, color='red',line_dash=[4,4])
p.line('timestamp','LE',source=source, color='blue', line_dash=[4,4])
line=p.line('timestamp','Rn',source=source, color='black', line_dash=[4,4])
p.line('timestamp','G',source=source, color='green', line_dash=[4,4])
# Create a hover tool
hover = HoverTool(tooltips=[("Date", "@Year"),('DOY',"@DOY"),
('Time',"@Time"),('H','@H'),
('LE','@LE'),('Rn','@Rn'),
('G','@G'),('flag','@flag')],line_policy='nearest',point_policy='snap_to_data',mode='vline', renderers=[line])
p.add_tools(hover)
# Filter only good quatlity data points flag<5:
H=np.array(output['H_model'])
H[output['flag']>=5]=float('nan')
LE=np.array(output['LE_model'])
LE[output['flag']>=5]=float('nan')
Rn=np.array(output['Rn_model'])
Rn[output['flag']>=5]=float('nan')
G=np.array(output['G_model'])
G[output['flag']>=5]=float('nan')
#Plot good quality data as straight lines
p.line(x=timestamp,y=H, color='red', legend='H')
p.line(x=timestamp,y=LE, color='blue', legend='LE')
p.line(x=timestamp,y=Rn, color='black', legend='Rn')
p.line(x=timestamp,y=G, color='green', legend='G')
show(p);
In [ ]: