Skip to contents

Detects terminal arm tips in a graph by:

  1. computing graph endpoint scores from the 3D embedding,

  2. optionally smoothing those scores on the graph using fit.rdgraph.regression() and refit.rdgraph.regression(),

  3. finding graph-local maxima with detect.local.extrema(),

  4. retaining only maxima that persist across neighborhood scales.

The function works with terminal regions in an embedding; returned endpoints need not be degree-1 vertices.

Usage

detect.graph.endpoints(
  adj.list,
  length.list,
  layout.3d,
  neighborhood = c("geodesic_k", "geodesic_radius"),
  k = c(10L, 20L, 30L),
  radius = NULL,
  q = 0.1,
  neighbor.weighting = c("uniform", "inverse_distance", "gaussian"),
  gaussian.sigma = NULL,
  min.neighborhood.size = 3L,
  scale.aggregate = c("mean", "median", "min", "max"),
  score.metric = c("score", "m", "s.q", "s.min"),
  smooth = FALSE,
  fitted.model = NULL,
  smooth.fit.args = NULL,
  smooth.refit.args = NULL,
  detect.max.radius = 2,
  detect.min.neighborhood.size = 2L,
  scale.stability.radius = NULL,
  min.scale.stability = 0.5,
  min.score.quantile = 0.8,
  max.endpoints = NULL,
  verbose = FALSE
)

Arguments

adj.list

Graph adjacency list (1-based vertex indices).

length.list

Edge-length list aligned with adj.list.

layout.3d

Numeric matrix or data frame with 3 columns giving the 3D embedding coordinates for graph vertices.

neighborhood

Character string. Either "geodesic_k" (default) or "geodesic_radius".

k

Integer vector of geodesic neighborhood sizes used when neighborhood = "geodesic_k".

radius

Positive numeric vector of geodesic radii used when neighborhood = "geodesic_radius".

q

Quantile used for s.q. Must lie in [0, 1]. Default is 0.1.

neighbor.weighting

Character string controlling neighbor weights for m and weighted pair quantiles. One of "uniform" (default), "inverse_distance", or "gaussian".

gaussian.sigma

Optional positive numeric scale used when neighbor.weighting = "gaussian".

min.neighborhood.size

Minimum number of usable neighbors required after removing zero-length embedding vectors.

scale.aggregate

How to aggregate scores across multiple neighborhood scales. One of "mean" (default), "median", "min", or "max".

score.metric

Which score to maximize. One of "score" (default), "m", "s.q", or "s.min".

smooth

Logical; if TRUE, smooths aggregated scores on the graph before detecting extrema.

fitted.model

Optional fitted graph smoother from fit.rdgraph.regression(). If supplied, smoothing reuses its spectral decomposition via refit.rdgraph.regression().

smooth.fit.args

Optional named list of arguments passed to fit.rdgraph.regression() when smooth = TRUE and fitted.model is NULL. X, y, adj.list, length.list, and verbose.level are filled automatically when not supplied.

smooth.refit.args

Optional named list of arguments passed to refit.rdgraph.regression() when smoothing aggregated score fields.

detect.max.radius

Maximum radius passed to detect.local.extrema() when calling endpoint candidates from the final detection score.

detect.min.neighborhood.size

Minimum neighborhood size passed to detect.local.extrema() when calling endpoint candidates.

scale.stability.radius

Optional non-negative geodesic radius used when translating per-scale local maxima into multiscale support. If NULL (default), uses detect.max.radius. This allows smoothed maxima that shift slightly inward to remain supported by nearby raw multiscale maxima.

min.scale.stability

Minimum fraction of scales for which a vertex must be a local maximum of the per-scale detection score to be retained as an endpoint. Default is 0.5.

min.score.quantile

Quantile filter applied to the final detection score before returning endpoints. Default is 0.8, which suppresses weak local maxima while keeping high-scoring terminal tips.

max.endpoints

Optional positive integer cap on returned endpoints.

verbose

Logical; if TRUE, prints progress.

Value

A list with endpoint vertices, score diagnostics, optional smoothed scores, scale stability summaries, and the local-extrema fit used for endpoint calling.

Examples

chain <- create.graph("chain", n = 8)
layout <- cbind(seq_len(8), 0, 0)
endpoints <- detect.graph.endpoints(graph.adjacency(chain), graph.lengths(chain),
    layout, k = c(2,
    3), min.neighborhood.size = 2, detect.max.radius = 2, detect.min.neighborhood.size = 2,
    min.score.quantile = 0.5)
endpoints$endpoints
#> [1] 1 8