Nothing
#eq 1
eq.Ms <- function(Ms, Gs, Ls){
Ms + Gs - Ls
}
#eq 2
eq.Mr <- function(Mr, Gr, Lr){
Mr + Gr - Lr
}
#eq 3
eq.Gs <- function(g, Cs, Ns, Ms){
g * Cs * Ns / Ms
}
#eq 4
eq.Gr <- function(g, Cr, Nr, Mr){
g * Cr * Nr / Mr
}
#eq 5
eq.Ls <- function(m, Ms, Km){
m * Ms / (1 + Km / Ms)
}
#eq 6
eq.Lr <- function(m, Mr, Km){
m * Mr / (1 + Km / Mr)
}
#eq 7
eq.Uc <- function(a, Ms, Ka, Cs, Jc){
a * Ms / ((1 + Ms/Ka)*(1 + Cs/(Ms * Jc)))
}
#eq 8
eq.Un <- function(b, Mr, Ka, Nr, Jn){
b * Mr / ((1 + Mr/Ka)*(1 + Nr/(Mr*Jn)))
}
#eq 9
eq.Tauc <- function(Ms, Mr, Cs, Cr){
(Ms * Mr / (Ms + Mr)) * (Cs / Ms - Cr / Mr)
}
#eq 10
eq.Taun <- function(Ms, Mr, Ns, Nr){
(Ms * Mr / (Ms + Mr)) * (Nr / Mr - Ns / Ms)
}
#eq 11
eq.Cs <- function(Cs, Uc, fc, Gs, Tauc){
Cs + Uc - fc * Gs - Tauc
}
#eq 12
eq.Cr <- function(Cr, Tauc, fc, Gr){
Cr + Tauc - fc * Gr
}
#eq 13
eq.Ns <- function(Ns, Taun, fn, Gs){
Ns + Taun - fn * Gs
}
#eq 14
eq.Nr <- function(Nr, Un, fn, Gr, Taun){
Nr + Un - fn * Gr - Taun
}
#step function
S <-function(X, b1, b2){
max(
min(
(X - b1) / (b2 - b1),
1
),
0
)
}
#trapezoid function
Z <- function(X, b1, b2, b3, b4){
max(
min(
(X - b1)/(b2 - b1),
1,
(b4 - X)/(b4 - b3)
),
0
)
}
#eq 15
a.std.eq <- function(amax, Z_T, S_Q, S_M, S_NsMs){
amax * min(Z_T, S_Q, S_M, S_NsMs)
}
#eq 16
a.fqr.eq <- function(afqr, S_M, S_NsMs){
afqr * min(S_M, S_NsMs)
}
#eq 17
a.red.eq <- function(afqr, S_M, S_NsMs){
afqr * S_M * S_NsMs
}
#eq 18
a.oak.eq <- a.red.eq
#eq 19
b.std.eq <- function(bmax, S_T, Z_M, S_Nsoil){
bmax * min(S_T, Z_M, S_Nsoil)
}
b.fqr.eq <- b.std.eq
#eq 20
b.red.eq <- function(bmax, S_T, Z_M, S_Nsoil){
bmax * S_T * Z_M * S_Nsoil
}
b.oak.eq <- b.red.eq
#eq 21
g.std.eq <- function(gmax, Z_T){
gmax * Z_T
}
g.fqr.eq <- g.std.eq
#eq 22
g.red.eq <- function(gmax, Z_T, S_M){
gmax * Z_T * S_M
}
g.oak.eq <- g.red.eq
#eq 23
#m.std.eq <- function(mmin, mmax, S_T){
# max(mmin, mmax * S_T)
#}
#m.fqr.eq <- m.std.eq
#m.red.eq <- m.std.eq
#changed in commit 73640cf: mortality with L_mix
m.std.eq <- function(p_1, p_2, mmax, S_T){
p_1 * mmax + p_2 * mmax * S_T
}
m.fqr.eq <- m.std.eq
m.red.eq <- m.std.eq
#eq 24
# m.oak.eq <- function(mmin, mmax, S_M, S_T){
# max(mmin, mmax * (1 - S_M), mmax * (1 - S_T))
# }
#changed in commit 73640cf: mortality with L_mix
m.oak.eq <- function(p_1, p_2, p_3, mmax, S_M, S_T){
p_1 * mmax + p_2 * mmax * S_T + p_3 * mmax * S_M
}
#addendum
positive <- function(v){
v[which(v < 0)] <- 0.0
v
}
a.eq <- function(version, state, parameters, constants, forcing_data){
amax <- constants["CUmax"]
Ns <- state["Ns"]
Ms <- state["Ms"]
switch(
version,
std = a.std.eq(
amax,
Z(forcing_data["tcur"],
parameters["CU_tcur_1"],
parameters["CU_tcur_2"],
parameters["CU_tcur_3"],
parameters["CU_tcur_4"]),
S(forcing_data["ppfd"],
parameters["CU_ppfd_1"],
parameters["CU_ppfd_2"]),
S(forcing_data["swc"],
parameters["CU_swc_1"],
parameters["CU_swc_2"]),
S(Ns / Ms,
parameters["CU_Ns_1"],
parameters["CU_Ns_2"])
),
fqr = a.fqr.eq(
amax / 30 * forcing_data["afqr"],
S(forcing_data["swc"],
parameters["CU_swc_1"],
parameters["CU_swc_2"]),
S(Ns/Ms,
parameters["CU_Ns_1"],
parameters["CU_Ns_2"])
),
red = a.red.eq(
amax / 30 * forcing_data["afqr"],
S(forcing_data["swc"],
parameters["CU_swc_1"],
parameters["CU_swc_2"]),
S(Ns/Ms,
parameters["CU_Ns_1"],
parameters["CU_Ns_2"])
),
oak = a.oak.eq(
amax / 30 * forcing_data["afqr"],
S(forcing_data["swc"],
parameters["CU_swc_1"],
parameters["CU_swc_2"]),
S(Ns/Ms,
parameters["CU_Ns_1"],
parameters["CU_Ns_2"])
)
)
}
b.eq <- function(version, state, parameters, constants, forcing_data){
bmax <- constants["NUmax"]
switch(
version,
std = b.std.eq(
bmax,
S(forcing_data["tnur"],
parameters["NU_tnur_1"],
parameters["NU_tnur_2"]),
Z(forcing_data["swc"],
parameters["NU_swc_1"],
parameters["NU_swc_2"],
parameters["NU_swc_3"],
parameters["NU_swc_4"]),
S(forcing_data["nsoil"],
parameters["NU_Nsoil_1"],
parameters["NU_Nsoil_2"])
),
fqr = b.fqr.eq(
bmax,
S(forcing_data["tnur"],
parameters["NU_tnur_1"],
parameters["NU_tnur_2"]),
Z(forcing_data["swc"],
parameters["NU_swc_1"],
parameters["NU_swc_2"],
parameters["NU_swc_3"],
parameters["NU_swc_4"]),
S(forcing_data["nsoil"],
parameters["NU_Nsoil_1"],
parameters["NU_Nsoil_2"])
),
red = b.red.eq(
bmax,
S(forcing_data["tnur"],
parameters["NU_tnur_1"],
parameters["NU_tnur_2"]),
Z(forcing_data["swc"],
parameters["NU_swc_1"],
parameters["NU_swc_2"],
parameters["NU_swc_3"],
parameters["NU_swc_4"]),
S(forcing_data["nsoil"],
parameters["NU_Nsoil_1"],
parameters["NU_Nsoil_2"])
),
oak = b.oak.eq(
bmax,
S(forcing_data["tnur"],
parameters["NU_tnur_1"],
parameters["NU_tnur_2"]),
Z(forcing_data["swc"],
parameters["NU_swc_1"],
parameters["NU_swc_2"],
parameters["NU_swc_3"],
parameters["NU_swc_4"]),
S(forcing_data["nsoil"],
parameters["NU_Nsoil_1"],
parameters["NU_Nsoil_2"])
)
)
}
g.eq <- function(version, state, parameters, constants, forcing_data){
gmax <- constants["gmax"]
switch(
version,
std = g.std.eq(
gmax,
Z(forcing_data["tgrowth"],
parameters["g_tgrowth_1"],
parameters["g_tgrowth_2"],
parameters["g_tgrowth_3"],
parameters["g_tgrowth_4"])
),
fqr = g.fqr.eq(
gmax,
Z(forcing_data["tgrowth"],
parameters["g_tgrowth_1"],
parameters["g_tgrowth_2"],
parameters["g_tgrowth_3"],
parameters["g_tgrowth_4"])
),
red = g.red.eq(
gmax,
Z(forcing_data["tgrowth"],
parameters["g_tgrowth_1"],
parameters["g_tgrowth_2"],
parameters["g_tgrowth_3"],
parameters["g_tgrowth_4"]),
S(forcing_data["swc"],
parameters["g_swc_1"],
parameters["g_swc_2"])
),
oak = g.oak.eq(
gmax,
Z(forcing_data["tgrowth"],
parameters["g_tgrowth_1"],
parameters["g_tgrowth_2"],
parameters["g_tgrowth_3"],
parameters["g_tgrowth_4"]),
S(forcing_data["swc"],
parameters["g_swc_1"],
parameters["g_swc_2"])
)
)
}
m.eq <- function(version, state, parameters, constants, forcing_data){
mmax <- constants["mmax"]
if(version == "oak") {
#m3 <- max(0.0, 100.0 - (parameters["L_mix_1"]+parameters["L_mix_2"]))
sum_m <- parameters["L_mix_1"] + parameters["L_mix_2"] + parameters["L_mix_3"]
}
switch(
version,
std = m.std.eq(
parameters["L_mix_1"]/100.0,
1.0 - parameters["L_mix_1"]/100.0,
mmax,
S(forcing_data["tloss"],
parameters["r_tloss_1"],
parameters["r_tloss_2"])
),
fqr = m.fqr.eq(
parameters["L_mix_1"]/100.0,
1.0 - parameters["L_mix_1"]/100.0,
mmax,
S(forcing_data["tloss"],
parameters["r_tloss_1"],
parameters["r_tloss_2"])
),
red = m.red.eq(
parameters["L_mix_1"]/100.0,
1.0 - parameters["L_mix_1"]/100.0,
mmax,
S(forcing_data["tloss"],
parameters["r_tloss_1"],
parameters["r_tloss_2"])
),
oak = m.oak.eq(
parameters["L_mix_1"] / sum_m,
parameters["L_mix_2"] / sum_m,
parameters["L_mix_3"] / sum_m,
mmax,
1.0 - S(forcing_data["swc"],
parameters["L_swc_1"],
parameters["L_swc_2"]),
1.0 - S(forcing_data["tloss"],
parameters["L_tloss_1"],
parameters["L_tloss_2"])
)
)
}
induce <- function(version, state, parameters, constants, forcing_data){
Ms <- state["Ms"]
Mr <- state["Mr"]
Cs <- state["Cs"]
Cr <- state["Cr"]
Ns <- state["Ns"]
Nr <- state["Nr"]
Km <- constants["KM"]
Ka <- constants["KA"]
Jc <- constants["Jc"]
Jn <- constants["Jn"]
fc <- constants["Fc"]
fn <- constants["Fn"]
#Divergence from technical specification
a <- a.eq(version, state, parameters, constants, forcing_data)
b <- b.eq(version, state, parameters, constants, forcing_data)
Uc <- eq.Uc(a, Ms, Ka, Cs, Jc)
Un <- eq.Un(b, Mr, Ka, Nr, Jn)
g <- g.eq(version, state, parameters, constants, forcing_data)
Gs <- eq.Gs(g, Cs, Ns, Ms)
Gr <- eq.Gr(g, Cr, Nr, Mr)
Tauc <- eq.Tauc(Ms, Mr, Cs, Cr)
Taun <- eq.Taun(Ms, Mr, Ns, Nr)
Cs <- eq.Cs(Cs = Cs, Uc = Uc, fc = fc, Gs = Gs, Tauc = Tauc)
Cr <- eq.Cr(Cr, Tauc, fc, Gr)
Ns <- eq.Ns(Ns, Taun, fn, Gs)
Nr <- eq.Nr(Nr, Un, fn, Gr, Taun)
m <- m.eq(version, state, parameters, constants, forcing_data)
Ls <- eq.Ls(m, Ms, Km)
Lr <- eq.Lr(m, Mr, Km)
Ms <- eq.Ms(Ms, Gs, Ls)
Mr <- eq.Mr(Mr, Gr, Lr)
list(
next.state = positive(c(
Ms = Ms,
Mr = Mr,
Cs = Cs,
Cr = Cr,
Ns = Ns,
Nr = Nr
)),
out = c(
Ms = state["Ms"],
Mr = state["Mr"],
Cs = state["Cs"],
Cr = state["Cr"],
Ns = state["Ns"],
Nr = state["Nr"],
TAUc = Tauc,
TAUn = Taun,
Uc = Uc,
Un = Un,
Gs = Gs,
Gr = Gr,
Ms_loss = Ls,
Mr_loss = Lr,
CUR = a,
NUR = b,
g = g,
loss = m
)
)
}
state_variables <- c("Ms", "Mr", "Cs", "Cr", "Ns", "Nr")
produce.expectation <- function(parameters, Data){
output <- rep(0, prod(Data$out.dim))
dim(output) <- Data$out.dim
dimnames(output) <- Data$out.dimnames
nspecies <- dim(output)["species"]
for(site in 1:dim(output)["sites"]){
initial_mass <- matrix(
data = ifelse(
Data$options$initial_mass_par,
parameters$beta["iM",],
rep(Data$options$initial_mass, nspecies)
),
nrow = 6,
ncol = nspecies
)
state <- initial_mass * matrix(
data = c(1,1,.05,.05,.01,.01),
nrow = length(state_variables),
ncol = nspecies)
dimnames(state) <- list(state_variables,Data$options$species)
for(step in 1:dim(output)["steps"]){
for(species in 1:nspecies){
ts <- Data$timeseries[,step,site]
ti <- Data$time.invariant[,site]
afqr <- unname(
switch(
as.character(Data$options$photo[species]),
c3 = ts["C3p"],
c4 = ts["C4p"]
)
)
forcing_data <- c(ts, ti, afqr = afqr)
constants <- Data$globals
out <- induce(
as.character(Data$options$ve),
state[,species],
c(parameters$alpha, parameters$beta[,species]),
constants,
forcing_data)
output[,species,step,site] <- out$out
state[,species] <- out$next.state
}
}
}
output[,,Data$options$steps,]
}
test_that("Compiled version has no significant errors", {
#create simulated data
nspecies <- 3
nsites <- 6
ntime <- 99
observations <- 1:(nspecies*nsites*ntime)
obsdim <- c(ntime,nspecies,nsites)
names(obsdim) <- c("time","species","site")
dim(observations) <- obsdim
wp <- rnorm(nsites, 1, 0.1)
fc <- rnorm(nsites, 10,0.5)
gauss_noise <- function(sd){
rnorm(ntime, 0, sd)
}
maxtemp<- rnorm(nsites, 15, 5)
mintemp<- rnorm(nsites, 8, 5)
moist <- pmin(100, pmax(rnorm(nsites, 50,40), 0))
per <- function(min, max, freq, sd){
min + (max-min)/2 * (sin((1:ntime)*2*pi/(ntime/freq))+1) + gauss_noise(sd)
}
swc <- sapply(moist, function(p){pmin(100,pmax(per(p/10,p,2,10),0))})
rsds <- sapply(1:nsites, function(a){pmax(per(0,100,3,10),0)})
minmax <- rbind(mintemp,maxtemp)
cols <- split(minmax, col(minmax))
tcur <- sapply(
cols,
function(col){per(col[[1]],col[[2]],5,5)+5}
)
tnur <- sapply(
cols,
function(col){per(col[[1]],col[[2]],5,5)}
)
tgrowth <- sapply(
cols,
function(col){per(col[[1]],col[[2]],5,5)+2}
)
tloss <- sapply(
cols,
function(col){per(col[[1]],col[[2]],5,5)-3}
)
inp <- get_input(
observations = observations,
seconds = 1,
p3 = TTR.PGM::p3,
p4 = TTR.PGM::p4,
lon = c(1:nsites),
lat = c(1:nsites),
swc=swc,
catm=matrix(200,nrow=ntime, ncol=nsites),
rsds=rsds,
tcur=tcur,
tnur=tnur,
tgrowth = tgrowth,
tloss = tloss
)
for(ver in c("std", "fqr", "red", "oak")){
opt <- standard_options
opt$steps <- 1:(ntime-1)
opt$species <- c("1", "2","3")
opt$photo <- c("c3","c4","c3")
opt$ve <- ver
optmin <- opt
optmin$steps <- nsites
Data <- make_data(inp, options = opt,globals = standard_globals)
some.parms <- rnorm(n=Data$n.parm, mean=(Data$bounds[,"lower"] + Data$bounds[,"upper"]) / 2, sd=1.2)
par <- get_parms(some.parms, Data)
x <- run_ttr(par, Data)
xexp <- produce.expectation(par, Data)
expect(all(abs(x["Ms",,,]-xexp["Ms",,,])/mean(x["Ms",,,]) < 1e-10) , paste0(ver, ": Ms error is OK"))
expect(all(abs(x["Mr",,,]-xexp["Mr",,,])/mean(x["Mr",,,]) < 1e-10) , paste0(ver, ": Mr error is OK"))
}
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.