Using TREX for reproducible and multi-method sap flow quantification
A workflow for TDM sap flow data processing
TREX Workflow
1. Background
The package TREX
(tree sapflow extractor) provides functionalities for thermal dissipation sap flow data pre- and post-processing.
More specifically, raw sap flow data (expressed as temperature or voltage differences) can be:
- visually inspected and outliers can be identified and removed (manual and automatic detection),
- zero-flow conditions can be derived using a wealth of well-established approaches,
- sap flow rates can be estimated using either literature- or user-specific calibration parameters for the thermal dissipation method,
- uncertainty of sap flow estimates stemming from parameter choices can be assessed,
- tree ecophysiologial responses to environmental drivers can be derived (e.g., crown conductance vs vapor pressure deficit relations).
For more details, visit the dedicated
TREX
website
2. Set-up Steps
# install if necessary
packages <- (c("remotes","zoo","lubridate","shiny","plotly"))
install.packages(setdiff(packages, rownames(installed.packages())))
remotes::install_github("the-Hull/TREX")
library(TREX)
# to get a full list of available functionalities check
#?TREX
library(zoo) # work with time series objects
library(lubridate) # work with date formats
library(shiny) # visual inspection and outlier detection
library(plotly) # interactive plots
3. Data preparation
Import data
Sap flow time series data and concurrently recorded meteorological data should be provided as input.
# URLs were the data are stored
vpd_url <- RCurl::getURL("https://raw.githubusercontent.com/deep-org/workshop_data/master/esa-workshop2020/Environmental%20data/Vapour_pressure_deficit%20(kPa).txt")
rad_url <- RCurl::getURL("https://raw.githubusercontent.com/deep-org/workshop_data/master/esa-workshop2020/Environmental%20data/Solar_radiance%20(W%20m-2).txt")
prc_url <- RCurl::getURL("https://raw.githubusercontent.com/deep-org/workshop_data/master/esa-workshop2020/Environmental%20data/Precipitation%20(mm).txt")
sensor_url <- RCurl::getURL("https://raw.githubusercontent.com/deep-org/workshop_data/master/esa-workshop2020/TDP%20data/N13Ad_S1_dV%20(mv).txt")
# VPD (15-min)
vpd <- read.table(text = vpd_url, header=T, sep="\t")
head(vpd)
## Timestamp VPD
## 1 (10/19/06 16:15:00) NA
## 2 (10/19/06 16:30:00) NA
## 3 (10/19/06 16:45:00) NA
## 4 (10/19/06 17:00:00) NA
## 5 (10/19/06 17:15:00) NA
## 6 (10/19/06 17:30:00) NA
# solar radiation (15-min)
rad <- read.table(text = rad_url, header=T, sep="\t")
head(rad)
## Timestamp SR
## 1 (10/19/06 16:15:00) 83.33
## 2 (10/19/06 16:30:00) 58.67
## 3 (10/19/06 16:45:00) 58.67
## 4 (10/19/06 17:00:00) 30.33
## 5 (10/19/06 17:15:00) 18.33
## 6 (10/19/06 17:30:00) 5.00
# precipitation (daily)
prc <- read.table(text = prc_url, header=T, sep="\t")
head(prc)
## Timestamp Prec
## 1 01/01/06 2.9140029
## 2 02/01/06 1.4081558
## 3 03/01/06 0.0821319
## 4 04/01/06 0.0000000
## 5 05/01/06 0.0000000
## 6 06/01/06 0.0000000
# sap flow (15-min)
sensor <- read.table(text = sensor_url, header=T, sep="\t")
head(sensor)
## Timestamp dV
## 1 (04/17/12 15:00:00) NA
## 2 (04/17/12 15:15:00) NA
## 3 (04/17/12 15:30:00) NA
## 4 (04/17/12 15:45:00) NA
## 5 (04/17/12 16:00:00) NA
## 6 (04/17/12 16:15:00) NA
# convert to data.frames with timestamp as 'date'
vpd <- data.frame(timestamp = mdy_hms(vpd$Timestamp, tz="GMT"), value = vpd$VPD)
rad <- data.frame(timestamp = mdy_hms(rad$Timestamp, tz="GMT"), value = rad$SR)
prc <- data.frame(timestamp = dmy(prc$Timestamp, tz="GMT"), value = prc$Prec)
sensor = data.frame(timestamp = mdy_hms(sensor$Timestamp, tz="GMT"), value = sensor$dV)
Create TREX-compatible objects and clip the same time period of sap flow and meteorological data
The package includes functions for checking the consistency in the imported data (e.g., regular time steps in the time series objects, time zone and class of the time stamps).
# see help pages for the following functions
#?is.trex
#?dt.steps
sensor_raw_15min <- is.trex(sensor,
tz="GMT",
time.format="%Y-%m-%d %H:%M:%S",
solar.time=T,
long.deg=7.7459,
ref.add=FALSE,
df=FALSE)
sensor_raw_1h <- dt.steps(input=sensor_raw_15min,
start = "2012-05-01 00:00:00",
end = "2015-10-31 23:30:00",
time.int=60,
max.gap=120,
decimals=10,
df=FALSE)
plot(sensor_raw_1h, main="hourly raw sap flow data (mV)")
# make a data.frame
sensor_raw_1h_df <- data.frame(timestamp = ymd_hms(index(sensor_raw_1h), tz="GMT"), value = coredata(sensor_raw_1h))
vpd_15min <- is.trex(vpd,
tz="GMT",
time.format="%Y-%m-%d %H:%M:%S",
solar.time=T,
long.deg=7.7459,
ref.add=FALSE,
df=FALSE)
# vpd data
vpd_1h <- dt.steps(input=vpd_15min,
start = "2012-05-01 00:00:00",
end = "2015-10-31 23:30:00",
time.int=60,
max.gap=120,
decimals=10,
df=FALSE)
plot(vpd_1h, main="hourly VPD data (kPa)")
# radiation data
rad_15min <- is.trex(rad,
tz="GMT",
time.format="%Y-%m-%d %H:%M:%S",
solar.time=T,
long.deg=7.7459,
ref.add=FALSE,
df=FALSE)
rad_1h <- dt.steps(input=rad_15min,
start = "2012-05-01 00:00:00",
end = "2015-10-31 23:30:00",
time.int=60,
max.gap=120,
decimals=10,
df=FALSE)
plot(rad_1h, main="hourly radiation data (W m-2)")
# precip data
prc_1day <- is.trex(prc,
tz="GMT",
time.format="%Y-%m-%d",
solar.time=T,
long.deg=7.7459,
ref.add=FALSE,
df=FALSE)
prc_1day <- window(prc_1day, start = "2012-05-01 00:00:00", end = "2015-10-31 23:30:00")
plot(prc_1day, main="hourly precipitation data (mm)")
Visual inspection of time series, outlier detection and removal
Note: the current version of outlier detection cannot handle large datasets (e.g., hourly data for several years) cause the interactive plots become slow. We suggest, if you have long time series that you would like to inspect, to split the time series in shorter time periods and run the following steps sequentially.
Here, we provide an illustration of the functionalities of the outlier()
using couple of months of hourly sap flow data.
In action, the outlier function looks as follows:
Figure: Application of the outlier()
function to the example data set - note the interactive selection and deselection of observations considered outliers. The interactive app allows saving a list to disk with the original data set, the cleaned version, as well as subsets containing the automatic and the manual outlier selection.
# see help page for a detailed description
#?outlier()
# from a quick visual inspection of the hourly time sap flow time series data, we see that there are few irregularities, and potential outliers at the beginning of the 2015 growing season
plot(sensor_raw_1h, main="hourly raw sap flow data (mV)")
# zoom-in to a shorter time period
plot(window(sensor_raw_1h, start = "2015-03-01 00:00:00", end = "2015-05-01 00:00:00"), main="March - April 2015; hourly raw sap flow data (mV)")
# create an object with the period of interest, i.e., March - April 2015
tocheck <- window(sensor_raw_1h, start = "2015-03-01 00:00:00", end = "2015-05-01 00:00:00")
# make a data.frame
tocheck_df <- data.frame(timestamp = ymd_hms(index(tocheck), tz="GMT"), value = coredata(tocheck))
# save an .RData
save(tocheck_df, file="tocheck.RData")
# call outlier() app and load the generated .RData file
#outlier()
# after inspecting the time series with the outlier() an .RDS file is exported with the 'outlier-free' data.
# load the 'tocheck_Cleaned.Rds' file
tocheck_Cleaned <- readRDS("tocheck_Cleaned.Rds")
tocheck_Cleaned <- tocheck_Cleaned$series_cleaned
summary(tocheck_Cleaned)
## timestamp value
## Min. :2015-03-01 00:00:00 Min. :0.6774
## 1st Qu.:2015-03-16 05:45:00 1st Qu.:0.7700
## Median :2015-03-31 10:30:00 Median :0.7864
## Mean :2015-03-31 11:50:37 Mean :0.7752
## 3rd Qu.:2015-04-15 19:15:00 3rd Qu.:0.7914
## Max. :2015-05-01 00:00:00 Max. :0.8113
## NA's :241
summary(sensor_raw_1h_df)
## timestamp value
## Min. :2012-05-01 00:00:00 Min. :0.495
## 1st Qu.:2013-03-16 17:45:00 1st Qu.:0.748
## Median :2014-01-30 11:30:00 Median :0.779
## Mean :2014-01-30 11:30:00 Mean :0.762
## 3rd Qu.:2014-12-16 05:15:00 3rd Qu.:0.789
## Max. :2015-10-31 23:00:00 Max. :0.845
## NA's :9307
# Merge the cleaned data with the complete 'sensor_raw_1h' time series
sensor_raw_1h_df_clean <- sensor_raw_1h_df
sensor_raw_1h_df_clean[(sensor_raw_1h_df_clean$timestamp >= "2015-03-01 00:00:00" & sensor_raw_1h_df_clean$timestamp <= "2015-05-01 00:00:00"),"value"] <- NA
sensor_raw_1h_df_clean[sensor_raw_1h_df_clean$timestamp %in% tocheck_Cleaned$timestamp, "value"] =tocheck_Cleaned$value
plot(sensor_raw_1h_df)
points(sensor_raw_1h_df_clean, col=2)
legend("bottomright", c("raw", "outlier-free"),
lty = 1, col = c("black", "red") )
# convert time stamp to character
sensor_raw_1h_df_clean$timestamp <- as.character(sensor_raw_1h_df_clean$timestamp)
4. Estimate zero-flow conditions (DTmax)
# see help page for a detailed description
#?tdm_dt.max
output.max <- tdm_dt.max(sensor_raw_1h_df_clean,
methods = c("pd","mw","dr","ed"),
det.pd = TRUE,
interpolate = FALSE,
max.days = 10,
ed.window = 2*60,
vpd.input = vpd_1h,
sr.input = rad_1h,
criteria = c(sr = 30, vpd = 0.1, cv = 0.5),
df = FALSE)
str(output.max)
## List of 17
## $ max.pd :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.637 0.637 0.637 0.637 0.637 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ max.mw :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.641 0.641 0.641 0.641 0.641 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ max.dr :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.641 0.641 0.641 0.641 0.641 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ max.ed :'zoo' series from 2012-04-30 12:00:00 to 2015-10-31 23:00:00
## Data: num [1:30697] 0.637 0.637 0.637 0.637 0.637 ...
## Index: POSIXct[1:30697], format: "2012-04-30 12:00:00" "2012-05-01 00:00:00" ...
## $ daily_max.pd:'zoo' series from 2012-05-01 to 2015-11-01
## Data: num [1:1280] 0.637 0.633 0.64 0.641 0.637 ...
## Index: Date[1:1280], format: "2012-05-01" "2012-05-02" ...
## $ daily_max.mw:'zoo' series from 2012-05-01 to 2015-11-01
## Data: num [1:1280] 0.641 0.641 0.641 0.641 0.641 ...
## Index: Date[1:1280], format: "2012-05-01" "2012-05-02" ...
## $ daily_max.dr:'zoo' series from 2012-05-01 to 2015-11-01
## Data: num [1:1280] 0.641 0.641 0.641 0.641 0.641 ...
## Index: Date[1:1280], format: "2012-05-01" "2012-05-02" ...
## $ daily_max.ed:'zoo' series from 2012-05-01 to 2015-11-01
## Data: num [1:1280] 0.637 0.633 0.64 0.639 0.637 ...
## Index: Date[1:1280], format: "2012-05-01" "2012-05-02" ...
## $ all.pd :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] NA NA NA 0.637 NA ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ all.ed :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] NA NA NA 0.637 NA ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ input :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.63 0.634 0.636 0.637 0.635 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ ed.criteria : Named num [1:3] 30 0.1 0.5
## ..- attr(*, "names")= chr [1:3] "sr" "vpd" "cv"
## $ methods : chr [1:4] "pd" "mw" "dr" "ed"
## $ k.pd :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.01012 0.00431 0.00118 0 0.00202 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ k.mw :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.01784 0.01199 0.00883 0.00764 0.00968 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ k.dr :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.017 0.01115 0.008 0.00681 0.00885 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ k.ed :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.01012 0.00431 0.00118 0 0.00202 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
plot(output.max$input, ylab = expression(Delta*italic("V")))
lines(output.max$max.pd, col = "green")
lines(output.max$max.mw, col = "blue")
lines(output.max$max.dr, col = "orange")
lines(output.max$max.ed, col = "purple")
points(output.max$all.pd, col = "green", pch = 16)
legend("bottomright", c("raw", "max.pd", "max.mw", "max.dr", "max.ed"),
lty = 1, col = c("black", "green", "blue", "orange", "purple") )
# for visualizing, clip a single month (April, 2014)
plot(window(output.max$input, start="2014-04-01 00:00:00", end="2014-04-30 23:30:00"), ylab = expression(Delta*italic("V")))
lines(window(output.max$max.pd, start="2014-04-01 00:00:00", end="2014-04-30 23:30:00"), col = "green")
lines(window(output.max$max.mw, start="2014-04-01 00:00:00", end="2014-04-30 23:30:00"), col = "blue")
lines(window(output.max$max.dr, start="2014-04-01 00:00:00", end="2014-04-30 23:30:00"), col = "orange")
lines(window(output.max$max.ed, start="2014-04-01 00:00:00", end="2014-04-30 23:30:00"), col = "purple")
points(window(output.max$all.pd, start="2014-04-01 00:00:00", end="2014-04-30 23:30:00"), col = "green", pch = 16)
legend("bottomright", c("raw", "max.pd", "max.mw", "max.dr", "max.ed"),
lty = 1, col = c("black", "green", "blue", "orange", "purple") )
5. Correction of sensor artifacts
Apply heartwood correction (if needed)
# The sapwood depth of the selected tree is 2.5 cm, and the probe length 2 cm, so no heartwood correction needs to be applied
# see help page for a detailed description
#?tdm_hw.cor
#SFD_cor = tdm_hw.cor(output.max,probe.length=20,
# sapwood.thickness= 25,
# df=F)
6. Calculate sap flux density
# see help page for a detailed description
#?tdm_cal.sfd
output.data <- tdm_cal.sfd(output.max,
make.plot=T,
df=FALSE,
species="Picea abies")
str(output.data)
## List of 23
## $ max.pd :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.637 0.637 0.637 0.637 0.637 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ max.mw :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.641 0.641 0.641 0.641 0.641 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ max.dr :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.641 0.641 0.641 0.641 0.641 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ max.ed :'zoo' series from 2012-04-30 12:00:00 to 2015-10-31 23:00:00
## Data: num [1:30697] 0.637 0.637 0.637 0.637 0.637 ...
## Index: POSIXct[1:30697], format: "2012-04-30 12:00:00" "2012-05-01 00:00:00" ...
## $ daily_max.pd:'zoo' series from 2012-05-01 to 2015-11-01
## Data: num [1:1280] 0.637 0.633 0.64 0.641 0.637 ...
## Index: Date[1:1280], format: "2012-05-01" "2012-05-02" ...
## $ daily_max.mw:'zoo' series from 2012-05-01 to 2015-11-01
## Data: num [1:1280] 0.641 0.641 0.641 0.641 0.641 ...
## Index: Date[1:1280], format: "2012-05-01" "2012-05-02" ...
## $ daily_max.dr:'zoo' series from 2012-05-01 to 2015-11-01
## Data: num [1:1280] 0.641 0.641 0.641 0.641 0.641 ...
## Index: Date[1:1280], format: "2012-05-01" "2012-05-02" ...
## $ daily_max.ed:'zoo' series from 2012-05-01 to 2015-11-01
## Data: num [1:1280] 0.637 0.633 0.64 0.639 0.637 ...
## Index: Date[1:1280], format: "2012-05-01" "2012-05-02" ...
## $ all.pd :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] NA NA NA 0.637 NA ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ all.ed :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] NA NA NA 0.637 NA ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ input :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.63 0.634 0.636 0.637 0.635 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ ed.criteria : Named num [1:3] 30 0.1 0.5
## ..- attr(*, "names")= chr [1:3] "sr" "vpd" "cv"
## $ methods : chr [1:4] "pd" "mw" "dr" "ed"
## $ k.pd :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.01012 0.00431 0.00118 0 0.00202 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ k.mw :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.01784 0.01199 0.00883 0.00764 0.00968 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ k.dr :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.017 0.01115 0.008 0.00681 0.00885 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ k.ed :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696] 0.01012 0.00431 0.00118 0 0.00202 ...
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ sfd.pd :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696, 1:4] 0.01011 0.00431 0.00118 0 0.00202 ...
## ..- attr(*, "dimnames")=List of 2
## .. ..$ : chr [1:30696] "10118" "4313" "1180" "1" ...
## .. ..$ : chr [1:4] "k" "sfd" "q025" "q975"
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ sfd.mw :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696, 1:4] 0.01784 0.01199 0.00883 0.00764 0.00968 ...
## ..- attr(*, "dimnames")=List of 2
## .. ..$ : chr [1:30696] "17843" "11992" "8835" "7646" ...
## .. ..$ : chr [1:4] "k" "sfd" "q025" "q975"
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ sfd.dr :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696, 1:4] 0.017 0.01115 0.008 0.00681 0.00885 ...
## ..- attr(*, "dimnames")=List of 2
## .. ..$ : chr [1:30696] "17002" "11157" "8003" "6814" ...
## .. ..$ : chr [1:4] "k" "sfd" "q025" "q975"
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ sfd.ed :'zoo' series from 2012-05-01 to 2015-10-31 23:00:00
## Data: num [1:30696, 1:4] 0.01011 0.00431 0.00118 0 0.00202 ...
## ..- attr(*, "dimnames")=List of 2
## .. ..$ : chr [1:30696] "10118" "4313" "1180" "1" ...
## .. ..$ : chr [1:4] "k" "sfd" "q025" "q975"
## Index: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## $ model.ens :'data.frame': 1000432 obs. of 4 variables:
## ..$ k : num [1:1000432] 0e+00 1e-06 2e-06 3e-06 4e-06 5e-06 6e-06 7e-06 8e-06 9e-06 ...
## ..$ sfd : num [1:1000432] 0.00 1.82e-06 3.64e-06 5.45e-06 7.27e-06 ...
## ..$ q025: num [1:1000432] 0.00 9.78e-07 1.96e-06 2.94e-06 3.91e-06 ...
## ..$ q975: num [1:1000432] 0.00 3.62e-06 7.24e-06 1.09e-05 1.45e-05 ...
## $ out.param :'data.frame': 1 obs. of 7 variables:
## ..$ n : int 100
## ..$ a_mu : num 84.6
## ..$ a_sd : num 3.89
## ..$ log.a_mu: num 4.44
## ..$ log.a_sd: num 0.0462
## ..$ b_mu : num 1.55
## ..$ b_sd : num 0.0548
output.data$out.param
## n a_mu a_sd log.a_mu log.a_sd b_mu b_sd
## 1 100 84.60794 3.889986 4.436976 0.04619634 1.545292 0.05480365
plot(output.data$sfd.pd$sfd)
7. Calculate crown conductance to water, and its response to VPD
# see help page for a detailed description
#?out.data
output <- out.data(input=output.data$sfd.pd$sfd,
vpd.input=vpd_1h,
sr.input=rad_1h,
prec.input=prc_1day,
low.sr = 150, peak.sr=300, vpd.cutoff= 0.5, prec.lim=1,
method="env.filt", max.quant=0.99, make.plot=TRUE)
str(output)
## List of 4
## $ raw :'data.frame': 30696 obs. of 12 variables:
## ..$ timestamp: POSIXct[1:30696], format: "2012-05-01 00:00:00" "2012-05-01 01:00:00" ...
## ..$ year : num [1:30696] 2012 2012 2012 2012 2012 ...
## ..$ doy : num [1:30696] 122 122 122 122 122 122 122 122 122 122 ...
## ..$ hour : num [1:30696] 0 1 2 3 4 5 6 7 8 9 ...
## ..$ sr : num [1:30696] 0.6 0.6 0.6 0.6 0.6 ...
## ..$ sr.day : num [1:30696] 183 183 183 183 183 ...
## ..$ vpd : num [1:30696] 0.0595 0.047 0.0415 0.0434 0.0392 ...
## ..$ vpd.filt : num [1:30696] NA NA NA NA NA NA NA NA NA NA ...
## ..$ prec.day : num [1:30696] 11.1 11.1 11.1 11.1 11.1 ...
## ..$ fd : num [1:30696] 10.295 2.742 0.378 0 0.839 ...
## ..$ gc : num [1:30696] 172.9 58.4 9.1 0 21.4 ...
## ..$ gc.filt : num [1:30696] NA NA NA NA NA NA NA NA NA NA ...
## $ peak.mean :'data.frame': 1279 obs. of 4 variables:
## ..$ timestamp: chr [1:1279] "2012-05-01" "2012-05-02" "2012-05-03" "2012-05-04" ...
## ..$ vpd.filt : num [1:1279] NA NA 0.622 0.855 NA ...
## ..$ gc.filt : num [1:1279] NA NA 1034 859 NA ...
## ..$ gc.norm : num [1:1279] NA NA 1.51 1.25 NA ...
## $ sum.mod :List of 11
## ..$ formula :Class 'formula' language y ~ a + d * x^(-0.5)
## .. .. ..- attr(*, ".Environment")=<environment: 0x000000001e183a60>
## ..$ residuals : num [1:329] 715 599 288 611 392 ...
## ..$ sigma : num 177
## ..$ df : int [1:2] 2 327
## ..$ cov.unscaled: num [1:2, 1:2] 0.0961 -0.0874 -0.0874 0.082
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr [1:2] "a" "d"
## .. .. ..$ : chr [1:2] "a" "d"
## ..$ call : language stats::nls(formula = y ~ a + d * x^(-0.5), data = df, start = list(a = 1, d = 1), algorithm = "default", con| __truncated__ ...
## ..$ convInfo :List of 5
## .. ..$ isConv : logi TRUE
## .. ..$ finIter : int 1
## .. ..$ finTol : num 1.17e-08
## .. ..$ stopCode : int 0
## .. ..$ stopMessage: chr "converged"
## ..$ control :List of 5
## .. ..$ maxiter : num 50
## .. ..$ tol : num 1e-05
## .. ..$ minFactor: num 0.000977
## .. ..$ printEval: logi FALSE
## .. ..$ warnOnly : logi FALSE
## ..$ na.action : NULL
## ..$ coefficients: num [1:2, 1:4] -83.78 318 54.77 50.59 -1.53 ...
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr [1:2] "a" "d"
## .. .. ..$ : chr [1:4] "Estimate" "Std. Error" "t value" "Pr(>|t|)"
## ..$ parameters : num [1:2, 1:4] -83.78 318 54.77 50.59 -1.53 ...
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr [1:2] "a" "d"
## .. .. ..$ : chr [1:4] "Estimate" "Std. Error" "t value" "Pr(>|t|)"
## ..- attr(*, "class")= chr "summary.nls"
## $ sum.mod.norm:List of 11
## ..$ formula :Class 'formula' language y ~ a + d * x^(-0.5)
## .. .. ..- attr(*, ".Environment")=<environment: 0x000000001e183a60>
## ..$ residuals : num [1:329] 1.042 0.873 0.421 0.891 0.572 ...
## ..$ sigma : num 0.258
## ..$ df : int [1:2] 2 327
## ..$ cov.unscaled: num [1:2, 1:2] 0.0961 -0.0874 -0.0874 0.082
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr [1:2] "a" "d"
## .. .. ..$ : chr [1:2] "a" "d"
## ..$ call : language stats::nls(formula = y ~ a + d * x^(-0.5), data = df_n, start = list(a = 1, d = 1), algorithm = "default", c| __truncated__ ...
## ..$ convInfo :List of 5
## .. ..$ isConv : logi TRUE
## .. ..$ finIter : int 1
## .. ..$ finTol : num 1.22e-08
## .. ..$ stopCode : int 0
## .. ..$ stopMessage: chr "converged"
## ..$ control :List of 5
## .. ..$ maxiter : num 50
## .. ..$ tol : num 1e-05
## .. ..$ minFactor: num 0.000977
## .. ..$ printEval: logi FALSE
## .. ..$ warnOnly : logi FALSE
## ..$ na.action : NULL
## ..$ coefficients: num [1:2, 1:4] -0.1222 0.4638 0.0799 0.0738 -1.5298 ...
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr [1:2] "a" "d"
## .. .. ..$ : chr [1:4] "Estimate" "Std. Error" "t value" "Pr(>|t|)"
## ..$ parameters : num [1:2, 1:4] -0.1222 0.4638 0.0799 0.0738 -1.5298 ...
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr [1:2] "a" "d"
## .. .. ..$ : chr [1:4] "Estimate" "Std. Error" "t value" "Pr(>|t|)"
## ..- attr(*, "class")= chr "summary.nls"
8. Estimate uncertainties with a thorough global sensitivity/uncertainty analysis
# The implemented methods for the global sensitivity and uncertainty analysis are computational demanding. Here, for illustration purposes we have selected a sub-period of few months.
# see help page for a detailed description
#?tdm_uncertain
output <- tdm_uncertain(window(sensor_raw_1h,
start = "2014-03-01 00:00:00",
end = "2014-09-01 00:00:00"),
probe.length=20,
method="pd",
n=2000,
sw.cor=25,
sw.sd=16,
log.a_mu=output.data$out.param$log.a_mu,
log.a_sd=output.data$out.param$log.a_sd,
b_mu=output.data$out.param$b_mu,
b_sd=output.data$out.param$b_sd,
make.plot=TRUE)
9. Using TREX
For use in publication, the reference is:
citation("TREX")
##
## To cite package 'TREX' in publications use:
##
## Richard Peters, Christoforos Pappas and Alexander Hurley (2020).
## TREX: TRree sap flow EXtractor. R package version 0.0.0.9000.
## https://the-hull.github.io/TREX/
##
## A BibTeX entry for LaTeX users is
##
## @Manual{,
## title = {TREX: TRree sap flow EXtractor},
## author = {Richard Peters and Christoforos Pappas and Alexander Hurley},
## year = {2020},
## note = {R package version 0.0.0.9000},
## url = {https://the-hull.github.io/TREX/},
## }
10. References
- Richard Peters, Christoforos Pappas and Alexander Hurley (2020). TREX: TRree sap flow EXtractor. R package version 0.0.0.9000. https://the-hull.github.io/TREX/