% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/dm.growth.fit.R
\name{dm.growth.fit}
\alias{dm.growth.fit}
\title{Fit dendrometer growth curves by vegetation season}
\usage{
dm.growth.fit(
  df,
  TreeNum = "all",
  method = c("gam", "gompertz", "logistic", "richards", "loess", "spline"),
  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,
  fix_a_to_observed_max = FALSE,
  fixed_a_multiplier = 1,
  start_value_gompertz_parameters = list(a = NA_real_, b = NA_real_, k = NA_real_),
  start_value_richards_parameters = list(a = NA_real_, k = NA_real_, t0 = NA_real_, v =
    1),
  loess_span = 0.2,
  spline_df = 10,
  verbose = TRUE
)
}
\arguments{
\item{df}{A data frame or tibble. The first column must be a timestamp
\code{Date}, \code{POSIXct}, or parseable date-time string. All selected
remaining columns must be numeric dendrometer series.}

\item{TreeNum}{Either \code{"all"} to use all dendrometer series, a numeric
vector selecting dendrometer columns by position, or a character vector
with series names.}

\item{method}{Fitting method. One of \code{"gam"}, \code{"gompertz"},
\code{"logistic"}, \code{"richards"}, \code{"loess"}, or \code{"spline"}.}

\item{years}{Either \code{"all"} to fit all available vegetation seasons, or
a character vector of season labels to retain.}

\item{year_mode}{Either \code{"yearly"} to fit one curve per vegetation
season, or \code{"pooled"} to fit one pooled curve across all retained
seasons.}

\item{fit_GRO}{Logical. If \code{TRUE}, processed daily series are converted
to cumulative growth using a cumulative maximum within each vegetation
season.}

\item{site_mode}{Vegetation season definition. One of \code{"NH"},
\code{"SH"}, or \code{"CS"}.}

\item{custom_veg_season}{Numeric vector of length two giving the start and
end day-of-year for custom vegetation seasons in \code{"CS"} mode.
Cross-year seasons are supported, for example \code{c(275, 274)}.}

\item{growth_fraction}{Numeric vector of length two giving the lower and
upper fractions of final fitted seasonal growth used to define cumulative
growth onset and cessation, for example \code{c(0.1, 0.9)}.}

\item{min_unique_growth}{Minimum number of unique non-missing cumulative
growth values required before a fit is attempted.}

\item{rate_threshold_fraction}{Numeric scalar between 0 and 1. Active-growth
dates are derived from the fitted growth-rate curve as the first and last
days where fitted growth rate exceeds this fraction of the peak fitted
growth rate.}

\item{fix_a_to_observed_max}{Logical. If \code{TRUE} and
\code{method = "gompertz"}, \code{"logistic"}, or \code{"richards"}, the
asymptote parameter \code{a}, representing maximum seasonal growth, is fixed
to the observed maximum cumulative growth of the corresponding series and
vegetation season. This is most appropriate with
\code{year_mode = "yearly"}. For \code{year_mode = "pooled"}, one pooled
maximum is used.}

\item{fixed_a_multiplier}{Numeric multiplier applied to the observed maximum
when \code{fix_a_to_observed_max = TRUE}. The default is \code{1}, meaning
\code{a} is fixed exactly to the observed seasonal maximum. Values slightly
above 1, for example \code{1.01} or \code{1.05}, allow the fitted asymptote
to sit just above the observed maximum.}

\item{start_value_gompertz_parameters}{Optional named list with starting
values for Gompertz fits. Supported names are \code{a}, \code{b}, and
\code{k}. If \code{fix_a_to_observed_max = TRUE}, supplied \code{a} is
ignored.}

\item{start_value_richards_parameters}{Optional named list with starting
values for Richards and logistic fits. Supported names are \code{a},
\code{k}, \code{t0}, and \code{v}. If
\code{fix_a_to_observed_max = TRUE}, supplied \code{a} is ignored.}

\item{loess_span}{Span used when \code{method = "loess"}.}

\item{spline_df}{Degrees of freedom used when \code{method = "spline"}.}

\item{verbose}{Logical. If \code{TRUE}, prints a short completion message.}
}
\value{
An object of class \code{"dm_growth_fit"} with elements:
\describe{
  \item{call}{The matched function call.}
  \item{original_daily_data}{Raw daily dendrometer data after resampling to
    daily maxima and assigning vegetation seasons, but before centering and
    optional cumulative-growth transformation.}
  \item{processed_data}{Daily processed data used for fitting.}
  \item{fitted_data}{Daily fitted values on the full vegetation-season grid.}
  \item{fit_statistics}{Table with fit-level statistics and estimated timing.}
  \item{fit_parameters}{Table with fit-level model parameters and convergence
    information.}
  \item{season_table}{Vegetation seasons retained for fitting.}
}
}
\description{
Fits cumulative growth curves to daily dendrometer series using one of
several supported methods: generalized additive model \code{"gam"},
Gompertz \code{"gompertz"}, logistic \code{"logistic"}, Richards
\code{"richards"}, local regression \code{"loess"}, or smoothing spline
\code{"spline"}.

The function:
\itemize{
  \item resamples dendrometer data to daily maxima using [dendro.resample()],
  \item assigns each daily observation to a vegetation season,
  \item optionally converts daily stem-size values to cumulative growth
    with \code{fit_GRO = TRUE},
  \item fits one curve per series and season with
    \code{year_mode = "yearly"} or one pooled curve across retained seasons
    with \code{year_mode = "pooled"},
  \item estimates growing-season timing from the fitted cumulative-growth
    curve,
  \item additionally identifies active-growth timing from the fitted
    growth-rate curve.
}

For Gompertz, logistic, and Richards fits, the asymptote parameter
\code{a}, representing maximum seasonal growth, can optionally be fixed to
the observed maximum cumulative growth for that series and vegetation season.
This is controlled by \code{fix_a_to_observed_max}.
}
\details{
The first column of \code{df} is treated as the time column and renamed to
\code{"TIME"} internally. If it is not already a date-time object, the
function attempts to parse it using [lubridate::parse_date_time()].

\code{growth_start_*} and \code{growth_end_*} are based on cumulative fitted
growth. \code{rate_start_*} and \code{rate_end_*} are based on the fitted
growth-rate curve.

For Gompertz, logistic, and Richards models, \code{a} is the upper asymptote.
When \code{fix_a_to_observed_max = TRUE}, this parameter is not estimated by
nonlinear least squares. Instead, it is fixed to:

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

where \eqn{y_{obs}} is the observed cumulative growth for that series and
vegetation season.
}
\examples{
\donttest{
# fit <- dm.growth.fit(
#   df = dendro_data,
#   TreeNum = "all",
#   method = "gompertz",
#   year_mode = "yearly",
#   fit_GRO = TRUE,
#   fix_a_to_observed_max = TRUE
# )

# fit2 <- dm.growth.fit(
#   df = dendro_data,
#   TreeNum = "all",
#   method = "richards",
#   year_mode = "yearly",
#   fit_GRO = TRUE,
#   fix_a_to_observed_max = TRUE,
#   fixed_a_multiplier = 1.02
# )
}

}
\seealso{
[summary.dm_growth_fit()], [print.dm_growth_fit()]
}
