FluxSeparator separates diffusive and ebullitive (bubble) methane fluxes from continuous concentration measurements. It uses a running variance approach to identify sudden concentration increases caused by ebullition, then calculates diffusive flux from the remaining data using linear regression.
For methodological details, see [Sø et al. (2024)].
The package includes a small dataset from Lake Lyng with two pump cycles: one with only diffusive flux and one with an ebullitive event.
library(FluxSeparator)
data(DIY_sensor_data)
str(DIY_sensor_data)
#> spc_tbl_ [2,400 × 12] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
#> $ datetime : POSIXct[1:2400], format: "2021-09-28 03:11:35" "2021-09-28 03:11:37" ...
#> $ RH : num [1:2400] 73.3 73.4 73.3 73.3 73.3 73.3 73.3 73.4 73.4 73.5 ...
#> $ tempC : num [1:2400] 19.8 18 17.9 17.9 17.9 17.9 17.9 17.9 17.9 17.9 ...
#> $ CH4smV : num [1:2400] 493 493 493 493 493 ...
#> $ K33_RH : num [1:2400] 44.2 44.2 44.2 44.2 44.2 ...
#> $ K33_Temp : num [1:2400] 28.4 28.4 28.4 28.4 28.4 ...
#> $ K33_CO2 : num [1:2400] 387 387 387 387 387 387 387 387 387 387 ...
#> $ SampleNumber: num [1:2400] 1 2 3 4 5 6 7 8 9 10 ...
#> $ PumpCycle : num [1:2400] 1 1 1 1 1 1 1 1 1 1 ...
#> $ pred_CH4 : num [1:2400] 0.786 2.149 2.243 2.243 2.243 ...
#> $ station : num [1:2400] 1 1 1 1 1 1 1 1 1 1 ...
#> $ sensor : num [1:2400] 1 1 1 1 1 1 1 1 1 1 ...
#> - attr(*, "spec")=
#> .. cols(
#> .. datetime = col_datetime(format = ""),
#> .. `RH%` = col_double(),
#> .. tempC = col_double(),
#> .. CH4smV = col_double(),
#> .. K33_RH = col_double(),
#> .. K33_Temp = col_double(),
#> .. K33_CO2 = col_double(),
#> .. SampleNumber = col_double(),
#> .. PumpCycle = col_double(),
#> .. pred_CH4 = col_double(),
#> .. station = col_double(),
#> .. sensor = col_double()
#> .. )
#> - attr(*, "problems")=<pointer: (nil)>The ebullitive_flux() function identifies bubble events
using a running variance threshold. When the running variance exceeds
runvar_cutoff, the data is flagged as an ebullitive
event.
ebul_flux <- ebullitive_flux(DIY_sensor_data, show_plots = FALSE)
ebul_flux
#> # A tibble: 2 × 10
#> # Groups: station [1]
#> station PumpCycle datetime_start datetime_end
#> <dbl> <dbl> <dttm> <dttm>
#> 1 1 1 2021-09-28 03:11:35 2021-09-28 03:51:37
#> 2 1 2 2021-09-28 04:11:35 2021-09-28 04:51:36
#> # ℹ 6 more variables: sum_bubbles_concentration <dbl>, n_bubbles <dbl>,
#> # pumpcycle_duration_hr <dbl>, temp <dbl>, bubbles_per_time <dbl>,
#> # concentration_per_time <dbl>runvar_cutoff (default: 0.5): Lower
values detect more bubbles. Start high and decrease until you capture
the events you see in the data.IndexSpan (default: 30): How many
observations to include before/after each detected event.top_selection: Use "last"
(default) or "max" to determine the peak concentration of
each bubble.show_plots: Set to TRUE
for interactive visual inspection.The diffusive_flux() function first removes ebullitive
events (unless look_for_bubbles = FALSE), then fits a
linear model to the remaining concentration data to estimate the
diffusive flux.
diff_flux <- diffusive_flux(DIY_sensor_data,
cutoff_start_value = 5,
show_plots = FALSE)
#> Adding missing grouping variables: `PumpCycle`
diff_flux
#> # A tibble: 1 × 9
#> # Groups: PumpCycle, station [1]
#> PumpCycle station datetime_start datetime_end
#> <dbl> <dbl> <dttm> <dttm>
#> 1 1 1 2021-09-28 03:18:16 2021-09-28 03:31:37
#> # ℹ 5 more variables: slope_concentration_hr <dbl>, slope_standard_error <dbl>,
#> # n_obs_included_in_lm <int>, r2 <dbl>, temp <dbl>cutoff_start_value: Maximum starting
concentration for a cycle to be included. Use Inf (default)
to include all cycles.remove_observations_prior (default:
200): Skip the first N observations to allow the chamber to
equilibrate.number_of_observations_used (default:
400): Number of observations for the linear regression.look_for_bubbles (default:
TRUE): Set to FALSE for gases where ebullition
is unlikely (e.g., CO2).Convert from ppm per hour to µmol m⁻² h⁻¹ using the ideal gas law:
runvar_cutoffThe most important parameter is runvar_cutoff. To find
the best value:
ebullitive_flux() with
show_plots = TRUErunvar_cutoff until bubble events are correctly
identifiedrunvar_cutoff for both
ebullitive_flux() and diffusive_flux()Both functions can return plot objects as an attribute when
show_plots = TRUE:
citation("FluxSeparator")
#> To cite package 'FluxSeparator' in publications use:
#>
#> Sø J, Sand-Jensen K, Kragh T (2026). _FluxSeparator: Separation of
#> Diffusive and Ebullitive Fluxes_.
#> doi:10.32614/CRAN.package.FluxSeparator
#> <https://doi.org/10.32614/CRAN.package.FluxSeparator>.
#>
#> A BibTeX entry for LaTeX users is
#>
#> @Manual{,
#> title = {FluxSeparator: Separation of Diffusive and Ebullitive Fluxes},
#> author = {Jonas Stage Sø and Kaj Sand-Jensen and Theis Kragh},
#> year = {2026},
#> doi = {10.32614/CRAN.package.FluxSeparator},
#> }