Gas concentration is typically measured in fractional units (e. g., ppm) by gas analysers. When calculating the fluxes, the temperature, pressure, and gas constant are used to transform the flux in a volumetric concentration (e.g., mmol/l). Since the temperature might be changing over time during the measurement, the average is usually used in that calculation.
From fluxible 1.4.0, it is possible to transform each
gas concentration datapoints in volumetric units before modelling the
slope, and calculating the flux. This accounts better for temperature
changes in the chamber, typically in hot climate, but requires more
temperature measurements during the flux measurements.
This vignette is showing this pathway with a sample dataset from the NatuRA project in the Drakensberg in South Africa. CO2 concentration was measured every second with an LI7810, air temperature inside the chamber also every second, and the atmospheric pressure daily average was retrieved from a nearby weather station.
library(tidyverse)
conc_df <- read_csv("ex_data/sample_vol_conc.csv")
head(conc_df)
#> # A tibble: 6 × 7
#> CO2 datetime temp_air f_start f_fluxid
#> <dbl> <dttm> <dbl> <dttm> <dbl>
#> 1 376. 2026-01-26 08:37:00 27.2 2026-01-26 08:37:00 270
#> 2 377. 2026-01-26 08:37:01 27.1 2026-01-26 08:37:00 270
#> 3 379. 2026-01-26 08:37:02 27.1 2026-01-26 08:37:00 270
#> 4 382. 2026-01-26 08:37:03 27.1 2026-01-26 08:37:00 270
#> 5 384. 2026-01-26 08:37:04 27.1 2026-01-26 08:37:00 270
#> 6 386. 2026-01-26 08:37:05 27.1 2026-01-26 08:37:00 270
#> # ℹ 2 more variables: f_end <dttm>, atm_press <dbl>We can now transform the concentration in volumetric units with the
flux_conc function. Because the CO2 was measured
in ppm, the volumetric concentration will be in µmol/l.
library(fluxible)
conc_df_vol <- flux_conc(
conc_df,
CO2,
temp_air,
atm_press
)
head(conc_df_vol)
#> # A tibble: 6 × 8
#> CO2 datetime temp_air f_start f_fluxid
#> <dbl> <dttm> <dbl> <dttm> <dbl>
#> 1 376. 2026-01-26 08:37:00 27.2 2026-01-26 08:37:00 270
#> 2 377. 2026-01-26 08:37:01 27.1 2026-01-26 08:37:00 270
#> 3 379. 2026-01-26 08:37:02 27.1 2026-01-26 08:37:00 270
#> 4 382. 2026-01-26 08:37:03 27.1 2026-01-26 08:37:00 270
#> 5 384. 2026-01-26 08:37:04 27.1 2026-01-26 08:37:00 270
#> 6 386. 2026-01-26 08:37:05 27.1 2026-01-26 08:37:00 270
#> # ℹ 3 more variables: f_end <dttm>, atm_press <dbl>, f_conc_vol <dbl>Now we do the model fitting, quality check, and plotting as usual.
fit_df <- flux_fitting(
conc_df_vol,
f_conc_vol,
datetime
)
quality_df <- flux_quality(
fit_df,
f_conc_vol,
ambient_conc = 18, # approx ambient CO2 concentration at 20°C in umol/l
error = 4 # this one also needs to be adapted
)
flux_plot(
quality_df,
f_conc_vol,
datetime,
f_ylim_upper = 25, # default values are for ppm
f_ylim_lower = 10
)Then we can calculate fluxes with flux_calc. We still
input the columns atm_press and temp_air, to
get them averaged per fluxes. They are however not used in the flux
calculation since this was done with flux_conc already.
fluxes <- flux_calc(
quality_df,
f_slope,
datetime,
temp_air,
conc_unit = "umol/l", # notice the units change
flux_unit = "umol/m2/s",
setup_volume = 125,
atm_pressure = atm_press,
plot_area = 0.25,
cut = FALSE
)
str(fluxes)
#> tibble [3 × 7] (S3: tbl_df/tbl/data.frame)
#> $ f_fluxid : num [1:3] 270 427 434
#> $ f_slope : num [1:3] 0.03818 -0.01441 0.00693
#> $ f_temp_air_ave : num [1:3] 28.2 27 19
#> $ f_atm_pressure_ave: num [1:3] 0.991 0.99 0.99
#> $ datetime : POSIXct[1:3], format: "2026-01-26 08:37:00" "2026-01-29 09:30:20" ...
#> $ f_flux : num [1:3] 19.09 -7.2 3.46
#> $ f_model : chr [1:3] "exp_zhao18" "exp_zhao18" "exp_zhao18"