Public API
BiodiversityObservationNetworks.AdaptiveHotspot Type
AdaptiveHotspot{I, F} <: BONSamplerImplements Adaptive Hotspot Sampling for high-uncertainty or high-value targets.
Fields
num_nodes::I: Number of sites.scale::F: Range parameter (ρ) of the Matérn covariance kernel.smoothness::F: Smoothness parameter (ν) of the Matérn covariance kernel.
Description
Starts at the global maximum of the target/uncertainty surface. Subsequent points are chosen to maximize a trade-off between the target value and spatial diversity (measured via the determinant of a kernel matrix).
References
- Andrade-Pacheco, R., et al. (2020) Finding hotspots...
BiodiversityObservationNetworks.BalancedAcceptance Type
BalancedAcceptance <: BONSamplerImplements Balanced Acceptance Sampling (BAS) using Halton sequences.
Fields
num_nodes::Int: The number of sites to select.
Description
BAS generates spatially balanced samples by mapping the domain to a Halton sequence. If inclusion probabilities are provided, it uses a 3D Halton sequence where the third dimension acts as an acceptance threshold against the probability surface.
References
- Robertson, B. L., et al. (2013).
BiodiversityObservationNetworks.BiodiversityObservationNetwork Type
BiodiversityObservationNetwork{N, D}Represents the selected sampling sites and their associated data.
Fields
nodes::N: The coordinates or indices of the selected sites.auxiliary: The matrix of auxiliary variables associated with each node.
BiodiversityObservationNetworks.CubeSampling Type
CubeSampling <: BONSamplerImplements the Cube method for balanced sampling with respect to auxiliary variables.
Fields
num_nodes::Int: The expected sample size.
Description
The algorithm selects a sample such that the Horvitz-Thompson estimates of auxiliary variables match the population totals as closely as possible. It proceeds in two phases:
Flight Phase: Random walk modifying inclusion probabilities while respecting constraints.
Landing Phase: Linear programming (using HiGHS) to resolve remaining fractional probabilities.
References
- Deville, J. C., & Tillé, Y. (2004). Efficient balanced sampling: The cube method.
BiodiversityObservationNetworks.DistanceToMedian Type
DistanceToMedianRarity score defined as Euclidean distance in feature space to the per-feature median across the raster stack. Optionally, features can be PCA-transformed prior to z-scoring.
sourceBiodiversityObservationNetworks.GeneralizedRandomTesselated Type
GeneralizedRandomTesselatedGeneralizedRandomTesselated is a type of BONSampler for generating BiodiversityObservationNetworks with spatial spreading.
GRTS was initially proposed in (Stevens and Olsen, 2022).
Arguments:
num_nodes: the number of sites to selectgrid_size: if being used on a polygon, the dimensions of the grid used to cover the extent. GRTS sampling uses discrete Cartesian indices
GRTS represents each cell of a rasterized version of the sampling domain using an address, where the address of each cell is represented as a D-digit base-4 number.
The value of D depends on the size of the raster. GRTS works by recursively splitting the rasterized domain into quadrants, and those quadrants into further quadrants, until a single pixel is reached. At each step, each quadrant is randomly labeled with a number 1, 2, 3, or 4 (without replacement, so all values are used).
The addresses are then sorted numerically, and the num_nodes smallest values are chosen.
BiodiversityObservationNetworks.MoransI Type
MoransI <: SpatialBalanceMetricComputes Moran's I on the inclusion indicator variable.
Description
Calculates spatial autocorrelation of the sample indicator
BiodiversityObservationNetworks.MultivariateEnvironmentalSimilarity Type
MultivariateEnvironmentalSimilarityMultivariate Environmental Similarity Surface (MESS). For each cell, compute the minimum over features of a per-feature similarity score derived from the ECDF of the training distribution, following the standard MESS definition.
sourceBiodiversityObservationNetworks.Pivotal Type
Pivotal <: BONSamplerImplements the Local Pivotal Method (LPM).
Fields
num_nodes::Int: The number of sites to select.
Description
Iteratively pairs nearby units and updates their inclusion probabilities so that, locally, one unit tends toward selection while the other tends toward non-selection. Repeating this over the domain produces a sample that is more spatially balanced than simple random sampling, while respecting per-unit inclusion probabilities when provided.
High-level algorithm:
Select an unfinished unit
i; then choose its nearest unfinished neighborj.If
πᵢ + πⱼ < 1, move probability mass so one unit goes to 0 and the other toπᵢ+πⱼ.Otherwise (if
πᵢ + πⱼ ≥ 1), move probability mass so one unit is selected and the other retains the leftover probabilityπᵢ + πⱼ - 1.Repeat until all are complete.
References
- Grafström, A. (2012).
BiodiversityObservationNetworks.PolygonDomain Type
PolygonDomain{T} <: AbstractDomainA domain defined by a vector geometry (polygon).
Fields
data::T: The underlying geometry object.
BiodiversityObservationNetworks.RasterDomain Type
RasterDomain{T, P} <: AbstractDomainA wrapper around a raster-like object (Matrix or SDMLayer) that maintains a "pool" of valid sampling indices.
Fields
data::T: The underlying raster data (e.g.,MatrixorSDMLayer).pool::P: A collection of valid indices that can be sampled.
BiodiversityObservationNetworks.RasterStack Type
RasterStack{T} <: AbstractDomainA collection of aligned RasterDomains, used when sampling requires multivariate features.
Fields
rasters::Vector{<:RasterDomain{<:T}}: The stack of layers.pool: The intersection of valid pools from all layers.
BiodiversityObservationNetworks.SimpleRandom Type
SimpleRandom <: BONSamplerImplements simple random sampling (SRS) and weighted random sampling.
Fields
num_nodes::Int: The number of sites to select.
Description
Selects num_nodes locations from the domain uniformly at random without replacement. If an inclusion probability surface is provided, it performs weighted random sampling without replacement, where the weight of each candidate cell is proportional to its inclusion probability.
Notes
While computationally efficient, Simple Random Sampling does not guarantee spatial balance and may result in clustering of sampling points.
sourceBiodiversityObservationNetworks.SpatiallyCorrelatedPoisson Type
SpatiallyCorrelatedPoisson <: BONSamplerImplements Spatially Correlated Poisson Sampling (SCPS).
Fields
num_nodes::Int: The number of sites to select.
Description
Iterates through units, selecting them based on inclusion probabilities, and dynamically adjusting the probabilities of neighboring units to maintain spatial balance.
References
- Grafström, A. (2012). Spatially correlated Poisson sampling.
BiodiversityObservationNetworks.SpatiallyStratified Type
SpatiallyStratifiedSpatiallyStratified performs stratified random sampling over discrete categories present in the domain. Each pool element belongs to a stratum given by domain[x]. The number of draws allocated to each stratum is proportional to the stratum size (via the multinomial distribution), and units are then sampled without replacement from each stratum.
BiodiversityObservationNetworks.VoronoiVariance Type
VoronoiVarianceThe VoronoiVariance method for characterizing the spatial balance of a sample is based on the initial method proposed by (Stevens and Olsen, 2022), and then extended by (Grafström, 2025).
For a given BiodiversityObservationNetwork bon, the Voronoi tesselation splits the plane into a series of polygons, where the i-th polygon consists of all points in the plane whose nearest node in bon is the i-th node.
These polygons can then be used to assess the spatial balance of a sample.
In an ideally balanced sample, the sum of the inclusion probabilities across each polygon i would equal 1, because in expectation exactly one unit would be sampled in that region.
If we define i, i.e.
then we can assess the spatial balance of a sample by measuring the distance of B, defined as
to measure spatial balance, where smaller values indicate better spatial balance.
sourceBiodiversityObservationNetworks.extent Method
extent(p::PolygonDomain{T<:SimpleSDMPolygons.AbstractGeometry})BiodiversityObservationNetworks.jensenshannon Method
jensenshannonThe Jensen-Shannon Divergence is a method for measuring the distance between two probability distributions.
This method provides a comparison between the distribution of environmental variables in set of SDMLayers, layers, to the values of those variables at the sites within a BiodiversityObservationNetwork bon.
BiodiversityObservationNetworks.rarity Method
rarity(::DistanceToAnalogNode, bon, layers; pca=false)For each cell, compute the distance in z-scored feature space to the nearest selected BON node in layers. Optionally apply a shared PCA transform first.
BiodiversityObservationNetworks.rarity Method
rarity(::WithinRange, bon, layers)Boolean rarity surface indicating whether each cell lies within the hyper- rectangle spanned by the per-feature minima and maxima of the BON nodes.
sourceBiodiversityObservationNetworks.spatialbalance Method
spatialbalance(::MoransI, raster::SDMLayer, bon::BiodiversityObservationNetwork)BiodiversityObservationNetworks.spatialbalance Method
spatialbalance(::Type{VoronoiVariance}, bon::BiodiversityObservationNetwork, geom)BiodiversityObservationNetworks.spatialbalance Method
spatialbalance(metric::SpatialBalanceMetric, bon, domain)Calculate a specific spatial balance metric for a given network and domain.
sourceBiodiversityObservationNetworks.voronoi Method
voronoi(bon, domain)Construct Voronoi polygons for the nodes in a BiodiversityObservationNetwork within the given domain. The domain is coerced to a PolygonDomain when needed. Output polygons are clipped to the domain extent.
Private API
BiodiversityObservationNetworks.RarityMetric Type
RarityMetricAbstract type encompassing all methods for computing environmental rarity.
sourceBiodiversityObservationNetworks._2d_bas Method
_2d_bas(sampler, domain)2D BAS using Halton bases [2,3] to generate spatially spread candidate cells, accepting those that fall on unmasked locations until num_nodes are selected.
BiodiversityObservationNetworks._3d_bas Method
_3d_bas(sampler, domain, inclusion)3D BAS using Halton bases [2,3,5]. A candidate (i,j,z) is accepted if the cell is unmasked and z < inclusion[i,j].
BiodiversityObservationNetworks._above_one_update! Method
_above_one_update!(inclusion, pool, i, j, complete_flags, inclusion_flags)Apply the LPM update when the paired units have πᵢ + πⱼ ≥ 1.
One of the two units is set to 1 (selected) and the other is reduced to πᵢ + πⱼ - 1. The unit whose probability reaches 1 is marked both as included (inclusion_flags) and complete (complete_flags).
BiodiversityObservationNetworks._aggregate_pool Method
_aggregate_pool(domains)Compute the intersection of valid sampling pools across multiple domains.
Arguments
domains: An iterable collection of domain objects (e.g., a vector ofRasterDomain). Each element must have apoolfield containing a boolean mask.
Returns
- A
BitArrayrepresenting the intersection of all pools. A cell is considered valid (true) only if it is valid in all provided domains.
Description
This internal utility is primarily used when constructing a RasterStack. It ensures that sampling only occurs in locations that are valid across every layer in the stack (e.g., avoiding NaNs, missing data, or masked areas present in any single layer).
BiodiversityObservationNetworks._apply_update_rule! Method
_apply_update_rule!(inclusion, pool, i, j, inclusion_flags, complete_flags)Dispatch to the appropriate LPM update based on whether πᵢ + πⱼ is below or at/above one.
BiodiversityObservationNetworks._below_one_update! Method
_below_one_update!(inclusion, pool, i, j, complete_flags)Apply the LPM update when the paired units have πᵢ + πⱼ < 1.
One of the two units is set to 0 (not selected) and the other is increased to πᵢ + πⱼ. The unit whose probability reaches 0 is marked complete.
BiodiversityObservationNetworks._cube_flight_phase Method
_cube_flight_phase(πₖ, x)Run the flight phase of the cube method.
πₖ are current inclusion probabilities; x (auxiliary matrix) is augmented with a first row of πₖ' so sample size fixed. The method repeatedly finds a direction in the null space of the constraint matrix and pushes a small subset of probabilities to 0 or 1 while preserving balances in expectation.
BiodiversityObservationNetworks._cube_landing_phase Method
_cube_landing_phase(pikstar, πₖ, x)Run the landing phase if some probabilities are still fractional after flight. Formulate a small linear program over the fractional units to select a 0/1 sample whose auxiliary totals match pikstar in expectation with minimal cost C(s) (per Deville & Tillé, 2004).
BiodiversityObservationNetworks._get_address_length Method
_get_address_lengthReturns the number of digits in a GeneralizedRandomTessellatedStratified address for a specific geometry, computed based on the raster dimensions.
BiodiversityObservationNetworks._h Method
_h(K)Entropy-like diversity score based on the log-determinant of the kernel matrix K. Larger values encourage selecting points that are diverse with respect to previously chosen sites.
BiodiversityObservationNetworks._matérn Method
_matérn(d, ρ, ν)Matérn covariance kernel evaluated at distance d, range ρ, smoothness ν. Normalized so that _matérn(0, ρ, ν) == 1.
BiodiversityObservationNetworks._pick_nodes Method
_pick_nodes(sampler, raster, addresses)BiodiversityObservationNetworks._quadrant_fill! Method
_quadrant_fill!(mat)Takes a matrix mat and splits it into quadrants randomly labeled one through four.
BiodiversityObservationNetworks._quadrant_split! Method
_quadrant_split!(mat, grid_size)Splits a matrix mat into nested quadrants, where the side-length of a submatrix to be split into quadrants is given by grid_size.
BiodiversityObservationNetworks._redistribute_masked_weight! Method
_redistribute_masked_weight!(domain, inclusion::RasterDomain{<:Matrix})Matrix-backed variant of masked weight redistribution.
sourceBiodiversityObservationNetworks._redistribute_masked_weight! Method
_redistribute_masked_weight!(domain, inclusion::RasterDomain{<:SDMLayer})Redistribute any probability mass assigned to masked-out cells uniformly across valid indices in domain. Mutates inclusion in-place.
BiodiversityObservationNetworks._rescale_node Method
_rescale_node(domain, x::Real, y::Real)Map unit-cube Halton coordinates (x, y) to integer raster indices in domain.
BiodiversityObservationNetworks._sample Method
_sample(sampler::BalancedAcceptance, domain; inclusion=nothing)Generate a spatially balanced sample using BAS. With inclusion, perform 3D BAS to respect per-cell probabilities; otherwise perform 2D BAS over the mask.
BiodiversityObservationNetworks._sample Method
_sample(sampler::CubeSampling, domain; inclusion=nothing)Draw a sample using the cube method, balancing means of auxiliary variables (getfeatures(domain)) while achieving the desired sample size in expectation.
Arguments:
sampler.num_nodes: desired number of selected sitesdomain: sampling domain; must supportgetpool(domain)andgetfeatures(domain)inclusion: optional vector/array of inclusion probabilities indexed by pool items
Returns a BiodiversityObservationNetwork.
BiodiversityObservationNetworks._sample Method
_sample(sampler::Pivotal, domain; inclusion=nothing)Draw a spatially balanced sample using the Local Pivotal Method.
Arguments:
sampler.num_nodes: desired number of selected sites (also used to derive a uniform inclusion vector wheninclusionis not provided)domain: sampling domain; must supportgetpool(domain)andgetnearestneighbors(domain)inclusion: optional vector/array of inclusion probabilities indexed by pool items; ifnothing, uniform probabilities are computed viaget_uniform_inclusion.
Returns a BiodiversityObservationNetwork with nodes whose final inclusion indicators are 1 after the LPM iterations.
BiodiversityObservationNetworks._sample Method
_sample(sampler::SpatiallyCorrelatedPoisson, domain, inclusion_probs)Perform Spatially Correlated Poisson sampling following Grafström (2012).
Arguments
sampler::SpatiallyCorrelatedPoisson: The sampling strategy object.domain: The spatial domain (supportssize(domain)and distance calculation).inclusion_probs: Initial inclusion probabilities for each unit. Defaults to uniform:(number_of_nodes / N)for all units.
Returns
- A
BiodiversityObservationNetwork.jlcontaining units included in the sample.
Example Usage
sample(SpatiallyCorrelatedPoisson(), zeros(30,20))
BiodiversityObservationNetworks._sample Method
_sample(sampler::SpatiallyStratified, domain; inclusion=nothing)Draw a stratified random sample across unique values in domain.
Arguments:
sampler.num_nodes: total number of units to sample across all stratadomain: sampling domain; must supportgetpool(domain)and indexingdomain[x]
Returns a BiodiversityObservationNetwork.
BiodiversityObservationNetworks._sort_features_by_mahalanobis Method
_sort_features_by_mahalanobis(features, inclusion)Order units to stabilize the flight phase by spreading early decisions across feature space. Units are sorted by Mahalanobis distance from the inclusion- weighted mean feature vector.
sourceBiodiversityObservationNetworks._standardize Method
_standardizeStandardizes the values of a matrix of predictors across the entire population Xfull, and a set of predictors associated with the sampled sites, Xsampled by scaling each predictor to [0,1].
Xsampled is standardized based on the minimum and maximum values of each predictor across the population, so both matrices a return on the same scale.
Arguments:
Xfull: annxdmatrix, wherenis the size of the population, anddis the number of predictorsXsampled: anmxdmatrix, wherem<nis the size of the sample
BiodiversityObservationNetworks._update_psi Method
_update_psi(Ψ, B)Given current working vector Ψ and constraint block B, compute a feasible update along a null-space direction u by maximizing step sizes λ₁, λ₂ that keep probabilities within [0,1].
BiodiversityObservationNetworks.convert_inclusion Method
convert_inclusion(sampler, domain, inclusion; kwargs...)Coerce an inclusion specification to a representation compatible with domain. Also ensures totals sum to sampler.num_nodes (renormalizing if needed) and redistributes probability assigned to masked-out cells back to valid cells. Returns nothing when inclusion is nothing.
BiodiversityObservationNetworks.convert_mask Method
convert_mask(domain::RasterDomain, mask::AbstractMatrix; kwargs...)Convert a boolean matrix mask to a RasterDomain-aligned mask.
BiodiversityObservationNetworks.convert_mask Method
convert_mask(domain::RasterDomain, mask::PolygonDomain; kwargs...)Rasterize a polygon mask into the grid of domain and return a RasterDomain-aligned mask.
BiodiversityObservationNetworks.convert_mask Method
convert_mask(domain::RasterDomain, mask::SDMLayer; kwargs...)Convert an SDMLayer to a RasterDomain mask with aligned indices.
BiodiversityObservationNetworks.convert_mask Method
convert_mask(domain::RasterDomain, mask::SimpleSDMPolygons.AbstractGeometry)Coerce a polygon geometry to a RasterDomain mask by rasterizing the polygon.
BiodiversityObservationNetworks.convert_mask Method
convert_mask(domain::RasterDomain{<:SDMLayer}, mask::RasterDomain{<:SDMLayer}; kwargs...)Validate size, extent, and CRS when both domain and mask are SDMLayer-backed.
sourceBiodiversityObservationNetworks.convert_mask Method
convert_mask(domain::RasterDomain{T}, mask::RasterDomain{<:Matrix}; kwargs...) where TValidate size when the mask is matrix-backed.
sourceBiodiversityObservationNetworks.get_uniform_inclusion Method
get_uniform_inclusion(sampler, bon::BiodiversityObservationNetwork)Construct a uniform inclusion vector for a BON-like domain.
sourceBiodiversityObservationNetworks.get_uniform_inclusion Method
get_uniform_inclusion(sampler, domain)Construct a uniform inclusion surface for domain such that the sum of inclusion probabilities equals sampler.num_nodes.
Returns a RasterDomain when given a raster-like domain.
BiodiversityObservationNetworks.getcoordinates Method
getcoordinates(domain)Retrieve the spatial coordinates of all valid (unmasked) sampling locations in the domain.
Arguments
domain: ARasterDomainor aRasterStack.
Returns
- A
2 x NMatrix{Float32}, whereNis the number of valid locations in the pool,
where each column is a coordinate in the valid pool of locations.
Description
Returns a matrix of coordinates corresponding to the valid sampling pool.
For Matrix-backed domains, coordinates are the integer column (x) and row (y) indices.
For SDMLayer-backed domains, coordinates are the projected spatial coordinates (e.g., Longitude/Latitude) derived from the layer's geotransform.
For RasterStacks, coordinates are derived from the first layer in the stack (assuming all layers share the same grid).
BiodiversityObservationNetworks.getfeatures Method
getfeatures(domain)Return a matrix of auxiliary variables (features) for valid pixels in the domain. Rows are features, columns are pixels.
sourceBiodiversityObservationNetworks.getpool Method
getpool(domain)Return the collection of valid (unmasked) indices for the given domain.
sourceBiodiversityObservationNetworks.mask! Method
mask!(domain, mask)Apply mask to domain in-place. Overloads handle RasterDomains backed by SDMLayer or Matrix, and propagate to all rasters in a RasterStack. Polygon masks are supported for SDMLayer-backed rasters.
BiodiversityObservationNetworks.normalize_inclusion! Method
normalize_inclusion!(sampler, inclusion)Scale inclusion so that its total mass equals sampler.num_nodes. Overloads exist for SDMLayer-backed rasters, matrix-backed rasters, and vectors. Mutates inclusion in-place.
BiodiversityObservationNetworks.tilt Method
tilt(layer, α)Performs logistic-exponential tilting on the on a layer with scaling factor α. This is useful for adjusting inclusion probabilities to scale more toward (α > 1) or away from (α < 1) extreme values.
sourceBiodiversityObservationNetworks.to_domain Method
to_domain(x; kwargs...)Coerce an input object into a valid internal domain representation (e.g., RasterDomain, RasterStack).
Arguments
x: The input object to convert. Can be a Matrix, SDMLayer, Vector of layers, Polygon, or an existing domain/network.kwargs...: Helper arguments for specific conversions (see below).
Methods
1. Matrices and SDMLayers: Wraps the input in a RasterDomain. For SDMLayer inputs, the existing valid indices (non-NaN/masked) are preserved in the pool.
to_domain(mat::AbstractMatrix)->RasterDomainto_domain(layer::SDMLayer)->RasterDomain
2. Collections of layers (Stacks): Converts a vector of inputs into a RasterStack. The sampling pool is aggregated as the intersection of valid pixels across all layers.
to_domain(layers::Vector{<:SDMLayer})->RasterStackto_domain(mats::Vector{<:AbstractMatrix})->RasterStack
3. Polygons (Rasterization): Converts a vector geometry (Polygon) into a binary RasterDomain by rasterizing it.
to_domain(poly::SimpleSDMPolygons.AbstractGeometry; grid_size=(100,100))->RasterDomainto_domain(poly::PolygonDomain; grid_size=(100,100))->RasterDomain
4. Identity: Returns the input unchanged if it is already a valid domain or network type.
to_domain(rd::RasterDomain)->RasterDomainto_domain(rs::RasterStack)->RasterStackto_domain(bon::BiodiversityObservationNetwork)->BiodiversityObservationNetwork
BiodiversityObservationNetworks.unique_permutations Method
unique_permutations(x::T, prefix = T()) where {T}Generate all unique permutations for a multiset x without repetition of duplicates. Based on StackOverflow (https://stackoverflow.com/questions/65051953/julia-generate-all-non-repeating-permutations-in-set-with-duplicates).