simulate fish tracks with/without acoustic detections in featureless and semi-realistic environments
{simfish} is an R package that facilitates simulation of fish tracks in semi-realistic environments (coastal oceans, fjords, and lakes). A user-supplied raster defining the water body - land boundaries is used to constrain simulated tracks. Fish movements are simulated (currently) as either a correlated random walk or a biased & correlated random walk, with the bias toward a defined Centre-of-Attraction. A potential function is used to ensure the tracks avoid land. The package can also be used to simulate detections of acoustically-tagged fish by acoustic receivers at user-defined locations.
You can install simfish from GitHub with:
# install.packages("remotes")
remotes::install_github("ianjonsen/simfish")
require(tidyverse, quietly = TRUE)
require(simfish, quietly = TRUE)
## define simulation parameters
my.par <- sim_par(
N = 250, # number of simulation time steps
time.step = 60, # time step in minutes
coa = c(15, 30), # location of centre-of-attraction for biased correlated random walk (can be NA)
nu = 1, # strength of attraction to CoA (range: 0 - infinity)
rho = 0.6 # angular dispersion param for move directions (range 0 - 1)
)
## simulate a single track
s1 <- sim_fish(id = 1,
data = NULL,
mpar = my.par)
plot(s1)
require(sf, quietly = TRUE)
## create raster using rnaturalearth hires polygon data
x <- generate_env(ext = c(-70,43,-52,53),
grad = TRUE)
## parameterize the simulation
my.par <- sim_par(
N = NULL, # simulation runs until fish gets to within coa.tol km of CoA
start = c(-6850, 5710), # start location for simulated fish
time.step = 60*2, # time step in minutes
bl = 2, # move speed in body-lengths / s
fl = 0.4, # fork-length (m)
coa = c(-6080, 5930), # location of centre-of-attraction for biased correlated random walk (can be NA)
coa.tol = 10, # tolerance around CoA(s) (km)
nu = 0.75, # strength of attraction to CoA (range: 0 - infinity)
rho = 0.65, # angular dispersion param for move directions (range 0 - 1)
beta = c(-8,-8) # potential function parameters for x and y directions to
# keep fish off land. Larger -ve values result in stronger land avoidance but can
# introduce unrealistic jumps (possibly across narrow land features) in the track.
)
## simulate a single track
s2 <- sim_fish(id = 1,
data = x,
mpar = my.par)
Now simulate acoustic detections on a receiver array - we’ll use the Ocean Tracking Network’s Cabot Strait receiver line
tmp <- tempfile(fileext = ".csv")
download.file("https://members.oceantrack.org//geoserver/wfs?request=getfeature&service=wfs&outputFormat=CSV&typename=otn:stations_receivers&cql_filter=collectioncode+EQ+%27CBS%27",
destfile = tmp)
recLocs <- read_csv(tmp) %>%
filter(deploy_date >= "2020-01-01")
## project receiver locations from long-lat to Mercator grid
xy <- recLocs %>%
st_as_sf(., coords = c("stn_long", "stn_lat"), crs = 4326) %>%
st_transform(crs = "+proj=merc +datum=WGS84 +units=km") %>%
st_coordinates() %>%
as.data.frame()
## set all receiver depths to 100 m
recLocs <- bind_cols(recLocs, xy) %>%
dplyr::select(id = station_name, x = X, y = Y) %>%
mutate(z = 100)
## add receiver locations to data list object
x$recLocs <- recLocs
## simulate detections of a V13 acoustic tag
## parameters (intercept, slope) from a logistic regression of distance on
## detection rate
## use calc_pdrf to calculate slope for 50% detection rate at 500 m with an
## intercept of 5
my.par$pdrf <- calc_pdrf(pdet = 0.5, dist = 500, int = 5)
s2 <- s2 %>%
sim_detect(data = x)
map(s2,
env = x,
xlim = c(-7000, -6000),
ylim = c(5600, 6200))