% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/dm.growth.evaluate.R
\name{dm.growth.evaluate}
\alias{dm.growth.evaluate}
\title{Compare dendrometer growth-fitting methods using fit statistics}
\usage{
dm.growth.evaluate(
  df,
  TreeNum = "all",
  methods = c("gam", "gompertz", "logistic", "richards", "loess", "spline",
    "double_gompertz", "double_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,
  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),
  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),
  loess_span = 0.2,
  spline_df = 10,
  verbose = TRUE
)
}
\arguments{
\item{df}{A data frame or tibble. The first column must be a time stamp and
the remaining selected columns must be numeric dendrometer series.}

\item{TreeNum}{Either `"all"`, a numeric vector selecting dendrometer series
by position, or a character vector of series names.}

\item{methods}{Character vector of fitting methods to evaluate.}

\item{years}{Either `"all"` or a character vector of vegetation-season labels.}

\item{year_mode}{Either `"yearly"` or `"pooled"`.}

\item{fit_GRO}{Logical. If `TRUE`, convert processed daily series to
cumulative growth before fitting.}

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

\item{custom_veg_season}{Numeric vector of length 2 defining a custom season
in day-of-year coordinates when `site_mode = "CS"`.}

\item{growth_fraction}{Numeric vector of length 2 used by the fitting
functions to estimate cumulative-growth timing.}

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

\item{rate_threshold_fraction}{Numeric scalar between 0 and 1. Passed to the
fitting functions where supported.}

\item{peak_separation_min}{Minimum peak separation in days for
[dm.growth.fit.double()].}

\item{valley_ratio_max}{Maximum allowed valley-to-peak ratio for
[dm.growth.fit.double()].}

\item{min_relative_peak}{Minimum relative peak height for
[dm.growth.fit.double()].}

\item{start_value_gompertz_parameters}{Optional starting values for Gompertz
fits.}

\item{start_value_richards_parameters}{Optional starting values for logistic
and Richards fits.}

\item{start_value_double_gompertz_parameters}{Optional starting values for
double-Gompertz fits.}

\item{start_value_double_richards_parameters}{Optional starting values for
double-Richards fits.}

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

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

\item{verbose}{Logical. If `TRUE`, prints progress messages.}
}
\value{
A tibble with one row per fitted series and fit, containing:
\describe{
  \item{method}{Fitting method used for the row.}
  \item{series}{Series name.}
  \item{fit_id}{Vegetation-season label or `"pooled"`.}
  \item{n_compare}{Number of observed days used for comparison.}
  \item{rmse}{Root mean squared error.}
  \item{mae}{Mean absolute error.}
  \item{bias}{Mean fitted minus observed value.}
  \item{r2}{Coefficient of determination.}
  \item{correlation}{Pearson correlation between observed and fitted values.}
  \item{nrmse}{RMSE divided by the observed range.}
  \item{rss}{Residual sum of squares.}
  \item{aic_approx}{Approximate AIC based on RSS and effective parameter count.}
  \item{bic_approx}{Approximate BIC based on RSS and effective parameter count.}
  \item{k_effective}{Effective parameter count used in the approximate
    information criteria.}
  \item{converged}{Logical convergence flag returned by the fitting function.}
  \item{model_note}{Model note, warning, or error message returned by the
    fitting function.}
}
}
\description{
Fits one or more growth models to dendrometer series and returns a compact
table of evaluation statistics only.

This function is intended for method comparison rather than data extraction.
It runs the selected fitting methods, aligns observed and fitted values on
all non-missing observation days, and calculates goodness-of-fit measures for
each fitted series and vegetation-season fit.

Supported single-curve methods are `"gam"`, `"gompertz"`, `"logistic"`,
`"richards"`, `"loess"`, and `"spline"`, which are fitted using
[dm.growth.fit()]. Supported bimodal methods are `"double_gompertz"` and
`"double_richards"`, which are fitted using [dm.growth.fit.double()].

The function returns only an evaluation table and does not return fitted
curves, processed data, or parameter objects. It is therefore useful for
comparing alternative fitting methods across series, years, or sites before
selecting a final modeling approach.
}
\details{
Evaluation statistics are calculated by comparing observed daily values
against fitted daily values on all days where observed values are available.

The returned metrics have the following interpretation:
\itemize{
  \item `rmse`: root mean squared error. Smaller values indicate closer fit.
  \item `mae`: mean absolute error. Smaller values indicate closer fit and are
    less sensitive to large deviations than RMSE.
  \item `bias`: mean fitted minus observed value. Positive values indicate
    overestimation and negative values indicate underestimation.
  \item `r2`: coefficient of determination, computed from residual and total
    sums of squares. Larger values indicate better fit.
  \item `correlation`: Pearson correlation between observed and fitted values.
    Larger values indicate stronger agreement in shape.
  \item `nrmse`: normalized RMSE, calculated as RMSE divided by the observed
    value range. This allows comparison across series with different
    magnitudes.
  \item `rss`: residual sum of squares.
  \item `aic_approx` and `bic_approx`: approximate information criteria based
    on RSS and an effective parameter count rather than the exact likelihood
    returned by each modeling function.
}

The columns `aic_approx` and `bic_approx` are labeled as approximate because
they are not extracted from the original model objects through a unified
likelihood interface. Instead, they are computed from the residual sum of
squares and an effective number of fitted parameters. They are therefore most
useful for relative comparison among methods fitted to the same dataset.

Negative values of `aic_approx` or `bic_approx` are not an error. They occur
naturally when the average residual variance is smaller than 1, because the
logarithmic term in the information-criterion formula becomes negative. In
practice, the absolute sign is not important; only differences among methods
fitted to the same data should be interpreted.

For methods with flexible smoothness, such as GAM or spline, the effective
parameter count is approximate. Consequently, `aic_approx` and `bic_approx`
should be treated as heuristic ranking measures rather than exact
likelihood-based criteria.
}
\seealso{
[dm.growth.fit()], [dm.growth.fit.double()]
}
