-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprocess_false_detections_sf.Rd
85 lines (77 loc) · 7.27 KB
/
process_false_detections_sf.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
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/processing.R
\name{process_false_detections_sf}
\alias{process_false_detections_sf}
\title{Pass putative false detections through a spatial filter}
\usage{
process_false_detections_sf(det, tf, sf, dist_btw_receivers)
}
\arguments{
\item{det}{A dataframe containing detection time series. Following \code{\link[glatos]{false_detections}}, this should contain the following columns: `detection_timestamp_utc', `transmitter_codespace', `transmitter_id' and `receiver_sn', as well as `passed_filter' (see \code{\link[glatos]{false_detections}}).}
\item{tf}{A number that defines the time threshold (s) used to flag false detections (see \code{\link[glatos]{false_detections}}).}
\item{sf}{A number that defines the threshold Euclidean distance between receivers beyond which, even if a false detection is accompanied by detections at other receivers, it is likely to be a true false detection, because the individual could not have moved between receivers separated by more than this threshold over the specified time interval. \code{sf} should be defined in the same units as the distances provided in \code{dist_btw_receivers} (see below).}
\item{dist_btw_receivers}{A dataframe that defines the distances between receiver pairs. This should contain the columns: `r1', `r2' and `dist', whereby `r1' and `r2' contain the unique receiver serial number for all combinations of receivers and `dist' contains the distance between them. This dataframe should include duplicate combinations (e.g., both r1 = 1 and r2 = 2 and r1 = 2 and r2 = 1). This can be created with \code{\link[flapper]{dist_btw_receivers}}.}
}
\value{
The function returns a vector, of the same length as \code{det} with three possible values: NA, which identifies detections which have not been flagged as false detections (i.e., \code{passed_filter = 0}, see \code{\link[glatos]{false_detections}}) and are therefore not passed through the spatial filter; 1, which identifies detections which `passed' the spatial filter (i.e., false detections which are accompanied by detections at nearby receivers within the defined spatial and temporal thresholds); or 0, which defines detections which `failed' the spatial filter (i.e., false detections which are not accompanied by detections at nearby receivers within the defined spatial and temporal thresholds). This vector has one attribute, `details', a dataframe with the same number of rows as \code{det} with the following columns: `passed_filter_sf', `n_wn_sf', `detection_timestamp_utc_sf' and `receiver_sn_sf'. `passed_filter_sf' takes a value of NA, 0 or 1 depending on whether or not the detection was flagged as a false detection (if not, NA) and whether each false detection passed the spatial filter (no, 0; yes, 1). If the detection did pass the spatial filter, `n_wn_sf' provides the number of detections at nearby receivers within \code{tf} and \code{sf}; and `detection_timestamp_utc_sf', `receiver_sn_sf' and `dist_sf' define the timestamp of the detection at the nearest receiver, the receiver at which the detection was made and the distance between the two receivers respectively.
}
\description{
The identification of false detections in acoustic telemetry data is an important aspect of processing and/or modelling these data. False detections can be identified using the short interval criterion, whereby any detection of an individual at a receiver which is not accompanied by other detections at the same receiver in a specified time window (depending on the nominal acoustic transmission delay) are flagged. This approach can be implemented using the \code{\link[glatos]{false_detections}} function in the \code{\link[glatos]{glatos}} package. Flag detections can then be examined, or passed through other filters, to examine their plausibility.
This function passes false detections flagged by \code{\link[glatos]{false_detections}} through a spatial filter. The key idea is that detections at nearby receivers within a defined time window may, in fact, be plausible. To implement this approach, the user must define a dataframe comprising detections, a temporal threshold, a spatial threshold and a dataframe of distances between receivers. The function examines whether any putative false detections are accompanied by additional detections at other receivers within a user-defined time window and Euclidean distance of that receiver. If so, these could be explained by an individual that dips in-and-out of the detection ranges of receivers (e.g. in a sparse acoustic array) and may not, in fact, be false.
}
\details{
There are limitations with the application of this spatial filter to false detections. First, the spatial threshold beyond which false detections are likely to be false is based on Euclidean distances at present. These may be problematic (e.g. when receivers hug complex coastlines). Second, for small arrays, fast-swimming organisms and/or a large nominal transmission delay (i.e., time threshold), the spatial filter is a poor filter because individuals can access the whole area over the whole time interval.
}
\examples{
#### Define necessary columns to compute false detections using glatos::false_detections()
det <- dat_acoustics[dat_acoustics$individual_id == 25, ]
stopifnot(!is.unsorted(det$timestamp))
det$detection_timestamp_utc <- det$timestamp
det$transmitter_codespace <- substr(det$transmitter_id, 1, 8)
det$transmitter_id <- substr(det$transmitter_id, 10, 13)
det$receiver_sn <- det$receiver_id
det <- det[, c(
"detection_timestamp_utc",
"transmitter_codespace",
"transmitter_id",
"receiver_sn"
)]
#### Clean false detections from 'raw' data
det <- glatos::false_detections(det, tf = 3600)
det <- det[det$passed_filter == 1, ]
det$passed_filter <- NULL
det$min_lag <- NULL
#### Add 'new' false detections for demonstration purposes
# Add three rows to `det` which, below, we'll make 'false detections'
det <- rbind(det, det[rep(nrow(det), 3), ])
pos_false <- (nrow(det) - 2):nrow(det)
# Add an isolated detection accompanied by a detection at a nearby receiver
det$detection_timestamp_utc[pos_false[1:2]] <-
det$detection_timestamp_utc[pos_false[1:2]] + 60 * 60 * 60
det$receiver_sn[pos_false[2]] <- 52
# Add an isolated detection not accompanied by a detection at a nearby receiver
det$detection_timestamp_utc[pos_false[3]] <-
det$detection_timestamp_utc[pos_false[3]] + 60 * 60 * 60 * 2
det <- glatos::false_detections(det, tf = 3600)
stopifnot(length(which(det$passed_filter == 0)) == 3L)
tail(det$passed_filter)
##### Implement spatial filter
# Calculate distances between receivers
# * For simplicity, here, we ignore differences in deployment timing
dist_btw_receivers_km <-
dist_btw_receivers(dat_moorings[, c("receiver_id", "receiver_long", "receiver_lat")])
# Note the function returns a vector, unlike glatos::false_detections():
det$passed_filter_sf <-
process_false_detections_sf(det,
tf = 3600,
sf = 0.5,
dist_btw_receivers = dist_btw_receivers_km)
# Only the last observation failed the spatial filter, as expected:
tail(det$passed_filter_sf)
stopifnot(which(det$passed_filter_sf == 0) == nrow(det))
# Additional information is available from the attributes dataframe:
tail(attr(det$passed_filter_sf, "details"))
}
\author{
Edward Lavender
}