% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/network.interpolation.R
\name{network.interpolation}
\alias{network.interpolation}
\title{Interpolate missing dendrometer values using a site network}
\usage{
network.interpolation(
  df,
  referenceDF,
  niMethod = c("proportional", "linear"),
  n_boot = 1000,
  return_flags = TRUE,
  return_pi = TRUE,
  pi_for_all = FALSE,
  return_fit = FALSE,
  assess = FALSE,
  assess_lengths_steps = c(1, 2, 3, 6, 12, 24),
  assess_samples_per_length = 20,
  assess_buffer_steps = 1,
  assess_seed = NULL,
  assess_use_only_observed = TRUE,
  progress = interactive(),
  correct_gap_jumps = FALSE,
  jump_threshold = NULL,
  jump_adjustment_method = c("window_median", "point_diff"),
  jump_adjust_window = 5,
  jump_set_point_na = FALSE
)
}
\arguments{
\item{df}{Data frame containing focal dendrometer data. The first column must
be datetime (\code{POSIXct}, \code{Date}, or character convertible by
\code{lubridate::ymd_hms}). Remaining columns are focal series.}

\item{referenceDF}{Data frame containing reference dendrometer data. The
first column must be datetime, and remaining columns are reference series.}

\item{niMethod}{Character. Interpolation method. One of
\code{"proportional"} or \code{"linear"}.}

\item{n_boot}{Integer. Number of bootstrap resamples used in proportional
mode.}

\item{return_flags}{Logical. If \code{TRUE}, add a logical column
\code{<series>_interp} indicating which focal values were imputed.}

\item{return_pi}{Logical. If \code{TRUE}, add 95\% prediction-limit columns
\code{<series>_pi_lo} and \code{<series>_pi_hi}.}

\item{pi_for_all}{Logical. If \code{TRUE}, prediction limits are also
attached for non-imputed rows where the model could be formed. If
\code{FALSE}, limits are returned only for imputed rows.}

\item{return_fit}{Logical. If \code{TRUE}, add \code{<series>_fit} columns
containing the model-implied fitted value.}

\item{assess}{Logical. If \code{TRUE}, run synthetic-gap validation.}

\item{assess_lengths_steps}{Integer vector. Artificial gap lengths,
expressed in number of rows/time steps, to test during validation.}

\item{assess_samples_per_length}{Integer. Number of sampled artificial gaps
per gap length and per focal series.}

\item{assess_buffer_steps}{Integer. Number of observed steps required before
and after each artificial gap when
\code{assess_use_only_observed = TRUE}.}

\item{assess_seed}{Integer or \code{NULL}. Random seed for reproducible
validation sampling.}

\item{assess_use_only_observed}{Logical. If \code{TRUE}, synthetic gaps are
sampled only from windows fully observed in the focal series, including
the requested buffer.}

\item{progress}{Logical. If \code{TRUE}, display a single-line progress
indicator.}

\item{correct_gap_jumps}{Logical. If \code{TRUE}, inspect the first observed
point after each imputed run and optionally remove a detected jump.}

\item{jump_threshold}{Numeric. Minimum absolute jump size required before a
post-gap correction is applied. Required if
\code{correct_gap_jumps = TRUE}.}

\item{jump_adjustment_method}{Character. Method used to estimate the
post-gap offset. One of \code{"window_median"} or \code{"point_diff"}.}

\item{jump_adjust_window}{Integer. Window size used by
\code{jump_adjustment_method = "window_median"}.}

\item{jump_set_point_na}{Logical. If \code{TRUE}, the jump point itself is
set to \code{NA} after correction.}
}
\value{
A data frame with class \code{"network_interpolation"}.

The data frame contains the original \code{TIME} column, focal series
columns, and optionally:
\describe{
  \item{\code{<series>_interp}}{Logical flag for imputed rows.}
  \item{\code{<series>_pi_lo}, \code{<series>_pi_hi}}{95\% prediction
  limits.}
  \item{\code{<series>_fit}}{Model-implied fitted values.}
  \item{\code{<series>_jump_correction}}{Numeric jump offset removed at the
  first observed point after an imputed run. \code{NA} means no correction
  was applied.}
}

In addition, the following attributes are attached:
\describe{
  \item{\code{network_original}}{Original focal data on the aligned time
  grid.}
  \item{\code{network_reference}}{Reference data aligned to the focal time
  grid.}
  \item{\code{network_diagnostics}}{Long-format diagnostics for plotting.}
  \item{\code{network_summary}}{Per-series interpolation summary table.}
  \item{\code{network_jump_corrections}}{Table of inspected and corrected
  post-gap jumps.}
  \item{\code{network_validation_raw}}{Per-gap validation summary table, or
  \code{NULL}.}
  \item{\code{network_validation_points}}{Point-level validation results, or
  \code{NULL}.}
  \item{\code{network_validation_summary}}{Summarized validation metrics by
  series and gap length, or \code{NULL}.}
  \item{\code{network_validation_seasonal}}{Seasonal validation diagnostics
  by day of year, or \code{NULL}.}
  \item{\code{network_method}}{Interpolation method used.}
  \item{\code{network_n_boot}}{Number of bootstrap resamples used.}
  \item{\code{network_assessed}}{Logical indicating whether validation was
  run.}
  \item{\code{network_jump_settings}}{List of jump-correction settings.}
}
}
\description{
Fills \code{NA} gaps in one or more focal dendrometer series by borrowing
information from a reference network recorded at the same site and on the
same time grid.

The focal dataset \code{df} is treated as the master time axis. The
reference network is aligned to that axis, so missing timestamps already
inserted into \code{df} are preserved during interpolation.

Two interpolation modes are available:
\itemize{
  \item \code{niMethod = "proportional"} uses the average relative change in
  the reference network between consecutive timestamps and propagates that
  change to the focal series.
  \item \code{niMethod = "linear"} fits a cross-sensor regression between
  reference values at time \eqn{t-1} and \eqn{t}, and predicts the focal
  value at time \eqn{t} from the focal value at time \eqn{t-1}.
}

Optional bootstrap-based uncertainty limits can be attached, synthetic-gap
validation can be used to assess recovery performance, and an optional
post-processing step can detect and correct abrupt post-gap jumps in the
interpolated series.
}
\details{
The function assumes that missing timestamps have already been inserted into
\code{df} and corresponding measurements set to \code{NA}, for example with
\code{\link{dm.na.interpolation}}.

For a focal series \eqn{a}, let \eqn{a_{t-1}} be the last available focal
value before the current timestamp. Let \eqn{b_{t-1}} and \eqn{b_t} be the
vectors of reference values at the previous and current timestamps.

In proportional mode, the relative reference change is
\deqn{
  \delta = \mathrm{mean}\left(\frac{b_t - b_{t-1}}{\max(b_{t-1}, \epsilon)}\right)
}
and the focal estimate is
\deqn{
  \hat{a}_t = a_{t-1}(1 + \delta).
}
Bootstrap resampling of reference sensors is used to estimate a 95\%
interval.

In linear mode, a simple regression of \eqn{b_t} on \eqn{b_{t-1}} is fit
across reference sensors at each step, and the focal value is predicted from
\eqn{a_{t-1}} with a 95\% prediction interval.

If fewer than two valid reference sensors are available at a timestamp pair,
or if the focal previous value is missing, the focal value is left unchanged.

If \code{correct_gap_jumps = TRUE}, the function inspects the first observed
point immediately after each imputed run. If a jump larger than
\code{jump_threshold} is detected, the estimated offset is removed from that
point onward. This is useful when a dendrometer resumes from a shifted
baseline after a gap.

If \code{assess = TRUE}, the function inserts artificial gaps into observed
sections of each focal series, interpolates them with the chosen method, and
compares predictions with the true values. This produces both per-gap
summaries and seasonal diagnostics of interpolation error.

The returned object is a data frame with class
\code{"network_interpolation"}.
}
\section{Interpretation}{

Smaller validation metrics such as \code{MAE}, \code{RMSE}, \code{MAPE}, and
\code{MdAPE} indicate better gap recovery. \code{PI_coverage_95} indicates
how well the nominal 95\% uncertainty interval captures the true values
under synthetic-gap validation. Seasonal diagnostics help identify periods
of the year when network interpolation is more or less reliable.

If many post-gap corrections are applied or \code{max_abs_gap_jump} is
large, it may indicate re-zeroing, sensor reset, or baseline
discontinuities after gaps.
}

\section{Notes}{

\itemize{
  \item The focal dataset \code{df} defines the output time grid.
  \item Reference series are aligned to that grid using the datetime column.
  \item At least two valid reference sensors are required at consecutive
  timestamps for interpolation.
  \item Jump correction is a post-processing step and does not alter the
  core interpolation logic.
}
}

\examples{
\donttest{
#library(dendRoAnalyst)
#data("gf_nepa17")

## Create an artificial focal gap
#df1 <- gf_nepa17
#df1[40:50, "T2"] <- NA

## Build a small reference network
#ref <- cbind(gf_nepa17, gf_nepa17[, 2:3], gf_nepa17[, 2:3])
#colnames(ref) <- c("Time", "T1", "T2", "T3", "T4", "T5", "T6")

## Interpolate with uncertainty limits
#out <- network.interpolation(
#  df1, ref,
#  niMethod = "proportional",
#  n_boot = 100,
#  return_flags = TRUE,
#  return_pi = TRUE
#)

#head(out, 10)

# Interpolate with jump correction and validation
#out2 <- network.interpolation(
#  df1, ref,
#  niMethod = "proportional",
#  n_boot = 100,
#  return_flags = TRUE,
#  return_pi = TRUE,
#  assess = TRUE,
#  assess_lengths_steps = c(1, 2, 4),
#  correct_gap_jumps = TRUE,
#  jump_threshold = 0.05,
#  jump_adjustment_method = "window_median",
#  jump_adjust_window = 5
#)
# Plotting
#plot(out2)
#plot(out2, type = "compare")
#plot(out2, type = "seasonal_error")

# Extracting the information using attr()
#attr(out, "network_validation_summary")
#attr(out, "network_validation_points")
#attr(out, "network_validation_seasonal")
}

}
\seealso{
\code{\link{plot.network_interpolation}},
\code{\link{dm.na.interpolation}}
}
