-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpf_kud_.Rd
233 lines (206 loc) · 14.4 KB
/
pf_kud_.Rd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/pf_analyse_either.R
\name{pf_kud_}
\alias{pf_kud_}
\alias{pf_kud_1}
\alias{pf_kud_2}
\title{(Experimental) Alternative kernel smoothing routines for particles or paths from a PF algorithm}
\usage{
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{
\item{xpf}{A \code{\link[flapper]{pf_archive-class}} object (from \code{\link[flapper]{pf}} plus \code{\link[flapper]{pf_simplify}} with \code{return = "archive"}) or a \code{\link[flapper]{pf_path-class}} object (from \code{\link[flapper]{pf}} plus \code{\link[flapper]{pf_simplify}} with \code{return = "path"}). For particle-based implementations, for \code{\link[flapper]{pf_kud_1}}, \code{\link[flapper]{pf_simplify}} should be implemented with \code{summarise_pr = FALSE}; for \code{\link[flapper]{pf_kud_2}}, \code{\link[flapper]{pf_simplify}} should be implemented with \code{summarise_pr = TRUE} (see Details).}
\item{bathy}{A \code{\link[raster]{raster}} that defines the grid across which \code{\link[flapper]{pf}} was applied. This used to extract cell coordinates and to express KUD(s).}
\item{sample_size}{(optional) An integer that defines the number of particles to sample from (a) particle histories or (b) each path in \code{xpf} for KUD estimation. For \code{\link[flapper]{pf_kud_1}}, sampling is used to account for particle uncertainty so \code{sample_size} should be greater than the number of particle samples at each time step (see Details). If specified, for each time step, \code{sample_size} particles are sampled from (a) particle histories or (b) reconstructed paths with replacement in line with their probability. For \code{\link[flapper]{pf_kud_2}}, sampling is used to reduce memory requirements and computation time, so \code{sample_size} should be lower than the total number of particle samples (per path, if applicable). If specified, \code{sample_size} particles are sampled from (a) particle histories or (b) each path with replacement in line with their probability. If \code{sample_size = NULL}, all particles are used.}
\item{estimate_ud}{A function (either \code{\link[adehabitatHR]{kernelUD}} or \code{\link[flapper]{kud_around_coastline}}) that estimates kernel utilisation distributions. For \code{\link[flapper]{pf_kud_1}}, \code{\link[flapper]{kud_around_coastline_fast}} can also be used for faster estimation.}
\item{grid, ...}{Arguments passed to \code{estimate_ud} (and ultimately \code{\link[adehabitatHR]{kernelUD}}, where they are defined) to estimate the kernel utilisation distribution. If \code{\link[flapper]{kud_around_coastline}} or \code{\link[flapper]{kud_around_coastline_fast}} is supplied to \code{estimate_ud}, then \code{grid} must be a \code{\link[sp]{SpatialPixelsDataFrame}}. However, note that in all cases, KUD(s) are resampled onto \code{bathy}.}
\item{scale}{For \code{\link[flapper]{pf_kud_1}}, \code{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.}
\item{plot_by_time, prompt}{For \code{\link[flapper]{pf_kud_1}}, \code{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, \code{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 \code{cl}, below).}
\item{chunks, cl, varlist}{For \code{\link[flapper]{pf_kud_1}}, \code{chunks}, \code{cl} and \code{varlist} are chunk-wise implementation controls. \code{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 \code{cl} and \code{varlist}. \code{cl} is (a) a cluster object from \code{\link[parallel]{makeCluster}} or (b) an integer that defines the number of child processes. \code{varlist} is a character vector of variables for export (see \code{\link[flapper]{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 \code{\link[flapper]{cl_stop}}). For further information, see \code{\link[flapper]{cl_lapply}} and \code{\link[flapper]{flapper-tips-parallel}}.}
\item{mask}{(optional) A spatial mask (see \code{\link[raster]{mask}}).}
\item{plot}{A logical input that defines whether or not to plot the KUD.}
\item{verbose}{A logical input that defines whether or not to print messages to the console to monitor function progress.}
}
\value{
The functions return a \code{\link[raster]{raster}} of the KUD.
}
\description{
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) \code{\link[flapper]{pf_archive-class}} object from \code{\link[flapper]{pf}} (plus \code{\link[flapper]{pf_simplify}} with the \code{return = "archive"} argument) containing particle histories for connected particles or (b) a \code{\link[flapper]{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., \code{\link[adehabitatHR]{kernelUD}} or \code{\link[flapper]{kud_around_coastline}}). The functions extract the utilisation distribution(s) as \code{\link[raster]{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 \code{\link[raster]{raster}}.
}
\details{
\subsection{Methods}{These function create smooth KUD representations of particle or path samples from a PF algorithm (see \code{\link[flapper]{pf_plot_map}}). Two different methods are implemented.
}
\subsection{Method (1)}{\code{\link[flapper]{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 \code{\link[flapper]{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 (\code{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 \code{chunks}, \code{cl} and \code{varlist}.
}
\subsection{Method (2)}{\code{\link[flapper]{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 \code{\link[flapper]{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 \code{\link[flapper]{pf_simplify}} and \code{\link[flapper]{pf_plot_map}}). These particles are used for KUD estimation. By default, all particles are used, but \eqn{n =} \code{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 \code{\link[adehabitatHR]{kernelUD}}. This distribution is then processed, plotted and returned.
For path-based implementations, this function is designed to be implemented for paths reconstructed by \code{\link[flapper]{pf_simplify}}. As for the particle-based implementation, for each path, all locations, or random sample of \code{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).
}
}
\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)
#### Process particles and paths
out_dcpf_particles_1 <-
pf_simplify(out_dcpf_particles, return = "archive")
out_dcpf_particles_2 <-
pf_simplify(out_dcpf_particles, summarise_pr = TRUE, return = "archive")
out_dcpf_paths <-
pf_simplify(out_dcpf_particles, max_n_paths = 100L)
#### 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
)
## 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
)
}
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
)
## Implementation based on paths
pf_kud_2(out_dcpf_paths,
bathy = bathy,
estimate_ud = kud_around_coastline, grid = grid
)
prettyGraphics::add_sp_path(
x = out_dcpf_paths$cell_x, y = out_dcpf_paths$cell_y,
length = 0.01
)
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)
)
## 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
)
}
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
)
## 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
)
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
)
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
)
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
)
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
)
par(pp)
}
\seealso{
\code{\link[flapper]{pf}}, \code{\link[flapper]{pf_simplify}}, \code{\link[flapper]{pf_plot_map}}, \code{\link[adehabitatHR]{kernelUD}}, \code{\link[flapper]{kud_around_coastline}}, \code{\link[flapper]{kud_around_coastline_fast}}, \code{\link[flapper]{eval_by_kud}}
}
\author{
Edward Lavender
}