Selecting environmentally unique locations
For some applications, we want to sample a set of locations that cover a broad range of values in environment space. Another way to rephrase this problem is to say we want to find the set of points with the least covariance in their environmental values.
To do this, we use a BONRefiner
called Uniqueness
. We'll start by loading the required packages.
using BiodiversityObservationNetworks
using SpeciesDistributionToolkit
using StatsBase
using NeutralLandscapes
using CairoMakie
┌ Error: Error during loading of extension SDMToolkitExt of BiodiversityObservationNetworks, use `Base.retry_load_extensions()` to retry.
│ exception =
│ 1-element ExceptionStack:
│ ArgumentError: Package SDMToolkitExt [75f002dd-b8c9-5168-9854-88ac03dd3cdb] is required but does not seem to be installed:
│ - Run `Pkg.instantiate()` to install all recorded dependencies.
│
│ Stacktrace:
│ [1] _require(pkg::Base.PkgId, env::Nothing)
│ @ Base ./loading.jl:1774
│ [2] _require_prelocked(uuidkey::Base.PkgId, env::Nothing)
│ @ Base ./loading.jl:1660
│ [3] _require_prelocked(uuidkey::Base.PkgId)
│ @ Base ./loading.jl:1658
│ [4] run_extension_callbacks(extid::Base.ExtensionId)
│ @ Base ./loading.jl:1255
│ [5] run_extension_callbacks(pkgid::Base.PkgId)
│ @ Base ./loading.jl:1290
│ [6] run_package_callbacks(modkey::Base.PkgId)
│ @ Base ./loading.jl:1124
│ [7] _require_prelocked(uuidkey::Base.PkgId, env::String)
│ @ Base ./loading.jl:1667
│ [8] macro expansion
│ @ ./loading.jl:1648 [inlined]
│ [9] macro expansion
│ @ ./lock.jl:267 [inlined]
│ [10] require(into::Module, mod::Symbol)
│ @ Base ./loading.jl:1611
│ [11] eval
│ @ ./boot.jl:370 [inlined]
│ [12] #17
│ @ ~/.julia/packages/Documenter/bYYzK/src/Expanders.jl:629 [inlined]
│ [13] cd(f::Documenter.Expanders.var"#17#19"{Module, Expr}, dir::String)
│ @ Base.Filesystem ./file.jl:112
│ [14] (::Documenter.Expanders.var"#16#18"{Documenter.Documents.Page, Module, Expr})()
│ @ Documenter.Expanders ~/.julia/packages/Documenter/bYYzK/src/Expanders.jl:628
│ [15] (::IOCapture.var"#4#7"{DataType, Documenter.Expanders.var"#16#18"{Documenter.Documents.Page, Module, Expr}, IOContext{Base.PipeEndpoint}, IOContext{Base.PipeEndpoint}, Base.PipeEndpoint, Base.PipeEndpoint})()
│ @ IOCapture ~/.julia/packages/IOCapture/Rzdxd/src/IOCapture.jl:161
│ [16] with_logstate(f::Function, logstate::Any)
│ @ Base.CoreLogging ./logging.jl:514
│ [17] with_logger
│ @ ./logging.jl:626 [inlined]
│ [18] capture(f::Documenter.Expanders.var"#16#18"{Documenter.Documents.Page, Module, Expr}; rethrow::Type, color::Bool, passthrough::Bool, capture_buffer::IOBuffer)
│ @ IOCapture ~/.julia/packages/IOCapture/Rzdxd/src/IOCapture.jl:158
│ [19] runner(#unused#::Type{Documenter.Expanders.ExampleBlocks}, x::Markdown.Code, page::Documenter.Documents.Page, doc::Documenter.Documents.Document)
│ @ Documenter.Expanders ~/.julia/packages/Documenter/bYYzK/src/Expanders.jl:627
│ [20] dispatch(::Type{Documenter.Expanders.ExpanderPipeline}, ::Markdown.Code, ::Vararg{Any})
│ @ Documenter.Utilities.Selectors ~/.julia/packages/Documenter/bYYzK/src/Utilities/Selectors.jl:170
│ [21] expand(doc::Documenter.Documents.Document)
│ @ Documenter.Expanders ~/.julia/packages/Documenter/bYYzK/src/Expanders.jl:42
│ [22] runner(#unused#::Type{Documenter.Builder.ExpandTemplates}, doc::Documenter.Documents.Document)
│ @ Documenter.Builder ~/.julia/packages/Documenter/bYYzK/src/Builder.jl:226
│ [23] dispatch(#unused#::Type{Documenter.Builder.DocumentPipeline}, x::Documenter.Documents.Document)
│ @ Documenter.Utilities.Selectors ~/.julia/packages/Documenter/bYYzK/src/Utilities/Selectors.jl:170
│ [24] #2
│ @ ~/.julia/packages/Documenter/bYYzK/src/Documenter.jl:273 [inlined]
│ [25] cd(f::Documenter.var"#2#3"{Documenter.Documents.Document}, dir::String)
│ @ Base.Filesystem ./file.jl:112
│ [26] #makedocs#1
│ @ ~/.julia/packages/Documenter/bYYzK/src/Documenter.jl:272 [inlined]
│ [27] top-level scope
│ @ ~/work/BiodiversityObservationNetworks.jl/BiodiversityObservationNetworks.jl/docs/make.jl:10
│ [28] include(mod::Module, _path::String)
│ @ Base ./Base.jl:457
│ [29] exec_options(opts::Base.JLOptions)
│ @ Base ./client.jl:307
│ [30] _start()
│ @ Base ./client.jl:522
└ @ Base loading.jl:1261
[ Info: Loading NeutralLandscapes support for SimpleSDMLayers.jl...
Consider setting your SDMLAYERS_PATH
When accessing data using SimpleSDMDatasets.jl
, it is best to set the SDM_LAYERSPATH
environmental variable to tell SimpleSDMDatasets.jl
where to download data. This can be done by setting ENV["SDMLAYERS_PATH"] = "/home/user/Data/"
or similar in the ~/.julia/etc/julia/startup.jl
file. (Note this will be different depending on where julia
is installed.)
bbox = (left=-83.0, bottom=46.4, right=-55.2, top=63.7);
temp, precip, elevation =
convert(Float32, SimpleSDMPredictor(RasterData(WorldClim2, AverageTemperature); bbox...)),
convert(Float32, SimpleSDMPredictor(RasterData(WorldClim2, Precipitation); bbox...)),
convert(Float32, SimpleSDMPredictor(RasterData(WorldClim2, Elevation); bbox...));
(SDM response → 105×167 grid with 11478 Float32-valued cells, SDM response → 105×167 grid with 11478 Float32-valued cells, SDM response → 105×167 grid with 11478 Float32-valued cells)
Now we'll use the stack
function to combine our four environmental layers into a single, 3-dimensional array, which we'll pass to our Uniqueness
refiner.
```@example 1 layers = BiodiversityObservationNetworks.stack([temp,precip,elevation]);
this requires NeutralLandscapes v0.1.2
```julia
uncert = rand(MidpointDisplacement(0.8), size(temp), mask=temp);
heatmap(uncert)
Now we'll get a set of candidate points from a BalancedAcceptance seeder that has no bias toward higher uncertainty values.
candpts, uncert = uncert |> seed(BalancedAcceptance(numpoints=100, α=0.0));
(CartesianIndex[CartesianIndex(40, 143), CartesianIndex(86, 59), CartesianIndex(4, 40), CartesianIndex(56, 96), CartesianIndex(17, 65), CartesianIndex(69, 121), CartesianIndex(63, 46), CartesianIndex(37, 102), CartesianIndex(24, 15), CartesianIndex(50, 127) … CartesianIndex(60, 28), CartesianIndex(34, 84), CartesianIndex(57, 127), CartesianIndex(30, 34), CartesianIndex(70, 53), CartesianIndex(11, 5), CartesianIndex(37, 117), CartesianIndex(24, 80), CartesianIndex(29, 67), CartesianIndex(68, 86)], [0.251900323340195 0.27347957539914114 … NaN NaN; 0.24274322050612135 0.2515882692635109 … NaN NaN; … ; NaN NaN … NaN NaN; NaN NaN … NaN NaN])
Now we'll refine
our 100
candidate points down to the 30 most environmentally unique.
```@example 1 finalpts, uncert = refine(candpts, Uniqueness(;numpoints=30, layers=layers), uncert)
=
heatmap(uncert) scatter!([p[2] for p in candpts], [p[1] for p in candpts], fa=0.0, msc=:white, label="Candidate Points") scatter!([p[2] for p in finalpts], [p[1] for p in finalpts], c=:dodgerblue, msc=:white, label="Selected Points")=# ```