dm.growth.fit.double: Fit bimodal dendrometer growth curves by vegetation season

View source: R/dm.growth.fit.double.R

dm.growth.fit.doubleR Documentation

Fit bimodal dendrometer growth curves by vegetation season

Description

Fits bimodal cumulative growth curves to daily dendrometer series using either a double-Gompertz or double-Richards model.

Overall growing-season timing is derived from the fitted cumulative-growth curve using growth_fraction. Pulse-specific timing is derived from the derivative of the fitted curve using a pulse-specific relative rate threshold given by rate_threshold_fraction.

Pulse-specific timing is returned as NA when the fitted curve does not show a convincing two-pulse pattern according to derivative-based criteria.

If fallback_to_single = TRUE and no convincing two-pulse pattern is found, the function refits a corresponding single growth curve and returns that fit instead. In that case, overall season timing is still returned, but pulse-specific timing remains NA.

For double-Gompertz and double-Richards fits, the total asymptote can optionally be fixed to the observed maximum cumulative growth of the corresponding series and vegetation season. In the double-curve case, this means a + a2 is fixed, while the relative contribution of the first and second pulse is estimated.

Usage

dm.growth.fit.double(
  df,
  TreeNum = "all",
  method = c("gompertz", "richards"),
  years = "all",
  year_mode = c("yearly", "pooled"),
  fit_GRO = TRUE,
  site_mode = c("NH", "SH", "CS"),
  custom_veg_season = c(275, 274),
  growth_fraction = c(0.1, 0.9),
  min_unique_growth = 10,
  rate_threshold_fraction = 0.1,
  peak_separation_min = 10,
  valley_ratio_max = 0.4,
  min_relative_peak = 0.05,
  fallback_to_single = TRUE,
  fix_a_to_observed_max = FALSE,
  fixed_a_multiplier = 1,
  start_value_double_gompertz_parameters = list(a = NA_real_, k = NA_real_, t0 =
    NA_real_, a2 = NA_real_, k2 = NA_real_, t02 = NA_real_),
  start_value_double_richards_parameters = list(a = NA_real_, k = NA_real_, t0 =
    NA_real_, v = 1, a2 = NA_real_, k2 = NA_real_, t02 = NA_real_, v2 = 1),
  verbose = TRUE
)

Arguments

df

A data frame or tibble. The first column must be a time stamp Date, POSIXct, or parseable date-time string. Remaining selected columns must be numeric dendrometer series.

TreeNum

Either "all" to use all dendrometer series, a numeric vector selecting dendrometer columns by position, or a character vector of column names.

method

Double-curve fitting method. One of "gompertz" or "richards".

years

Either "all" to fit all available vegetation seasons, or a character vector of season labels to retain.

year_mode

Either "yearly" to fit one curve per vegetation season, or "pooled" to fit one pooled curve across all retained seasons.

fit_GRO

Logical. If TRUE, processed daily series are converted to cumulative growth using a cumulative maximum within each vegetation season.

site_mode

Vegetation season definition. One of "NH", "SH", or "CS".

custom_veg_season

Numeric vector of length two giving the start and end day-of-year for custom vegetation seasons in "CS" mode.

growth_fraction

Numeric vector of length two giving the lower and upper fractions of final fitted seasonal growth used to define overall growing-season onset and cessation.

min_unique_growth

Minimum number of unique non-missing cumulative growth values required before a fit is attempted.

rate_threshold_fraction

Numeric scalar between 0 and 1. Pulse start and end are defined as the first and last days where fitted growth rate exceeds this fraction of the pulse-specific peak fitted growth rate.

peak_separation_min

Minimum number of days separating the two fitted derivative peaks required to classify a fit as truly two-pulse.

valley_ratio_max

Maximum allowed ratio between the valley rate and the weaker of the two derivative peaks. Smaller values require a deeper valley between pulses.

min_relative_peak

Minimum relative height, expressed as a fraction of the global derivative maximum, for a local derivative peak to be considered.

fallback_to_single

Logical. If TRUE, and the fitted double curve does not show a convincing two-pulse pattern according to derivative-based criteria, the function refits a corresponding single growth curve "gompertz" or "richards" and returns that fit instead.

fix_a_to_observed_max

Logical. If TRUE, the total asymptote of the double-growth curve is fixed to the observed maximum cumulative growth for that series and vegetation season. For double-Gompertz and double-Richards models, this means a + a2 is fixed, while the relative contribution of the two pulses is estimated. This is most appropriate with year_mode = "yearly". For year_mode = "pooled", one pooled maximum is used.

fixed_a_multiplier

Numeric multiplier applied to the observed maximum when fix_a_to_observed_max = TRUE. The default is 1, meaning the total asymptote is fixed exactly to the observed seasonal maximum. Values slightly above 1, for example 1.01 or 1.05, allow the fitted asymptote to sit slightly above the observed maximum.

start_value_double_gompertz_parameters

Optional named list of starting values for the double-Gompertz fit. Supported names are a, k, t0, a2, k2, and t02. If fix_a_to_observed_max = TRUE, supplied a and a2 are used only to initialize the relative pulse contribution.

start_value_double_richards_parameters

Optional named list of starting values for the double-Richards fit. Supported names are a, k, t0, v, a2, k2, t02, and v2. If fix_a_to_observed_max = TRUE, supplied a and a2 are used only to initialize the relative pulse contribution.

verbose

Logical. If TRUE, prints a short completion message.

Details

The second pulse is constrained to occur after the first pulse, which improves numerical stability and reduces label switching between the two components.

For double-Gompertz and double-Richards models, the total seasonal asymptote is:

a_{total} = a + a2

When fix_a_to_observed_max = TRUE, the function fits:

a + a2 = max(y_{obs}) \times fixed\_a\_multiplier

where y_{obs} is the observed cumulative growth of the selected dendrometer series and vegetation season.

The fitted pulse contributions are still returned as a and a2, and their sum should equal fixed_a_value, apart from small numerical rounding.

Non-applicable parameters are returned as NA. For example, b and b2 are relevant for double-Gompertz, while v and v2 are relevant for double-Richards.

Value

An object of class "dm_growth_fit" with elements:

call

The matched function call.

original_daily_data

Raw daily dendrometer data after resampling to daily maxima and assigning vegetation seasons, but before centering and optional cumulative-growth transformation.

processed_data

Daily processed data used for fitting.

fitted_data

Daily fitted values on the full vegetation-season grid.

fit_statistics

Fit-level statistics and estimated timing.

fit_parameters

Fit-level model parameters and convergence information.

season_table

Vegetation seasons retained for fitting.

See Also

[dm.growth.fit()], [summary.dm_growth_fit()], [print.dm_growth_fit()]

Examples


# Double-Gompertz with total seasonal asymptote fixed
# fit_gomp <- dm.growth.fit.double(
#   df = dendro_data,
#   TreeNum = "all",
#   method = "gompertz",
#   year_mode = "yearly",
#   fit_GRO = TRUE,
#   fix_a_to_observed_max = TRUE
# )

# Double-Richards with the total asymptote set 2 percent above observed max
# fit_rich <- dm.growth.fit.double(
#   df = dendro_data,
#   TreeNum = "all",
#   method = "richards",
#   year_mode = "yearly",
#   fit_GRO = TRUE,
#   fix_a_to_observed_max = TRUE,
#   fixed_a_multiplier = 1.02
# )



dendRoAnalyst documentation built on May 20, 2026, 5:07 p.m.