These functions assemble a timeline and observations for the particle filter (pf_filter()
).
assemble_timeline(.datasets = list(), .step, .trim = FALSE)
assemble_acoustics(.timeline, .acoustics, .moorings, .services = NULL)
assemble_archival(.timeline, .archival)
Arguments for assemble_timeline()
.
.datasets
---A list
of data.table
s, one for each data type, each containing a timestamp
column;
.step
---A character
(such as "2 mins"
), passed to lubridate::round_date()
and seq.POSIXt()
, that defines the resolution of the timeline;
.trim
---A logical
variable that defines whether or not to trim the timeline to the overlapping period between datasets;
A POSIXct
vector of regularly spaced time stamps that defines the timeline for the simulation (optionally from assemble_timeline()
). Here, timeline
is used to:
Define the resolution of observations;
The data.tables for assemble_acoustics()
(see pat_setup_data()
).
.acoustics
is a data.table of acoustic detections for a single individual. This must contain the receiver_id
and timestamp
columns.
.moorings
is a data.table
of acoustic receiver deployments. This must contain the receiver_id
, receiver_start
, and receiver_end
columns, plus additional parameter columns.
.services
is a data.table
of servicing events. This must contain the receiver_id
, service_start
and service_end
columns.
For assemble_archival()
, .archival
is a data.table
of archival observations (such as depth measurements) for a single individual. This must contain timestamp
and obs
columns plus additional parameter columns.
assemble_timeline()
is a simple function that defines a regular timeline, of resolution .step
, from a list
of input datasets.
If .trim = FALSE
, this defines a sequence of regular time stamps across the full range of time stamps in the input datasets.
If .trim = TRUE
, the timeline is trimmed to the overlapping period between datasets.
assemble_acoustics()
and assemble_archival()
prepare timelines of acoustic and archival observations as required for the particle filter (pf_filter()
). The filter expects a list
of datasets (one for each data type). Each dataset must contain the following columns: timestamp
, sensor_id
, obs
and additional columns with the parameters of the observation model (see glossary
).
assemble_acoustics()
prepares a timeline of acoustic observations, as required by the filter. This function expects a 'standard' acoustic dataset (that is, a data.table
like dat_acoustics
) that defines detections at receivers alongside a moorings dataset (like dat_moorings
) that defines receiver deployment periods and optionally a data.table
of servicing events (when receiver(s) were non-operational). assemble_acoustics()
uses these datasets to assemble a complete time series of acoustic observations; that is, a data.table
of time stamps and receivers that defines, for each time step and each operational receiver whether (1L
) or not (0L
) a detection was recorded at that time step. Duplicate observations (that is, detections at the same receiver in the same time step, are dropped.) If available in .moorings
, additional columns (receiver_alpha
, receiver_beta
and receiver_gamma
) are included as required for the default acoustic observation model (that is, ModelObsAcousticLogisTrunc
). If observation model parameters vary both by receiver and through time, simply amend these columns as required.
assemble_archival()
prepares a timeline of archival observations (such as depth measurements), as required by the filter. This function expects a data.table
that includes, at a minimum, the timestamp
and obs
columns. The latter defines the observations. For archival data, the sensor_id
column (if unspecified) is simply set to 1L
. The function re-expresses time stamps at the resolution specified by timeline
. Duplicate observations (that is, multiple measurements in the same time step) throw a warning
.
Additional datasets are easy to incorporate into the particle filter but require manual preparation in the format described above. Observations can be recorded irregularly or regularly through time but must be expressed at the temporal resolution defined by the timeline.
In Julia
, datasets are translated into a hash-table (Dict
) of observations (via Patter.assemble_yobs()
). For each time stamp with an observation, this includes a Vector
of Tuple
s, each containing the observation and the associated ModelObs
instance that defines the parameters of the observation model. The particle filter (Patter.particle_filter()
) iterates over each time step in the timeline, uses a movement model to simulate animal movement and, for the time stamps with observations, evaluates the likelihood of those observations for the simulated locations (particles).
assemble_*()
routines are only required for real-world analyses.
Particle filters and smoothers sample states (particles) that represent the possible locations of an individual through time, accounting for all data and the individual's movement.
To simulate artificial datasets, see sim_*()
functions (especially sim_path_walk()
, sim_array()
and sim_observations()
).
To assemble real-world datasets for the filter, see assemble
_*()
functions.
pf_filter()
runs the filter:
To run particle smoothing, use pf_smoother_two_filter()
.
To map emergent patterns of space use, use a map_*()
function (such as map_pou()
, map_dens()
and map_hr()
).
library(data.table)
library(dtplyr)
library(dplyr, warn.conflicts = FALSE)
#### Define example dataset(s) for a selected individual
# Acoustic time series
# * Observation model parameters are defined in `.moorings`
acc <-
dat_acoustics |>
filter(individual_id == 25L) |>
select("timestamp", "receiver_id") |>
as.data.table()
# Archival time series
# * Observation model parameters must be included
# * Here, we define parameters for `?ModelObsDepthNormalTrunc`
arc <-
dat_archival |>
filter(individual_id == 25L) |>
select("timestamp", obs = "depth") |>
mutate(depth_sigma = 50, depth_deep_eps = 20) |>
as.data.table()
#### Example (1): Define a timeline
# Define a timeline manually
timeline <- seq(as.POSIXct("2016-03-01 00:00:00", tz = "UTC"),
as.POSIXct("2016-04-01 00:00:00"),
by = "2 mins")
# Use `assemble_timeline()` with `.trim = FALSE`
timeline <- assemble_timeline(list(acc, arc), .step = "2 mins")
range(timeline)
#> [1] "2016-03-16 00:00:00 UTC" "2017-06-01 05:58:00 UTC"
# Use `assemble_timeline()` with `.trim = TRUE`
timeline <- assemble_timeline(list(acc, arc), .step = "2 mins", .trim = TRUE)
timeline <- timeline[1:1440]
range(timeline)
#> [1] "2016-03-17 01:50:00 UTC" "2016-03-19 01:48:00 UTC"
#### Example (2): Assemble an acoustic timeline
# Assemble a timeline of acoustic observations (0, 1) and model parameters
# * The default acoustic observation model parameters are taken from `.moorings`
# * But can be modified or added afterwards for custom observation models
acoustics <- assemble_acoustics(.timeline = timeline,
.acoustics = acc,
.moorings = dat_moorings)
head(acoustics)
#> timestamp sensor_id obs receiver_x receiver_y receiver_alpha
#> <POSc> <int> <int> <num> <num> <num>
#> 1: 2016-03-17 01:50:00 3 0 706442.1 6254007 4
#> 2: 2016-03-17 01:50:00 4 0 709742.1 6267707 4
#> 3: 2016-03-17 01:50:00 7 0 708742.1 6269107 4
#> 4: 2016-03-17 01:50:00 9 0 706042.1 6254307 4
#> 5: 2016-03-17 01:50:00 11 0 707542.1 6267707 4
#> 6: 2016-03-17 01:50:00 12 0 710042.1 6267307 4
#> receiver_beta receiver_gamma
#> <num> <num>
#> 1: -0.01 750
#> 2: -0.01 750
#> 3: -0.01 750
#> 4: -0.01 750
#> 5: -0.01 750
#> 6: -0.01 750
#### Example (3): Assemble an archival timeline
# Assemble a timeline of archival observations and model parameters
archival <- assemble_archival(.timeline = timeline,
.archival = arc)
head(archival)
#> timestamp sensor_id obs depth_sigma depth_deep_eps
#> <POSc> <int> <num> <num> <num>
#> 1: 2016-03-17 01:50:00 1 73.78 50 20
#> 2: 2016-03-17 01:52:00 1 73.32 50 20
#> 3: 2016-03-17 01:54:00 1 73.32 50 20
#> 4: 2016-03-17 01:56:00 1 73.32 50 20
#> 5: 2016-03-17 01:58:00 1 73.55 50 20
#> 6: 2016-03-17 02:00:00 1 68.70 50 20
#### Example (4): Implement particle filter
# Use `pf_filter()` to implement the particle filter
# A list of assembled datasets is passed to the `yobs` argument
# The corresponding `ModelObs` sub-types must also be specified