-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdot-acs.Rd
280 lines (247 loc) · 18.4 KB
/
dot-acs.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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/acs_backend.R
\name{.acs}
\alias{.acs}
\title{Back-end implementation of the AC and ACDC algorithms}
\usage{
.acs(
acoustics,
archival = NULL,
step = 120,
round_ts = TRUE,
plot_ts = TRUE,
bathy,
map = NULL,
detection_containers,
detection_kernels = NULL,
detection_kernels_overlap = NULL,
detection_time_window = 5,
mobility,
calc_depth_error = function(...) matrix(c(-2.5, 2.5), nrow = 2),
normalise = TRUE,
chunk = 1L,
save_record_spatial = 1L,
write_record_spatial_for_pf = NULL,
save_args = TRUE,
verbose = TRUE,
con = "",
progress = 1L,
check = TRUE
)
}
\arguments{
\item{acoustics}{A dataframe that contains passive acoustic telemetry detection time series for a specific individual (see \code{\link[flapper]{dat_acoustics}} for an example). This should contain the following columns: an integer vector of receiver IDs, named `receiver_id' (that must match that inputted to \code{\link[flapper]{acs_setup_containers}}); an integer vector of detection indices, named `index'; a POSIXct vector of time stamps when detections were made, named `timestamp'; and a numeric vector of those time stamps, named `timestamp_num'.}
\item{archival}{For the ACDC algorithm, \code{archival} is a dataframe that contains depth time series for the same individual (see \code{\link[flapper]{dat_archival}} for an example). This should contain the following columns: a numeric vector of observed depths, named `depth'; a POSIXct vector of time stamps when observations were made, named `timestamp'; and a numeric vector of those time stamps, named `timestamp_num'. Depths should be recorded in the same units and with the same sign as the bathymetry data (see \code{bathy}). Absolute depths (m) are suggested. Unlike the detection time series, archival time stamps are assumed to have occurred at regular intervals.}
\item{step}{A number that defines the time step length (s) between consecutive detections. If \code{archival} is supplied, this is the resolution of the archival data (e.g., 120 s).}
\item{round_ts}{A logical input that defines whether or not to round the \code{acoustics} and/or \code{archival} time series to the nearest \code{step/60} minutes. This step is necessary to ensure appropriate alignment between the two time series given the assumption of a constant \code{mobility} parameter (see below). For implementations via \code{\link[flapper]{.acs_pl}}, this step is implemented in \code{\link[flapper]{.acs_pl}}.}
\item{plot_ts}{A logical input that defines whether or not to the plot movement series before the algorithm is initiated.}
\item{bathy}{A \code{\link[raster]{raster}} that defines the area (for the AC algorithm) or bathymetry (for the ACDC* algorithm) across the area within which the individual could have moved. For the ACDC algorithm, this must be recorded in the same units and with the same sign as the depth observations (see \code{archival}). The coordinate reference system should be the Universal Transverse Mercator system, with distances in metres (see also \code{\link[flapper]{acs_setup_containers}}).}
\item{map}{(optional) A blank \code{\link[raster]{raster}}, with the same properties (i.e., dimensions, resolution, extent and coordinate reference system) as the area/bathymetry raster (see \code{bathy}), but in which all values are 0. If \code{NULL}, this is computed internally, but supplying a pre-defined raster can be more computationally efficient if the function is applied iteratively (e.g., over different time windows).}
\item{detection_containers}{A list of detection containers, with one element for each number from \code{1:max(acoustics$receiver_id)}, from \code{\link[flapper]{acs_setup_containers}}.}
\item{detection_kernels}{A named list of detection probability kernels, from \code{\link[flapper]{acs_setup_detection_kernels}} and created using consistent parameters as specified for other \code{acs_setup_*} functions and here (i.e., see the \code{overlaps}, \code{calc_detection_pr} and \code{map} arguments in \code{\link[flapper]{acs_setup_detection_kernels}}).}
\item{detection_kernels_overlap}{(optional) A named list (the `list_by_receiver' element from \code{\link[flapper]{get_detection_containers_overlap}}), that defines, for each receiver, for each day over its deployment period, whether or not its detection container overlapped with those of other receivers. If \code{detection_kernels_overlap} and \code{detection_time_window} (below) are supplied, the implementation of detection probability kernels when a detection is made accounts for overlaps in receivers' detection containers; if unsupplied, receiver detection probability kernels are assumed not to overlap.}
\item{detection_time_window}{(optional) A number that defines the maximum duration (s) between consecutive detections at different receivers such that they can be said to have occurred at `effectively the same time'. This indicates that the same transmission was detected by multiple receivers. If \code{detection_kernels_overlap} (above) and \code{detection_time_window} are supplied, the implementation of detection probability kernels when a detection is made accounts for overlaps in receivers' detection containers, by up-weighting overlapping areas between receivers that detected the transmission and down-weighting overlapping areas between receivers that did not detect the transmission (see Details in \code{\link[flapper]{acs_setup_detection_kernels}}). Note that the timing of detections is affected by \code{step} (see Details).}
\item{mobility}{A number that defines the distance (m) that an individual could move in the time steps between acoustic detections (see also \code{\link[flapper]{acs_setup_containers}}).}
\item{calc_depth_error}{In the ACDC algorithm, \code{calc_depth_error} is function that returns the depth errors around a vector of depths. The function should accept vector of depths (from \code{archival$depth}) and return a matrix, with one row for each (lower and upper) error and one one column for each depth (if the error varies with depth). For each depth, the two numbers are added to the observed depth to define the range of depths on the bathymetry raster (\code{bathy}) that the individual could plausibly have occupied at any time. Since the depth errors are added to the individual's depth, the first number should be negative (i.e., the individual could have been shallower that observed) and the second positive (i.e., the individual could have been deeper than observed). The appropriate form for \code{calc_depth_error} depends on the species (pelagic versus demersal/benthic species), the measurement error for the depth observations in \code{archival} and bathymetry (\code{bathy}) data, as well as the tidal range (m) across the area (over the duration of observations). For example, for a pelagic species, the constant function \code{calc_depth_error = function(...) matrix(c(-2.5, Inf)} implies that the individual could have occupied bathymetric cells that are deeper than the observed depth + (-2.5) m and shallower than Inf m (i.e. the individual could have been in any location in which the depth was deeper than the shallow depth limit for the individual). In contrast, for a benthic species, the constant function \code{calc_depth_error = function(...) matrix(c(-2.5, 2.5), nrow = 2)} implies that the individual could have occupied bathymetric cells whose depth lies within the interval defined by the observed depth + (-2.5) and + (+2.5) m.}
\item{normalise}{A logical variable that defines whether or not to normalise the map of possible locations at each time step so that they sum to one.}
\item{chunk}{An integer that defines the chunk ID (from \code{\link[flapper]{.acs_pl}}).}
\item{save_record_spatial}{An integer vector that defines the time steps for which to save a record of the spatial information from each time step. \code{save_record_spatial = 0} suppresses the return of this information and \code{save_record_spatial = NULL} returns this information for all time steps.}
\item{write_record_spatial_for_pf}{(optional) A named list, passed to \code{\link[raster]{writeRaster}}, to save a subset of the spatial record (specifically the \code{\link[raster]{raster}} of the individual's possible positions at each time step) to file. This forms the basis for extending maps of space use via particle filtering (see \code{\link[flapper]{pf}}.) The `filename' argument should be the directory in which to save files. Files are named by chunk ID, acoustic and internal (archival) time steps. For example, the file for the first chunk, the first acoustic time step and the first archival time step is named `chu_1_acc_1_arc_1'.}
\item{save_args}{A logical input that defines whether or not to include a list of function arguments in the outputs. This can be switched off if the function is applied iteratively.}
\item{verbose}{A logical variable that defines whether or not to print messages to the console or to file to relay function progress. If \code{con = ""}, messages are printed to the console; otherwise, they are written to file (see below).}
\item{con}{If \code{verbose = TRUE}, \code{con} is character string that defines the full pathway to a .txt file (which can be created on-the-fly) into which messages are written to relay function progress. This approach, rather than printing to the console, is recommended for clarity, speed and debugging.}
\item{progress}{(optional) If the algorithm is implemented step-wise, \code{progress} is an integer (\code{1}, \code{2} or \code{3}) that defines whether or not to display a progress bar in the console as the algorithm moves over acoustic time steps (\code{1}), the `archival' time steps between each pair of acoustic detections (\code{2}) or both acoustic and archival time steps (\code{3}), in which case the overall acoustic progress bar is punctuated by an archival progress bar for each pair of acoustic detections. This option is useful if there is a large number of archival observations between acoustic detections. Any other input will suppress the progress bar. If the algorithm is implemented for chunks, inputs to \code{progress} are ignored and a single progress bar is shown of the progress across acoustic chunks.}
\item{check}{A logical input that defines whether or not to check function inputs. This can be switched off to improve computation time when the function is applied iteratively or via a front-end function (e.g., \code{\link[flapper]{ac}} or \code{\link[flapper]{acdc}}).}
}
\value{
The function returns an \code{\link[flapper]{acdc_record-class}} object with the following elements: `map', `record', `time', `args', `chunks' and `simplify'. The main output element is the `map' RasterLayer that shows where the individual could have spent more or less time over the duration of the movement time series. The `record' element records time-specific information on the possible locations of the individual, and can be used to plot maps of specific time points or to produce animations (for the time steps specified by \code{save_record_spatial}). The `time' element is a dataframe that defines the times of sequential stages in the algorithm's progression, providing a record of computation time. The `args' element is a named list of user inputs that record the parameters used to generate the outputs (if \code{save_args = TRUE}, otherwise the `args' element is \code{NULL}).
}
\description{
This function is the back-end of the acoustic-container (AC) and acoustic-container depth-contour (ACDC) algorithms.
}
\examples{
#### Step (1) Prepare study site grid
# Grid resolution needs to be sufficiently high to capture detection probability/movement
# And sufficiently low to minimise computational costs
blank <- raster::raster(raster::extent(dat_gebco), res = c(75, 75))
gebco <- raster::resample(dat_gebco, blank)
#### Step (2) Implement setup_acdc_*() steps
# ... Define detection containers required for algorithm(s) (see acs_setup_containers())
#### Step (3) Prepare movement time series for algorithm(s)
# Add required columns to dataframes:
dat_acoustics$timestamp_num <- as.numeric(dat_acoustics$timestamp)
dat_archival$timestamp_num <- as.numeric(dat_archival$timestamp)
# Focus on an example individual
id <- 25
acc <- dat_acoustics[dat_acoustics$individual_id == id, ]
arc <- dat_archival[dat_archival$individual_id == id, ]
# Focus on the subset of data for which we have both acoustic and archival detections
acc <- acc[acc$timestamp >= min(arc$timestamp) - 2 * 60 &
acc$timestamp <= max(arc$timestamp) + 2 * 60, ]
arc <- arc[arc$timestamp >= min(acc$timestamp) - 2 * 60 &
arc$timestamp <= max(acc$timestamp) + 2 * 60, ]
# We'll focus on a one day period with overlapping detection/depth time series for speed
end <- as.POSIXct("2016-03-18")
acc <- acc[acc$timestamp <= end, ]
arc <- arc[arc$timestamp <= end, ]
arc <- arc[arc$timestamp >= min(acc$timestamp) - 2 * 60 &
arc$timestamp <= max(acc$timestamp) + 2 * 60, ]
# Process time series
# ... Detections should be rounded to the nearest step
# ... Duplicate detections
# ... ... (of the same individual at the same receiver in the same step)
# ... ... should be dropped
# ... This step has already been implemented for dat_acoustics.
#### Example (1) Implement AC algorithm with default arguments
out_acdc_1 <- flapper:::.acs(
acoustics = acc,
bathy = gebco,
detection_containers = dat_containers,
mobility = 200
)
#### Example (2) Implement ACDC algorithm with default arguments
out_acdc_2 <- flapper:::.acs(
acoustics = acc,
archival = arc,
bathy = gebco,
detection_containers = dat_containers,
mobility = 200,
calc_depth_error = function(...) matrix(c(-2.5, 2.5), nrow = 2)
)
#### Example (3) Implement AC or ACDC algorithm with detection probability kernels
## (A) Get detection container overlaps
# Define receiver locations as a SpatialPointsDataFrame object with a UTM CRS
proj_wgs84 <- sp::CRS(SRS_string = "EPSG:4326")
proj_utm <- sp::CRS(SRS_string = "EPSG:32629")
rownames(dat_moorings) <- dat_moorings$receiver_id
xy <- sp::SpatialPoints(
dat_moorings[, c("receiver_long", "receiver_lat")],
proj_wgs84
)
xy <- sp::spTransform(xy, proj_utm)
xy <- sp::SpatialPointsDataFrame(xy, dat_moorings[, c(
"receiver_id",
"receiver_start_date",
"receiver_end_date"
)])
# Get detection overlap(s) as a SpatialPolygonsDataFrame
containers <- get_detection_containers(
xy = sp::SpatialPoints(xy),
detection_range = 425,
coastline = dat_coast,
byid = TRUE
)
containers_df <- dat_moorings[, c(
"receiver_id",
"receiver_start_date",
"receiver_end_date"
)]
row.names(containers_df) <- names(containers)
containers <- sp::SpatialPolygonsDataFrame(containers, containers_df)
overlaps <- get_detection_containers_overlap(containers = containers)
## (B) Define detection probability function based on distance and detection_range
calc_dpr <-
function(x) {
ifelse(x <= 425, stats::plogis(2.5 + -0.02 * x), 0)
}
## (C) Get detection kernels (a slow step)
kernels <- acs_setup_detection_kernels(
xy = xy,
containers = dat_containers,
overlaps = overlaps,
calc_detection_pr = calc_dpr,
bathy = gebco
)
## (D) Implement algorithm
out_acdc_3 <- flapper:::.acs(
acoustics = acc,
archival = arc,
bathy = gebco,
detection_containers = dat_containers,
detection_kernels = kernels,
detection_kernels_overlap = overlaps$list_by_receiver,
detection_time_window = 10,
mobility = 200,
calc_depth_error = function(...) matrix(c(-2.5, 2.5), nrow = 2)
)
#### Example (4): Compare outputs with/without detection probability and normalisation
## Without detection kernels
out_acdc_4a <- flapper:::.acs(
acoustics = acc,
archival = arc,
bathy = gebco,
detection_containers = dat_containers,
mobility = 200,
calc_depth_error = function(...) matrix(c(-2.5, 2.5), nrow = 2)
)
out_acdc_4b <- flapper:::.acs(
acoustics = acc,
archival = arc,
bathy = gebco,
detection_containers = dat_containers,
normalise = TRUE,
mobility = 200,
calc_depth_error = function(...) matrix(c(-2.5, 2.5), nrow = 2)
)
## With detection kernels
out_acdc_4c <- flapper:::.acs(
acoustics = acc,
archival = arc,
bathy = gebco,
detection_containers = dat_containers,
detection_kernels = kernels,
mobility = 200,
calc_depth_error = function(...) matrix(c(-2.5, 2.5), nrow = 2)
)
out_acdc_4d <- flapper:::.acs(
acoustics = acc,
archival = arc,
bathy = gebco,
detection_containers = dat_containers,
detection_kernels = kernels, normalise = TRUE,
mobility = 200,
calc_depth_error = function(...) matrix(c(-2.5, 2.5), nrow = 2)
)
## Comparison of final maps
pp <- par(mfrow = c(2, 2))
raster::plot(out_acdc_4a$map, main = "4a")
raster::plot(out_acdc_4b$map, main = "4b")
raster::plot(out_acdc_4c$map, main = "4c")
raster::plot(out_acdc_4d$map, main = "4d")
par(pp)
#### Example (5): Implement AC or ACDC algorithm and write messages to file via 'con'
out_acdc_5 <- flapper:::.acs(
acoustics = acc,
archival = arc,
bathy = gebco,
detection_containers = dat_containers,
mobility = 200,
calc_depth_error = function(...) matrix(c(-2.5, 2.5), nrow = 2),
verbose = TRUE,
con = paste0(tempdir(), "/", "acdc_log.txt")
)
# Check log
utils::head(readLines(paste0(tempdir(), "/", "acdc_log.txt")))
utils::tail(readLines(paste0(tempdir(), "/", "acdc_log.txt")))
#### Example (6): Implement AC or ACDC algorithm and return spatial information
# Specify save_record_spatial = NULL to include spatial information for all time steps
# ... (used for plotting) or a vector to include this information for specific time steps
out_acdc_6 <- flapper:::.acs(
acoustics = acc,
archival = arc,
bathy = gebco,
detection_containers = dat_containers,
mobility = 200,
calc_depth_error = function(...) matrix(c(-2.5, 2.5), nrow = 2),
save_record_spatial = NULL,
verbose = TRUE,
con = paste0(tempdir(), "/", "acdc_log.txt")
)
}
\seealso{
The front-end functions \code{\link[flapper]{ac}} and \code{\link[flapper]{acdc}} call \code{\link[flapper]{.acs_pl}} which in turn calls this function. \code{\link[flapper]{acs_setup_containers}} defines the detection containers required by this function. \code{\link[flapper]{acs_setup_mobility}} is used to examine the assumption of the constant `mobility' parameter. \code{\link[flapper]{acs_setup_detection_kernels}} produces detection probability kernels for incorporation into the function. For calls via \code{\link[flapper]{ac}} and \code{\link[flapper]{acdc}}, \code{\link[flapper]{acdc_simplify}} simplifies the outputs and \code{\link[flapper]{acdc_plot_trace}}, \code{\link[flapper]{acdc_plot_record}} and \code{\link[flapper]{acdc_animate_record}} visualise the results.
}
\author{
Edward Lavender
}
\keyword{internal}