These functions are wrappers designed to apply kernel utilisation distribution (KUD) estimation to the outputs of a particle filtering (PF) algorithm. To implement these routines, an (a) pf_archive-class object from pf (plus pf_simplify with the return = "archive" argument) containing particle histories for connected particles or (b) a pf_path-class object containing reconstructed paths must be supplied. Depending on the implementation, using a subset, all or an expanded sample of sampled locations, the functions apply KUD smoother(s) via a user-supplied estimation routine (i.e., kernelUD or kud_around_coastline). The functions extract the utilisation distribution(s) as raster(s), combine distribution(s) (if necessary), apply a spatial mask (e.g. coastline), plot the processed distribution (if specified) and return this as a raster.

pf_kud_1(
  xpf,
  bathy,
  sample_size = NULL,
  estimate_ud = adehabitatHR::kernelUD,
  grid,
  ...,
  scale = FALSE,
  plot_by_time = FALSE,
  prompt = TRUE,
  chunks = 1L,
  cl = NULL,
  varlist = NULL,
  mask = NULL,
  plot = TRUE,
  verbose = TRUE
)

pf_kud_2(
  xpf,
  bathy,
  sample_size = NULL,
  estimate_ud = adehabitatHR::kernelUD,
  grid,
  ...,
  mask = NULL,
  plot = TRUE,
  verbose = TRUE
)

Arguments

xpf

A pf_archive-class object (from pf plus pf_simplify with return = "archive") or a pf_path-class object (from pf plus pf_simplify with return = "path"). For particle-based implementations, for pf_kud_1, pf_simplify should be implemented with summarise_pr = FALSE; for pf_kud_2, pf_simplify should be implemented with summarise_pr = TRUE (see Details).

bathy

A raster that defines the grid across which pf was applied. This used to extract cell coordinates and to express KUD(s).

sample_size

(optional) An integer that defines the number of particles to sample from (a) particle histories or (b) each path in xpf for KUD estimation. For pf_kud_1, sampling is used to account for particle uncertainty so sample_size should be greater than the number of particle samples at each time step (see Details). If specified, for each time step, sample_size particles are sampled from (a) particle histories or (b) reconstructed paths with replacement in line with their probability. For pf_kud_2, sampling is used to reduce memory requirements and computation time, so sample_size should be lower than the total number of particle samples (per path, if applicable). If specified, sample_size particles are sampled from (a) particle histories or (b) each path with replacement in line with their probability. If sample_size = NULL, all particles are used.

estimate_ud

A function (either kernelUD or kud_around_coastline) that estimates kernel utilisation distributions. For pf_kud_1, kud_around_coastline_fast can also be used for faster estimation.

grid, ...

Arguments passed to estimate_ud (and ultimately kernelUD, where they are defined) to estimate the kernel utilisation distribution. If kud_around_coastline or kud_around_coastline_fast is supplied to estimate_ud, then grid must be a SpatialPixelsDataFrame. However, note that in all cases, KUD(s) are resampled onto bathy.

scale

For pf_kud_1, scale is a logical input that defines whether or not to scale the KUD for each time step such that the most probable locations are assigned a score of one.

plot_by_time, prompt

For pf_kud_1, plot_by_time is a logical variable that defines whether or not to plot the cumulative (un-normalised) KUD for each time step. If supplied, prompt is a logical variable that defines whether or not to pause function execution between sequential plots. These arguments are not implemented in parallel (see cl, below).

chunks, cl, varlist

For pf_kud_1, chunks, cl and varlist are chunk-wise implementation controls. chunks is an integer that defines the number of chunks into which to split particle/path time series. To minimise memory requirements, within each chunk, a blank map is sequentially updated with the KUD for each time step; the cumulative KUD for each chunk is then summed across chunks to create a single KUD. This approach minimises memory use while facilitating improvements in computation time through the parallel processing of each chunk via cl and varlist. cl is (a) a cluster object from makeCluster or (b) an integer that defines the number of child processes. varlist is a character vector of variables for export (see cl_export). Exported variables must be located in the global environment. If a cluster is supplied, the connection to the cluster is closed within the function (see cl_stop). For further information, see cl_lapply and flapper-tips-parallel.

mask

(optional) A spatial mask (see mask).

plot

A logical input that defines whether or not to plot the KUD.

verbose

A logical input that defines whether or not to print messages to the console to monitor function progress.

Value

The functions return a raster of the KUD.

Details

Methods

These function create smooth KUD representations of particle or path samples from a PF algorithm (see pf_plot_map). Two different methods are implemented.

Method (1)

pf_kud_1 implements KUD estimation by fitting a single kernel to sampled locations at each time step; time step-specific kernels are then summed and re-normalised. This method can be implemented for (a) the sampled particles that formed continuous paths from the start to the end of the time series (see pf_simplify) or (b) reconstructed paths. The method has two main advantages. First, the kernel bandwidth is allowed to vary through time. Second, this implementation permits a Bayesian-style resampling process that can be used to account for particle uncertainty. Specifically, at each time step, large numbers of particles can be re-sampled, in line with their probability and with replacement, from the initial list of sampled particles; more probable locations are sampled more often and consequently have more influence on the KUD for each time step, thus accounting for particle probability.

A limitation with this method is that the fitting a KUD to each time step can be memory intensive and computationally intensive. To minimise memory requirements, by default (chunks = 1L), the function starts with a blank map and iterates over each time step, sequentially adding KUDs to the map at each step. By continuously updating a single map, this option minimises memory requirements but is slow. A faster option is to split the time series into chunks, implement an iterative option within each chunk, and then join maps for each chunk. The advantage of this option is that memory use remains limited while computation time can be improved by the parallel processing of each chunk. This is implemented via chunks, cl and varlist.

Method (2)

pf_kud_2 implements KUD estimation by fitting a single kernel to all sampled locations or to each path (and then aggregating KUDs across paths). The main advantage of this method is speed: unlike pf_kud_1, KUDs are not fitted to the locations for each time step. The limitations are that kernel bandwidth is constant for all time steps and in most situations re-sampling cannot be used in the same way to account for particle uncertainty (due to memory limitations).

For particle-based implementations, this method is designed to be implemented for the subset of unique, sampled particles that formed continuous paths from the start to the end of the time series (see pf_simplify and pf_plot_map). These particles are used for KUD estimation. By default, all particles are used, but \(n =\) sample_size particles can be sampled at random, in line with their probability, if specified, for faster KUD estimation. Selected particles are then used to estimate a KUD by effectively treating samples as `relocations', ultimately via kernelUD. This distribution is then processed, plotted and returned.

For path-based implementations, this function is designed to be implemented for paths reconstructed by pf_simplify. As for the particle-based implementation, for each path, all locations, or random sample of sample_size locations are used to estimate a KUD by treating sampled locations as `relocations'. KUDs are processed and combined across paths into a single, average KUD. The advantage of this approach is that the overall probability of the paths can be incorporated in the estimation procedure via sampling or weights when path-specific KUDs are averaged (although that is not yet implemented).

Author

Edward Lavender

Examples

#### Define particle samples for smoothing
# To do this, we will re-implement the pf() for the example dat_dcpf_histories
# ... dataset, but with a larger number of particles. This is necessary
# ... because kernel smoothing is only appropriate if there are
# ... enough locations to permit smoothing.
set.seed(1)
dcpf_args <- dat_dcpf_histories$args
dcpf_args$calc_distance_euclid_fast <- TRUE
dcpf_args$n <- 250L
out_dcpf_particles <- do.call(pf, dcpf_args)
#> flapper::pf() called (@ 2023-08-29 15:45:06)... 
#> ... Setting up function... 
#> ... Determining the set of possible starting locations (t = 1)... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... Implementing algorithm iteratively over time steps... 
#> ... ... Time = 1... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 2... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 3... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 4... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 5... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 6... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 7... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 8... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 9... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 10... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 11... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 12... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 13... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 14... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 15... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 16... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 17... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... ... ... For each particle, getting the possible positions for the next time step... 
#> Warning: GEOS support is provided by the sf and terra packages among others
#> ... ... Time = 18... 
#> ... ... ... Selecting candidate starting positions for the current time step... 
#> ... flapper::pf() call completed (@ 2023-08-29 15:45:10) after ~0.07 minutes. 

#### Process particles and paths
out_dcpf_particles_1 <-
  pf_simplify(out_dcpf_particles, return = "archive")
#> flapper::pf_simplify() called (@ 2023-08-29 15:45:10)... 
#> ... Getting pairwise cell movements based on calc_distance = 'euclid'... 
#> ... ... Stepping through time steps to join coordinate pairs... 
#> ... ... Identifying connected cells... 
#> ... ... Processing connected cells for return = 'archive'... 
#> ... flapper::pf_simplify() call completed (@ 2023-08-29 15:45:10) after ~0 minutes. 
out_dcpf_particles_2 <-
  pf_simplify(out_dcpf_particles, summarise_pr = TRUE, return = "archive")
#> flapper::pf_simplify() called (@ 2023-08-29 15:45:10)... 
#> ... Getting pairwise cell movements based on calc_distance = 'euclid'... 
#> ... ... Stepping through time steps to join coordinate pairs... 
#> ... ... Identifying connected cells... 
#> ... ... Processing connected cells for return = 'archive'... 
#> ... flapper::pf_simplify() call completed (@ 2023-08-29 15:45:10) after ~0.01 minutes. 
out_dcpf_paths <-
  pf_simplify(out_dcpf_particles, max_n_paths = 100L)
#> flapper::pf_simplify() called (@ 2023-08-29 15:45:10)... 
#> ... Getting pairwise cell movements based on calc_distance = 'euclid'... 
#> ... ... Stepping through time steps to join coordinate pairs... 
#> ... ... Identifying connected cells... 
#> ... Assembling paths... 
#> ... Formatting paths... 
#> ... Adding cell coordinates and depths... 
#> ... flapper::pf_simplify() call completed (@ 2023-08-29 15:45:11) after ~0 minutes. 

#### Define a grid across which to implement estimation
# This grid takes values of 0 on land and values of 1 in the sea
bathy <- out_dcpf_particles$args$bathy
grid <- raster::raster(raster::extent(bathy), nrows = 100, ncols = 100)
raster::values(grid) <- 0
grid <- raster::mask(grid, dat_coast, updatevalue = 1)
grid <- methods::as(grid, "SpatialPixelsDataFrame")

#### Example (1): Implement pf_kud_1() using default options
## Implementation based on particles
pp <- par(mfrow = c(1, 2), mar = c(3, 3, 3, 3))
pf_kud_1(out_dcpf_particles_1,
  bathy = bathy,
  sample_size = 500,
  estimate_ud = kud_around_coastline_fast, grid = grid
)
#> flapper::pf_kud_1() called (@ 2023-08-29 15:45:11)... 
#> ... Setting up function... 
#> CRS taken as: 'NA'.
#> ... Processing sampled locations... 
#> ... Defining chunk(s)... 
#> ... Implementing KUD estimation over chunk(s)... 
#> ... Processing KUD(s)... 
#> ... Plotting KUD... 
#> prettyGraphics::pretty_map() CRS taken as: 'NA'.
#> ... flapper::pf_kud_1() call completed (@ 2023-08-29 15:45:12) after ~0.02 minutes. 
#> class      : RasterLayer 
#> dimensions : 80, 80, 6400  (nrow, ncol, ncell)
#> resolution : 25, 25  (x, y)
#> extent     : 707884.6, 709884.6, 6253404, 6255404  (xmin, xmax, ymin, ymax)
#> crs        : NA 
#> source     : memory
#> names      : layer 
#> values     : 0, 0.004805  (min, max)
#> 
## Implementation based on paths
if (flapper_run_parallel) {
  pf_kud_1(out_dcpf_paths,
    bathy = bathy,
    sample_size = 500,
    estimate_ud = kud_around_coastline_fast, grid = grid
  )
  prettyGraphics::add_sp_path(
    x = out_dcpf_paths$cell_x,
    y = out_dcpf_paths$cell_y,
    length = 0.01
  )
}
#> flapper::pf_kud_1() called (@ 2023-08-29 15:45:12)... 
#> ... Setting up function... 
#> CRS taken as: 'NA'.
#> ... Processing sampled locations... 
#> ... Defining chunk(s)... 
#> ... Implementing KUD estimation over chunk(s)... 
#> Fewer than five unique cells for kernel estimation at time 1.
#> ... Processing KUD(s)... 
#> ... Plotting KUD... 
#> prettyGraphics::pretty_map() CRS taken as: 'NA'.
#> ... flapper::pf_kud_1() call completed (@ 2023-08-29 15:45:13) after ~0.02 minutes. 
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped

par(pp)

#### Example (2): Implement pf_kud_2() using default options
## Implementation based on particles
pp <- par(mfrow = c(1, 2), mar = c(3, 3, 3, 3))
pf_kud_2(out_dcpf_particles_2,
  bathy = bathy,
  estimate_ud = kud_around_coastline, grid = grid
)
#> flapper::pf_kud_2() called (@ 2023-08-29 15:45:13)... 
#> ... Setting up function... 
#> CRS taken as: 'NA'.
#> ... Processing sampled locations... 
#> ... Implementing KUD estimation... 
#> ... Processing KUD(s)... 
#> ... Plotting KUD... 
#> prettyGraphics::pretty_map() CRS taken as: 'NA'.
#> ... flapper::pf_kud_2() call completed (@ 2023-08-29 15:45:13) after ~0 minutes. 
#> class      : RasterLayer 
#> dimensions : 80, 80, 6400  (nrow, ncol, ncell)
#> resolution : 25, 25  (x, y)
#> extent     : 707884.6, 709884.6, 6253404, 6255404  (xmin, xmax, ymin, ymax)
#> crs        : NA 
#> source     : memory
#> names      : ud 
#> values     : 0, 0.00101676  (min, max)
#> 
## Implementation based on paths
pf_kud_2(out_dcpf_paths,
  bathy = bathy,
  estimate_ud = kud_around_coastline, grid = grid
)
#> flapper::pf_kud_2() called (@ 2023-08-29 15:45:13)... 
#> ... Setting up function... 
#> CRS taken as: 'NA'.
#> ... Implementing KUD estimation... 
#> ... Processing KUD(s)... 
#> ... Plotting KUD... 
#> prettyGraphics::pretty_map() CRS taken as: 'NA'.
#> ... flapper::pf_kud_2() call completed (@ 2023-08-29 15:45:19) after ~0.09 minutes. 
#> class      : RasterLayer 
#> dimensions : 80, 80, 6400  (nrow, ncol, ncell)
#> resolution : 25, 25  (x, y)
#> extent     : 707884.6, 709884.6, 6253404, 6255404  (xmin, xmax, ymin, ymax)
#> crs        : NA 
#> source     : memory
#> names      : layer 
#> values     : 0, 0.0009089496  (min, max)
#> 
prettyGraphics::add_sp_path(
  x = out_dcpf_paths$cell_x, y = out_dcpf_paths$cell_y,
  length = 0.01
)
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped
#> Warning: zero-length arrow is of indeterminate angle and so skipped

par(pp)

#### Example (3): For improved speed with pf_kud_1(), use parallelisation
## Implementation based on particles
pp <- par(mfrow = c(1, 2), mar = c(3, 3, 3, 3))
pf_kud_1(out_dcpf_particles_1,
  bathy = bathy,
  sample_size = 500,
  estimate_ud = flapper::kud_around_coastline_fast, grid = grid,
  chunks = 2L,
  cl = parallel::makeCluster(2L)
)
#> flapper::pf_kud_1() called (@ 2023-08-29 15:45:19)... 
#> ... Setting up function... 
#> CRS taken as: 'NA'.
#> ... Processing sampled locations... 
#> ... Defining chunk(s)... 
#> ... Implementing KUD estimation over chunk(s)... 
#> ... Processing KUD(s)... 
#> ... Plotting KUD... 
#> prettyGraphics::pretty_map() CRS taken as: 'NA'.
#> ... flapper::pf_kud_1() call completed (@ 2023-08-29 15:45:24) after ~0.09 minutes. 
#> class      : RasterLayer 
#> dimensions : 80, 80, 6400  (nrow, ncol, ncell)
#> resolution : 25, 25  (x, y)
#> extent     : 707884.6, 709884.6, 6253404, 6255404  (xmin, xmax, ymin, ymax)
#> crs        : NA 
#> source     : memory
#> names      : layer 
#> values     : 0, 0.005050926  (min, max)
#> 
## Implementation based on paths
if (flapper_run_parallel) {
  cl <- parallel::makeCluster(2L)
  parallel::clusterEvalQ(cl = cl, library(raster))
  pf_kud_1(out_dcpf_paths,
    bathy = bathy,
    sample_size = 500,
    estimate_ud = flapper::kud_around_coastline_fast, grid = grid,
    chunks = 2L,
    cl = cl
  )
}
#> flapper::pf_kud_1() called (@ 2023-08-29 15:45:26)... 
#> ... Setting up function... 
#> CRS taken as: 'NA'.
#> ... Processing sampled locations... 
#> ... Defining chunk(s)... 
#> ... Implementing KUD estimation over chunk(s)... 
#> ... Processing KUD(s)... 
#> ... Plotting KUD... 
#> prettyGraphics::pretty_map() CRS taken as: 'NA'.

#> ... flapper::pf_kud_1() call completed (@ 2023-08-29 15:45:27) after ~0.02 minutes. 
#> class      : RasterLayer 
#> dimensions : 80, 80, 6400  (nrow, ncol, ncell)
#> resolution : 25, 25  (x, y)
#> extent     : 707884.6, 709884.6, 6253404, 6255404  (xmin, xmax, ymin, ymax)
#> crs        : NA 
#> source     : memory
#> names      : layer 
#> values     : 0, 0.08127464  (min, max)
#> 
par(pp)

#### Example (4): For improved speed with pf_kud_2(), use sample_size
## Implementation based on particles
pp <- par(mfrow = c(1, 2), mar = c(3, 3, 3, 3))
pf_kud_2(out_dcpf_particles_2,
  bathy = bathy,
  sample_size = 50, # sample 50 particles overall
  estimate_ud = kud_around_coastline, grid = grid
)
#> flapper::pf_kud_2() called (@ 2023-08-29 15:45:27)... 
#> ... Setting up function... 
#> CRS taken as: 'NA'.
#> ... Processing sampled locations... 
#> ... Implementing KUD estimation... 
#> ... Processing KUD(s)... 
#> ... Plotting KUD... 
#> prettyGraphics::pretty_map() CRS taken as: 'NA'.
#> ... flapper::pf_kud_2() call completed (@ 2023-08-29 15:45:27) after ~0 minutes. 
#> class      : RasterLayer 
#> dimensions : 80, 80, 6400  (nrow, ncol, ncell)
#> resolution : 25, 25  (x, y)
#> extent     : 707884.6, 709884.6, 6253404, 6255404  (xmin, xmax, ymin, ymax)
#> crs        : NA 
#> source     : memory
#> names      : ud 
#> values     : 0, 0.0007348167  (min, max)
#> 
## Implementation based on paths
pf_kud_2(out_dcpf_paths,
  bathy = bathy,
  sample_size = 50, # sample 50 particles per path
  estimate_ud = kud_around_coastline, grid = grid
)
#> flapper::pf_kud_2() called (@ 2023-08-29 15:45:27)... 
#> ... Setting up function... 
#> CRS taken as: 'NA'.
#> Warning: 'sample_size' is greater than the number of particles.
#> ... Implementing KUD estimation... 
#> ... Processing KUD(s)... 
#> ... Plotting KUD... 
#> prettyGraphics::pretty_map() CRS taken as: 'NA'.

#> ... flapper::pf_kud_2() call completed (@ 2023-08-29 15:45:32) after ~0.08 minutes. 
#> class      : RasterLayer 
#> dimensions : 80, 80, 6400  (nrow, ncol, ncell)
#> resolution : 25, 25  (x, y)
#> extent     : 707884.6, 709884.6, 6253404, 6255404  (xmin, xmax, ymin, ymax)
#> crs        : NA 
#> source     : memory
#> names      : layer 
#> values     : 0, 0.02694652  (min, max)
#> 
par(pp)

#### Example (5): Compare pf_kud_1() and pf_kud_2()
pp <- par(mfrow = c(2, 2), mar = c(3, 3, 3, 3))
kud_1a <- pf_kud_1(
  xpf = out_dcpf_particles_1,
  bathy = out_dcpf_particles$args$bathy,
  sample_size = out_dcpf_particles$args$n,
  estimate_ud = kud_around_coastline_fast, grid = grid,
  plot = TRUE
)
#> flapper::pf_kud_1() called (@ 2023-08-29 15:45:32)... 
#> ... Setting up function... 
#> CRS taken as: 'NA'.
#> ... Processing sampled locations... 
#> ... Defining chunk(s)... 
#> ... Implementing KUD estimation over chunk(s)... 
#> ... Processing KUD(s)... 
#> ... Plotting KUD... 
#> prettyGraphics::pretty_map() CRS taken as: 'NA'.
#> ... flapper::pf_kud_1() call completed (@ 2023-08-29 15:45:34) after ~0.02 minutes. 

kud_1b <- pf_kud_1(
  xpf = out_dcpf_particles_1,
  bathy = out_dcpf_particles$args$bathy,
  sample_size = 500,
  estimate_ud = kud_around_coastline_fast, grid = grid,
  plot = TRUE
)
#> flapper::pf_kud_1() called (@ 2023-08-29 15:45:34)... 
#> ... Setting up function... 
#> CRS taken as: 'NA'.
#> ... Processing sampled locations... 
#> ... Defining chunk(s)... 
#> ... Implementing KUD estimation over chunk(s)... 
#> ... Processing KUD(s)... 
#> ... Plotting KUD... 
#> prettyGraphics::pretty_map() CRS taken as: 'NA'.
#> ... flapper::pf_kud_1() call completed (@ 2023-08-29 15:45:34) after ~0.02 minutes. 

kud_1c <- pf_kud_1(
  xpf = out_dcpf_particles_1,
  bathy = out_dcpf_particles$args$bathy,
  sample_size = 5000,
  estimate_ud = kud_around_coastline_fast, grid = grid,
  plot = TRUE
)
#> flapper::pf_kud_1() called (@ 2023-08-29 15:45:34)... 
#> ... Setting up function... 
#> CRS taken as: 'NA'.
#> ... Processing sampled locations... 
#> ... Defining chunk(s)... 
#> ... Implementing KUD estimation over chunk(s)... 
#> ... Processing KUD(s)... 
#> ... Plotting KUD... 
#> prettyGraphics::pretty_map() CRS taken as: 'NA'.
#> ... flapper::pf_kud_1() call completed (@ 2023-08-29 15:45:38) after ~0.05 minutes. 

kud_1d <- pf_kud_2(
  xpf = out_dcpf_particles_2,
  bathy = out_dcpf_particles$args$bathy,
  estimate_ud = kud_around_coastline, grid = grid,
  plot = TRUE
)
#> flapper::pf_kud_2() called (@ 2023-08-29 15:45:38)... 
#> ... Setting up function... 
#> CRS taken as: 'NA'.
#> ... Processing sampled locations... 
#> ... Implementing KUD estimation... 
#> ... Processing KUD(s)... 
#> ... Plotting KUD... 
#> prettyGraphics::pretty_map() CRS taken as: 'NA'.

#> ... flapper::pf_kud_2() call completed (@ 2023-08-29 15:45:38) after ~0 minutes. 
par(pp)