-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathREADME.Rmd
659 lines (484 loc) · 30.6 KB
/
README.Rmd
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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
---
output: github_document
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
op <- options(terra.pal = rev(terrain.colors(256)))
```
# `patter` <a href="https://edwardlavender.github.io/patter/"><img src="man/figures/logo.png" align="right" height="136" alt="patter website" /></a>
**Particle algorithms for animal movement modelling in [`R`](https://www.r-project.org)**
```{r, include = FALSE}
# Compute statistics for package badges
# R CMD CHECK
# * This is currently handled by a CI
# Test coverage
# * We compute test coverage locally, when:
# - This readme is rendered
# - If the time since the last check was >= 24 hours
# * The local computation of test coverage:
# - Saves GitHub Action minutes
# - Is simpler than using bespoke GitHub Actions for covr configured for Windows
# Determine whether or not to compute coverage
# * By default, TRUE
# * If previously computed < 24 hours ago, FALSE
cov_compute <- TRUE
cov_cache_file <- file.path("data-raw", "README", "coverage.rds")
if (file.exists(cov_cache_file)) {
cov_cache <- readRDS(cov_cache_file)
cov_pc <- cov_cache$pc
cov_timestamp <- cov_cache$timestamp
cov_difftime <- difftime(Sys.time(), cov_timestamp, units = "secs")
if (cov_difftime < 24 * 60 * 60) {
cov_compute <- FALSE
}
}
# Compute coverage (~100 s)
if (cov_compute) {
# Get coverage %
cov_pc <-
covr::package_coverage() |>
covr::percent_coverage()
# Update cov_cache
cov_cache <- list(pc = cov_pc, timestamp = Sys.time())
try(saveRDS(cov_cache, cov_cache_file), silent = TRUE)
}
# Build badge
cov_pc <- round(as.numeric(cov_pc))
cov_col <- ifelse(cov_pc >= 90, "brightgreen",
ifelse(cov_pc >= 75, "orange", "red"))
cov_badge <- paste0("https://img.shields.io/badge/coverage-",
cov_pc, "%25-", cov_col)
```
<!-- badges: start -->
[](https://www.repostatus.org/#active)
[](https://lifecycle.r-lib.org/articles/stages.html#experimental)
[](https://CRAN.R-project.org/package=patter)

[](https://github.com/edwardlavender/patter/actions/workflows/R-CMD-check.yaml)
<!-- badges: end -->
`patter` provides particle filtering, smoothing and sampling algorithms for animal movement modelling, with a focus on passive acoustic telemetry systems. This wraps and enhances a fast `Julia` backend ([`Patter.jl`](https://edwardlavender.github.io/Patter.jl)). The methodology enables the reconstruction of movement paths and patterns of space use. `patter` unifies a suite of methods formerly known as the [`flapper`](https://github.com/edwardlavender/flapper) algorithms and supersedes the experimental [`flapper`](https://github.com/edwardlavender/flapper) package (Lavender et al., [2023](https://doi.org/10.1111/2041-210X.14193)).
> **Note:**
> `patter` is a new `R` package. Like all new packages, you should use it with a degree of caution. Please share feedback and issues.
> **[NEWS](NEWS)**
> Welcome to `patter v.2.0.0`! This includes some **breaking changes**. For projects based on earlier versions, use [`renv`](https://rstudio.github.io/renv/articles/renv.html). For future projects, `patter v.2.0.0` is recommended.
# Highlights
`patter` is designed to reconstruct movement paths and emergent patterns of space use from animal tracking data. A powerful, flexible, process-orientated, particle-based framework is used for this purpose. This framework unifies the [`flapper`](https://github.com/edwardlavender/flapper) algorithms and provides important opportunities for development, which we exploit here.
The essential functions are `pf_filter()` and `pf_smoother_two_filter()`:
* **`pf_filter()`** is the particle filter. This simulates the possible locations of an individual moving forwards in time, accounting for all of the data (for example, acoustic observations, depth observations and any other observations) _up to_ each time point and the animal's movement (a partial marginal distribution).
* **`pf_smoother_two_filter()`** is a particle smoothing algorithm. At each time step, the smoother accounts for all of the data from both the past _and_ the future (the full marginal distribution) and substantially refines maps of space use.
We hope to add backward sampling algorithms to the package in due course.
# Evolution
`patter` evolved from the experimental [flapper](https://github.com/edwardlavender/flapper) package, but is:
* **More powerful**, with a substantially revised methodology;
* **Faster**, with overhauled internal routines;
* **Simpler** to use and maintain;
* **Stable**, with fewer dependencies and an upgraded spatial ecosystem;
* **Better tested**, with comprehensive unit tests;
See [`NEWS`](https://github.com/edwardlavender/patter/blob/main/NEWS.md) for a summary of the evolution of [`flapper`](https://github.com/edwardlavender/flapper) to `patter`.
At the time of writing (May 2024), `patter` is more streamlined than [`flapper`](https://github.com/edwardlavender/flapper) and focuses on the implementation of fast particle-based algorithms for the reconstruction of movements and patterns of space use. Please get in touch if you would like to see additional functionality brought into `patter`.
# Installation
> **Note:**
> `patter` works Windows, MacOS and Linux (with some restrictions). On Windows, everything _should_ work if you follow the instructions below. On MacOS, some additional set up (such as compiler configuration) may be required, depending on your set up. On Debian/Ubuntu, `patter` can be used but you cannot simultaneously use geospatial routines in `R` and `Julia`. Thus, you can only call `library(terra)` or `terra::foo()` and use `patter` routines that exploit `terra` and other geospatial packages in `R` sessions that are not connected to a `Julia` session (via `julia_connect()`). We haven't tried other Linux distributions. Package examples were written on MacOS and may not run safely on Linux without modification. Check the function documentation for supported options and share your experience. In case of issues, you should be able to use `Patter.jl` directly, which on some systems may be simpler than getting `R` and `Julia` to play together!
1. **Install [`R`](https://www.r-project.org)**. This package requires `R` version ≥ 4.1 (but the most recent version is recommended). You can check your version from the `R` console using `R.version.string`.
2. **Install build packages.** Package installation and configuration (may) require the [`devtools`](https://github.com/r-lib/devtools), [`pkgbuild`](https://github.com/r-lib/pkgbuild) and [`rmarkdown`](https://github.com/rstudio/rmarkdown) packages. Install them with:
``` r
install.packages(c("devtools", "pkgbuild", "rmarkdown"))
```
On Linux, this step may require system libraries (see below).
3. **Install system libraries**.
* **On Windows**, package building requires `RTools`. You can check whether `RTools` is installed with `pkgbuild::has_rtools()`. If `RTools` is not installed, it is necessary to download and install the appropriate version of `RTools` before proceeding by following the instructions [here](https://cran.r-project.org/bin/windows/RTools/).
* **On MacOS**, some system-specific step up (e.g., compiler configuration) may be required. Follow the steps below and address any issues as required for your system.
* **On Linux**, a suite of system libraries, including `GDAL`, `GEOS` and `PROJ`, are required. See the package [DESCRIPTION](DESCRIPTION) for required/suggested packages and follow the instructions for your system. On Debian/Ubuntu, see [`r2u`](https://eddelbuettel.github.io/r2u/) or follow the instructions below to get up and running.
<details><summary><b>Click</b> for system dependency installation instructions on Ubuntu.</summary>
```bash
sudo apt update
# `make` utility required to compile packages e.g., data.table
sudo apt install build-essential
# Geospatial dependencies for {terra}
sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable
sudo apt install libgdal-dev libgeos-dev libproj-dev
# `ffpmeg` and `libavfilter-dev` for {av} (suggested)
sudo apt install ffmpeg
sudo apt install libavfilter-dev
# `GSL` for {RcppGSL} for {Rfast} (suggested)
sudo apt install libgsl-dev
# `gfortran` for {classInt} -> {sf} (suggested)
sudo apt install gfortran
# `units` for {units} -> {sf} (suggested)
sudo apt install libudunits2-dev
```
</details>
4. **Install [`Julia`](https://julialang.org)**. `Julia` is high-performance programming language that `patter` uses as a backend. If you do not have `Julia` installed on your system, follow the instructions below to install `Julia`.
**A. On Windows, the easiest option is to download and install `Julia` from [JuliaLang](https://julialang.org/downloads/#long_term_support_release)**. During installation, check `Add Julia to PATH`.
**B. Another option is to use `juliaup`**. Some users have found this easier on `MacOS` because you don't have to worry about finding the right `Julia` installation for your architecture.
* Install the `juliaup` installer, following the instructions [here](https://github.com/JuliaLang/juliaup). For example, on `MacOS`, open the shell (Terminal) and type:
```bash
curl -fsSL https://install.julialang.org | sh
```
* In the shell, then install `Julia` (release version) via `juliaup`:
```bash
juliaup update
juliaup default release
```
```{r, include = FALSE}
library(JuliaCall)
julia_setup()
VERSION <- julia_eval("string(VERSION)")
```
> **Note:**
> Install a recent `Julia` version. This README was last built on `r Sys.Date()` with Julia `r VERSION`.
5. **Setup JuliaCall.** The next step is to set up `JuliaCall`, which provides the integration between `R` and `Julia`.
``` r
# Install the {JuliaCall} package:
install.packages("JuliaCall")
# Use the development version if the CRAN version is unavailable:
devtools::install_github("JuliaInterop/JuliaCall",
dependencies = TRUE)
```
``` r
# Run julia_setup() to set up the Julia installation
# * This includes an installJulia argument if the above Julia installation options fail
# * Set `JULIA_HOME` if Julia is not found (see `?julia_setup()`)
# * Note this may take several minutes
# * Set `rebuild = TRUE` if you've previously used JuliaCall on an older R version
library(JuliaCall)
julia <- julia_setup()
```
``` r
# Validate the Julia installation:
# * TRUE: `Julia` is working!
# * FALSE: `Julia` is not working (see below)!
isTRUE(try(julia_eval('true'), silent = TRUE))
```
If `julia_setup()` fails with `'Julia is not found'`, you should tell `R` the location of the `Julia` binary via `JULIA_HOME` (see `?JuliaCall::julia_setup()` and the [`JuliaCall`](https://cran.r-project.org/web/packages/JuliaCall) [README](https://cran.r-project.org/web/packages/JuliaCall/readme/README.html), as well as the relevant `patter` GitHub [issues](https://github.com/edwardlavender/patter/issues?q=label%3Ainstallation) for troubleshooting and ways to get help).
6. **Install [`patter`](https://github.com/edwardlavender/patter).** To install `patter` from the `main` branch, use:
``` r
devtools::install_github("edwardlavender/patter",
dependencies = TRUE,
build_vignettes = rmarkdown::pandoc_available())
```
The `dependencies = TRUE` argument ensures that suggested packages are also installed, which are required for some functions and to build vignettes. This process may take several minutes. Set `build_vignettes = FALSE` for a faster installation.
To install `patter` from the development (`dev`) branch, if available, use:
``` r
devtools::install_github("edwardlavender/patter@dev",
dependencies = TRUE,
build_vignettes = rmarkdown::pandoc_available())
```
This branch may include bug fixes and new features but should be used **with caution**.
We recommend using [`renv`](https://rstudio.github.io/renv/articles/renv.html) (or similar) and [RStudio Projects](https://r4ds.had.co.nz/workflow-projects.html) to track the version of `patter` that you use in your projects. This will ensure that your code continues to work, even if we have to make breaking changes to `patter` as the package evolves in response to user feedback.
7. **Connect to `Julia`**. At the start of every `R` session, you need to connect `R` to `Julia` (and `patter` to [`Patter.jl`](https://github.com/edwardlavender/Patter.jl)):
``` r
# Load & attach {patter}:
library(patter)
# Option (A): Connect to `Julia`:
# * Set `JULIA_HOME` if 'Julia not found'
# * Set `JULIA_PROJ` to use a local Julia project (recommended)
# * Set `JULIA_NUM_THREADS` to exploit multi-threading (recommended)
# * Set `.pkg_update = TRUE` if you've just installed a newer version of `patter`
# * Set `JULIA_PATTER_SOURCE` = "dev" as well if you've installed from the `dev` branch
# * See `julia_connect()` for further guidance
julia <- julia_connect()
```
The first time you run `julia_connect()`, it will connect to `Julia` and install (and pre-compile) [`Patter.jl`](https://github.com/edwardlavender/Patter.jl) and the additional `Julia` dependencies. This usually takes up to five minutes on first run but may take up to twenty minutes depending on the speed of your machine. Subsequent `julia_connect()` calls will be faster.
8. **Validate the `R`---`Julia` connection**. To validate that `patter` works on your system, run:
``` r
julia_validate()
```
This should return `NULL`, invisibly, in which case you are good to go. Otherwise, the function will return an error (or `R` may crash).
9. **(optional) Run package checks**. To run package checks locally, follow the instructions in [dev/001-check.R](dev/001-check.R). See [test-environments.md](test-environments.md) for a list of the systems on which we currently run comprehensive testing and the latest results. We run tests on `MacOS`, `Windows` and `Linux` systems for a selection of recent `R` and `Julia` versions. We only run tests using up-to-date `R` and `Julia` packages. [Issue](https://github.com/edwardlavender/patter/issues) reports are appreciated.
# Functionality
## Vignettes
For an introduction to `patter`, use:
* `vignette("a-methodology", package = "patter")` for a conceptual introduction to the methodology;
* `vignette("b-workflow-outline", package = "patter")` for an overview of the workflow;
For a full list of all functions, see `help(package = 'patter')`.
For a glossary of key arguments, see `glossary`.
## Datasets
For example datasets from the Movement Ecology of Flapper Skate project (`datasets-mefs`), which inspired `patter`, see:
* `dat_moorings` for acoustic receiver deployments;
* `dat_detections` for acoustic detection time series;
* `dat_archival` for archival (depth) time series;
* `dat_gebco()` for a bathymetry grid;
* `dat_coast()` for a coastline vector;
* `dat_mpa()` for a Marine Protected Area boundary
To validate new datasets for use with `patter`, see `pat_setup_data()` and/or the `assemble_*()` function documentation.
For example algorithm outputs (`datasets-algorithms`), see:
* `dat_path()` for an example output from `sim_path_walk()`;
* `dat_coa()` for an example output from `coa()`;
* `dat_pff()` and `dat_pfb()` for an example output from `pf_filter()`;
* `dat_tff()` for an example output from `pf_smoother_two_filter()`;
## Set up `Julia`
To link `patter` and the [`Patter.jl`](https://edwardlavender.github.io/Patter.jl) `Julia` backend, use:
* `julia_connect()` to connect to `R` to `Julia`;
* `julia_validate()` to validate the `R`---`Julia` connection;
* `set_seed()` to set the seed in `R` and `Julia`;
* `set_map()` to make a `SpatRaster` of the study area available in `Julia`;
These functions should be run at the start of every `R` session.
## Abstract Types
`patter` is based on three Abstract Types, defined in `Julia`:
* `State` structures hold the state (location) of an animal at a given time step;
* `ModelMove` structures hold movement model, used to simulate new states;
* `ModelObs` structures hold observation model parameters, used to evaluate the correspondence between simulated states and observations;
## Simulation
To simulate animal movement time series, see:
* `sim_path_walk()` to simulate a movement path from a walk model (via `ModelMove`);
* `sim_array()` to simulate an acoustic array;
* `sim_observations()` to simulate observational time series (via `ModelObs`);
To evaluate model skill in reconstructing simulated patterns, see `skill_*()` functions:
* `skill_mb()` to calculate mean bias;
* `skill_me()` to calculate mean error;
* `skill_rmse()` to calculate root mean squared error;
* `skill_R()` to calculate Spearman's rank correlation coefficient;
* `skill_d()` to calculate the index of agreement;
## Data exploration
For help with data acquisition, processing, checking and preliminary analyses, see the [`flapper`](https://github.com/edwardlavender/flapper) package. This facilitates:
* Data preparation;
* Spatial operations;
* Distance calculations;
* Movement analyses;
Please submit a [feature request](https://github.com/edwardlavender/patter/issues) if you would like functions from [`flapper`](https://github.com/edwardlavender/flapper) in `patter`.
## Algorithms
The main thrust of `patter` is the provision of fast, integrated modelling workflow based on particle filtering for reconstructing animal movement paths and emergent patterns of space use from observational time series (with a focus on passive acoustic telemetry systems).
**To assemble datasets for particle filtering**, use `assemble_*()` functions:
* `assemble_timeline()` assembles a timeline;
* `assemble_acoustics()` assembles an acoustic time series;
* `assemble_acoustics_containers()` assembles a corresponding time series of acoustic containers;
* `assemble_archival()` assembles an archival time series;
* `assemble_custom()` assembles custom time series;
Ancillary time series should be structured in the same way for inclusion in the particle filter.
**To implement particle filtering (PF) routines**, use:
* `pf_filter()` to implement the particle filter;
* `pf_smoother_two_filter()` to implement the two-filter smoother;
These functions return `pf_particles-class` objects.
**For convenience plotting functions**, see:
* `plot_xyt()` to plot particle locations;
**For mapping utilisation distributions**, use:
* `map_pou()` to map probability-of-use;
* `map_dens()` to create smooth maps using `spatstat`, plus the supporting functions:
* `as.im.SpatRaster()`, to convert `SpatRaster`s to pixel images;
* `as.owin.SpatRaster()`, to convert `SpatRaster`s to observation windows;
* `as.owin.sf()`, to convert `sf` objects to observation windows;
* `map_hr_*()` to map home ranges, specifically:
* `map_hr_prop()` for a custom range;
* `map_hr_core()` for the 'core' range;
* `map_hr_home()` for the 'home' range;
* `map_hr_full()` for the full range;
## Options
For additional options in `patter`, see:
* `patter-progress` to monitor function progress;
# Usage
## Set up
This is the basic `patter` workflow to reconstruct movement paths and patterns of space use from animal tracking data. First, we load some essential packages:
```{r}
library(patter)
library(data.table)
library(dtplyr)
library(dplyr, warn.conflicts = FALSE)
options(patter.verbose = FALSE)
```
Second, we connect `R` to `Julia` and set the seed in `R` and `Julia` to ensure reproducibility of our simulations:
```{r, results = "hide"}
julia_connect()
julia_validate()
set_seed(123L)
```
Third, we define the properties of our study area; namely, a `SpatRaster` of our study area that defines the area within which movements are possible and the timeline over which we will model movements:
```{r}
# Define map
# * Use file path on Linux
map <- dat_gebco()
set_map(map)
# Define timeline
timeline <- seq(as.POSIXct("2016-03-17 01:50:00", tz = "UTC"),
as.POSIXct("2016-03-18 01:48:00", tz = "UTC"),
by = "2 mins")
```
## Movement
We will reconstruct the movements of a tagged flapper skate (_Dipturus intermedius_) within a study area off the west coast of Scotland, based on electronic tagging and tracking data. To do so, we need a model for the individual's movements and a series of observation models that connect movements to observations. In this example, we are interested in the two-dimensional (x, y) location of our animal through time (that is, the animal's 'state' is an object of type `StateXY`). The animal can move up to 750 m in two minutes, which is the resolution at which we will model movement, and we formulate a random walk model accordingly based on step lengths and headings:
```{r}
# Define the animal's state:
state <- "StateXY"
# Formulate a corresponding movement model:
mobility <- 750.0
model_move <- model_move_xy(.mobility = "750.0",
.dbn_length = "truncated(Gamma(1, 250.0), upper = 750.0)",
.dbn_heading = "Uniform(-pi, pi)")
# Visualise realisations of the movement model (Windows/MacOS):
# (Paths are coloured by time step from purple (start) to yellow (end))
map |>
sim_path_walk(.timeline = timeline,
.state = state,
.model_move = model_move,
.n_path = 4L,
.one_page = TRUE) |>
invisible()
```
## Observations
We have collected acoustic and archival (depth) observations from tagged flapper skate. Let's pull out the time series for a selected individual:
```{r}
# Define acoustic detections
det <-
dat_detections |>
filter(individual_id == 25L) |>
mutate(individual_id = NULL) |>
as.data.table()
# Define archival (depth) observations
arc <-
dat_archival |>
filter(individual_id == 25L) |>
mutate(individual_id = NULL,
depth_sigma = 50,
depth_deep_eps = 50) |>
rename(obs = depth) |>
as.data.table()
```
Individual movements are connected to the observations by models of the observation process for each dataset. Without going into details, here we bundle together the observations with the parameters of the observation models:
```{r}
# ModelObsAcousticLogisTrunc
acoustics <- assemble_acoustics(.timeline = timeline,
.detections = det,
.moorings = dat_moorings)
# ModelObsContainer
containers <- assemble_acoustics_containers(.timeline = timeline,
.acoustics = acoustics,
.mobility = mobility)
# ModelObsDepthNormalTruncSeabed
archival <- assemble_archival(.timeline = timeline,
.archival = arc)
# Named lists of ModelObs sub-types and associated observations
# * The container dataset is direction specific so we assemble two yobs lists
yobs_fwd <- list(ModelObsAcousticLogisTrunc = acoustics,
ModelObsContainer = containers$forward,
ModelObsDepthNormalTruncSeabed = archival)
yobs_bwd <- list(ModelObsAcousticLogisTrunc = acoustics,
ModelObsContainer = containers$backward,
ModelObsDepthNormalTruncSeabed = archival)
```
Of course, you do not need acoustic and archival data to implement the algorithms (these are just the data we have collected from flapper skate)---other datasets can be used just as easily. To simulate observations instead, see `sim_observations()`.
## Particle filter
We are now in a position to run the particle filter. This runs a simulation forwards (or backwards) in time, sampling states (locations, termed 'particles') that are consistent with the movement model and the observations up to and including each time point. We end up with a time series (`data.table::data.table`) of particles that approximate the partial marginal distribution for the location of the animal, at each time step:
```{r}
# List filter arguments
args <- list(.timeline = timeline,
.state = state,
.yobs = yobs_fwd,
.model_move = model_move,
.n_record = 1000L,
.n_particle = 1e4L)
# Forward run
fwd <- do.call(pf_filter, args, quote = TRUE)
# Forward run outputs
head(fwd$states)
head(fwd$diagnostics)
fwd$callstats
# Backward run
args$.yobs <- yobs_bwd
args$.direction <- "backward"
bwd <- do.call(pf_filter, args, quote = TRUE)
# Backward run outputs
head(bwd$states)
head(bwd$diagnostics)
bwd$callstats
```
## Particle smoother
Particle smoothers refine the outputs from the particle filter. Smoothed particles approximate the full marginal distribution for the location of the individual at each time step (accounting for all of the data before and after each step).
```{r}
# Set `vmap` for probability calculations
# * Use file path rather on Linux
set_vmap(.map = map, .mobility = mobility)
# Run smoother
smo <- pf_smoother_two_filter(.n_particle = 750L, .n_sim = 100L)
# Smoother outputs
head(smo$states)
head(smo$diagnostics)
smo$callstats
```
## Mapping
Particles can be used to reconstruct movement paths and patterns of space use. We can estimate a utilisation distribution from our particle samples as follows:
```{r}
# Estimate UD
# * This must be done in a separate R session on Linux
ud <- map_dens(.map = map,
.coord = smo$states,
.sigma = bw.h)$ud
# Add home range
map_hr_home(ud, .add = TRUE)
mtext(side = 4, "Probability density", line = -3)
```
This basic workflow is highly customisable. You have the flexibility to define species-specific movement models, include any type of observational dataset and implement system-specific observation models. See the vignettes and function examples for further details and reach out with queries.
```{r, include = FALSE}
options(op)
```
# Resources
**For full details on the methods**, see the references below.
**For further information of the `patter` package**, see:
* `?patter::patter` for an overview of package functions;
* `?patter::pf_filter `for information on specific functions (such as `pf_filter()`);
* [`patter-workshops`](https://github.com/edwardlavender/patter-workshops) for introductory materials;
**For further code examples**, see:
* [`patter-demo`](https://github.com/edwardlavender/patter-demo) for simple demonstrations;
* [`patter-eval`](https://github.com/edwardlavender/patter-eval) for a simulation-based workflow and analysis;
* [`patter-flapper`](https://github.com/edwardlavender/patter-flapper) for a real-world analysis on flapper skate;
* [`patter-trout`](https://github.com/edwardlavender/patter-trout) for a real-world analysis on lake trout;
Note that the code base in some repositories may be outdated.
# Disclaimer and troubleshooting
`patter` is a new `R` package. All routines are experimental. Researchers interested in using the package are encouraged to get in touch while the methods and package remain at an early stage of evolution (edward.lavender@eawag.ch).
# Citation
**To cite `patter` in publications**, please use:
* Lavender, E., Scheidegger, A., Albert, C., Biber, S. W., Illian, J., Thorburn, J., Smout, S., & Moor, H. (2025). Particle algorithms for animal movement modelling in receiver arrays. Methods in Ecology and Evolution, 00, 1–12. https://doi.org/10.1111/2041-210X.70028
* Lavender, E., Scheidegger, A., Albert, C., Biber, S. W., Illian, J., Thorburn, J., Smout, S., & Moor, H. (2025). patter: Particle algorithms for animal tracking in R and Julia. Methods in Ecology and Evolution, 00, 1–8. https://doi.org/10.1111/2041-210X.70029
* Lavender, E., Scheidegger, A., Albert, C., Biber, S. W., Brodersen, J., Aleynik, D., Cole, G., Dodd, J., Wright, P. J., Illian, J., James, M., Smout, S., Thorburn, J., & Moor, H. (2025). Animal tracking with particle algorithms for conservation. bioRxiv. https://doi.org/10.1101/2025.02.13.638042
For the `BibTex`:
```bibtex
@Article{Lavender2025a,
author = {Lavender, Edward and Scheidegger, Andreas and Albert, Carlo and Biber, Stanisław W. and Illian, Janine and Thorburn, James and Smout, Sophie and Moor, Helen},
title = {Particle algorithms for animal movement modelling in receiver arrays},
journal = {Methods in Ecology and Evolution},
year = {2025},
volume = {00},
pages = {1--12},
doi = {10.1111/2041-210X.70028}
}
```
```bibtex
@Article{Lavender2025b,
author = {Lavender, Edward and Scheidegger, Andreas and Albert, Carlo and Biber, Stanisław W. and Illian, Janine and Thorburn, James and Smout, Sophie and Moor, Helen},
title = {patter: Particle algorithms for animal tracking in R and Julia},
journal = {Methods in Ecology and Evolution},
year = {2025},
volume = {00},
pages = {1--8},
doi = {10.1111/2041-210X.70029}
}
```
```bibtex
@Article{Lavender2025c,
author = {Lavender, Edward and Scheidegger, Andreas and Albert, Carlo and Biber, Stanisław W. and Brodersen, Jakob and Aleynik, Dmitry and Cole, Georgina and Dodd, Jane and Wright, Peter J. and Illian, Janine and James, Mark and Smout, Sophie and Thorburn, James and Moor, Helen},
title = {Animal tracking with particle algorithms for conservation},
journal = {bioRxiv},
year = {2025},
doi = {10.1101/2025.02.13.638042}
}
```
**`patter` evolved from the [`flapper`](https://github.com/edwardlavender/flapper) [`R`](https://www.r-project.org) package**. Please also consider citing that publication:
Lavender, E., Biber, S., Illian, J., James, M., Wright, P., Thorburn, J., & Smout, S. (2023). An integrative modelling framework for passive acoustic telemetry. Methods in Ecology and Evolution, 14, 2626–2638. https://doi.org/10.1111/2041-210X.14193
```bibtex
@Article{Lavender2023,
author = {Lavender, Edward and Biber, Stanisław W. and Illian, Janine and James, Mark and Wright, Peter J. and Thorburn, James and Smout, Sophie},
title = {An integrative modelling framework for passive acoustic telemetry},
journal = {Methods in Ecology and Evolution},
year = {2023},
volume = {14},
pages = {2626--2638},
doi = {10.1111/2041-210X.14193}
}
}
```
**Thank you for citing the package. Your citations help to justify continued investments in its development.**
---
Please note that `patter` is released with a [Contributor Code of Conduct](https://contributor-covenant.org/version/2/1/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms.