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

.datasets, .step, .trim

Arguments for assemble_timeline().

  • .datasets---A list of data.tables, 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;

.timeline

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;

.acoustics, .moorings, .services

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.

.archival

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.

Details

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 Tuples, 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.

See also

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.

Author

Edward Lavender

Examples

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