diff --git a/previews/PR66/index.html b/previews/PR66/index.html index 8a98268..31f742c 100644 --- a/previews/PR66/index.html +++ b/previews/PR66/index.html @@ -533,19 +533,19 @@

High-level types

BONSampler
 

A union of the abstract types BONSeeder and BONRefiner. Both types return a tuple with the coordinates as a vector of CartesianIndex, and the weight matrix as a Matrix of AbstractFloat, in that order.

-

source

+

source

# BiodiversityObservationNetworks.BONSeederType.

abstract type BONSeeder end
 

A BONSeeder is an algorithm for proposing sampling locations using a raster of weights, represented as a matrix, in each cell.

-

source

+

source

# BiodiversityObservationNetworks.BONRefinerType.

abstract type BONRefiner end
 

A BONRefiner is an algorithm for proposing sampling locations by refining a set of candidate points to a smaller set of 'best' points.

-

source

+

source

Seeder and refiner functions

@@ -554,7 +554,7 @@

Seeder and refiner functions

seed(sampler::ST)
 

Produces a set of candidate sampling locations in a vector coords of length numsites from a raster using sampler, where sampler is a BONSeeder.

-

source

+

source

# BiodiversityObservationNetworks.seed!Function.

seed!(coords::Vector{CartesianIndex}, sampler::ST, uncertainty::Matrix{T})
@@ -563,27 +563,27 @@ 

Seeder and refiner functions

  • Seeder's work on rasters, refiners work on set of coordinates.
-

source

+

source

# BiodiversityObservationNetworks.refineFunction.

refine(pool::Vector{CartesianIndex}, sampler::ST)
 

Refines a set of candidate sampling locations and returns a vector coords of length numsites from a vector of coordinates pool using sampler, where sampler is a BONRefiner.

-

source

+

source

refine(sampler::BONRefiner)
 

Returns a curried function of refine

-

source

+

source

# BiodiversityObservationNetworks.refine!Function.

refine!(cooords::Vector{CartesianIndex}, pool::Vector{CartesianIndex}, sampler::ST)
 

Refines a set of candidate sampling locations in the preallocated vector coords from a vector of coordinates pool using sampler, where sampler is a BONRefiner.

-

source

+

source

refine!(cooords::Vector{CartesianIndex}, pool::Vector{CartesianIndex}, sampler::ST)
 

The curried version of refine!, which returns a function that acts on the input coordinate pool passed to the curried function (p below).

-

source

+

source

Seeder algorithms

@@ -592,7 +592,7 @@

Seeder algorithms

BalancedAcceptance
 

A BONSeeder that uses Balanced-Acceptance Sampling (Van-dem-Bates et al. 2017 https://doi.org/10.1111/2041-210X.13003)

-

source

+

source

Refiner algorithms

@@ -602,13 +602,13 @@

Refiner algorithms

...

numsites, an Integer (def. 50), specifying the number of points to use.

-

source

+

source

# BiodiversityObservationNetworks.UniquenessType.

Uniqueness
 

A BONRefiner

-

source

+

source

Helper functions

@@ -622,13 +622,13 @@

Helper functions

This function turns a matrix A (storing measurement values) into pixel-wise entropy values, stored in a matrix U (that is previously allocated).

Pixel-wise entropy is determined by measuring the empirical probability of randomly picking a value in the matrix that is either lower or higher than the pixel value. The entropy of both these probabilities are calculated using the -p×log(2,p) formula. The entropy of the pixel is the sum of the two entropies, so that it is close to 1 for values close to the median, and close to 0 for values close to the extreme of the distribution.

-

source

+

source

# BiodiversityObservationNetworks.entropizeFunction.

entropize(A::Matrix{Number})
 

Allocation version of entropize!.

-

source

+

source

diff --git a/previews/PR66/search/search_index.json b/previews/PR66/search/search_index.json index 7ed17d0..7474676 100644 --- a/previews/PR66/search/search_index.json +++ b/previews/PR66/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Home","text":""},{"location":"#biodiversityobservationnetworksjl","title":"BiodiversityObservationNetworks.jl","text":"

The purpose of this package is to provide a high-level, extensible, modular interface to the selection of sampling point for biodiversity processes in space. It is based around a collection of types representing point selection algorithms, used to select the most informative sampling points based on raster data. Specifically, many algorithms work from a layer indicating entropy of a model based prediction at each location.

This package is in development

The BiodiversityObservationNetworks.jl package is currently under development. The API is not expected to change a lot, but it may change in order to facilitate the integration of new features.

"},{"location":"#high-level-types","title":"High-level types","text":"

# BiodiversityObservationNetworks.BONSampler \u2014 Type.

BONSampler\n

A union of the abstract types BONSeeder and BONRefiner. Both types return a tuple with the coordinates as a vector of CartesianIndex, and the weight matrix as a Matrix of AbstractFloat, in that order.

source

# BiodiversityObservationNetworks.BONSeeder \u2014 Type.

abstract type BONSeeder end\n

A BONSeeder is an algorithm for proposing sampling locations using a raster of weights, represented as a matrix, in each cell.

source

# BiodiversityObservationNetworks.BONRefiner \u2014 Type.

abstract type BONRefiner end\n

A BONRefiner is an algorithm for proposing sampling locations by refining a set of candidate points to a smaller set of 'best' points.

source

"},{"location":"#seeder-and-refiner-functions","title":"Seeder and refiner functions","text":"

# BiodiversityObservationNetworks.seed \u2014 Function.

seed(sampler::ST)\n

Produces a set of candidate sampling locations in a vector coords of length numsites from a raster using sampler, where sampler is a BONSeeder.

source

# BiodiversityObservationNetworks.seed! \u2014 Function.

seed!(coords::Vector{CartesianIndex}, sampler::ST, uncertainty::Matrix{T})\n

Puts a set of candidate sampling locations in the preallocated vector coords from a raster uncertainty using sampler, where sampler is a BONSeeder.

source

# BiodiversityObservationNetworks.refine \u2014 Function.

refine(pool::Vector{CartesianIndex}, sampler::ST)\n

Refines a set of candidate sampling locations and returns a vector coords of length numsites from a vector of coordinates pool using sampler, where sampler is a BONRefiner.

source

refine(sampler::BONRefiner)\n

Returns a curried function of refine

source

# BiodiversityObservationNetworks.refine! \u2014 Function.

refine!(cooords::Vector{CartesianIndex}, pool::Vector{CartesianIndex}, sampler::ST)\n

Refines a set of candidate sampling locations in the preallocated vector coords from a vector of coordinates pool using sampler, where sampler is a BONRefiner.

source

refine!(cooords::Vector{CartesianIndex}, pool::Vector{CartesianIndex}, sampler::ST)\n

The curried version of refine!, which returns a function that acts on the input coordinate pool passed to the curried function (p below).

source

"},{"location":"#seeder-algorithms","title":"Seeder algorithms","text":"

# BiodiversityObservationNetworks.BalancedAcceptance \u2014 Type.

BalancedAcceptance\n

A BONSeeder that uses Balanced-Acceptance Sampling (Van-dem-Bates et al. 2017 https://doi.org/10.1111/2041-210X.13003)

source

"},{"location":"#refiner-algorithms","title":"Refiner algorithms","text":"

# BiodiversityObservationNetworks.AdaptiveSpatial \u2014 Type.

AdaptiveSpatial\n

...

numsites, an Integer (def. 50), specifying the number of points to use.

source

# BiodiversityObservationNetworks.Uniqueness \u2014 Type.

Uniqueness\n

A BONRefiner

source

"},{"location":"#helper-functions","title":"Helper functions","text":"

Missing docstring.

Missing docstring for squish. Check Documenter's build log for details.

# BiodiversityObservationNetworks.entropize! \u2014 Function.

entropize!(U::Matrix{AbstractFloat}, A::Matrix{Number})\n

This function turns a matrix A (storing measurement values) into pixel-wise entropy values, stored in a matrix U (that is previously allocated).

Pixel-wise entropy is determined by measuring the empirical probability of randomly picking a value in the matrix that is either lower or higher than the pixel value. The entropy of both these probabilities are calculated using the -p\u00d7log(2,p) formula. The entropy of the pixel is the sum of the two entropies, so that it is close to 1 for values close to the median, and close to 0 for values close to the extreme of the distribution.

source

# BiodiversityObservationNetworks.entropize \u2014 Function.

entropize(A::Matrix{Number})\n

Allocation version of entropize!.

source

"},{"location":"bibliography/","title":"Bibliography","text":""},{"location":"bibliography/#references","title":"References","text":""},{"location":"vignettes/entropize/","title":"Entropize","text":""},{"location":"vignettes/entropize/#getting-the-entropy-matrix","title":"Getting the entropy matrix","text":"

For some applications, we want to place points to capture the maximum amount of information, which is to say that we want to sample a balance of entropy values, as opposed to absolute values. In this vignette, we will walk through an example using the entropize function to convert raw data to entropy values.

using BiodiversityObservationNetworks\nusing NeutralLandscapes\nusing CairoMakie\n

Entropy is problem-specific

The solution presented in this vignette is a least-assumption solution based on the empirical values given in a matrix of measurements. In a lot of situations, this is not the entropy that you want. For example, if your pixels are storing probabilities of Bernoulli events, you can directly use the entropy of the events in the entropy matrix.

We start by generating a random matrix of measurements:

measurements = rand(MidpointDisplacement(), (200, 200)) .* 100\nheatmap(measurements)\n

Using the entropize function will convert these values into entropy at the pixel scale:

@example 1 U = entropize(measurements) locations = seed(BalancedAcceptance(; numsites = 100, uncertainty=U))

"},{"location":"vignettes/overview/","title":"Overview","text":""},{"location":"vignettes/overview/#an-introduction-to-biodiversityobservationnetworks","title":"An introduction to BiodiversityObservationNetworks","text":"

In this vignette, we will walk through the basic functionalities of the package, by generating a random uncertainty matrix, and then using a seeder and a refiner to decide which locations should be sampled in order to gain more insights about the process generating this entropy.

using BiodiversityObservationNetworks\nusing NeutralLandscapes\nusing CairoMakie\n

In order to simplify the process, we will use the NeutralLandscapes package to generate a 100\u00d7100 pixels landscape, where each cell represents the entropy (or information content) in a unit we can sample:

U = rand(MidpointDisplacement(0.5), (100, 100))\nheatmap(U)\n

In practice, this uncertainty matrix is likely to be derived from an application of the hyper-parameters optimization step, which is detailed in other vignettes.

The first step of defining a series of locations to sample is to use a BONSeeder, which will generate a number of relatively coarse proposals that cover the entire landscape, and have a balanced distribution in space. We do so using the BalancedAcceptance sampler, which can be tweaked to capture more (or less) uncertainty. To start with, we will extract 200 candidate points, i.e. 200 possible locations which will then be refined.

candidates = seed(BalancedAcceptance(; numsites = 200));\n
200-element Vector{CartesianIndex}:\n CartesianIndex(19, 2)\n CartesianIndex(44, 18)\n CartesianIndex(4, 35)\n CartesianIndex(29, 7)\n CartesianIndex(16, 24)\n CartesianIndex(41, 41)\n CartesianIndex(10, 13)\n CartesianIndex(35, 30)\n CartesianIndex(23, 46)\n CartesianIndex(48, 4)\n \u22ee\n CartesianIndex(32, 34)\n CartesianIndex(20, 6)\n CartesianIndex(45, 23)\n CartesianIndex(4, 39)\n CartesianIndex(29, 12)\n CartesianIndex(17, 28)\n CartesianIndex(42, 45)\n CartesianIndex(11, 2)\n CartesianIndex(36, 19)\n

We can have a look at the first five points:

candidates[1:5]\n
5-element Vector{CartesianIndex}:\n CartesianIndex(19, 2)\n CartesianIndex(44, 18)\n CartesianIndex(4, 35)\n CartesianIndex(29, 7)\n CartesianIndex(16, 24)\n

The positions of locations to sample are given as a vector of CartesianIndex, which are coordinates in the uncertainty matrix. Once we have generated a candidate proposal, we can further refine it using a BONRefiner \u2013 in this case, AdaptiveSpatial, which performs adaptive spatial sampling (maximizing the distribution of entropy while minimizing spatial auto-correlation).

```@example 1 locations = refine(candidates, AdaptiveSpatial(; numsites = 50, uncertainty=U)) locations[1:5]

The reason we start from a candidate set of points is that some algorithms struggle with full landscapes, and work much better with a sub-sample of them. There is no hard rule (or no heuristic) to get a sense for how many points should be generated at the seeding step, and so experimentation is a must!\n\n\nThe previous code examples used a version of the `seed` and `refine` functions that is very useful if you want to change arguments between steps, or examine the content of the candidate pool of points. In addition to this syntax, both functions have a curried version that allows chaining them together using pipes (`|>`):\n\n\n```@example 1\nlocations =\n    seed(BalancedAcceptance(; numsites = 200)) |>\n    refine(AdaptiveSpatial(; numsites = 50, uncertainty=U))\n

This works because seed and refine have curried versions that can be used directly in a pipeline. Proposed sampling locations can then be overlayed onto the original uncertainty matrix:

@example 1 plt = heatmap(U) scatter!(plt, [x[1] for x in locations], [x[2] for x in locations]) current_figure()

"},{"location":"vignettes/uniqueness/","title":"Uniqueness.jl","text":""},{"location":"vignettes/uniqueness/#selecting-environmentally-unique-locations","title":"Selecting environmentally unique locations","text":"

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\nusing SpeciesDistributionToolkit\nusing StatsBase\nusing NeutralLandscapes\nusing CairoMakie\n
[ Info: Loading NeutralLandscapes support for SimpleSDMLayers.jl...\n

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.)

```@example 1 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...));

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.\n\n\n```@example 1\nlayers = BiodiversityObservationNetworks.stack([temp,precip,elevation]);\n

```@example 1 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.\n\n\n```julia\ncandpts = seed(BalancedAcceptance(numsites=100));\n

100-element Vector{CartesianIndex}:\n CartesianIndex(23, 15)\n CartesianIndex(48, 32)\n CartesianIndex(3, 49)\n CartesianIndex(28, 1)\n CartesianIndex(15, 18)\n CartesianIndex(40, 35)\n CartesianIndex(9, 7)\n CartesianIndex(34, 23)\n CartesianIndex(21, 40)\n CartesianIndex(46, 12)\n \u22ee\n CartesianIndex(30, 29)\n CartesianIndex(17, 46)\n CartesianIndex(42, 3)\n CartesianIndex(11, 20)\n CartesianIndex(36, 37)\n CartesianIndex(23, 9)\n CartesianIndex(48, 26)\n CartesianIndex(3, 42)\n CartesianIndex(28, 14)\n

Now we'll refine our 100 candidate points down to the 30 most environmentally unique.

@example 1 finalpts = refine(candpts, Uniqueness(;numsites=30, layers=layers)) heatmap(uncert) scatter!([p[1] for p in candpts], [p[2] for p in candpts], color=:white) scatter!([p[1] for p in finalpts], [p[2] for p in finalpts], color=:dodgerblue, msc=:white) current_figure()

"}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Home","text":""},{"location":"#biodiversityobservationnetworksjl","title":"BiodiversityObservationNetworks.jl","text":"

The purpose of this package is to provide a high-level, extensible, modular interface to the selection of sampling point for biodiversity processes in space. It is based around a collection of types representing point selection algorithms, used to select the most informative sampling points based on raster data. Specifically, many algorithms work from a layer indicating entropy of a model based prediction at each location.

This package is in development

The BiodiversityObservationNetworks.jl package is currently under development. The API is not expected to change a lot, but it may change in order to facilitate the integration of new features.

"},{"location":"#high-level-types","title":"High-level types","text":"

# BiodiversityObservationNetworks.BONSampler \u2014 Type.

BONSampler\n

A union of the abstract types BONSeeder and BONRefiner. Both types return a tuple with the coordinates as a vector of CartesianIndex, and the weight matrix as a Matrix of AbstractFloat, in that order.

source

# BiodiversityObservationNetworks.BONSeeder \u2014 Type.

abstract type BONSeeder end\n

A BONSeeder is an algorithm for proposing sampling locations using a raster of weights, represented as a matrix, in each cell.

source

# BiodiversityObservationNetworks.BONRefiner \u2014 Type.

abstract type BONRefiner end\n

A BONRefiner is an algorithm for proposing sampling locations by refining a set of candidate points to a smaller set of 'best' points.

source

"},{"location":"#seeder-and-refiner-functions","title":"Seeder and refiner functions","text":"

# BiodiversityObservationNetworks.seed \u2014 Function.

seed(sampler::ST)\n

Produces a set of candidate sampling locations in a vector coords of length numsites from a raster using sampler, where sampler is a BONSeeder.

source

# BiodiversityObservationNetworks.seed! \u2014 Function.

seed!(coords::Vector{CartesianIndex}, sampler::ST, uncertainty::Matrix{T})\n

Puts a set of candidate sampling locations in the preallocated vector coords from a raster uncertainty using sampler, where sampler is a BONSeeder.

source

# BiodiversityObservationNetworks.refine \u2014 Function.

refine(pool::Vector{CartesianIndex}, sampler::ST)\n

Refines a set of candidate sampling locations and returns a vector coords of length numsites from a vector of coordinates pool using sampler, where sampler is a BONRefiner.

source

refine(sampler::BONRefiner)\n

Returns a curried function of refine

source

# BiodiversityObservationNetworks.refine! \u2014 Function.

refine!(cooords::Vector{CartesianIndex}, pool::Vector{CartesianIndex}, sampler::ST)\n

Refines a set of candidate sampling locations in the preallocated vector coords from a vector of coordinates pool using sampler, where sampler is a BONRefiner.

source

refine!(cooords::Vector{CartesianIndex}, pool::Vector{CartesianIndex}, sampler::ST)\n

The curried version of refine!, which returns a function that acts on the input coordinate pool passed to the curried function (p below).

source

"},{"location":"#seeder-algorithms","title":"Seeder algorithms","text":"

# BiodiversityObservationNetworks.BalancedAcceptance \u2014 Type.

BalancedAcceptance\n

A BONSeeder that uses Balanced-Acceptance Sampling (Van-dem-Bates et al. 2017 https://doi.org/10.1111/2041-210X.13003)

source

"},{"location":"#refiner-algorithms","title":"Refiner algorithms","text":"

# BiodiversityObservationNetworks.AdaptiveSpatial \u2014 Type.

AdaptiveSpatial\n

...

numsites, an Integer (def. 50), specifying the number of points to use.

source

# BiodiversityObservationNetworks.Uniqueness \u2014 Type.

Uniqueness\n

A BONRefiner

source

"},{"location":"#helper-functions","title":"Helper functions","text":"

Missing docstring.

Missing docstring for squish. Check Documenter's build log for details.

# BiodiversityObservationNetworks.entropize! \u2014 Function.

entropize!(U::Matrix{AbstractFloat}, A::Matrix{Number})\n

This function turns a matrix A (storing measurement values) into pixel-wise entropy values, stored in a matrix U (that is previously allocated).

Pixel-wise entropy is determined by measuring the empirical probability of randomly picking a value in the matrix that is either lower or higher than the pixel value. The entropy of both these probabilities are calculated using the -p\u00d7log(2,p) formula. The entropy of the pixel is the sum of the two entropies, so that it is close to 1 for values close to the median, and close to 0 for values close to the extreme of the distribution.

source

# BiodiversityObservationNetworks.entropize \u2014 Function.

entropize(A::Matrix{Number})\n

Allocation version of entropize!.

source

"},{"location":"bibliography/","title":"Bibliography","text":""},{"location":"bibliography/#references","title":"References","text":""},{"location":"vignettes/entropize/","title":"Entropize","text":""},{"location":"vignettes/entropize/#getting-the-entropy-matrix","title":"Getting the entropy matrix","text":"

For some applications, we want to place points to capture the maximum amount of information, which is to say that we want to sample a balance of entropy values, as opposed to absolute values. In this vignette, we will walk through an example using the entropize function to convert raw data to entropy values.

using BiodiversityObservationNetworks\nusing NeutralLandscapes\nusing CairoMakie\n

Entropy is problem-specific

The solution presented in this vignette is a least-assumption solution based on the empirical values given in a matrix of measurements. In a lot of situations, this is not the entropy that you want. For example, if your pixels are storing probabilities of Bernoulli events, you can directly use the entropy of the events in the entropy matrix.

We start by generating a random matrix of measurements:

measurements = rand(MidpointDisplacement(), (200, 200)) .* 100\nheatmap(measurements)\n

Using the entropize function will convert these values into entropy at the pixel scale:

@example 1 U = entropize(measurements) locations = seed(BalancedAcceptance(; numsites = 100, uncertainty=U))

"},{"location":"vignettes/overview/","title":"Overview","text":""},{"location":"vignettes/overview/#an-introduction-to-biodiversityobservationnetworks","title":"An introduction to BiodiversityObservationNetworks","text":"

In this vignette, we will walk through the basic functionalities of the package, by generating a random uncertainty matrix, and then using a seeder and a refiner to decide which locations should be sampled in order to gain more insights about the process generating this entropy.

using BiodiversityObservationNetworks\nusing NeutralLandscapes\nusing CairoMakie\n

In order to simplify the process, we will use the NeutralLandscapes package to generate a 100\u00d7100 pixels landscape, where each cell represents the entropy (or information content) in a unit we can sample:

U = rand(MidpointDisplacement(0.5), (100, 100))\nheatmap(U)\n

In practice, this uncertainty matrix is likely to be derived from an application of the hyper-parameters optimization step, which is detailed in other vignettes.

The first step of defining a series of locations to sample is to use a BONSeeder, which will generate a number of relatively coarse proposals that cover the entire landscape, and have a balanced distribution in space. We do so using the BalancedAcceptance sampler, which can be tweaked to capture more (or less) uncertainty. To start with, we will extract 200 candidate points, i.e. 200 possible locations which will then be refined.

candidates = seed(BalancedAcceptance(; numsites = 200));\n
200-element Vector{CartesianIndex}:\n CartesianIndex(27, 48)\n CartesianIndex(14, 6)\n CartesianIndex(39, 22)\n CartesianIndex(8, 39)\n CartesianIndex(33, 11)\n CartesianIndex(20, 28)\n CartesianIndex(45, 45)\n CartesianIndex(5, 17)\n CartesianIndex(30, 33)\n CartesianIndex(17, 50)\n \u22ee\n CartesianIndex(2, 21)\n CartesianIndex(27, 38)\n CartesianIndex(14, 10)\n CartesianIndex(39, 26)\n CartesianIndex(8, 43)\n CartesianIndex(33, 15)\n CartesianIndex(21, 32)\n CartesianIndex(46, 49)\n CartesianIndex(5, 1)\n

We can have a look at the first five points:

candidates[1:5]\n
5-element Vector{CartesianIndex}:\n CartesianIndex(27, 48)\n CartesianIndex(14, 6)\n CartesianIndex(39, 22)\n CartesianIndex(8, 39)\n CartesianIndex(33, 11)\n

The positions of locations to sample are given as a vector of CartesianIndex, which are coordinates in the uncertainty matrix. Once we have generated a candidate proposal, we can further refine it using a BONRefiner \u2013 in this case, AdaptiveSpatial, which performs adaptive spatial sampling (maximizing the distribution of entropy while minimizing spatial auto-correlation).

```@example 1 locations = refine(candidates, AdaptiveSpatial(; numsites = 50, uncertainty=U)) locations[1:5]

The reason we start from a candidate set of points is that some algorithms struggle with full landscapes, and work much better with a sub-sample of them. There is no hard rule (or no heuristic) to get a sense for how many points should be generated at the seeding step, and so experimentation is a must!\n\n\nThe previous code examples used a version of the `seed` and `refine` functions that is very useful if you want to change arguments between steps, or examine the content of the candidate pool of points. In addition to this syntax, both functions have a curried version that allows chaining them together using pipes (`|>`):\n\n\n```@example 1\nlocations =\n    seed(BalancedAcceptance(; numsites = 200)) |>\n    refine(AdaptiveSpatial(; numsites = 50, uncertainty=U))\n

This works because seed and refine have curried versions that can be used directly in a pipeline. Proposed sampling locations can then be overlayed onto the original uncertainty matrix:

@example 1 plt = heatmap(U) scatter!(plt, [x[1] for x in locations], [x[2] for x in locations]) current_figure()

"},{"location":"vignettes/uniqueness/","title":"Uniqueness.jl","text":""},{"location":"vignettes/uniqueness/#selecting-environmentally-unique-locations","title":"Selecting environmentally unique locations","text":"

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\nusing SpeciesDistributionToolkit\nusing StatsBase\nusing NeutralLandscapes\nusing CairoMakie\n
[ Info: Loading NeutralLandscapes support for SimpleSDMLayers.jl...\n

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);\ntemp, precip, elevation =\n    convert(Float32, SimpleSDMPredictor(RasterData(WorldClim2, AverageTemperature); bbox...)),\n    convert(Float32, SimpleSDMPredictor(RasterData(WorldClim2, Precipitation); bbox...)),\n    convert(Float32, SimpleSDMPredictor(RasterData(WorldClim2, Elevation); bbox...));\n
(SDM response \u2192 105\u00d7167 grid with 11478 Float32-valued cells, SDM response \u2192 105\u00d7167 grid with 11478 Float32-valued cells, SDM response \u2192 105\u00d7167 grid with 11478 Float32-valued cells)\n

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]);

```julia\nuncert = rand(MidpointDisplacement(0.8), size(temp), mask=temp);\nheatmap(uncert)\n

Now we'll get a set of candidate points from a BalancedAcceptance seeder that has no bias toward higher uncertainty values.

candpts = seed(BalancedAcceptance(numsites=100));\n
100-element Vector{CartesianIndex}:\n CartesianIndex(19, 29)\n CartesianIndex(44, 46)\n CartesianIndex(13, 3)\n CartesianIndex(38, 20)\n CartesianIndex(25, 36)\n CartesianIndex(50, 9)\n CartesianIndex(1, 25)\n CartesianIndex(26, 42)\n CartesianIndex(13, 14)\n CartesianIndex(38, 31)\n \u22ee\n CartesianIndex(34, 48)\n CartesianIndex(22, 5)\n CartesianIndex(47, 22)\n CartesianIndex(6, 39)\n CartesianIndex(31, 11)\n CartesianIndex(18, 27)\n CartesianIndex(43, 44)\n CartesianIndex(12, 16)\n CartesianIndex(37, 33)\n

Now we'll refine our 100 candidate points down to the 30 most environmentally unique.

@example 1 finalpts = refine(candpts, Uniqueness(;numsites=30, layers=layers)) heatmap(uncert) scatter!([p[1] for p in candpts], [p[2] for p in candpts], color=:white) scatter!([p[1] for p in finalpts], [p[2] for p in finalpts], color=:dodgerblue, msc=:white) current_figure()

"}]} \ No newline at end of file diff --git a/previews/PR66/vignettes/entropize/index.html b/previews/PR66/vignettes/entropize/index.html index 18443e0..9bf48ca 100644 --- a/previews/PR66/vignettes/entropize/index.html +++ b/previews/PR66/vignettes/entropize/index.html @@ -409,7 +409,7 @@

Getting the entropy matrix

measurements = rand(MidpointDisplacement(), (200, 200)) .* 100
 heatmap(measurements)
 
-

+

Using the entropize function will convert these values into entropy at the pixel scale:

@example 1 U = entropize(measurements) diff --git a/previews/PR66/vignettes/gvqxvyl.png b/previews/PR66/vignettes/gvqxvyl.png new file mode 100644 index 0000000..7947d11 Binary files /dev/null and b/previews/PR66/vignettes/gvqxvyl.png differ diff --git a/previews/PR66/vignettes/overview/index.html b/previews/PR66/vignettes/overview/index.html index fa04a3a..8c29e7c 100644 --- a/previews/PR66/vignettes/overview/index.html +++ b/previews/PR66/vignettes/overview/index.html @@ -405,42 +405,42 @@

An introduction to B
U = rand(MidpointDisplacement(0.5), (100, 100))
 heatmap(U)
 
-

+

In practice, this uncertainty matrix is likely to be derived from an application of the hyper-parameters optimization step, which is detailed in other vignettes.

The first step of defining a series of locations to sample is to use a BONSeeder, which will generate a number of relatively coarse proposals that cover the entire landscape, and have a balanced distribution in space. We do so using the BalancedAcceptance sampler, which can be tweaked to capture more (or less) uncertainty. To start with, we will extract 200 candidate points, i.e. 200 possible locations which will then be refined.

candidates = seed(BalancedAcceptance(; numsites = 200));
 
200-element Vector{CartesianIndex}:
- CartesianIndex(19, 2)
- CartesianIndex(44, 18)
- CartesianIndex(4, 35)
- CartesianIndex(29, 7)
- CartesianIndex(16, 24)
- CartesianIndex(41, 41)
- CartesianIndex(10, 13)
- CartesianIndex(35, 30)
- CartesianIndex(23, 46)
- CartesianIndex(48, 4)
+ CartesianIndex(27, 48)
+ CartesianIndex(14, 6)
+ CartesianIndex(39, 22)
+ CartesianIndex(8, 39)
+ CartesianIndex(33, 11)
+ CartesianIndex(20, 28)
+ CartesianIndex(45, 45)
+ CartesianIndex(5, 17)
+ CartesianIndex(30, 33)
+ CartesianIndex(17, 50)
  ⋮
- CartesianIndex(32, 34)
- CartesianIndex(20, 6)
- CartesianIndex(45, 23)
- CartesianIndex(4, 39)
- CartesianIndex(29, 12)
- CartesianIndex(17, 28)
- CartesianIndex(42, 45)
- CartesianIndex(11, 2)
- CartesianIndex(36, 19)
+ CartesianIndex(2, 21)
+ CartesianIndex(27, 38)
+ CartesianIndex(14, 10)
+ CartesianIndex(39, 26)
+ CartesianIndex(8, 43)
+ CartesianIndex(33, 15)
+ CartesianIndex(21, 32)
+ CartesianIndex(46, 49)
+ CartesianIndex(5, 1)
 

We can have a look at the first five points:

candidates[1:5]
 
5-element Vector{CartesianIndex}:
- CartesianIndex(19, 2)
- CartesianIndex(44, 18)
- CartesianIndex(4, 35)
- CartesianIndex(29, 7)
- CartesianIndex(16, 24)
+ CartesianIndex(27, 48)
+ CartesianIndex(14, 6)
+ CartesianIndex(39, 22)
+ CartesianIndex(8, 39)
+ CartesianIndex(33, 11)
 

The positions of locations to sample are given as a vector of CartesianIndex, which are coordinates in the uncertainty matrix. Once we have generated a candidate proposal, we can further refine it using a BONRefiner – in this case, AdaptiveSpatial, which performs adaptive spatial sampling (maximizing the distribution of entropy while minimizing spatial auto-correlation).

```@example 1 diff --git a/previews/PR66/vignettes/qczcdsv.png b/previews/PR66/vignettes/qczcdsv.png deleted file mode 100644 index 913bec0..0000000 Binary files a/previews/PR66/vignettes/qczcdsv.png and /dev/null differ diff --git a/previews/PR66/vignettes/qeuxdnq.png b/previews/PR66/vignettes/qeuxdnq.png deleted file mode 100644 index e7a705a..0000000 Binary files a/previews/PR66/vignettes/qeuxdnq.png and /dev/null differ diff --git a/previews/PR66/vignettes/rywithx.png b/previews/PR66/vignettes/rywithx.png new file mode 100644 index 0000000..899e3c3 Binary files /dev/null and b/previews/PR66/vignettes/rywithx.png differ diff --git a/previews/PR66/vignettes/uniqueness/index.html b/previews/PR66/vignettes/uniqueness/index.html index 78da144..6a44aa1 100644 --- a/previews/PR66/vignettes/uniqueness/index.html +++ b/previews/PR66/vignettes/uniqueness/index.html @@ -408,48 +408,46 @@

Selecting environmentally un

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 -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...)); -

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]);
-

-

```@example 1 +

```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.
-
-
-```julia
-candpts = seed(BalancedAcceptance(numsites=100));
+heatmap(uncert)
 

+

+

Now we'll get a set of candidate points from a BalancedAcceptance seeder that has no bias toward higher uncertainty values.

+
candpts = seed(BalancedAcceptance(numsites=100));
+
100-element Vector{CartesianIndex}:
- CartesianIndex(23, 15)
- CartesianIndex(48, 32)
- CartesianIndex(3, 49)
- CartesianIndex(28, 1)
- CartesianIndex(15, 18)
- CartesianIndex(40, 35)
- CartesianIndex(9, 7)
- CartesianIndex(34, 23)
- CartesianIndex(21, 40)
- CartesianIndex(46, 12)
+ CartesianIndex(19, 29)
+ CartesianIndex(44, 46)
+ CartesianIndex(13, 3)
+ CartesianIndex(38, 20)
+ CartesianIndex(25, 36)
+ CartesianIndex(50, 9)
+ CartesianIndex(1, 25)
+ CartesianIndex(26, 42)
+ CartesianIndex(13, 14)
+ CartesianIndex(38, 31)
  ⋮
- CartesianIndex(30, 29)
- CartesianIndex(17, 46)
- CartesianIndex(42, 3)
- CartesianIndex(11, 20)
- CartesianIndex(36, 37)
- CartesianIndex(23, 9)
- CartesianIndex(48, 26)
- CartesianIndex(3, 42)
- CartesianIndex(28, 14)
+ CartesianIndex(34, 48)
+ CartesianIndex(22, 5)
+ CartesianIndex(47, 22)
+ CartesianIndex(6, 39)
+ CartesianIndex(31, 11)
+ CartesianIndex(18, 27)
+ CartesianIndex(43, 44)
+ CartesianIndex(12, 16)
+ CartesianIndex(37, 33)
 

Now we'll refine our 100 candidate points down to the 30 most environmentally unique.

@example 1 diff --git a/previews/PR66/vignettes/vzcgywx.png b/previews/PR66/vignettes/vzcgywx.png new file mode 100644 index 0000000..12686da Binary files /dev/null and b/previews/PR66/vignettes/vzcgywx.png differ