samplingDensity: Pre-Survey Power Analysis for Bathymetric Sampling Design

View source: R/samplingDensity.R View source: R/samplingDensity.R View source: R/samplingDensity.R

samplingDensityR Documentation

Pre-Survey Power Analysis for Bathymetric Sampling Design

Description

Before any depth data are collected, estimate how far apart survey transects can be spaced and still produce an accurate bathymetric DEM. Because no real depth data exist yet, this works as a simulation study: a plausible "true" bathymetry is generated for the waterbody, a survey at each candidate transect spacing is simulated by sampling that truth, a DEM is reconstructed from those simulated samples (via interpBathy), and the reconstruction is compared back against the generated DEM. This is repeated many times per spacing to average out randomness, and across all candidate spacings, to build a curve of expected DEM accuracy vs. transect spacing - along with a recommended spacing and a map of what that survey design looks like on the actual waterbody outline.

Before any depth data are collected, estimate how far apart survey transects can be spaced and still produce an accurate bathymetric DEM. Because no real depth data exist yet, this works as a simulation study: a plausible "true" bathymetry is generated for the waterbody, a survey at each candidate transect spacing is simulated by sampling that truth, a DEM is reconstructed from those simulated samples (via interpBathy), and the reconstruction is compared back against the generated DEM. This is repeated many times per spacing to average out randomness, and across all candidate spacings, to build a curve of expected DEM accuracy vs. transect spacing - along with a recommended spacing and a map of what that survey design looks like on the actual waterbody outline.

Before any depth data are collected, estimate how far apart survey transects can be spaced and still produce an accurate bathymetric DEM. Because no real depth data exist yet, this works as a simulation study: a plausible synthetic "true" bathymetry is generated for the waterbody (a bowl-shaped depth profile plus spatially-correlated random roughness), a survey at each candidate transect spacing is simulated by sampling that synthetic truth, a DEM is reconstructed from those simulated samples (via interpBathy), and the reconstruction is compared back against the known synthetic truth. This is repeated many times per spacing to average out randomness, and across all candidate spacings, to build a curve of expected DEM accuracy vs. transect spacing - along with a recommended spacing and a map of what that survey design looks like on the actual lake outline.

Usage

samplingDensity(
  outline,
  max_depth,
  spacings = NULL,
  n_sim = 10,
  shape = 1,
  truth_model = "Exp",
  truth_range = NULL,
  truth_sill = NULL,
  truth_nugget = 0,
  along_track_interval = NULL,
  orientation = NULL,
  res = NULL,
  method = "IDW",
  nmax = 20,
  idp = 2,
  model = "Sph",
  psill = NULL,
  range = NULL,
  nugget = 0,
  kappa = NULL,
  trend_order = 1,
  zero_threshold = 0.05,
  tolerance = 0.1,
  n_truth_examples = 3,
  plot = TRUE,
  seed = NULL
)

samplingDensity(
  outline,
  max_depth,
  spacings = NULL,
  n_sim = 10,
  shape = 1,
  truth_model = "Exp",
  truth_range = NULL,
  truth_sill = NULL,
  truth_nugget = 0,
  along_track_interval = NULL,
  orientation = NULL,
  res = NULL,
  method = "IDW",
  nmax = 20,
  idp = 2,
  model = "Sph",
  psill = NULL,
  range = NULL,
  nugget = 0,
  kappa = NULL,
  trend_order = 1,
  zero_threshold = 0.05,
  tolerance = 0.1,
  n_truth_examples = 3,
  plot = TRUE,
  seed = NULL
)

samplingDensity(
  outline,
  max_depth,
  spacings = NULL,
  n_sim = 10,
  shape = 1,
  truth_model = "Exp",
  truth_range = NULL,
  truth_sill = NULL,
  truth_nugget = 0,
  along_track_interval = NULL,
  orientation = NULL,
  res = NULL,
  method = "IDW",
  nmax = 20,
  idp = 2,
  model = "Sph",
  psill = NULL,
  range = NULL,
  nugget = 0,
  kappa = NULL,
  trend_order = 1,
  zero_threshold = 0.05,
  tolerance = 0.1,
  n_truth_examples = 3,
  plot = TRUE,
  seed = NULL
)

Arguments

outline

shapefile outline of a waterbody. Accepts a SpatVector, an sf object, or anything terra::vect() can read.

max_depth

expected maximum depth of the waterbody, in meters. This drives the synthetic bathymetry and has a large effect on the results - use the best estimate available (a known max depth, an old chart, or a knowledgeable guess).

spacings

numeric vector of candidate transect spacings to test, in meters. Default = NULL, in which case a sequence scaled to the waterbody's size is generated automatically (roughly 2%%-40%% of the lake's characteristic length).

n_sim

number of independent synthetic "true" bathymetries to simulate and test each spacing against, default = 10. Higher values give a more stable accuracy estimate at the cost of runtime.

shape

numeric value controlling the synthetic depth profile's shape: depth = max_depth * (relative distance to shore) ^ shape. shape = 1 (default) gives a linear, cone-like profile; shape < 1 gives a broader, flatter deep basin; shape > 1 gives a narrower, steeper-sided basin.

truth_model

character variogram model used to generate the synthetic bathymetry's random roughness (see gstat::vgm options), default = "Exp".

truth_range

numeric range parameter (in meters) for the synthetic roughness's spatial autocorrelation, default = NULL, in which case it is set to one quarter of the waterbody's characteristic length (sqrt(area)).

truth_sill

numeric sill (variance, in squared meters) for the synthetic roughness, default = NULL, in which case it is set to (max_depth/5)^2.

truth_nugget

numeric nugget for the synthetic roughness variogram, default = 0.

along_track_interval

numeric spacing (in meters) at which simulated samples are drawn along each transect line, representing how frequently a sonar unit records depth while underway. Default = NULL, in which case it is set to 1/10th of the smallest tested spacing.

orientation

numeric angle, in degrees (0 = along the x-axis/east, increasing counterclockwise), giving the orientation of transect lines. Default = NULL, in which case the orientation is chosen automatically to align with the waterbody's long axis.

res

numeric DEM cell resolution (in meters) used both for generating the synthetic truth surface and for reconstructing the DEM from simulated samples. Default = NULL, in which case it is set to 1/5th of the smallest tested spacing. This should generally be left fine relative to 'spacings'.

method

character describing method of interpolation used to reconstruct DEMs, "IDW", "OK", or "UK". Default = "IDW" (recommended for this use, since it is run many times and OK's variogram fitting adds considerable runtime).

nmax

numeric value describing number of neighbors used in interpolation, default = 20

idp

numeric value describing inverse distance power value for IDW interpolation

model

character describing type of model used in Ordinary Kriging, options include 'Sph', 'Exp', 'Gau', 'Sta', default = 'Sph'

psill

numeric value describing the partial sill value for OK interpolation, default = NULL

range

numeric describing distance beyond which there is no spatial correlation in Ordinary Kriging models, default = NULL

nugget

numeric describing variance at zero distance in Ordinary Kriging models, default = 0

kappa

numeric value describing model smoothness, default = NULL

trend_order

numeric value (1 or 2) giving the polynomial trend order for Universal Kriging ("UK" only), default = 1

zero_threshold

numeric proportion (0-1) of surface area that must interpolate to exactly 0 before the automatic zero re-interpolation pass runs - passed through to interpBathy(). Default = 0.05.

tolerance

numeric value (proportion) used to pick the recommended spacing: the coarsest tested spacing whose mean RMSE is still within 'tolerance' of the best (finest-spacing) RMSE. Default = 0.1 (10%%).

n_truth_examples

numeric value giving how many of the n_sim synthetic "true" bathymetries to save and return/plot, so you can visually check whether the assumed depth profile and roughness look like your lake before trusting the rest of the results. Default = 3 (capped at n_sim).

plot

logical: should diagnostic plots (accuracy-vs-spacing curve, and outline + recommended transects map) be drawn? Default = TRUE.

seed

optional numeric value used to seed the random number generator, for reproducible results across runs. Default = NULL (not seeded).

Details

This is a power analysis under assumed, not observed, bathymetry - it can only be as realistic as the 'max_depth', 'shape', 'truth_range', and 'truth_sill' inputs. Once real depth data have been collected, use crossValidate(), interpBathy(), and optimizeParams() on the actual data to check whether observed accuracy matches what was predicted here, and adjust future survey effort accordingly. Runtime scales with n_sim x length(spacings) x (cost of one synthetic-surface simulation + one interpBathy call). For a first look, consider a smaller n_sim (e.g. 5) and a coarser 'res' before committing to a longer run.

This is a power analysis under assumed, not observed, bathymetry - it can only be as realistic as the 'max_depth', 'shape', 'truth_range', and 'truth_sill' inputs. Once real depth data have been collected, use crossValidate() and interpBathy() on the actual data to check whether observed accuracy matches what was predicted here, and adjust future survey effort accordingly.

This is a power analysis under assumed, not observed, bathymetry - it can only be as realistic as the 'max_depth', 'shape', 'truth_range', and 'truth_sill' inputs. Once real depth data have been collected, use crossValidate() and interpBathy() on the actual data to check whether observed accuracy matches what was predicted here, and adjust future survey effort accordingly. Runtime scales with n_sim x length(spacings) x (cost of one synthetic-surface simulation + one interpBathy call). For a first look, consider a smaller n_sim (e.g. 5) and a coarser 'res' before committing to a long run.

Value

a list with:

results

a data frame of spacing, mean RMSE, and SD of RMSE across simulations

recommended_spacing

the recommended transect spacing, in meters

transects

a SpatVector of the recommended transect lines, in the original CRS of 'outline'

total_transect_length

total length of the recommended transects, in meters

truth_examples

a multi-layer SpatRaster (one layer per saved example) of synthetic "true" bathymetries used during the simulation, in the original CRS of 'outline', for visually sanity-checking the assumed depth profile

a list with:

results

a data frame of spacing, mean RMSE, and SD of RMSE across simulations

recommended_spacing

the recommended transect spacing, in meters

transects

a SpatVector of the recommended transect lines, in the original CRS of 'outline'

total_transect_length

total length of the recommended transects, in meters

truth_examples

a multi-layer SpatRaster (one layer per saved example) of synthetic "true" bathymetries used during the simulation, in the original CRS of 'outline', for visually sanity-checking the assumed depth profile

a list with:

results

a data frame of spacing, mean RMSE, and SD of RMSE across simulations

recommended_spacing

the recommended transect spacing, in meters

transects

a SpatVector of the recommended transect lines, in the original CRS of 'outline'

total_transect_length

total length of the recommended transects, in meters

truth_examples

a multi-layer SpatRaster (one layer per saved example) of synthetic "true" bathymetries used during the simulation, in the original CRS of 'outline', for visually sanity-checking the assumed depth profile

Author(s)

Tristan Blechinger, Department of Zoology & Physiology, University of Wyoming

Examples


outline <- terra::vect(system.file("extdata", "example_outline.shp", package = 'rLakeHabitat'))
samplingDensity(outline, max_depth = 40, n_sim = 5, seed = 123)

outline <- terra::vect(system.file("extdata", "example_outline.shp", package = 'rLakeHabitat'))
samplingDensity(outline, max_depth = 40, n_sim = 5, seed = 123)

outline <- terra::vect(system.file("extdata", "example_outline.shp", package = 'rLakeHabitat'))
samplingDensity(outline, max_depth = 40, n_sim = 5, seed = 123)

rLakeHabitat documentation built on July 30, 2026, 5:11 p.m.