Skip to content

Commit 716e281

Browse files
authored
Merge pull request #3719 from ayushman1210/fix
Replace manual unit conversions with ud_convert() for consistency across models
1 parent 9859b29 commit 716e281

11 files changed

Lines changed: 149 additions & 63 deletions

File tree

base/utils/tests/testthat/test-ud_convert.R

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,21 @@ test_that("ud_convert() warns with wrong input units for difftime", {
3636
expect_warning(ud_convert(as.difftime("12:00:00"), u1 = "years", u2 = "minutes"))
3737
#should still error if units are not convertible
3838
expect_error(ud_convert(as.difftime("12:00:00"), u1 = "kilograms", u2 = "minutes"))
39+
})
40+
41+
test_that("model-specific pool conversions", {
42+
# DALEC/SIPNET C pools
43+
expect_equal(ud_convert(100, "g/m2", "kg/m2"), 0.1)
44+
# GDAY pools
45+
expect_equal(ud_convert(10, "Mg/ha", "kg/m2"), 1)
46+
})
47+
48+
test_that("model-specific flux conversions", {
49+
# DALEC/SIPNET C fluxes
50+
expect_equal(ud_convert(86400, "g/m2/d", "kg/m2/s"), 0.001, tolerance = 1e-10)
51+
})
52+
53+
test_that("photosynthesis parameters", {
54+
# Photosynthesis energy parameters
55+
expect_equal(ud_convert(1000, "J/mol", "kJ/mol"), 1)
3956
})

docker/depends/pecan_package_dependencies.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,7 @@
698698
"withr","*","base/workflow","Suggests",FALSE
699699
"withr","*","models/basgra","Suggests",FALSE
700700
"withr","*","models/ed","Suggests",FALSE
701+
"withr","*","models/gday","Suggests",FALSE
701702
"withr","*","models/rothc","Suggests",FALSE
702703
"withr","*","models/sibcasa","Suggests",FALSE
703704
"withr","*","models/sipnet","Suggests",FALSE

models/dalec/R/model2netcdf.DALEC.R

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,22 @@ model2netcdf.DALEC <- function(outdir, sitelat, sitelon, start_date, end_date) {
8383

8484
## Setup outputs for netCDF file in appropriate units
8585
output <- list()
86-
## Fluxes
87-
output[[1]] <- (sub.DALEC.output[, 1] * 0.001)/timestep.s # Autotrophic Respiration in kgC/m2/s
88-
output[[2]] <- (sub.DALEC.output[, 21] + sub.DALEC.output[, 23]) * 0.001 / timestep.s # Heterotrophic Resp kgC/m2/s
89-
output[[3]] <- (sub.DALEC.output[, 31] * 0.001)/timestep.s # GPP in kgC/m2/s
90-
output[[4]] <- (sub.DALEC.output[, 33] * 0.001)/timestep.s # NEE in kgC/m2/s
91-
output[[5]] <- (sub.DALEC.output[, 3] + sub.DALEC.output[, 5] + sub.DALEC.output[, 7]) * 0.001/timestep.s # NPP kgC/m2/s
92-
output[[6]] <- (sub.DALEC.output[, 9] * 0.001) / timestep.s # Leaf Litter Flux, kgC/m2/s
93-
output[[7]] <- (sub.DALEC.output[, 11] * 0.001) / timestep.s # Woody Litter Flux, kgC/m2/s
94-
output[[8]] <- (sub.DALEC.output[, 13] * 0.001) / timestep.s # Root Litter Flux, kgC/m2/s
86+
## Fluxes (convert g/m2/day to kg/m2/s)
87+
output[[1]] <- PEcAn.utils::ud_convert(sub.DALEC.output[, 1], "g/m2/d", "kg/m2/s") # Autotrophic Respiration
88+
output[[2]] <- PEcAn.utils::ud_convert(sub.DALEC.output[, 21] + sub.DALEC.output[, 23], "g/m2/d", "kg/m2/s") # Heterotrophic Resp
89+
output[[3]] <- PEcAn.utils::ud_convert(sub.DALEC.output[, 31], "g/m2/d", "kg/m2/s") # GPP
90+
output[[4]] <- PEcAn.utils::ud_convert(sub.DALEC.output[, 33], "g/m2/d", "kg/m2/s") # NEE
91+
output[[5]] <- PEcAn.utils::ud_convert(sub.DALEC.output[, 3] + sub.DALEC.output[, 5] + sub.DALEC.output[, 7], "g/m2/d", "kg/m2/s") # NPP
92+
output[[6]] <- PEcAn.utils::ud_convert(sub.DALEC.output[, 9], "g/m2/d", "kg/m2/s") # Leaf Litter Flux
93+
output[[7]] <- PEcAn.utils::ud_convert(sub.DALEC.output[, 11], "g/m2/d", "kg/m2/s") # Woody Litter Flux
94+
output[[8]] <- PEcAn.utils::ud_convert(sub.DALEC.output[, 13], "g/m2/d", "kg/m2/s") # Root Litter Flux
9595

96-
## Pools
97-
output[[9]] <- (sub.DALEC.output[, 15] * 0.001) # Leaf Carbon, kgC/m2
98-
output[[10]] <- (sub.DALEC.output[, 17] * 0.001) # Wood Carbon, kgC/m2
99-
output[[11]] <- (sub.DALEC.output[, 19] * 0.001) # Root Carbon, kgC/m2
100-
output[[12]] <- (sub.DALEC.output[, 27] * 0.001) # Litter Carbon, kgC/m2
101-
output[[13]] <- (sub.DALEC.output[, 29] * 0.001) # Soil Carbon, kgC/m2
96+
## Pools (convert g/m2 to kg/m2)
97+
output[[9]] <- PEcAn.utils::ud_convert(sub.DALEC.output[, 15], "g/m2", "kg/m2") # Leaf Carbon
98+
output[[10]] <- PEcAn.utils::ud_convert(sub.DALEC.output[, 17], "g/m2", "kg/m2") # Wood Carbon
99+
output[[11]] <- PEcAn.utils::ud_convert(sub.DALEC.output[, 19], "g/m2", "kg/m2") # Root Carbon
100+
output[[12]] <- PEcAn.utils::ud_convert(sub.DALEC.output[, 27], "g/m2", "kg/m2") # Litter Carbon
101+
output[[13]] <- PEcAn.utils::ud_convert(sub.DALEC.output[, 29], "g/m2", "kg/m2") # Soil Carbon
102102

103103
## standard composites
104104
output[[14]] <- output[[1]] + output[[2]] # Total Respiration

models/fates/R/write.configs.FATES.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -307,25 +307,25 @@ write.config.FATES <- function(defaults, trait.values, settings, run.id){
307307
# Ha activation energy for vcmax - FATES units: J/mol
308308
if(var == "Ha_Modified_Arrhenius_Vcmax"){
309309
ncdf4::ncvar_put(nc=fates.param.nc, varid='fates_vcmaxha', start = ipft, count = 1,
310-
vals=pft[v]*1000) ## convert from kj/mol to J/mol (FATES units)
310+
vals=PEcAn.utils::ud_convert(pft[v], "kJ/mol", "J/mol"))
311311
}
312312

313313
# Hd deactivation energy for vcmax - FATES units: J/mol
314314
if(var == "Hd_Modified_Arrhenius_Vcmax"){
315315
ncdf4::ncvar_put(nc=fates.param.nc, varid='fates_vcmaxhd', start = ipft, count = 1,
316-
vals=pft[v]*1000) ## convert from kj/mol to J/mol (FATES units)
316+
vals = PEcAn.utils::ud_convert(pft[v], "kJ/mol", "J/mol"))
317317
}
318318

319319
# Ha activation energy for Jmax - FATES units: J/mol
320320
if(var == "Ha_Modified_Arrhenius_Jmax"){
321321
ncdf4::ncvar_put(nc=fates.param.nc, varid='fates_jmaxha', start = ipft, count = 1,
322-
vals=pft[v]*1000) ## convert from kj/mol to J/mol (FATES units)
322+
vals = PEcAn.utils::ud_convert(pft[v], "kJ/mol", "J/mol"))
323323
}
324324

325325
# Hd deactivation energy for Jmax - FATES units: J/mol
326326
if(var == "Hd_Modified_Arrhenius_Jmax"){
327327
ncdf4::ncvar_put(nc=fates.param.nc, varid='fates_jmaxhd', start = ipft, count = 1,
328-
vals=pft[v]*1000) ## convert from kj/mol to J/mol (FATES units)
328+
vals = PEcAn.utils::ud_convert(pft[v], "kJ/mol", "J/mol"))
329329
}
330330

331331
# deltaS Vcmax - BETY units:J/mol/K; FATES units: J/mol/K

models/gday/DESCRIPTION

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ Imports:
2020
lubridate (>= 1.6.0),
2121
ncdf4 (>= 1.15)
2222
Suggests:
23-
testthat (>= 1.0.2)
23+
testthat (>= 1.0.2),
24+
withr
2425
SystemRequirements: GDAY
2526
OS_type: unix
2627
License: BSD_3_clause + file LICENSE

models/gday/R/model2netcdf.GDAY.R

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@
1515
model2netcdf.GDAY <- function(outdir, sitelat, sitelon, start_date, end_date) {
1616

1717

18-
G_2_KG <- 0.001
19-
TONNES_PER_HA_TO_G_M2 <- 100
20-
THA_2_KG_M2 <- TONNES_PER_HA_TO_G_M2 * 0.001
2118

2219
### Read in model output in GDAY format
2320
GDAY.output <- utils::read.csv(file.path(outdir, "gday_out.csv"), header = TRUE, sep = ",", skip = 1)
@@ -44,17 +41,20 @@ model2netcdf.GDAY <- function(outdir, sitelat, sitelon, start_date, end_date) {
4441
output <- list()
4542

4643
## standard variables: C-Fluxes
47-
output[[1]] <- (sub.GDAY.output[, "auto_resp"] * THA_2_KG_M2) / timestep.s
48-
output[[2]] <- (sub.GDAY.output[, "hetero_resp"] * THA_2_KG_M2) / timestep.s
49-
output[[3]] <- (sub.GDAY.output[, "auto_resp"] + sub.GDAY.output[, "hetero_resp"] *
50-
THA_2_KG_M2) / timestep.s
51-
output[[4]] <- (sub.GDAY.output[, "gpp"] * THA_2_KG_M2) / timestep.s
52-
output[[5]] <- (sub.GDAY.output[, "nep"] * -1 * THA_2_KG_M2) / timestep.s
53-
output[[6]] <- (sub.GDAY.output[, "npp"] * THA_2_KG_M2) / timestep.s
44+
## NOTE: GDAY outputs daily accumulated values in Mg/ha/day
45+
## Transform all to kg/m2/sec for PEcAn output
46+
output[[1]] <- PEcAn.utils::ud_convert(sub.GDAY.output[, "auto_resp"], "Mg/ha/day", "kg/m2/s")
47+
output[[2]] <- PEcAn.utils::ud_convert(sub.GDAY.output[, "hetero_resp"], "Mg/ha/day", "kg/m2/s")
48+
output[[3]] <- PEcAn.utils::ud_convert(sub.GDAY.output[, "auto_resp"] + sub.GDAY.output[, "hetero_resp"], "Mg/ha/day", "kg/m2/s")
49+
output[[4]] <- PEcAn.utils::ud_convert(sub.GDAY.output[, "gpp"], "Mg/ha/day", "kg/m2/s")
50+
output[[5]] <- PEcAn.utils::ud_convert(sub.GDAY.output[, "nep"] * -1, "Mg/ha/day", "kg/m2/s")
51+
output[[6]] <- PEcAn.utils::ud_convert(sub.GDAY.output[, "npp"], "Mg/ha/day", "kg/m2/s")
5452

55-
## standard variables: C-State
56-
output[[7]] <- (sub.GDAY.output[, "stem"] + sub.GDAY.output[, "branch"] * THA_2_KG_M2) / timestep.s
57-
output[[8]] <- (sub.GDAY.output[, "soilc"] * THA_2_KG_M2) / timestep.s
53+
## standard variables: C-State (pools)
54+
# NOTE: GDAY outputs stocks in Mg/ha.
55+
# Transform to kg/m2 for PEcAn output
56+
output[[7]] <- PEcAn.utils::ud_convert(sub.GDAY.output[, "stem"] + sub.GDAY.output[, "branch"], "Mg/ha", "kg/m2")
57+
output[[8]] <- PEcAn.utils::ud_convert(sub.GDAY.output[, "soilc"], "Mg/ha", "kg/m2")
5858
output[[9]] <- (sub.GDAY.output[, "lai"])
5959

6060
## standard variables: water fluxes
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# GDAY output
2+
year,day,auto_resp,hetero_resp,gpp,nep,npp,stem,branch,soilc,lai,et,transpiration
3+
2004,1,0.01,0.02,0.05,-0.03,0.03,100,50,200,2,0.5,0.3
4+
2004,2,0.01,0.02,0.05,-0.03,0.03,100,50,200,2,0.5,0.3
5+
2004,3,0.01,0.02,0.05,-0.03,0.03,100,50,200,2,0.5,0.3
6+
2004,4,0.01,0.02,0.05,-0.03,0.03,100,50,200,2,0.5,0.3
7+
2004,5,0.01,0.02,0.05,-0.03,0.03,100,50,200,2,0.5,0.3
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
##' Test for GDAY model2netcdf unit conversions
2+
##'
3+
##' This test verifies that the unit conversions in model2netcdf.GDAY are correct.
4+
##'
5+
##' Reference: https://github.com/PecanProject/pecan/pull/3719
6+
##' GDAY outputs daily values in Mg/ha/day, which should be converted to kg/m2/s
7+
##'
8+
##' Conversion factors:
9+
##' 1 Mg/ha = 0.1 kg/m2 (area conversion)
10+
##' 1 day = 86400 seconds
11+
##' Therefore: 1 Mg/ha/day = 0.1 / 86400 kg/m2/s = 1.157e-6 kg/m2/s
12+
13+
context("GDAY model2netcdf unit conversions")
14+
15+
test_that("model2netcdf.GDAY runs without error and produces netCDF", {
16+
outdir <- withr::local_tempdir()
17+
file.copy("data/gday_out.csv", outdir)
18+
19+
# Run the function
20+
expect_silent(
21+
model2netcdf.GDAY(
22+
outdir = outdir,
23+
sitelat = 40,
24+
sitelon = -88,
25+
start_date = "2004-01-01",
26+
end_date = "2004-12-31"
27+
)
28+
)
29+
30+
# Check that netCDF file is created
31+
nc_file <- file.path(outdir, "2004.nc")
32+
expect_true(file.exists(nc_file))
33+
34+
# Check that we can read the output
35+
output <- PEcAn.utils::read.output(
36+
ncfiles = nc_file,
37+
variables = c("GPP", "AbvGrndWood"),
38+
dataframe = TRUE,
39+
verbose = FALSE,
40+
print_summary = FALSE
41+
)
42+
# GPP should be in kg/m2/s (converted from Mg/ha/day)
43+
secs_day <- 86400
44+
kg_Mg <- 1000
45+
m2_ha <- 10000
46+
gday2pecan <- kg_Mg/m2_ha/secs_day
47+
expect_equal(nrow(output), 5)
48+
expect_equal(output$GPP, rep(0.5, 5) * gday2pecan, tolerance = 1e-6)
49+
50+
# AbvGrndWood is a stock (Mg/ha), not a flux (Mg/ha/day).
51+
# Conversion: 1 Mg/ha = 0.1 kg/m2
52+
stock_conv <- 0.1
53+
expect_equal(output$AbvGrndWood, rep(150, 5) * stock_conv, tolerance = 1e-6)
54+
})

models/sipnet/R/model2netcdf.SIPNET.R

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -134,21 +134,19 @@ model2netcdf.SIPNET <- function(outdir, sitelat, sitelon, start_date, end_date,
134134
bounds <- round(bounds,4)
135135

136136
## Setup outputs for netCDF file in appropriate units
137-
output <- list(
138-
"GPP" = (sub.sipnet.output$gpp * 0.001) / timestep.s, # GPP in kgC/m2/s
139-
"NPP" = (sub.sipnet.output$gpp * 0.001) / timestep.s - ((sub.sipnet.output$rAboveground *
140-
0.001) / timestep.s + (sub.sipnet.output$rRoot * 0.001) / timestep.s), # NPP in kgC/m2/s. Post SIPNET calculation
141-
"TotalResp" = (sub.sipnet.output$rtot * 0.001) / timestep.s, # Total Respiration in kgC/m2/s
142-
"AutoResp" = (sub.sipnet.output$rAboveground * 0.001) / timestep.s + (sub.sipnet.output$rRoot *
143-
0.001) / timestep.s, # Autotrophic Respiration in kgC/m2/s
144-
"HeteroResp" = ((sub.sipnet.output$rSoil - sub.sipnet.output$rRoot) * 0.001) / timestep.s, # Heterotrophic Respiration in kgC/m2/s
145-
"SoilResp" = (sub.sipnet.output$rSoil * 0.001) / timestep.s, # Soil Respiration in kgC/m2/s
146-
"NEE" = (sub.sipnet.output$nee * 0.001) / timestep.s, # NEE in kgC/m2/s
147-
"AbvGrndWood" = (sub.sipnet.output$plantWoodC * 0.001), # Above ground wood kgC/m2
148-
"leaf_carbon_content" = (sub.sipnet.output$plantLeafC * 0.001), # Leaf C kgC/m2
149-
"TotLivBiom" = (sub.sipnet.output$plantWoodC * 0.001) + (sub.sipnet.output$plantLeafC * 0.001) +
150-
(sub.sipnet.output$coarseRootC + sub.sipnet.output$fineRootC) * 0.001, # Total living C kgC/m2
151-
"TotSoilCarb" = (sub.sipnet.output$soil * 0.001) + (sub.sipnet.output$litter * 0.001) # Total soil C kgC/m2
137+
output <- list(
138+
"GPP" = PEcAn.utils::ud_convert(sub.sipnet.output$gpp, "g/m2", "kg/m2") / timestep.s,
139+
"NPP" = PEcAn.utils::ud_convert(sub.sipnet.output$gpp - (sub.sipnet.output$rAboveground + sub.sipnet.output$rRoot), "g/m2", "kg/m2") / timestep.s,
140+
"TotalResp" = PEcAn.utils::ud_convert(sub.sipnet.output$rtot, "g/m2", "kg/m2") / timestep.s,
141+
"AutoResp" = (PEcAn.utils::ud_convert(sub.sipnet.output$rAboveground + sub.sipnet.output$rRoot, "g/m2", "kg/m2")) / timestep.s,
142+
"HeteroResp" = PEcAn.utils::ud_convert(sub.sipnet.output$rSoil - sub.sipnet.output$rRoot, "g/m2", "kg/m2") / timestep.s,
143+
"SoilResp" = PEcAn.utils::ud_convert(sub.sipnet.output$rSoil, "g/m2", "kg/m2") / timestep.s,
144+
"NEE" = PEcAn.utils::ud_convert(sub.sipnet.output$nee, "g/m2", "kg/m2") / timestep.s,
145+
"AbvGrndWood" = PEcAn.utils::ud_convert(sub.sipnet.output$plantWoodC, "g/m2", "kg/m2"),
146+
"leaf_carbon_content" = PEcAn.utils::ud_convert(sub.sipnet.output$plantLeafC, "g/m2", "kg/m2"),
147+
"TotLivBiom" = (PEcAn.utils::ud_convert(sub.sipnet.output$plantWoodC + sub.sipnet.output$plantLeafC +
148+
sub.sipnet.output$coarseRootC + sub.sipnet.output$fineRootC, "g/m2", "kg/m2")),
149+
"TotSoilCarb" = PEcAn.utils::ud_convert(sub.sipnet.output$soil + sub.sipnet.output$litter, "g/m2", "kg/m2")
152150
)
153151
if (revision == "unk") {
154152
## *** NOTE : npp in the sipnet output file is actually evapotranspiration, this is due to a bug in sipnet.c : ***
@@ -164,8 +162,12 @@ model2netcdf.SIPNET <- function(outdir, sitelat, sitelon, start_date, end_date,
164162
output[["SoilMoist"]] <- (sub.sipnet.output$soilWater * 10) # Soil moisture kgW/m2
165163
output[["SoilMoistFrac"]] <- (sub.sipnet.output$soilWetnessFrac) # Fractional soil wetness
166164
output[["SWE"]] <- (sub.sipnet.output$snow * 10) # SWE
167-
output[["litter_carbon_content"]] <- sub.sipnet.output$litter * 0.001 ## litter kgC/m2
168-
output[["litter_mass_content_of_water"]] <- (sub.sipnet.output$litterWater * 10) # Litter water kgW/m2
165+
output[["litter_carbon_content"]] <- PEcAn.utils::ud_convert(sub.sipnet.output$litter, "g/m2", "kg/m2")
166+
# litterWater was removed in SIPNET v2; only extract if present
167+
if ("litterWater" %in% names(sub.sipnet.output)) {
168+
# Units are labeled elsewhere as kg water m-2 (which is equivalent to mm, but ud_convert doesn't know that)
169+
output[["litter_mass_content_of_water"]] <- PEcAn.utils::ud_convert(sub.sipnet.output$litterWater, "cm", "mm")
170+
}
169171
#calculate LAI for standard output
170172
# LAI = plantLeafC / leafCSpWt
171173
# both operands are in carbon units (gC/m2 and gC/m2_leaf),
@@ -176,17 +178,19 @@ model2netcdf.SIPNET <- function(outdir, sitelat, sitelon, start_date, end_date,
176178
leafCSpWt <- param[param[, 1] == "leafCSpWt", 2]
177179
SLA <- 1000 / leafCSpWt # m2 leaf / kg C
178180
output[["LAI"]] <- output[["leaf_carbon_content"]] * SLA
179-
output[["fine_root_carbon_content"]] <- sub.sipnet.output$fineRootC * 0.001 ## fine_root_carbon_content kgC/m2
180-
output[["coarse_root_carbon_content"]] <- sub.sipnet.output$coarseRootC * 0.001 ## coarse_root_carbon_content kgC/m2
181-
output[["GWBI"]] <- (sub.sipnet.output$woodCreation * 0.001) / 86400 ## kgC/m2/s - this is daily in SIPNET
182-
output[["AGB"]] <- (sub.sipnet.output$plantWoodC + sub.sipnet.output$plantLeafC) * 0.001 # Total aboveground biomass kgC/m2
181+
output[["fine_root_carbon_content"]] <- PEcAn.utils::ud_convert(sub.sipnet.output$fineRootC, "g/m2", "kg/m2")
182+
output[["coarse_root_carbon_content"]] <- PEcAn.utils::ud_convert(sub.sipnet.output$coarseRootC, "g/m2", "kg/m2")
183+
if ("woodCreation" %in% names(sub.sipnet.output)) {
184+
output[["GWBI"]] <- PEcAn.utils::ud_convert(sub.sipnet.output$woodCreation, "g/m2/day", "kg/m2/s")
185+
}
186+
output[["AGB"]] <- PEcAn.utils::ud_convert(sub.sipnet.output$plantWoodC + sub.sipnet.output$plantLeafC, "g/m2", "kg/m2")
183187
# columns only present in sipnet >= v2 with N and methane turned on
184188
if ("n2o" %in% names(sub.sipnet.output)) {
185-
output[["N2O_flux"]] <- (sub.sipnet.output$n2o * 0.001) / timestep.s
189+
output[["N2O_flux"]] <- PEcAn.utils::ud_convert(sub.sipnet.output$n2o, "g/m2", "kg/m2") / timestep.s
186190
# convert g N m-2 per timestep -> kg N m-2 s-1
187191
}
188192
if ("ch4" %in% names(sub.sipnet.output)) {
189-
output[["CH4_flux"]] <- (sub.sipnet.output$ch4 * 0.001) / timestep.s
193+
output[["CH4_flux"]] <- PEcAn.utils::ud_convert(sub.sipnet.output$ch4, "g/m2", "kg/m2") / timestep.s
190194
# convert g C m-2 per timestep -> kg C m-2 s-1
191195
}
192196
output[["time_bounds"]] <- c(rbind(bounds[,1], bounds[,2]))
@@ -235,19 +239,22 @@ model2netcdf.SIPNET <- function(outdir, sitelat, sitelon, start_date, end_date,
235239
"SoilMoistFrac" = PEcAn.utils::to_ncvar("SoilMoistFrac", dims),
236240
"SWE" = PEcAn.utils::to_ncvar("SWE", dims),
237241
"litter_carbon_content" = PEcAn.utils::to_ncvar("litter_carbon_content", dims),
238-
"litter_mass_content_of_water" = PEcAn.utils::to_ncvar("litter_mass_content_of_water", dims),
239242
"LAI" = PEcAn.utils::to_ncvar("LAI", dims),
240243
"fine_root_carbon_content" = PEcAn.utils::to_ncvar("fine_root_carbon_content", dims),
241244
"coarse_root_carbon_content" = PEcAn.utils::to_ncvar("coarse_root_carbon_content", dims),
242-
"GWBI" = ncdf4::ncvar_def("GWBI", units = "kg C m-2", dim = list(lon, lat, t), missval = -999,
243-
longname = "Gross Woody Biomass Increment"),
244245
"AGB" = ncdf4::ncvar_def("AGB", units = "kg C m-2", dim = list(lon, lat, t), missval = -999,
245246
longname = "Total aboveground biomass"),
246247
"time_bounds" = ncdf4::ncvar_def(name="time_bounds", units='',
247248
longname = "history time interval endpoints", dim=list(time_interval,time = t),
248249
prec = "double")
249250
)
250-
251+
if ("litter_mass_content_of_water" %in% names(output)) {
252+
nc_var[["litter_mass_content_of_water"]] <- PEcAn.utils::to_ncvar("litter_mass_content_of_water", dims)
253+
}
254+
if ("litter_mass_content_of_water" %in% names(output)) {
255+
nc_var[["GWBI"]] <- ncdf4::ncvar_def("GWBI", units = "kg C m-2", dim = list(lon, lat, t), missval = -999,
256+
longname = "Gross Woody Biomass Increment")
257+
}
251258
if ("N2O_flux" %in% names(output)) {
252259
nc_var[["N2O_flux"]] <- PEcAn.utils::to_ncvar("N2O_flux", dims)
253260
}

models/sipnet/R/write_restart.SIPNET.R

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,11 @@ write_restart.SIPNET <- function(outdir, runid, start.time, stop.time, settings,
4747

4848
## Converting to sipnet units
4949
prior.sla <- new.params[[which(!names(new.params) %in% c("soil", "soil_SDA", "restart"))[1]]]$SLA
50-
unit.conv <- 2 * (10000 / 1) * (1 / 1000) * (3.154 * 10^7) # kgC/m2/s -> Mg/ha/yr
5150

5251
analysis.save <- list()
5352

5453
if ("NPP" %in% variables) {
55-
analysis.save[[length(analysis.save) + 1]] <- PEcAn.utils::ud_convert(new.state$NPP, "kg/m^2/s", "Mg/ha/yr") #*unit.conv -> Mg/ha/yr
54+
analysis.save[[length(analysis.save) + 1]] <- PEcAn.utils::ud_convert(new.state$NPP, "kg/m^2/s", "Mg/ha/yr")
5655
names(analysis.save[[length(analysis.save)]]) <- c("NPP")
5756
}
5857

0 commit comments

Comments
 (0)